如何在鼠标悬停时使静态窗口增加大小

时间:2020-08-01 22:40:02

标签: c++ windows winapi button hover

我在另一个窗口中有一堆窗口。 子Windows是在docker run类的CreateBoard()方法中创建的。 MainWindowCreate()的{​​{1}}方法来自MS Documentation MainWindow抽象类,在这里,每个类都通过调用{{1} }

GemWindow

BaseWindow方法在棋盘中创建宝石。

RegisterClass()

我希望每个子窗口在鼠标悬停时分别增加其大小4个像素。但是,在扩大大小之后,它们会留下痕迹,有时将鼠标悬停在单个窗口上会增加整个行或列的大小。引用图片,例如:

Problem demo

我有每个子窗口的处理代码,如下所示。 template <class DERIVED_TYPE> class BaseWindow { public: static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { DERIVED_TYPE* pThis = NULL; if (uMsg == WM_NCCREATE) { CREATESTRUCT* pCreate = (CREATESTRUCT*)lParam; pThis = (DERIVED_TYPE*)pCreate->lpCreateParams; SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pThis); pThis->m_hwnd = hwnd; } else { pThis = (DERIVED_TYPE*)GetWindowLongPtr(hwnd, GWLP_USERDATA); } if (pThis) { //getting read access violation here why? //because on resize you are not initializing tiles //but resizing the thing return pThis->HandleMessage(uMsg, wParam, lParam); } else { return DefWindowProc(hwnd, uMsg, wParam, lParam); } } BaseWindow() : m_hwnd(NULL) { } BOOL Create( PCWSTR lpWindowName, DWORD dwStyle, DWORD dwExStyle = 0, int x = CW_USEDEFAULT, int y = CW_USEDEFAULT, int nWidth = CW_USEDEFAULT, int nHeight = CW_USEDEFAULT, HWND hWndParent = 0, HMENU hMenu = 0 ) { WNDCLASS wc = { 0 }; wc.lpfnWndProc = DERIVED_TYPE::WindowProc; wc.hInstance = GetModuleHandle(NULL); wc.lpszClassName = ClassName(); RegisterClass(&wc); m_hwnd = CreateWindowEx( dwExStyle, ClassName(), lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, GetModuleHandle(NULL), this ); return (m_hwnd ? TRUE : FALSE); } //returns handle HWND Window() const { return m_hwnd; } protected: virtual PCWSTR ClassName() const = 0; virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) = 0; HWND m_hwnd; }; CreateBoard()类中的BOOL MainWindow::CreateBoard() { for (unsigned int i = 0; i < GetcGem(); i++) { for (unsigned int j = 0; j < GetcGem(); j++) { if (Gems[i][j].Create(L"gem", WS_CHILDWINDOW | WS_VISIBLE, NULL, 5 + i * GetsGem().cx + i * 10, 5 + j * GetsGem().cy + j * 10, GetsGem().cx, GetsGem().cy, Window(), NULL)) { //pass from main window to Gem object Gems[i][j].SetSize(GetsGem().cx, GetsGem().cy); Gems[i][j].SetPosition(5 + i * GetsGem().cx + i * 10, 5 + j * GetsGem().cy + j * 10); HBRUSH hbrush = CreateSolidBrush(RGB(125,125,125)); HBRUSH hOldBrush = (HBRUSH)SetClassLongPtr(Gems[i][j].Window(), GCLP_HBRBACKGROUND, (LONG_PTR)hbrush); DeleteObject(hOldBrush); InvalidateRect(Gems[i][j].Window(), NULL, TRUE); } else { return FALSE; } } } return TRUE; }

tracking

static BOOLGemWindow的一种方法,它初始化BOOL GemWindow::tracking = false; LRESULT GemWindow::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_DESTROY: DestroyWindow(Window()); break; case WM_MOUSEMOVE: { if (!tracking) { TrackMouse(); tracking = true; } }break; case WM_MOUSEHOVER: { MoveWindow(Window(), GetSize().cx + 4, GetSize().cy + 4, GetPosition().x - 2, GetPosition().y - 2, TRUE); InvalidateRect(Window(), NULL, TRUE); OutputDebugString(L"MOUSE ENTERED\n"); }break; case WM_MOUSELEAVE: { MoveWindow(Window(), GetSize().cx, GetSize().cy, GetPosition().x, GetPosition().y, TRUE); InvalidateRect(Window(), NULL, TRUE); OutputDebugString(L"MOUSE LEFT\n"); tracking = false; }break; case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(m_hwnd, &ps); //FillRect(hdc, &ps.rcPaint, CreateSolidBrush(color)); EndPaint(m_hwnd, &ps); //OutputDebugString(L"PAINT\n"); } return 0; default: return DefWindowProc(m_hwnd, uMsg, wParam, lParam); } return TRUE; } 并调用TrackMouse()

GemWindow

我认为这是因为我不是在更新区域,但是这样做并没有改变任何东西。我对此错误感到困惑,无法想到任何合理的理由。

感谢所有花时间帮助的人。

1 个答案:

答案 0 :(得分:1)

BOOL MoveWindow(
  HWND hWnd,
  int  X,  //The new position of the left side of the window.
  int  Y,  //The new position of the top of the window.
  int  nWidth, //The new width of the window.
  int  nHeight, //The new height of the window.
  BOOL bRepaint
);

修改以下代码:

   case WM_MOUSEHOVER:
    {
//      MoveWindow(Window(), GetSize().cx + 4, GetSize().cy + 4, GetPosition().x - 2, GetPosition().y - 2, TRUE);
        MoveWindow(Window(), GetPosition().x - 2, GetPosition().y - 2, GetSize().cx + 4, GetSize().cy + 4, TRUE);            
        ...

    case WM_MOUSELEAVE:
    {
 //     MoveWindow(Window(), GetSize().cx, GetSize().cy, GetPosition().x, GetPosition().y, TRUE);
        MoveWindow(Window(), GetPosition().x, GetPosition().y, GetSize().cx, GetSize().cy,  TRUE);
        ...

调试:

enter image description here