I am creating an MFC SDI explorer style application (it has a splitter bar and the right-hand pane is the text-edit area, left-hand pane is the tree-view)
My right-hand pane is a CRichEditView.
I want to be able to detect when a user has edited the text so that a flag is set to show that a change has been made but has not been saved. I have tried several ways of doing this e.g. catching WM_KEYDOWN in PreTranslateMessage, but this catches everything and prevents the keypresses from editing the view. I have also tried adding ON_WM_KEYDOWN() to the message map in the MyView.cpp. Again, this seems to prevent the keystrokes from having any affect on the text in the view. I want to allow the user to edit the text in the view, but the application to know that this has been done.
Please help - I have looked for hours for ways to do this.
Many thanks
Adding ON_WM_KEYDOWN() to the message map is probably the correct approach. You must make sure that your implementation of the OnKeyDown() method calls the base class method so that the message gets passed on as appropriate.
Related
I need to extend an existing MFC app with a UI that will end up very cluttered unless I use a tab control. However, the nature of the UI is that there are some controls that are global, and only some that can be localised to a particular tab.
The standard use of tab controls (CPropertySheet + CPropertyPage) more or less expects there only to be CPropertyPage instances (tabs) visible on the CPropertySheet object, and nothing else. There is a Microsoft Example Project that shows a single additional window painted outside the area occupied by the tab control... but it's not immediately clear how it is created/drawn/handled, and it is only one single additional window that generates few events (I guess it is painted, so there must be a WM_PAINT event handler lurking somewhere).
Is it possible to lay out a bunch of controls with the MS Dialog Editor, including a tab control, and create the CPropertySheet using that template, hook up event handlers in a nice way, etc... or some equivalent way of getting the MFC framework to do as much of the creating, drawing and event handling as possible when it comes to a situation like this?
Yes it is possible to create dialog templates and use them in a CPropertyPage.
Each CPropertyPage behaves nearly like a dialog and handles all events for the controls on it.
Also there are features like OnApply that help you to manage the data exchange between the controls and your internal storage.
The central CPropertySheet only creates the dialog that get active. So OnInintDialog for a page is called the first time when the page gets active.
In the MFC since 2010 are more possibilities than a CPropertySheet. You can create tabbed views, that again may be CFormViews. I don't like CDialog based applications so I would prefer a tabbed view in a standard frame with toolbar and menus if appropriate for the application. So another method to unclutter your UI is to choose the MDI interface with tabbed documents... but multiple documents maybe isn't what you want.
Here is a sample of an SDI application with multiple tabbed views.
Also Coeproject shows some more samples here and with splitters and tabs here.
There are at least three solutions paths:
Try to squeeze the situation into the CPropertySheet + CPropertyPage framework which does not naturally allow for additional dialog controls on the CPropertySheet object, and so you will get no framework support this
Place a tab control on an ordinary dialog, and then use the TCN_SELCHANGE messages to fire code that manually hides & shows individual dialog controls subject to the tab control (again no framework support, but this time "within" the tab control instead of outside it)
Follow Mark Ransom's observation that if you can embed one kind of CWnd-based control on a CPropertySheet then you can probably embed any such object, including a CDialog-based object that has been developed in the MFC Dialog Editor
All of these approaches are going to encounter challenges, and it will depend on the specifics of the situation as to which is better. But first you should really consider whether there is a cleaner UI design which would lend itself to a simpler solution.
In my specific case, I saw no cleaner design alternatives, and found it easiest to take the second approach. It left me with some reasonably simple calls to ShowWindow() to show/hide the controls inside the tab control.
I'm turning mad with a little problem with Visual Studio 2008 and MFC. I'm working on a project actually and I'm trying to create an SDI Application. Right, now I want to add a dockable DialogBar. Well, the first time I added it with the resource view, I could create the bar without problems.
But... I want to add some controls like a couple of ListBox, buttons and so on. The program doesn't allows me to create member variables for these controls. The option appears in grey.
Searching a little, I found that it's mandatory to create a new class derived from CDialogBar and "enhance" it with the Message handler and so on. I've been reading some tutorials and it didn't work for me.
Can you please help me? I'm starting to get nervous, the use of dialogbars is mandatory in my design and I've never implemented them before.
Thank you very much, and sorry for my poor english.
You can add a control member variable by hand instead of using the wizard. All it takes is a call to DDX_Control in the dialog bar's DoDataExchange function.
But CDialogBar-derived classes do not handle control clicks. The CDialogBar class forwards all of those messages to the dialog bar's parent window. So be prepared to add the message handlers to the parent (usually CMainFrame).
For learning purposes you might try creating your dialog bar as a CDialog first, to see the proper code lines and message map entries supplied by the wizard. Then you can copy/move these details as appropriate into your actual code project.
The latest version of Microsoft Office uses property sheets that have the context help [?] button next to the close button:
When the context button is clicked it invokes the application's help rather than switching to 'context mode', by which I mean the arrow cursor with a question mark, i.e. there is no context help despite this being the context help button (or appears to be).
I'm trying to recreate this behaviour in an property sheet derived from the MFC CPropertySheet. So far I've had no luck. Ideally I'd like a click on this button to act in the same way as pressing F1, e.g. call directly on to the OnHelpInfo function.
Can anyone tell me how this might be achieved?
As per my comment, adding ON_WM_SYSCOMMAND to the message map and then processing SC_CONTEXTHELP in OnSysCommand did the trick.
I'm migrating an application from a homegrown UI to Qt. One of the most important controls is the property panel, which takes an object that implements my reflection API's interface and spits out a dialog box containing editors for all the properties.
I've written an implementation of QAbstractItemModel for my property system and I've written a few handlers for various types inside of a QTableView. I've also written a QItemDelegate to create editors for the properties.
The trouble is that I'd like the editors to hang around, rather than be strictly popups. This is so that they can handle the rendering of the property, require less clicks to operate and also not disappear as soon as something else gets the focus, such as my colour button - the editor (which has the slots listening for colour changes) disappears as soon as the colour picker dialog appears, which means that nothing is then listening for changes.
I can't find any options for making the editors persist. Am I barking up the wrong tree here or is there a more appropriate way of doing this? I've tried to do things the 'Qt' way but I'm already hitting brick walls.
Thanks,
There is the QAbstractItemView::openPersistentEditor() method.
This should be obvious, but I can't find anywhere that spells it out.
I want to derive a MyCEdit from CEdit so I can override the OnChar handler and do useful things with keyboard input to an edit box. Each edit box I have fills the client area on a MyCPropertyPage (derived from CPropertyPage), and several such pages make up a tab control used to display diagnostics. I leave the edit boxes enabled and not read only (for aesthetics, not function).
In the resource editor (or elsewhere) how to I tell Visual Studio that I want a certain edit box to be a MyCEdit rather than a CEdit? Can I hope to just override the OnChar in MyCEdit to intercept characters... or do I have to override OnKeyDown as well - I have read a suggestion to this effect, but found no MS source article spelling out why.
So far, the only thing I can easily override is MCPropertyPage::OnChar... but that seems to get bypassed, and characters just go straight to the edit box child.
HI if i understand you need you can add simple edit to your page, then add control variable and write MyCEdit in class name field. And dont forget to set parent notify option in resource editor on your MCPropertyPage.