system tray icon of our app is invisible on windows 2008

Hello
We have 32 bit binary which runs the following  C code, icon is visible in system tray of windows 2003 machine. But Win2008 machine does not display this icon.

==========================================
NOTIFYICONDATA      tnd;
HICON                  hIcon;
hIcon = (HICON)LoadImage(G_hInst, MAKEINTRESOURCE(wIconId), IMAGE_ICON,
      GetSystemMetrics(SM_CXSMICON),
                        GetSystemMetrics(SM_CYSMICON), 0); // 16x16 icon

    tnd.cbSize = sizeof(NOTIFYICONDATA);
    tnd.hWnd = G_hWnd;
    tnd.uID = 1;
    tnd.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP;
    tnd.uCallbackMessage= MYWM_NOTIFYICON;
    tnd.hIcon= hIcon;
    res = Shell_NotifyIcon(dwMessage, &tnd);

==================================================

Please let me know, if i need to make some code changes on the above code as per win 2008 api framework

Sham
 
mohet01Asked:
Who is Participating?
 
tampnicConnect With a Mentor Commented:
That is what I was going to attempt. It looks like Microsoft do not support it any more. From what I read its virtually impossible for a service to manipulate the GUI in any way now.

I did a bit of research and it looks like the best way to have a notification icon for a service is to have a completely separate process running which manages the icon. You can then choose an Inter-Process Communication (IPC) mechanism for the icon-manager process and your service to talk to each other. Possible choices for IPC could be the clipboard, network sockets, DDE, RPC, named pipes, etc etc. Personally I think a named pipe would work well for this situation http://msdn.microsoft.com/en-us/library/windows/desktop/aa365590(v=vs.85).aspx

E.g. if the service is stopping it sends an IPC message to the icon-manager process which changes or removes the icon. If the icon is clicked it sends an IPC message to the service to react to the click, or starts the service if it isn't running already.

Cheers,
   Chris
0
 
tampnicCommented:
Is this just a display issue? Does your icon resource contain multiple pictures at different sizes? A Windows icon usually needs multiple versions for different display settings e.g. 16x16, 32x32,48x48 and each size requires versions for colour depths 256colour, "high colour" and "true colour"? I would try playing with the display settings on your Win2008 machine to see if the icon appears at certain colour depths.

If this turns out to be the problem, you can use a program such as IcoFX to convert your icons or bitmaps into Windows icons with all the formats for different display settings included.

Cheers,
   Chris
0
 
nonubikCommented:
Have you checked the hIcon variable after the call to LoadImage?

If it is NULL, then it's a loading problem. If it is not NULL, it's another issue.
0
Cloud Class® Course: CompTIA Healthcare IT Tech

This course will help prep you to earn the CompTIA Healthcare IT Technician certification showing that you have the knowledge and skills needed to succeed in installing, managing, and troubleshooting IT systems in medical and clinical settings.

 
mohet01Author Commented:
Hello Chris
Above code is working fine with windows 2003
I dont know why is is not working in win2008
Sham
0
 
mohet01Author Commented:
Other icons from other aplications(Microsoft) are being displayed on systray
0
 
tampnicCommented:
Are the colour settings of the display exactly the same on both the win2003 and win2008 machine? Specifically I am wondering if the same colour depth is used e.g. "High Color", "True Color", "256 Color". The Microsoft apps will definitely have all the necessary bitmaps in their icon resources, I'm not sure if your application icon does.

Q1) Did you try changing the display settings on the Win2008 machine to see if the icon appears?

Q2) Is there a placeholder in the system tray where your icon should be, i.e. an invisible rectangle that your app responds to when you click it?

Another possibility is that Win 2008 thinks the icon is inactive. Right-click in the system tray or on the task bar - you should get the Taskbar and Start Menu Properties dialog. Look for the Notification tab, make sure the "hide inactive icons" checkbox is not ticked. On Windows 7 this option can be accessed through the "Customise" option in the system tray.

Cheers,
  Chris
0
 
mohet01Author Commented:
Q! answer) No
Q2 Answer) you need to answer this from the code given

Whetver properties that we are giving to that icon is shown in the code.
0
 
tampnicCommented:
I'm 80% sure the code is OK. One thing I would do to the code though is make sure the tnd structure is initialised before using it. Add the line SecureZeroMemory(&tnd,sizeof(NOTIFYICONDATA)); to the code as follows

NOTIFYICONDATA      tnd;
HICON                  hIcon;
hIcon = (HICON)LoadImage(G_hInst, MAKEINTRESOURCE(wIconId), IMAGE_ICON, 
      GetSystemMetrics(SM_CXSMICON),
                        GetSystemMetrics(SM_CYSMICON), 0); // 16x16 icon

if (hIcon != NULL ) {
    SecureZeroMemory(&tnd,sizeof(NOTIFYICONDATA));
    tnd.cbSize = sizeof(NOTIFYICONDATA); 
    tnd.hWnd = G_hWnd; 
    tnd.uID = 1; 
    tnd.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP; 
    tnd.uCallbackMessage= MYWM_NOTIFYICON; 
    tnd.hIcon= hIcon; 
    res = Shell_NotifyIcon(dwMessage, &tnd);
} else {
    // display or log an error message here
}

Open in new window


 The issue might be in your icon file though. Its impossible to tell from the code what your icon file contains. Follow previous instructions so I can help you - there are multiple possible solutions and I cannot diagnose the problem if you haven't changed the display settings on the Win2008 box to rule out icon file issues.

The icon file compiled into your executable should contain multiple bitmaps at various colour depths. The operating system selects the appropriate bitmap to display depending on what the user has chosen in the display settings of their video card/monitor. Sometimes the operating system can't find a suitable bitmap and displays nothing, or exhibits an empty space where your icon should be.

If you are using Visual Studio, go into the resource editor and find the icon. Tell me how many bitmaps the icon contains and at what sizes and color depths, e.g a windows application icon would normally contain at least nine bitmaps - 16x16  32x32 in 4bit colours, 16x16 32x32 48x48 in 8bit colours, 16x16 32x32 48x48 256x256 in 32bit colours.

