有没有像 PeekMessage 这样不处理消息的函数?

发布于 2024-07-29 00:58:55 字数 592 浏览 4 评论 0原文

我试图无意中调用

PeekMessage(&msg, 0, WM_KEYDOWN, WM_KEYUP, PM_NOREMOVE | PM_NOYIELD);

,而 Windows Vista 64 在 PeekMessage 调用中正在处理消息。 结果是我将重新进入我的绘制调用以及各种其他代码。

在我们的应用程序中,绘画可能需要几秒钟的时间,因此我们添加了 PeekMessage 调用来查看用户是否按下了某个键,这样我们就可以中断该绘画并启动下一个绘画。 我们几乎没有意识到 Windows 可以开始处理我们的消息。 将真正的绘画工作放在单独的线程中将是一次重大重构...我们试图查看是否按下了特定的键,或者是否旋转了鼠标滚轮或单击了鼠标按钮,以中断渲染。

我尝试过专门添加代码来防止重新进入,然后将绘制消息重新注入队列等。这一切都非常混乱,并且在某些情况下它不能很好地工作。

我可以在 PeekMessage 调用中添加一些标志吗? 我在 MSDN 上的文档中没有看到任何新内容。 我确实需要一个不处理消息的 PeekMessage 。 帮助!

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.

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.

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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

笔落惊风雨 2024-08-05 00:58:55

也许我错过了显而易见的事情,但是 规范非常冗长它会这样做

PeekMessage 函数调度
传入
发送的消息,检查
已发布的线程消息队列
消息,并检索消息(如果
任何存在)。

...

在此通话期间,系统提供
待处理的、非排队的消息
,即
发送到拥有的窗口的消息
使用 SendMessage 调用线程,
发送消息回调,
发送消息超时,或
发送通知消息函数。 然后
第一条符合的排队消息
检索指定的过滤器。
系统还可以处理内部
事件。 如果没有指定过滤器,
消息被处理在
以下顺序:

  • 已发送消息
  • 已发布消息
  • 输入(硬件)消息和系统内部事件
  • (再次)发送消息
  • WM_PAINT消息
  • WM_TIMER 消息

检索之前输入的消息
发布消息,使用 wMsgFilterMin
和 wMsgFilterMax 参数。

Perhaps I'm missing the obvious, but the spec is pretty verbose that it will do so:

The PeekMessage function dispatches
incoming
sent messages, checks the
thread message queue for a posted
message, and retrieves the message (if
any exist).

...

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_PAINT messages
  • WM_TIMER messages

To retrieve input messages before
posted messages, use the wMsgFilterMin
and wMsgFilterMax parameters.

风月客 2024-08-05 00:58:55

GetQueueStatus 是检查是否有可用消息的最快方法。 它只会检查几个标志,并且只需要 1 个参数,而 peekmessage 需要 5 个参数。 如果有可用消息,它会给出快速提示,但不会以任何方式处理该消息。

GetQueueStatus 和 GetInputStatus 是相关函数。

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 and GetInputStatus are related functions.

寂寞清仓 2024-08-05 00:58:55

我认为这就是 PeekMessage 应该做的。 它和 GetMessage 之间的唯一区别是GetMessage 会阻塞,直到消息到达,而 PeekMessage 将根据是否找到与过滤器匹配的消息返回 TRUE 或 FALSE。 如果找到消息,它仍然会处理消息。

I think this is what PeekMessage is supposed to do. The only difference between it and GetMessage is 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.

做个少女永远怀春 2024-08-05 00:58:55

PeekMessage 处理消息,因为这就是 PeekMessage 的作用。

也许它的命名很糟糕,但 PeekMessage 确实会从队列中删除消息(如果有可用的消息)。

PeekMessage processes messages because that's what PeekMessage does.

Maybe it's badly named, but PeekMessage do remove the message from the queue if there are any available.

挽你眉间 2024-08-05 00:58:55
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 )            
            }
    }


    }
}
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 )            
            }
    }


    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文