[python-win32] Overlay Icon Question...

Andrea Gavana andrea.gavana at gmail.com
Tue Apr 15 15:51:45 CEST 2008


Hi All,

On Tue, Apr 15, 2008 at 2:44 PM, Andrea Gavana wrote:
> 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.

Sorry to break in again... something unusual happened: when I start my
app, as soon as I open a file dialog from my app, I get this nice
error from PythonCom:

D:\MyProjects\K-SVR>K-SVR.py
Registered: K-SVR.IShellIconOverlayIdentifier
Registered: K-SVR.IShellIconOverlayIdentifier

==> Here I open the file dialog <==

pythoncom error: ERROR: server.policy could not create an instance.

Traceback (most recent call last):
  File "C:\Python25\Lib\site-packages\win32com\server\policy.py", line
144, in CreateInstance
    return retObj._CreateInstance_(clsid, reqIID)
  File "C:\Python25\Lib\site-packages\win32com\server\policy.py", line
202, in _CreateInstance_
    myob = call_func(classSpec)
  File "C:\Python25\Lib\site-packages\win32com\server\policy.py", line
739, in call_func
    return resolve_func(spec)(*args)
<type 'exceptions.TypeError'>: __init__() takes exactly 2 arguments (1 given)
pythoncom error: Unexpected gateway error

Traceback (most recent call last):
  File "C:\Python25\Lib\site-packages\win32com\server\policy.py", line
144, in CreateInstance
    return retObj._CreateInstance_(clsid, reqIID)
  File "C:\Python25\Lib\site-packages\win32com\server\policy.py", line
202, in _CreateInstance_
    myob = call_func(classSpec)
  File "C:\Python25\Lib\site-packages\win32com\server\policy.py", line
739, in call_func
    return resolve_func(spec)(*args)
<type 'exceptions.TypeError'>: __init__() takes exactly 2 arguments (1 given)
pythoncom error: CPyFactory::CreateInstance failed to create instance.
(80004005)

I have no idea of what this means, but for sure I have messed up with
something :-( :-(

Andrea.

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


More information about the python-win32 mailing list