The issue might be in the operating system settings too, follow the instructions in my last post to turn off "hide inactive icons" - to make sure the operating system is not filtering your icon out of the display.

Cheers,
  Chris
0
 
tampnicCommented:
As a side note, the recommendation is not to use window handles to identify icons for the notification area but to use GUIDs for win7 and beyond. See http://msdn.microsoft.com/en-us/library/windows/desktop/ee330740(v=vs.85).aspx for more details.

Cheers,
   Chris
0
 
mohet01Author Commented:
Hello Chris
I will try your inputs on Monday
Sham
0
 
mohet01Author Commented:
chris,
It will also help me, if u can tell the meaning of the code that I posted.
I mean each line of code

Sham
0
 
tampnicCommented:
I added comments into the code which should explain to you what is going on.

// declare variables
NOTIFYICONDATA      tnd; // a structure containing variables used to specify the behaviour of a notification icon
HICON                  hIcon; // handle used to reference an icon


// Find the icon with resource id "wIconId" (this code fragment doesn't show what wIconId was set to)
// Because an instance is specified this must be looking for the icon in the resources compiled into the executable
hIcon = (HICON)LoadImage(G_hInst, MAKEINTRESOURCE(wIconId), IMAGE_ICON, 
      GetSystemMetrics(SM_CXSMICON),
                        GetSystemMetrics(SM_CYSMICON), 0); // 16x16 icon

// only continue if LoadImage() succeeded and hIcon is valid
if (hIcon != NULL ) {
    // make sure the memory allocated for the tnd structure is initialised
    SecureZeroMemory(&tnd,sizeof(NOTIFYICONDATA));
    // tell  Shell_NotifyIcon() the size of the structure being passed into it
    tnd.cbSize = sizeof(NOTIFYICONDATA); 
    // next two lines tell Windows to identify the notification icon by application window handle and ID
    tnd.hWnd = G_hWnd; 
    tnd.uID = 1;
    // tell Shell_NotifyIcon() we will be setting the callback message, the icon, and the tooltip when we call it
    tnd.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP; 
    // tell Shell_NotifyIcon() what windows message to send to the application when the notification icon is clicked
    // MYWM_NOTIFYICON should have been set to something like WM_USER+1 elsewhere in your code
    // Somewhere else in your code the application will have code to respond to this message
    tnd.uCallbackMessage= MYWM_NOTIFYICON; 
    // tell  Shell_NotifyIcon() the icon handle to use
    tnd.hIcon= hIcon; 
    // now call Shell_NotifyIcon() passing in the information we just set up
    // We said we were going to set the tooltip but tnd.szTip is not set in this code! 
    // However we zeroed the memory so the tooltip should be interpreted as an empty string
    // The code fragment does not show where dwMessage is set but I assume it is set to NIM_ADD at this point
    res = Shell_NotifyIcon(dwMessage, &tnd);
} else {
    // display or log an error message here
}

Open in new window


Cheers,
   Chris
0
 
CSecurityCommented:
compile your code; using Windows 7's SDK
0
 
mohet01Author Commented:
Oh different suggestions here
0
 
CSecurityCommented:
my suggestion is based on my experience
I had same problem about system tray in windows 7 and compiled my code in windows 7's SDK and problem solved
As you're using windows server 2008, it's same as windows 7. compile it and see the result

Regards
0
 
tampnicCommented:
Well I compiled and ran the code on Windows 7 using the latest SDK and it didn't put an icon into the system tray unless I initialised the tnd structure with SecureZeromemory() first. Probably due to the fact the code says it will set the tooltip but doesn't, so an invalid pointer value is sitting in tnd.szTip. That's why i recommended initialising the structure.

Cheers,
   Chris
0
 
mohet01Author Commented:
We have tried you recommendations, still we do not see the icon.

Only thing we missed we did not use GUID

Sham
0
 
tampnicCommented:
If the icon file is fully populated with bitmaps at each size and colour depth, and "hide inactive icons" is turned off, and the structure is initialised before being used, and it still doesn't work then I'm stumped!

The code fragment I supplied in a previous post works fine in a test application I developed and ran on Win7, using Visual Studio 10 and v7.0A SDK. AFAICT the main differences in your situation would be the icon file or operating system settings. You have checked those.

I'm clutching at straws now ...

Q1) Does the code definitely get called in your application? To check this, set a breakpoint in the function and run the app through the debugger? If your application doesn't stop at the breakpoint then the code is not being called for some reason.

Q2) Is G_hWnd definitely set to the application main window handle when your function is called? You might want to check the value of G_hWnd in the debugger at the line "tnd.hWnd = G_hWnd; " If its NULL, 0, or INVALID_HANDLE this would be a problem!

Cheers,
   Chris
0
 
CSecurityCommented:
forget using system tray icon :trollface: =D
0
 
mohet01Author Commented:
hello CSec
I did not get your point
What is the meaning of ":trollface: =D "?

Sham
0
 
mohet01Author Commented:
One more point is, this is 32 bit binary running on wow64 in win 2008
0
 
mohet01Author Commented:
Hello CSec
We still see the problem.

1)
 This is 32 bit binary running on wow64 in win 2008.
 So, this was working fine in win 2003
2)
What is the necessityof, compiling the code using Windows 7's SDK?
How different it is from win2003 SDK?

3)
I did not get you, when you said: "forget using system tray icon :trollface: =D "
Wha tis the meaning o this statement?



Sham
0
 
mohet01Author Commented:
Hello
I have one more interesting point.
If i run the above code building in win2003 as stand alone module, it is working fine on win2008.

This module is started as thread(_beginthread) in our app.
So We are checking, What is the problem?
Sham
0
 
tampnicCommented:
The problem is probably to do with the window handle. I am guessing that G_hWnd is a global variable, so any code accessing that value from a thread should be made thread-safe. Wrap any reading or writing of the global variable in a critical section, or make sure accesses are synchronised explicitly using a mutex/semaphore. The following link might help ... http://www.codeproject.com/KB/cpp/Thread_Syncronization.aspx

