TrackMouseEvent und WM_MOUSEHOVER will nicht funktionieren



  • 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??



  • @ChrisK: Könntest du mir den mal schicken inklusive Code? Keine Angst da wird nichts kopiert ich brauche es für Delphi. ich werde es dann eh nach Delphi umsetzen. mpuff@luckie-online.de wäre die Adresse dann.



  • Ja klar das mache ich gleich heute Abend. Bin so 20 Uhr zurück ... Bis dann ...

    Achja: Du kannst von mir aus dann auch den Code übernehmen oder stenzen, was solls 🙂

    Ist eh nicht mein "großes" Projekt, sondern ein Testprogramm welches 6 OwnerdrawButtons anzeigt :))

    Aber die sind echt nice!

    Also bis heute Abend. Ich schicks Dir dann.

    CU 😃



  • So habe es Dir geschickt.

    Viel Spass!


Anmelden zum Antworten