MFC - How to post a message to all views that were derived from CView class?

微笑、不失礼 提交于 2021-01-28 05:03:57

问题


I want to post a message to all views. I'm considering get a Document global reference and then implement a method like below

void SomeAppDoc::DispatchToAll( UINT msg, WPARAM wP, LPARAM lP )
{
  //some how get all view's reference
  //iterate and update each views 
}

What is the effective way?


回答1:


The simplest way is to call CDocument::UpdateAllViews, which calls the OnUpdate function of each view attached to the document.

If you really need to post a message to each view, rather than call OnUpdate, do something similar to 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);
    }
}

I hope this helps!




回答2:


I had a similar problem however I found this provided answer to be insufficient as there are two parts to a solution to this question.

The first is as provided with the process of iterating through the various views and using PostMessage() to send a message to each view.

The second part is what to do on the CView side that is receiving the message being sent and I want to provide a bit of a note on that part.

In the MFC application I am working on, I wanted to send a message to the CView and was running into an exception due to a mistake on my part as to how to process the message being sent.

In the class derived from CDocument I had a function that iterates over the list of CView objects to send a message to each. In this particular case I was wanting to reposition the view port to a designated section of a report. This required the Windows message that was sent to include an offset value as well as a message identifier.

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

I am using the standard Windows SDK define WM_APP to create a unique message identifier within the range of user defined message ids (as opposed to standard Windows message ids) to send a message indicating the offset to use as the WPARAM argument of PostMessage(). See Message Map Macros - ON_MESSAGE which states:

User-defined messages are any messages that are not standard Windows WM_MESSAGE messages. When selecting a message ID, you must use values within the range of WM_USER (0x0400) to 0x7FFF or WM_APP (0x8000) to 0xBFFF. For more information regarding message IDs, see WM_APP.

In the CView class I added an entry to the message map for the CView class. I am using ON_MESSAGE rather than ON_COMMAND because I need to provide the offset to the CView processing the message.

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

and then added the source for the actual message handler itself which calculates the correct viewport scroll position by using the offset of the text line in a buffer along with the line height of each text line:

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

    CPoint  ptOrigin;
    ptOrigin = GetScrollPosition();

    wParam *= m_sizeCell.cy;    // multiple text line offset by height of each line of text
    ptOrigin.y = wParam;        // change the vertical position of the scroll bar

    ScrollToPosition(ptOrigin);   // move the scroll bar elevator

    this->UpdateWindow();     // tell view to update displayed window to match elevator position

    return 0;
}

For more details about messages see Message Handling and Mapping in the Microsoft docs.



来源:https://stackoverflow.com/questions/8740263/mfc-how-to-post-a-message-to-all-views-that-were-derived-from-cview-class

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!