Relationship between CDocument and CPropertySheet - mfc

I have a CPropertySheet instance which is initialized using DoModal() in one of the methods of my CDocument class, in an MDI MFC application
My problem is I would like to refresh the view associated with the document from the sheet without ending the DoModal().
How do I get an handle back to the CDocument from my CPropertySheet so I can manipulated the CView easily ?
I have tried different things from this MSDN article but I am not able to retrieve what I want http://msdn.microsoft.com/en-us/library/bs315d2c.aspx
Thanks a lot.

You can use the SendMessage or PostMessage to the target window. Do this when the apply button is clicked.
Refer: http://cppandmfc.blogspot.com/2012/08/mfc-creating-and-using-property-page.html
You will get a Nice idea from that writeup

Related

Possible to Superclass a Dialog Box in Win32?

I'm using raw Win32 and C++ for a project. As I understand it, I am able to superclass Windows controls by retrieving the class information, replacing the procedure, then registering this as a new class and using it when creating a new window. Subclassing is done by replacing the window's procedure after the window is created. The advantage of superclassing is that you are able to process messages before CreateWindow() returns.
I'm looking to see if it's possible to superclass a dialog box created with CreateDialog() because I'd like to use a resource file for the dialog layout. The problem is that I don't know how I would provide my superclass when I create a dialog box. Is it even possible? Any idea how MFC handles this?
If you use an extended dialog box template to create your dialog, you can specify a custom window class as part of the DLGTEMPLATEEX definition.
The dialog manager will create and layout your dialog as normal, and call your window procedure for any dialog messages. You can use the DefDlgProc function to obtain default processing for any dialog messages you don't want to handle yourself.

MFC: How to catch set focus of each control of dialog in one function

I have "n" dialogs which have the same base dialog. Each dialog has its own controls
edit boxes
combo boxes
list controls
etc.
In base dialog, how do I set focus messages of each control and,for example, give a Message box with
text("Hello I got focus, my ID is %d")?
The easiest way is using the classical subclassing method. The problem is that WM_SETFOCUS is not pumped through the message Loop, so PreTranslateMessage will not help.
Thee are some nice classes that help to do additional subclassing without disturbing the MFC stuff.
Paul Di Lascia wrote CSubclassWnd. PJ Naughter wrote CHookWnd. And with the ATL has CWindowsImpl.
All this classes allow easy additional subclassing even if a window is already subclassed by the MFC.
You can use "standard subclassing" GetWindowLong/SetWindowLong too.
According to this SO article, you can hook the WM_SETFOCUS message.
You can get the Control ID by using GetDlgCtrlID with the hwnd returned by the hook.
But beware of popping up a MessageBox, that will change the focus and trigger your hook proc, making it go into a loop!
As Jerry already said make a hook, get parent window handler via GetParent() and SendMessage(hParentWND, WM_MESSAGE, lParam, wParam).
Of course, you should handle WM_MESSAGE in your parent window.
Btw, framework calls OnSetFocus function when window gained focus.

What are the differences between FormView and Dialog in MFC?

What are the differences between FormView and Dialog in MFC? and can anyone suggest when to use FormView and when to use Dialog?
I have to respectfully disagree with posts above. There is no difference between CFormView and a dialog.
CFormView is a dialog created as modeless and hosted by the frame as a client, resized as frame resize.
It is created from dialog resource you have to supply, as any standalone dialog. All message handlers for dialog controls are the same.
CFormView Create member calls CreateDlg, passing dialog template loaded by the constructor.
CWnd CreateDialog, calls CreateDlgIndirect member that in turn calls CreateDialogIndirect API creating modeless dialog.
You can also embed modeless dialog inside another dialog and it is still a dialog.
A dialog application just shows a dialog (and whatever controls you put in the dialog, plus any other controls you pop up from it, etc.)
A FormView gives you a fairly normal application with a main menu and such -- but the view part can also hold controls.
You'd use a dialog if you just want a dialog, and a formview if you want (possibly multiple) views that can hold controls. Big difference is that making it a dialog changes the basic nature of the entire application, where a formview just changes one view -- you could (for example) also have other (non-form) views if you wanted.
someone_ smiley
To answer your question about dialog versus CFormView.
I rarely use dialog-based application; only in cases that require simple tasks without overhead of more complicated UI.
Most of programmers start with dialog based app and after getting into implementing some functionality, it usually turns that the application needs menu and a toolbar and status bar, data storing/handling object, command routing handling and so on.
I would suggest creating SDI application with non-resizable frame.
You will have a dialog look and all the functionality of the MFC application free. You do not have to use document support if you do not need one.
From the coders view point, FormView supports laying out of UI controls with dialog resource, in WYSIWYG way. So when making a view with a lots of controls FormView could be helpful.
Dialog is not a view. It is totally different. Dialogs are separate windows and normally presented in the modal event loop (or modelessly in special cases).

