Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - ist ein OnMouseOver möglich


sunday_2 - Mi 06.11.02 13:44
Titel: ist ein OnMouseOver möglich
Hi Leute,

ich möchte ein Fenster entwickeln, indem die Menüleiste nur dann zu sehen ist, wenn ich mit der Maus an den oberen Rand gehe.
Quasi ein OnMouseOver-Ereignis (würde man so in HTML bezeichnen).
Als menüleiste habe ich ein Panel genutzt, in der diverse Buttons sind.
Ein zweites Problem ist, das ich nicht weis wie ich ein Pull down menü hinbekomme.

Wäre für hilfe echt dankbar.

Gruß Sunday


LCS - Mi 06.11.02 14:10

Hi
der einfachste Weg für den Menü wäre ein MouseMove für das Formular um die aktuelle Position zu bekommen und wenn die Mouse am oberen Rand steht das Panel sichtbar zu schalten:

Quelltext
1:
2:
3:
4:
5:
procedure TfrmMain.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  Panel1.Visible := y < 10;  
end;


Für das Menü selbst erstellst du erst mal ein normales Menü, dass du dann unsichtbar schaltest. Dann ersetzt du dein Panel durch eine TToolbar und weisst der Eigenschaft Menu dein erstelltes Menü zu. Damit bekommst du Schaltflächen die deinem Menü entsprechen.

Gruss Lothar


tommie-lie - Mi 06.11.02 14:45

mach's doch einfach menuell:
Prüfe ob die Maus am oberen Rand ist

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  if Y < 10 then
    // mach Panel sichtbar
  else
    // mach's wieder weg
end;

Dazu muss natürlich am Anfang das Panel unsichtbar sein. Jedesmal wenn die Maus an 10 Pixel vom oberen Rand entfernt rankommt, wird das "Menü" angezeigt.

Wenn du Popups haben willst, wieso machst du dann nicht mit 'nem normalen TMainMenu? Da sind so Dinger schon drin.
Du machst am Anfang dein Menu (Objekt gibt's unter "Standard", zweites Objekt von links) und alle Einträge, so wie du sie haben willst.
Dann musst du bei Form1 (oder deiner Hauptform, wo das Menü erscheinen soll) das Menu-Property auf nil (einfach im objektinspector das Edit-Feld für Menu löschen, geht mit ENTF *g*).
So, jetzt kommt das spannende, der Code:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  if Y < 10 then
    Menu := MainMenu1
  else
    Menu := nil;
end;

Wenn man jetz' die Maus nach oben bewegt und sie an 10 Pixel vom oberen Rand kommt, wird das Menu zugewiesen und somit angezeigt. Andernfalls wird's wieder rausgemacht. Hat den Vorteil, daß das TMainMenu ein bisschen komfortabler ist, als hunderttausend Panels, weil man die Einträge bequem umbenennen kann und auch schon Popdown-Menüs drin sind. Außerdem kann man sie ganz einfach auf Disbled stellen und Actions zuweisen.

Der Code oben ist getestet, also sollte er laufen. Viel Spaß beim menürisieren deines Progs...

Tschüß
Thomas


LCS - Mi 06.11.02 15:21

Hi
tommie-lie hat folgendes geschrieben:
mach's doch einfach menuell:
Prüfe ob die Maus am oberen Rand ist

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  if Y < 10 then
    // mach Panel sichtbar
  else
    // mach's wieder weg
end;


Irgendwie genau das gleiche was ich geschrieben habe :mrgreen:

tommie-lie hat folgendes geschrieben:


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  if Y < 10 then
    Menu := MainMenu1
  else
    Menu := nil;
end;


Damit schaltest du dann IMHO allerdings auch alle ShortCuts des verwendeten Menüs aus. :?

Gruss Lothar


tommie-lie - Mi 06.11.02 17:12

sorry, hab deinen Post überlesen.

Ob dann auch die Shortcuts weg sind, weiß ich nicht. Müsste man mal ausprobieren.
Aber eigentlich doch nicht, weil das Objekt (also das Menü an sich) ja immer noch exisitert, nur eben nirgendwo zugewiesen ist. Und die Shortcuts gehören ja zum Menü...


LCS - Mi 06.11.02 18:03

Hi
habs gerade nochmal getestet. Shortcuts sind nicht aktiv.

Gruss Lothar


sunday_2 - Do 07.11.02 11:30

Hi, habe folgenden Code eingebunden

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, 
  Y: Integer); 