Cheers,
    Chris

N.B. "Trollface" - Its CSecurity telling us he is making a joke by putting on his troll face! http://en.wikipedia.org/wiki/Troll_(Internet)
0
 
tampnicCommented:
I added some error handling into your code to display message boxes at run-time if an obvious error occurs.

 
// declare variables
NOTIFYICONDATA	tnd; // a structure containing variables used to specify the behaviour of a notification icon
HICON			hIcon; // handle used to reference an icon


// Find the icon
hIcon = (HICON)LoadImage(G_hInst, MAKEINTRESOURCE(wIconId), IMAGE_ICON, 
      GetSystemMetrics(SM_CXSMICON),
                        GetSystemMetrics(SM_CYSMICON), 0); // 16x16 icon

// only continue if LoadImage() succeeded and hIcon is valid
if (hIcon != NULL ) {
    // make sure the memory allocated for the tnd structure is initialised
    SecureZeroMemory(&tnd,sizeof(NOTIFYICONDATA));
    // tell  Shell_NotifyIcon() the size of the structure being passed into it
    tnd.cbSize = sizeof(NOTIFYICONDATA); 

    // next two lines tell Windows to identify the notification icon by application window handle and ID
    if ( IsWindow(G_hWnd) ) {
		tnd.hWnd = G_hWnd; 
		tnd.uID = 1;
	} else {
		MessageBox(nullptr, _T("Window handle variable G_hWnd does not refer to a real window"), _T("Error"), MB_OK|MB_ICONSTOP); 
	}
    // tell Shell_NotifyIcon() we will be setting the callback message and the icon when we call it
    tnd.uFlags = NIF_MESSAGE|NIF_ICON; 
    // tell Shell_NotifyIcon() what windows message to send to the application when the notification icon is clicked
    tnd.uCallbackMessage= MYWM_NOTIFYICON; 
    // tell  Shell_NotifyIcon() the icon handle to use
    tnd.hIcon= hIcon; 
    // now call Shell_NotifyIcon() passing in the information we just set up
    // The code fragment does not show where dwMessage is set but I assume it is set to NIM_ADD at this point
    res = Shell_NotifyIcon(dwMessage, &tnd);
} else {
    // display or log an error message as LoadImage() failed
	DWORD dwError = GetLastError();
	LPTSTR lpMsgBuf = NULL;
	// lookup the messsage string associated with the error code in the operating system
	FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,NULL,dwError,0,(LPTSTR)&lpMsgBuf,0,NULL);
  
	if ( lpMsgBuf ) {
		// Display the error message
		MessageBox(nullptr, (LPTSTR)lpMsgBuf, TEXT("Error"), MB_OK|MB_ICONSTOP); 
		LocalFree(lpMsgBuf);
	}
}

Open in new window


Trying the changes out may help diagnose the problem. I didn't wrap the global variables in any synchronisation method as the technique you choose needs to be decided by yourself and implemented in *every* piece of code where the variables are written to or read.

Cheers,
   Chris
0
 
tampnicCommented:
Also , things like creating a notification icon can be done in the main process and don't benefit from threading. I would suggest creating the notification icon in the main process just before the thread is spawned, and responding to the thread ending by removing the notification icon.

When designing software architecture if I come across a situation which looks like it could be accomplished with threading, my first thought is "how can I avoid multi-threading". It rarely gives the benefits people think it will and can introduce horrible complexity to basically simple applications. There are occasional situations where multi-threading is the correct way to go, but I don't follow that path until I have looked down all the others first!

Cheers,
    Chris
0
 
mohet01Author Commented:
Hello Chris
We are getting this message
"Window handle variable G_hWnd does not refer to a real window'
Sham
0
 
tampnicCommented:
That is why your code is not working then. We have a better "handle" on the problem now :-)

G_hWnd is not set correctly before your code has been called. Reasons could be ....

1) A variable access issue. See my comments in the previous post regarding synchronising access  to global variables in multi-threaded code.
2) The thread is running before the window has been created.
3) The code which sets G_hWnd has not been called yet.
4) The thread which sets G_hWnd is lagging behind the thread which uses the variable - could be a million reasons why!

Its very important to maintain synchronisation objects in multi-threaded code, so that values are accessed when they are valid and not before. Also synchronisation prevents one thread changing a value while another thread is reading the value.

Cheers,
   Chris
0
 
mohet01Author Commented:
It is the same thread that is printing the above error and the which is creating G_hWnd
One good news is, we came to know that, we are not coming out of below call.
I mean, if i display the debug msg after this call, it does not print.


G_hWnd=CreateWindow(NtfSubWindowClassName,
                                "notification",
                           WS_OVERLAPPEDWINDOW,
                    CW_USEDEFAULT,
                    CW_USEDEFAULT,
                    CW_USEDEFAULT,
                    CW_USEDEFAULT,
                    (HWND)NULL,
                    (HMENU)NULL,
                    //(HANDLE)hInst,
                              (HANDLE)G_hInst,
                    (LPSTR)NULL);


Can you please let us know, why?

here
CW_USEDEFAULT is 0
G_hInst is not NULL

Sham
0
 
