Windows edit control programming question
Windows edit control programming question
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?
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?
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: Windows edit control programming question
Use Visual Basic 6.0. The best stop for all your GUI problems
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)
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)
-
- Member
- Posts: 204
- Joined: Thu Apr 12, 2007 8:15 am
- Location: Michigan
Re: Windows edit control programming question
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.
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.
Some people are offended by the verifiable truth; such people tend to remain blissfully unencumbered by fact.
If you are one of these people, my posts may cause considerable discomfort. Read at your own risk.
If you are one of these people, my posts may cause considerable discomfort. Read at your own risk.
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: Windows edit control programming question
Subclassing isn't limited to VB. I use the same term when doing that stuff in C
-
- Member
- Posts: 204
- Joined: Thu Apr 12, 2007 8:15 am
- Location: Michigan
Re: Windows edit control programming question
Out of curiosity, in what case would subclassing be necessary in C?
Some people are offended by the verifiable truth; such people tend to remain blissfully unencumbered by fact.
If you are one of these people, my posts may cause considerable discomfort. Read at your own risk.
If you are one of these people, my posts may cause considerable discomfort. Read at your own risk.
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: Windows edit control programming question
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).
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).
-
- Member
- Posts: 204
- Joined: Thu Apr 12, 2007 8:15 am
- Location: Michigan
Re: Windows edit control programming question
Err.. I understand subclassing to be the technique along these lines:
(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.
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);
}
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.
Some people are offended by the verifiable truth; such people tend to remain blissfully unencumbered by fact.
If you are one of these people, my posts may cause considerable discomfort. Read at your own risk.
If you are one of these people, my posts may cause considerable discomfort. Read at your own risk.
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: Windows edit control programming question
Oh well, time to brush up my knowledge on low level windows controls. Still, WM_Command can't tell you everything.
-
- Member
- Posts: 134
- Joined: Thu Aug 18, 2005 11:00 pm
- Location: Sol. Earth. Europe. Romania. Bucuresti
- Contact:
Re: Windows edit control programming question
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.
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.
Ambition is a lame excuse for the ones not brave enough to be lazy; Solar_OS http://www.oby.ro/os/
-
- Member
- Posts: 204
- Joined: Thu Apr 12, 2007 8:15 am
- Location: Michigan
Re: Windows edit control programming question
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.
Some people are offended by the verifiable truth; such people tend to remain blissfully unencumbered by fact.
If you are one of these people, my posts may cause considerable discomfort. Read at your own risk.
If you are one of these people, my posts may cause considerable discomfort. Read at your own risk.
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: Windows edit control programming question
I see that you're not familiar with the full abilities of visual basicmadeofstaples 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.
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)
BS. The vast majority require the same amount of logic in either language.but it's a pain in the @$$ when writing even somewhat simple end-user applications.
Import bitblt and friends and you're setThings like painting in the non-client area
Form_Resize() FTWsetting the minimum and/or maximum dimensions to which the window can be sized
I did those without subclassing too.docking to other windows (e.g, in a tool-window based interface), etc require subclasing in Visual Basic
Any more undereducated petty insults at visual basic?
The only real problem with subclassing is that it breaks the debugger so a good VB programmer knows how to stay away from that
-
- Member
- Posts: 204
- Joined: Thu Apr 12, 2007 8:15 am
- Location: Michigan
Re: Windows edit control programming question
People in glass houses shouldn't throw stonesCombuster wrote:I see that you're not familiar with the full abilities of visual basicmadeofstaples 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.
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.Combuster wrote:The majority of window messages are mapped 1:1 to a visual basic event.
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.
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:Its just that some messages are missing, or some are reused for internal processing (like the menu stuff, WM_command, and the like)
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.Combuster wrote:BS. The vast majority require the same amount of logic in either language.but it's a pain in the @$$ when writing even somewhat simple end-user applications.
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).
And how do you plan to use them to paint onto the non-client area??Combuster wrote:Import bitblt and friends and you're setThings like painting in the non-client area
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:Form_Resize() FTWsetting the minimum and/or maximum dimensions to which the window can be sized
Yes, these are things I'm saying that subclassing is necessary for in Visual Basic.Combuster wrote:I did those without subclassing too.docking to other windows (e.g, in a tool-window based interface), etc require subclasing in Visual Basic
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:Any more undereducated petty insults at visual basic?
Yes, save your work.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
Some people are offended by the verifiable truth; such people tend to remain blissfully unencumbered by fact.
If you are one of these people, my posts may cause considerable discomfort. Read at your own risk.
If you are one of these people, my posts may cause considerable discomfort. Read at your own risk.
Re: Windows edit control programming question
But a number around 32 sounds like a good size, and 200 is flaming idiotic overkill.In Visual Basic 6 that leaves about 24 message-handling functions, while WinUser.h defines over 200 messages.
-
- Member
- Posts: 204
- Joined: Thu Apr 12, 2007 8:15 am
- Location: Michigan
Re: Windows edit control programming question
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.bewing wrote:But a number around 32 sounds like a good size, and 200 is flaming idiotic overkill.
Some people are offended by the verifiable truth; such people tend to remain blissfully unencumbered by fact.
If you are one of these people, my posts may cause considerable discomfort. Read at your own risk.
If you are one of these people, my posts may cause considerable discomfort. Read at your own risk.
Re: Windows edit control programming question
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.
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.