WINAPI - Nachrichten in Message-Queque zählen

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
Benutzeravatar
starcow
Establishment
Beiträge: 527
Registriert: 23.04.2003, 17:42
Echter Name: Mischa Schaub
Kontaktdaten:

WINAPI - Nachrichten in Message-Queque zählen

Beitrag von starcow »

Abend zusammen :-)

Ich würde gerne Zwecks Experiment die Nachrichten in einer Message-Queque von Windows zählen.
Auch wenn ich die Nachrichten ja mittels PeekMessage und PM_NOREMOVE in der Schlange belassen kann, sehe ich irgendwie keine Möglichkeit sie zu zählen oder auf einem anderen Weg an deren Anzahl zu bestimmen.

Kann es sein, dass dies "per se" gar nicht möglich ist?
Hat von euch jemand vielleicht eine Idee, wie das klappen könnte?
Freelancer 3D- und 2D-Grafik
mischaschaub.com
Benutzeravatar
gombolo
Establishment
Beiträge: 147
Registriert: 26.01.2011, 20:33

Re: WINAPI - Nachrichten in Message-Queque zählen

Beitrag von gombolo »

Habe schon lange nichts mehr mit der WinAPI gemacht, aber müsste das so nicht gehen? Eine andere Möglichkeit fällt mir nicht ein. irgendwo liegt noch der Wälzer von Petzold...müsste ich mal schauen.

int count =0;

while (PeekMessage(&msg, NULL, 0, 0,..... weiss incht mehr was da rein kommt)
{
...

count++;
}
MEIN AKTELLES PROJEKT -> FirstStrike PLAY THE DEMO

NEUER ENDBOSS -> schau dir das Video an

WAS ICH SONST SO MACHEN -> Grafik und Design

ICH MACH MAL SCHNELL EINE 3D ENGINE -> oyname 3DEngine
NytroX
Establishment
Beiträge: 364
Registriert: 03.10.2003, 12:47

Re: WINAPI - Nachrichten in Message-Queque zählen

Beitrag von NytroX »

Ich glaube das geht nicht offiziell.
Normalerweise macht es auch keinen Sinn, die Nachrichten in der Queue zu zählen, weil es deine Applikation unperformant macht.
Die Nachrichten sollten immer so schnell wie möglich aus der Queue abgeholt werden.

Gibt es einen Grund, warum du sie nicht einfach abholen und in eine eigene Queue schreiben kannst? Dann kannst du beim Durchlauf zählen.
Ansonsten könntest du sie ja auch abholen und mit "SendMessage" quasi wieder "oben reinstecken". Aber das ist ein böser Hack :-)

Oder du versuchst die Struktur herauszufinden, wie hier in Solution 3:
https://www.codeproject.com/questions/2 ... ows-thread

Das ist aber noch böser als der erste Vorschlag.

Anscheinend geht es auch über WMI irgendwie, aber ich habe keine Ahnung wie man an den Queue-Namen kommen soll:
https://www.meadow.se/wordpress/retriev ... mq-queues/

Generell macht es wie gesagt vermutlich wenig Sinn, aber du kannst es als Experiment ja mal versuchen :-)
NytroX
Establishment
Beiträge: 364
Registriert: 03.10.2003, 12:47

Re: WINAPI - Nachrichten in Message-Queque zählen

Beitrag von NytroX »

Btw eine ähnliche Antwort wie von Gombolo sagt mir die KI, aber es macht für mich erstmal keinen Sinn, dass PeekMessage() die Nachrichten durchgeht, ohne die erste abzuholen, könnte also grober Unfug sein:
https://www.perplexity.ai/search/e23f68 ... 0cc8ad481e

Aber wer weiß, kannst du ja auch mal probieren.
Benutzeravatar
gombolo
Establishment
Beiträge: 147
Registriert: 26.01.2011, 20:33

Re: WINAPI - Nachrichten in Message-Queque zählen

Beitrag von gombolo »

http://winapi.freetechsecrets.com/win32 ... Status.htm

hmmm->The high-order word of the return value indicates the types of messages currently in the queue. The low-order word indicates the types of messages that have been added to the queue and that are still in the queue since the last call to the GetQueueStatus, GetMessage, or PeekMessage function.

