CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 7 of 7
  1. #1
    Join Date
    Sep 2013
    Location
    Spain
    Posts
    4

    CDockablePane messages in MFC document/view architecture (good programming practices)

    I am developing a small MFC program, and I'm obsessed with good programming practices.
    I would like to know how to manage messages between windows in SDI application in the right way on a document / view architecture.
    Below I will outline practical case in which I have encountered a problem. The following image is a screenshot of my SDI application generated with visual studio wizard.

    Name:  Captura.jpg
Views: 3599
Size:  65.3 KB

    The three main classes generated by visual studio wizard are:

    Code:
    	CSingleDocTemplate* pDocTemplate;
    	pDocTemplate = new CSingleDocTemplate(
    		IDR_MAINFRAME,
    		RUNTIME_CLASS(CCameraCalibrationDoc),
    		RUNTIME_CLASS(CMainFrame),       // Ventana de marco SDI principal
    		RUNTIME_CLASS(CCameraCalibrationView));
    The window that I have numbered as one is a Class CCameraCalibrationView, and is easy to access the document linked to by the function GetDocument() and modify it in response to user interaction with the window.

    Code:
    class CCameraCalibrationView : public CView
    {
    protected: // Crear sólo a partir de serialización
    	CCameraCalibrationView();
    	DECLARE_DYNCREATE(CCameraCalibrationView)
    
    // Atributos
    public:
    	CCameraCalibrationDoc* GetDocument() const;
    
    // Operaciones
    public:
    ...
    So it is just as easy to call the function UpdateAllViews (CView * pSender, LPARAM lHint = 0L, CObject * pHint = NULL) after modifying the document to refresh the view CCameraCalibrationView class.

    UpdateAllViews only modifies CView inherited classes that are part of the document template in the case of my application is CCameraCalibrationView (and on a SDI application I think I can only have one view linked to the document). The problem is that my CDockablePane controls (2 and 3 in the screenshot) that should be able to modify the document in response to the user and should be updated as CCameraCalibrationView to the modification of the document.

    I dont know how to do it, respecting the document / view architecture and program it in an elegant way.

    I can only think in generate custom windows messages from DockablePanes in respond to user inputs and send it to the CMainFrame, cath it from the MainFrame and change the document from here and redistribuite the message to all views including the CDockablePanes. it's rigth? it's smart?

  2. #2
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: CDockablePane messages in MFC document/view architecture (good programming practi

    CDockablePane is a command target, so from your document you can post some command to main frame, and command will be routed to any window that handles it. The thing is, you need to implement ON_COMMAND_EX style handling to let other panes to get the command too.

    And yes, updating panes stands totally apart from doc/view. Just because panes are not views.
    Last edited by Igor Vartanov; October 1st, 2013 at 01:54 AM.
    Best regards,
    Igor

  3. #3
    Join Date
    Sep 2013
    Location
    Spain
    Posts
    4

    Re: CDockablePane messages in MFC document/view architecture (good programming practi

    First at all, thanks for the reply Igor,
    on the ON_COMMAND_EX the most interesting part is that command will be routed to any window that handles it but the inconvenient is that ON_COMMAND_EX take a single parameter, a UINT containing the command ID, but none information about modified object, isn't better to post a custom windows message with more information to mainfraim and redistribute this message to his own controls?
    I'm thinking in anything like this:

    My left dockablepane contain a CTreeView inherited from a CTreeCtrl

    Code:
    #define UWM_CHECKSTATECHANGE (WM_USER + 100)
    #define UWM_ITEMSELECTED (WM_USER + 101)
    
    class CViewTree : public CTreeCtrl
    {
    // Construcción
    public:
    	CViewTree();
    private:
    	CImageList *treeStateImageList;
    // Invalidaciones
    protected:
    	virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
    // Implementación
    public:
    	virtual ~CViewTree();
    	int GetTreeCheckState(HTREEITEM inItem);
    	void SetTreeCheckState(HTREEITEM inItem, int inState);
    
    protected:
    	DECLARE_MESSAGE_MAP()
    public:
    	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
    	afx_msg LRESULT OnTreeViewCheckbox(WPARAM wParam, LPARAM lParam);
    	afx_msg LRESULT OnTreeViewItem(WPARAM wParam, LPARAM lParam);
    	virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
    };
    This class cath the DownButton click event and Post a message to the MainFrameWindow:

    Code:
    LRESULT CViewTree::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
    {
    	// TODO: Add your specialized code here and/or call the base class
    
    	switch (message) {
    
    		case WM_LBUTTONDOWN: {
    
    			TVHITTESTINFO ht = {0};
    
    			ht.pt.x = GET_X_LPARAM (lParam);
    			ht.pt.y = GET_Y_LPARAM (lParam);
    			
    			TreeView_HitTest(GetSafeHwnd(), &ht);
    
    			if (TVHT_ONITEMSTATEICON & ht.flags) {
    				AfxGetMainWnd()->PostMessage (UWM_CHECKSTATECHANGE, (WPARAM)GetSafeHwnd(), (LPARAM) ht.hItem);
    				return 0;
    			} else
    
    			if (TVHT_ONITEM & ht.flags) {
    				AfxGetMainWnd()->PostMessage (UWM_ITEMSELECTED, (WPARAM)GetSafeHwnd(), (LPARAM) ht.hItem);
    			}			
    
    			break;
    		}
    	}
    	return CTreeCtrl::WindowProc(message, wParam, lParam);
    }
    In this case lparam contain information of the item that contain the object of the documents that have to be modified and wparam contain information about the control that is posting the message
    From the mainfraim i'm not implemented the code yet, but we would have to cath the events, manipulate the Document and post the the message to the owners controls like the 2 dockablepanes and maybe send a message text to the output control (the bottom listbox control).

    Im looking for the ON_COMMAND_EX in the web but i don't know how to make anything similar without information of the object that i want to modify. I think that ON_COMAND & ON_COMAND_EX style handling are thinked in response to Menu and ToolBars clicks events, but i'm not sure at all.

    Sorry if you dont understand my english (is very poor) i'm learnig more english looking for MFC information in the web that the own MFC

  4. #4
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: CDockablePane messages in MFC document/view architecture (good programming practi

    Quote Originally Posted by odiezgz View Post
    First at all, thanks for the reply Igor,
    on the ON_COMMAND_EX the most interesting part is that command will be routed to any window that handles it but the inconvenient is that ON_COMMAND_EX take a single parameter, a UINT containing the command ID, but none information about modified object, isn't better to post a custom windows message with more information to mainfraim and redistribute this message to his own controls?
    In my opinion, no. Having the ON_COMMAND_EX not take any parameters isn't a problem because all you really need is a 'trigger' message. The reason behind this is that presumably all the views in the app are getting their data from the document and since all the views have access from the document, all you need to do is set the selected (tree node) data in the document, then send a 'trigger' message to another view. When the other view receives this message, it grabs the selected data from the document and acts on it.

    Using this approach, each view only refreshes itself from the document and is only told to refresh itself by either the built-in update view mechanism or by an ON_COMMANDxxx message. In either case, a view only reads data out of the document to refresh.

    IMO, this simplifies the code (and debugging) because you don't have a mix of code where views are updated sometimes from the document and other times from data contained within messages.

  5. #5
    Join Date
    Sep 2013
    Location
    Spain
    Posts
    4

    Re: CDockablePane messages in MFC document/view architecture (good programming practi

    Hello Arjay and thank you for your help.
    Its the first time that i post a question in a forum and is being gratifying to see that professional programmers spend a bit of your free time to help simple mortals,

    Every day I like more the idea of the ON_COMMAND_EX message suggested by Igor, and detailed by Arjay.
    If i understand well, In response to a user action in any window, it modify a variable in CDocument that points to the object to be modified (to avoid having to scroll through thousands of possible data contained in the document) and immediately generate the ON_COMMAND_EX message to the all windows which will have a custom handler for update herself (accessing the object pointed by CDocument). I think that to propagate the message to all the windows, each ON_COMMAND_EX handler have to return false. its rigth?.

    According to what I read in other documentation, CDocument should only contain persistent information, even if this works it seems an excellent idea. Simply i will no save the information of the selected object pointer to disk.

    I will try to program it this weekend, and if its sucessfully i have been thinking in another interesting question about properties dockablepane that i will ask in another thread because it is not related to this topic.

  6. #6
    Join Date
    Sep 2013
    Location
    Spain
    Posts
    4

    Re: CDockablePane messages in MFC document/view architecture (good programming practi

    I was about to implement the code when I thought about the following:
    What would happen if while ON_COMMAND_EX is propagating through all windows with CDocument pointing to the object to modify, another piece of code or the user shoot a new ON_COMMAND_EX and change again the CDocument pointer to the object to modify before the previus ON_COMMAND_EX finalize?
    Well, actually I know what would happen, the first change would look not reflected in some of the windows (in which would execute twice ON_COMMAND_EX handler with the same last pointer).
    how could I solve this? with a stack of modified objects? if so, do I know when all windows have handled all modifications to clear the stack?
    Or is it much easier than this and I'm warming my head thinking

  7. #7
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: CDockablePane messages in MFC document/view architecture (good programming practi

    Quote Originally Posted by odiezgz View Post
    I was about to implement the code when I thought about the following:
    What would happen if while ON_COMMAND_EX is propagating through all windows with CDocument pointing to the object to modify, another piece of code or the user shoot a new ON_COMMAND_EX and change again the CDocument pointer to the object to modify before the previus ON_COMMAND_EX finalize?
    Well, actually I know what would happen, the first change would look not reflected in some of the windows (in which would execute twice ON_COMMAND_EX handler with the same last pointer).
    how could I solve this? with a stack of modified objects? if so, do I know when all windows have handled all modifications to clear the stack?
    Or is it much easier than this and I'm warming my head thinking
    As long as all ui meassages are handled in the main ui thread everything will be queued up properly. If you have additional worker threads doing work, you will need to provide synchronization.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured