Tegenwoordig verbergen een aantal Windows programma hun hoofdmenu (mainmenu) en door op Alt te drukken wordt het menu zichtbaar of weer verborgen. Uiteraard wilde ik dit ook in een van mijn programma's gaan gebruiken (Rename My TV series). Na wat knoeien vond ik een oplossing voor Windows.
Het idee;
Standaard is het menu verborgen, door op Alt te drukken wordt het menu zichtbaar, en nogmaals op Alt drukken verbergt het menu weer.
Deze methode doet precies dat met het kleine nadeel dat het verbergen van het menu pas na 2 of 3x op Alt drukken gebeurt. Dit laatse omdat het menu zelf een functie aan de Alt knop heeft gehangen.
Stap 1: Show/Hide het menu
The TMainMenu kent geen Show/Hide functie of visible property, dus doen we het zo:
self.Menu:=nil;
Effectief koppelen we dus het MainMenu los van de Form.
Weer zichtbaar maken is eenvoudig door Mainmenu weer aan de Form te koppelen (er vanuit gaande dat jouw hoofdmenu MainMenu1 heet):
self.Menu:=MainMenu1;
Step 2: De Alt Toets opvangen
Deze oplossing is dus alleen voor Windows en dus NIET CROSSPLATFORM!
Je moet de unit "windows" aan de "uses" clausule toevoegen.
Voeg het volgende aan de "private" sectie van jouw form:
procedure KeyMessage(Msg: LongWord; wParam:longint);
Voeg het volgende toe meteen na het "implementation" keyword:
var
AltKeyHook: HHOOK;
function MessageHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var
Msg: LCLType.PMsg absolute lParam;
begin
if nCode >= 0 then
case Msg^.message of
WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, WM_SYSKEYUP, WM_CHAR, WM_SYSCHAR:
Form1.KeyMessage(Msg^.message, Msg^.wParam); // make sure to use the right form variable here!
end;
Result := CallNextHookEx(AltKeyHook, nCode, wParam, lParam);
end;
procedure TForm1.KeyMessage(Msg: LongWord; wParam:longint);
begin
if (Msg=WM_SYSKEYDOWN) and (wParam=18{=Alt key}) then
begin
if self.Menu=nil then// Toggle menu, assuming your MainMenu is called Mainmenu1
self.Menu:=MainMenu
else
self.Menu:=nil;
end;
end;
In de FormCreate event voeg je dit toe:
AltKeyHook := SetWindowsHookEx(WH_GETMESSAGE, @MessageHookProc, 0, MainThreadID);
En in het FormDestroy event:
if AltKeyHook <> 0 then
begin
UnhookWindowsHookEx(AltKeyHook);
AltKeyHook := 0;
end;
And that's it ...
In de Keymessage functie kun je voor "Msg" ook deze waarden opvangen: WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, WM_SYSKEYUP, WM_CHAR, and WM_SYSCHAR. De "wParam" waarde bevat of de toetscode of een char, dus b.v. IntToStr(wParam) of Chr(wParam).