'How can my Delphi 11 FMX project detect that "My Menu Item" in system menu clicked?
I've tried using wndproc to detect "My Menu Item" clicked in System Menu in windows. I used from source code to capture WndProc and add menu item to system menu. Mouse wheel in WndProc can detected but "My Menu Item" click not detected. My code is:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Classes, FMX.Forms,
FMX.Platform.Win, FMX.Types, FMX.Layouts, FMX.Memo, FMX.Memo.Types,
FMX.Controls, FMX.Controls.Presentation, FMX.ScrollBox;
const
SC_MyMenuItem = WM_USER + 1;
type
TForm1 = class(TForm)
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
FHwnd: HWND;//Save the window handle
FOldWndProc: LONG;//Save the original message processing function
public
function WndProc(HWND: HWND; Msg: UINT; wParam: wParam; lParam: lParam): LRESULT;
end;
var
Form1: TForm1;
implementation
{$R *.fmx}
function WindowProc(HWND: HWND; Msg: UINT; wParam: wParam; lParam: lParam): LRESULT; stdcall;
begin
//Because during normal development, you need to access the methods or controls inside the window, etc.
//For convenience, so here is a message forwarding
Result := Form1.WndProc(HWND, Msg, wParam, lParam);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
//Obtain the handle of the main window. Under the FMX framework, Handle is no longer the handle of this window, you need to convert it
FHwnd := FmxHandleToHwnd (Handle);
AppendMenu(GetSystemMenu(FHwnd, FALSE), MF_SEPARATOR, 0, '');
AppendMenu(GetSystemMenu(FHwnd, FALSE), MF_STRING, SC_MyMenuItem, 'My Menu Item');
//Save the original WindowProc address
FOldWndProc := GetWindowLongPtr(FHwnd, GWL_WNDPROC);
//Get message processing rights
SetWindowLongPtr(FHwnd, GWL_WNDPROC, NativeInt(@WindowProc));
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
//Because the message delivered by Windows cannot be processed after the window is destroyed, a memory access error will occur
//So before the window is destroyed, the message processing power should be transferred to the original WindowProc
SetWindowLongPtr(FHwnd, GWL_WNDPROC, FOldWndProc);
end;
function TForm1.WndProc(HWND: HWND; Msg: UINT; wParam: wParam; lParam: lParam): LRESULT;
begin
Result := 0;
//Test the mouse wheel message here
if Msg = WM_MOUSEWHEEL then
begin
Memo1.Lines.Add('You used the mouse wheel');
Exit;
end;
if Msg = SC_MyMenuItem then
begin
Memo1.Lines.Add('My Menu Item Clicked');
Exit;
end;
// if Msg = 293 then
// begin
// Memo1.Lines.Add('My Menu Item Clicked');
// Exit;
// end;
Result := CallWindowProc(Ptr(FOldWndProc), HWND, Msg, wParam, lParam);
end;
end.
In TForm1.WndProc Mouse wheel can detected but "My Menu Item" click not detected. what is the problem?
Solution 1:[1]
Your coding style looks like Visual C++, processing all message by yourself.
But you don't need to do so in Delphi. In your Project, you can edit your Form1 in Design mode visually.
After placing the component you named "My Menu Item" on the Form1, you can double click the "My Menu Item" in Design mode, and the default event handler will create "OnClick" event for you.
And then you can add any codes you wish to have for the event in the method.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Dennies Chang |