Question

I'm doing an application using MFC. I just made a class that is derived from CEdit so I could intercept OnChar() and do data validation. How do I substitute the edit control in my application with the derived one I made?

Was it helpful?

Solution 2

I found the solution. The reason why I was having such a hard time is because I didn't use the Class Wizard to create the new class, making things very complicated. If you simply use the Class Wizard, you have the option to add control variables to your derived classes like if they were regular classes, as long as the base class is the right class for your element. This is not necessary though. All you have to do is create a pointer of the type of your derived class and cast the item you are trying to get, like you would normally do with a non-derived class.

Example of accessing an Edit Control using a class derived from CEdit

CMyCustomEdit * editPtr = (CMyCustomEdit*)GetDlgItem(IDC_EDIT1);

As mentioned below by another member (Thanks for that), using GetDlgItem is not a good idea. I actually, in my code, ended up Sub-Classing it so I could use my new class with my Edit Controls that already existed. As mentioned before, I did not understand that an Edit Control was not necessarily attached to CEdit, so the example above should give a clear idea that your IDC_EDIT can be used as CMyCustomEdit as well as a CWnd and so on; it will behave naturally as long as you reference it with the right classes.

Now for the Sub-Classing. If you actually want to make you Edit Control to always call your derived class before your base class, you will have to make it a Sub Class. Don't think of it as an Object Oriented concept, this is only so the messages (Like WN_CHAR) will go through your derived class first and then call the base class.

Example of Sub-Classing CMyCustomEdit on an Edit Control:

First you need to include the .h file of your new class in the .cpp and .h of your dialog box. Those are the ones that usually has the same name as your project. Here it will be MyMainDialog.

#include "CMyCustomEdit.h"

In the derived dialog class include a variable of the type of your new derived class:

class MyMainDialog : public CDialogEx
{
protected:
  CMyCustomEdit m_cmCEdit;
}

Then in the OnInitDialog() of your derived dialog class (MyMainDialog) Sub-Class your edit control. For safety, add this after the regular code in the function and before the return (As usual):

m_cmCEdit.SubclassDlgItem(IDC_EDIT1, this);

After this is done, when you do anything in your Edit Control with the ID IDC_EDIT1, the messages will go trough CMyCustomEdit before going to CEdit. This usually is necessary when you need to overwrite messages from the base classes.

Hope it helps anyone with a similar question.

OTHER TIPS

Do NOT use GetDlgItem!!

GetDlgItem() returns a CWnd-pointer and nothing else. This means you have a sliced CMyCustomEdit pointer. Sure, it works in all cases where your method sends a message to the underlying HWND. But that's just pure luck! You can read more about the problem here.

The right solution is to subclass your edit control using DDX_Control.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top