Page 1 of 2

Windows edit control programming question

Posted: Wed Sep 10, 2008 10:30 pm
by bewing
I've wondered for many years about this, so I guess I'll be a n00b for a day, and ask you guys -- I want to know what the cleverest workaround hack is for the following piece of M$ idiocy, that you do.

Assume: You have a typical UI screen. It has some fields on it, like maybe a box where a user can enter a filename.
The text entry boxes are guaranteed to be short. Less than 80 characters, maybe -- and it fits nicely on the screen.

Now, it is beyond tempting to use some kind of edit control for those text input boxes, right? It almost works perfectly. But there is generally at least one irritating problem, whatever you do.

You can use a singleline edit box.
The annoying problem: when the user wants to hit Enter, to finalize the enry -- they will get a ding/bell/chime, because Enter is an illegal character in a singleline edit control.

workaround #1 (the M$ preferred solution, AFAIK): you can subclass the WM_CHARs, wait for a Enter key, and return 0.
The annoying thing about workaround 1: about 40 extra lines of fugly, confusing code, just to turn off a damned bell. This is what I have always done in the past.

workaround #2: use a multiline edit box, instead. Then Enter is a legal key and won't chime.
The annoying thing about workaround #2: once the Enter key has been hit, it gets stored in the edit box, and you can't get rid of it. Yes, I know you should just be able to select the text in the box and CLEAR it -- but it doesn't work. That just deletes the text, not the CR/LF. You still end up with TWO lines in your edit box -- that was supposed to exist for the purpose of entering one line of text -- and the caret is on the wrong line.

Workaround to the workaround?: Somehow, someway, delete that last damned CR/LF?

workaround #3: Somehow, someway, disable the damned chime?

So ... all you Windoze programmers out there ... please make me look like an idiot. What is your preferred slick, elegant solution to using edit controls for singleline text prompt input, that I haven't clued into?

Re: Windows edit control programming question

Posted: Thu Sep 11, 2008 2:03 am
by Combuster
Use Visual Basic 6.0. The best stop for all your GUI problems :twisted:

Seriously, Method #1 is the one I'd use. The problem is in the overhead of subclassing that text box rather than that simple check for 'enter'.
If I had to do such things repeatedly, I'd stow away the fugly part of the code into a dark corner so that only the check for enter remains. (Most likely, using a class for a control)

Re: Windows edit control programming question

Posted: Thu Sep 11, 2008 5:40 pm
by madeofstaples
Since your offered solution involves subclassing, I'm assuming you are working with Visual Basic.

Subclassing is not necessary, just add code in the KeyPress event. If KeyAscii is set to vbCr, then set KeyAscii to 0 and do whatever processing the Enter key should do (it may be a little different than how I say; it's been a while since I've had to touch visual basic, thank god).

In C/C++, you should be able to handle similar messages through the WM_COMMAND message to the main window. How, exactly, you do this may differ depending on if you use an edit control (defined as a system window class), or an edit control provided by the comctls library, and which version you're linking against.

Re: Windows edit control programming question

Posted: Fri Sep 12, 2008 12:30 am
by Combuster
Subclassing isn't limited to VB. I use the same term when doing that stuff in C

Re: Windows edit control programming question

Posted: Fri Sep 12, 2008 8:24 am
by madeofstaples
Out of curiosity, in what case would subclassing be necessary in C?

Re: Windows edit control programming question

Posted: Fri Sep 12, 2008 8:38 am
by Combuster
In fact, for every standard control you stick onto a form, you'll have to subclass it to be able to do something with it, even just as basic thing as a button needs subclassing so you can respond to the "I got poked" event.

Edit: In VB and friends, The form editor generates the code needed to handle those messages, and if required redirects them to your handlers, so you don't normally need to subclass manually (and make sure VB doesn't lock up once you enter the debugger).

Re: Windows edit control programming question

Posted: Fri Sep 12, 2008 8:59 am
by madeofstaples
Err.. I understand subclassing to be the technique along these lines:

Code: Select all

oldWndProc = SetWindowLongPtr(hWnd, GWL_WNDPROC, subclassProc);
...
LRESULT CALLBACK subclassProc(HWND hWnd, MSG msg, LPARAM lParam, WPARAM wParam)
{
	if(msg==...)
	{
		...
		// return appropriate value if necessary, or let message continue to the original window procedure
	}
	return CallWindowProc(oldWndProc, hWnd, msg, lParam, wParam);
}
(or the same idea with the SetWindowSubclass() function, if you only plan to support XP or newer and are not subclassing a window owned by a separate thread).

