Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / Interop / May 2004

Tip: Looking for answers? Try searching our database.

C# | Shell Extension Handler (Icon Overlay Handler)

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Jan Willem Zondag - 26 May 2004 22:16 GMT
I am trying to implement an Icon Overlay Handler in C#.
So far I have come up with the following code.
After registering the dll with regasm I get icon overlays all over the place
just as requested.
The problem is that a different icon is displayed as overlay than the
iconFile I
pass in te GetOverlayInfo methode.
Running the whole thing through the debugger I can see that on entering the
GetOverlayInfo methode the iconFileBuffer
is already filled and although I change it the "older" iconFile is used.
This leads me to the conclusion that I dealing with a string marshalling
problem. Switching to StringBuilder doesn't correct it.
Anyone?

using System;
using System.Runtime.InteropServices;
using Microsoft.Win32;

namespace ShellExtension
{

   public sealed class ShellInterop
   {

       private ShellInterop()
       {
       }

       /*
        * void SHChangeNotify(
        *     LONG wEventId,
        *     UINT uFlags,
        *     LPCVOID dwItem1,
        *     LPCVOID dwItem2);
        */
       [DllImport("shell32.dll")]
       public static extern void SHChangeNotify(
           int      eventID,
           uint    flags,
           IntPtr item1,
           IntPtr item2);

   }

   [ComVisible(false)]
   [ComImport]
   [Guid("0C6C4200-C589-11D0-999A-00C04FD655E1")]
   [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
   public interface IShellIconOverlayIdentifier
   {

       [PreserveSig]    int IsMemberOf(
           [MarshalAs(UnmanagedType.LPWStr)]    string path,

uint attributes);

       [PreserveSig]    int GetOverlayInfo(
           [MarshalAs(UnmanagedType.LPWStr)]    string iconFileBuffer,

int     iconFileBufferSize,

out int iconIndex,

out uint flags);

       [PreserveSig]    int GetPriority(
           out int priority);

   }

   [ComVisible(true)]
   [Guid("B8FA9E43-38E6-4654-8A13-FF905AD22CE5")]
   public class MyIconOverlay:IShellIconOverlayIdentifier
   {

       #region IShellIconOverlayIdentifier Members

       public int IsMemberOf(string path, uint attributes)
       {
           //Show everything with icon overlay
           return 0; // S_OK
       }

       public int GetOverlayInfo(string iconFileBuffer, int
iconFileBufferSize, out int iconIndex, out uint flags)
       {
           iconFileBuffer = @"c:\overlay.ico";
           iconIndex = 0;
           flags = 1; // ISIOI_ICONFILE
           return 0; // S_OK
       }

       public int GetPriority(out int priority)
       {
           priority = 0; // 0-100 (0 is highest priority)
           return 0; // S_OK
       }

       #endregion

       #region Registry

       [ComRegisterFunction]
       public static void Register(Type t)
       {
           RegistryKey rk =
Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersi
on\Explorer\ShellIconOverlayIdentifiers\_" + t.Name);
           rk.SetValue(string.Empty, t.GUID.ToString("B").ToUpper());
           rk.Close();
           ShellInterop.SHChangeNotify(0x08000000, 0, IntPtr.Zero,
IntPtr.Zero);
       }

       public static void Unregister(Type t)
       {

Registry.LocalMachine.DeleteSubKeyTree(@"SOFTWARE\Microsoft\Windows\CurrentV
ersion\Explorer\ShellIconOverlayIdentifiers\_" + t.Name);
           ShellInterop.SHChangeNotify(0x08000000, 0, IntPtr.Zero,
IntPtr.Zero);
       }

       #endregion

   }

}
"Ying-Shen Yu[MSFT]" - 28 May 2004 03:12 GMT
Hi Jan,

I'm not sure if the default marshaler will copy the modified string back to
the unmanaged memory area. In this situation I suggest you defining this
method as

[PreserveSig]    int GetOverlayInfo(
    IntPtr iconFileBuffer,
    int iconFileBufferSize,
    out int iconIndex,
    out uint flags);

and doing marshalling by yourself.
public int GetOverlayInfo( IntPtr iconFileBuffer, int iconFileBufferSize,
out int iconIndex, out uint flags)
{
   
System.Diagnostics.Debug.WriteLine(string.Format("GetOverlayInfo::{0}",iconF
ileBuffer));
   
System.Diagnostics.Debug.WriteLine(string.Format("GetOverlayInfo::{0}",iconF
ileBufferSize));
    string fname = @"c:\overlay.ico";

    int bytesCount = System.Text.Encoding.Unicode.GetByteCount(fname);

   
System.Diagnostics.Debug.WriteLine(string.Format("GetOverlayInfo::{0}",bytes
Count));

    byte[] bytes = System.Text.Encoding.Unicode.GetBytes(fname);

    if (bytes.Length + 2 < iconFileBufferSize)
    {
        for(int i = 0; i < bytes.Length; i++)
        {
            Marshal.WriteByte(iconFileBuffer,i,bytes[i]);
        }
                              //write the "\0\0"
        Marshal.WriteByte(iconFileBuffer,bytes.Length,0);
        Marshal.WriteByte(iconFileBuffer,bytes.Length+1,0);
    }

    iconIndex = 0;
    flags = 1; // ISIOI_ICONFILE
    return 0; // S_OK
}

Does it resolve your problem?
If you have any problem on this issue, please feel free to reply this
thread.
Thanks!

Best regards,

Ying-Shen Yu [MSFT]
Microsoft Community Support
Get Secure! - www.microsoft.com/security

This posting is provided "AS IS" with no warranties and confers no rights.
This mail should not be replied directly, please remove the word "online"
before sending mail.
Jan Willem Zondag - 28 May 2004 08:55 GMT
Hi Ying-Shen,

Problem resolved, thanks!

Thought it had to do with marshalling, had tried several options:

- marschalling with [String]
- marshalling with [StringBuilder]
- IntPtr iconFileBuffer = Marshal.StringToCoTaskMemUni("string")
- IntPtr iconFileBuffer = Marshal.StringToHGlobalUni("string")

forgot to use your solution: write to unmanaged memory area directly

Regards,
Jan

> Hi Jan,
>
[quoted text clipped - 12 lines]
> out int iconIndex, out uint flags)
> {

System.Diagnostics.Debug.WriteLine(string.Format("GetOverlayInfo::{0}",iconF
> ileBuffer));

System.Diagnostics.Debug.WriteLine(string.Format("GetOverlayInfo::{0}",iconF
> ileBufferSize));
> string fname = @"c:\overlay.ico";
>
> int bytesCount = System.Text.Encoding.Unicode.GetByteCount(fname);

System.Diagnostics.Debug.WriteLine(string.Format("GetOverlayInfo::{0}",bytes
> Count));
>
[quoted text clipped - 30 lines]
> This mail should not be replied directly, please remove the word "online"
> before sending mail.

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.