Creating a DialogBar with MFC with my own controls - c++

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.

Related

Changing button name MFC Visual Studio

I just started the GUI development, i had started on C++Builder but i switched to Visual Studio for differents reasons. But in Visual Studio, i've got a big problem :
In the GUI development interface (rc file) i can create buttons and place it, but i can't change there names. The name for all of MFC components i placed is initialize to a default name which i can't call and i can't change the property by the properties interface, i can change the Text, for change the Label of the Button, but not the name...
It's very incomfortable because by that i can't call my buttons for do anything, i have the same problem for Listboxs, so i can't modify my list because i can't call there
I just want to modify access my component by my c++ code for modifying this component
enter image description here
Thank for your help !
The MFC way of doing event handling is a bit more elaborate.
After the control is created on the form in the designer, an ID is generated ("IDC_BUTTON1" in the attached screenshot).
This is the ID that will be used for accessing this UI control from the code.
All this can be done via the designer also as shown in this article.
Basically, in the background this generated ID is put in a 'message map'
(more about message maps here).
In short 'message map' is used to specify what action needs to be performed when a certain type of action is done on the UI control by the user.
For, example if the button click is to be handled then in code:
the message map would look like:
BEGIN_MESSAGE_MAP(CSurface3DView, CView)
ON_BN_CLICKED(IDC_BUTTON1, CallMyFunction)
END_MESSAGE_MAP()
'ON_BN_CLICKED' is a predefined event macro.
The 'CallMyFunction()' function has to be declared with 'afx_msg' in the class. Besides please, have a look at data exchange mechanism as well. This know-how about data exchange will come in handy going forward.

Rewrite CListBox as a CCheckListBox

I am working on a Windows application using MFC and Visual Studio C++ 17.
I have multiple tabs in the application, one of which is currently implemented using CListBox and needs to be reimplemented using CCheckListBox.
CCheckListBox is a child class of CListBox.
I have a vector of unique CString's I want to display in the box.
To start simple, I tried making the tab with CListBox and by using CListBox::AddString(), this worked exactly as I wanted it to. It sorted the strings alphabetically, and automatically added a scroll bar on the side when the vector had too many CString's to display all at once in the list.
However, when swapping the CListBox variable to a CCheckListBox variable, I have come across the error when I press run along the lines of:
Debug Assertion Failed! ..... \mfc\winctrl3.cpp Line: 588
I found this GitHub link that has the winctrl3.cpp file and on line 588, there is a function called OnLButtonDblClk which is somewhat explained here.
The trouble is I am unsure of how to swap a variable from a parent class to a child class. Is it so different for Windows classes? In the courses and programs I have taken and written in the past, switching from a parent to child variable was straightforward but this is quite the opposite !
Any help is appreciated, thank you in advance ! :D
There is no assertion in line 588 of the source file in your link. That github upload dates back to 2014. Why not search the winctrl3.cpp source file in your own Visual Studio installation instead? In my own installation, it is in function PreSubclassWindow() and there is indeed an assertion there:
// CCheckListBoxes must be owner drawn
ASSERT(GetStyle() & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE));
That is the CCheckListBox must be owner-drawn. Find the CCheckListBox constructor code above, you will notice that it calls the CListBox (parent-class) constructor, applying either of the two owner-drawn styles. Instead, the CListBox constructor calls CWnd::Create() with the "LISTBOX" Windows Class-Name as a parameter. That is, it seems to be a MFC-implemented control, overriding the CListBox class, with an owner-drawn style. There is no mention of a native "Check-ListBox" class or style in the Win32 documentation either. Also the CCheckListBox documentation (in the link you posted) clearly states: CCheckListBox is only for owner-drawn controls because the list contains more than text strings.
Therefore:
If you are creating the control using a resource script, add an owner-drawn style (eg LBS_OWNERDRAWFIXED) to the control (or set the Owner-Drawn property in the property editor).
If you are creating the control programmatically make sure you are calling the CCheckListBox constructor, not the CListBox one.
Not sure what you mean about the scroll-bar (and why you mention it), doesn't the list-box display a scroll-bar automatically (WS_VSCROLL style - or property), do you have to do something on your own?
EDIT:
Forgot to mention, if you are creating the control using a resource script use the Class Wizard to add a member variable (of "Control" type, not "Value") to the dialog class. The new variable must be of type CCheckListBox (MFC class). This will subclass the control. If the old project already had a CListBox member variable change it to CCheckListBox.

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 to hide/collapse main menu in a win32/mfc application

I always been interested on how we can accomplish this (hide/show the main menu using the alt key), and now some applications do this very often. One that really please me is the visual studio 2010 with this plugin:
http://visualstudiogallery.msdn.microsoft.com/bdbcffca-32a6-4034-8e89-c31b86ad4813?SRC=VSIDE
(firefox also do this, but i think that is in a different way)
Can anyone explain me how this can be achieved or if you known of any sample project that demonstrate this please tell me.
(what i can see in some replies here in stack is that we have to destroy the menu when is to hide and create it when is to show?! but this seems a bit bad solution...)
Thanks
The SetMenu function lets you add/remove the menu from the window. It does not destroy the menu.
Note that most applications which have the dynamic menu hide/show behavior are not really showing a menu. They're showing a custom control that looks like a menu.
You might also take a look at MFC support for auto hiding menus. I used this technique and it worked really well.
in CMainFrame::OnCreate I did
m_wndMenuBar.ShowWindow(SW_HIDE);
which actually works fine in our project
I stumbled across a related pit fall that will show a hidden main frame without your consent:
Whenever the focus for a child window in an MDI application changes (e.g. due to right clicking in it), the function CMDIChildWnd::OnMDIActivate will be called, which in turn shows the main menu (even if it was removed or destroyed previously) of the MDI application.
This works basically by adding the saved main manu from the underlying's CMDIChildWnd m_hMenuShared variable.
A quick&dirty hack to prevent this, is setting m_hMenuShared to NULL (it's protected in CMDIChildWnd so this needs a custom derived child class of CMDIChildWnd) for all child frames.

How to create and add a custom made component to a Dialog based app (MFC)?

I want to make a custom made component (a line chart), that would be used in other applications.
I don't know 2 things:
Where should I use (within component class!) the methods for drawing, like FillRect
or PolyLine? In OnPaint handler that I should define and map it in MESSAGE MAP? Will
it (OnPaint handler) be called from OnPaint handler of the dialog of the application
or where from?
How to connect the component, once it is made, to the test application, which will
for example be dialog based? Where should I instantiate that component? From an
OnCreate method of the MyAppDialog.cpp?
I started coding in MFC few days ago and I'm so confused about it.
Thanks in advance,
Cheers.
Painting the control is handled exactly like it would be if it wasn't a control. Given that you're using MFC, that (at least normally) means you do the drawing in the View class' OnDraw (MFC normally handles OnPaint internally, so you rarely touch it).
Inserting the resulting ActiveX control in the host application will be done like inserting any other ActiveX control. Assuming you're doing your development in Visual Studio, you'll normally do that by opening the dialog, right clicking inside the dialog box, and clicking "Insert ActiveX Control..." in the menu that pops up. Pick your control from the list, and it'll generate a wrapper class for the control and code to create an object of that class as needed. From the viewpoint of the dialog code, it's just there, and you can use it about like any other control.
For create new component in MFC, you must create a class from the window class (CWND),
after that you can have your MessageMap for the component and your methods and also can override CWND::OnDraw method to draw the thing you want.
Before that I suggest you to take a look to device context
http://msdn.microsoft.com/en-us/library/azz5wt61(VS.80).aspx
Good Luck friend.