I have a class derived from CPropertySheet in my MDI application. It is a model-less property sheet shown when a button is pressed in one of the views of application. I need to make the sheet as a child view of the application
How to do it?
You just need to change the parent of property sheet using SetParent, or when you instantiate the CPropertySheet-derived class object, you can pass the parent CWnd* reference to constructor of CPropertySheet.
Is this not working?
Related
I'm trying to display a ToolTip for a CStatic derived control in my dialog.
What I've already done:
Added a CMFCToolTipCtrl item to my CDialogEx member.
In the init dialog member I've specified CMFCToolTipInfo structure and passed it as argument in CMFCToolTipCtrl item constructor.
Call the EnableToolTips(); member for my CStaticExts and for my CDialogEx.
Overrided the PreTranslateMessage of my CDialogEx adding the "RelayEvent".
Set "Notify: TRUE" in the resource editor.
Doing so I managed to display the tooltip in a partially customized way (baloon and background color) but now I would like to enlarge the font, make it bold and, eventually, display an icon, similarly to the tool tips I can see on my toolbar.
I already tried calling "SetFont" and "SetIcon" methods for the CMFCToolTipCtrl item but it didn't work.
Is that possible?
The normal Font that is used in CMFCToolTipCtrl ist retrieved from a global data store inside the MFC (see GetGlobalData()->fontTooltip). This data structure AFX_GLOBAL_DATA is filled when the MFC is started. SetFont has no effect here.
If you want to change the behaviour you have to create your own CMFCToolTipCtrl class and overwrite OnDrawLabel. You have the source of the MFC so it is easy to provide your own implementation.
I want to add a CDialog control inside CDockablePane. When I use CDialog.DoModal() to display the dialog window, it makes the MFC application unresponsive and waiting for the CDialog result.
How can I make the application display the dialog and continue running without waiting for the CDialog result?
You cannot use DoModal to display the dialog. That displays a modal dialog, which prevents interaction with any other windows in your application until the dialog has been dismissed. Just like a message box does.
To display a non-modal dialog, you call the Create member function. Use the instance of your CDockablePane as the dialog's parent. You will also need to ensure that the dialog itself is a child window, without a border.
It might be easier to use a class derived from CFormView or CPaneDialog.
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().
Anyone knows how to add a button to the titlebar of a CDockablePane ? I tried the usual way with CDialog but it does not work for CDockablePane...
Thanks
You need to create an instance of CMFCCaptionButton, then use the protected but undocumented m_arrButtons member of the CDockablePane class:
yourDockablePane.m_arrButtons.Add(new CMFCCaptionButton(YOURCOMMANDID));
I have a custom MFC control, subclassing CWnd. Other than providing OnPaint and PreSubclassWindow implementations, it overrides no default functionality and does nothing weird in construction except registering a window class in the constructor.
The control is added to the dialog using the dialog editor to add a custom control.
The dialog worked when it was a simple modal dialog deriving from CDialog, but we have code which calls CWnd::CreateDlgIndirect to instance dialogs and this fails with the custom control... but works if the custom control is removed from the resource template.
Found it!
I had the custom control register its window class in its own constructor. I had member in the dialog of this custom control type, so the ctor was being called when the dialog was created, as intended.
But, it turns out the base class I changed the dialog to derive from, instead of CDialog, was calling CreateDlgIndirect in its own ctor, before my new class' own initialisation was reached - so it was trying to create custom control before the window class was registered.
My (slightly messy solution) is to ensure the window class registration happens at application startup in the InitInstance method, before any dialog stuff happens.