Schreiben der Fensterprozedur

Die DispatchMessage-Funktion ruft die Fensterprozedur des Fensters auf, das das Ziel der Nachricht ist. Die Fensterprozedur hat die folgende Signatur.

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

Es gibt vier Parameter:

  • hwnd ist ein Handle für das Fenster.
  • uMsg ist der Nachrichtencode. Die WM _ SIZE-Meldung gibt beispielsweise an, dass die Größe des Fensters geändert wurde.
  • wParam und lParam enthalten zusätzliche Daten, die sich auf die Nachricht beziehen. Die genaue Bedeutung hängt vom Nachrichtencode ab.

LRESULT ist ein ganzzahliger Wert, den Ihr Programm zurückgibt, um Windows. Sie enthält die Antwort Ihres Programms auf eine bestimmte Nachricht. Die Bedeutung dieses Werts hängt vom Nachrichtencode ab. CALLBACK ist die Aufrufkonvention für die Funktion.

Eine typische Fensterprozedur ist einfach eine umfangreiche switch-Anweisung, die den Meldungscode einschaltet. Fügen Sie Fälle für jede Nachricht hinzu, die Sie behandeln möchten.

switch (uMsg)
{
    case WM_SIZE: // Handle window resizing

    // etc
}

Zusätzliche Daten für die Nachricht sind in den Parametern lParam und wParam enthalten. Beide Parameter sind ganzzahlige Werte, die die Größe einer Zeigerbreite (32 Bits oder 64 Bits) haben. Die Bedeutung der einzelnen hängt vom Nachrichtencode (uMsg ) ab. Für jede Nachricht müssen Sie den Nachrichtencode auf MSDN nachschauen und die Parameter in den richtigen Datentyp casten. In der Regel sind die Daten entweder ein numerischer Wert oder ein Zeiger auf eine Struktur. Einige Nachrichten enthalten keine Daten.

In der Dokumentation für die WM _ SIZE-Meldung wird beispielsweise Folgendes angezeigt:

  • wParam ist ein Flag, das angibt, ob das Fenster minimiert, maximiert oder die Größe geändert wurde.
  • lParam enthält die neue Breite und Höhe des Fensters als 16-Bit-Werte, die in eine 32- oder 64-Bit-Zahl gepackt sind. Sie müssen einige Bitverschiebungen durchführen, um diese Werte zu erhalten. Glücklicherweise enthält die Headerdatei WinDef.h Hilfsmakros, die dies tun.

Eine typische Fensterprozedur verarbeitet Dutzende von Nachrichten, sodass sie sehr lang werden kann. Eine Möglichkeit, Ihren Code modularer zu machen, besteht in der Logik für die Behandlung jeder Nachricht in einer separaten Funktion. Geben Sie in der Fensterprozedur die Parameter wParam und lParam in den richtigen Datentyp um, und übergeben Sie diese Werte an die Funktion. Um beispielsweise die WM _ SIZE-Meldung zu verarbeiten, sieht die Fensterprozedur wie die folgende aus:

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_SIZE:
        {
            int width = LOWORD(lParam);  // Macro to get the low-order word.
            int height = HIWORD(lParam); // Macro to get the high-order word.

            // Respond to the message:
            OnSize(hwnd, (UINT)wParam, width, height);
        }
        break;
    }
}

void OnSize(HWND hwnd, UINT flag, int width, int height)
{
    // Handle resizing
}

Die MAKROs LOWORD und HIWORD erhalten die Werte für Breite und Höhe von 16 Bit aus lParam. (Sie können diese Art von Details in der MSDN-Dokumentation für jeden Meldungscode nachschauen.) Die Fensterprozedur extrahiert die Breite und Höhe und übergibt diese Werte dann an die OnSize Funktion.

Standardnachrichtenbehandlung

Wenn Sie eine bestimmte Nachricht in Ihrer Fensterprozedur nicht verarbeiten, übergeben Sie die Nachrichtenparameter direkt an die DefWindowProc-Funktion. Diese Funktion führt die Standardaktion für die Nachricht aus, die je nach Nachrichtentyp variiert.

return DefWindowProc(hwnd, uMsg, wParam, lParam);

Vermeiden von Engpässen in der Fensterprozedur

Während die Fensterprozedur ausgeführt wird, werden alle anderen Meldungen für Fenster blockiert, die im selben Thread erstellt wurden. Vermeiden Sie daher eine lange Verarbeitung innerhalb der Fensterprozedur. Angenommen, Ihr Programm öffnet eine TCP-Verbindung und wartet unbegrenzt, bis der Server antwortet. Wenn Sie dies innerhalb der Fensterprozedur tun, antwortet Ihre Benutzeroberfläche erst, wenn die Anforderung abgeschlossen ist. Während dieser Zeit kann das Fenster keine Maus- oder Tastatureingabe verarbeiten, sich selbst neu anmalen oder sogar schließen.

Stattdessen sollten Sie die Arbeit in einen anderen Thread verschieben, indem Sie eine der multitasking-Einrichtungen verwenden, die in die Windows:

  • Erstellen Sie einen neuen Thread.
  • Verwenden von Threadpools.
  • Verwenden Sie asynchrone E/A-Aufrufe.
  • Verwenden Sie asynchrone Prozeduraufrufe.

Nächste

Malen des Fensters