[python-win32] Overlay Icon Question...

Andrea Gavana andrea.gavana at gmail.com
Tue Apr 15 15:44:36 CEST 2008


Hi Tim, Roger & All,

On Tue, Apr 15, 2008 at 10:03 AM, Tim Golden wrote:
> Andrea Gavana wrote:
> > Hi Roger,
> >
> > On Tue, Apr 15, 2008 at 12:21 AM, Roger Upole wrote:
> >> I've been meaning to look at how this works for some time,
> >> so I took a few minutes to cook up an example (attached).
> >
> > Thank you very much for the sample! It is really enlighting. I have
> > however some difficulty to understand it (sorry for the dumb
> > questions):
>
> (I think Roger's in a different timezone, so I'll answer what
> I can for the purposes of expediency. He can obviously speak
> for himself when he's online).
>
> You really want to look at:
>
> http://msdn2.microsoft.com/en-us/library/bb776858(VS.85).aspx?topic=306117
>
> for the inside story.
>
> > 1) How do you actually use the SIOI class?
>
> As a class, you don't. It's simply the mechanism for serving the
> COM object which contains the methods the shell will be calling
> back. There's some magic which the UseCommandLine call does
> on your behalf to register the class as the COM server which the
> shell expects.
>
> > I tried to run the sample,
> > then creating various files here and there in my hard drive, but I
> > don't really know what IsMemberOf() is accepting as fname to make the
> > overlay. Is it the file name? The icon name? Something else?
>
> Find an icon file that exists, unless you happen to have something
> on your J: drive which exactly matches Roger's example. I used the
> TortoiseSVN icons on my machine under:
>
> c:\Program Files\TortoiseSVN\icons\Classic\TortoiseAdded.ico
>
> Replace the path in GetOverlayInfo with whatever you've chosen.
> This is the icon which will be overlaid (in miniature) over whatever
> existing icon a file has.
>
> Have the IsMemberOf method return S_OK for every file whose icon
> you want overlaid. The first param is the filename. Roger's example simply
> looks for the world "overlay" in the filename.
>
> > 2) Let's suppose that I want to assign an overlayed icon to a
> > particular file in a directory: let's say this file is called
> > "HELLO.DATA" and the directory contains also other files with the
> > .DATA extension. What should I do to assign the overlayed icon only to
> > this particular file?
>
> Change the .IsMemberOf function to say something like:
>
> if os.path.basename (fname) == "HELLO.DATA":
>  return winerror.S_OK
> return winerror.E_FAIL
>
> Hope that helps

Yes, thank you, it helps a lot... although I still have some doubts.
These are my modifications of the class Roger posted:

class SIOI(object):
    _reg_clsid_='{02844251-42C2-44CA-B43D-424FCE4F4660}'
    _reg_progid_='K-SVR.IShellIconOverlayIdentifier'
    _reg_desc_='Python implementation of IShellIconOverlayIdentifier'
    _public_methods_ = ['GetOverlayInfo','GetPriority','IsMemberOf']
    _com_interfaces_=[shell.IID_IShellIconOverlayIdentifier,
pythoncom.IID_IDispatch]
    __name__ = "SIOI"

    def __init__(self, fileNames):
        self.fileNames = fileNames

    def AddFile(self, fileName):
        if fileName not in self.fileNames:
            self.fileNames.append(fileName)

    def RemoveFile(self, fileName):
        if fileName in self.fileNames:
            self.fileNames.remove(fileName)

    def GetOverlayInfo(self):
        return (r'icons/KSVROverlay.ico', 0, shellcon.ISIOI_ICONFILE)

    def GetPriority(self):
        return 50

    def IsMemberOf(self, fname, attributes):
        if fname in self.fileNames:
            return winerror.S_OK
        return winerror.E_FAIL


def IconOverlay(fileNames):

    import win32com.server.register
    overlayClass = SIOI(fileNames)
    win32com.server.register.UseCommandLine(overlayClass)
    keyname=r'Software\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers\KSVROverlayHandler'
    key=win32api.RegCreateKey(win32con.HKEY_LOCAL_MACHINE, keyname)
    win32api.RegSetValue(key, None, win32con.REG_SZ, SIOI._reg_clsid_)

    return overlayClass


And this is what I do:

1) When my app is launched, the database returns a list of file names
(with the full path) stored inside the variable fileNames;
2) I then call the method IconOverlay, which initializes the class
SIOI with these fileNames;
3) in the IsMemberOf method, if a file name is in the fileNames list,
the icon should be overlayed.

I can't see any icon overlayed on my PC, even after logging off and on
(or restarting). I am doing something stupid for sure, althought I am
too newbie to find out what I am doing wrong :-(
I suppose I can't initialize the SIOI class as I am doing, or I can't
test IsMemberOf using the fileNames list as I am doing... Am I missing
something? Is there another way to accomplish what I am looking for?

Thank you for your suggestions.

Andrea.

"Imagination Is The Only Weapon In The War Against Reality."
http://xoomer.alice.it/infinity77/


More information about the python-win32 mailing list