[Win32/C++] Pop-up menu taskbar notification area

Pagina: 1
Acties:
  • 109 views sinds 30-01-2008
  • Reageer

  • The - DDD
  • Registratie: Januari 2000
  • Laatst online: 03-09 16:40
Ik kom er dus niet uit, heb al vanalles bekeken en gezocht (ben er de afgelopen 2.5 uur mee bezig geweest).

Ik wil een pop-up menu wanneer je rechts klikt op een icoontje in je taskbar notification area (System Tray voor de leken).

Iemand die me kan helpen hiermee? Op Got alleen info voor Delphi en VB kunnen vinden, online wordt er gelijk naar MFC gedoken.

  • stylee
  • Registratie: December 2000
  • Laatst online: 04-09-2021

stylee

blah zeg ik je


  • stylee
  • Registratie: December 2000
  • Laatst online: 04-09-2021

stylee

blah zeg ik je

ps er zal vast wel iets staan op codeguru.com of codeproject.com, vraag/zoek het anders ff in de codeguru.com forums... daar komen best veel win32 programmeurs

Verwijderd

Moet je eerst je icon registreren met Shell_notifyIcon.
Als flag geef je NIM_ADD mee; om te verwijderen NIM_DELETE
In de NotifyIcon struct, vul je bij hWnd de handle van je main window in, en bij uCallbackMessage een message ID van de callback message ( bij voorkeur gedefineerd als WM_USER + ... ). Vervolgens zal Windows een message posten naar je mainwindow als er iets gebeurd met het icon (bv als de muis erover beweegt, of als er op geklikt wordt ). Dan is het enkel nog zaak om die message juist af te handelen. Dus je popupmenu tonen met TrackPopupMenu.

Zie MSDN over
Shell_NotifyIcon
NOTIFYICONDATA
Dit heel fijn artikeltje over de taskbar (inclusief sample code voor de icons !)

Suc6 8-)

  • Lone Gunman
  • Registratie: Juni 1999
  • Niet online
Eerst moet je dmv je NOTIFYICONDATA structure een callbackmessage geven.

Dat kan op de volgende manier :
code:
1
nid.uCallbackMessage = UWM_SYSTRAY;

Je ontvangt daarna in je wndproc een UWM_SYSTRAY message als de muis zich boven jouw icoontje in de systray bevind.

Daarna kun je in je wndproc deze message afvangen, bv zo :
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    case UWM_SYSTRAY:
    switch (lParam) {
      case WM_RBUTTONUP:
        GetCursorPos(&pt);
        hmenu = LoadMenu(ghInst, MAKEINTRESOURCE(IDM_CONTEXTMAIN));
        hpopup = GetSubMenu(hmenu, 0);

        SetForegroundWindow(hwnd);
        switch (TrackPopupMenu(hpopup, TPM_RETURNCMD | TPM_RIGHTBUTTON, pt.x, pt.y, 0, hwnd, NULL))
        {
        case IDM_EXIT: DestroyWindow(hwnd); break;
        case IDM_MESSAGEBOX: MessageBox(hwnd, "blabla", "About", MB_TASKMODAL); break;
        }
        PostMessage(hwnd, 0, 0, 0);
        DestroyMenu(hmenu);
        break;
    }

SetForegroundWindow(hwnd) en PostMessage(hwnd, 0, 0, 0) worden hier gebruikt om een "feature" te omzeilen. Als je dit niet doet blijft je menuutje staan, ook al klikt de user buiten je menu.

K hoop dat je hier wat mee kunt :)

mzzl, lone

Experience has taught me that interest begets expectation, and expectation begets disappointment, so the key to avoiding disappointment is to avoid interest.


  • The - DDD
  • Registratie: Januari 2000
  • Laatst online: 03-09 16:40
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
    case UWM_SYSTRAY:
        {
            switch(LOWORD(lParam))
            {
            case WM_LBUTTONDBLCLK:
                {
                    SetWindowPos(hWnd,0,0,0,0,0,SWP_SHOWWINDOW |SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE);
                    ShowWindow(hWnd, SW_RESTORE);
                    break;
                }
            case WM_RBUTTONUP:
                {
                    HMENU hmenu = LoadMenu(hInstance, TEXT("IDR_NOTIFY_POPUP"));
                    HMENU hpopup = GetSubMenu(hmenu, 0);

                    POINT pos;
                    GetCursorPos(&pos);

                    SetForegroundWindow(hWnd);
                    switch (TrackPopupMenu(hpopup,0/*TPM_RIGHTBUTTON | TPM_LEFTALIGN | TPM_VERTICAL*/,pos.x,pos.y,0,hWnd,NULL))
                    {
                    case IDM_CLOSE:
                        SendMessage (hWnd, WM_CLOSE, 0, 0);
                    }
                    PostMessage(hWnd, WM_NULL, 0, 0);
                    DestroyMenu(hmenu);
                    break;                  
                }
            }
            break;
            
        }

M'n messagehandler van mijn notigy...

