-
September 30th, 2013, 03:10 PM
#1
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.
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?
-
October 1st, 2013, 01:51 AM
#2
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
-
October 1st, 2013, 11:41 AM
#3
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
-
October 1st, 2013, 01:26 PM
#4
Re: CDockablePane messages in MFC document/view architecture (good programming practi
Originally Posted by odiezgz
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.
-
October 2nd, 2013, 11:42 AM
#5
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.
-
October 5th, 2013, 04:23 AM
#6
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
-
October 5th, 2013, 09:58 AM
#7
Re: CDockablePane messages in MFC document/view architecture (good programming practi
Originally Posted by odiezgz
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|