mohet01Author Commented:
Hello Chris
may be i will check,
what is the thread# that creates G-hWnd?
and
What is the thread# that uses as below
 if ( IsWindow(G_hWnd) ) {  
                tnd.hWnd = G_hWnd;


Only contention could be with G_hWnd but not with G_hInst as per the code placed in my question, correct?


Sham
0
 
tampnicCommented:
G_hInst is not a problem in the original code fragment because it is used by LoadImage() successfully. Therefore it must have been set before the LoadImage() call is made..

When you say you place a debug msg after the CreateWindow() call and no message appears, it sounds like the CreateWindow() call is never performed. Is this code in a different function to the code fragment you supplied in your original question? I would need to see more of the code to understand why this call is not made. Place a breakpoint on the CreateWindow() line and run the application in debug mode; if the code never stops at your breakpoint then your function is not called. If it does stop, check the call stack and make sure G_hInst has been set before CreateWindow() was attempted.

Something which might be an issue, might not be .... why is G_hInst cast to (HANDLE)G_hInst in the CreateWindow() call? CreateWindow() expects a HINSTANCE  at this point. Most handles resolve down to integers so its probably just a coding preference and doesn't make a difference, but personally I would remove it and use the code below just in case.

G_hWnd=CreateWindow(NtfSubWindowClassName,
                                "notification",
                           WS_OVERLAPPEDWINDOW,
                    CW_USEDEFAULT,
                    CW_USEDEFAULT,
                    CW_USEDEFAULT,
                    CW_USEDEFAULT,
                    (HWND)NULL,
                    (HMENU)NULL,
                    //(HANDLE)hInst,
                    G_hInst,
                    (LPSTR)NULL);

Cheers,
    Chris
0
 
mohet01Author Commented:
Hello
I am attaching the code which has 3 functions from a same file
TrayMessage() //which actually shows icon
NtfSubWndProc() //Event handlingfunction andwe enter into "default:" casewhich invokes Traymessage(), becasue the messg is "TaskbarCreated"
ntf_thread_proc() // this is invoked using _beginthread(), NtfSubWndProc() is registered from here

Yes, If i place a debug statement exactly before Createwindow() it is displaying.

As per my observation and conversation, I feel G_hWnd is being deadloacked by Traymessage() and ntf_thread_proc() despite they shown as single thread, Becasue RegisterClass(&wc)  invoked from ntf_thread_proc() makes NtfSubWndProc() run parallely with ntf_thread_proc() code where createwindow() is invoked in next line after registerclass(&wc). am i correct?



Sham


Sham
 code.c
0
 
tampnicCommented:
I just had a read through "How To Create Windows in a Multithreaded Application" http://support.microsoft.com/kb/90975

There are various different steps you can try next.

If you are creating the main window of the application ...
You should do this in the main process, not on a separate thread. To do otherwise is possible, but is asking for synchronisation issues! Redesign the code is my recommendation.

For child windows ...
One way is to prompt the main process from your thread that you need a window creating. From ntf_thread_proc(), use PostMessage() to send a user-defined message to the main window. Wait until the window is created, then carry on. The main window's message procedure react's to your message by calling CreateWindow(). You can use the lParam of the message to communicate the window class you want to create.

A quicker thing to try. You should pass the parent window handle in your CreateWindow() call. If that doesn't unblock CreateWindow() then try calling AttachThreadInput() to join the message queues of the thread calling CreateWindow() and the thread where NtfSubWndProc resides.

Cheers,
  Chris
0
 
mohet01Author Commented:
hello chris
I did not understand the code change
First of all why did this work in win 2003?
can u provide the code change?
Sham
0
 
mohet01Author Commented:
what exactly is the cause of the message "Window handle variable G_hWnd does not refer to a real window"
0
 
tampnicCommented:
The cause of the message "Window handle variable G_hWnd does not refer to a real window" is because "IsWindow(G_hWnd)" returns FALSE. IsWindow() is a standard win32 API call. The operating system does not think the windows handle is valid at that point in time. The invalid window handle is passed to Shell_NotifyIcon() ... Shell_NotifyIcon must validate the handle and choose not to display the icon.

Creating windows in a separate thread to the main process is usually a very bad idea. It introduces synchronisation issues for variables and also issues with message queues, often causing deadlocks. If it was me, I would redesign the application to not create the window in the spawned thread, wrap global variable accesses in critical sections, and use a semaphore to flag when a global variable has been initialised. I did outline a technique for creating windows in the main process at the request of a thread using PostMessage(). Its a sufficiently large code change I would expect you to "hire me" from my profile page if I was going to write the code for you.

What particular difference between win2003 and win2008 has caused this unexpected behaviour, I don't know. When an unrecommended practice is attempted, then you are more likely to run into differences between operating system versions.

Cheers,
    Chris

0
 
mohet01Author Commented:
IsWindow(G_hWnd)" returns FALSE
This is obvious
But why do you think G_hWnd, Is it becasue createwindow() was not called before this check?
Sham
0
 
mohet01Author Commented:
If this is the cause, How do i synchronzie this G_hWnd?
Can you give the code snippet?
0
 
tampnicCommented:
It could be because CreateWindow() has not been called yet, or it could be that CreateWindow() has locked up (probably when trying to start the message queue for the window). As it looks like there are no synchronisation techniques being used, its difficult to tell. Its not just a snippet of code to make the application properly thread-safe. It would also require a full copy of the source code to check all code paths.

A hack might be to try and force the message pump of the main process to continue while the thread is executing, by using PostMessage() to send a dummy message into the main process. That has been known to prevent CreateWindow() from freezing. However the fact remains that your application does not follow recommended Windows practice - all windows should be created in the main process and never from a thread.

Cheers,
   Chris
0
 
mohet01Author Commented:
Do you think we require sncronisation between createwindow() and using that G_hWnd in callback of RegisterClass(&wc), becasue it is running in same thread

am thinking of sleeping for some time before using G_hWnd and check the behaviour

"all windows should be created in the main process and never from a thread", Canu provide resource link on this?


0
 
mohet01Author Commented:
your msdn link says the below:
"
In a multithreaded application, any thread can call the CreateWindow() API to create a window. There are no restrictions on which thread(s) can create windows.

It is important to note that the message loop and window procedure for the window must be in the thread that created the window. If a different thread creates the window, the window won't get messages from DispatchMessage(), but will get messages from other sources. Therefore, the window will appear but won't show activation or repaint, cannot be moved, won't receive mouse messages, and so on.

"

createwindow() and NtfSubWndProc() for that windows in same thread, so w are following this.
0
 
mohet01Author Commented:
OK.
I have checked, if it is syncronisation issue, by grab/release.
This is not syncronisation issue
CreateWindow() is hanging.

G_hWnd=CreateWindow(NtfSubWindowClassName,
              "notification",
            WS_OVERLAPPEDWINDOW,
                    CW_USEDEFAULT,
                    CW_USEDEFAULT,
                    CW_USEDEFAULT,
                    CW_USEDEFAULT,
                    (HWND)NULL,
                    (HMENU)NULL,
                    //(HANDLE)hInst,
      (HANDLE)G_hInst,
                    (LPSTR)NULL);

Can you help me know why it is hanging?

Sham
0
 
mohet01Author Commented:
Please remember this is 32 bt binary runing on 2008 machine
0
 
mohet01Author Commented:
Hello
i created the dump and analyzed

this is what i see in debugdiag analysis
 
Error The following threads(10) in dsmMonitor_111221_134639.dmp are displaying a message box. The call to display the message box originated from user32!DialogBox2+222.
( 10 )
9.09% of threads blocked
 Server-side applications should not have any UI elements since they are supposed to run without any user intervention. Moreover, service applications run in non-interactive desktops, so no one can actually see the message box and dismiss it. This causes the application to hang.



stack is:

Function   Source
user32!NtUserWaitMessage+15    
user32!DialogBox2+222    
user32!InternalDialogBox+e5    
user32!SoftModalMessageBox+757    
user32!MessageBoxWorker+269    
user32!MessageBoxTimeoutW+52    
user32!MessageBoxTimeoutA+76    
user32!MessageBoxExA+1b    
user32!MessageBoxA+18    
dsmMonitor+478d    
dsmMonitor+5228    
user32!InternalCallWinProc+23    
user32!UserCallWinProcCheckWow+109    
user32!DispatchClientMessage+e0    
user32!__fnINOUTLPPOINT5+2e    
ntdll!KiUserCallbackDispatcher+2e    
0x00971cb0    
user32!_CreateWindowEx+210    
user32!CreateWindowExA+33    
dsmMonitor+5542    
msvcr71!_threadstart+6c    
kernel32!BaseThreadInitThunk+e    
ntdll!__RtlUserThreadStart+70    
ntdll!_RtlUserThreadStart+1b


Sham


Please follow up with vendor Microsoft Corporation for problem resolution concerning the following file: C:\Windows\SysWOW64\user32.dll.
0
 
tampnicCommented:
By creating all windows in the main process your application requires one message pump - therefore eliminating in one stroke any issues with message synchronisation amongst user-interface elements (like the one we are probably experiencing here).

In the old days on Windows 3 with co-operative multitasking it was sometimes necessary to maintain a few message pumps in a system to keep the UI responsive. Since Windows 95 and pre-emptive multitasking this is not necessary any more, so the less message pumps in an application the better to reduce risk of bugs and deadlocks.

Your dump analysis thinks that the thread is a service, as it has no message pump.

I will repeat for the last time - create all windows in the main process and the problems you are having will disappear. To do this, implement a custom Windows message e.g. #define WM_MYCREATEWIN WM_USER+100; In the thread, when you want to create the window use PostMessage() to send this message to the main process. Write a handler in the main process message pump to respond to WM_MYCREATEWIN by creating the window and setting G_hWnd.

Cheers,
   Chris

0
 
mohet01Author Commented:
Hello Chris
I understood your point in making parent process run createwindow() and set to G_hWnd.

But i would request you to help me in writing the postmessage() to main process and responding back from main process after creating window in main process

Attached file(main_process.c)  shows how we create ntf_thread_proc
code.c(already attached) has the ntf_thread_proc implementation.

I donot know, How to increase the points for this query?

Sham






0
 
mohet01Author Commented:
0
 
mohet01Author Commented:
I think you are telliing something like this:

#define WM_MYNEWMESSAGE (WM_USER+100)  // in main process code
...
// In thread:
::PostMessage(hWnd, WM_MYNEWMESSAGE, wParam, lParam);
...
// In main process
ON_MESSAGE(WM_MYNEWMESSAGE, OnMyNewMessage)
...
LRESULT CMyWnd::OnMyNewMessage(WPARAM, LPARAP)
{
  // G_hWnd=createwindow()
  return 0;
}


Correct?
0
 
tampnicCommented:
Yes, your last comment is on the right path.

I would pass the handle of the main window into the thread function as a parameter when the thread is created. That means you must make sure the main window has been created before creating the thread.

To make the code more recyclable, I would use the lParam of the new message to point to a string containing the window class you want to create. That way in the message procedure of your main process you can react to the message by creating a window of the class requested. Other threads which might want to create windows of different class re-use the handler in the main process.

Cheers,
   Chris
0
 
mohet01Author Commented:
Am still not clear, How do i receive the message in main process and run the CreateWindow(), Becasue that should also run as a thread to be ready for the message
0
 
tampnicCommented:
The main process is not a light-weight thread, its a fully-fledged process. It is time-sliced onto the processor with your thread so appears to run at the same time. You need to synchronise these two pieces of code somehow.

One way is to use an event object http://msdn.microsoft.com/en-us/library/windows/desktop/ms686915(v=VS.85).aspx. Create the Event before creating the thread. The thread code runs PostMessage() then uses WaitForSingleObject() on the Event. The main process message handler signals the Event after creating the window and setting G_hWnd, so your thread then proceeds to do work.

Another way ... In your thread code post the message, then use FindWindow() in a loop until you detect that the main process has handled your message and created the window, then you can continue work in the thread. I recommend using an Event object personally.

What is the name of the message procedure you specify when you create the main window of the application? That's where the message handler code should go. Exactly what type of application is this? Its not supposed to be a Windows service is it? Is it using MFC to create the main window, if it is then use an MFC macro e.g. ON_MESSAGE(WM_MYNEWMESSAGE, OnMyNewMessage)? Otherwise the main message pump is specified when you CreateWindow() with a registered windows class in the application's InitInstance().

Cheers,
   Chris
0
 
mohet01Author Commented:
What is the name of the message procedure you specify when you create the main window of the application?
This is not the major GUI application. There is no main window.
Only one time createwindow() is called in thread(ntf_thread_proc) tries creating systray icon in taskbar.
So, your first way would not work.

Second way, am not clear
 


Sham
0
 
mohet01Author Commented:
This is windows console project.
And am still not clear, why createwindow() call in a launched thread hangs? Any proper reason?

Sham


0
 
mohet01Author Commented:
I have also heard that processing msg using msg handler for that window has been changed in 2008? is that so?
0
 
tampnicCommented:
There is some good information similar to your situation in the this thread on MSDN

http://social.msdn.microsoft.com/Forums/en/vcgeneral/thread/259d1ec7-f5fc-4189-9d2e-ae080d697e1c

Advice seems to be not to multi-thread user-interface objects.

I think the CreateWindow() is hanging because there is a deadlock between the thread and the window procedure supplied to the call. One of the function calls in the window procedure must be trying to access the message pump of the thread which created the window, which isn't running yet. Have you tried putting breakpoints into the "switch ... default:" section of NtfSubWndProc() to see if that code is ever accessed?

Cheers,
  Chris
0
 
tampnicCommented:
Or try handling WM_CREATE separately in NtfSubWndProc(), and then post a message to the window after CreateWindow() is finished so that the "switch ... default" section is performed. At the moment your window procedure performs "default" operations when WM_CREATE is passed to it. I think it might be deadlocking in NtfSubWndProc() when WM_CREATE is being processed.

Cheers,
    Chris
0
 
tampnicCommented:
From MSDN - http://msdn.microsoft.com/en-us/library/windows/desktop/ms632619(v=vs.85).aspx

WM_CREATE
Sent when an application requests that a window be created by calling the CreateWindowEx or CreateWindow function. (The message is sent before the function returns.)

So .... your application calls CreateWindow(). CreateWindow() calls NtfSubWndProc() with a WM_CREATE message before it returns so at this point in time G_hWnd is not initialised. NtfSubWndProc() doesn't handle WM_CREATE explicitly so the "default" section of code runs. This section requires G_hWnd to be initialised, but it isn't because CreateWindow() hasn't returned yet.

Cheers,
   Chris
0
 
tampnicCommented:
Damn! I just noticed that you are handling WM_CREATE! Sorry about that. The problem might be with RegisterWindowMessage() in the WM_CREATE section, try setting breakpoints in the WM_CREATE section of NtfSubWndProc() and stepping through the code to see how far you get before it hangs.

Cheers,
   Chris
0
 
tampnicCommented:
Another thing to try is to call GetConsoleWindow() in the main process. Use the hWnd returned from this as the parent window value when you call CreateWindow(). This might allow CreateWindow() to proceed. At the moment I'm only guessing why CreateWindow() is freezing.

As an aside ...
RegisterWindowMessage(TEXT("TaskbarCreated"));
should contain a GUID or some other unique hash in the name for safety sake. You are writing into a  system global string table with this call so entries should be unique to your application, and "TaskbarCreated" could potentially be used by other installed apps.

Cheers,
   Chris
0
 
mohet01Author Commented:
Hello Chris

Here is my observation for your queires in the attached file(obs.txt)
So,
traymessage() is getting called from ntf_thread_proc() in win2003
traymessage() is not getting called from ntf_thread_proc()  because createwindow() is hanged in win 2008

 obs.txt


Sham
 obs.txt
0
 
mohet01Author Commented:
AS per my previous update, why createwindow() is hanging?
I think this has nothing to do with message handler(NtfSubWndProc)

0
 
tampnicCommented:
From the trace you supplied the code is stopping inside the WM_CREATE handler of NtfSubWndProc(). the "Out WM_Create" trace message never appears to show we left the handler. Run the code in debug mode with a breakpoint set on this line
s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated"));

Open in new window

. Then step through the code one line at a time and see what happens.

Cheers,
    chris
0
 
mohet01Author Commented:
Hello Chris
My apologies.
trace is as shown below in win 2008

ntf_thread_proc            : Before calling CreateWindow()
NtfSubWndProc              : In Default
 NtfSubWndProc              : In Default with messg in else part: 24
 NtfSubWndProc              : Out Default
NtfSubWndProc              : In Default
 NtfSubWndProc              : In Default with messg in else part: 81
 NtfSubWndProc              : Out Default
 NtfSubWndProc              : In Default
 NtfSubWndProc              : In Default with messg in else part: 83
 NtfSubWndProc              : Out Default
NtfSubWndProc              : In WM_Create
 NtfSubWndProc              : In WM_Create with s_uTaskbarRestart : c081
 NtfSubWndProc              : Out WM_Create
ntf_thread_proc            : After Calling CreateWindow()
ntf_thread_proc            : Calling TrayMessage()

But still i dont see icon

Sham
0
 
mohet01Author Commented:
Hello Chris
I further analysed traymessage().
I think we are close to the problem now, I see that shell_notifyicon() is failing in win 2008
Please find the attached(obs2.txt) which shows shell_notifyicon() failing.

Can you please let me know, is there is a way to resolve this failure?
I also see msdn talking something about it


Sham


obs2.txt
0
 
mohet01Author Commented:
Ignore nstatus value in te attached file it is product specific
0
 
tampnicCommented:
Try changing the size of the NOTIFYICONDATA structure member cbSize. Instead of
tnd.cbSize = sizeof(NOTIFYICONDATA);

Open in new window

try
tnd.cbSize = NOTIFYICONDATA_V3_SIZE;

Open in new window


This has been known to make balloon tips work on systems that didn't before, might be worth a try here! If that doesn't work first time try setting it to NOTIFYICONDATA_V2_SIZE and having another go. If either of these fix the problem you will have to start getting the exact version of shell32.dll and changing the structure size according to the version of shell32.dll installed on the target systems.

I found this interesting article http://stefansundin.com/blog/68 where the guy works around the error by re-trying to add the icon multiple times with the same code and it eventually works!

Cheers,
    Chris

Cheers,
   Chris
0
 
mohet01Author Commented:
One info is,

We are building the traymessage() code using VisualStudio 2003 on windows 7 machine
Is this a problem?

Becasue we already tried,
NOTIFYICONDATA_V3_SIZE
NOTIFYICONDATA_V2_SIZE

But it says undeclared identifier, I think shell32api.h is not having this macros

Sham
0
 
mohet01Author Commented:
sorry it is shellapi.h

0
 
mohet01Author Commented:
Hello Chris
In runtime i see that our visual studio project(application) 32 bit binary  is using c:\windows\syswow64\shell32.dll,
I think if we use c:\windows\system32\shell32.dll on win2008, does it work?

If yes, How do i force our app to use system32\shell32.dll?

Sham
0
 
tampnicCommented:
The machine you build it on should not matter - you could even cross-compile the code using Linux if you wanted! Also the installed compiler version does not matter as long as you are compiling with the right SDK.

You are definitely not compiling with the latest SDK if NOTIFYICONDATA_V3_SIZE is not defined. I just looked in ShellAPI.h on my machines installation of the SDK v7.0A and it is there. What is _WIN32_IE defined as in your application? Parts of ShellAPI.h are not included depending on the value of _WIN32_IE and may also affect behaviour of your application.

Cheers,
   Chris
0
 
mohet01Author Commented:
Hello Chris
1) in the app it is,  #define _WIN32_IE 0x0500
What is the meaning/significance of this statement?
2) The machine where am building this code has shellapi.h which does not have your recommended macros.
3) Do you think NOTIFYICONDATA_V3_SIZE is going to resolve problem? why?

