问题标签 [message-pump]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
10470 浏览

python - Python - pythoncom.PumpMessages()

我很惊讶地发现没有很多关于函数pythoncom.PumpMessages()pythoncom模块的解释文档。

那么做什么pythoncom.PumpMessages()pythoncom.PumpWaitingMessages()做什么以及如何做?我真正知道的只是用于捕获来自输入设备的事件。

0 投票
1 回答
1042 浏览

c# - 窗体和控件 (WM_xxx) 之间的 C# Windows(触摸 -> 单击/聚焦)消息

我有一个第 3 方开源控件(实际上哪个并不重要,但它的 CefSharp 的 Chromium Web 浏览器 [v 43])。

最初,如果在控件内部单击时打开了表单菜单,则存在一个问题,该菜单不会自行关闭(好像控件正在吞噬单击事件)。

为了避免这种情况,示例应用程序建议截取窗体和控件之间的WM_MOUSEACTIVATE消息,并通过将WM_NCLBUTTONDOWN发布回包含窗体上的元素(在我的例子中是面板栏)来做出反应。这解决了这个问题。

然而,它创造了另一个。现在,一旦您在控件内部(触摸屏)至少触摸 3 次,您就不能再触摸该控件之外的元素。您必须用鼠标单击 [外部元素] 才能恢复再次响应触摸事件所需的焦点水平。

我发现如果我还截获WM_SETCURSOR消息(到控件)并阻塞泵 5 毫秒(Thread.Sleep()),那么问题就会神奇地消失。

我很想知道发生了什么。我介于这是一个线程/上下文问题的理论之间,或者延迟WM_SETCURSOR消息是允许表单中的相邻消息首先处理(这不可能是真的,因为它们共享同一个线程)。

因此,我进行了测试(没有 5ms 的睡眠)并实时记录了控件和表单接收到的所有消息。在测试过程中,我用鼠标单击了我的面板栏(浏览器控件上方),然后触摸(长和短)控件内部的各个区域,然后再次触摸该栏(被忽略)。

在此处输入图像描述

以下是消息:

根据这些,第3次和第4次触球打破了焦点。我们可以看到 chromium 控件在 586 之后停止接收最后一堆消息。我猜它缺少WM_PARENTNOTIFY备份到导致问题的表单。

我找不到有关 282、581、582、583、586 和 587 消息的任何信息。我可能会对 586 消息做出反应,并手动将WM_PARENTNOTIFY 发布到表单?我不确定快速连续接收其中两个会产生什么影响?

有谁知道为什么WM_SETCURSOR上的 5ms 睡眠保持这些消息流动?

或者关于修复的任何更好的想法?

0 投票
1 回答
681 浏览

c# - GUI 消息队列(消息泵 - 并行或串行)

我似乎无法在任何地方找到答案。我不确定我是否知道如何表达它。

发往表单控件的消息是否相互并行处理?

我一直认为我们每个线程单元都有一个消息泵,并且一个泵会为附加到该线程的整个 GUI 提供数据。因此,如果您在一个控件上连接到 wndproc 并冻结线程 (Thread.Sleep()),整个表单会冻结吗?

如果是这样,这个问题似乎证明了通过在特定消息到达子控件时休眠,相邻控件处理了它的下一条消息。如何?

0 投票
2 回答
147 浏览

c# - UI 在后台工作人员频繁更新期间没有响应

我正在开发一个 Windows 窗体应用程序,它逐行读取文件 [在后台工作线程中] 并填充数据网格视图 [使用 BeginInvoke]。完成此操作后,UI 变得无响应(无法取消/退出或拖动窗口),但我可以看到 datagridview 正在更新。我所知道的是,这是因为消息被泵入消息队列,其优先级高于用户输入消息。

有没有一种方法可以让 UI 仍然响应用户输入?

0 投票
1 回答
1472 浏览

winapi - GetMessage 不检索消息

当我运行我的程序(下面的代码)并通过 USB 电缆插入硬盘驱动器时,WindowProcedure会调用WM_DEVICECHANGEdevice-change event type 的消息DBT_DEVICEARRIVAL

然而,GetMessage不返回。文档GetMessage说_GetMessage

从调用线程的消息队列中检索消息。

因此,听起来线程的消息队列中没有消息。

为什么我的调用线程的消息队列中没有消息?

如果我的调用线程的消息队列中没有消息,如何/为什么为设备更改事件类型WindowProcedure的消息调用我的函数?WM_DEVICECHANGEDBT_DEVICEARRIVAL

注意:我已经阅读了一些相关的帖子和​​页面。 这个stackoverflow帖子似乎可能是相关的。如果是这样,我怎么知道哪些消息实际放置在消息队列中?

0 投票
3 回答
3817 浏览

.net - ShowDialog 方法挂起而不显示窗口¿死锁?

我们有一个 WPF 繁忙窗口指示器。它显示在主线程上,使用window.ShowDialog(). 在响应 Loaded 事件时,将执行一个操作并关闭窗口,以便应用程序继续其工作。

