Fenster an Bildschirmrand docken
-
Ich raff's nicht
Weshalb soll das nicht in die WM_MOVING Nachricht?
-
Du musst nicht in WM_MOVING ein Fenster "moven" weil dass schon in diesem Moment geschieht. In WM_MOVING fragt Dich jemand: Darf es diese Position sein?
Moven macht dann die darunterliegende API. Du musst hier nur sagen was Du willst.Lies bitte mal die Doku.
http://msdn2.microsoft.com/en-us/library/ms632632.aspxlParam
Pointer to a RECT structure with the current position of the window, in screen coordinates. To change the position of the drag rectangle, an application must change the members of this structure.
Return ValueAn application should return TRUE if it processes this message.
-
Ok, danke, nun habe ich es so:
case WM_MOVING: if(((RECT*)lParam)->left < 10) { ((RECT*)lParam)->right = ((RECT*)lParam)->right - ((RECT*)lParam)->left; ((RECT*)lParam)->left = 0; } if(((RECT*)lParam)->top < 10) { ((RECT*)lParam)->bottom = ((RECT*)lParam)->bottom - ((RECT*)lParam)->top; ((RECT*)lParam)->top = 0; } if(((RECT*)lParam)->right > (GetSystemMetrics(SM_CXFULLSCREEN) + 10)) { ((RECT*)lParam)->left = ((RECT*)lParam)->left + (GetSystemMetrics(SM_CXFULLSCREEN) + 20 - ((RECT*)lParam)->right); ((RECT*)lParam)->right = GetSystemMetrics(SM_CXFULLSCREEN) + 20; } if(((RECT*)lParam)->bottom > (GetSystemMetrics(SM_CYFULLSCREEN) + 10)) { ((RECT*)lParam)->top = ((RECT*)lParam)->top + (GetSystemMetrics(SM_CYFULLSCREEN) + 20 - ((RECT*)lParam)->bottom); ((RECT*)lParam)->bottom = GetSystemMetrics(SM_CYFULLSCREEN) + 20; } break;
Aber so ganz flüssig läuft das nicht ab
Und das mit dem Mauszeiger ist auch nicht optimal..Test-Code (Copy & Paste)
main.c:#include <windows.h> LRESULT CALLBACK MASTER(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { int i; switch(msg) { case WM_LBUTTONDOWN: PostQuitMessage(0); break; case WM_MOVING: if(((RECT*)lParam)->left < 10) { ((RECT*)lParam)->right = ((RECT*)lParam)->right - ((RECT*)lParam)->left; ((RECT*)lParam)->left = 0; } if(((RECT*)lParam)->top < 10) { ((RECT*)lParam)->bottom = ((RECT*)lParam)->bottom - ((RECT*)lParam)->top; ((RECT*)lParam)->top = 0; } if(((RECT*)lParam)->right > (GetSystemMetrics(SM_CXFULLSCREEN) - 10)) { ((RECT*)lParam)->left = ((RECT*)lParam)->left + (GetSystemMetrics(SM_CXFULLSCREEN) - ((RECT*)lParam)->right); ((RECT*)lParam)->right = GetSystemMetrics(SM_CXFULLSCREEN); } if(((RECT*)lParam)->bottom > (GetSystemMetrics(SM_CYFULLSCREEN) + 10)) { ((RECT*)lParam)->top = ((RECT*)lParam)->top + (GetSystemMetrics(SM_CYFULLSCREEN) + 20 - ((RECT*)lParam)->bottom); ((RECT*)lParam)->bottom = GetSystemMetrics(SM_CYFULLSCREEN) + 20; } break; } return DefWindowProc(hWnd, msg, wParam, lParam); } int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdline, int nShowCmd) { MSG msg; HWND hWnd; WNDCLASSEX wc; wc.cbClsExtra = NULL; wc.cbSize = sizeof(WNDCLASSEX); wc.cbWndExtra = NULL; wc.hbrBackground = (HBRUSH)COLOR_WINDOW; wc.hCursor = LoadCursor(NULL, IDC_UPARROW); wc.hIcon = LoadIcon(hInstance, NULL); wc.hIconSm = LoadIcon(hInstance, NULL); wc.hInstance = hInstance; wc.lpfnWndProc = MASTER; wc.lpszClassName = "Test"; wc.lpszMenuName = NULL; wc.style = CS_DBLCLKS; if(!RegisterClassEx(&wc)) { return 1; } hWnd = CreateWindowEx(0, "Test", "Test", WS_OVERLAPPED, (GetSystemMetrics(SM_CXSCREEN) - 400) / 2, (GetSystemMetrics(SM_CYSCREEN) - 400) / 2, 400,400, (HWND)NULL/*HWND_DESKTOP?*/, (HMENU)NULL, hInstance, (LPVOID)NULL); if(!hWnd) { return 1; } ShowWindow(hWnd, nShowCmd); while(GetMessage(&msg, 0, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } UnregisterClass("Test", 0); return msg.wParam; }
-
Also ich hab das mal so gebaut:
void CDocktestDlg::OnMoving(UINT fwSide, LPRECT pRect) { if(pRect->left < 10) { pRect->right = pRect->right - pRect->left; pRect->left = 0; } if(pRect->top < 10) { pRect->bottom = pRect->bottom - pRect->top; pRect->top = 0; } if(pRect->right > (GetSystemMetrics(SM_CXFULLSCREEN) - 10)) { pRect->left = pRect->left + (GetSystemMetrics(SM_CXFULLSCREEN) - pRect->right); pRect->right = GetSystemMetrics(SM_CXFULLSCREEN); } if(pRect->bottom > (GetSystemMetrics(SM_CYFULLSCREEN) + 10)) { pRect->top = pRect->top + (GetSystemMetrics(SM_CYFULLSCREEN) + 20 - pRect->bottom); pRect->bottom = GetSystemMetrics(SM_CYFULLSCREEN) + 20; } CDialog::OnMoving(fwSide, pRect); }
Funktioniert und läuft auch flüssig.. weiß ja nicht, was du fürn Rechner hast
-
Das scheint sich nicht gerade von meinem Code zu unterscheiden, trotzdem Danke für die Antwort..
-
Wenn ich das Fenster irgendwo andocken lasse, ein paar Sekunden warte und es dann wieder wegziehen will,
-
(Hans Solo/MrDock)
d a n n i s t z u d e m Z e i t p u n k t, i n w e l c h e m s i c h d a s g e d o c k t e F e n s t e r w i e d e r u n d o c k e n l ä s s t , d e r M a u s z e i g e r f a s t a m a n d e r e n E n d e d e s B i l d s c h i r m s.
Das heißt, dass ich den Mauszeiger immens bewegen muss, damit das Verschieben des Fensters wieder funktioniert
-
Und wer setzt den Cursor? Windows nicht!
Benutzt Du irgendwo SetCursorPos?
-
Nein.
We nn ic h da s Fe nster e in w e nig be wege u nd de r Ra dius un ter 10 ble ibt, da nn wir d d as Fe nst er doc h zurü ck a n d ie 'Nu l ler' Posi tion ges etzt (a lso ge do ckt), jed och d er Cur sor bl eib t d a w o e r is t..
-
Und? Was ist das Probklem? Entweder bewegst Du einfach den Cursor umdas Offset mit, oder eben nicht.
Ansonsten würde ich mal die Koordination Deines Dauemns kontrollieren. Irgendwie passen die Leerzeichen nicht an die Stellen wo sie stehen.
-
Entweder bewegst Du einfach den Cursor umdas Offset mit, oder eben nicht.
Und wenn es nur teilweise erfolgt, wandert der Cursor ins Unerreichbare, aber das Fenster bleibt an der Seite kleben.
-
Sample Programm mit dem hier veröffentlichen Code zeigt dieses Verhalten nicht.
-
Martin Richter schrieb:
Sample Programm mit dem hier veröffentlichen Code zeigt dieses Verhalten nicht.
richtig, bei mir läufts einwandfrei, wie bei winamp etc... weiß nicht wo das problem ist...
-
Ein Problem gibt es aber:
wenn das Fesnter angedockt ist und man es wieder verschieben will, muss man schnell mit der maus das Fenster wegziehen. Wenn man aber versuhct das fesnter langsam zu verschieben geht das eben nicht, da bewegt man nur den zeiger.Bei winamp ist das ja nicht der fall, da kann man die fenste auch langsam verschieben,
-
Ist zwar ein altes Topic, aber...du hast Recht. Schade, sowas wäre sonst
vlt. was für die FAQ oder @Mods?
-
Z.B. dieser Codeabschnitt:
if(((RECT*)lParam)->left < 10) { ((RECT*)lParam)->right = ((RECT*)lParam)->right - ((RECT*)lParam)->left; ((RECT*)lParam)->left = 0; }
das bedeutet Eigentlich, dass, wenn das Fenster links angedockt ist, es nicht mehr bewegt werden kann oder?
-
Das Problem ist, dass das Fenster immer wieder zurückgedockt wird.
Man müsste also beim ersten WM_MOVEING die Cursorposition vermerken und das Fenster entdocken, wenn die Distanz, die die Maus bewegt wurde, größer als der Dockbereich wird.Man kann dazu die Nachricht WM_ENTERSIZEMOVE verwenden und die Mausposition speichern und dann mit der Position vergleichen, die man bei WM_MOVING hat.