2 Stimmen

MFC - Wie kann eine Nachricht an alle Ansichten gesendet werden, die von der CView-Klasse abgeleitet wurden?

Ich möchte eine Nachricht an alle Ansichten posten. Ich überlege, eine globale Referenz auf das Dokument zu erhalten und dann eine Methode wie unten zu implementieren

void SomeAppDoc::DispatchToAll( UINT msg, WPARAM wP, LPARAM lP )
{
  //irgendwie alle Ansichtenreferenzen erhalten
  //iterieren und jede Ansicht aktualisieren
}

Was ist der effektivste Weg?

2voto

ChrisN Punkte 16165

Der einfachste Weg ist, CDocument::UpdateAllViews aufzurufen, das die OnUpdate Funktion jeder Ansicht aufruft, die am Dokument angehängt ist.

Wenn Sie wirklich eine Nachricht an jede Ansicht senden müssen, anstatt OnUpdate aufzurufen, tun Sie etwas Ähnliches wie UpdateAllViews:

void SomeAppDoc::DispatchToAll(UINT msg, WPARAM wParam, LPARAM lParam)
{
    POSITION pos = GetFirstViewPosition();
    while (pos != NULL)
    {
        CView* pView = GetNextView(pos);
        pView->PostMessage(msg, wParam, lParam);
    }
}

Ich hoffe, das hilft!

0voto

Richard Chambers Punkte 15587

Ich hatte ein ähnliches Problem, jedoch fand ich diese bereitgestellte Antwort als unzureichend, da es zwei Teile einer Lösung zu dieser Frage gibt.

Der erste Teil besteht darin, den Prozess des Durchlaufs durch die verschiedenen Ansichten und die Verwendung von PostMessage() zum Senden einer Nachricht an jede Ansicht bereitzustellen.

Der zweite Teil ist, was auf der CView-Seite zu tun ist, die die Nachricht empfängt, und ich möchte zu diesem Teil eine Anmerkung machen.

In der MFC-Anwendung, an der ich arbeite, wollte ich eine Nachricht an die CView senden und stieß auf eine Ausnahme aufgrund eines Fehlers meinerseits, wie die gesendete Nachricht verarbeitet werden sollte.

In der von CDocument abgeleiteten Klasse hatte ich eine Funktion, die über die Liste von CView-Objekten iteriert, um eine Nachricht an jede zu senden. In diesem speziellen Fall wollte ich den Ansichtsbereich in einen bestimmten Abschnitt eines Berichts verschieben. Dafür musste die gesendete Windows-Nachricht einen Offset-Wert sowie einen Nachrichtenidentifikator einschließen.

        POSITION pos = GetFirstViewPosition();
        while (pos != NULL)
        {
            CView* pView = GetNextView(pos);
            if (pView)
                pView->PostMessage(WM_APP + 10, sectionHeader.m_ListOffset, 1);
        }

Ich verwende die Standard-Windows-SDK-Definition WM_APP, um einen eindeutigen Nachrichtenidentifikator im Bereich der benutzerdefinierten Nachrichten-IDs (im Gegensatz zu Standard-Windows-Nachrichten-IDs) zu erstellen, um eine Nachricht zu senden, die den Offset als das WPARAM-Argument von PostMessage() verwendet. Siehe Message Map Macros - ON_MESSAGE, die besagt:

Benutzerdefinierte Nachrichten sind Nachrichten, die keine standardmäßigen Windows-Nachrichten sind. Bei der Auswahl einer Nachrichten-ID müssen Werte im Bereich von WM_USER (0x0400) bis 0x7FFF oder WM_APP (0x8000) bis 0xBFFF verwendet werden. Weitere Informationen zu Nachrichten-IDs finden Sie unter WM_APP.

In der CView-Klasse habe ich einen Eintrag in der Nachrichtenkarte für die CView-Klasse hinzugefügt. Ich verwende ON_MESSAGE anstelle von ON_COMMAND, weil ich dem CView den Offset zur Verarbeitung der Nachricht bereitstellen muss.

ON_MESSAGE(WM_APP + 10, &CPCSampleView::OnWindowSetSection)

und fügte dann die Quelle für den tatsächlichen Nachrichtenhandler hinzu, der die richtige Scroll-Position des Viewports berechnet, indem er den Offset der Textzeile in einem Puffer sowie die Zeilenhöhe jeder Textzeile verwendet:

LRESULT CPCSampleView::OnWindowSetSection(WPARAM  wParam, LPARAM  lParam)
{
    CPCSampleDoc *pDoc = GetDocument();

    CPoint  ptOrigin;
    ptOrigin = GetScrollPosition();

    wParam *= m_sizeCell.cy;    // multipliziere den Textzeilenoffset mit der Höhe jeder Textzeile
    ptOrigin.y = wParam;        // ändere die vertikale Position der Scrollleiste

    ScrollToPosition(ptOrigin);   // bewege den Scroll-Leistenelevator

    this->UpdateWindow();     // sag der Ansicht, das angezeigte Fenster an die Position des Elevators anzupassen

    return 0;
}

Für weitere Details zu Nachrichten siehe Message Handling and Mapping in den Microsoft-Dokumenten.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X