Position der Form
-
aus der werd ich nicht ganz schlau. Hier mal meine Funktion:
void TfrmMain::OpenFormOnFixedPos(TForm* frm) { TPoint pForm, pButton; pForm = ClientToScreen(); //hier müssten doch die Koordinaten des Buttons rein oder? frm->Left = pForm.x; frm->Top = pForm.y; frm->ShowModal(); }
ich komm an dieser Stelle nicht weiter
-
so vielleicht. Funktioniert aber leider nicht:
void TfrmMain::OpenFormOnFixedPos(TForm* frm, TLMDSpeedButton* btn) //öffnet Forms an Position der Komponente { TPoint p = ClientToScreen(Point(btn->Left, btn->Top)); frm->Left = p.x; frm->Top = p.y; frm->ShowModal(); }
-
rudpower schrieb:
so vielleicht. Funktioniert aber leider nicht:
void TfrmMain::OpenFormOnFixedPos(TForm* frm, TLMDSpeedButton* btn) //öffnet Forms an Position der Komponente { TPoint p = ClientToScreen(Point(btn->Left, btn->Top)); frm->Left = p.x; frm->Top = p.y; frm->ShowModal(); }
Was funktioniert nicht ?
Das Fenster soll "neben" dem Button erscheinen ?
Die Breite der Komponente zum frm->Left addieren.
-
Was funktioniert nicht ?
die Position des Fensters stimmt weder in der x noch in der y Richtung. Es ist viel weiter links. Es gibt mehrere solcher Buttons, die ein kleines Fenster öffnen. Ruf ich die Funkion in einem anderen Button auf für ein anderes Fenster öffnet sich dieses an der selben Position wie das erste Fenster. Dies wundert mich, da ich ja als Parameter den Button übergebe.
Das Fenster soll "neben" dem Button erscheinen ?
Das neue Fenster soll direkt neben dem Button mit der Oberkante abschließen so dass es rechts daneben steht.
Die Breite der Komponente zum frm->Left addieren.
Ja damit das Fenster, wenn es dann funktioniert, nicht direkt über dem Button steht. Das Fenster sollte ja nach der Funktion oben direkt links am Button anliegen.
Edit: Ich hab mir mal die Funktion mit dem Debugger angeschaut. Ich zeig das mal an den x-Werten. Die Komponenten haben in der Entwurfsansicht folgende Werte:
btn->Left=66 ---> Panel: pan->Left=340 ---> Form: frmMain->Left = 247 (Der Button liegt in einem Panel. Dieses liegt direkt auf der Form.)
Im Debugger zeigt er mir aber in der ersten Zeile der Funktion, dass p gleich 317 sein soll. Wenn ich die oben gezeigten Werte zusammenrechne, müsste x aber 653 haben.
-
Hier mal ne Lösung mit der WinAPI-Funktion ClientToScreen.
In diesem Bsp. haben die vier TButtons die Tags 0 bis 3 und das selbe Klick-Event.void __fastcall TFormMain::Button1Click(TObject *Sender) { // deine Forms; werden passend zu den Button-Tags abgerufen TForm* frm[4] = {FormA, FormB, FormC, FormD}; TButton* btn = dynamic_cast<TButton*>(Sender); if ( NULL != btn) { POINT pt; pt.x = btn->Left; pt.y = btn->Top; ::ClientToScreen(btn->Handle, &pt); int tag = btn->Tag; frm[tag]->Left = pt.x - btn->Left + btn->Width + 2; frm[tag]->Top = pt.y - btn->Top; frm[tag]->Show(); } }
Das jeweilige Form wird 2 Pixel rechts neben dem Button positioniert.
-
ok. Was ich in dem Code nicht verstehe sind folgende Zeilen:
TButton* btn = dynamic_cast<TButton*>(Sender); if ( NULL != btn) {
::ClientToScreen(btn->Handle, &pt);
Müssen hier die 2 Doppelpunkte da sein? In der Hilfe hatte die Methode nur einen Parameter. Vll funktionierte es deshalb bei mir nicht.
-
Hallo
1. Der dynamic_cast prüft, ob Sender vom Typ TButton ist. Wenn ja, wird der Block innerhalb der Bedingung ausgeführt.
2. Mit den beiden Doppelpunkten vor ClientToScrenn zwingst du den Compiler, die statische Funktion aus dem anonymen Namespace zu verwenden (wo alle Funktionen landen, die nicht explizit in einem Namenspace oder als Member einer Klasse definiert werden), und nicht die Membermethode mit dem gleichen Namen.
In deinem Code hast du in der Tat die falsche Methode verwendet. Allerdings liegt das eher daran, das du nicht die richtigen Parameter übergeben hast. Mit den richtigen Parametern hätte der Compiler die richtige Funktion auch selber gefunden.bis bald
Stefan
-
ok, da gibts noch ein Problem. Ich verwende statt einem TButton ein TLMDSpeedButton (LMDTools), der keine Eigenschaft mit der Bezeichnung "Handle" hat.
-
Hallo rudpower,
ich meinte ja auch:
TPoint p = btn->ClientToScreen(Point(x, y));
wobei x und y die Koordinaten relativ zu deinem Button sind, z.B. rechts oben:
x = btn->Width; y = 0;
-
super so funktioniert es. Ich danke Euch vielmals. Hier die Funktion:
void __fastcall TfrmMain::btnSetV1Click(TObject *Sender) { //Forms werden passend zu den Button-Tags abgerufen und rechts neben Button positioniert TForm* frm[5] = {frmV1, frmP4, frmP2, frmP1, frmP3}; TLMDSpeedButton* btn = dynamic_cast<TLMDSpeedButton*>(Sender); if (NULL != btn) { POINT pt = btn->ClientToScreen(Point(btn->Width + 2, 0)); int tag = btn->Tag; frm[tag]->Left = pt.x; frm[tag]->Top = pt.y; frm[tag]->ShowModal(); } }