Sham
0
 
tampnicCommented:
_WIN32_IE basically sets the minimum version of Windows that your application will support. 0x0500 means your minimum supported client is Windows 2000 and Internet Explorer 5 (you can find these values in sdkddkver.h). Many of the SDK headers check this definition and don't include new functionality if it conflicts with the minimum supported Windows version.

You need to download and install the Windows v7.1 SDK from http://www.microsoft.com/download/en/details.aspx?id=8279

I don't know about your version of Visual Studio, I jumped from VC++ 6 to Visual Studio 2010 with a lot of unix work inbetween. On Visual Studio 2010 it is in the first page of project options where you choose which SDK to compile with. The "Windows7.1SDK" option appeared automatically after I installed the SDK, but I have to select it manually for each new project. If this doesn't appear automatically you will have to google how to set up the SDK with Visual Studio 2003.

Cheers,
   Chris
0
 
mohet01Author Commented:
I already told that version is visual studio 2003
0
 
tampnicCommented:
Visual Studio 2003 will have a SDK that comes supplied with it, but you need to install a more up-to-date SDK and use that from Visual Studio 2003. You are not upgrading the compiler version, you are adding a SDK that the compiler can work with (updated Windows headers etc). The latest Windows Platform SDK supplied by Microsoft is v7.1 and can be downloaded from the link I gave you. However you have to connect the compiler to the new SDK. Its done automatically in Visual Studio 2010, I don't know if Visual Studio 2003 does this.