unter Umständen damit?
MEIN AKTELLES PROJEKT -> FirstStrike PLAY THE DEMO

NEUER ENDBOSS -> schau dir das Video an

WAS ICH SONST SO MACHEN -> Grafik und Design

ICH MACH MAL SCHNELL EINE 3D ENGINE -> oyname 3DEngine
Benutzeravatar
Krishty
Establishment
Beiträge: 8245
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: WINAPI - Nachrichten in Message-Queque zählen

Beitrag von Krishty »

Viele Win32-Nachrichten sind keine echten Nachrichten, die in der Schlange landen. WM_MOUSEMOVE, WM_TIMER und WM_PAINT sind sowas – wenn die Anwendung viel zu tun hat, werden sie erst gar nicht generiert; wenn die Anwendung leer läuft, ständig.

Davon ab hast du aber doch sicher irgendwo GetMessage() oder PeekMessage() laufen, wie gombolo sagt?

Wenn du den Zähler nicht direkt in der Anwendung brauchst, sondern nur mal gucken willst, gibt Spy++ dir auch alle Nachrichten zu einem Prozess aus.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Hannes
Beiträge: 37
Registriert: 11.06.2008, 06:04

Re: WINAPI - Nachrichten in Message-Queque zählen

Beitrag von Hannes »

Ich hab das mal schnell gebaut.
Ist ganz witzig. :-)

Code: Alles auswählen

//#undef UNICODE

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

LRESULT WndProc(HWND, UINT, WPARAM, LPARAM);

int main()
{
    int msgCounter = 0;
    MSG msg = { 0 };
    HWND hwndMain = 0;
    HINSTANCE hInstance = GetModuleHandle(NULL);
    WNDCLASS wc = { 0 };

    wc.style = 0;
    wc.lpfnWndProc = (WNDPROC)WndProc;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon((HINSTANCE)NULL,  IDI_APPLICATION);
    wc.hCursor = LoadCursor((HINSTANCE)NULL, IDC_ARROW);
    wc.hbrBackground = GetStockObject(WHITE_BRUSH);
    wc.lpszClassName = TEXT("MainWndClass");
    if (!RegisterClass(&wc))
        return FALSE;

    // Create the main window. 
    hwndMain = CreateWindow(TEXT("MainWndClass"), TEXT("Sample"),
        WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT,
        CW_USEDEFAULT, CW_USEDEFAULT, (HWND)NULL,
        (HMENU)NULL, hInstance, (LPVOID)NULL);
    if (!hwndMain)
        return FALSE;
    
    // Start the message loop.
    while (TRUE)
    {
        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            if (msg.message == WM_QUIT)
                break;

            TranslateMessage(&msg);
            DispatchMessage(&msg);

            {
                TCHAR buffer[256] = { 0 };
                ++msgCounter;
                wsprintf(buffer, TEXT("Message Counter: %d"), msgCounter);
                SetWindowText(hwndMain, buffer);
            }
        }
    }
    // Return the exit code to the system. 

    return msg.wParam;
}

LRESULT WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
    switch (message)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }

    return DefWindowProc(hwnd, message, wparam, lparam);
}
Kurze frage: Wie funktionieren die Code-Tags für eine bestimmte Sprache? Also für C in diesem Fall.
Benutzeravatar
starcow
Establishment
Beiträge: 527
Registriert: 23.04.2003, 17:42
Echter Name: Mischa Schaub
Kontaktdaten:

Re: WINAPI - Nachrichten in Message-Queque zählen

Beitrag von starcow »

Danke euch für die guten Vorschläge!
NytroX hat geschrieben: 21.06.2023, 20:02 Gibt es einen Grund, warum du sie nicht einfach abholen und in eine eigene Queue schreiben kannst? Dann kannst du beim Durchlauf zählen.
Ansonsten könntest du sie ja auch abholen und mit "SendMessage" quasi wieder "oben reinstecken". Aber das ist ein böser Hack :-)
Ich denke du meinst PostMessage (?). Mit SendMessage laden die Nachrichten ja nicht in der Message Queque sondern werden direkt an die Callback function weitergereicht.

