CButton into CEdit  
Author Message
João H. Kiehn Jr.





PostPosted: Visual C++ General, CButton into CEdit Top

Hi guys. May someone help me in my problem.

Im trying to put a CButton inside an CEdit control. There's no problem doing this cause I just have to create the button as a child of the edit. The problem is: When I click into the edit in the dialog to get the focus and type some data the draw of the edit component overhide the draw of the button.

I dont know why and where is the creation of the "window" that let the user input the data into the edit. I just wanna draw my button inside my edit without problems.

On the PreSubclassWindow of the CEdit I create the button: The m_btnKeyboard is a CButton.

//Get the rect of the button and set it position to the right of the text area.
CRect t_rcBtn;
this->GetClientRect( t_rcBtn );

t_rcBtn.left = t_rcBtn.right - 32;

this->m_btnKeyboard.Create( _T(""), BS_PUSHBUTTON, t_rcBtn, this, 0xAAAA );
this->m_btnKeyboard.ShowWindow( SW_SHOW );

this->SetMargins(0,32);

Sorry about any grammar errors or stuff like that. English isn't my first language.



Visual C++5  
 
 
Simple Samples





PostPosted: Visual C++ General, CButton into CEdit Top

You should ask this question in a forum for Windows programming. Eventhough you are using MFC, you are asking about Windows programming more than anything else.

You might get help in a Windows programming forum or newsgroup using a button control in an edit control, but I think it is not practical. It might be easier to use a CRichEditCtrl.

For the details of doing it using a regular edit control, look in sites such as CodeProject and CodeGuru for samples of editable list controls. That is done by putting other controls such as edit controls on top of the list control. Hopefully that will be relevant for what you are doing too.



 
 
jmsigler2





PostPosted: Visual C++ General, CButton into CEdit Top

Let me try at an answer from memory as it has been a while for me.  Your button messages are either unknown in kind to the edit control or trapped from reaching the edit control so they are never processed.  So, as a result, the parent of the edit control does not know a button exists in your edit control; it only received messages for the edit control itself.

You must subclass the EDIT or CEdit control to accomplish this and/or subclass the BUTTON or CButton itself.  Subclassing a control allows the developer to process any and all windows messages not necessarily those more limited default designed messages allowed through for processing by Microsoft.  You then have the option to allow further processing of messages forward to the parent.  Normally all messages from a control process immediately from the child directly to the parent.  Ironically, the parent can push them back to the child control for further processing using message reflection.  I think of this as poor-mans subclassing.

The Win32 SDK allows an option to set the proc in ::SetWindowLong() but this is not used much anymore at the application level.  From memory, you must first register an "Edit" type windows class (ie. RegisterClass() I think) that maps to the new proc.  Then create a window (ie. CreateWindow()).  Once you create this window, you have a windows handle which maps to the new proc.  At the low level you might be able to call ::SetWindowLong() to redirect messages to the new proc.  Under the MFC, typically one creates the CEdit control and then calls SubclassWindow() to update the attached handle to the handle to the new subclassed window.  Alternatively, you could call pWnd->Detach(HWND) and then pWnd->Attach(HWND) to change the attached handle to the subclassed control.  This subclassed control will allow you to receive any and all windows message just like a CWnd but also allow you to pass messages for further processing forward to the parent control.  There is a default dialog and default window proc call that is made at the bottom of a proc's switch to carry on further default behavior.

For the strict MFC types, I have seen a Microsoft book that provided a proc that did nothing but did nothing but create a CWnd object and attach that object or its handle to a new class derived from CEdit such as CMyEdit.  This call inside the proc would designed to only run once the first time the proc is called.  I can try to locate that reference if you like.

Microsoft now considers much of this system level stuff and limited or removed at least SDK support years ago.  You might need some older reference books for VC 6.0 or further back.  Anyway, inside the proc, if going that way, inside the WM_CREATE message, you will create the child control or button inside the edit control.  You might have to handle other messages like WM_PAINT, WM_DRAW, WM_ERASEBACKGROUND etc...

In the more recent compilers .NET 2003/2005, Microsoft is pushed the creation of MFC ActiveX controls.  It is not clear to me if going this path will get you a workable solution.  I am looking into this myself at the moment.  I see something about extending properties but I am not sure about events or custom events that will allow the user to create a child control within a control, or button inside an edit control.  Supposedly, there might be a path here that will allow for some design time or design-level support for developer who use your special control.