Cheers,
    Chris
0
 
mohet01Author Commented:
hello chris
I will raise another query for  how to link v7.1 sdk with vs 2003.
Currently how do I know which version of sdk does vs 2003 uses?

Sham
0
 
mohet01Author Commented:
Hello chris
I see that,
The Windows 7 SDK will probably not work with these VS 2003 versions. It is recommended that you upgrade to one of the newer Visual C++ versions (VS 2010).

But i have a problem here,
1)  I am unable to convert VS 2003 project to VS 2010 project, I would need help on this. Shall i raise another query thread on this?
2) Why do you think that v7.1 SDk, which provide V3_size/V2_size is going to work?
Sham



Sham


0
 
mohet01Author Commented:
Hello Chris
As per your update in ID: 37279060
You say that it is working.
Did you compiled my traymessage() code in VS 2010 with windows 7 SDk?
Sham
0
 
mohet01Author Commented:
hello chris
As per id: 37279060,
Did you test by launching a thread, because in our code ntfTHREADPROC IS LAUNCHed as thread
Sham
0
 
tampnicCommented:
No I created a test win32 project and put your code into the InitInstance() of the application. No threading and it was a widowed app, not a console  app. Very minor changes just to get it to compile. I then had to add the SecureZeroMemory() call for the icon to appear.

