Есть ли такая функция, как PeekMessage, которая не обрабатывает сообщения? - PullRequest
3 голосов
/ 15 июля 2009

я пытаюсь невинно позвонить

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

и Windows Vista 64 в вызове PeekMessage обрабатывают сообщения . В результате я возвращаюсь к своему вызову рисования и ко всему прочему коду.

В нашем приложении рисование может занять несколько секунд, поэтому мы добавили вызов PeekMessage, чтобы увидеть, нажал ли пользователь клавишу, чтобы мы могли прервать это рисование и запустить следующее. Мало ли мы поняли, что Windows может начать обрабатывать сообщения на нас. Было бы серьезным рефакторингом поместить реальную работу рисования в отдельный поток ... Мы пытаемся увидеть, были ли нажаты определенные клавиши, или вращалось ли колесо мыши или кнопки мыши, чтобы прервать рендеринг.

Я пытался добавить код специально для предотвращения повторного входа, а затем повторно вводить сообщения рисования в очередь и т. Д. Это все очень грязно, и есть случаи, когда он не работает хорошо.

Есть ли какой-нибудь флаг, который я мог бы добавить к вызову PeekMessage? Я не увидел ничего нового в документации по MSDN. Мне действительно нужен PeekMessage, который не обрабатывает сообщения. Помогите!

Ответы [ 5 ]

5 голосов
/ 15 июля 2009

Возможно, я упускаю очевидное, но спецификация довольно многословна , что это сделает так :

Функция PeekMessage отправляет входящие отправленные сообщения, проверяет цепочка сообщений для опубликованных сообщений сообщение и получает сообщение (если любой существует).

...

Во время этого звонка система доставляет ожидающие сообщения без очереди , то есть сообщения, отправленные на окна, принадлежащие вызов потока с использованием SendMessage, SendMessageCallback, SendMessageTimeout или Функция SendNotifyMessage. Тогда первое сообщение в очереди, которое соответствует указанный фильтр получен. The Система также может обрабатывать внутренние События . Если фильтр не указан, сообщения обрабатываются в следующий заказ:

  • Отправленные сообщения
  • Отправленные сообщения
  • Входные (аппаратные) сообщения и системные события
  • Отправленные сообщения (снова)
  • WM_PAINT сообщения
  • WM_TIMER сообщения

Для получения входных сообщений перед опубликованные сообщения, используйте wMsgFilterMin и параметры wMsgFilterMax.

2 голосов
/ 15 июля 2009

Я думаю, что именно это и должен делать PeekMessage. Единственная разница между ним и GetMessage заключается в том, что GetMessage блокируется до тех пор, пока не прибудет сообщение, а PeekMessage вернет TRUE или FALSE в зависимости от того, было ли найдено сообщение, соответствующее фильтру. Он все равно будет обрабатывать сообщения, если они найдены.

1 голос
/ 14 сентября 2010

GetQueueStatus - это самый быстрый способ проверить наличие доступных сообщений. Он проверит только несколько флагов и примет только 1 параметр по сравнению с 5 параметрами peekmessage. Он быстро подскажет, если есть доступные сообщения, и не обработает сообщение каким-либо образом.

GetQueueStatus и GetInputStatus являются связанными функциями.

0 голосов
/ 03 февраля 2015
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 )            
            }
    }


    }
}
0 голосов
/ 16 июля 2009

PeekMessage обрабатывает сообщения, потому что это то, что делает PeekMessage.

Возможно, оно имеет неправильное название, но PeekMessage действительно удаляет сообщение из очереди, если оно есть.

...