Aside from subclassing, another branch usually methioned is custom controls which again could be construed as writing a control that may itself have other child controls.  This is sometimes convenient from the .NET managed side.  However, the compilers sometimes have problems with this.  On the managed side you can add child controls to tools list.  But if you update the user/custom control, sometimes the user controls must be deleted from the tools list and then readded or the compilers throw errors.

I do not have access to a kernel license; however, some Microsoft managed code communicates to native code by way of a "Native" interface library or calls.  In the future, much of this may be eliminated as controls are rewritten from C# to bypass native C++ and talk directly to C/C-assembly.  Of course, there will be cases like yours where someone wants a unique control Microsoft does not provide or one you would like to extend.

One other thing, years ago I used some view classes such as CEditView or CTreeView.  These types of classes are actually wrapper classes to other MFC of windows controls.  CEditView wraps CEdit which in turn wraps a windows EDIT control, for example.  I cannot remember if there is a CTreeCtl or not; but I think there is a windows control like systreectl32 or something like that.  Anyway, in using these views, I was not able to access the actually windows handle.  In other words, the view classes are not intended to be customized.

You should look at rich text edit controls as they may provide more latitude in the flow of messages coming from its own child controls.

Your path should succeed, but takes some research.  And, the new VS 2003/2005 compilers are not so friendly in this area with code generation, design time support, or documentation.

By the way, if you subclass the button control, you can handle the WM_PAINT or WM_DRAW messages within the Button control itself.  You might not even bother sending the message to the parent edit control.  In this case you would create your own button windows class and create a CMyButton class to handle the draw functionality you desire.

I also think you are on track with the use of PreSubclassWindow in the MFC.  This is the same as WM_NCCREATE or more likely WM_CREATE.  From my memory, WM_NCCREATE is usually the pre-create call for data exclusive of child controls.  The child controls themselves are created in the WM_CREATE message.  At the end of the WM_CREATE message, further default processing creates the parent window to the child controls.

I hope this helps.

James, 12-29-2006

 


 
 
Simple Samples





PostPosted: Visual C++ General, CButton into CEdit Top

 
You must subclass the EDIT or CEdit control to accomplish this and/or subclass the BUTTON or CButton itself.  Subclassing a control allows the developer to process any and all windows messages not necessarily those more limited default designed messages allowed through for processing by Microsoft.
Another possible explanation for why the button does not get the messages is the Z-order. I am not sure but if it were me I would investigate that as a possibility.

 
The Win32 SDK allows an option to set the proc in ::SetWindowLong() but this is not used much anymore at the application level.
As far as I know it is still done; I know of no reason not to do subclassing that way or another way to subclass. That is, if MFC is not used nor any other interface to the Win32 SDK; if MFC or something like that is used, then it would be nearly impossible to do subclassing directly.

I am hightly skeptical that subclassing would help here. I am very interested in knowing a specific example of how it would be relevant. I did not ask this question so if the person asking the question wants to try subclassing then it's their choice, but I suspect it is a waste of time.

 
Microsoft now considers much of this system level stuff and limited or removed at least SDK support years ago.  You might need some older reference books for VC 6.0 or further back.  Anyway, inside the proc, if going that way, inside the WM_CREATE message, you will create the child control or button inside the edit control.  You might have to handle other messages like WM_PAINT, WM_DRAW, WM_ERASEBACKGROUND etc...
Actually there are many Platform SDK samples that use the SDK directly.

 
I see something about extending properties but I am not sure about events or custom events that will allow the user to create a child control within a control, or button inside an edit control.  Supposedly, there might be a path here that will allow for some design time or design-level support for developer who use your special control.
It is more a matter of controls on controls instead of controls in controls.

 
I also think you are on track with the use of PreSubclassWindow in the MFC.  This is the same as WM_NCCREATE or more likely WM_CREATE.  From my memory, WM_NCCREATE is usually the pre-create call for data exclusive of child controls.  The child controls themselves are created in the WM_CREATE message.  At the end of the WM_CREATE message, further default processing creates the parent window to the child controls.
WM_NCCREATE is sent when the non-client area is created. The non-client area is the borders, caption and such; the portion that is not the client area. I am not totally sure when PreSubclassWindow is called, but I am nearly certain it is called after the window and all children (controls) have been created. PreSubclassWindow is not a message; it is a virtual member function of CWnd.