Click to See Complete Forum and Search --> : Problem with tray icon


Miah-Avl
March 22nd, 2006, 05:47 PM
Hello,

I am writing a Win32 app which uses a tray icon, and I can get the icon to load using the LoadImage() function fine, but not with LoadIcon/MAKEINTRESOURCE().

I want to use LoadIcon because when I moved the app to another computer, the icon did not load in the tray. I think this is because with LoadImage, you must have to have the image on your machine, and with LoadIcon/MAKEINTRESOURCE it uses a resource so you don't? Let me know if I'm wrong there.

Anyway, it's about time for some code and an explanation:

void* icon = LoadImage(NULL, "icon2.ico", IMAGE_ICON, 16, 16, LR_LOADFROMFILE);
HICON icon2 = LoadIcon(NULL, MAKEINTRESOURCE(IDI_ICON2));

tray.cbSize = sizeof(tray);
tray.uID = 100;
tray.uFlags = NIF_ICON | NIF_TIP | NIF_MESSAGE;
tray.hIcon = icon2; //TODO: Find out why this peice of poop won't work.
if(tray.hIcon == NULL)
{
MessageBox(NULL, "OMG, no icon!", "Fux0r3d!", MB_OK);
tray.hIcon = (HICON)icon;
}
tray.hWnd = wnd; // wnd is a function argument.
tray.uCallbackMessage = WM_USER;
strcpy(tray.szTip, tooltip); // Tooltip is a function argument.

Shell_NotifyIcon(NIM_ADD, &tray);

Okay, now for the explanation:

The above code is contained in a function, which takes an HWND paramater for the parent window, and a string for the tooltip. As you can see, I create an icon using two different methods, and fall back on the second when the first one fails (and fail it does). However, the second method works, and both use the same icon file.

In general, this may be because I'm having some sort of problem with MAKEINTRESOURCE(), because the second method will also fail if I attempt to load an image from a resource.

Thanks for any help anyone can provide.

Miah-Avl
March 22nd, 2006, 06:22 PM
I think I may have found the answer:

void* icon = LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON2), IMAGE_ICON, 16, 16, 0);

Unless I'm mistaken, the above code will get the instance of the app, and load the icon from the resource instead of from the file. Again, let me know if I'm wrong.

kkez
March 23rd, 2006, 09:39 AM
This is clearly stated in MSDN:
LoadIcon: Handle to an instance of the module whose executable file contains the icon to be loaded. This parameter must be NULL when a standard icon is being loaded.
For example, IDI_APPLICATION is a standard icon loaded from a windows resource dll.

And, this
void* icon = LoadImage(NULL, "icon2.ico", IMAGE_ICON, 16, 16, LR_LOADFROMFILE);
does not raise an error, but i prefer
HICON icon = (HICON)LoadImage(NULL, "icon2.ico", IMAGE_ICON, 16, 16, LR_LOADFROMFILE);

So, this code is right:
//Load an icon from a file, first parameter can be NULL
HICON icon = (HICON)LoadImage(NULL, "icon2.ico", IMAGE_ICON, 16, 16, LR_LOADFROMFILE);

//Load an icon from your executable, the first parameter must be the instance of your application.
HICON icon2 = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON2));

Miah-Avl
March 24th, 2006, 10:53 PM
So pretty much, the LoadIcon() function you posted last does the same thing as the LoadImage() function I posted in my first reply.

I am also aware that when loading a stock icon, you use a NULL instance, however, I did not want to use a stock icon, nor did I want to load from I file, I just needed to load the image from a resource.

kkez
March 25th, 2006, 06:54 AM
So pretty much, the LoadIcon() function you posted last does the same thing as the LoadImage() function I posted in my first reply.
No, the first LoadImage function (with the LR_LOADFROMFILE flag) you posted loads an icon from a file. The second one
HICON icon = LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON2), IMAGE_ICON, 16, 16, 0);
is correct, and you can achieve the same thing with the LoadIcon function i posted:
HICON icon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON2));

I am also aware that when loading a stock icon, you use a NULL instance, however, I did not want to use a stock icon, nor did I want to load from I file, I just needed to load the image from a resource.
Then why you used NULL as first parameter, if you wanted to load an icon from resources and you knew how to do it?