5

我试图无辜地打电话

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

在 PeekMessage 调用中,Windows Vista 64 正在处理消息。结果是我要重入我的绘画调用和各种其他代码。

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

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

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

4

5 回答 5

5

也许我错过了明显的,但规范非常冗长它会这样做

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

...

在此调用期间,系统会传递待处理的非排队消息,即使用 SendMessage、SendMessageCallback、SendMessageTimeout 或 SendNotifyMessage 函数发送到调用线程拥有的窗口的消息。然后检索与指定过滤器匹配的第一个排队消息。系统还可以处理内部事件。如果未指定过滤器,则按以下顺序处理消息:

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

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

于 2009-07-15T19:45:48.550 回答
3

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

GetQueueStatus 和 GetInputStatus 是相关函数。

于 2010-09-13T20:15:37.130 回答
2

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

于 2009-07-15T19:49:32.770 回答
0

PeekMessage 处理消息,因为这就是 PeekMessage 所做的。

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

于 2009-07-15T20:03:39.763 回答
-1
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 )            
            }
    }


    }
}
于 2015-02-03T15:58:06.277 回答