[wxPython] Solution to small/large icons on Windows

Thanks to Robin and Vadim, I was able to come up with a solution to setting both the large and small icons in wxPython. You'll need to store them in separate files, and you'll need both win32api from the win32 extensions and the windll library (because LoadImage doesn't appear to be exposed in the win32 extensions, so I had to get at it through windll). windll is available as part of DynWin by Sam Rushing at:

http://www.nightmare.com/~rushing/dynwin/

···

##########
from wxPython.wx import *

class MyApp(wxApp):
    def OnInit(self):
        frame = wxFrame(NULL, -1, "My Frame", wxDefaultPosition, wxSize(350, 200))

        import windll, win32api
        user32 = windll.module('user32')
        hIcon = user32.LoadImage(0, windll.cstring(r'myicon.ico'), 1, 0, 0, 16)
        win32api.SendMessage(frame.GetHandle(), 128, 1, hIcon)
        hIcon = user32.LoadImage(0, windll.cstring(r'myiconsmall.ico'), 1, 0, 0, 16)
        win32api.SendMessage(frame.GetHandle(), 128, 0, hIcon)

        frame.Show(TRUE)
        return TRUE

app = MyApp(0)
app.MainLoop()
##########

--

- Geoff Talvola
  Parlance Corporation
  gtalvola@NameConnector.com

_______________________________________________
wxPython-users mailing list
wxPython-users@lists.sourceforge.net
http://lists.sourceforge.net/lists/listinfo/wxpython-users

I worked on it a bit more, and came up with an improved version of the Windows small/large icon solution that doesn't require windll -- just the win32api module from the win32 extensions:

···

##########
from wxPython.wx import *
from win32api import SendMessage

class MyApp(wxApp):
    def OnInit(self):
        frame = wxFrame(NULL, -1, "My Frame", wxDefaultPosition, wxSize(350, 200))

        icon = wxIcon('myicon.ico', wxBITMAP_TYPE_ICO)
        frame.SetIcon(icon)
        icon = wxIcon('myiconsmall.ico', wxBITMAP_TYPE_ICO)
        SendMessage(frame.GetHandle(), 128, 0, icon.GetHandle())

        frame.Show(TRUE)
        return TRUE

app = MyApp(0)
app.MainLoop()
##########

--

- Geoff Talvola
  Parlance Corporation
  gtalvola@NameConnector.com

_______________________________________________
wxPython-users mailing list
wxPython-users@lists.sourceforge.net
http://lists.sourceforge.net/lists/listinfo/wxpython-users

Geoff Talvola wrote:

I worked on it a bit more, and came up with an improved version of the Windows small/large icon solution that doesn't require windll -- just the win32api module from the win32 extensions:

Unfortunately, I just noticed that the "improved" solution doesn't work properly -- if you resize the window, the small window icon instantly reverts to a shrunk-down version of the large icon. The original solution I sent using windll and avoiding wxIcon works properly.

···

--

- Geoff Talvola
  Parlance Corporation
  gtalvola@NameConnector.com

_______________________________________________
wxPython-users mailing list
wxPython-users@lists.sourceforge.net
http://lists.sourceforge.net/lists/listinfo/wxpython-users

This won't work because the icon handle will become invalid when the
(local) variable icon goes out of scope. You should make icon's lifetime
at least as long as the frame's one.

Regards,
VZ

···

On Mon, 5 Feb 2001, Geoff Talvola wrote:

        icon = wxIcon('myiconsmall.ico', wxBITMAP_TYPE_ICO)
        SendMessage(frame.GetHandle(), 128, 0, icon.GetHandle())

_______________________________________________
wxPython-users mailing list
wxPython-users@lists.sourceforge.net
http://lists.sourceforge.net/lists/listinfo/wxpython-users

Vadim Zeitlin wrote:

···

On Mon, 5 Feb 2001, Geoff Talvola wrote:

> icon = wxIcon('myiconsmall.ico', wxBITMAP_TYPE_ICO)
> SendMessage(frame.GetHandle(), 128, 0, icon.GetHandle())

This won't work because the icon handle will become invalid when the
(local) variable icon goes out of scope. You should make icon's lifetime
at least as long as the frame's one.

OK, so here's one way to do it that works (and doesn't need windll). But I noticed that the small icon doesn't look quite the same as it does using the windll version! wxIcon seems to be modifying the colors slightly or somehow editing the picture. The windll version that doesn't use wxIcon displays it properly.

I can email an example icon file to anyone who might be interested in figuring out why -- let me know if you want it. In the meantime, I'll stick with the windll technique.

##########
from wxPython.wx import *
from win32api import SendMessage

class MyApp(wxApp):
    def OnInit(self):
        frame = wxFrame(NULL, -1, "My Frame", wxDefaultPosition, wxSize(350, 200))

        self.__icon = wxIcon('myicon.ico', wxBITMAP_TYPE_ICO)
        frame.SetIcon(self.__icon)
        # Note that the small icon doesn't quite get displayed right,
        # for some reason I don't understand
        self.__iconSmall = wxIcon('myiconsmall.ico', wxBITMAP_TYPE_ICO)
        SendMessage(frame.GetHandle(), 128, 0, self.__iconSmall.GetHandle())

        frame.Show(TRUE)
        return TRUE

app = MyApp(0)
app.MainLoop()
##########

--

- Geoff Talvola
  Parlance Corporation
  gtalvola@NameConnector.com

_______________________________________________
wxPython-users mailing list
wxPython-users@lists.sourceforge.net
http://lists.sourceforge.net/lists/listinfo/wxpython-users