Hi All,
I've been holding off on doing the 2.8.10.x release until I could solve or workaround the issue of Python 2.6 not including a reference to the themed version of the comctl32 DLL in the executable's embedded manifest. The last time I worked on it I got so frustrated that I really procrastinated taking another look at it, but I finally did this week and have made a little more progress, but still don't have a real good solution.
A little background info:
* Two versions of the comctl32 (common controls) DLL are distributed on Windows since XP. One that supports XP style themes and one that doesn't. Instead it provides the old unthemable UI that was available on win2k.
* To tell the system to use the new comctl32 DLL an application is supposed to provide a manifest file (or embedded resource) which is a little snippet of XML that specifies which "side by side assemblies" are to be loaded. (SxS assemblies are MS's answer to DLL Hell, but most developers agree that it just made it worse, not better.)
* Prior to Python 2.6 the python executables did not include a manifest (embedded or in an external file) so I was able to install my own manifest file that caused the system to load comctl32 v6 when python[w].exe is run and all was good. Python 2.6 does include an embedded manifest, but it does *not* include a reference to the comctl32 assembly, just the C Runtime. Using the old file manifest trick seems to still work on 32-bit XP but not 64-bit XP or either version of Vista. For some people wxPython apps would just look ugly, for others they would crash.
* I submitted a bug report to Python asking that the embedded resource be updated, but got enough push-back on it that I decided to try and find another solution. http://bugs.python.org/issue5019.
* wxPython 2.8.9.2 is distributed with a little script that can be used to hack the embedded manifest in the python executable, but that is obviously not a very nice or safe thing to do.
* I tried using the windows API to create explicit activation contexts that load a manifest with the reference to the themed version of comctl32. At first it seemed to have absolutely no effect whatsoever and I spent a bunch of time chasing snakes down the wrong rat hole, thinking that by the time the wxPython extension modules are loaded that it was too late to try and force a different DLL to be loaded. After all, the extension modules have their own manifest resources and they didn't make any difference either...
* Eventually we figured out that if the wxPython demo used the splash screen then it would use the old unthemed version of the DLL. If I commented out the use of the splash screen then it would use the themed version. The odd thing is that wxSpashScreen is mostly generic code and does almost nothing differently than any other wxFrame, so it just didn't make any sense that it could have this kind of effect. This is where I practically gave up several weeks ago and started procrastinating and focusing on 2.9 instead.
Ok, so that was more than just a bit of background info...
This week I was able to further narrow down the source of the problem, but still no real cause nor how to work around it. The wxSpashScreen uses a timer and in the wxPython demo we are creating and showing the main frame from the splash's EVT_CLOSE handler and the close is happening from in the timer event. If I instead click on the splash so that it closes itself from the mouse handler then the themed comctl32 is correctly used. At first I thought that it only mattered if the first window was created inside a timer event or not, but I then looked at other timers and found that any UI objects created in timer events are ignoring the explicit activation context that I set and are falling back to the process's default activation context (using the manifest embedded in python.exe.) So in other words, if you create window objects from timers you can easily have a situation where some windows are using themes and others are not. (Please don't ask me what I think about microsoft right now, you would be ashamed of me after hearing the words I would use.)
So far Google hasn't turned up anything relevant to this situation. wxTimer is just using basic win32 APIs for implementing the timer so nothing weird is going on there... If anybody has any ideas, or better Google searches, then please let me know. I do have one solution, but it involves putting what would probably be wxPython-specific code into wxWidgets, so I'd like to avoid that if possible.
P.S. The wxErlang folks ran into the same problem and talked to me about it a couple weeks ago. They eventually just convinced the Erlang project to update their embedded manifest, but since it was just a matter of talking to the guy in the cubicle down the hall it wasn't too difficult to get it approved.
···
--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!