我正在使用Delphi XE6开发的Windows应用程序进行一些最后的修改。
目前,我对窗口系统菜单感到困惑,我的意思是当你点击左边标题栏中的图标时出现的菜单。
我已经定义了两个程序:
// this inserts one additional command into the menu
procedure InsertCommand(Sender: TObject);
// this is obviously a handler of mouse clicks on that menu
procedure OnSysCommand(var Msg: TWMSysCommand); message WM_SYSCOMMAND;
定义如下:
const
ALWAYS_ON_TOP_ID = 1000;
var
HandleMenu: THandle;
sAlwaysOnTop: string;
procedure TFormMain.InsertCommand(Sender: TObject);
begin
// get the system menu handle and store it into form-level defined variable
HandleMenu := GetSystemMenu(Handle, False);
// just to make it nicer, I add a separator line
AppendMenu(HandleMenu, MF_SEPARATOR, 0, '');
// append "Always on Top" language localized string at the end of the menu
AppendMenu(HandleMenu, MF_STRING, ALWAYS_ON_TOP_ID, PChar(sAlwaysOnTop));
end;
procedure TFormMain.OnSysCommand(var Msg: TWMSysCommand);
begin
if Msg.CmdType = ALWAYS_ON_TOP_ID then
if GetMenuState(HandleMenu, ALWAYS_ON_TOP_ID, MF_BYCOMMAND) and MF_CHECKED = MF_CHECKED
then begin
FormStyle := fsNormal;
CheckMenuItem(HandleMenu, ALWAYS_ON_TOP_ID, MF_UNCHECKED);
end else begin
FormStyle := fsStayOnTop;
CheckMenuItem(HandleMenu, ALWAYS_ON_TOP_ID, MF_CHECKED);
end;
inherited;
end;
我现在读到正确的用法是:
Msg.CmdType and $FFF0
但如果我使用它,我的代码就会停止工作。
从官方MSDN source开始,我引用:
在
WM_SYSCOMMAND
消息中,wParam
参数的四个低位由系统内部使用。要在测试wParam
的值时获得正确的结果,应用程序必须使用按位AND运算符将值0xFFF0
与wParam
值组合。
问题是,我是否必须避开$FFF0
面具,或者是否有更合适的方式?
答案 0 :(得分:5)
文档准确,代码停止工作的原因当您按位进行测试时,使用$ FFF0是您定义的常量并不好。
const
ALWAYS_ON_TOP_ID = 1000;
1000十六进制是3E8,最低四位数应为0,最低四位为0. IOW,二进制1111是十六进制F,所以你应该把最后一位数留给系统。
以十六进制设置常量,这样就不会出错。在定义常量时,请注意保持SC_...
范围($ F000 ... $ F ###)的清晰度。 E.g:
const
ALWAYS_ON_TOP_ID = $100; {256}
所以现在你可以安全地测试
if Msg.CmdType and $FFF0 = ALWAYS_ON_TOP_ID then
...