Whereas controls on a form pass their messages to the parent window via the WM_COMMAND notification as documented here. This is not subclassing because you should have created the main window's class, where you specified the callback window procedure function (the lpfnWndProc member of the WNDCLASSEX structure), and thus there's no need to override it with subclassing because you own the original window procedure.

Re: Windows edit control programming question

Posted: Fri Sep 12, 2008 9:05 am
by Combuster
Oh well, time to brush up my knowledge on low level windows controls. Still, WM_Command can't tell you everything.

Re: Windows edit control programming question

Posted: Fri Sep 12, 2008 9:42 am
by bontanu
Subclassing and superclassing are done even in assembly ...

Look here for ASM samples and very good explanations of Iczelion:
Subclassing - http://win32assembly.online.fr/tut20.html
Superclassing - http://win32assembly.online.fr/tut22.html

C is very similar.

Re: Windows edit control programming question

Posted: Fri Sep 12, 2008 10:19 am
by madeofstaples
bontanu wrote:Subclassing and superclassing are done even in assembly ...

Look here for ASM samples and very good explanations of Iczelion:
Subclassing - http://win32assembly.online.fr/tut20.html
Superclassing - http://win32assembly.online.fr/tut22.html

C is very similar.

I did not mean to imply that subclassing could not be done in C or assembly. Saying that wouldn't logically follow from the fact that a VB application would be compiled into machine code (which, as we know, maps directly to assembly). The reason it's done in Visual Basic is often because Visual Basic (at least up to version 6, I'm not sure if they rethought things since .NET) tries to abstract too far away from the window procedure.

This is good for people just learning basics about programming, or just needing to write a simple application very quickly, but it's a pain in the @$$ when writing even somewhat simple end-user applications. Things like painting in the non-client area, setting the minimum and/or maximum dimensions to which the window can be sized, docking to other windows (e.g, in a tool-window based interface), etc require subclasing in Visual Basic, whereas these things do not need to be subclassed in Assembly or C.

Re: Windows edit control programming question

Posted: Fri Sep 12, 2008 10:44 am
by Combuster
madeofstaples wrote:I did not mean to imply that subclassing could not be done in C or assembly. Saying that wouldn't logically follow from the fact that a VB application would be compiled into machine code (which, as we know, maps directly to assembly). The reason it's done in Visual Basic is often because Visual Basic (at least up to version 6, I'm not sure if they rethought things since .NET) tries to abstract too far away from the window procedure.
I see that you're not familiar with the full abilities of visual basic :roll:
The majority of window messages are mapped 1:1 to a visual basic event. Its just that some messages are missing, or some are reused for internal processing (like the menu stuff, WM_command, and the like)
but it's a pain in the @$$ when writing even somewhat simple end-user applications.
BS. The vast majority require the same amount of logic in either language.
Things like painting in the non-client area
Import bitblt and friends and you're set
setting the minimum and/or maximum dimensions to which the window can be sized
Form_Resize() FTW
docking to other windows (e.g, in a tool-window based interface), etc require subclasing in Visual Basic
I did those without subclassing too.

Any more undereducated petty insults at visual basic? :twisted:


The only real problem with subclassing is that it breaks the debugger so a good VB programmer knows how to stay away from that :)

Re: Windows edit control programming question

Posted: Fri Sep 12, 2008 11:58 am
by madeofstaples
Combuster wrote:
madeofstaples wrote:I did not mean to imply that subclassing could not be done in C or assembly. Saying that wouldn't logically follow from the fact that a VB application would be compiled into machine code (which, as we know, maps directly to assembly). The reason it's done in Visual Basic is often because Visual Basic (at least up to version 6, I'm not sure if they rethought things since .NET) tries to abstract too far away from the window procedure.
I see that you're not familiar with the full abilities of visual basic :roll:
People in glass houses shouldn't throw stones :roll:
Combuster wrote:The majority of window messages are mapped 1:1 to a visual basic event.
For one, the OLE related events aren't window messages, but ignoring that glaring incongruity, a quick look at the available methods for a form is even more contradictory of what you just said.

For example, "Activate" and "Deactivate" are conveyed with the same window message (WM_ACTIVATE).

Ruling out the ones I know are not window messages (i.e, the OLE related ones) and counting Activate and Deactivate as one, the rest seem for the most part at least linked to their own message. In Visual Basic 6 that leaves about 24 message-handling functions, while WinUser.h defines over 200 messages. Majority? Please.
Combuster wrote:Its just that some messages are missing, or some are reused for internal processing (like the menu stuff, WM_command, and the like)
The point was that this is why it is often necessary to subclass when using Visual Basic--it automatically handles many messages, but it may not handle them the way the programmer needs it to.
Combuster wrote:
but it's a pain in the @$$ when writing even somewhat simple end-user applications.
BS. The vast majority require the same amount of logic in either language.
Not if you want to subclass a message but still need to pass the message to the form to have that code execute. Non-client painting has some quirks to it as well in Visual Basic only. Also there's the extra processing for every message to retrieve the address of the original window procedure, calling the default window procedure or the original window procedure to examine the return value before doing processing (necessary in some cases). This can really add up for messages such as WM_MOVING.

Then there's the fact that if you made any silly mistake that is caught at run-time, you better have saved your work... It makes utilization of error handling methods a pain as well (while it doesn't interfere with try...catch(), or throw in C++, for example).
Combuster wrote:
Things like painting in the non-client area
Import bitblt and friends and you're set
And how do you plan to use them to paint onto the non-client area??
Combuster wrote:
setting the minimum and/or maximum dimensions to which the window can be sized
Form_Resize() FTW
That would be a naive way to achieve such a specification. This method would flicker a bit, and if I remember correctly, it wouldn't work in the case where the user maximizes the window (it may even raise an error).
Combuster wrote:
docking to other windows (e.g, in a tool-window based interface), etc require subclasing in Visual Basic
I did those without subclassing too.
Yes, these are things I'm saying that subclassing is necessary for in Visual Basic.
Combuster wrote:Any more undereducated petty insults at visual basic? :twisted:
Well, you'll have to be the one to decide if any more undereducated posts end up in this thread. I'm not even intending to insult visual basic...
Combuster wrote:The only real problem with subclassing is that it breaks the debugger so a good VB programmer knows how to stay away from that :)
Yes, save your work.

