[Win32/Delphi] Popupmenu moet bijven na een klik op een item

Pagina: 1
Acties:

  • Guillome
  • Registratie: Januari 2001
  • Niet online
Hoi

Ik ben bezig een TPopup menu te maken. Alleen wil ik nu iets waar ik zelf niet uit kom.

Ik wil dat als er met de rechtermuisknop geklikt wordt op sommige items, dat het menu dan blijft staan.
Normaal wordt dit gezien als een normale klik, dus verdwijnt het popup menu.
Maar dat moet niet, dan moet hij blijven staan zodat ik nog acties kan uitvoeren.
Een soort Startmenu van Windows dus.

Heeft iemand een idee hoe ik dit kan doen?

If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router


  • dusty
  • Registratie: Mei 2000
  • Laatst online: 21-02 00:06

dusty

Celebrate Life!

Zover ik weet kan het niet met het standaard object. Je zult dus waarschijnlijk zelf een afgeleide object moeten maken die die properties wel ondersteunt.

Back In Black!
"Je moet haar alleen aan de ketting leggen" - MueR


  • Guillome
  • Registratie: Januari 2001
  • Niet online
Dat doe ik ook, dat zei ik toch? (vraag)
Ik maak een nieuw component gebaseerd op een TPopupmenu, of bedoel je dat niet?

If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Aangezien TPopupMenu gebouwd is rond de Windows implementatie ervan zou je daar moeten zoeken. Bijvoorbeeld de TrackPopupMenu functie die wordt aangeroepen in TPopupMenu.Popup. Helaas kan ik daar niets vinden wat je kan helpen. Misschien moet je de vraag als algemene winapi vraag stellen zodat de VC++ guru's ook meedenken.

PS: Trap niet in de fout die in de win32 sdk help staat over prcRect parameter

We adore chaos because we like to restore order - M.C. Escher


  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 07:34

Tomatoman

Fulltime prutser

Een popupmenu is niet bedoeld om te gebruiken op de manier die jij bedoelt. Dat moet je dus ook niet willen, het gaat immers tegen de logica van een nette Windows-applicatie in. Met andere woorden: een popupmenu dat op het scherm blijft staan, is een voorbeeld van een slechte gebruikersinterface.

Een goede grap mag vrienden kosten.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

LordLarry schreef op 28 januari 2004 @ 20:32:
Misschien moet je de vraag als algemene winapi vraag stellen zodat de VC++ guru's ook meedenken.
Hoi :w ;)

Ik weet ook niet hoe het Start-menu control-technisch werkt, alhoewel je daar met Spy++ best uit zou moeten kunnen komen. Tomatoman heeft gelijk dat popupmenu's niet bedoeld zijn om te blijven staan (en dat is dan ook default behaviour), echter als je bij Office op Customize... klikt kun je ook submenu's op alle menu's oppoppen. DevExpress ExpressBars ondersteunt deze feature ook... en helaas heb ik al een tijdje de sources daar niet meer van anders kon ik het voor je opzoeken.

Wellicht dat iemand anders met een ExpressBars license even kan neuzen?

Professionele website nodig?


  • Guillome
  • Registratie: Januari 2001
  • Niet online
Bedankt voor het aanpassen van de topictitle :)
Maar het is misschien wel technisch gezien niet netjes, maar wel super handig.
Ik hoop dat er een oplossing mogelijk is :)

If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router


  • klinz
  • Registratie: Maart 2002
  • Laatst online: 21-05 09:01

klinz

weet van NIETS

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<smerig>
var
   pt: TPoint;

procedure TForm1.PopupMenu1Popup(Sender: TObject);
begin
     GetCursorPos(pt);
end;

procedure TForm1.MenuItem1Click(Sender: TObject);
begin
     PopupMenu1.Popup(pt.x, pt.y);
end;
</smerig>

Ik heb de source code van TPopupMenu (over smerig gesproken) bekeken, maar ik heb het idee dat het sluiten een Windows(tm) ding is waar je niet zo eenvoudig tussen komt.

  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 07:34

Tomatoman

Fulltime prutser

curry684 schreef op 28 januari 2004 @ 20:44:
DevExpress ExpressBars ondersteunt deze feature ook... en helaas heb ik al een tijdje de sources daar niet meer van anders kon ik het voor je opzoeken.

Wellicht dat iemand anders met een ExpressBars license even kan neuzen?
Aye sir!

