windows 有没有像 PeekMessage 这样不处理消息的函数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1133507/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there a function like PeekMessage that doesn't process messages?
提问by Matt Cruikshank
I'm trying to innocently call
我试着无辜地打电话
PeekMessage(&msg, 0, WM_KEYDOWN, WM_KEYUP, PM_NOREMOVE | PM_NOYIELD);
and Windows Vista 64, in the PeekMessage call, is processing messages. The result is that I'm going re-entrant on my paint call, and all sorts of other code.
和 Windows Vista 64,在 PeekMessage 调用中,正在处理消息。结果是我将重新进入我的绘画调用和各种其他代码。
Painting can take seconds in our application, so we added the PeekMessage call to see if the user hit a key, so we could interrupt that painting and start up the next one. Little did we realize that Windows could start processing messages on us. It'd be a major refactoring to put the real work of painting in a separate thread... We're trying to see if specific keys were pressed, or if the mouse wheel rotated or mouse buttons were clicked, to interrupt rendering.
在我们的应用程序中绘画可能需要几秒钟,所以我们添加了 PeekMessage 调用来查看用户是否按下了一个键,这样我们就可以中断该绘画并开始下一个绘画。我们几乎没有意识到 Windows 可以开始处理我们的消息。将真正的绘画工作放在一个单独的线程中将是一个重大的重构......我们试图查看是否按下了特定的键,或者是否旋转了鼠标滚轮或单击了鼠标按钮,以中断渲染。
I've tried adding code specifically to prevent re-entrancy, and then re-injecting paint messages into the queue, etc. It's all very kludgey, and there are cases where it doesn't work well.
我试过专门添加代码来防止重入,然后将绘制消息重新注入队列等。这一切都非常笨拙,并且在某些情况下效果不佳。
Is there some flag I could add to the PeekMessage call? I didn't see anything new in the documentation on MSDN. I really need a PeekMessage
that doesn't process messages. Help!
我可以在 PeekMessage 调用中添加一些标志吗?我在 MSDN 上的文档中没有看到任何新内容。我真的需要一个PeekMessage
不处理消息的。帮助!
回答by Remus Rusanu
Perhaps I'm missing the obvious, but the spec is pretty verbosethat it will do so:
也许我错过了显而易见的事情,但规范非常冗长,它会这样做:
The PeekMessage function dispatches incomingsent messages, checks the thread message queue for a posted message, and retrieves the message (if any exist).
PeekMessage 函数分派传入的已发送消息,检查线程消息队列中是否有已发布的消息,并检索该消息(如果存在)。
...
...
During this call, the system delivers pending, nonqueued messages, that is, messages sent to windows owned by the calling thread using the SendMessage, SendMessageCallback, SendMessageTimeout, or SendNotifyMessage function. Then the first queued message that matches the specified filter is retrieved. The system may also process internal events. If no filter is specified, messages are processed in the following order:
- Sent messages
- Posted messages
- Input (hardware) messages and system internal events
- Sent messages (again)
- WM_PAINTmessages
- WM_TIMER messages
To retrieve input messages before posted messages, use the wMsgFilterMin and wMsgFilterMax parameters.
在此调用期间,系统传递未决的非排队消息,即使用 SendMessage、SendMessageCallback、SendMessageTimeout 或 SendNotifyMessage 函数发送到调用线程拥有的窗口的消息。然后检索与指定过滤器匹配的第一条排队消息。系统还可以处理内部事件。如果未指定过滤器,则按以下顺序处理消息:
- 发送信息
- 发布的消息
- 输入(硬件)消息和系统内部事件
- 发送消息(再次)
- WM_PAINT消息
- WM_TIMER 消息
要在发布消息之前检索输入消息,请使用 wMsgFilterMin 和 wMsgFilterMax 参数。
回答by IRBMe
I think this is what PeekMessage is supposed to do. The only difference between it and GetMessageis that GetMessage blocks until a message arrives, where as PeekMessage will return TRUE or FALSE depending on whether a message matching the filter was found. It will still process the messages if they are found.
我认为这就是 PeekMessage 应该做的。它和GetMessage之间的唯一区别是 GetMessage 阻塞直到消息到达,而 PeekMessage 将根据是否找到与过滤器匹配的消息返回 TRUE 或 FALSE。如果找到消息,它仍将处理这些消息。
回答by zemtex
GetQueueStatus is the fastest way to check if there are available messages. It will only check a few flags and takes only 1 parameter compared to 5 parameters of peekmessage. It will give a quick hint if there are available messages, it will not process the message in any way.
GetQueueStatus 是检查是否有可用消息的最快方法。与 peekmessage 的 5 个参数相比,它只会检查几个标志并且只需要 1 个参数。如果有可用消息,它将给出快速提示,它不会以任何方式处理消息。
GetQueueStatus and GetInputStatus are related functions.
GetQueueStatus 和 GetInputStatus 是相关函数。
回答by nos
PeekMessage processes messages because that's what PeekMessage does.
PeekMessage 处理消息,因为这就是 PeekMessage 所做的。
Maybe it's badly named, but PeekMessage do remove the message from the queue if there are any available.
也许它的名字很糟糕,但是 PeekMessage 确实从队列中删除了消息,如果有的话。
回答by Richard Pincince
Just modified the PM_REMOVE flag for the PM_NOREMOVE
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PROJECT_NAME
{
class cUtil
{
//===============================
cUtil()
{
}
//================================
~cUtil()
{
}
//=================================
public struct Message
{
public IntPtr handle;
public uint msg;
public IntPtr wParam;
public IntPtr lParam;
public uint time;
public System.Drawing.Point p;
}
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern bool PeekMessage(out Message lpMsg, Int32 hwnd, Int32 wMsgFilterMin, Int32 wMsgFilterMax, uint wRemoveMsg);
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern bool TranslateMessage(out Message lpMsg); //(ref Message lpMsg);
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern Int32 DispatchMessage(out Message lpMsg); //(ref Message lpMsg);
//private static uint PM_NOREMOVE = 0x0000;
private static uint PM_REMOVE = 0x0001;
//private static uint PM_NOYIELD = 0x0002;
public static void Peek()
{
Message winMsg;
while (PeekMessage(out winMsg, (Int32)0, (Int32)0, (Int32)0, PM_REMOVE))
{
TranslateMessage(out winMsg);
DispatchMessage(out winMsg);
}
}
}
}
//================================
//================================
//===============================
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace PROJECT_NAME
{
public partial class foNAME : Form
{
//===================================
public foRAMQ()
{
InitializeComponent();
}
//===================================
private void Job()
{
int cnt = 0;
while( reading_DBMS() )
{
cUtil.Peek();
.
.
.
.
.
cnt++;
lable_count.Text = string.Format("Count: {0}", cnt )
}
}
}
}