Re: Windows edit control programming question

Posted: Fri Sep 12, 2008 2:49 pm
by bewing
In Visual Basic 6 that leaves about 24 message-handling functions, while WinUser.h defines over 200 messages.
But a number around 32 sounds like a good size, and 200 is flaming idiotic overkill. :wink:

Re: Windows edit control programming question

Posted: Fri Sep 12, 2008 3:34 pm
by madeofstaples
bewing wrote:But a number around 32 sounds like a good size, and 200 is flaming idiotic overkill. :wink:
Not only is this a matter of opinion, but it is beside the point. 24 is not the majority of 200, and the programmer still has to subclass in Visual Basic where he/she wouldn't need to subclass in C/C++/Assembly/what have you. Thus, saying "The majority of window messages are mapped 1:1 to a visual basic event." demonstrates a misunderstanding of Visual Basic and/or Windows/Messages in the Windows environment.

Re: Windows edit control programming question

Posted: Fri Sep 12, 2008 8:32 pm
by bewing
Then let me say it this way, since you seem to be insisting on being pedantic:

There are not, in actuality, 200 different kinds of events inside a windoze computer. The 200 separate messages overlap in their functionality. They are not exclusive of each other. Therefore, it is quite possible that an intelligent combination of some 24 element subset of those messages may actually, in fact, comprise a complete set. Plus, the 24 functions that you refer to are not all methods of the same class of object, are they? So they don't necessarily have to all be the same 24 functions, do they?

I am programming Windoze in C, ATM. In just about every Windoze GUI program I've written in C, I need to subclass the stupid edit windows. I almost never have to subclass a damned thing in VB -- because the VB interface to the API does it all for me. In fact, somehow VB manages to create effects that I've never been able to figure out how to recreate in C. So, I am basically in agreement with Combuster. VB programs require fewer instances of writing subclassing functions, from a programmer's point of view.

The problem that I have with VB is that it can take a flawless piece of sourcecode, and make it run wrong every time, or make it run wrong in a random fashion. There are places where you never ever want bugs, and your compiler is at the top of that list.