Een goede grap mag vrienden kosten.


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Een mogelijkheid die natuurlijk gegarendeerd werkt is het allemaal zelf doen en niet meer van TPopup en Windows afhankelijk zijn. Gewoon zelf een scherm oppoppen en je ding doen. Zo verwacht ik ook dat Office en ExpressBars het doen.

We adore chaos because we like to restore order - M.C. Escher


  • Guillome
  • Registratie: Januari 2001
  • Niet online
Dat is veel werk.
Ik gebruik het namelijk niet op een form, maar vanuit de systray :) Dus die optie valt af. Dat is veel te veel werk in verhouding tot de meerwaarde

If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router


Verwijderd

Kan je niet op een of andere manier in delphi de messageloop onderscheppen nog voor dat een message door delphi's framework wordt afgehandeld? Op die manier kan je rechtermuisklik events zelf afvangen en je ding doen. Vervolgens gooi je ze gewoon weg zodat delphi niet meer aan het afhandelen toe komt :) .

(Geheel bekeken vanuit een MFC standpunt overigens... voor het zelfde geld kan het niet en klets ik maar wat)

  • BoomSmurf
  • Registratie: Maart 2003
  • Laatst online: 23:42

BoomSmurf

Am-Ende!

Verwijderd schreef op 28 januari 2004 @ 22:38:
Kan je niet op een of andere manier in delphi de messageloop onderscheppen nog voor dat een message door delphi's framework wordt afgehandeld? Op die manier kan je rechtermuisklik events zelf afvangen en je ding doen. Vervolgens gooi je ze gewoon weg zodat delphi niet meer aan het afhandelen toe komt :) .

(Geheel bekeken vanuit een MFC standpunt overigens... voor het zelfde geld kan het niet en klets ik maar wat)
Jawel dat kan. Of het het gewenste resultaat heeft is een tweede :)

  • Guillome
  • Registratie: Januari 2001
  • Niet online
Misschien met een WindowHook?

If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router


  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 07:34

Tomatoman

Fulltime prutser

Ik heb de code in ExpressBars eens zitten doorploegen. Het blijkt dat daarin een popupmenu helemaal wordt opgebouwd zonder de code in TPopupMenu.

Ze werken er onder andere met een property IsCustomizing die aangeeft of het menu op dat moment wordt aangepast en dus niet automatisch mag sluiten. Het menu kan op een heleboel manieren gesloten worden, onder andere door een menu-item aan te klikken, door een andere applicatie te activeren en door op Escape te drukken. Er zijn dus heel veel plekken waar je zou moeten ondervangen dat het popupmenu gesloten wordt.

Het lijkt me beter om de window class te subclassen. Ieder popupmenu wordt toegevoegd aan de globale variabele PopupList (class TPopupList), die je kunt vinden in de unit Menus. Je zou zoiets kunnen doen:
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
unit MijnPopupMenus;

interface

uses
  Classes, Messages, Menus;

type
  TMijnPopupList = class(TPopupList)
  protected
    procedure WndProc(var Message: TMessage); override;
  end;

implementation

procedure TMijnPopupList.WndProc(var Message: TMessage);
var
  i: Integer;
begin
  case Message.Msg of
  { meest voorkomende messages:
    WM_EXITMENULOOP
    WM_COMMAND
    WM_INITMENUPOPUP
    WM_UNINITMENUPOPUP
    WM_MENUSELECT
    WM_CANCELMODE
    WM_MENUCHAR
    WM_MENUCOMMAND            }
  end;
  inherited WndProc(Message);
end;

var
  OriginalPopupList: TPopupList;

initialization
  { unit Menus heeft PopupList geinitialiseerd }
  OriginalPopupList := PopupList;
  PopupList := TMijnPopupList.Create;
finalization
  PopupList.Free;
  PopupList := OriginalPopupList;
  { unit Menus zal PopupList opruimen }
end.
Ik heb een heleboel zitten testen en het blijkt dat bij een muisklik in het menu de messages in de volgende volgorde binnenkomen: WM_UNINITMENULOOP, WM_EXITMENULOOP, WM_COMMAND. Ik ben er nog steeds niet achter hoe je kunt voorkomen dat de menu loop wordt verlaten. Misschien lukt het door alle menu-items om te toveren in controls, zodat een muisklik naar de control wordt verzonden in plaats van de menu loop te beëindigen.

Een goede grap mag vrienden kosten.

Pagina: 1