Hi all,
i'm trying to figure out how to use the trayicon in a program without a GUI. I want the trayicon to stay put even when you hover over it with the mouse while now it is disappearing :(
does anyone know of an easy solution so that i don't have to write the complete framework for a GUI ?
here's the code i have so far:
.586
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
include \masm32\include\shell32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\shell32.lib
IconName EQU 1000
.DATA
AppName db "TrayIcon example.",0
nope db "Not added.",0
yep db "Tray icon has been added successfully.",0
.DATA?
hInstance DWORD ?
hIcon DWORD ?
nfdat NOTIFYICONDATA <>
.CODE
start:
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke LoadIcon,hInstance,IconName
mov hIcon,eax
mov nfdat.cbSize,sizeof NOTIFYICONDATA
push hInstance
pop nfdat.hwnd
mov nfdat.uID,0
push hIcon
pop nfdat.hIcon
mov nfdat.uFlags,NIF_ICON
invoke Shell_NotifyIcon,NIM_ADD,addr nfdat
.IF eax!=TRUE
invoke MessageBox,NULL,addr nope,addr AppName,MB_ICONERROR
invoke CloseHandle,hInstance
invoke CloseHandle,hIcon
invoke ExitProcess,1
.ENDIF
invoke MessageBox,NULL,addr yep,addr AppName,MB_OK
invoke Shell_NotifyIcon,NIM_DELETE,addr nfdat
invoke CloseHandle,hInstance
invoke CloseHandle,hIcon
invoke ExitProcess,0
end start
here's the rc file:
#include "\masm32\include\resource.h"
#define IconName 1000
IconName ICON "wscorpion.ico"
and of course an icon of a white scorpion on a black background, but that doesn't really matter i think :toothy
Many Thanks in advance!
In the taskbar properties there is a checkbox that causes inactive icons to be hidden. Just uncheck it.
Paul
I tend to just create a basic window, but never show it - so you don't need to handle many messages.
white scorpion,
That is a pretty neat trick, I assembled your program and tested it because I thought I was missing the point and as it turns out, I was. Anyway the NIM_DELETE flag will tell the icon to delete itself once it gets focus. Very funny!
Paul
let me be more specific. i don't mean the icon disappears by "unused icons", and i'm also positive it doens't disappear by using the NIM_DELETE flag (yeah it does, but only when you have pressed ok on the messagebox), but the problem is that when you hover over with the mouse it just vanishes, i've tried figuring out using iczelion's tutorial (part 23) since his example doesn't have the same problem, but i can't :(
try running the program, keep the messagebox untouched and then touch the trayicon with your mouse, you will see what i mean..
Thanks anyway for the responses...
Well, now it has become a mission because I do not know why it is happening. It has to be something being triggered by the mouseover event. Pretty cool, dude!!
Paul
Hi white scorpion,
I compiled your code. The program works Ok in win98SE. The trayicon appears and after I click Ok in the messagebox, it disappears. Its gotta be something with your local settings. I suppose you use winxp
Thomas :U
Thomas,
Run the program, don't touch the message box, move the mouse arrow over the icon without clicking. Does the icon disappear?
Paul
I just tested it on Windows ME and the icon will disappear there, also.
Paul
Nop.
The icon is still there and I didn't bring the mouse even remotely near the messagebox. I hovered the mouse over the icon and even clicked it. It stayed there. I have a screenshot. I had placed the pointer on the icon but it didn't appear in the screenshot. The icon is there. I have marked it.
Thomas
[attachment deleted by admin]
Thank you Thomas
It's just a guess, but you are using hInstance as a HWND. Isn't this a bug? When the mouse is over the icon, the shell wants to send you a message and this may fail, so the shell deletes the icon.
The icon disappears on mouse over under Windows 2000. Changing nfdat.hwnd to zero did not change the behavior. Substituting NIM_SETFOCUS for NIM_DELETE did not change the behavior. Substituting NIM_MODIFY for NIM_DELETE did not change the behavior. I ran out of time trying to use an NIM_SETVERSION message to specify pre-version 5.0 behavior because the MASM32 NOTIFYICONDATAA structure does not include the required members.
Hi Michael,
It would appear that White Scorpion has stumbled upon a very interesting problem. I, also tried diffent f values without any different resulta.
Paul
Hi Paul,
Did you try running it in Ollydbg or something. You can see if something is going on while you put the mouse over the icon.
Thomas :U
That's a good idea, Thomas, I will try that later when I get up.
Paul
running it through olly doesn't show anything unusual, just as changing the handle of the window.
this is really strange, on windows 98 it works like it should, but on ME,2000 and XP it doesn't work like it should...
i'm glad i'm not the only one having this problem (otherwise i would have felt stupid :lol), but this makes the challenge of solving it a lot bigger :8)
i'm still trying about everything i can think of, but the only way i can get it to work is to create a thread with an infinite loop sending the message to show the icon... Not a clean solution.....
<edit> another interesting thing, run the program and without touching the messagebox kill the program. this will still keep the icon in the traybar until you touch it with your mousepointer. it really looks like the icon is living it's own life....</edit>
solved !!!
the NOTIFYICONDATA's hWnd should be a valid window handle !!!
the following code works at my place:
---
.
.
.
invoke GetDesktopWindow
mov hDesk,eax
.
.
.
push hDesk
pop nfdat.hwnd
.
.
.
---
This prevents the trayicon from dissappearing. :clap: :)
shantanu,
That is a very good solution. I don't think I have ever done that before, but the ability to get the handle to the desktop is a good thing to know.
Thank you,
Paul
Quote from: shantanu_gadgil on April 23, 2005, 02:56:40 PM
solved !!!
the NOTIFYICONDATA's hWnd should be a valid window handle !!!
the following code works at my place:
---
.
.
.
invoke GetDesktopWindow
mov hDesk,eax
.
.
.
push hDesk
pop nfdat.hwnd
.
.
.
---
This prevents the trayicon from dissappearing. :clap: :)
Yes, that works under Windows 2000 :U
I had been assuming that the handle for the desktop window would always be zero, and that was why I tried a handle value of zero. But in my tests just now the handle returned by GetDesktopWindow was 1000Ah. Handle zero seems to always work for a message box, so what is it?
Hey,
That was what I was going to post. I just got Window 2003 Enterprise Server. I tested and found the icon disappearing. I put the handle from GetDesktopWindow and it worked
Thomas :U
An optimization tip:
instead of
invoke PROCEDURE
mov MEM,eax
...
push MEM
pop STRUCT.MEM
put
invoke PROCEDURE
mov STRUCT.MEM,eax
wow!!! perfect solution!!!!
I never thought of it but it works like a charm :lol:
Thanks guys for all the support and help :bg
Quote from: MichaelW on April 23, 2005, 05:45:49 PM
I had been assuming that the handle for the desktop window would always be zero, and that was why I tried a handle value of zero. But in my tests just now the handle returned by GetDesktopWindow was 1000Ah. Handle zero seems to always work for a message box, so what is it?
I doubt NULL is a valid handle for anything. However, it does work for messagebox, which means there is either some special handling, or I suppose it could be the handle of the desktop container(?) ie. the window that contains the desktop(s).
My experience with invoking a messagebox with a handle of zero was that it did NOT become modal - it shows up as a separate entity on the taskbar. (But it does work without error.) Replace that zero with hWnd, and it becomes modal; meaning there is no additional entry in the taskbar - the messagebox is now "part" of the source application.
From the MASM32 windows.inc (1.27d BETA):
HWND_DESKTOP equ 0
From winuser.h in the PSDK:
/*
* Special value for CreateWindow, et al.
*/
#define HWND_DESKTOP ((HWND)0)
Just encountered the same problem (on windows 2003) and found that if I don't put anything in hwnd (just leave default value, which ever it is) that icon is not disappearing, so if someone else could also check this to confirm that this is actually working... :)