Prevent views stealing focus/setting focus to a view - c++

I have an MFC sdi app that uses a splitter window to contain a tree control alongside the main view showing the data.
When the user selects something in the tree, that view keeps focus until the user deliberately clicks in the main data window. This means that any toolbar buttons associated with the main view are disabled.
Is there any way to programmatically switch focus back to the main view after the user has clicked the tree control? Or am I doing something fundamentally wrong using a CSplitterWnd and 2 views?

You don't want to bring the focus back to the other view as soon as someone clicks the tree: It would make your app unusable. e.g. It would prevent users from navigating through the tree using the keyboard since the tree would never keep the focus long enough.
I you really want the toolbar to keep reflecting the state of your 2nd view (I'm not sure it's a good idea), you have a few options. Make your pick. 2 come to mind:
Your tree view should NOT be a CView. Use a simple CTreeCtrl. Not very nice because it kind of break the doc/view paradigm (e.g. no more tree's OnUpdate() called whenever an UpdateAllViews() is called).
Prevent the tree from becoming the active view. To do so:
2.a. When you view gets the focus (OnSetFocus()):
STATIC_DOWNCAST(CFrameWnd, AfxGetMainWnd())->SetActiveView(pTheOtherView);
2.b. Derive a CMySplitterWnd class from CSplitterWnd, then override CMySplitterWnd::SetActivePane() to prevent it from setting the treeview as the active view.
In all cases, welcome to the wonderful world of MFC internals where diving into the source code is the mandatory daily sport ;-)

Related

MFC: How to receive ON_UPDATE_COMMAND_UI for a CTabView itself?

I have an SDI Document/View MFC app the wizard created with several different windows (workspace, properties, view, output). My main view CMyView is derived from a CTabView.
I want to offer a "Close Tab" option via the toolbar, menus and context menus, but ON_UPDATE_COMMAND_UI from within CMyView is not called, my guess is it's probably going to whatever view is in a tab but there are several different types of views that can be opened in a tab so I want CMyView to handle it in one place.
To me, having it handled in the CTabView makes the most sense design wise, but maybe I'll have to do it in the mainframe and then call a method of the view to get the result. But I thought I'd check here with people with more experience using MFC. What is the best way to handle it?

How insert multiple FormView in View of an SDI application

I searched on the forum and I don't find a solution for my issue. So I hope you can help me :)
I work on a personal project for SFC designing (Sequential functional chart) and I'm working with visual studio in SDI(I'm using MFC library). If you see the "design" of an SFC you can see the different elements needed to compose this. So you can find Step, Transition, and more. If I take a step for explaining my issue, after double click on the step a popup dialog is opened with the elements to define this step (actions on this step, and more). The issue is here, I can't see two or more step elements at the same time. I want to reuse the existing concept on other software, see this.
Step close
Step open
Dialog to add
My question is, how I can implement a dialog with my graphic element in mainframe (In this case, a step)? I don't know how I can insert a dialog with my element, I think I need to use CFormView, but I don't know.
This dialog needs to be resizable and reduce directly by the step graphic.
any idea?
Thank you in advance! Sorry for my English ..
Sorry, I think my request is not clear .. (Thank you for your answer)
The context, it's an SDI application with the Document/View architecture. Actually the view is derived from CScrollView.
So, in the document class, you have the different lists of components for make SFC (Steps, transitions and symbols ..). I'm working today on Step element.
The user inserts a new step, the step is draw on the view like this :
enter image description here
And now the user want change the events on this Step, for this after double click on the step the events editor is opened at right of step draw, like this :
enter image description here
For this, I've created a new dialog resource and create the class by wizard in CForwView derived class. In step attribute, you can find one instance of this derived class (The derived class of dialog).
But this doesn't work correctly, I think my method is bad. At the first try, I have sent the pointer of the current document to the "CFormView::Create" function for having the "Save" button active with the focus on the FormView. But after destroying the step, the instance of FormView is destroyed and the document with the instance of formview ...
No problem, you can use "Create" within CCreateContext a null pointer. But with the document or without I have a lot of problems (graphic design not correct in FormView, regularly (not systematic I have assert fail on Proc exchange (for differents reason)). But the "concept" is good, the editor follows the draw if I scroll, I can open or close the editor at any time and on any elements.
For the old capture, it's my SFC designer "model". My application is a complement to this application, so I want a similar design. I don't know how work my model application ..
On my application all is draw by MFC GDI, I don't use ActiveX or other tools.
So what is the correct way to implement one instance of editor by instance of step ?
For the implementation on this FormView I have :
- Make new dialog in ressource
- Create a derived class of CFormView with the created dialog
- Add one instance in attributes of Step element
- "OnDbClickOnStep" -> Call "Create" with the good position / size, pointer of mainview (in my case the CSrollView derived class)
- Done, FormView inserted in a mainview, I can edit my step events.
? Not done, I lost save button and other function linked to the document with the focus on a control in FormView. The app want a document with this view, how to override this ?
? Error in Proc exchange, for different reason...
You have an idea ?
You normally don't draw anything in the "main frame" (or the "MDI clild frames", in the case of a MDI application), this is done by the library, and imo sufficiently so. You display your data in a CView-derived class.
CView is the base class of all other MFC view classes. It's a simple graphical class - you need to paint it yourself in the OnDraw() member.
CScrollView is a descendant of CView, adding scrolling functionality (scroll-bars are automatically displayed if the scrollable area is bigger than the visible window area).
CFormView is a descendant of CScrollView, displaying a dialog resource-script, containing "controls" (edit-boxes, check-boxes, images, ActiveX etc).
As in your case the "controls" won't be initially known (except maybe for some few special cases) and rather programatically created, the resource script will most likely be empty, so using either CFormView or CScrollView will basically be the same. I would suggest starting with CFormView, and "downgrade" it to CScrollView if CFormView is not necessary or causes you troubles.
What are those "Step" items shown in the pics? ActiveX controls, child dialogs maybe? These work best as child controls on a dialog window. Are they already implemented, or they are just pics of some other software? Btw ActiveX is a way to define controls that can be used in other projects too, without having to include them in the project source.

How can you be notified when the user switches between views?

In an MDI application, when the user switches between views something has to be updated. What's the best message to handle for realizing when this happens?
In my application a document has only one view, but logically I want to get notified when switch is between documents.
You can catch WM_SETFOCUS in CChildFrame (ChildFrm.h). When a user clicks a view window, or sets focus to a view in another manner, this member function can be a bridge to whatever you need to set in the application.

Aid with design issue?

In my game, I have a panelA that has checkboxes to toggle panels in panelA's parent. It also has a Leave button which needs to make a call to the scene manager that only PanelA's parent is aware of.
I've thought of:
Making a listener just for this
Have the parent make the PanelA and make its children so it has
access to them and can receive action events from them
Neither of these feel that clean. Would there be a better way?
My game uses a gui system that I made. Sending events up to the parent wouldn't work because the parent does not know which gui components it's looking to handle.
Thanks
It's a bit hard to know without knowing the design of your system, but basically you don't want to change checkboxes in the panel, but you want to change the state and have those checkboxes reflect the state.
Say you want to check a box for Vertical Blanking in your main-panel. Do do not want to do this
parent->waitForVerticalBlankCheck.Checked=true
instead you want this
renderingConfiguration->isVerticalBlankEnabled=true;
and in your "main panel"
if(renderingConfiguration->isVerticalBlankEnabled)
waitForVerticalBlankCheck.Checked=true;
Uhm.. very pseudocody, but hopefully you get the idea :)

How to make Qt delegate editors 'sticky'

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.