C WINAPI Как я могу запустить событие мыши только один раз?

#c #winapi

Вопрос:

Этот код в моем фреймворке без окон представляет собой область,похожую на кнопку, но какой-то код я хотел запустить только один раз, пока мышь не переместится в область в следующий раз. Весь этот код находится в WM_MOUSEMOVE.

 int ClickAreaPtInfo(HWND hWnd, int x, int y, int sizex, int sizey, LPARAM lParam,int amp;value)
    {
        POINT pt;
        pt.x = LOWORD(lParam);
        pt.y = HIWORD(lParam);
        RECT rect;
        GetClientRect(hWnd, amp;rect);
        RECT  rc = { x,y,x   sizex,y   sizey };
        if (PtInRect(amp;rc, pt))
        {
            value = 1;
            return -1;
        }
        else
        {
            value = 0;
            return -1;
        }
        return -1;
    }
int _CreateMouseEvent(HWND hWnd, int x, int y, int sizex, int sizey, LPARAM lParam,RUNFUN function(), const wchar_t* Panelid, const wchar_t* CtlName)
        {
            int val = 0;
            int msg = 0;


            //int ist = 0;            int istprev = 0;
            RECT winrc;
            GetClientRect(hWnd, amp;winrc);
            RECT rc;
            RectTypeConvert(rc,x, y, sizex, sizey);

            if (Panelid == PanelID)
            {
                int nst = 1;
                //OutputDebugString(L"HOVER!n");
                msg = 1;
                ClickAreaPtInfo(hWnd, x, y, sizex, sizey, lParam, val);
                if (val == 1)
                {

                    if (ClickMsg == 1) //Click(Get from WM_LBUTTONUP)
                    {
                        ClickMsg = 0;
                        function();
                    }
                    else
                    {
//It must be run for only once until the mouse leave next time,or it will  lead to a lot of resource occupation
                        if (CtlName == L"Button") //HOVER
                        {

                            if (nst == 1)
                            {
                                HDC hdc = GetDC(hWnd);
                                CreateSimpleButtonEx(hWnd, hdc, x, y, sizex, sizey, UICOLOR_GREENSEA, 1, ButtonText);
                                ReleaseDC(hWnd, hdc);
                                nst = 0;
                                return 0;
                            }
                            else
                            {
                                nst = 0;
                                return 0;
                            }
                            return 0;
                        }
                        if (CtlName == L"CloseButton") ///HOVER
                        {
                            if (nst == 1)
                            {
                                HDC hdc = GetDC(hWnd);
                                CreateRect(hWnd, hdc, x, y, sizex, sizey, UICOLOR_PEACHRED);
                                PanelDrawCloseBtn(hWnd, hdc, rc.right - 40, 0, 40, 40, 12, UICOLOR_WHITE);
                                ReleaseDC(hWnd, hdc);
                                nst = 0;
                                return 0;
                            }
                            else
                            {
                                nst = 0;
                                return 0;
                            }
                            return 0;
                        }
                        else
                        {
                            return 0;
                        }
                    }

                }
                if (val == 0) //Leave
                {
                        nst = 1;
                        InvalidateRect(hWnd, amp;rc, 0); //It must be run for only once until the mouse leave next time,or it will  lead to a lot of resource(CPU) occupation
 
                }
            }
            if (Panelid == PrevPanelID)
            {
                msg = 1;
            }

            else
            {
                msg = 0;
            }
            

            return 0;
        }
 

затем обработайте CreateMouseEvent в WM_MOUSEMOVE:

 case WM_MOUSEMOVE:
{
    CreateMouseEvent(hWnd, 20, 60, 140, 40, lParam, test, L"Init",L"Button");
    CreateMouseEvent(hWnd, 20, 120, 140, 40, lParam, test3, L"Init", L"Button");
    CreateMouseEvent(hWnd, 20, 180, 140, 40, lParam, btn3, L"Init",L"Button");
    CreateMouseEvent(hWnd, rc.right - 40, 0, 40, 40, lParam, CloseWindow, L"Init",L"CloseButton");
    break;
}
 

И я также дам ответ на этот вопрос!
http://db.vertexstudio.xyz/lnk/PanelPic/debuginf.png

есть какое-нибудь решение?Спасибо!

Комментарии:

1. Вы звоните CreateSimpleButtonEx каждый раз, когда мышь перемещается по кнопке. Ты это нарочно? Похоже, вы ожидаете, что значение локальной переменной nst каким-то образом сохранится между вызовами.

2. здесь я хочу запустить только один раз, когда мышь уйдет:если (val == 0) //Оставить { nst = 1; InvalidateRect(hWnd, amp;rc,0); //Его нужно запустить только один раз, пока мышь не уйдет в следующий раз, или это приведет к занятию большого количества ресурсов(процессора)}

3. Если я создам глобальную переменную,и на панели будет несколько событий мыши, это вызовет еще одну ошибку

4. Поэтому вам нужно разработать способ поддержания постоянного состояния отдельно для каждой кнопки.

5. По сути, вы хотите реализовать то, каким было бы гипотетическое WM_MOUSEENTER сообщение. Видите, почему нет сообщения WM_MOUSEENTER? чтобы научиться это делать.

Ответ №1:

Некоторые из ваших проблем уже упоминались выше.

Есть некоторые переменные, которые не определены в вашем примере, ни тип, ни значение, но я могу экстраполировать, по крайней мере, некоторые.

Кроме того, в нескольких местах вы пытаетесь напрямую сравнить строковый указатель в стиле C (не a std::string !) с другим строковым указателем в стиле C.

     if (Panelid == PanelID) is one place
    
    if (CtlName == L"Button") //HOVER  === is another

    if (CtlName == L"CloseButton") ///HOVER another
 

Вы можете использовать что-то вроде int _wcsnicmp( const wchar_t *string1,const wchar_t *string2, size_t count); или все, что поддерживает ваш компилятор. При желании вы можете просто использовать std::wstring .

Что касается щелчка, вам нужно сохранить прямую кишку, которую вы получаете, с GetClientRect(hWnd, amp;winrc); ней нужна настойчивость, т. Е. сохранена вне функции и доступна. Затем сравните с этим прямоугольником и действуйте соответственно.

Комментарии:

1. Не могли бы вы дать мне способ осознать это? Спасибо!