Die Idee wäre ja an sich nicht schlecht, doch Nachrichten des Typs WM_PAINT kriegt man ja weder mit GetMessage noch mit PeekMessage einfach abgeräumt. Nur wenn der Bereich als "aktualisiert" gekennzeichnet wird, entfernt Windows WM_PAINT (also entweder über ValidateRect, ValidateRgn oder BeginPaint / EndPaint). Alternativ überlässt man die Nachricht DefWindowProc. (Petzold S. 196, 197, deutsche Ausgabe).

Eigentlich würde ich die Nachrichten alle gerne in der Message Queque belassen. Aber da man ja anscheinend keine Möglichkeit hat, zu erkennen, ob man ein und dieselbe Nachricht wieder "in den Händen" hält, sehe ich auch keine Lösung, die Nachrichten in der Schlage auf diese Weise zu zählen. Sonst könnte man ja einfach alle Nachrichten unbearbeitet durchgehen, bis man wieder zur selben Nachricht gelangt.
gombolo hat geschrieben: 21.06.2023, 20:19 http://winapi.freetechsecrets.com/win32 ... Status.htm

hmmm->The high-order word of the return value indicates the types of messages currently in the queue. The low-order word indicates the types of messages that have been added to the queue and that are still in the queue since the last call to the GetQueueStatus, GetMessage, or PeekMessage function.

unter Umständen damit?
Danke, damit hatte ich es auch schon versucht. Bei mir kam aber leider nie die konkrete Anzahl der Nachrichten als Rückgabewert.
Wenn ich die Funktion richtig verstehe, liefert sie blos die Anzahl der Nachrichten-Typen. So 100% schlau bin ich daraus noch nicht geworden:
The high-order word of the return value indicates the types of messages currently in the queue. The low-order word indicates the types of messages that have been added to the queue and that are still in the queue since the last call to the GetQueueStatus, GetMessage, or PeekMessage function.
Krishty hat geschrieben: 21.06.2023, 20:41 Viele Win32-Nachrichten sind keine echten Nachrichten, die in der Schlange landen. WM_MOUSEMOVE, WM_TIMER und WM_PAINT sind sowas – wenn die Anwendung viel zu tun hat, werden sie erst gar nicht generiert; wenn die Anwendung leer läuft, ständig.

Davon ab hast du aber doch sicher irgendwo GetMessage() oder PeekMessage() laufen, wie gombolo sagt?

Wenn du den Zähler nicht direkt in der Anwendung brauchst, sondern nur mal gucken willst, gibt Spy++ dir auch alle Nachrichten zu einem Prozess aus.
Ich habe beides versucht - mittels GetMessage und über PeekMessage. Aber auf eine Lösung bin ich nicht gekommen.
Soviel ich jetzt verstanden habe, gibt es indirekte Nachrichten und direkte Nachrichten. Nur die Indirekten laden dabei in der Message Queque.
Z. B. sendet UpdateWindow eine WM_PAINT Nachricht direkt an die registrierte Callback Funktion.
Deine Aussage bezieht sich aber nicht darauf, oder?
Wenn das so ist, dann wird das Ganze ja ziemlich schnell "undurchschaubar". Wird das später nicht zum Problem, wenn man sich nicht darauf verlassen kann, ob z. B. eine WM_TIMER Nachricht nun gepostet wird - oder nicht gepostet wird?

Also ist möglicherweise meine Idee so nicht umsetzbar...
Gewisse Dinge hätten sich so quasi sehr einfach experimentell feststellen lassen.
Z. B. bin ich mir nicht ganz sicher, ob sich tatsächlich nur maximal eine WM_PAINT Nachricht in der Schlange befinden kann (egal zu welcher Zeit). Sowas (und Anderes) könnte man sofort sehen, wenn man die Anzahl der Nachrichten auslesen könnte.
Freelancer 3D- und 2D-Grafik
mischaschaub.com
Benutzeravatar
Krishty
Establishment
Beiträge: 8245
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: WINAPI - Nachrichten in Message-Queque zählen

