Click here to Skip to main content
14,237,256 members

C / C++ / MFC

 
GeneralRe: Writing Vector object into a .txt file Pin
Richard Andrew x6423-Mar-15 8:39
professionalRichard Andrew x6423-Mar-15 8:39 
GeneralRe: Writing Vector object into a .txt file Pin
Jochen Arndt23-Mar-15 21:53
mveJochen Arndt23-Mar-15 21:53 
GeneralRe: Writing Vector object into a .txt file Pin
Member 935023723-Mar-15 23:47
memberMember 935023723-Mar-15 23:47 
GeneralRe: Writing Vector object into a .txt file Pin
Jochen Arndt24-Mar-15 0:17
mveJochen Arndt24-Mar-15 0:17 
GeneralRe: Writing Vector object into a .txt file Pin
Member 935023725-Mar-15 4:25
memberMember 935023725-Mar-15 4:25 
GeneralRe: Writing Vector object into a .txt file Pin
Jochen Arndt25-Mar-15 4:46
mveJochen Arndt25-Mar-15 4:46 
GeneralRe: Writing Vector object into a .txt file Pin
Jochen Arndt25-Mar-15 6:56
mveJochen Arndt25-Mar-15 6:56 
QuestionBIG trouble with 64-bit Shell_NotifyIcon() - can anyone help? Pin
Tacitonitus16-Mar-15 11:24
memberTacitonitus16-Mar-15 11:24 
Hi Everyone..

I very rarely ask programming-specific questions in public forums, but this one has me completely stumped.

I just can't seem to get the Windows Native API function, "Shell_NotifyIcon" to work, no matter what I try.

This is the Windows API function that enables an application to add its "Icon" to the Windows System Tray, aka: the "System Notification Area", and then enables it to pop up "notifications", etc..

At least, in theory..

No matter what I try however, this function always fails in my app.

