我正在禁用和启用窗体的“关闭”按钮,如下所示:
uses WinApi.Windows;
...
//disabling
EnableMenuItem(GetSystemMenu(MyForm.Handle, False), SC_CLOSE, MF_BYCOMMAND OR MF_DISABLED);
//enabling
EnableMenuItem(GetSystemMenu(MyForm.Handle, False), SC_CLOSE, MF_BYCOMMAND OR MF_ENABLED);我试图检查关闭按钮目前是否已启用或禁用。在检查此MSDN页面之后,我编写了以下代码:
var
ItemInfo : TMenuItemInfo;
MyForm : TForm;
begin
MyForm := GetAFormInSomeWay();
ItemInfo.fMask := MIIM_STATE;
GetMenuItemInfo(GetSystemMenu(MyForm.Handle, False), SC_CLOSE, False, ItemInfo);
if(ItemInfo.fState = MFS_ENABLED)
then ShowMessage('Enabled')
else ShowMessage('Disabled');它总是显示“禁用”(ItemInfo.fState总是5395358)。我做错了什么?
更新:
现在它成功了,多亏了你的建议。
uses
WinApi.Windows, Vcl.Forms, System, System.SysUtils;
...
var
ItemInfo : TMenuItemInfo;
MyForm : TForm;
SystemMenu : HMENU;
begin
MyForm := GetAFormInSomeWay();
ItemInfo.fMask := MIIM_STATE;
ItemInfo.cbSize := SizeOf(MENUITEMINFO);
SystemMenu := GetSystemMenu(MyForm.Handle, False);
if((SystemMenu = 0) OR (GetMenuItemInfo(SystemMenu, SC_CLOSE, False, ItemInfo) = False))
then raise Exception.Create(SysErrorMessage(GetLastError()));
if((ItemInfo.fState AND MFS_DISABLED) = 0)
then ShowMessage('Enabled')
else ShowMessage('Disabled');
end;发布于 2016-05-07 16:33:04
您正在犯Win32编程的经典错误。您正在调用Win32 API函数,但未能检查错误。你怎么知道他们是否成功?答案是你没有。因为你不检查。您必须改变心态,以便在调用Win32 API函数时检查错误成为第二天性。这些函数不会引发例外情况。它们以其他方式表示失败,通常是通过返回值。了解如何读取您调用的每个函数的文档。
对GetMenuItemInfo的调用失败,因为您没有遵循文档中的说明。具体来说,这一部分涵盖了项目信息参数:
请注意,在调用此函数之前,必须将cbSize成员设置为sizeof(MENUITEMINFO)。
按照该指令解决您的问题。
如果您检查了错误,您就会看到GetMenuItemInfo返回False,GetLastError返回ERROR_INVALID_PARAMETER。
代码调用以下API函数:GetSystemMenu、EnableMenuItem和GetMenuItemInfo。您无法检查每个调用中是否有错误。
您应该按位使用,并检查状态中的标志,而不是相等。虽然您的测试在我的系统上有效,但在语义上是错误的。例如,如果该项是默认项,它将失败。
坦率地说,与检查错误的重要性相比,手头的问题是微不足道的。我希望你能吸取教训。所以,请不要仅仅设置cbSize并继续前进,也请添加错误检查。
https://stackoverflow.com/questions/37090878
复制相似问题