Ersterstellte Controls sollen immer "oben" bleiben (Z-Order?)



  • Hallo,
    Ich probier grad ein wenig herum mit der WinAPI.
    Ich möchte dem User die Möglichkeit geben die Controls (Edit & Buttons)
    so auf dem Fenster herum zu schieben wie er möchte.

    Das hab ich auch schon alles hingekriegt. Das einzige, was mich noch
    stört:
    Ich erstelle die Buttons vor den Edits. Wenn ich alles richtig verstanden
    habe, ist laut Z-Order der Button nun "über" der Editbox.

    Das funktioniert am Anfang ja auch. Wenn man jetzt aber die Editbox anklickt
    und übers Fenster schiebt, kann sie den Button überdecken...
    Das möchte ich verhindern, weil der Button immer sichtbar sein soll...

    Gibts da einen Trick?

    Achja, ich habe bereits MoveWindow & SetWindowPos(mit SWP_NOZORDER) ausprobiert.
    Daran scheints aber nicht zu liegen.

    Zum Bewegen der Fenster registiere ich die Mousemoves auf dem HWND (SetCapture)
    und schiebe das Fenster einfach "hinterher"... (Falls das von überhaupt von Bedeutung ist)

    Bin über jeden Tip dankbar!



  • Du könntest den Buttons SetWindowPos(..., HWND_TOPMOST, ...) zuweisen - so sind sie immer oben ... mehr oder weniger elegant 😉

    M.T.



  • Ja, das wär ne Möglichkeit. 🤡
    Aber irgendwie unbefriedigend... da ich plane später zb. noch eine Listbox zu
    verwenden, wo wiederrum das Editcontrol drüber sein soll...

    Also muß ich irgendwie auf Z-Order zugreifen... aber wie 😞



  • du machst etwas falsch, denn bei der Angabe des SWP_NOZORDER Flags, wird an der Reihenfolge, auf der Z-Achse nichts verändert. Zeig mal ein bisschen Code...



  • ok:

    Also jedes "Objekt" hat dieselben Funktionen für Mousemove & Mouseup/down:

    case WM_MOUSEMOVE:
    		  SetCursor (LoadCursor (NULL, IDC_ARROW)) ;	
    		  if (wParam == MK_LBUTTON) {				
    			/*meine Funktion, die einen Rahmen zeichnet,
                                 anstatt das Control direkt zu verschieben
                                 (Hier wird erst der alte Rahmen gelöscht)
                                 (Rahmen 2 Mal zeichnen=löschen)*/
                               DrawFrame(hwnd,&oldrect,false);
    		         GetWindowRect(hwnd,&wrect);
                               //neue Pos ermitteln
    			wrect.left = wrect.left + (pt.x-startx);
    			wrect.top = wrect.top + (pt.y-starty);
    			wrect.right = wrect.left + width;
    			wrect.bottom = wrect.top + height;				
    			//Rahmen an neuer Pos zeichnen
                                DrawXorFrame(hwnd,&wrect,false);
    			CopyRect(&oldrect,&wrect);
    		 }
    		 return 0;
          case WM_LBUTTONDOWN:
    		 startx = pt.x;
    		 starty = pt.y;		 
    		 SetCapture(hwnd);
    		 GetWindowRect(hwnd,&oldrect); 
    		 width = oldrect.right - oldrect.left;
    		 height = oldrect.bottom - oldrect.top;
    
    		 DrawFrame(hwnd,&oldrect,false);
    		 return 0;
          case WM_LBUTTONUP:		 
    		 ReleaseCapture();
                       //Rahmen wird gelöscht
    		 DrawFrame(hwnd,&oldrect,false);		 		 		 		 
    		 //MoveWindow(hwnd,GetWindowLeft(hwnd,oldrect),GetWindowTop(hwnd,oldrect),width,height,true);	 
    		 SetWindowPos(hwnd,0,GetWindowLeft(hwnd,oldrect),GetWindowTop(hwnd,oldrect),width,height,SWP_NOZORDER);
    		 //InvalidateRect(GetParent(hwnd),0,true);
    		 InvalidateRect(hwnd,0,true);
    		 return 0;
    ...
    return CallWindowProc ((WNDPROC) alteWNDProc, hwnd, message, wParam, lParam);
    

    Die Variablen in der WNDPROC sind:

    POINT pt;
    	pt.x = GET_X_LPARAM(lParam); 
    	pt.y = GET_Y_LPARAM(lParam);	
    	static RECT wrect, oldrect;	
    	static int startx, starty, width, height;
    

    Wie man leicht erkennen kann, werden die einzelnen "Objekte" einfach durch LBUTTONDOWN erkannt.
    Das ist auch das Problem. Sobald man die Controls angeklickt hat, sind sie schon ganz zu
    sehen.

    Wär cool, wenn jmd. meinen Fehler finden kann 🙂



  • Vielleicht ist noch interessant, daß die Controls nicht in "WM_CREATE" erstellt werden,
    sondern nur auf Wunsch des Users. (bei einem Click auf einen Button wird ein weiteres
    Fenster(Button od. Edit) erstellt...

    Vielleicht ist das noch wichtig



  • Vereinfachen den Code doch mal soweit, dass du weist, was genau dazu führt, dass das Control in den Vordergrund kommt 🙂



  • Also ich hab jetzt mal das

    InvalidateRect(hwnd,0,true);
    

    in LBUTTONUP weggenommen und dann kommt es auch nicht mehr
    in den Vordergrund. ABER wenn man das Editfenster,
    was unterhalb des Buttons ist wieder "freischiebt", dann
    sieht man darauf noch den Button (also nur das Aussehen)



  • Nein, quatsch... zu früh gefreut..
    (Das sah natürlich nur so aus)



  • Wie jetzt? Lag es an InvalidateRect, oder nicht? 😕



  • Nein, lag leider nicht dran.
    (Da in der EditBox soz. ein Foto von dem Button war,
    sah es erst so aus)


Anmelden zum Antworten