I am using Visual C++ 2010 & MFC to write a small dialog-based application.
I click a control (such as a "static text" control) in the dialog,and the corresponding class creates a function and variable automatically.
Now I find the event handler is useless. How can I delete the event handler automatically?
Well, you can right click it in one of the propert windows and choose delete event handler. But what it will do is comment out the code.
It can also be done from the ClassWizard. Quote:
With ClassView and WizardBar, deleting a message-handling function is the same as deleting any other member function. ClassView and WizardBar:
delete the function declaration
removes any associated map entry from the MSG, MESSAGE or DISPATCH map
and comment out the function body, or definition, so that you can easily delete it if you wish.
This includes variables. There is more information about other ways here
Class Wizard
Right-click the dialog resource and choose Class Wizard
Select the event handler you want to delete and then choose Delete Handler
Class View
Select the class first so that it has focus:
Click the lightening bolt on the Properties pane and then expand the control to see the events:
Click on the drop arrow and select Delete:
Hopefully this are enough examples to show you how you can delete functions. Please let me know if you want me to provide you with more information.
Related
I've run into this a few times, don't recall what I did to fix it last time (probably started all over). Here's what I did:
I copied an existing CMFCPropertySheet dialog box and pasted as new one then edited the dialog ID to IDD_MINE, deleted all the controls as a starting place. Next I added the various controls for the this dialog.
After setting up the dialog the way I wanted it, I went to "Add Class" and added a class for the dialog (choosing the base class CMFCPropertySheet). When it was done, it was incorrect (VS2017 has never done the property sheet correct for me). Referencing another property sheet that I have working, I added the missing IDD_MINE to the constructor and the AFX_DESIGN_TIME { enum IDD=IDD_MINE }.
Once the class was setup I was ready to start adding variables. However I noticed some of the controls that were a checkbox should have been a radio button so I deleted them, created radio buttons (push like) then choose the existing IDC_ names (old checkbox names) from the dropdown list for the control id. Next I try to add the first radio button as a value variable but that fails with the following error:
Object reference not set to an instance of an object.
So I go to the Class Wizard for the Dialog and look in "Member Variables" tab. It lists all the controls IDs except the radio buttons (and IDC_STATIC items that are -1) . I tried renaming the radio buttons by changing the IDC_ names but that didn't change anything (exit program, etc.., still same).
So does someone know how I get visual stdio resource editor / class wizard back in sync with the controls that really exist so I can add them using the wizard?
TIA!!
EDIT:
Even those variables which exist in the "Member Variables" tab can't be used with the wizard. Same Object Reference not set to instance of an object message.
So being desperate, I manually added the function:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
Everything works now!!
Which the wizard would take care of all this on its own.
I have a CDialogEx Class called Properties in which I handle the ON_COMMAND message. Now, ON_COMMAND should get called when I click the menu item ID_EDIT_PROPERTIES (as a submenu from main menu). The event handler wizard wrote that code for me, but when I start the Application the menu item remains grayed out. I've tried to manually activate it by calling EnableMenuItem when ON_UPDATE_COMMAND_UI happens, but to no avail.
Any help would be greatly appreciated.
You just need to understand how menu items enabling/disabling is handled:
If there is neither ON_COMMAND nor ON_UPDATE_COMMAND_UI handler the item is disabled.
If there exists no ON_UPDATE_COMMAND_UI handler but there is an ON_COMMAND one in the currently active document or view (or even the "mainframe"), the item is enabled.
If there exists a ON_UPDATE_COMMAND_UI handler, en-/disabling the item is determined by the handler (pCmdUI->Enable(bEnableState)).
Also keep in mind that:
You may not call EnableMenuItem() yourself, instead call pCmdUI->Enable(bEnableState) in an ON_UPDATE_COMMAND_UI handler. This affects not only the menu item, but any other "command"-type item (with the same ID), eg main menu, context menu, toolbar or rebar button.
Where to put the handler, is a matter of application design and depends on the data you are processing or representing. It can be put in the mainframe class (if it depends on some "global" data or setting), in the document class (if it depends on or changes some data or setting in the document - possibly affecting all views), or in the view class(-es) (depending on or affecting the current view only).
In your case, if I understand correctly, the item is disabled because the handler is in the CDialogEx-derived class, but no instance of this class has been created yet, ie there exists no ON_COMMAND handler for your ID_EDIT_PROPERTIES command.
Per m_bAutoMenuEnable, When this data member is enabled (which is the default), menu items that do not have ON_UPDATE_COMMAND_UI or ON_COMMAND handlers will be automatically disabled when the user pulls down a menu.
I admit that I don't know ii it is different for CDialogEx, But for CDialog I found that the UPDATE_COMMAND_UI didn't ever work unless I handled the WM_KICKIDLE event.
In your OnKickIdle event handler make a call to:
CWnd::UpdateDialogControls
There is a short tutorial on it here.
Forgive me if CDialogEx supercedes this information and I will remove the answer.
I have a MFC app written in Visual Studio 6 which I am adding some new functionality to. What I want to be able to do is display a context menu when the user right clicks on the header column on the list control within a property page. The CListCtrl class was added view the Class Wizard.
Via the ClassWizard for the property page, I have added a handler for the right click on the listctrl. This does get called and I added the following code to work out if the rclick was over the header section and if so which header item. Like this
POINT Point;
GetCursorPos (&Point);
ScreenToClient(&Point);
HDHITTESTINFO HitTest;
//Offset of right scrolling
HitTest.pt.x = Point.x+ m_ctrlRecordList.GetScrollPos(SB_HORZ); //Offset of right scrolling
HitTest.pt.y = Point.y;
//Send the Hit Test Message
m_ctrlRecordList.GetHeaderCtrl()->SendMessage(HDM_HITTEST,0,(LPARAM)&HitTest);
// Check hit test result.
*pResult = 0;
However, the hit test always returns -1.
I tried just on left click instead by handling the HDN_ItemClick message of the header control in the property page. This is all done in the ClassWizard so I expected to be able to handle this notification here. However, from what I have researched so far, there may be a bug in MFC where the ClassWizard puts this code into your code for you but this notification will never get as far as the parent of your list control. Is this the case?
What would be the best way to do this? I would prefer on right click but left click would do if necessary.
You cannot do it trying to handle message from a list’s header in a dialog, nor can you do it in the CListCtrl derived class.
MFC is using message reflection for certain controls and only for certain messages/notification codes.
Most likely you are passing coordinates of the mouse click on the list control, hence hit test fails.
Try this:
Add class derived from CHeaderCtrl. Declare member variable of the derived class in a dialog.
I assume you have already subclassed (have variable inserted by the wizard) list control.
In OnInitDialog write the following:
// m_List is the dialog’s member of the subclassed list control,
// m_header is a member variable of your new header class:
// insert this code after list control is already
// initialized and all columns are added.
CHeaderCtrl* pHeaeder = m_List.GetHeaderCtrl();
m_Header.SubclassWindow(pHeaeder->m_hWnd);
Insert handler for WM_CONTEXTMENU or WM_LBUTTONUP in the derived class and popup menu. You will receive CPoint type for click position.
I have managed to sort this out and thought I would add the answer in case anyone else stumbles upon this with the same problem. The code I posted originally is fine but it needs to go in the OnNotify handler of a class derived from CListCtrl. The ClassWizard allows you to add a reflect handler to the parent of the list control but the message never gets that far.
I've created a simple Dialog box with a few controls (edit, text, etc) and saved
it to the resource folder in GME/GME.rc/Dialog
I added an auto-gen'd event handler which created a new class (Class.cpp
for the purposes of this example) Note: the Class::Class(CWnd *pParent) :
CDialogEx(Class::IDD, pParent) constructor is empty, I'm not sure if that's
relevant but I don't think it is..
There's a MESSAGE_MAP COMMAND(menu_item_id, &class::member_function())
invocation within the Class.cpp was auto-generated. It's wrapped in the
standard BEGIN_MESSAGE_MAP macro stuff.
However: when the menu item is clicked, the item remains gray. The
properties for "enabled=true" and "gray=false" are both properly
configured. So, I assume this is error is due to the message handler isnt
registered.
Any help would be appreciated.
Without code, it's pretty darn hard to help. Are you sure you put the message handler for the menu id in either a CView, CFrame, CDocument, or CWinApp derived class? If you put the menu handler in your dialog class, it's not going to do you much good.
Dialogs do not contain the code to run through the list of ON_UPDATE_COMMAND_UI handlers that MFC uses to enable menu items. Ordinarily this is handled by CFrameWnd for example. Try calling UpdateDialogControls in your OnInitDialog function.
I see that your code is also missing the ON_UPDATE_COMMAND_UI macro for the menu item, even though the handler it would reference was created for you.
You add menu item handlers to the window that has the menu, which is usually the CMainFrame. Copy the message map and handler to the CMainFrame and see if that helps. I'm not sure what you're trying to do here - I assume you want to display 'Class' (maybe better to edit your post to call this 'ExampleDialog' or something...) when the menu item is clicked, right? Or did you somehow add a menu to your CDialogEx-derived class? If the last, I guess this is what Mark is referring to - 'how are you displaying the menu'? How are you manually adding a menu to your dialog?
I'm fairly new to VC++ and MFC, so bear with me. I have created a new dialog, and I want to figure out how to display it when the user clicks a button.
I have not create a class or header file for the dialog -- I tried using the class wizard, but it pretty much sucked and didn't work. That, or I was doing something wrong. Either one is equally as likely if you ask me.
So what steps do I need to take when creating the source/header files and getting the dialog to launch/display? It is a modal dialog.
CLARIFICATION: I understand that I need to create an instance of the dialog class, then just call DoModal() on it, but I'm not sure how to create the class file (with and/or without the wizard).
Right click the project and select
Add | Resource...
Select Dialog under Resource
type and click New.
Select Project | Add Class...
Enter CMyDialog for the Class
name, CDialog for the Base class
and Click Finish.
Read more: How to Make MFC Dialog Boxes
Seems to me you can make the button click just create a new instance of the dialog object and activate it. You'll probably have to keep a reference to the dialog so it doesn't get killed when the button action fxn returns it doesn't get garbage collected..