Click to See Complete Forum and Search --> : Tabbing Problem with ActiveX
Curtis Harrison
May 6th, 1999, 12:56 PM
I have been having a problem with tabbing in 2 different situations.
1. I create a dialog template in the resource workshop (I set the tabstops, tab order, and groups appropriately). Now at runtime, I create this dialog and place it inside of a window. The window I pass the pointer to the window as the parent to the dialog in the Create(...) call. When a control on the dialog has focus, and I press the Tab or Shift-Tab keys, the focus leaves the control that was in focus, but does not go anywhere else... (basically it goes to never-never land). I can click anywhere with my mouse pointer and it works fine. But I cannot tab around the controls on the dialog, or use the arrows on my keyboard.
2. Same tabbing problem as above, but this is when I make a CDialog in the resource workshop, and then at run time, I place 2 active X controls on the dialog. I created these activeX controls myself...
So, are there some flags or settings somewhere that I am missing? Do I need to override some virtual functions to intercept the Tab and Arrow keys?
Let me know if you have actually done this yourself, and what solution you found...
Thanks,
Curtis
Curtis Harrison
May 10th, 1999, 06:53 PM
To fix the above problem, complete the following 7 steps:
1. Make sure that we checked the Tabstop box under properties for any controls on the dialogs we create.
2. Make sure that when manually placing ActiveX controls on dialogs at runtime, we have the WS_TABSTOP flag set. Also, call Create on the controls in the order that you want the tabbing order to go.
3. Use the Layout/Tabbing Order menu option to set the tabbing order for all the controls on the dialog.
4. For any dialogs that will be used as ActiveX controls, set the following two properties: “Control” and “Control Parent”. Control is set because this will be an ActiveX Control, and Control Parent is set because this dialog has child controls on it (ie: Buttions, checkboxes, list controls, etc…).
5. For the actual ctrl class of the ActiveX control, you need to make sure a certain style is set. To do this, override the PreCreateWindow(..) virtual function and replace the “ToDo” comment with: cs.dwExStyle |= WS_EX_CONTROLPARENT;
6. To make sure everything is getting set correctly, you may also want to override the PreCreateWindow(..) virtual function of the actual dialog from step 3 above… Do it in the same way you did #4 above, and also add the line: cs.style |= DS_CONTROL; This step makes sure that the style gets set no matter how the dialog was created.
7. Lastly, you need to override the PreTranslateMessage(..) method of the container that will house the ActiveX control. You need to see if the pMsg can be handled by IsDialogMessage(). This is done in the following way:
BOOL CMyView::PreTranslateMessage(MSG *pMsg)
{
if(IsDialogMessage(pMsg)
{
return TRUE;
}
else
{
return CView::PreTranslateMessage(pMsg);
//Note, this line will already be here
//by default… CView may be CDialog,
//or CWnd, etc…
}
}
July 13th, 1999, 09:36 AM
This is good example, but the enter key is not same as click. How do I execute <enter> key as click? Thanks in Advance.
July 13th, 1999, 10:39 AM
You don't... You see, when you click the mouse button, the mouse arrow is at a certain location. The control that the mouse arrow is on actually handles the click message. When you press enter, depending on what control has focus, the control may be pressed, or the default button "usually CANCEL" will be pressed. These are different operations.
How to solve the problem really depends on what you want to do... If you want the <Enter> to act EXACTLY as the mouse click, (ie. Differently depending on where the mouse arrow is) you could probably create events for the WM_KEYPRESS message. You would need to do this for each control on the dialog, or any dialog you placed on your control. Then you could map the events to individual methods, all of which Post the WM_LEFTBUTTONCLICK (I think) message to the active window (when the keypress is the "Enter" key). This should do it, but it won't be pretty...
July 13th, 1999, 02:35 PM
Here is an easier solution. Just check for <enter> key. If it is an <enter> key, then convert it to space key. Space is same as click.
BOOL CMyView::PreTranslateMessage(MSG *pMsg)
{
if (pMsg->wParam == VK_RETURN)
{
//replace ENTER key with SPACE key, SPACE is the same as CLICK
pMsg->wParam = VK_SPACE;
}
if (IsDialogMessage(pMsg))
{
return TRUE;
}
else
{
return CView::PreTranslateMessage(pMsg);
//Note, this line will already be here by default… CView may be CDialog,
//or CWnd, etc…
}
}
Paul H.
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.