And when I call the GetLastError() function to try to determine what was allegedly wrong with the call, sometimes I'll get a "timeout" error (whatever that means), sometimes I'll get an "invalid window handle" (but the handle's perfectly valid), and other times the call will actually succeed, but the very next call will fail with the same variable results..

I'm compiling in Windows 64-bit using Visual C++ Express, BTW..

I've tried calling both the ANSI and Unicode versions of this function and get the same results. I've tried specifying different "versions" to this function (it's a parameter), and I get the same results. I've tried compiling both with and without "enabling Visual Styles", but, you guessed it, same results..

And I've looked at all the sample code on the Internet that uses this function, including most of the code on this site, and without exception, none of the code I've looked at is doing anything more than my own code is doing..

Which is all, needless to say, exceedingly frustrating..

My app also changes its own execution priority, so I took that out to see if it would make a difference - it didn't..

I also came across an excellent article on Shell_NotifyIcon on the Internet:

"The trouble with Shell_NotifyIcon()"]

So I implemented a retry count, as he suggested. Unfortunately, the only difference that made was that I had to wait four seconds before I could see it fail (yet again)..

The methodology involved is this:

my Main Dialog Box's WM_INITDIALOG message handler calls this:
#define TRAY_ICON_ID  0xABC  // <== ..our System Tray Icon Id
#define BALL_ICON_ID  0xDEF  // <== ..our Balloon Tip Icon Id

#define MSG_FROM_TRAY  (WM_APP + 0xDAD)   // <== ..the "callback message" ID..

static NOTIFYICONDATA *NID;

static void Init_NID( HWND hDlg )
{
    if ( NID = new NOTIFYICONDATA )
    {
         memset( NID, 0, sizeof( NOTIFYICONDATA ) );

         if ( LoadIconMetric( AppInst,
                              (PCWSTR)MAKEINTRESOURCE( IDR_TrayIcon ),
                              LIM_SMALL, &NID->hIcon ) == S_OK )
         {
              if ( LoadIconMetric( AppInst,
                                   (PCWSTR)MAKEINTRESOURCE( IDR_BallIcon ),
                                   LIM_SMALL, &NID->hBalloonIcon ) == S_OK )
              {
                   bool Opning =  // <== ..amended per "Frankie-C"..
                   strcpy( NID->szTip, "My App Name" ) &&
                   strcpy( NID->szInfoTitle, "Hi There" ) &&
                   strcpy( NID->szInfo, "My notification message.." );

                   if ( Opning )
                   {
                        NID->uTimeout = 5000;
                        NID->uID = TRAY_ICON_ID;
                        NID->dwInfoFlags = NIIF_USER;
                        NID->uCallbackMessage = MSG_FROM_TRAY;
                        NID->cbSize = sizeof( NOTIFYICONDATA );
                        NID->dwState = 0;
                        NID->dwStateMask = NIS_HIDDEN | NIS_SHAREDICON;

                        return;
                   }

                   DestroyIcon( NID->hBalloonIcon );
              }

              DestroyIcon( NID->hIcon );
         }

         delete NID;
         NID = NULL;
    }
}

The same Dialog Box procedure also calls two other Tray-related functions, Min2SysTray(), which attempts to add the Tray Icon, display a notification, then hide the Dialog Box, and ProcMsgFromTray(), which processes messages from the Tray.

All three are invoked from the same Dialog Box procedure in the following way:
static INT_PTR CALLBACK MainDlg( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
    switch ( uMsg )
    {
        case WM_SYSCOMMAND:

            switch ( wParam )
            {
                case SC_CLOSE:      // <== ..as for example..

                    QuitThisApp( hDlg );
                    return( true );

                case IDM_About:    // <== ..as for example..

                    DialogBoxParam( AppInst,
                                    MAKEINTRESOURCE( IDD_About ),
                                    hDlg, AboutDlg, 0 );
                    return( true );

                case SC_MINIMIZE: if ( Min2SysTray( hDlg ) ) return( true );
            }

            break;

//      << bunch of other cases >>

        case MSG_FROM_TRAY:

            ProcMsgFromTray( hDlg, wParam, lParam );
            return( true );

        case WM_INITDIALOG:

            Init_NID( hDlg );
            return( true );

        case WM_DESTROY: PostQuitMessage( 0 );
    }

    return( false );
}

Where the code for my Min2SysTray() function is:
static bool Min2SysTray( HWND hDlg )
{
    bool Success = false;

    if ( NID )
    {
         NOTIFYICONDATA Ver;
         memset( &Ver, 0, sizeof( NOTIFYICONDATA ) );

         Ver.uID = NID->uID;
         Ver.uVersion = NOTIFYICON_VERSION_4;
         Ver.cbSize = sizeof( NOTIFYICONDATA );

         NID->hWnd = Ver.hWnd = hDlg;
         NID->uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP | NIF_SHOWTIP;

         if ( Shell_NotifyIcon( NIM_ADD, NID ) &&  // <== ..adds the icon..
              Shell_NotifyIcon( NIM_SETVERSION, &Ver ) )
         {
              NID->uFlags =  NIF_INFO | NIF_MESSAGE | NIF_TIP | NIF_SHOWTIP;

              if ( Success = Shell_NotifyIcon( NIM_MODIFY, NID ) )
                   ShowWindow( hDlg, SW_HIDE );
         }
    }

    return( Success );
}

And the code for my ProcMsgFromTray() function is:
static void ProcMsgFromTray( HWND hDlg, WPARAM wParam, LPARAM lParam )
{
    if ( HIWORD( lParam ) == NID->uID )
    {
         switch ( LOWORD( lParam ) )
         {
//           case WM_CONTEXTMENU:   // <== ..I don't need this..
//               break;

             case NIN_SELECT:
             case NIN_KEYSELECT:
             case WM_LBUTTONDBLCLK:

                 if ( NID ) Shell_NotifyIcon( NIM_DELETE, NID );
                 ShowWindow( hDlg, SW_SHOW );
         }
    }
}

And that's pretty much all of the code. Needless to say, I haven't been able to figure out what's wrong with it (yet?), if anything..

So what I need is another pair of eyes. Or two, or four.. or a thousand..

Uh! My frustration's bubbling to the surface.. please to excuse..

Anyway, if there's anyone out there who can find anything wrong with the above code, and/or can help in any other way, please respond..

Thanks in advance..

modified 16-Mar-15 23:23pm.

AnswerRe: BIG trouble with 64-bit Shell_NotifyIcon() - can anyone help? Pin
Frankie-C16-Mar-15 13:00
memberFrankie-C16-Mar-15 13:00 
GeneralRe: BIG trouble with 64-bit Shell_NotifyIcon() - can anyone help? Pin
Tacitonitus16-Mar-15 15:36
memberTacitonitus16-Mar-15 15:36 
GeneralRe: BIG trouble with 64-bit Shell_NotifyIcon() - can anyone help? Pin
Frankie-C16-Mar-15 22:39
memberFrankie-C16-Mar-15 22:39 
GeneralRe: BIG trouble with 64-bit Shell_NotifyIcon() - can anyone help? Pin
Tacitonitus17-Mar-15 3:34
memberTacitonitus17-Mar-15 3:34 
GeneralRe: BIG trouble with 64-bit Shell_NotifyIcon() - can anyone help? Pin
Frankie-C17-Mar-15 4:11
memberFrankie-C17-Mar-15 4:11 
GeneralRe: BIG trouble with 64-bit Shell_NotifyIcon() - can anyone help? Pin
Tacitonitus17-Mar-15 7:21
memberTacitonitus17-Mar-15 7:21 
GeneralRe: BIG trouble with 64-bit Shell_NotifyIcon() - can anyone help? Pin
Frankie-C17-Mar-15 7:29
memberFrankie-C17-Mar-15 7:29 
GeneralRe: BIG trouble with 64-bit Shell_NotifyIcon() - can anyone help? Pin
Frankie-C17-Mar-15 22:48
memberFrankie-C17-Mar-15 22:48 
QuestionVC++ DLL throws error when call it from C#[EntryPointNotFound] Pin
Member 988367216-Mar-15 1:38
memberMember 988367216-Mar-15 1:38 
AnswerRe: VC++ DLL throws error when call it from C#[EntryPointNotFound] Pin
Richard Andrew x6416-Mar-15 5:48
professionalRichard Andrew x6416-Mar-15 5:48 
QuestionIAccessible - get word under mouse pointer in IE Pin
Fourblack15-Mar-15 22:01
memberFourblack15-Mar-15 22:01 
QuestionC++ to C problem Pin
alexx00614-Mar-15 10:03
memberalexx00614-Mar-15 10:03 
AnswerRe: C++ to C problem Pin
Richard Andrew x6414-Mar-15 13:15
professionalRichard Andrew x6414-Mar-15 13:15 
AnswerRe: C++ to C problem Pin
Frankie-C15-Mar-15 5:49
memberFrankie-C15-Mar-15 5:49 
GeneralRe: C++ to C problem Pin
David Crow16-Mar-15 2:54
memberDavid Crow16-Mar-15 2:54 
QuestionUI widget Pin
Member 1152499814-Mar-15 7:01
memberMember 1152499814-Mar-15 7:01 
AnswerRe: UI widget Pin
Albert Holguin15-Mar-15 17:19
professionalAlbert Holguin15-Mar-15 17:19 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.