Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - PopUpMenu aufpoppen lassen *g*


Andreas L. - So 15.02.04 20:31
Titel: PopUpMenu aufpoppen lassen *g*
Hi,
wie kann ich machen das bei Buttonclick ein PopUpMenu an der unteren, linken Kante eines Buttons aufklappt?

Habe da schon ein bisschen geschaut:


Delphi-Quelltext
1:
PopUpMenu1.popup(X:Integer, Y:Integer);                    


Ja, das ist kein Problem. Das einzige Problem sind die Koordinaten. Das PopUpMenu geht ja vom gesamten Bildschirm aus, also kann ich nicht festlegen wo es aufklappen soll, da das Form ja hin und her geschoben sein könnte.


Delphi-Quelltext
1:
PopUpMenu1.popupcomponent :=TComponent;                    


1. Wenn ich SpeedButton1 hinschreibe erscheint das Menü gar nicht am Bildschirm; 2. Wenn es gehen würde dann könnte ich ja nicht festlegen wo am Button es auftauchen soll.


Delphi-Quelltext
1:
BcBarPopUpMenu1.popupatcurser;                    


Hier habe ich eine Komponente (Bluecave BarMenu PopUpMenu) die ich schon seit längeren habe, sie bittet die obere Funktion an, leider taucht das Menü wirklich am Curser auf...

Könnt ihr mir helfen?

Greetz und thx


StefanH - So 15.02.04 20:43

vllt Form.Left + SpeedButton.Left nehmen????


Motzi - So 15.02.04 22:06

Es gibt 2 Methoden die die Punkt-Koordinaten relativ zu einem Controls umrechnen: ClientToScreen() bzw ScreenToClient()... näheres dazu findet man in der OnlineHilfe... 8)


Andreas L. - Mo 16.02.04 17:28

Onlinehilfe hat folgendes geschrieben:

Translates a given point from client area coordinates to global screen coordinates.

function ClientToScreen(const Point: TPoint): TPoint;

Description

Use ClientToScreen to convert a point whose coordinates are expressed locally to the control to the corresponding point in screen coordinates. In client area coordinates (0, 0) corresponds to the upper left corner of the control's client area. In screen coordinates (0, 0) corresponds to the upper left corner of the screen.

Use ScreenToClient along with ClientToScreen to convert from one control's coordinate system to another control's coordinate system. For example,

P := TargetControl.ScreenToClient(SourceControl.ClientToScreen(P));

converts P from coordinates in SourceControl to coordinates in TargetControl.


Wie bitte????


Motzi - Mo 16.02.04 18:04

Nix verstehen...? ;)

Ganz einfach.. du übergibst der Methode ClientToScreen eine Variable vom Typ TPoint und bekommst einen TPoint zurück. Der Rückgabewert enthält dann die Koordinaten die relativ zum Bildschirm sind. Berechnet werden die Koordination dabei ausgehend von der Position des Controls dessen Methode zu aufgerufen hast... jetzt etwas klarer..?


Andreas L. - Mo 16.02.04 18:23

Motzi hat folgendes geschrieben:
jetzt etwas klarer..?


Ne....

Kannste mir mit einen kleinen Beispiel helfen?


Anonymous - Mo 16.02.04 18:42


Delphi-Quelltext
1:
ScreenPosition := ClientToScreen(point(x,y));                    


so, z.B. (in Mouse-Move/Down/Up)


Motzi - Mo 16.02.04 18:43

Ok.. du hast ein Formular namens Form1, das sich ander Position Left:200, Top:100 befindet und auf diesem Formular einen Button namens Button1 mit Left:10 und Top:10


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
var
  aPoint: TPoint;

aPoint := Point(1,1);

aPoint := Form1.ClientToScree(aPoint);

aPoint hat nun den Wert x:201, y:101 - wieso? Weil Das Formular an der Position 200,100 ist und wir den Punkt 1,1 ausgehend vom Formular auf die Bildschirm-Koordinaten umrechnen, also Form1.Left + aPoint.x bzw Form1.Top + aPoint.y


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
var
  aPoint: TPoint;

aPoint := Point(1,1);

aPoint := Button1.ClientToScree(aPoint);

In diesem Fall werden die neuen Koordinaten ausgehend vom Button berechnet.. also praktisch nach dem Schema Form1.Left + Button1.Left + aPoint.x und genauso auch für y...

Probier einfach mal ein bisschen herum und schau dir mit dem Debugger die Ergebnisse der Umrechnung an (oder gib sie in einfach einem kleinen Test-Programm aus..)


Andreas L. - Mo 16.02.04 18:53

Verwirrend :nut:

Ich danke dir für deine Hilfe, werde mich zu einen späteren Zeitpunkt mit den Testergebnissen wiedermelden :-)

Greetz


Andreas L. - Mo 16.02.04 19:10

Ich blick des immernoch net. Wieso 1,1 und wie muss ich das am Schluss zusammensetzen...

*nix check*


rokdd - Di 17.02.04 10:28

Hallo,

hier nochmal meine Variante des Quelltextes(zum erklären):


Delphi-Quelltext
1:
2:
3:
4:
var p:tpoint; //0
....
p:=Clienttoscreen(Point(Button.left, button.top+button.height)); //1
PopUpMenu1.popup(p.x,p.y);//2


ClienttoScreen rechnet wie schon oben gepostet wurde die Koordinaten Einer Komponente, die auf das Formular bezogen sind, in Koordinaten bezogen auf den Bildschirm um. Es espart dir also die mühseligen Additionswege. Clienttoscreen braucht als parameter vom tpoint, deswegen habe ich Point(...) geschrieben. Der Rückgabewert ist auch vom typ tpoint deswegen habe die var p deklariert(0). Nach dem Umrechnen(1) gibst du dann die Coords an das Popmenu weiter(2), wobei du dann p.x und p.y schreiben musst, weil p ja ein point und eine x,y Koordinate hat.

Hoffe das hilft

Rokdd


Andreas L. - Di 17.02.04 14:07

rokdd hat folgendes geschrieben:
Hallo,

hier nochmal meine Variante des Quelltextes(zum erklären):


Delphi-Quelltext
1:
2:
3:
4:
var p:tpoint; //0
....
p:=Clienttoscreen(Point(Button.left, button.top+button.height)); //1
PopUpMenu1.popup(p.x,p.y);//2


ClienttoScreen rechnet wie schon oben gepostet wurde die Koordinaten Einer Komponente, die auf das Formular bezogen sind, in Koordinaten bezogen auf den Bildschirm um. Es espart dir also die mühseligen Additionswege. Clienttoscreen braucht als parameter vom tpoint, deswegen habe ich Point(...) geschrieben. Der Rückgabewert ist auch vom typ tpoint deswegen habe die var p deklariert(0). Nach dem Umrechnen(1) gibst du dann die Coords an das Popmenu weiter(2), wobei du dann p.x und p.y schreiben musst, weil p ja ein point und eine x,y Koordinate hat.

Hoffe das hilft

Rokdd


Ahh jetzt, das ist ja nichtmal so schwer, werde deine Variante gleich mal ausprobieren.

Greetz und thx


Andreas L. - Di 17.02.04 21:10

OK, geht.

--CLOSED--