TrackMouseEvent und WM_MOUSEHOVER will nicht funktionieren



  • Dann würde ich das an deiner Stelle mit SubClassing machen.
    Hier ist dazu ein Beispiel.
    Zwar mit Editfeld, ist aber genau das gleiche.



  • Aber so wie es aussieht, ist das genau der selbe Code, wie ich ihn programmiert habe... Hast Du Dir meinen Code angesehen?
    Also im Pronzip das gleiche, nur funktioniert TrackMouseEvent nicht 😕

    😞

    Tschüssle,
    Chris



  • Gesubclasst hat er.

    @ChrisK:
    Mach mal ein #define _WIN32_WINNT 0x0400 bevor du die windows.h inkludierst.

    Pack das TrackMouseEvent(&tme) nach WM_MOUSEMOVE der ButtonProc.
    'Oder' den tme.dwFlags TME_LEAVE hinzu. Nun musst du nur die Nachrichten WM_MOUSEHOVER und WM_MOUSELEAVE abarbeiten (ebenfalls in der BottonProc).
    Grundsätzlich sollte es dann funktionieren. Der Rest ist nur der Feinschliff.

    Edit: fehlerhaften Zeilenumbruch beseitigt.

    Edit2: MSDN Beispiel Zwar fürs Hauptfenster, aber das ist hoffentlich kein Problem oder 😉

    [ Dieser Beitrag wurde am 08.11.2002 um 18:51 Uhr von kwoTx editiert. ]

    [ Dieser Beitrag wurde am 08.11.2002 um 18:59 Uhr von kwoTx editiert. ]



  • Uff also das ist doch seltsam 😞

    #define _WIN32_WINNT 0x0400
    
    #include "windows.h"
    #include "resource.h"
    #include "commctrl.h"
    
    const char szClassName[] = "MYAPP";
    const char szWinName[]   = "Ownerdraw Button";
    
    HWND hButton = NULL;
    
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    LRESULT CALLBACK Button(HWND, UINT, WPARAM, LPARAM);
    WNDPROC BUTTON_PROC;
    HINSTANCE hInst;
    
    int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                         PSTR szCmdLine, int iCmdShow)
    {
        HWND        hWnd;
        MSG         msg;
        WNDCLASSEX  wndclass;
    
        wndclass.cbSize        = sizeof (wndclass);
        wndclass.style         = CS_HREDRAW | CS_VREDRAW;
        wndclass.lpfnWndProc   = WndProc;
        wndclass.cbClsExtra    = 0;
        wndclass.cbWndExtra    = 0;
        wndclass.hInstance     = hInstance;
        wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION);
        wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW);
        wndclass.hbrBackground = (HBRUSH) GetStockObject (LTGRAY_BRUSH);
        wndclass.lpszMenuName  = NULL;
        wndclass.lpszClassName = szClassName;
        wndclass.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);
    
        RegisterClassEx(&wndclass);
    
        hWnd = CreateWindow(szClassName, szWinName, WS_OVERLAPPEDWINDOW,
                            CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
                            NULL, NULL, hInstance, NULL);
    
        ShowWindow(hWnd, iCmdShow);
        UpdateWindow(hWnd);
    
        hInst = hInstance;
    
        while (GetMessage (&msg, NULL, 0, 0))
        {
            TranslateMessage (&msg);
            DispatchMessage (&msg);
        }
        return (int)msg.wParam;
    }
    
    LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch(message)
        {
            case WM_CREATE:
            {
                hButton = CreateWindowEx(NULL, "button", "BUTTON1", WS_VISIBLE | WS_CHILD | BS_NOTIFY | BS_OWNERDRAW, 100, 100, 300, 50, hWnd, (HMENU)IDC_BUTTON, hInst, NULL);
                BUTTON_PROC = (WNDPROC)SetWindowLong(hButton, GWL_WNDPROC, (long)Button);
                return true;
            }
            case WM_MOUSEMOVE:
            {
                TRACKMOUSEEVENT tme;
                tme.cbSize      = sizeof(TRACKMOUSEEVENT);
                tme.dwFlags     = TME_HOVER;
                tme.dwHoverTime = HOVER_DEFAULT;
                tme.hwndTrack   = hWnd;
                _TrackMouseEvent(&tme);
                break;
            }
            case WM_DRAWITEM:
            {
                LPDRAWITEMSTRUCT dis = (LPDRAWITEMSTRUCT)lParam;
                HPEN hPen1 = NULL;
                HPEN hPen2 = NULL;
                HPEN hPen3 = NULL;
                HPEN hPen4 = NULL;
                switch(dis->CtlID)
                {
                    case IDC_BUTTON:
                    {
                        //Rectangle(dis->hDC, dis->rcItem.left, dis->rcItem.top, dis->rcItem.right, dis->rcItem.bottom);
    
                        SetTextColor(dis->hDC, RGB(0, 0, 255));
                        TextOut(dis->hDC, 20, 20, "Mein Ownerdraw Button", strlen("Mein Ownerdraw Button"));
                        hPen1 = CreatePen(PS_SOLID, 0, RGB(255, 255, 255));
                        hPen2 = CreatePen(PS_SOLID, 0, RGB(230, 230, 230));
                        hPen3 = CreatePen(PS_SOLID, 0, RGB(170, 170, 170));
                        hPen4 = CreatePen(PS_SOLID, 0, RGB(110, 110, 110));
    
                        SelectObject(dis->hDC, (HPEN)hPen1);
                        MoveToEx(dis->hDC, dis->rcItem.left,  dis->rcItem.top, (LPPOINT)NULL);
                        LineTo  (dis->hDC, dis->rcItem.right - 1, dis->rcItem.top);
                        MoveToEx(dis->hDC, dis->rcItem.left,  dis->rcItem.top, (LPPOINT)NULL);
                        LineTo  (dis->hDC, dis->rcItem.left,  dis->rcItem.bottom - 1);
    
                        SelectObject(dis->hDC, (HPEN)hPen2);
                        MoveToEx(dis->hDC, dis->rcItem.left + 1,  dis->rcItem.top + 1, (LPPOINT)NULL);
                        LineTo  (dis->hDC, dis->rcItem.right - 2, dis->rcItem.top + 1);
                        MoveToEx(dis->hDC, dis->rcItem.left + 1,  dis->rcItem.top + 1, (LPPOINT)NULL);
                        LineTo  (dis->hDC, dis->rcItem.left + 1,  dis->rcItem.bottom - 2);
    
                        SelectObject(dis->hDC, (HPEN)hPen3);
                        MoveToEx(dis->hDC, dis->rcItem.left + 1,  dis->rcItem.bottom - 2, (LPPOINT)NULL);
                        LineTo  (dis->hDC, dis->rcItem.right - 1, dis->rcItem.bottom - 2);
                        MoveToEx(dis->hDC, dis->rcItem.right - 2,  dis->rcItem.bottom - 2, (LPPOINT)NULL);
                        LineTo  (dis->hDC, dis->rcItem.right - 2,  dis->rcItem.top);
    
                        SelectObject(dis->hDC, (HPEN)hPen4);
                        MoveToEx(dis->hDC, dis->rcItem.left - 1,  dis->rcItem.bottom - 1, (LPPOINT)NULL);
                        LineTo  (dis->hDC, dis->rcItem.right - 1, dis->rcItem.bottom - 1);
                        MoveToEx(dis->hDC, dis->rcItem.right - 1,  dis->rcItem.bottom - 1, (LPPOINT)NULL);
                        LineTo  (dis->hDC, dis->rcItem.right - 1,  dis->rcItem.top - 1);
    
                        if(dis->itemState & ODS_FOCUS)
                        {
                            SetTextColor(dis->hDC, RGB(0, 0, 255));
                            TextOut(dis->hDC, 20, 20, "Mein Ownerdraw Button", strlen("Mein Ownerdraw Button"));
                        }
                        if(dis->itemState & ODS_SELECTED)
                        {
                            SelectObject(dis->hDC, (HPEN)hPen4);
                            MoveToEx(dis->hDC, dis->rcItem.left,  dis->rcItem.top, (LPPOINT)NULL);
                            LineTo  (dis->hDC, dis->rcItem.right - 1, dis->rcItem.top);
                            MoveToEx(dis->hDC, dis->rcItem.left,  dis->rcItem.top, (LPPOINT)NULL);
                            LineTo  (dis->hDC, dis->rcItem.left,  dis->rcItem.bottom - 1);
    
                            SelectObject(dis->hDC, (HPEN)hPen3);
                            MoveToEx(dis->hDC, dis->rcItem.left + 1,  dis->rcItem.top + 1, (LPPOINT)NULL);
                            LineTo  (dis->hDC, dis->rcItem.right - 2, dis->rcItem.top + 1);
                            MoveToEx(dis->hDC, dis->rcItem.left + 1,  dis->rcItem.top + 1, (LPPOINT)NULL);
                            LineTo  (dis->hDC, dis->rcItem.left + 1,  dis->rcItem.bottom - 2);
    
                            SelectObject(dis->hDC, (HPEN)hPen2);
                            MoveToEx(dis->hDC, dis->rcItem.left + 1,  dis->rcItem.bottom - 2, (LPPOINT)NULL);
                            LineTo  (dis->hDC, dis->rcItem.right - 1, dis->rcItem.bottom - 2);
                            MoveToEx(dis->hDC, dis->rcItem.right - 2,  dis->rcItem.bottom - 2, (LPPOINT)NULL);
                            LineTo  (dis->hDC, dis->rcItem.right - 2,  dis->rcItem.top);
    
                            SelectObject(dis->hDC, (HPEN)hPen1);
                            MoveToEx(dis->hDC, dis->rcItem.left - 1,  dis->rcItem.bottom - 1, (LPPOINT)NULL);
                            LineTo  (dis->hDC, dis->rcItem.right - 1, dis->rcItem.bottom - 1);
                            MoveToEx(dis->hDC, dis->rcItem.right - 1,  dis->rcItem.bottom - 1, (LPPOINT)NULL);
                            LineTo  (dis->hDC, dis->rcItem.right - 1,  dis->rcItem.top - 1);
                            SetTextColor(dis->hDC, RGB(0, 0, 255));
                            TextOut(dis->hDC, 22, 22, "Mein Ownerdraw Button", strlen("Mein Ownerdraw Button"));
                        }
                        break;
                    }
                    break;
                }
                DeleteObject(hPen1);
                DeleteObject(hPen2);
                DeleteObject(hPen3);
                DeleteObject(hPen4);
                break;
            }
            case WM_DESTROY:
            {
                PostQuitMessage(0);
                break;
            }
            break;
        }
        return DefWindowProc (hWnd, message, wParam, lParam);
    }
    
    LRESULT CALLBACK Button(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch(message)
        {
            case WM_INITDIALOG:
            {
                return true;
            }
            case WM_MOUSEHOVER:
            {
                MessageBox(hDlg, NULL, NULL, NULL);
                break;
            }
            case WM_DESTROY:
            {
                PostQuitMessage(0);
                break;
            }
            break;
        }
        return CallWindowProc(BUTTON_PROC, hDlg, message, wParam, lParam);
    }
    

    Es klappt einfach nicht. Keine HOVER Nachricht.
    Weiß nicht mehr weiter

    Deine Hilfe war bestimmt super, nur in dem MSDN Beispiel finde ich mich doch nicht so gut zurecht...



  • (Beim MSDN-Beispiel genügt für diene Zwecke die MainWindowProc, das Zeugs davor ist nicht so wichtig. Villeicht kannst du dann was mit anfangen)

    Ich hab jetzt einfach mal deinen Code als Basis genommen und nur ein paar Kleinigkeiten verändert. Sollte zumindest lauffähig sein.
    Insbesondere hab ich das WM_MOUSEMOVE zeugs in die Button-Proc verlagert.

    #define _WIN32_WINNT 0x0400
    
    #include <windows.h>
    
    const char szClassName[] = "MYAPP";
    const char szWinName[]   = "Ownerdraw Button";
    
    HWND hButton = NULL;
    
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    LRESULT CALLBACK Button(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
    WNDPROC BUTTON_PROC;
    HINSTANCE hInst;
    
    int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                         PSTR szCmdLine, int iCmdShow)
    {
        HWND        hWnd;
        MSG         msg;
        WNDCLASSEX  wndclass;
    
        wndclass.cbSize        = sizeof (wndclass);
        wndclass.style         = CS_HREDRAW | CS_VREDRAW;
        wndclass.lpfnWndProc   = WndProc;
        wndclass.cbClsExtra    = 0;
        wndclass.cbWndExtra    = 0;
        wndclass.hInstance     = hInstance;
        wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION);
        wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW);
        wndclass.hbrBackground = (HBRUSH) GetStockObject (LTGRAY_BRUSH);
        wndclass.lpszMenuName  = NULL;
        wndclass.lpszClassName = szClassName;
        wndclass.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);
    
        RegisterClassEx(&wndclass);
    
        hWnd = CreateWindow(szClassName, szWinName, WS_OVERLAPPEDWINDOW,
                            CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
                            NULL, NULL, hInstance, NULL);
    
        ShowWindow(hWnd, iCmdShow);
        UpdateWindow(hWnd);
    
        hInst = hInstance;
    
        while (GetMessage (&msg, NULL, 0, 0))
        {
            TranslateMessage (&msg);
            DispatchMessage (&msg);
        }
        return (int)msg.wParam;
    }
    
    LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch(message)
        {
            case WM_CREATE:
            {
                hButton = CreateWindowEx(NULL, "button", "BUTTON1", WS_VISIBLE | WS_CHILD | BS_NOTIFY, 100, 100, 300, 50, hWnd, 0, hInst, NULL);
                BUTTON_PROC = (WNDPROC)SetWindowLong(hButton, GWL_WNDPROC, (long)Button);
                return true;
            }
            case WM_DESTROY:
            {
                PostQuitMessage(0);
                break;
            }
        }
        return DefWindowProc (hWnd, message, wParam, lParam);
    }
    
    LRESULT CALLBACK Button(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch(message)
        {
            case WM_MOUSEHOVER:
            {
                MessageBox(hDlg, "Hier kommt die Maus", "Stefan Raab", MB_OK);
                break;
            }
            case WM_MOUSELEAVE: // kwoTx: WM_MOUSELEAVE hinzugefügt;
                MessageBox(hDlg,"Die Maus ist raus","Ooooooh :(",MB_OK);
                break;
            case WM_MOUSEMOVE:
            {
                TRACKMOUSEEVENT tme;
                tme.cbSize      = sizeof(TRACKMOUSEEVENT);
                tme.dwFlags     = TME_HOVER|TME_LEAVE; // TME_LEAVE 'or'ed
                tme.dwHoverTime = HOVER_DEFAULT;
                tme.hwndTrack   = /*hWnd*/ hDlg; // hDlg, soll ja für den Button gelten
                TrackMouseEvent(&tme);
                break;
            }
            case WM_DESTROY:
            {
                PostQuitMessage(0);
                break;
            }
            break;
        }
        return CallWindowProc(BUTTON_PROC, hDlg, message, wParam, lParam);
    }
    


  • Ochjerjee, es war tatsächlich nur das, dass das (wieso so viele das und dass? Naja.) WM_MOUSEMOVE in die Prozedur des Buttons musste. Mphprf... Naja, Dein Code funzt super und ich bin jetzt glücklich :))

    1000 Thx,
    Bye



  • Also ist es echt so, oder denke ich da nur falsch: ich muss dann eigentlich für jeden Button exta eine Prozedur erstellen. Ist das richtig?



  • Du kannst doch immer die gleiche Callback-Funktion angeben!



  • Die ID des Buttons kannst du dann mit

    id = GetWindowLong (hWnd, GWL_ID);
    

    oder mit

    id = GetDlgItem (hWnd);
    

    ermitteln!



  • klar, aber bei mir ist das so:

    wenn WM_MOUSEHOVER ankommt, so setzte ich eine globale variable auf WM_MOUSEHOVER:

    (int) iButtonState = WM_MOUSEHOVER;
    

    und das selbe auch bei WM_MOUSELEAVE:

    (int) iButtonState = WM_MOUSELEAVE;
    

    wenn ich jetzt mehrere Buttons habe, darf ich doch iButtonState nicht verändern, denn wenn ein Button iButtonState verändert, hat das auswirkungen auf alle anderen Buttons ...

    Versteht Ihr?



  • dann musst du eben ein array anlegen, in dem du deine Buttons ablegst, oder hab ich dich jetzt falsch verstanden? 🙄

    iButtonID = GetDlgItem(hWnd);
    iButtonState[iButtonID] = WM_MOUSEHOVER;
    

    [ Dieser Beitrag wurde am 10.11.2002 um 20:07 Uhr von flenders editiert. ]



  • doch doch, ich schätze das trifft genau mein problem! das muss ich wohl so machen thx!
    ich meld mich wenn was nicht kappt 🙂



  • Also wenn ich das bei mehrer Buttons auf die gleiche ButtonProc umbiege bekomme ich keine Problem.

    Nur ich hätte da mal ne Frage: Mein Hover-Effekt soll die Schriftfarbe des Buttons ändern. Ich dachte von standard schwarz an so ein blau eben. Nur wie kann ich die Schriftfarbe ändern ohne dass ich den button komplet selber zeichnen muß? Gibt es da eine Lösung? Die LogFont-Struktur hat leider kein Farbmember.



  • ach mal lieber selber, ist doch ziemlich einfach



  • Es wäre nur einfacher, wenn es anderst ginge, was die Wiederverwendbarkeit des Codes angeht. Einfach die standard Button-Prozedur auf die eigene umbiegen - fertig. Die kann man ja in einer separaten Datei halten.



  • ?? Naja also selberzeichnen ist wirklich sehr einfach und mein Hoverbutton sieht sowas von geil aus! Ich freue mich ewig darüber...



  • Zeig mal, wo kann man den Bewundern. Am besten im Programm oder per Screenshots. Bitte, bitte, ich muss den unbedingt sehen 🙂



  • Kann ich ein Programm irgendwo uploaden?



  • Klar kannste machen!



  • Aber wo denn??


Anmelden zum Antworten