Tastendruck-Mausklick abfragen (im System Tray)



  • Hi,

    ich hab ne Anwendung die auf dem SystemTray liegt, nun möchte ich das diese wenn ich eine bestimmte Maus-Tastatur kombination drücke maximiert wird. Ich krieg das aber nicht hin da ja meine Anwendung im tray keinen Maus oder tastatur Focus mehr besitzt. Also mit WM_LBUTTONUP oderso hab ich das nicht hingekriegt. Weiß einer von euch wie das geht?



  • Also einen Tastendruck könntest du mit RegisterHotkey abfangen - für die Kombination mit einem Mausklick zusammen wirst du dir sowas wohl selber basteln müssen 🙄



  • Nachdem ich nichts in der SDK-Hilfe gefunden habe, habe ich darüber nachgesonnen und bin auf einen Trick gekommen. Du könntest dir beim Start deiner Applikation ein kleines unsichtbares transparentes Fenster (evtl. 10x10 pxls) machen ohne Titelleiste. Bei einem Eintreffen eines WM_HOTKEYs könntest du das Fenster "sichtbar" machen und so zum Cursor-Hotspot bewegen, dass dieser im Fenster liegt und eine statische BOOL-Variable auf TRUE setzen. Du bekommst dann eine WM_MOUSEMOVE-Nachricht, in der du dann je nachdem, ob die BOOL-Variable gesetzt ist oder nicht, im wParam nachschauen kannst, ob ein Mousebutton gedrückt ist, und wenn ja, welcher. Danach machst du das Fenster wieder unsichtbar und setzt die BOOL-Variable wieder auf FALSE (alles noch im WM_MOUSEMOVE).
    Da mir das alles aber doch recht umständlich erscheint, würde ich dir raten, dich mit einem einfachen Hotkey zu begnügen.



  • Da ich gerne mit sowas spiele, hab ich mal ein wenig probiert.
    Über die WinMain kommt:

    #define TIMER_ID 50
    
    ATOM HotKey_ID;
    
    LRESULT CALLBACK W_Proc(HWND hwnd, UINT uiMsg, WPARAM wParam, LPARAM lParam);
    VOID MyNotification()
    {
      MessageBox(NULL, TEXT("HOTKEY!!!"), TEXT("NOTIFY"), MB_OK|MB_ICONINFORMATION);
    }
    

    In die WinMain schreibst du

    // Eine eindeutige ID bekommen
    HotKey_ID = GlobalAddAtom( TEXT("F8-Hotkey") );
    
    WNDCLASS wc;
    
    wc.style = 0;
    wc.lpfnWndProc = W_Proc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = NULL;
    wc.hCursor = NULL;
    wc.hbrBackground = NULL;
    wc.lpszMenuName = NULL;
    wc.lpszClassName = TEXT("DUMMYWND_CLASS");
    
    RegisterClass(&wc);
    
    CreateWindowEx(WS_EX_TRANSPARENT|WS_EX_TOOLWINDOW,
                   TEXT("DUMMYWND_CLASS"), NULL,
                   WS_POPUP, 0, 0, 10, 10,
                   NULL, NULL, hInstance, 0);
    

    Die Fenster-Prozedur für das kleine Fenster:

    LRESULT CALLBACK W_Proc(HWND hwnd, UINT uiMsg, WPARAM wParam, LPARAM lParam)
    {
       static POINT pt;
       static BOOL  bDetectMouse = FALSE;
    
       switch(uiMsg)
       {
          case WM_CREATE:
             // Den HotKey registrieren
             RegisterHotKey(hwnd, HotKey_ID, 0, VK_F8);
             return 0;
    
          case WM_LBUTTONDOWN:
             if(bDetectMouse)                 // Es wurde F8 und gleich danach der
             {                                // linke Mousebutton gedrückt
                ShowWindow(hwnd, SW_HIDE);
                bDetectMouse = FALSE;
                MyNotification();
             }
             return 0;
    
          case WM_HOTKEY:                     // Es wurde F8 gedrückt
             if(!bDetectMouse)
             {
                bDetectMouse = TRUE;
                // Das Fenster unter den Cursor schieben ...
                GetCursorPos(&pt);
                SetWindowPos(hwnd, HWND_TOPMOST, pt.x - 5, pt.y - 5, 10, 10, 0);
                // ... und anzeigen
                ShowWindow(hwnd, SW_SHOW);
                // Einen Timer starten
                SetTimer(hwnd, TIMER_ID, 300, NULL);
             }
             return 0;
    
          case WM_TIMER:
             if(bDetectMouse)                 // Es wurde F8 gedrückt und kein Mouse-
             {                                // klick innehalb von 300 ms empfangen
                // Den Timer stoppen ...
                KillTimer(hwnd, TIMER_ID);
                // ... und das Fenster wieder verstecken
                ShowWindow(hwnd, SW_HIDE);
                bDetectMouse = FALSE;
             }
             return 0;
    
          case WM_DESTROY:
             UnregisterHotKey(hwnd, HotKey_ID);
             GlobalDeleteAtom(HotKey_ID);
             return 0;
       }
    
       return DefWindowProc(hwnd, uiMsg, wParam, lParam);
    }
    

    Du musst ZUERST F8 drücken und dann erst den linken MouseButton. Andersherum habe ich es nicht hinbekommen, weil ja die Maus gecaptured ist und keine Nachrichten im Fenster ankommen. Die Idee mit dem WM_MOUSEMOVE kann man also getrost vergessen. Aber so ist es doch auch OK, oder?



  • danke für eure Beiträge, das wird mir bestimmt weiterhelfen



  • Wenn es dir nicht zu viel Aufwand ist, wirst du das wohl am Besten mit einem Hook (Maus) + Hook (Keyb) od. RegisterHotkey lösen können 😉



  • @flenders: Ich denke, ein Hook ist für so ein kleines Problem nun wirklich des Guten zu viel. Einfach zu krass! Außerdem hab ich doch schon ne Lösung gepostet.



  • Du hast doch auch selbst das Problem deiner Lösung aufgezeigt:

    WebFritzi schrieb:

    Du musst ZUERST F8 drücken und dann erst den linken MouseButton. Andersherum habe ich es nicht hinbekommen, weil ja die Maus gecaptured ist und keine Nachrichten im Fenster ankommen. Die Idee mit dem WM_MOUSEMOVE kann man also getrost vergessen. Aber so ist es doch auch OK, oder?

    Wenn er diesen Fall eben auch abfangen will, wirrd er wohl Hooks brauchen, oder liege ich da wiedermal falsch 🙄



  • Ne, sorry. Aber ich denke, meine Lösung reicht schon aus, oder meinst du nicht?



  • Das muss Zapology entscheiden 😉 - ich hab nur die andere Möglichkeit der Vollständigkeit halber noch erwähnt 🙂


Anmelden zum Antworten