- ベストアンサー
マウスカーソルがボタンに乗った時、反応するには何が必要ですか?
- C言語とWIN32APIを使用し、マウスカーソルがボタンに乗った時にボタンが反応しない問題が発生しています。
- WM_DRAWITEMメッセージでボタンの描画を行う際、オンマウスで色を反転する目的の処理が記載されていましたが、マウスカーソルがボタンに乗った時に反応しない状態です。
- マウスカーソルがボタンに乗った時に反応するためには、どのような処理が必要なのでしょうか?
- みんなの回答 (1)
- 専門家の回答
質問者が選んだベストアンサー
こんばんは。 ホバーボタンの事かと思います。現段階で必要なものは、TrackMouseEvent()とボタンのサブクラス化です。 中々ややこしいので、以下URLの説明を参考になさってみてください。 http://hp.vector.co.jp/authors/VA016117/hoverbtn.html http://hp.vector.co.jp/authors/VA016117/hoverbtn2.html 一応当方からもコードを提示しておきます。3つのボタンを出して、ホバーさせます。以下参考程度に。 #include<windows.h> #include<tchar.h> #define ArrayCount(a) (sizeof(a)/sizeof(a[0])) typedef struct _BUTTONDATA { HWND hButton; WNDPROC wndProcOrg; bool bHover; } BUTTONDATA, *PBUTTONDATA; static BUTTONDATA buttons[3] = {NULL}; const int BUTTON_COUNT = ArrayCount(buttons); const UINT IDC_BUTTON1 = 1000; const LPCTSTR TSTR_BUTTONDATA = TEXT("HoverButton"); LRESULT CALLBACK ButtonProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { PBUTTONDATA pButton = static_cast<PBUTTONDATA>(::GetProp(hWnd, TSTR_BUTTONDATA)); switch(message) { case WM_MOUSEMOVE: if(pButton->bHover == false && wParam == 0x0) { pButton->bHover = true; TRACKMOUSEEVENT tme = {sizeof(tme)}; tme.dwFlags = TME_LEAVE; tme.hwndTrack = hWnd; ::TrackMouseEvent(&tme); ::InvalidateRect(hWnd, NULL, TRUE); } break; case WM_LBUTTONDOWN: pButton->bHover = false; break; case WM_LBUTTONUP: pButton->bHover = true; break; case WM_MOUSELEAVE: pButton->bHover = false; ::InvalidateRect(hWnd, NULL, TRUE); } return ::CallWindowProc(pButton->wndProcOrg, hWnd, message, wParam, lParam); } LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_CREATE: { LPCREATESTRUCT pcs = reinterpret_cast<LPCREATESTRUCT>(lParam); PBUTTONDATA pButton = static_cast<PBUTTONDATA>(pcs->lpCreateParams); for(int i = 0; i < BUTTON_COUNT; ++i) { pButton[i].hButton = ::CreateWindowEx(0, TEXT("BUTTON"), TEXT("OK"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | BS_OWNERDRAW, 20 + (60 * i), 20, 60, 40, hWnd, reinterpret_cast<HMENU>(IDC_BUTTON1 + i), ::GetModuleHandle(NULL), NULL); pButton[i].wndProcOrg = reinterpret_cast<WNDPROC>(::SetWindowLong(pButton[i].hButton, GWL_WNDPROC, reinterpret_cast<LONG>(&::ButtonProc))); ::SetProp(pButton[i].hButton, TSTR_BUTTONDATA, &pButton[i]); } } break; case WM_DRAWITEM: { LPDRAWITEMSTRUCT DrawItem = reinterpret_cast<LPDRAWITEMSTRUCT>(lParam); PBUTTONDATA pButton = static_cast<PBUTTONDATA>(::GetProp(DrawItem->hwndItem, TSTR_BUTTONDATA)); if(pButton == NULL) break; ::FillRect(DrawItem->hDC, &DrawItem->rcItem, reinterpret_cast<HBRUSH>(::GetStockObject(WHITE_BRUSH))); TCHAR buf[256]; ::GetWindowText(DrawItem->hwndItem, buf, ArrayCount(buf)); ::DrawText(DrawItem->hDC, buf, ::_tcslen(buf), &DrawItem->rcItem, DT_VCENTER | DT_CENTER | DT_SINGLELINE); if(pButton->bHover) { ::InvertRect(DrawItem->hDC, &DrawItem->rcItem); } if(DrawItem->itemState & ODS_SELECTED) { ::DrawEdge(DrawItem->hDC, &DrawItem->rcItem, EDGE_SUNKEN, BF_RECT); } else { DrawEdge(DrawItem->hDC, &DrawItem->rcItem, EDGE_RAISED, BF_RECT); } if(DrawItem->itemState & ODS_FOCUS) { ::DrawFocusRect(DrawItem->hDC, &DrawItem->rcItem); } } break; case WM_CLOSE: ::DestroyWindow(hWnd); return 0; case WM_NCDESTROY: ::PostQuitMessage(0); return 0; } return ::DefWindowProc(hWnd, message, wParam, lParam); } int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR pszArgs, int showCmd) { MSG msg; WNDCLASSEX wc = {sizeof(wc)}; wc.lpszClassName = TEXT("TEST"); wc.lpfnWndProc = &::WndProc; wc.hbrBackground = (HBRUSH)(COLOR_WINDOW); wc.hInstance = hInst; wc.hCursor = LoadCursor(NULL, IDC_ARROW); if(!::RegisterClassEx(&wc)) return 0; HWND hWnd = ::CreateWindowEx( 0, wc.lpszClassName, NULL, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInst, &buttons[0]); ::ShowWindow(hWnd, SW_SHOW); while(::GetMessage(&msg, NULL, 0, 0) == TRUE) { ::TranslateMessage(&msg); ::DispatchMessage(&msg); } return msg.wParam; }
お礼
おはようございます。 早速、ご教示ありがとうございます。 勉強します。 ありがとうございます。