Forms - auf der Captionbar Maus-Events abfangen



  • Hi, wie kann ich auf der Titelleiste eine URL zeichnen, und dieser dann OnClick zufügen, also wenn man auf den Link klickt, dass dieser auch geöffnet wird.

    Vor einiger Zeit hab ich das mal mit Canvas->TextOutA probiert, aber damit kann man ja leider nur einen Text ausgeben.

    Hat jemand ne Idee?

    Wäre echt hilfreich!

    [ Dieser Beitrag wurde am 08.07.2003 um 12:52 Uhr von Tillmann David editiert. ]



  • verarbeitet das ereignis WM_NCLBUTTONDOWN.

    // im header der form
    void __fastcall WMNCLButtonDown(TMessage &Msg);
    
    BEGIN_MESSAGE_MAP
      MESSAGE_HANDLER(WM_NCLBUTTONDOWN, TMessage, WMNCLButtonDown)
    END_MESSAGE_MAP(TForm)
    
    // im code
    void __fastcall TForm1::WMNCLButtonDown(TMessage &Msg)  
    {
      TForm::Dispatch(&Msg);
    
      if (Msg.WParam == HTCAPTION)
        ShowMessage("CAPTION KLICKED");
    }
    

    p.s. währe in zukunft ohne H

    [ Dieser Beitrag wurde am 08.07.2003 um 12:48 Uhr von Sunday editiert. ]



  • Danke!
    Hab den Fehler geändert. 😉

    Und wie definierte ich das jetzt, wenn ich einen Titel habe und nach dem titel einen blauen link haben will, also nur das der link das onevent hat?

    Bsp der Titelleiste:
    Programm 1.2 (http://www.programm.de)

    Dabei soll aber http://www.programm.de nur das onevant haben, das muss man mit koordinaten machen->nur wie. 😞

    Danke schonmal!!!



  • Sieh dir doch mal WM_NCLBUTTONDOWN in der Hilfe an!

    Über den LParam kannst du die Mauskoordinaten ermitteln, mittels TCanvas::TextWidth o.ä. kannst du dann prüfen, ob die Mausposition im Link-Text liegt.



  • siehe nächsten post von mir...

    [ Dieser Beitrag wurde am 11.07.2003 um 16:51 Uhr von Sunday editiert. ]



  • Cool, genau das hab ich gesucht, danke!!!!!!!



  • hier mal eine ganz neue version, zum darstellen einer URL im Caption einer Form.
    ist ja vielleicht mal was für die FAQ?

    //---------------------------------------------------------------------------
    // im HEADER
    //---------------------------------------------------------------------------
    
    private:    
    
        TCanvas    *FormCanvas;   // zeichenfläche des formulares
    
        TRect       URLRect;      // rechteck der URL
    
        int         CaptionWidth; // breite der caption
        int         URLWidth;     // breite der URL
    
        TColor      URLNormal;    // normale farbe der URL
        TColor      URLOver;      // mouseover farbe der URL
        bool        URLStateOver; // status der URL
    
        AnsiString  URLString;    // die eigentliche URL
        AnsiString  ACaption;     // anfangstext der caption
        AnsiString  ECaption;     // endtext der caption (kann leer sein)
    
        void __fastcall SetSystemFont(TCanvas *FCanvas);
        void __fastcall DrawURL(TColor TextColor);
        bool __fastcall MouseInURL(LPARAM lparam);
    
        // ereignis methoden
        void __fastcall WMNCLButtonDown(TMessage &Msg);
        void __fastcall WMNCPaint(TMessage &Msg);
        void __fastcall WMNCHitTest(TMessage &Msg);
        void __fastcall WMNCActivate(TMessage &Msg);
        void __fastcall WMMouseMove(TMessage &Msg);
        void __fastcall WMActivate(TMessage &Msg);
    
        // folgende ereignisse abfangen
        BEGIN_MESSAGE_MAP
          MESSAGE_HANDLER(WM_NCLBUTTONDOWN, TMessage, WMNCLButtonDown)
          MESSAGE_HANDLER(WM_NCPAINT,       TMessage, WMNCPaint)
          MESSAGE_HANDLER(WM_NCHITTEST,     TMessage, WMNCHitTest)
          MESSAGE_HANDLER(WM_NCACTIVATE,    TMessage, WMNCActivate)
          MESSAGE_HANDLER(WM_MOUSEMOVE,     TMessage, WMMouseMove)
          MESSAGE_HANDLER(WM_ACTIVATE,      TMessage, WMActivate)
        END_MESSAGE_MAP(TForm)
    
    //---------------------------------------------------------------------------
    // im QUELLCODE
    //---------------------------------------------------------------------------
    
    __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
    {
      URLString = "http://www.ricosonntag.de";
      ACaption  = "URL-Caption-Klick-Test [";
      ECaption  = "]";
    
      Caption   = "";
    
      URLOver   = clRed;
      URLNormal = clLime;
    }
    
    // funktion setzt den aktuelle systemfont für die caption
    void __fastcall TForm1::SetSystemFont(TCanvas *FCanvas)
    {
      LOGFONT          FormFont;
      NONCLIENTMETRICS NCM;
    
      NCM.cbSize = sizeof(NONCLIENTMETRICS);
    
      // den aktuellen Systemfont auslesen
      if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &NCM, 0) != 0)
      {
        // Informationen über den aktuelle Font der Form holen
        // -> Systemfont setzen
        if (GetObject(FCanvas->Font->Handle, sizeof(LOGFONT), &FormFont) != 0)
          FormFont = NCM.lfCaptionFont;
    
        // neuen (geänderten) Font auswählen und der Zeichenfläche zuweisen
        FCanvas->Font->Handle = CreateFontIndirect(&FormFont);
      }
    }
    
    // funktion prüft, ob sich die maus im rechteck der URL befindet
    bool __fastcall TForm1::MouseInURL(LPARAM lparam)
    {
      int LSpace = GetSystemMetrics(SM_CXBORDER) + GetSystemMetrics(SM_CXFRAME);
      int TSpace = GetSystemMetrics(SM_CXSIZE);
    
      POINTS MPoints    = MAKEPOINTS(lparam);
      TPoint MousePoint = TPoint(MPoints.x + LSpace, (MPoints.y + TSpace));
      MousePoint        = ScreenToClient(MousePoint);
    
      return PtInRect(&URLRect, MousePoint);
    }
    
    // den text der URL zeichnen
    void __fastcall TForm1::DrawURL(TColor TextColor)
    {
      TCanvas *FCanvas = new TCanvas();
      FCanvas->Handle  = GetWindowDC(Handle);
    
      // systemfont setzen
      SetSystemFont(FCanvas);
    
      FCanvas->Font->Color = TextColor;
    
      // hintergrund nicht verarbeiten
      SetBkMode(FCanvas->Handle, TRANSPARENT);
    
      // url zeichnen
      DrawText(FCanvas->Handle, URLString.c_str(), -1, &URLRect, DT_SINGLELINE | DT_VCENTER | DT_LEFT);
    
      ReleaseDC(Handle, FCanvas->Handle);
      FCanvas->Handle = 0;
    
      delete FCanvas;
    }
    
    // testen ob sich die maus über dem URL-Rechteck befindet
    // und wenn ja die farbe der URL ändern
    void __fastcall TForm1::WMNCHitTest(TMessage &Msg)
    {
      TForm::Dispatch(&Msg);
    
      if (Msg.Result == HTCAPTION)
      {
        if (MouseInURL(Msg.LParam))
        {
          URLStateOver = true;
    
          // mauszeiger verändern
          ::SetCursor(Screen->Cursors[crHandPoint]);
    
          // url neu zeichnen
          DrawURL(URLOver);
        }
        else
        {
          URLStateOver = false;
    
          // url neu zeichnen (maus ist ausserhalb)
          DrawURL(URLNormal);
        }
      }
    }
    
    // beim aktivieren der form -> neu zeichnen
    void __fastcall TForm1::WMActivate(TMessage &Msg)
    {
      TForm::Dispatch(&Msg);
    
      Perform(WM_NCPAINT, 0, 0);
    }
    
    // wenn fenster aktiv wird, neu zeichnen
    void __fastcall TForm1::WMNCActivate(TMessage &Msg)
    {
      TForm::Dispatch(&Msg);
    
      Perform(WM_NCPAINT, 0, 0);
    }
    
    // wenn maus im formular bewegt wird, farbe der URL zurücksetzen
    void __fastcall TForm1::WMMouseMove(TMessage &Msg)
    {
      TForm::Dispatch(&Msg);
    
      if (URLStateOver)
      {
        URLStateOver = false;
        DrawURL(URLNormal);
      }
    }
    
    // linke maustaste wurde im nonclient-bereich des formulares gedrückt
    // (caption, frame, border, ...)
    void __fastcall TForm1::WMNCLButtonDown(TMessage &Msg)
    {
      TForm::Dispatch(&Msg);
    
      if (Msg.WParam == HTCAPTION)
      {
        // link ausführen, wenn maus im bereich der URL
        if (MouseInURL(Msg.LParam))
          ShellExecute(0, "open", URLString.c_str(), 0, 0, SW_SHOWNORMAL);
      }
    }
    
    // zeichenfunktion für den nonclient-bereich des formulares
    void __fastcall TForm1::WMNCPaint(TMessage &Msg)
    {
      TForm::Dispatch(&Msg);
    
      // text-attribute setzen
      FormCanvas         = new TCanvas();
      FormCanvas->Handle = GetWindowDC(Handle);
    
      // systemfont setzen
      SetSystemFont(FormCanvas);
    
      // farbe des textes setzen
      if (Active) FormCanvas->Font->Color = clCaptionText;
      else        FormCanvas->Font->Color = clInactiveCaptionText;
    
      // breite des textes ermitteln
      int URLWidth     = FormCanvas->TextWidth(URLString);
      int CaptionWidth = FormCanvas->TextWidth(ACaption);
    
      TRect WindowRect;
    
      // rechteck des fensters holen
      GetWindowRect(Handle, (LPRECT) &WindowRect);
    
      int LeftSide       = GetSystemMetrics(SM_CXSIZE)   +
                           GetSystemMetrics(SM_CXBORDER) +
                           GetSystemMetrics(SM_CXFRAME);
    
      TRect CaptionRect;  // rechteck der verfügbaren caption
      TRect OutputRect1;  // rechteck des 1. caption-textes
      TRect OutputRect2;  // rechteck des 2. caption-textes
    
      // caption-rechteck berechnen
      CaptionRect.Left   = LeftSide;
      CaptionRect.Top    = GetSystemMetrics(SM_CYFRAME); // + 1;
      CaptionRect.Right  = WindowRect.Right - WindowRect.Left - (LeftSide * 3) - GetSystemMetrics(SM_CXFRAME);
      CaptionRect.Bottom = CaptionRect.Top + GetSystemMetrics(SM_CXSIZE) - 1;
    
      // rechteck der url berechnen
      URLRect.Left       = CaptionRect.Left + CaptionWidth;
      URLRect.Top        = CaptionRect.Top;
      URLRect.Right      = URLRect.Left + URLWidth;
      URLRect.Bottom     = CaptionRect.Bottom;
    
      // ausgaberechteck für 1. captiontext
      OutputRect1.Left   = CaptionRect.Left;
      OutputRect1.Right  = CaptionRect.Left + CaptionWidth;
      OutputRect1.Top    = CaptionRect.Top;
      OutputRect1.Bottom = CaptionRect.Bottom;
    
      // ausgaberechteck für 2. captiontext
      OutputRect2.Left   = CaptionRect.Left + CaptionWidth + URLWidth;
      OutputRect2.Right  = CaptionRect.Right;
      OutputRect2.Top    = CaptionRect.Top;
      OutputRect2.Bottom = CaptionRect.Bottom;
    
      // hintergrund nicht verarbeiten
      SetBkMode(FormCanvas->Handle, TRANSPARENT);
    
      // text zeichnen
      DrawText(FormCanvas->Handle, ACaption.c_str(), -1, &OutputRect1, DT_SINGLELINE | DT_VCENTER | DT_LEFT);
      DrawText(FormCanvas->Handle, ECaption.c_str(), -1, &OutputRect2, DT_SINGLELINE | DT_VCENTER | DT_LEFT);
    
      // wieder alles freigeben
      ReleaseDC(Handle, FormCanvas->Handle);
      FormCanvas->Handle = 0;
    
      // url zeichnen
      DrawURL(URLNormal);
    }
    

    anmerkung:

    ist für ein formular mit systemmenü, minimize und maximize button. bei anderen einstellungen müssen die rechtecke für caption und url angepasst werden.

    viel spass damit...

    [ Dieser Beitrag wurde am 12.07.2003 um 11:58 Uhr von Sunday editiert. ]



  • Hah, du willst doch nur deine Website promoten! 😉

    Im Ernst, eine schöne Lösung. Eventuell könnte man die Schriftgrösse noch automatisch an die Systemschrift anpassen?



  • hab den code angepasst, an den jeweils aktuell gewählten systemfont für die caption. ebenso wir die caption jetzt deaktiviert dargestellt, wenn die anwendung den fokus verliert.


Anmelden zum Antworten