Fenster an Bildschirmrand docken



  • Ich raff's nicht 😑

    Weshalb soll das nicht in die WM_MOVING Nachricht? 😕


  • Mod

    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.aspx

    lParam
    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 Value

    An 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


  • Mod

    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..


  • Mod

    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.


  • Mod

    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?


  • Mod

    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.


Anmelden zum Antworten