TMainMenu im Canvas zeichnen (Kopfzeile)
-
Hallo,
ich zeichnen mein komplettes Menü selbst, klappt auch wunderbar.
Nur die Kopfzeile bekomme ich nicht komplett gezeichnet, sondern nur
den Bereich, in dem die Menütexte stehen. Der Rest der Menüzeile
bis zum rechten Rand bleibt in der Farbe clBtnFace. Wie komme ich da
aber zum Zeichnen ran? Die Komponente bietet keine Funktion OnDrawItem
oder so wie die Menüeinträge selbst.Danke für jeden Tip. Im Google und hier finde ich leider nichts oder
ich suche falsch....
Gruss Stefan
-
Du mußt einfach mit Canvas->FillRect() den Hintergrund erst "leeren" (vorher Farbe mit Brush->Color setzen) und danach dann den Menu-Text zeichnen.
Schau dir mal die Eigenschaft Brush->Style an, dann findest du weitere Infos (evtl. kommt dann bei dir der AHA-Effekt).
-
Hallo, TH
ich fürchte nicht ganz. Die Menüs werden ja korrekt gezeichnet, aber eben nur die Fläche, wo auch in der Menüzeile (Datei, Bearbeiten... Hilfe) ein Menütext steht. Es geht aber um die restliche Fläche rechts daneben (also ab dem Menü Hilfe bis zum rechten Rand des Forms), für den ich keine Meldung erhalte, daß er neu gezeichnet werden muss, obwohl dieser Bereich ja zum TMainMenu gehört (oder nicht?) Die Komponente TMainMenu hat aber kein Ereignis OwnerDraw, sondern nur die Menüs selbst.
Gruss Stefan
-
Zeig mal deinen Code von OnDrawItem...
Du kannst das Rechteck auch selbst wählen, d.h. du brauchst nicht unbedingt den übergebenen Rect-Parameter 1:1 übernehmen (vergrößere doch einfach das Rechteck ein bißchen nach rechts (nur für die Hautpmenü-Einträge), bevor du den Hintergrund und den Text zeichnest).
P.S: ich habe gerade deinen Beitrag zum TabControl gelesen. Dort verwendest du ja auch das übergebene Rechteck (kopierst es sogar unnötigerweise). Und dann kannst du es aber genausogut vergrößern (z.B. mit Rect.Right = 800 ).
-
Hei, TH
danke für Deine Tipps...
Die Kopie auf Rect ist notwendig wegen DrawText; sonst kommt Meldung das Mehrdeutigikeit zwischen 'Rect' und 'tabRet*' besteht. Mit der scheinbaren
Übergabe auf CRect funktioniert es.
Mit der RECT Vergrösserung werde ich mir anschauen, sehe aber ein Problem:
Die Verlängerung der RECT wäre ja beim Menü Hilfe notwendig; wird aber nur rechts
ein Teil des Forms überlappt, kommt keine OnDraw Meldung, da das Menü Hilfe nicht neugezeichnet werden würde/müsste. Wozu gehört denn die Fläche rechts daneben?Aber für alle mal hier den Code zum Selbstzeichnen eines Menüs:
Dazu TMainMenu auf OwnerDraw=true setzen und jedem (!) Menüeintrag bei OnDrawItem=Bearbeiten1AdvancedDrawItem() zuordnen. PrgFarbe ist ein
Integerwert z.B. PrgFarbe=clBtnFacevoid __fastcall TForm1::Bearbeiten1AdvancedDrawItem(TObject *Sender, TCanvas *ACanvas, TRect &ARect, TOwnerDrawState State) {try { // Fehlerroutine Start Integer i2,iSymb; AnsiString z1,z2; TColor f1,f2; Boolean o1; // Vars definieren TMenuItem *CurItem = dynamic_cast<TMenuItem *> (Sender); // Versuchen, Sender als MenuItem anzusprechen if (!CurItem) { return; } // Wenn Versuch nicht erfolgreich, dann raus z1=CurItem->Caption; // Menübeschriftung z2=ShortCutToText(CurItem->ShortCut); // Tastenkombination z.B. Alt+F4 f1=PrgFarbe; if(State.Contains(odSelected)==true) { f1=clMenuHighlight; } // HG Farbe ACanvas->Brush->Color=f1; // Farbe HG festlegen ACanvas->FillRect(ARect); // HG befüllen if(z1=="-") { // TRENNSTRICH ARect.Top+=1; ARect.Bottom-=3; // Strich dünner machen ACanvas->Brush->Color=clGray; // Farbe HG festlegen ACanvas->Font->Color =clWhite; // Farbe VG festlegen ACanvas->FrameRect(ARect); // dünnen Balken zeichnen return; // und fertig } // ende if(z1 f1=PrgFarbe; if(State.Contains(odSelected)==true) { f1=clMenuHighlight; } // HG Farbe f2=clMenuText; if(State.Contains(odDisabled)==true) { f2=clGrayText; } // VG Farbe o1=false; // Voreinstellung if(CurItem->Tag==9999) { ARect.Left-=20; ARect.Right+=25; ARect.Top+=1; o1=true; } // Hauptmenüthema (immer linksbündig schreiben da keine Symbole) iSymb=CurItem->ImageIndex; // Grafiksymbol? if(State.Contains(odChecked)==true) { iSymb=58; } // Eintrag hat vorne einen Haken if(Form1->PrgComp && o1==false) { z1=z1+" (iSymb: "+IntToStr(iSymb)+")"; } // nur im IDE if(iSymb>-1) { // ja, vorhanden Graphics::TBitmap *bmp =new Graphics::TBitmap(); // neue Grafik anlegen frm1_ImageList1->GetBitmap(iSymb,bmp); // und aus Imageliste auslesen ACanvas->Draw(1,ARect.Top+1,bmp); // und zeichnen delete bmp; // Bitmap löschen } // ende if(iSymb ARect.Left+=25; ARect.Right-=25; // Koords anpassen wegen Symbole ARect.Top+=2; ARect.Bottom-=2; // Text x Pixel tiefer setzen ACanvas->Brush->Color=f1; // Farbe HG festlegen ACanvas->Font->Color =f2; // Farbe VG festlegen z1=z1+" "; // damit Abstand zu ShortCuts grösser wird DrawText(ACanvas->Handle,z1.c_str(),-1,&ARect,DT_LEFT | DT_SINGLELINE); // Menütext z.B. Beenden if(z2.Length()==0) { return; } // keine Tastenkombination mehr, fertig ARect.Right+=14; // mehr nach rechts rücken DrawText(ACanvas->Handle,z2.c_str(),-1,&ARect,DT_RIGHT | DT_SINGLELINE); // Tastenkombination z.B. Alt+F4 } catch(Exception& e) { MessageBox(NULL, e.Message.c_str(), "TForm1::Datei1DrawItem()", MB_OK); } // Fehler anzeigen }Gruss Stefan
-
Wozu gehört denn die Fläche rechts daneben?
Die Menüleiste selbst wird von Windows gemalt (der sogenannte NonClient-Bereich (NC area)). Da müßtest du schon mit Windows-Messages dran, um diese komplett selbst zu zeichnen.
-
Hei, TH
habe jetzt eine einfache Lösung gefunden:
Ein leeres Pseudomenü angehängt (nach Hilfe), den TAG auf 9998
gesetzt und dies im OnDrawMenü angefangen; RECT.Right auf Screen->Width
gesetzt, Menü Disabled und voila, funktioniert einwandfrei
Gruss Stefan
-
Na, geht doch