begin 
  if Y < 10 then 
    Menu := MainMenu1 
  else 
    Menu := nil; 
end;

Funktioniert auch. Leider flackert dabei die Titelleiste (dort wo Form1.Caption drin steht) :oops: wenn das Menü nicht sichtbar ist.
Woran liegt das und was kann ich dagegen tun?

Gruß Sunday


LCS - Do 07.11.02 15:52

Hi
im Nachhinein betrachtet völlig logisch. Wenn du ein Menü aus dem Fenster entfernst, stellt Delphi das Fenster neu dar. Und genau dieses Entfernen des Menüs machst du bei jeder Mausbewegung und macht sich als Flackern bemerkbar. :?
Eine Alternativlösung hab ich dir ja in meiner ersten Antwort schon gegeben. Wenn du mindestens D6 verwendest hast du damit eine Konstruktion die exakt so aussieht wie ein Menü und die sich ohne Nebenwirkungen ein- oder ausschalten läst. 8)

Gruss Lothar

P.S. Eine andere Lösung wäre, dass du die Maus einfach so schnell bewegst, dass du mindestens 75Hz erreichst :mrgreen:


sunday_2 - Do 07.11.02 16:45

Hi,

mal ne ganz blöde Frage.

Wie kann ich MainMenü unsichtbar machen? Visible hat die Komponente ja nicht.

Gruß Sunday


tommie-lie - Do 07.11.02 17:07

gar nicht. Du musst dann schon bei der Form das Menu-Property auf nil setzen. Aber zu deinem obigen Problem:

das Problem tritt bei mir auch auf.
Woran es liegt kann ich nur inetwa sagen:
Er macht bei jeder Mausbewegung das Menu auf nil, also muss jedesmal die Form neu zeichnen.
Einen Workaround (keine richtige Lösung, aber es umgeht das Problem) habe ich auch gleich gefunden:
Einfach anstatt deinem Code, folgenden einsetzen:

Quelltext
1:
2:
3:
4:
  if Y < 10 then
    Menu := MainMenu1
  else if Menu = MainMenu1 then
    Menu := nil;

Jetzt wird das Menu (und somit auch die ganze Form) nur noch dann neu zugewiesen, wenn es vorher etwas anderes war. Also solange das Menu gar nicht gezeigt wird, verändert sich nichts. Wird es dann angezeigt (wenn Cursor kleiner 10 usw), wird es nur ein einziges Mal wieder auf nil gesetzt, nämlich in dem Augenblick, wenn die Maus auf 11 Pixel steht. Dannach passiert wieder nichts.
Das hat zumindest bei mir das Problem behoben.
Wenn du auch noch eine Animation haben willst, also das das Menü "von oben hereinfährt", kannst du kein TMainMenu mehr nehmen, weil das statisch an eine Position gebunden ist (oberer Rand). Dann musst du tatsächlich ein panel nehmen und dieses dann per sleep (also 'ner kleinen verzögerung) immer ein bisschen mehr in die Form reinragen lassen (negative Y-Positionen sind bei solchen Elementen meines Wissens nach erlaubt), bis es dann ganz da ist. Oder du verdeckst ein normales TMainMenu mit einem Panel ohne Rand, das du dann etwas nach unten schiebst, wenn die Maus darüber fährt. So ließe sich übrigens auch das Menü verstecken: Einfach was anderes drüber machen und das beim Drüberfahren mit der Maus verschieben/unsichtbar machen.