-
September 10th, 2013, 02:26 AM
#1
Subclassing CRichEditCtrl VS2008 Windows 7
QUESTION: What is the class name of CRichEditCtrl? More generally, how can I figure this out myself eg with the debugger or documentation?
--------------
I've successfully made 3-4 fairly complicated controls from scratch, starting by subclassing CButton as shown in some of the associated example projects.
My current project needs a CRichEditCtrl, with just a slight bit of extra functionality.
I've always used a method called RegisterControlClass(), taken from the example projects, that filled in a WNDCLASS structure by getting another class's WNDCLASS then just modifying it a bit. To get the initial values I used the class name "button" as that was in the example program. It worked fine.
Now, to get the name of SCRichEdit, I'm stumped.
I started by examining a real CRichEditCtrl:
CRichEditCtrl* prich = (CRichEditCtrl*) GetDlgItem( IDC_PATCH );
I've tried using the debugger and looking at prich->GetRuntimeClass()->m_lpszClassName, but it equals "CWnd". Obviously wrong.
I found some docs on the 'net referring to MSFTEDIT_CLASS, which has a value of "RICHEDIT50W", that doesn't seem to work either.
I found some fields deep inside the prich object in the debugger leading me to think it might be simply "CRichEditCtrl" but alas not that either.
Here's the function with the class name "button" that works albeit isn't what I want.
Code:
BOOL SCRichEdit::RegisterControlClass() {
// STEP 1: check to see if a class is already registered with this name.
// If it is, and the WndProcHook is ours, then WE'VE already registered
// and its OK. Otherwise someone else is using the same class name. Not OK.
WNDCLASS wclsSCRichEdit;
static const TCHAR szClass[] = _T( "SCRichEdit" );
if ( ::GetClassInfo( AfxGetInstanceHandle(), szClass, &wclsSCRichEdit ) )
return wclsSCRichEdit.lpfnWndProc == (WNDPROC) SCRichEdit::WndProcHook;
// STEP 2: No "SCRichEdit" is registered, so register ourselves. To do this,
// we call RegisterClass() after filling out a WNDCLASS structure. Rather
// than fill it all out ourselves, we'll just duplicate the one used by
// the built-in "button" class and change a couple fields.
VERIFY( ::GetClassInfo( NULL, _T( "button" ), &wclsSCRichEdit ) );
wclsSCRichEdit.lpfnWndProc = SCRichEdit::WndProcHook;
wclsSCRichEdit.hInstance = AfxGetInstanceHandle();
wclsSCRichEdit.lpszClassName = szClass;
return RegisterClass( &wclsSCRichEdit ) != 0;
}
Last edited by Swiss Frank; September 10th, 2013 at 02:27 AM.
Reason: added code tags
-
September 10th, 2013, 08:28 AM
#2
Re: Subclassing CRichEditCtrl VS2008 Windows 7
1. Use Spy++ to see the class name of any window.
2. Could you post a link to "some docs on the 'net referring to MSFTEDIT_CLASS..."?
Victor Nijegorodov
-
September 10th, 2013, 09:31 AM
#3
Re: Subclassing CRichEditCtrl VS2008 Windows 7
Thanks Victor.
I've never used Spy++. Looks powerful. It reports the rich texts in my app are called RichEdit20A, and indeed GetClassInfo() is able to find that.
A follow-on question: I previously was creating the dialog with the VS2008 resource editor, and took Rich Edit 2.0 Control off the Toolbox menu. That gave many options in the Properties dialog, many of which are critical to proper running. Thanks to you, I can now register my subclass, but I now use Custom Control off the Toolbox menu, so the properties options no longer appear. I suppose I can set those all programmatically, but do you suggest any other options?
MSFTEDIT_CLASS: I saw it mentioned on http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx among a few other places. Not much detail made sense to me, but when I saw it was defined as a string that looked like a class name I thought it was worth trying.
-
September 10th, 2013, 09:43 AM
#4
Re: Subclassing CRichEditCtrl VS2008 Windows 7
Victor Nijegorodov
-
September 11th, 2013, 01:49 AM
#5
Re: Subclassing CRichEditCtrl VS2008 Windows 7
Originally Posted by Swiss Frank
QUESTION: What is the class name of CRichEditCtrl?
. . .
CRichEditCtrl* prich = (CRichEditCtrl*) GetDlgItem( IDC_PATCH );
I've tried using the debugger and looking at prich->GetRuntimeClass()->m_lpszClassName, but it equals "CWnd". Obviously wrong.
GetClassName gives you a window class name the control was registered with.
You should tell window class from C++ class. What you can see in debugger with GetRuntimeClass is C++ class names.
My current project needs a CRichEditCtrl, with just a slight bit of extra functionality.
Typically "a slight bit of extra functionality" is added by control subclassing, while what you do is superclassing. Feel the difference.
Best regards,
Igor
-
September 11th, 2013, 02:00 AM
#6
Re: Subclassing CRichEditCtrl VS2008 Windows 7
Thanks Igor but what do you mean that I am superclassing? I've been doing OO for 25 years and to me this is subclassing. Maybe there's a new term, or new usage, or rarer usage I'm not familiar with?
I'm also surprised to hear that GetRuntimeClass() is "C++ clas names". In the code I supplied the C++ class name is clearly CRichEditCtrl.
Note I'm very thankful for your help and you clearly understand this better than I do. I'd like to understand better than I currently do, so even though my current problem may be solved thanks to VictorN, I'd still like to know more.
-
September 11th, 2013, 04:30 AM
#7
Re: Subclassing CRichEditCtrl VS2008 Windows 7
In terms of Windows gui programming, superclassing and subclassing windows procedures are nothing at all to do with the terms as understood in connection with OO. They relate to how you modify the behaviour of a windows control using windows procedures and apply to c code as well as c++!
For more detail about sub/supper classing in terms of window procedure see
http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
September 11th, 2013, 06:21 AM
#8
Re: Subclassing CRichEditCtrl VS2008 Windows 7
Originally Posted by Swiss Frank
Thanks Igor but what do you mean that I am superclassing? I've been doing OO for 25 years and to me this is subclassing. Maybe there's a new term, or new usage, or rarer usage I'm not familiar with?
It seems you did not follow the links I provided, otherwise the terms would be clear for you.
I'm also surprised to hear that GetRuntimeClass() is "C++ clas names". In the code I supplied the C++ class name is clearly CRichEditCtrl.
No, it's definitely CWnd, as CWnd::GetDlgItem returns precisely CWnd*. Casting CWnd* pointer to CRichEditCtrl* never makes the object behind the pointer to mutate right away to anything else but what it really is.
Best regards,
Igor
-
September 11th, 2013, 06:45 AM
#9
Re: Subclassing CRichEditCtrl VS2008 Windows 7
Thanks Igor I see the hyperlinks now and am reading the article.
I also understand your point about object class. I didn't realize I was getting a pointer to a CWnd, I thought it was a CWnd pointer to a CRichEditCtrl object. In fact if its always a CWnd, I'm now confused how virtual methods on it work.
Thanks 2kaud--had I not now seen Igor's hyperlinks, your help would have gotten me on the right track I am sure.
-
September 11th, 2013, 07:04 AM
#10
Re: Subclassing CRichEditCtrl VS2008 Windows 7
Originally Posted by Swiss Frank
Thanks Igor I see the hyperlinks now and am reading the article.
I also understand your point about object class. I didn't realize I was getting a pointer to a CWnd, I thought it was a CWnd pointer to a CRichEditCtrl object. In fact if its always a CWnd, I'm now confused how virtual methods on it work.
Remove the cast to CRichEditCtrl and assign it to a CWnd pointer (not a CRichEditCtrl pointer). Do the virtual functions still call CRichEditCtrl methods?
If not, then what you did was fool C++ by casting to the wrong type. Once you do that, all bets are off as to what will happen, as C++ doesn't self-correct itself if what you're casting to is not what it really is.
In other words, once you dd this:
Code:
CRichEditCtrl* prich = (CRichEditCtrl*) GetDlgItem( IDC_PATCH );
Then the pinch pointer is a pointer to a CRichEditCtrl and all CRichEditCtrl methods will be called. But again, if it isn't really a CRichEditCtrl, expect undefined behaviour to occur (more than likely, functions that go into hyperspace, and/or crash).
Regards,
Paul McKenzie
Last edited by Paul McKenzie; September 11th, 2013 at 07:08 AM.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|