OnMouseMove auf ganzem Formular nutzen?



  • Hallo, ich habe mein Formular mit vielen Panels und anderen Komponenten "vollgepflastert" 😃

    Ich habe nun ein paar Befehle in das MouseMove-Ereignis des Formulars geschrieben, aber die werden nur ausgeführt, wenn ich wirklich mit der Maus über einem noch freiem Fleckchen des Formulars bin ... Wie kann ich das denn abändern, so dass mein Code immer bei einer Mausbewegung ausgeführt wird, egal über welcher Komponente sich mein Mauszeiger befindet?

    Liebe Grüße Michel



  • Ich befürchte du musst dann in den OnMouseMove() von jedem Steuerelement das OnMouseMove() von der Form aufrufen.



  • Hi,

    die einzigste Message, die man zuverlässig dafür nutzen kann, ist mE. WM_SETCURSOR.

    Die gibt zwar nicht die Mauskoordinaten, aber die werden einfach in dieser Messageverarbeitung abgefragt:

    // in Message-Map oder WndProc schreiben:
       POINT P;
       GetCursorPos(&P);
       ::ScreenToClient(Form1->Handle, &P);  // Umrechnung auf betreffendes Formular bezogen
       // anzeigen
       StatusBar->Panels->Items[0]->Text = " X : " + IntToStr(P.x);
       StatusBar->Panels->Items[1]->Text = " Y : " + IntToStr(P.y);
    

    mfg
    kpeter



  • Super, das mit der WindowsMessage hat funktioniert! Nur die Koordinaten hauen nicht so richtig hin ...

    Ich ziehe per Drag & Drop ein Panel über die Form. Wenn ich auf ein StringGrid klicke, soll das angeklickte Feld seine Farbe in die Farbe des Panels ändern!
    Aber ich habe immer noch das Problem, dass nun das bestimmte, angeklickte Feld im Grid erst bei 2. Mal Klicken die Farbe annimmt. Wieso ist das so? Wird das DrawCell-Ereignis nicht immer gleich ausgeführt?



  • MichelM schrieb:

    Nur die Koordinaten hauen nicht so richtig hin ...

    Die Berechnung erfolgt exakt. Wo gibts denn Abweichnungen?

    Zum Thema DrawCell mach bitte einen neuen Thread auf. Ist hier OT 😉

    mfg
    kpeter



  • die X-koordinate (waagerechte) stimmt ja, aber die Y-Koordinate (senkrechte) ist um ca. 150 pixel zu groß! Der Mauszeiger ist also ca. 150 Pixel höher als das Panel ...

    void __fastcall TKTPMainForm::WndProc(Messages::TMessage &Message)
    {
    // Cursor-Position bestimmen
    	switch (Message.Msg) {
    		case WM_SETCURSOR: {
    			POINT P;
    			GetCursorPos(&P);
    			::ScreenToClient(KTPMainForm->Handle, &P);  // Umrechnung auf betreffendes Formular bezogen
    			// anzeigen
    			if (dragndrop) {
    				ErzieherPanel->Left = P.x - ErzieherPanel->Width / 2 ;
    				ErzieherPanel->Top = P.y - 150;// - ErzieherPanel->Height / 2 ;
    			}
    			break ;
    		}
    		default:
    		;
    	}
    	TForm::WndProc(Message) ;
    }
    


  • Hallo,

    wahrscheinlich musst du die Mauskoordinaten auf dem Panel noch rausrechnen.

    // in *.h
    private:
        bool dragndrop;
        int xpos;
        int ypos;
    //--------------------
    in *.cpp
    
    void __fastcall TForm1::Panel1MouseDown(TObject *Sender,
          TMouseButton Button, TShiftState Shift, int X, int Y)
    {
        dragndrop = ! dragndrop;
    
        xpos = X;  // Mauskoordinaten auf dem Panel, speichern
        ypos = Y;
    }
    
    // in WndProc:
       .
       ::ScreenToClient(Form1->Handle, &P);
    
       if (dragndrop) {
          Panel1->Left = P.x - xpos;
          Panel1->Top  = P.y - ypos;
       }
       .
       .
    

    Beim Klick aufs Panel wird der bool gesetzt, die X- und Y- Pos wird gespeichert.
    Wird die Maus nun bewegt, geht das Panel mit. Beim nächsten Mausklick wird das Panel abgelegt. Pixelgenau 😃
    Probiers mal so.


Anmelden zum Antworten