Cheers,
Chris
0
 
mohet01Author Commented:
hello chris
It worked for us as stand alone program.
based on this, do you think this is 7.1 sdk issue?
Am unable to covert vs 2003 project to vs 2010 project. Can you help me on that?
Sham
0
 
tampnicCommented:
I will try and look up the size of the structure sometime today. You can try setting it manually instead of by using the definition. Shell32.dll expects different structure sizes depending its version. The information  is specified on the NOTIFYICONDATA page on MSDN .

Cheers,
Chris
0
 
mohet01Author Commented:
hello chris
Based on different structures, members also change, like sztip does not exist for one latest version .
So, can you comment on members accordingly?
Sham

0
 
tampnicCommented:
Here are the various sizes of struct you can try setting tnd.cbSize to.

  int tmp;

// project character set is "MBCS" or "not set"
  tmp =NOTIFYICONDATAA_V1_SIZE; // tnd.cbSize=88
  tmp =NOTIFYICONDATAA_V2_SIZE; // tnd.cbSize=488
  tmp =NOTIFYICONDATAA_V3_SIZE; // tnd.cbSize=504

// project character set is "UNICODE"
  tmp =NOTIFYICONDATAW_V1_SIZE; // tnd.cbSize=152
  tmp =NOTIFYICONDATAW_V2_SIZE; // tnd.cbSize=936
  tmp =NOTIFYICONDATAW_V3_SIZE; // tnd.cbSize=952

Open in new window


I found them out by running my debugger through some test code and marking the sizes as comments. Note the different sizes depending on whether you have defined UNICODE in your project options.

