Static Control Mouse Over
-
Benutze TrackMouseEvent.
https://msdn.microsoft.com/en-us/library/windows/desktop/ms646265(v=vs.85).aspxDas regelt vor allem das Verlassen des Fensters.
Einfacher ist es evtl. Das Staic zu belassen und im Parent unter dem Static einfach die Mausbewegungen abzufangen. Ein Static ohne SS_NOTIFY last Mausmessages ja durch and das Parent.
-
Danke auch dir Martin Richter für die Antwort.
Ich habs jetzt einmal so gemacht. Der Wechsel zwischen Hover und Leave funktioniert so. Nun sollte ich doch nur noch nach Durchgang von 'WM_MOUSEHOVER:' ein Feedback an das Parent senden können, damit das Static Control neu gezeichnet wird. Das wil mir aber nicht gelingen.
Wie mach ich das am Besten.
Danke für die Hilfe.
M.f.G. wachs
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){ int wmId, wmEvent; PAINTSTRUCT ps; HDC hdc; switch (message){ case WM_CREATE: CreateStaticControls(hWnd); break; case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); switch (wmId){//Sofern Menus case ID_LEER: break; default: return DefWindowProc(hWnd, message, wParam, lParam); } break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); EndPaint(hWnd, &ps); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } LRESULT CALLBACK SCProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){ PAINTSTRUCT ps; RECT rect; HDC hdc; switch (message){ case WM_PAINT:{ SetStaticBasic(hWnd); break; } case WM_MOUSEMOVE: if(_MouseOver==false){ TRACKMOUSEEVENT tme; tme.cbSize = sizeof(TRACKMOUSEEVENT); tme.dwFlags = TME_HOVER; tme.dwHoverTime = 100; tme.hwndTrack = hWnd; TrackMouseEvent(&tme); _MouseOver = true; SetCapture(hWnd); }else { TRACKMOUSEEVENT tme; tme.cbSize = sizeof(TRACKMOUSEEVENT); tme.dwFlags = TME_LEAVE; tme.hwndTrack = hWnd; TrackMouseEvent(&tme); _MouseOver = true; SetCapture(hWnd); } break; case WM_MOUSEHOVER:{ _MouseOver=false; ReleaseCapture(); return CallWindowProc(wndprocSC,hWnd, message, wParam, lParam); } case WM_MOUSELEAVE :{ _MouseOver=false; ReleaseCapture(); return CallWindowProc(wndprocSC,hWnd, message, wParam, lParam); } case WM_DESTROY: PostQuitMessage(0); break; default: return CallWindowProc(wndprocSC,hWnd, message, wParam, lParam); } return 0; }
bool SetStaticBasic(HWND hWnd){ HDC hdc; RECT rect; PAINTSTRUCT ps; TCHAR *szText = NULL; hdc = BeginPaint(hWnd, &ps); GetClientRect(hWnd, &rect); int nTextLength = SendMessage(hWnd, WM_GETTEXTLENGTH, 0, 0) + 1; szText = new TCHAR[nTextLength]; SendMessage(hWnd, WM_GETTEXT, nTextLength, (LPARAM)szText); HFONT myFont=CreateFont(30,0,0,0,FW_BOLD,FALSE,FALSE,0, ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,DEFAULT_PITCH | FF_SWISS,L"Arial"); SelectObject(hdc,myFont); SetTextColor(hdc, RGB(0, 32, 96)); SetBkMode(hdc, TRANSPARENT); DrawText(hdc, szText, -1, &rect, DT_SINGLELINE); DeleteObject(myFont); delete[] szText; EndPaint(hWnd, &ps); return true; }
-
wachs schrieb:
Danke auch dir Martin Richter für die Antwort.
Ich habs jetzt einmal so gemacht. Der Wechsel zwischen Hover und Leave funktioniert so. Nun sollte ich doch nur noch nach Durchgang von 'WM_MOUSEHOVER:' ein Feedback an das Parent senden können, damit das Static Control neu gezeichnet wird. Das wil mir aber nicht gelingen.
Wie mach ich das am Besten.
Danke für die Hilfe.
M.f.G. wachs
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){ int wmId, wmEvent; PAINTSTRUCT ps; HDC hdc; switch (message){ case WM_CREATE: CreateStaticControls(hWnd); break; case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); switch (wmId){//Sofern Menus case ID_LEER: break; default: return DefWindowProc(hWnd, message, wParam, lParam); } break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); EndPaint(hWnd, &ps); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } LRESULT CALLBACK SCProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){ PAINTSTRUCT ps; RECT rect; HDC hdc; switch (message){ case WM_PAINT:{ SetStaticBasic(hWnd); break; } case WM_MOUSEMOVE: if(_MouseOver==false){ TRACKMOUSEEVENT tme; tme.cbSize = sizeof(TRACKMOUSEEVENT); tme.dwFlags = TME_HOVER; tme.dwHoverTime = 100; tme.hwndTrack = hWnd; TrackMouseEvent(&tme); _MouseOver = true; SetCapture(hWnd); }else { TRACKMOUSEEVENT tme; tme.cbSize = sizeof(TRACKMOUSEEVENT); tme.dwFlags = TME_LEAVE; tme.hwndTrack = hWnd; TrackMouseEvent(&tme); _MouseOver = true; SetCapture(hWnd); } break; case WM_MOUSEHOVER:{ _MouseOver=false; ReleaseCapture(); return CallWindowProc(wndprocSC,hWnd, message, wParam, lParam); } case WM_MOUSELEAVE :{ _MouseOver=false; ReleaseCapture(); return CallWindowProc(wndprocSC,hWnd, message, wParam, lParam); } case WM_DESTROY: PostQuitMessage(0); break; default: return CallWindowProc(wndprocSC,hWnd, message, wParam, lParam); } return 0; }
bool SetStaticBasic(HWND hWnd){ HDC hdc; RECT rect; PAINTSTRUCT ps; TCHAR *szText = NULL; hdc = BeginPaint(hWnd, &ps); GetClientRect(hWnd, &rect); int nTextLength = SendMessage(hWnd, WM_GETTEXTLENGTH, 0, 0) + 1; szText = new TCHAR[nTextLength]; SendMessage(hWnd, WM_GETTEXT, nTextLength, (LPARAM)szText); HFONT myFont=CreateFont(30,0,0,0,FW_BOLD,FALSE,FALSE,0, ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,DEFAULT_PITCH | FF_SWISS,L"Arial"); SelectObject(hdc,myFont); SetTextColor(hdc, RGB(0, 32, 96)); SetBkMode(hdc, TRANSPARENT); DrawText(hdc, szText, -1, &rect, DT_SINGLELINE); DeleteObject(myFont); delete[] szText; EndPaint(hWnd, &ps); return true; }
InvalidateWindow einfach aufrufen?
-
Meinst du UpdateWindow(hWnd)? InvalidateWindow gibt es doch gar nicht.
Mit UpdateWindow(hWnd) habe ich's versucht .. will trotzdem nicht funktionieren.
LRESULT CALLBACK SCProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){ switch (message){ case WM_PAINT:{ if(wParam==0) SetStaticBasic(hWnd);//siehe oben if (wParam==20) SetStaticMouseEnter(hWnd); UpdateWindow(hWnd); break; } case WM_MOUSEMOVE: if(_MouseOver==false){ TRACKMOUSEEVENT tme; tme.cbSize = sizeof(TRACKMOUSEEVENT); tme.dwFlags = TME_HOVER; tme.dwHoverTime = 100; tme.hwndTrack = hWnd; TrackMouseEvent(&tme); _MouseOver = true; SetCapture(hWnd); }else { TRACKMOUSEEVENT tme; tme.cbSize = sizeof(TRACKMOUSEEVENT); tme.dwFlags = TME_LEAVE; tme.hwndTrack = hWnd; TrackMouseEvent(&tme); _MouseOver = true; SetCapture(hWnd); } break; case WM_MOUSEHOVER:{ _MouseOver=false; ReleaseCapture(); return CallWindowProc(SCProc,hWnd, 15, 20, lParam); } case WM_MOUSELEAVE :{ _MouseOver=false; ReleaseCapture(); return CallWindowProc(SCProc,hWnd, 15, 0, lParam); } case WM_DESTROY: PostQuitMessage(0); break; default: return CallWindowProc(wndprocSC,hWnd, message, wParam, lParam); } return 0; }
bool SetStaticMouseEnter(HWND hWnd){ HDC hdc; RECT rect; PAINTSTRUCT ps; TCHAR *szText = NULL; hdc = BeginPaint(hWnd, &ps); GetClientRect(hWnd, &rect); int nTextLength = SendMessage(hWnd, WM_GETTEXTLENGTH, 0, 0) + 1; szText = new TCHAR[nTextLength]; SendMessage(hWnd, WM_GETTEXT, nTextLength, (LPARAM)szText); HFONT myFont=CreateFont(30,0,0,0,FW_NORMAL,TRUE,FALSE,0, ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,DEFAULT_PITCH | FF_SWISS,L"Arial"); SelectObject(hdc,myFont); SetTextColor(hdc, RGB(255, 153, 0)); SetBkMode(hdc, TRANSPARENT); DrawText(hdc, szText, -1, &rect, DT_SINGLELINE); DeleteObject(myFont); delete[] szText; EndPaint(hWnd, &ps); return true; }
-
Sorry. Dachte daran:
https://msdn.microsoft.com/en-us/library/windows/desktop/dd145002(v=vs.85).aspx
UpdateWindow müsste auvh gehen. UpdateWindow ist aber nicht die Reaktion auf WM_PAINT sondrrn die Ursache.
UpdateWindow musst Du als Reaktion auf die Maudbewgung aufrufen. Auch genügt es, das Handle des static controls zu übergeben. Nur das soll ja neu gezeichnet werden.
Fg Martin
P.s: Scheißandroidtastatur.
-
Sorry. Dachte daran:
https://msdn.microsoft.com/en-us/library/windows/desktop/dd145002(v=vs.85).aspx
UpdateWindow müsste auvh gehen. UpdateWindow ist aber nicht die Reaktion auf WM_PAINT sondrrn die Ursache.
UpdateWindow musst Du als Reaktion auf die Maudbewgung aufrufen. Auch genügt es, das Handle des static controls zu übergeben. Nur das soll ja neu gezeichnet werden.
Fg Martin
P.s: Scheißandroidtastatur.
-
danke ... ich werde es mir morgen oder übermorgen abend nochmals anschauen ...
schlaf gut
-
Also ich persönlich finde der Wechsel von einem zum Anderen ein wenig träge. Kann man das eventuell noch performanter machen?
Funktionieren tut's mit dieser Callback-Funktion.
LRESULT CALLBACK SCProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){ PAINTSTRUCT ps;RECT rect;HDC hdc; int wmId, wmEvent; switch (message){ case WM_PAINT:{ InvalidateRect(hWnd,NULL,TRUE); hdc = BeginPaint(hWnd, &ps); GetClientRect(hWnd, &rect); FillRect(hdc,&rect,(HBRUSH)WHITE_BRUSH); if(wParam==0)SetStaticBasic(hWnd,hdc,rect); if (wParam==20)SetStaticMouseEnter(hWnd,hdc,rect); EndPaint(hWnd, &ps); //ValidateRect(hWnd,NULL); break; } case WM_COMMAND:{ wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); switch (wmId){ case ID_LEER: break; default: return DefWindowProc(hWnd, message, wParam, lParam); } } case WM_MOUSEMOVE: if(_MouseOver==false){ TRACKMOUSEEVENT tme; tme.cbSize = sizeof(TRACKMOUSEEVENT); tme.dwFlags = TME_HOVER; tme.dwHoverTime = 100; tme.hwndTrack = hWnd; TrackMouseEvent(&tme); _MouseOver = true; //SetCapture(hWnd); }else { TRACKMOUSEEVENT tme; tme.cbSize = sizeof(TRACKMOUSEEVENT); tme.dwFlags = TME_LEAVE; tme.hwndTrack = hWnd; TrackMouseEvent(&tme); _MouseOver = true; //SetCapture(hWnd); } break; case WM_MOUSEHOVER:{ _MouseOver=false; //ReleaseCapture(); return SendMessage(hWnd, WM_PAINT, 20, lParam); } case WM_MOUSELEAVE :{ _MouseOver=false; //ReleaseCapture(); return SendMessage(hWnd, WM_PAINT, 0, lParam); } case WM_DESTROY: PostQuitMessage(0); break; default: return CallWindowProc(wndOrigProcSC,hWnd, message, wParam, lParam); } return 0; }
Edit: Capture rausgenommen.
-
Du brauchst kein Capture, wenn Du TrackMouseEvent benutzt.
Warum?Nur wenn Du es nicht benutzt benötigst Du es.
-
Hallo und Guten Tag
Ich hab alle Capture rausgenommen. Den Unterschied merkt man ein wenig.
Nochmals Danke für die Hilfe.
wachs
PS. Ich hab versucht einen Anhang (StaticControlMain.cpp) mitzugeben. Ist das nicht möglich?