mouseover/mouseout funktion (label) - workaround?!



  • meins geht da mal 🙄 man muss nur entweder bei jeder Mausbotschaft die an Application gesendet wird check()aufrufen oder es in jedes MouseMove von jeder halbwegs in der Nähe befindlichen Komponente reinmachen



  • @Devil:

    Das mit den Komponenten hatte ich nicht berücksichtigt. Ja ich habe MySQLDAC V1.97 gekauft 😃 Aber es geht ja auch hauptsächlich um die *.h, *.cpp und die *.exe.

    Das Problem mit dem Panel kann man ansatzweise wie folgt lösen, es ist aber sicherlich nicht der Weisheit letzter Schluß:

    void __fastcall TForm1::OnMouseOver(TMessage & Msg)
    {
      if( ((TLabel *)Msg.LParam) == Panel1) // :D
      {
           Label1->Caption = "Mouse Over";
      }
    }
    

    Warum bei den VCL-Messages nicht der Name des Labels zurückgeliefert wird würde mich mal interessieren. 😕 Meiner Meinung nach ist es egal worauf das Label abgelegt ist, es muß doch eine Möglichkeit geben an den Namen des Labels unter dem Mauspfeil ranzukommen...
    Leider bin ich hier nicht der C++ Held 😞



  • hier mal eine Panel Version

    ich habe auch mal ein beispiel project hochgeladen:
    http://www.byte-island.com/bcb/mouseover.zip

    void __fastcall TForm1::OnMouseOver(TMessage & Msg)
    {
        if(((TLabel *)Msg.LParam) == Label2) ((TLabel *)Msg.LParam)->Color = clRed;
        else if( ((TPanel *)Msg.LParam) == Panel1 )
        {
             TPoint pos; GetCursorPos(&pos);
             TControl *control = ((TPanel *)Msg.LParam)->ControlAtPos(((TPanel *)Msg.LParam)->ScreenToClient (pos),false,true);
             if(control != NULL)
               if(control->ClassType() == Label1->ClassType()) ((TPanel *)control)->Color = clRed ;
        }
    }
    
    void __fastcall TForm1::OnMouseOut(TMessage & Msg)
    {
        if( ((TLabel *)Msg.LParam) == Label2) ((TLabel *)Msg.LParam)->Color = clYellow;
        else if( ((TPanel *)Msg.LParam) == Panel1 )
        {
             TPoint pos; GetCursorPos(&pos);
             TControl *control = ((TPanel *)Msg.LParam)->ControlAtPos(((TPanel *)Msg.LParam)->ScreenToClient (pos),false,true);
             if(control == NULL)  Label1->Color = clYellow ;
        }
    }
    

    [ Dieser Beitrag wurde am 01.07.2002 um 14:04 Uhr von raYne editiert. ]



  • möcht ja jetzt echt nich meckern oder so... aber nun setze ich auf das panel noch ne groubox (is bei mir wirklich so) und mach dann dort mein label rein und dann geht es ja wieder nicht....

    gibt es da echt keine einheitliche lösung für... muss man da wirklich jede eventualität einzeln berücksichtigen... d.h. wenn ich noch ein panel oder sonstwas hinzufüge, dann kann ich wieder meine ganze funktion umschreiben....!?

    😞 😕



  • So, jetzt reichts! <devil>, warum gehst du nicht meinem Vorschlag nach? Auf OnMouseMove der GroupBox reagieren! Scheinbar haben die Leute hier nicht durchgelesen, wo sich das Label von Devil befindet. Hier nochmal für alle:
    Das Label befindet sich in einer GroupBox, die auf einem Panel sitzt, das sich auf der Form befindet!
    Alles klar? Das heißt: Man kommt mit Message_Handlern nicht weiter. Und man frage sich außerdem, welche BCB-Standard-Events ausgelöst werden, wenn der Cursor das Label verlässt. Die Antwort ist: OnMouseMove der GroupBox, und sonst NICHTS! Das heißt:

    Er MUSS entweder auf das OnMouseMove der GroupBox reagieren oder für sein Panel ne neue WindowProc machen.

    Zu der ersten Variante habe ich ihm schon geraten. Das scheint er aber aus irgendeinem Grund nicht zu wollen. Daher erkläre ich jetzt, wie man für das Label eine neue WindowProc macht, damit sich dieser Thread langsam mal seinem Ende zuneigt:

    //  HEADER
    private:
      Controls::TWndMethod OldLabelProc;
      void __fastcall NewLabelProc(TMessage& Msg);
    
    //  CPP-Datei
    __fastcall TForm1::TForm1(TComponent* Owner)
            : TForm(Owner)
    {
      OldLabelProc       = Label1->WindowProc;
      Label1->WindowProc = NewLabelProc;
    }
    //------------------------------------------------------------------------------
    
    void __fastcall TForm1::NewLabelProc(TMessage &Msg)
    {
       if(Msg.Msg==CM_MOUSEENTER)
       {
          //  Hier der Code für OnMouseOver
       }
    
       if(Msg.Msg==CM_MOUSELEAVE)
       {
          //  Hier der Code für OnMouseOut
       }
    
       OldLabelProc(Msg);
    }
    


  • @WebFritzi: Warum machst du das immer mit:

    OldLabelProc = Label1->WindowProc;
    Label1->WindowProc = NewLabelProc;

    Ich dachte man kann die WindowProc (virtuelle Methode?) überschreiben.



  • *push*



  • *noch ein letztes mal* :p



  • Original erstellt von <blat>:
    Ich dachte man kann die WindowProc (virtuelle Methode?) überschreiben.

    Hi,

    ich bin zwar nicht WebFritzi aber ich tu mal so.

    Sicherlich gibt es die von Steuerelementen. Ist aber keine virtuelle Methode sondern ein Methodenpointer auf den Typ TWndMethod. Was WebFritzi da macht, ist den Pointer der Komponente zwischenzuspeichern und eine neue eigene Methode hinzufügen.

    Am Ende, wenn das Objekt zerstört werden soll, muss der zwischengespeicherte Pointer wieder hergestellt werden. Begründung: Eventuell werden in der Proc noch weitere Routinen aufgerufen, die für die Zerstörung von untergeordneten Objekten zuständig sind.

    [ Dieser Beitrag wurde am 26.02.2003 um 19:49 Uhr von AndreasW editiert. ]



  • Neee, das Wichtige am Speichern der OldWndProc ist, dass sie in der neuen WindowProc wieder aufgerufen werden muss (meist am Ende derer). Das verhält sich wie beim Subclassing von Windows-Controls.


Anmelden zum Antworten