Cheers,
    Chris
0
 
mohet01Author Commented:
Hello Chris
I tried all the sizes uni and non-uni
Didn't work.
With current code of traymessage() function, Do you think changing of cbsize will work?
Sham
0
 
tampnicCommented:
Here attached is a little test project I put together from your code. It is a console project which opens a thread and puts a notification icon into the notification area. I built it on Visual Studio 2010 with the 7.0a SDK. Works fine! I commented out a lot of your code as I didn't have the source for the function calls.  

testpad.cpp
resource.h
icon1.ico.mdb

I uploaded the icon file with a .mdb extension as .ico is not an acceptable file extension on experts-exchange, so you will need to rename that file.

If your app is not using MFC, you could use the Visual Studio 2010 Express edition (free) to compile your code with an up-to-date SDK.

Merry Xmas, I'm off to see the family now!

Cheers,
   Chris
0
 
mohet01Author Commented:
thanx chris
does this work on win 2008?
Sham
0
 
tampnicCommented:
I don't have a copy of win2008 server set up to test. I do have a copy of it on a dvd somewhere so will set it up in a virtual machine at some point. It will probably be quicker for you to download Visual Studio 2010 Express and test it out yourself as I will be doing Christmas with the family over the next few days.

Cheers,
Chris
0
 
mohet01Author Commented:
hello Chris
After running your program, isee like this (as attached)
But i dont see in tray
Do i need to place icon file in some folder on win 2008?
Sham
 scn
0
 
mohet01Author Commented:
Hello Chris
As per the  win console (no MFC)project file frm VStudio proessional 2010, I only placed your 3 files.
Remaining files was on its own.
But i dont see the icon in tray as per scn.png
Sham
0
 
tampnicCommented:
The icon should be compiled into the .exe as a resource, or just add an icon in the resource editor and make sure it has an id of IDI_ICON1. Click on the "show icons and notifications on the taskbar" checkbox and you should see it.

Cheers,
   Chris
0
 
mohet01Author Commented:
what is the option for selecting resource editor?
0
 
mohet01Author Commented:
Hello Chris
We already tried before the same like the one you wrote testpad.cpp, But we compiled on VS 2003 running on Win 7, This is working on win 2008.

But when this same logic happens in our app, it shell_notifyicon() fails

What could be the reason? permission issue?

Sham
0
 
tampnicCommented:
Resource editor can be accessed by pressing Ctrl-Shift-E - this shows the "resource view" pane. Right-click on your project and select Add->Resource from the popup menu.

I would ask if your main process has any message pump in it? I found the thread did not start while debugging until I put a message pump into the main process of my test app. Also while stepping through code the debugger would skip into the main process message pump on occasion, e.g. when CreateWindow() was called in the thread the debugger jumps into the main process message pump for one loop. Also if I right-click the icon, as well as running through the handler code it also occasionally jumps into the main process message pump.

Cheers,
   Chris
0
 
mohet01Author Commented:
Hello Chris
As you said that below code will keep thread alive,
1) Why does the thread needmessage pump to keep thread alive?
2) How do i interpret that this message goes from process to that specific thread?

// start pumping messages as the thread doesn't run until we kick it into action with this!
      while (GetMessage(&lpMsg,NULL,0,0)) {
            TranslateMessage(&lpMsg);
            DispatchMessage(&lpMsg);
      }

Sham
0
 
mohet01Author Commented:
hello chris
in addition to my previous query, I would also like to tell u that your message pump idea is not working.
Sham
0
 
mohet01Author Commented:
Hello
Please answer my queries in 3 updates.
Please continue with  ID: 27510711
on the same query.


I will close this thread, once the new one is closed. Becasue this thred is going to long.

Sham
0
 
mohet01Author Commented:
Hello Moderator
I did not read your update before i created this duplicate query.
I have no idea, how I would get any advantage, if i raise duplicate query.
My intention was to give more than 500 points to any technician who is helping me.

Becasue he has placed lot of effort on this.
Previously some technicians(pmasotta) also recommended me to award close to 1000 points. I think they are correct.

But for sure, you are adding overhead in the middle of our work. May be it is the process problem.


Sham

0
 
tampnicCommented:
Don't worry about points Sham. I help on Experts-Exchange because it feels good to help other people and I also learn at the same time. I know some experts can be precious about points, personally it doesn't worry me, but thanks for your consideration.

Cheers,
   Chris
0
 
mohet01Author Commented:
Hello Chris
1) If we take the icon module aside and make work, shell_notifyicon() returns true on win2008.
2) I this icon module runs as part of my app, shell_notifyicon() returns false on win2008.

What do you think the problem could be about shell_notifyicon() failing?
Sham
0
 
mohet01Author Commented:
Hello Chris
I have a new point
If a module run as a service,
and this module has to display icon in systray,
it does not work in 2008

Our module is running as service

Sham
0
 
mohet01Author Commented:
If you test your same code as a service, it will not work
Please let me know your test results.
Becasue i do not know how to write, service code

Sham
0
 
tampnicCommented:
I will try and get a test environment and some sample code put together either today or tomorrow.

Cheers,
   Chris
0
 
mohet01Author Commented:
Hello Chris
Are you saying that it is possible to write service code which displays the icon in systray
Becasue msdn says this: "Apparently Shell_NotifyIcon is no longer working in Windows 7 when called from a Windows System Service"

http://msdn.microsoft.com/en-us/library/windows/desktop/bb762159(v=vs.85).aspx


Sham
0
 
mohet01Author Commented:
Hello Chris
Can you help me in designing this?
Shall i raise a seperate query for this?
Sham
0
 
tampnicCommented:
I would be happy to help Sham.

Its probably best to raise a new query as this page is starting to take a while to load :-) Post the new query ID in this message thread so I can find it please.

Cheers,
   Chris
0
 
mohet01Author Commented:
Hello Chris
I have rasied another query for redesign
ID: 27515173

Please do the necessary
Sham
0
 
mohet01Author Commented:
thanx
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.