De double click werkt perfect. Deed ie zowiezo al. ;)
Het tijdelijk uitschakelen haalt ook niks uit.

Maar hij doet het dus gewoon niet.

  • The - DDD
  • Registratie: Januari 2000
  • Laatst online: 03-09 16:40
Op maandag 10 december 2001 00:16 schreef The - DDD het volgende:
code:
1
2
3
...
HMENU hmenu = LoadMenu(hInstance, TEXT("IDR_NOTIFY_POPUP"));
...
|:( :'( |:( :'( |:( :'( |:( :'( |:( :'( |:( :'( |:( :'( |:( :'( |:( :'(
ARGH!!! Dat was de fout...

Ik heb er nu dit van gemaakt:
code:
1
2
3
...
HMENU hmenu = LoadMenu(hInstance, MAKEINTRESOURCE(IDR_NOTIFY_POPUP));
...

Meer was er niet verkeerd!!

/me - DDD gaat zichzelf even verhangen. DAMN!!

Maar het werkt nu wel... :D

  • The - DDD
  • Registratie: Januari 2000
  • Laatst online: 03-09 16:40
Ok volgende vraag waar ik nu mee zit (is echt de laatste hierover, want verder werkt alles nu perfect).

Ik heb het volgende:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
case UWM_SYSTRAY:
{
switch(LOWORD(lParam))
{
    case WM_LBUTTONDOWN:
    {
        POINT pos;
        GetCursorPos(&pos);
        HWND hDlg = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_SYSTRAY_INFO), 0, SysTrayDlgProc);
        RECT Rect;
        GetWindowRect(hDlg,&Rect);
                    
        SetWindowPos(hDlg,HWND_TOPMOST,pos.x - (Rect.right - Rect.left),pos.y - (Rect.bottom - Rect.top),0,0,SWP_SHOWWINDOW | SWP_NOSIZE );
        break;
    }
    //verdere case statements voor Tray Icon...

Er wordt dus bij links klikken een dialog geopend.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_SYSTRAY_INFO DIALOGEX 0, 0, 56, 49
STYLE WS_POPUP | WS_BORDER
EXSTYLE WS_EX_TOOLWINDOW
FONT 8, "MS Sans Serif"
BEGIN
    CTEXT        "Activiteit:",IDC_STATIC,7,7,42,8
    CTEXT        "blabla",IDC_ACTIVITY,7,14,42,8
    CTEXT        "Duur:",IDC_STATIC,7,26,42,8
    CTEXT        "blabla",IDC_ACTIVITYTIME,7,34,42,8
END

Mijn bedoeling is dat ik een klein status windowtje aanmaak wat netjes wat actuele gegevens weergeeft.

Echter dat &$*# kreng moet weer oprotten wanneer ik ergens (waar dan ook) klik. Overal in mijn scherm, ook op andere windows. Maar het lukt niet echt. Links klikken op het ding werkt wel, vanwege mijn Windows procedure van het ding:
(zoals je ziet ben ik er aardag wat in aan het proberen geweest)
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
BOOL CALLBACK SysTrayDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    static HWND tray;
    switch (message)
    {
//  case WM_INITDIALOG:
    case WM_CREATE:
        SetCapture(hDlg);

//      GetFocus();
        return TRUE;
    case WM_COMMAND:
        switch (LOWORD(wParam))
        {
            case IDCANCEL:
            {
                ReleaseCapture();
                EndDialog(hDlg,0);
                return TRUE;
            }
            default:
            return FALSE;
        }

//  case WM_SETFOCUS:
//      {
//          
//      }
//
    case WM_CAPTURECHANGED :
        if (/*hDlg != (HWND)wParam && */tray == (HWND)wParam)
            break;
    case WM_LBUTTONDOWN:
    case WM_MBUTTONDOWN:
    case WM_RBUTTONDOWN:
    case WM_NCLBUTTONDOWN:
    case WM_NCMBUTTONDOWN:
    case WM_NCRBUTTONDOWN:
//  case WM_MOUSEMOVE:
//  case WM_NCMOUSEMOVE:
//  case WM_NCHITTEST:
        {
//          ReleaseCapture();
            EndDialog(hDlg,0);
            return TRUE;
        }
    }
    return FALSE;

}

  • The - DDD
  • Registratie: Januari 2000
  • Laatst online: 03-09 16:40
Bovenstaande reply lukt nog steeds niet. Dus ik schop hem maar is een keer omhoog.

*schop* :P

  • The - DDD
  • Registratie: Januari 2000
  • Laatst online: 03-09 16:40
Ok, ik heb het dus niet op kunnen lossen, maar in plaats daarvan heb ik er een handige feature van gemaakt.

Klik links op de tray icon en er verschijn een klein tool windowtje met wat info. Je weet wel met zo'n smal bovenbalkje en 1 klein sluit kruisje.

D'r loopt een tellertje in mee, hij is verplaatsbaar en TOPMOST gedefinieerd, dus altijd zichtbaar.

Mocht iemand toch nog antwoord weten op mijn laatste vraag, graag. Ik wil het graag weten.
Pagina: 1