Tab Order with CTabCtrl and child CFormViews

In my application I have a CFormView with a CTabCtrl, I also have 4 CFormViews that are children of the main CFormView and that are shown/hidden when the user changes the selected tab.
However, I can't find a way to make the Tab Order to work properly. If the CTabCtrl has the focus, pressing the Tab key has no effect and if one of the child CFormView has the focus the Tab key will move the focus only around the controls inside the CFormView.
I tried changing the z-order of the visible child CFormView to be right after the CTabCtrl with SetWindowPos, changed the child CFormViews styles to WS_EX_CONTROLPARENT but nothing seems to work.
You've started out from the wrong implementation: you shouldn't make a CFormView with a CTabCtrl and then stuff more CFormViews into it. This isn't going to work right. Instead, you should work with CPropertySheet and CPropertyPage, where focus handling has already been taken care of. You will still be able to access the CTabCtrl owned by the CPropertySheet by calling GetTabControl(), but MFC will take care of the problems you've encountered.
Briefly: derive classes from CPropertySheet for each of the dialog windows you want to show (e.g., CConfigPage1, CConfigPage2). Create a Dialog resource in the Resource Editor for each of them, and do all of the other standard CDialog setup.
Next, derive a class from CPropertySheet (e.g., CProps), and (optionally) handle WM_SIZE and TCN_SELCHANGE.
Finally, derive a class from a CView descendent, like CScrollView (e.g., CViewMyAwesomeStuff). Then add member variables for the CPropertySheet and CPropertyPages, and handle WM_CREATE where you Add() each page to the property sheet and then Create(this,WS_CHILD|WS_VISIBLE) the property sheet.
Bonus: You can forward the CView::OnUpdate to each child CPropertyPage by calling GetPage() in a loop and calling a function on each of them, or you can send a message to each of them (use a user-defined message, like WM_APP+1). They can discover their parent's CDocument by calling GetParent()->GetParent()->GetDocument().

Parent notification in MFC Dialog

I have a first dialog with a simple button on it and while clicking the button, a second dialog is created using CDialog::Create(IDD,this). I would like the parent to be notified when the second dialog is destroyed but without adding any code to the second dialog i.e., without adding a m_pParent->Notify() line in OnDestroy method.
I have tried OnParentNotify, PreTranslateMessage, SubclassWindow in the parent dialog with no success. I have not used the WS_CHILD style for the second dialog. Any idea?
To complete: in fact, I have a ComboBox derived class (but the issue is the same with buttons) and I'm displaying a modeless Dialog instead of displaying the listbox. But I would like the control to be as generic as possible so that any modeless dialog could be used. That's why I do not want to add a specific notification in the second dialog. If I'm obliged, I will use this trick but I asked for a more generic solution. PreTranslateMessage only catches WM_PAINT, WM_NCMOUSELEAVE and WM_NCMOUSEMOVE.
Use a base class and have your parent refer to the modeless child by base class only. In the base PostNcDestroy have it post to the parent.
It doesn't make sense to have the parent do a bunch of filtering / spying on all messages. It does make sense to implement behavior in a base class that you want to have common to all the different future flavors you might have of the modeless child.
OnParentNotify() is not called since dialog2 is not a child of dialog1.
PreTranslateMessage() should help here (although I don't like this bullet). The trick is that a modeless dialog doesn't destroy itself when it's closed. If you want the dialog to die, it must call DestroyWindow() when it closes, such in an OnCancel() override.
Of course, the first thing that comes to mind is t wonder why you don't want to add custom notification in your modeless dialog code.
EDIT: Another method would consist in installing a message hook (for the current thread, Not the whole system!). This would help you catch all messages for all windows associated to the same thread as dialog1. See SetWindowsHookEx()
How about posting a main parent form event to the message queue?