Sign in to follow this  
philipbennefall

Issue with tab key in multiline edit (Win32)

Recommended Posts

Hi folks, I am having a bit of an issue with a multiline edit control that I am making with the CreateWindow function. I'm basically creating a dialog box with a large multiline edit field and a few buttons, and I want the user to be able to tab between these. If I make it a single line edit field it works fine (e.g. the tabbing behavior is just like in any standard dialog box which is what I want), but as soon as I change it to multiline then it captures the keyboard focus and then won't let go of it. In short, if I set default focus to one of the buttons then I can tab around, but as soon as the edit field gets the keyboard focus then it keeps it exclusively. This, of course, is what one would expect in an application such as notepad where the idea is to be able to do text processing, but this is not what I want in this case; I want standard dialog box tabbing functionality but with the multiline edit field. Any advice would be highly appreciated. Thanks! Kind regards, Philip Bennefall

Share this post


Link to post
Share on other sites
This is because multi-line edit controls are built to process the tab key internally. You will want to subclass the control (pass in a custom wndproc), and within that capture the WM_KEYDOWN message. When you encounter the tab key, simply swap focus to the next highest tabstop.

Hopefully this helps.

Share this post


Link to post
Share on other sites
Hello there,

Thank you very much for the quick reply. I wonder if you would be able to show a quick example of how to subclass the control like you mention and how the code in the callback might be written? GUI programming is not a field in which I have much experience as I only code audio based games for the blind and visually impaired, and so it's extremely rare that I have to do anything with windows. So any code examples would be highly appreciated. I'm using C++ and calling CreateWindowEx.

Thanks in advance.

Kind regards,

Philip Bennefall

Share this post


Link to post
Share on other sites
Subclassing is really easy:
WNDPROC		oldEditWndProc; // ptr to old window proc
....
// after creation:
oldEditWndProc = ( WNDPROC ) SetWindowLong( hWndEdit, GWL_WNDPROC, ( long ) NewEditWndProc );
...

LONG WINAPI NewEditWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) {
// catch the messages here..
// else:
return CallWindowProc( oldEditWndProc, hWnd, uMsg, wParam, lParam );
}


notice how you call CallWindowProc instead of DefWindowProc

Share this post


Link to post
Share on other sites
Hello again,

Thank you very much, that code snippet makes perfect sense. However I am not entirely certain how I would go about setting the keyboard focus to the next or previous tabstop if the user pressed tab or shift+tab respectively. Basically I want it to work like a regular dialog box where shift+tab moves you to the previous item, and tab to the next. If I capture the WM_KEYDOWN message, won't I get two separate notifications for shift and tab for instance? And how exactly does one programatically switch focus to the next or previous tabstop? SetFocus works on a specified window handle, of course, but I do not know how to get handles to the previous and the next tabstop in relation to the currently focused control, nor do I know how to check for multiple keys being down at one time in the callback. All my previous experience is with DirectInput where one simply polls the device and then asks it whether a particular key is held down. Any hints?

Kind regards,

Philip Bennefall

Share this post


Link to post
Share on other sites
Hello again,

Looking at the GetNextDlgTabItem function it seems perfectly logical, however I don't quite understand what you mean by delegating the tab behavior to the dialog message function. I call this function in my main message loop already, as that was required to get it to tab between the other controls in the window. In short, what I need to find out is if the user tried to get focus away from the edit control by pressing either tab or shift+tab.

Thanks again for all the help.

Kind regards,

Philip Bennefall

Share this post


Link to post
Share on other sites
I thought of letting the IsDialogMessage doing the tab behaviour, but in this case you'd also need to override WM_GETDLGCODE when subclassing.

Probably easier to check for TAB yourself with WM_KEYDOWN. Check for VK_TAB and use GetAsyncKeyState to check if Shift is currently pressed to differ between the two cases.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this