Click to See Complete Forum and Search --> : Caret in custom Edit disappears on losing/gaining focus


sanx72
July 2nd, 2009, 09:20 AM
Hi,

I've written a C++ OCX control. This sits inside a VB.NET UserControl which is then presented to the client within Internet Explorer.

I wanted to display a custom caret shape so I coded it up and when I enter the edit control, the caret appears ok, blinking away as you'd expect. If I move to another control within the OCX and then move back to the edit control, the caret is shown correctly.

However, if I move focus to the edit control, then show then hide a message box the caret disappears, even though the focus is in the edit control.

I removed the caret code but still get the same behaviour.

Within the OCX, I create edit control windows, based on the standard EDIT class; e.g.

lpfnEdit = sWndSys.lpfnWndProc;

// Clone the Emulator Entry from the System Edit
sWndReg.lpszClassName = "MYEDIT";
sWndReg.lpfnWndProc = MyEntry;
sWndReg.style = sWndSys.style & ~CS_PUBLIC & ~CS_CLIPSIBLINGS;
RegisterClass(&sWndReg);
:
hwnd = CreateWindow("MYEDIT", pszEditText,
style, wr.x, wr.y, wr.cx, wr.cy,
parentHwnd,
(HMENU)nId, hAppInstance, NULL);
:

In the custom Window Proc I did have my own Paint to draw my own border, and some additional key handling routines, but I took all that out so that it just calls the standard EDIT class WndProc and I still get the same issue.

Have any other Win32 developers experienced a similar problem and if so, how did you get around it?

Cheers
Rich

dc_2000
July 2nd, 2009, 07:19 PM
I don't think that that is the correct way to subclass a Windows common control. Without the use of MFC, you need to get a handle to existing WindowProc (i.e. 'lpOldWndProc') by calling GetWindowLongPtr(GWLP_WNDPROC) for the window handle of a control, then set up your own WndProc by calling SetWindowLongPtr(GWLP_WNDPROC) for the same window handle.

Inside your WndProc that you passed to SetWindowLongPtr() API you need to do the following:
//Do message interception/processing here
...

//at the end call this API to pass messages on
return CallWindowProc(lpOldWndProc, hWnd, Msg, wParam, lParam);

Also before that control is destroyed you need to restore its WndProc by calling SetWindowLongPtr(GWLP_WNDPROC) with the 'lpOldWndProc'.

sanx72
July 3rd, 2009, 01:58 AM
Sorry dc_2000, I didn't show that bit of the code in my example, but that is what I'm doing, but I do it when I Register my own class using GetClassInfo. E.g.

// Get the details for the system "EDIT" class
// The first parameters identifies the instance of the application
// that created the class, which help says is NULL for Windows classes
GetClassInfo(NULL, "EDIT", &sWndSys);

// Save its window procedure
lpfnEdit = sWndSys.lpfnWndProc;

Then in my WndProc I call...

CallWindowProc(lpfnEdit, hEntry, msg, mp1, mp2);

...when I want to do the default processing for messages I'm not interested in and all those that I want to extend the default behaviour.

In this way I get a single WndProc for all edit fields. Are you suggesting that I should save a unique WndProc for each edit control I create and call that instead of the class one?

dc_2000
July 3rd, 2009, 02:03 PM
I do it when I Register my own class...
If you register your own class than you need to make your own WndProc, in that case you won't be able to take advantage of the EDIT control's WndProc. If, on the other hand, you subclass the existing EDIT control then you can do it like I described in my post above (which is probably the most appropriate way to do it for you). But you cannot mix the two.

torbiak
July 9th, 2009, 12:27 AM
Hey, I'm having a similar problem. I'm playing around with win32 in C and I've subclassed an edit control as dc_2000 described (similar to Microsoft's "Safe Subclassing" article on MSDN: http://msdn.microsoft.com/en-us/library/ms997565.aspx). Your subclassing method looks like it would work, too, despite what dc_2000 said. I hide (SW_HIDE) the edit control when it loses focus (WM_KILLFOCUS) and then when I show it again it looks fine except the caret is gone and I can't change the text interactively anymore.

Were you able to find a solution to your problem?

sanx72
July 9th, 2009, 02:03 AM
Sorry, didn't find a solution tho I took all my custom message processing out and still got the same issue so I think the problem might lie in the original control.

If I find a solution I'll update this thread!