Beitrag von Krishty »

starcow hat geschrieben: 22.06.2023, 20:37Z. B. bin ich mir nicht ganz sicher, ob sich tatsächlich nur maximal eine WM_PAINT Nachricht in der Schlange befinden kann (egal zu welcher Zeit). Sowas (und Anderes) könnte man sofort sehen, wenn man die Anzahl der Nachrichten auslesen könnte.
Feststellen, wie oft WM_PAINT gesendet wird, ist ein Bisschen wie feststellen, wie oft dein Balkon schmutzig wird. Die ganze Zeit, ohne Unterbrechung. Du kannst höchstens zählen, wie oft du ihn putzt.

WM_PAINT liegt nur mehrfach in der Schlange, falls es jemand mit PostMessage() o.Ä. explizit dort reintut. Was man auf keinen Fall tun sollte, außer in exotischen Randfällen. Ansonsten ist WM_PAINT schlicht ein Flag: https://devblogs.microsoft.com/oldnewth ... 00/?p=8863
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
starcow
Establishment
Beiträge: 527
Registriert: 23.04.2003, 17:42
Echter Name: Mischa Schaub
Kontaktdaten:

Re: WINAPI - Nachrichten in Message-Queque zählen

Beitrag von starcow »

Hannes hat geschrieben: 21.06.2023, 20:46 Ich hab das mal schnell gebaut.
Ist ganz witzig. :-)

Code: Alles auswählen

//#undef UNICODE

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

LRESULT WndProc(HWND, UINT, WPARAM, LPARAM);

int main()
{
    int msgCounter = 0;
    MSG msg = { 0 };
    HWND hwndMain = 0;
    HINSTANCE hInstance = GetModuleHandle(NULL);
    WNDCLASS wc = { 0 };

    wc.style = 0;
    wc.lpfnWndProc = (WNDPROC)WndProc;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon((HINSTANCE)NULL,  IDI_APPLICATION);
    wc.hCursor = LoadCursor((HINSTANCE)NULL, IDC_ARROW);
    wc.hbrBackground = GetStockObject(WHITE_BRUSH);
    wc.lpszClassName = TEXT("MainWndClass");
    if (!RegisterClass(&wc))
        return FALSE;

    // Create the main window. 
    hwndMain = CreateWindow(TEXT("MainWndClass"), TEXT("Sample"),
        WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT,
        CW_USEDEFAULT, CW_USEDEFAULT, (HWND)NULL,
        (HMENU)NULL, hInstance, (LPVOID)NULL);
    if (!hwndMain)
        return FALSE;
    
    // Start the message loop.
    while (TRUE)
    {
        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            if (msg.message == WM_QUIT)
                break;

            TranslateMessage(&msg);
            DispatchMessage(&msg);

            {
                TCHAR buffer[256] = { 0 };
                ++msgCounter;
                wsprintf(buffer, TEXT("Message Counter: %d"), msgCounter);
                SetWindowText(hwndMain, buffer);
            }
        }
    }
    // Return the exit code to the system. 

    return msg.wParam;
}

LRESULT WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
    switch (message)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }

    return DefWindowProc(hwnd, message, wparam, lparam);
}
Kurze frage: Wie funktionieren die Code-Tags für eine bestimmte Sprache? Also für C in diesem Fall.
Bezogen auf dein Beispiel Hannes:
Darf man die Calling-Convention bei der Windows-Programmierung wirklich einfach weglassen? Ich meine jetzt konkret CALLBACK und WINAPI (was ja, glaube ich, heute das selbe ist).
Freelancer 3D- und 2D-Grafik
mischaschaub.com
Benutzeravatar
Krishty
Establishment
Beiträge: 8245
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: WINAPI - Nachrichten in Message-Queque zählen

Beitrag von Krishty »

starcow hat geschrieben: 03.07.2023, 15:33Darf man die Calling-Convention bei der Windows-Programmierung wirklich einfach weglassen?
Eigentlich nicht. Aber 64-Bit Win32 hat nur eine einzige Calling Convention, darum klappt es dort. Als 32-Bit-Projekt würde das nicht kompilieren.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Antworten