为啥消息处理程序在调试模式下不起作用?

Posted

技术标签:

【中文标题】为啥消息处理程序在调试模式下不起作用?【英文标题】:Why a message handler doesn't work in debugging mode?为什么消息处理程序在调试模式下不起作用? 【发布时间】:2016-05-04 01:38:03 【问题描述】:

我在 Windows 10 中使用柏林。

以下消息处理程序在构建的应用程序中运行良好,但在调试模式下不可用。

如何调试消息处理程序?

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    procedure onReceive(var message: TMessage); message WM_COPYDATA;
  end;

procedure TForm1.onReceive(var message: TMessage);
begin
  Memo1.Lines.Add('a');
end;

发送方代码如下,struct的值无意义。

procedure TForm1.FormClick(Sender: TObject);
var
  _Handle: Cardinal;
  _CopyDataStruct: TCopyDataStruct;
begin
  _Handle := FindWindow(nil, 'test form');

  _CopyDataStruct.dwData := 0;
  _CopyDataStruct.cbData := Sizeof(_Handle);
  _CopyDataStruct.lpData := @_handle;

  SendMessage(_Handle, WM_COPYDATA, Handle, integer(@_CopyDataStruct));
end;

【问题讨论】:

Memo1.Lines.Add('a')上设置断点,然后运行。然后运行您的另一个应用程序,将 WM_COPYDATA 消息发送到您的第一个应用程序。 我的猜测是消息永远不会到达,发送方的目标是设计器中的窗口。 你的调试器运行提升了? @JOSeongGng:UIPI 阻止低完整性进程将窗口消息发送到高完整性(即提升)进程的窗口,除非高完整性进程调用自身的ChangeMessageFilter/Ex() 以允许通过 UIPI 过滤器发送特定窗口消息的低完整性进程。 停止运行提升的调试器。它会让你感到痛苦。 【参考方案1】:

如果您的 TForm1 类在 IDE 的表单设计器中打开,并且它的 Caption 在对象检查器中是 test form,那么 FindWindow() 可能会发现 HWND在运行时而不是正在运行的应用程序中的HWND(您可以使用GetWindowThreadProcessId() 来验证)。这意味着您会将您的消息发送到错误的HWND。这是在调试器中运行时使用FindWindow() 通过标题搜索TForm 时的常见问题。在 IDE 中关闭 TForm1 源文件,然后 FindWindow() 将无法再找到 HWND,它会在您正在运行的应用程序中找到 HWND

顺便说一句,您的_Handle 变量需要声明为HWNDTHandle 而不是Cardinal,并且SendMessage() 的最后一个参数需要类型转换为LPARAM 而不是@ 987654341@.

【讨论】:

查看 cmets 似乎提问者的问题是 ide 被提升了运行 这不会影响应用程序发送消息的能力,只会接收它们..我仍然认为问题与应用程序尝试有关发送到设计器窗口。如果 IDE 正在提升运行,并且FindWindow() 正在寻找设计器窗口,则 UIPI 将适用,尽管这并不重要,因为无论如何设计器都是错误的目标。使 IDE 不提升运行只会删除 UIPI,这仅在被调试的应用程序是接收方而不是发送方时才重要。我怀疑 zorder 只是不同,导致FindWindow() 找到不同的窗口。 接收失败可以说明问题。 Asker 评论说,运行非提升的 IDE 解决了这个问题。问题中的代码显示发送和接收。 如果 IDE 运行提升,任何从它运行的应用程序也将提升。提升的应用可以“看到”所有其他提升的应用,并且在许多情况下“看到”非提升的应用。

以上是关于为啥消息处理程序在调试模式下不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 DragDrop 在 VS2010 下不起作用?

为啥小写 [i] 在可视块模式下不起作用?

Vim:为啥 noremap 在插入模式下不起作用?

minifyEnabled - true 在调试模式下不起作用

JHipster 应用程序在 prod 模式下不起作用

Android minifyEnabled true 在调试和发布模式下不起作用