window.ShowDialog()似乎不时(非常罕见)挂起而不显示对话框,并且未触发 Loaded 事件,因此应用程序挂起。相关代码如下:

当应用程序挂起时,我可以看到window.ShowDialog()方法上的指令指针,但窗口在应用程序上不可见,并且 backgroundWorker 尚未启动,所以我的猜测是 OnLoaded 事件尚未引发。

该应用程序并没有真正挂起,因为它正确重绘,但您无法单击屏幕上的任何位置。作为一个奇怪的副作用,当应用程序挂起时,它会从 Windows 7 的任务栏中消失。

我在中断执行时看到的调用堆栈如下:

正如其他人之前所说的那样,它看起来像一个死锁,所以我使用 Visual Studio 进行了转储,并在其上运行了一些工具来寻找死锁。这是应用程序正在运行的线程的信息:

应用程序代码只有一个线程(0,使用 ShowDialog 调用托管 1)。其他线程没有应用程序代码,线程 15(托管 10)是唯一有一些 .Net 代码的线程。

查看线程 15(托管 10),因为它是带锁的线程,我看到以下调用堆栈:

这个调用堆栈看起来像一个等待被解雇的计时器,但也许我对这种解释错了,所以我不知道如何继续。

我可以根据要求提供您需要的任何信息。我不是 WinDbg 方面的专家,但我开始能够处理它,因此您也可以要求我获取有关它的信息。

更新 :

将一些日志添加到应用程序后,我们有以下额外信息:

问题是该方法dispatcher.Invoke(new Action(window.Close));被调用并且它在没有抛出异常的情况下执行但该方法window.ShowDialog();没有返回。

我们试图用 Spy++ 和类似工具找到窗口,据我所知,窗口不存在,但window.ShowDialog();一直在执行。

我希望这能让您对正在发生的事情有所了解。

0 投票
2 回答
473 浏览

c - 如何在循环中结合RECV和getMessage(C,WINAPI)

你如何在 C 中编写代码?

所需的流程是:

我试过这段代码:

我知道线程存在,但我想避免使用线程。如果这是唯一的方法,我将使用线程。

编辑:使用非阻塞套接字不是解决方案,因为如果没有数据可用并且队列中没有消息,那么我的程序将退出。

0 投票
2 回答
400 浏览

c++ - 分离窗口消息泵和接收 WM_QUIT

我正在尝试为我的项目创建独立的窗口包装类。它大部分都在工作,但无法弄清楚如何在我的主消息泵中获取 WM_QUIT。为了学习 Windows,我不想为此使用其他库。

这是正在发生的事情的一个简单示例。

PeekMessage 文档在这里:https ://msdn.microsoft.com/en-us/library/windows/desktop/ms644943(v=vs.85).aspx

我无法找到任何使用 -1 HWND 过滤器的示例,但 MSDN 说它将接收 HWND 为 NULL 的线程消息(我已经检查过 WM_QUIT 是否如此),我相信 PostQuitMessage与 WM_QUIT 一起使用。

仅当我创建一个窗口时才会出现此问题。

有什么我做错了,还是有更好的方法?

0 投票
1 回答
299 浏览

inno-setup - 在 PrepareToInstall 期间保持 Inno Setup UI 响应

为了保持 Inno Setup UI 响应,我使用了一种与如何在不阻塞 InnoSetup UI 的情况下执行 7zip 中描述的技术几乎相同的技术? 在我的一个[Files]条目中,我定义了一个AfterInstall运行冗长任务的过程。在此期间,由于上面链接描述的消息泵,我仍然可以单击向导表单并移动它等等。但是,如果我尝试从PrepareToInstall事件处理程序中调用相同的过程,我不能单击或移动向导表单 - 它仍然完全禁用/冻结。

PrepareToInstallInno Setup期间是否有一些特别的事情会故意禁用向导表单?

0 投票
0 回答
244 浏览

c# - 在 C# 中,可以访问和更改 Windows 消息泵以响应 WM_GETOBJECT 吗?

因此,如果您使用 Accessibility API 知道它的 Hwnd,那么有一种很好的技术可以从 Excel.exe 会话中获取 COM 指针跨进程(同一台机器)。具体的 Windows API 函数是AccessibleObjectFromWindow;如果使用 OBJID_NATIVEOM 的参数调用,则 Excel.exe 会将 COM 指针封送回 Excel.Window 对象。很酷。

所以我想知道开发人员是否可以为他们自己的应用程序实现相同的技术。 答案是肯定的,他们在消息泵代码中响应特定消息 WM_GETOBJECT。虽然这对于 C++ 应用程序是可行的,但我对如何为 C# 应用程序执行此操作感到困惑。

我假设答案是做一些事情来访问消息泵处理代码并改变它。也许可以使用一些魔法属性。只要它有效,我对任何一种技术都持开放态度。

这是从 Excel 获取 COM 指针的代码

这看起来很有希望从 NativeWindow 中处理 WM_GETOBJECT 返回一个 IOleCommandTarget