Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

Tabstops

Posted on 1998-12-24
7
Medium Priority
?
628 Views
Last Modified: 2008-02-01
I am working with VC++ 5.0 on a Win98 system, but have run into this same problem on a Win95 machine.  When I create a window and a group of controls on that window with the following code:

HWND hWnd = CreateWindowEx(WS_EX_NOPARENTNOTIFY, "RegScreen", "Install Pro 1.0", WS_VISIBLE | WS_CAPTION | WS_BORDER | WS_SYSMENU, pt.x, pt.y, 500, 400, NULL, NULL, hInst, NULL);

CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_TABSTOP | WS_CHILD | WS_BORDER| WS_VISIBLE | ES_LEFT, 165, 45, 305, 27, hWnd, (HMENU)IDC_USERNAME, hInst, NULL);

CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_TABSTOP | WS_CHILD | WS_BORDER| WS_VISIBLE | ES_LEFT, 165, 93, 305, 27, hWnd, (HMENU)IDC_COMPANY, hInst, NULL);      

CreateWindow("BUTTON", "<< Back", WS_TABSTOP | WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 210, 325, 65, 27, hWnd, (HMENU)IDC_BACK, hInst, NULL);

CreateWindow("BUTTON", "Next >>", WS_TABSTOP | WS_DISABLED | WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON, 275, 325, 65, 27, hWnd, (HMENU)IDC_NEXT, hInst, NULL);

CreateWindow("BUTTON", "Cancel", WS_TABSTOP | WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 410, 325, 65, 27, hWnd, (HMENU)IDC_CANCEL, hInst, NULL);

Why is it that the Tab button COMPLETLY REFUSES to work under any circumstances?  I was under the impression that if all the controls were created with the WS_TABSTOP style that the tab key would move between them.  However this does not happen on the window that I have created.
0
Comment
Question by:dirtdart
  • 4
  • 2
7 Comments
 
LVL 8

Expert Comment

by:Answers2000
ID: 1181005
I think...

The parent window for the controls needs to handle the WM_NEXTDLGCTL message.  The reason you don't need to include this code for dialog boxes, is that the default dialog procedure (DefDlgProc) handles this by default.  In your case, your parent window isn't a dialog, so you have to put in this code yourself in the parent window (the one you create first).

BTW if you are thinking of changing to use a dialog/modeless dialog box for the parent, watch out - I seem to recall that DefDlgProc only handles WM_NEXTDLGCTL message correctly for controls that are in the dialog's resource template at least under some versions of Windows.  Sorry I can't be more specific on this (extra) comment, as I simply don't remember too well!
0
 
LVL 5

Author Comment

by:dirtdart
ID: 1181006
Well, this seems like a logical answer, but I'm going to need a bit more information before I can grade it.  I attempted to process the message with what little information I can find on it in the Win32 SDK, but it certainly didn't work in the way I need it to.  My code:

case WM_NEXTDLGCTL:
      {
            SetFocus(GetDlgItem(hWnd, wParam));
            return 0;
      }

Since wParam supposedly returns the ID of the control that should receive focus, this seems to be a logical conclusion.  Whenever the Tab is pressed, it fires the message and the message pump sets the focus to the next provided control.  However.  When run, the above code simply prevents any of the controls on the form from receiving focus.
0
 
LVL 5

Author Comment

by:dirtdart
ID: 1181007
Well, I've waited two weeks for more of an explination, so I guess now I'll have to open the question back up.
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 4

Accepted Solution

by:
SaGS earned 800 total points
ID: 1181008
For the TAB key to work, you must call IsDialogMessage() in the main message loop. And call DefDlgProc() for default message processing, instead of DefWindowProc().

From your question&comment I see you are not using MS Foundation Classes. In this case, you have the control on the message loop - just insert IsDialogMessage() there (see help for details).

With MFC (the version I have, at least), CDialog accomplishes this by calling IsDialogMessage() from it's PreTranslateMessage() member function. You can define a CDialog-derived class (to provide the message table), and still create the window with CreateWindow(); just Attach() the HWND to the CDialog-derived object.

What you obtain is the equivalent of using a modeless dlgbox with a private class as the main window (I often use dlgboxes as main windows, it works fine), only that you don't rely on a template and CreateDialog() to create the window and the controls.
0
 
LVL 5

Author Comment

by:dirtdart
ID: 1181009
Well, that looks great, and it certainly answers my question.  However, I'd appreciate it if you'd give me one more piece of advice to go with this.  My main message loop processes messages for at least 12 different windows (kind of a wizard type thing).  How do I tell which window handle is currently being processed so that I can pass it to IsDialogMessage?
0
 
LVL 4

Expert Comment

by:SaGS
ID: 1181010
The key is the WM_ACTIVATE message. Define a global variable:

HWND hActiveWnd = NULL;

and inside all windows procedures (in fact, it's enough to do this only for windows that need the extra processing) handle the WM_ACTIVATE message. When the window is activated (WA_ACTIVE, WA_CLICKACTIVE), store the window's handle into the global variable; when deactivated (WA_INACTIVE), set the global handle to NULL (Windows takes care to send these messages in the proper order - first deactivates the old window, then activates the new one). In the main message loop, examine the global variable to decide what to do (NULL => nothing to do, the active win does not belong to your app or needs nothing special, !=NULL => your window, the value is the active window's HWND).

Note: You can use a similar trick to implement a window-specific accelerators table (a global "HACCEL hActiveWndAccel = NULL;", and so on).
0
 
LVL 5

Author Comment

by:dirtdart
ID: 1181011
Sounds great.  Thanks for all the help.  Now maybe I can get this junk finished!
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
Suggested Courses
Course of the Month11 days, 23 hours left to enroll

916 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question