Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Third party app control (Tab Control) 2

Status
Not open for further replies.

odlumb

Technical User
Oct 22, 2003
8
US
I have a third party app that I want to control from my own application. The third party app is a single main window with several controls, one of those controls being a Tab Control window containing about a dozen tab pages.

Launching the third part app manually and using Spy++ (Visual C++ .NET), I see that only the default tab page can be seen by Spy++, the other tab pages are presumably not instantiated yet. I confirmed this by manually clicking on one of the other tab pages, and then Spy++ could see that page (window) and all the controls (child windows) on that page.

Since the controls I wish to manipulate remotely are not on the default tab page when the program launches, I have to display the tab page of interest before I can proceed.

So, the order of business is:

1) launch the third party app remotely
2) bring up the tab page of interest
3) get the window handles of the controls on the new tab page
4) manipulate the controls on the tab page to achieve my goal
5) close the app

Launching (and closing) the app was not a problem. Since the app (when focused) responds to keyboard shortcuts Ctrl-PageUp and Ctrl-PageDown to switch tabs, my first approach was to emulate this programmatically. I got the window handle of the third party app, and tried the following code:

Code:
SendMessage(appWindow,WM_SETFOCUS,0,0);
SendMessage(appWindow,WM_KEYDOWN,VK_CONTROL,0);
SendMessage(appWindow,WM_KEYDOWN,VK_NEXT,0);
SendMessage(appWindow,WM_KEYUP,VK_NEXT,0);
SendMessage(appWindow,WM_KEYUP,VK_CONTROL,0);
SendMessage(appWindow,WM_PAINT,0,0);
This did absolutely nothing. I have no idea why. So question #1 – why didn’t this approach work?

Being resourceful, I tried a different approach. Spy++ told me that the name of the Tab Control window in the third party app was "SysTabControl32". Using this information and EnumChildWindows() I obtained the handle of this window and sent messages to it directly. I used two macros (TabCtrl_SetCurSel() and TabCtrl_SetCurFocus()) to select tab #1 (the tab of interest) and give it focus.

Code:
static void switchToTabOfInterest(HWND appWindow)
{
HWND	tabControlWindow;

tabControlWindow = NULL;
EnumChildWindows(appWindow,getTabCtrlWindow,(LPARAM)&tabControlWindow);
if (tabControlWindow != NULL) //class name = SysTabControl32
	{
	TabCtrl_SetCurSel(tabControlWindow,TAB_OF_INTEREST_INDEX);
	TabCtrl_SetCurFocus(tabControlWindow, TAB_OF_INTEREST_INDEX);
	SendMessage(tabControlWindow,WM_ERASEBKGND,0,0);
	SendMessage(tabControlWindow,WM_PAINT,0,0);
	}
}


BOOL CALLBACK getTabCtrlWindow(HWND handle,LPARAM pointer)
{
TCHAR	name[128];

GetClassName(handle,(LPSTR)&name,sizeof(name));
if (_tcscmp(name,_T("SysTabControl32")) == 0)
	{
	*reinterpret_cast<HWND*>(pointer) = handle;
	return(false); //we're done, no more child windows
	}
else
	return(true);
}
This had the following bizarre result – the TAB_OF_INTEREST_INDEX was in fact selected, but the visible contents of the displayed tab page still remained the same as before, i.e., it still looked like the original default tab page when the app first came up. This actually astonished me. I consider this to be an “illegal” or perhaps “incomplete” state, as though the Tab Control changed its tab index but didn’t instantiate or draw the contents (i.e., child controls) of the newly selected tab page.

So question #2 – what’s going on here? What have I forgotten to do?

At this point I’m completely stumped. Until I can get the desired tab page selected, instantiated and displayed, I can’t proceed toward my goal. Can anyone help? Or perhaps suggest an entirely different method for changing tab pages on a third party app?

Thanks in advance for your help.




 
#1:
Check what messages exactly are comming from Windows by pressing Ctrl PageUp - shouldn't be set some additional flags in wParam/lParam like "Ctrl key pressed" or something?
Or how do we know, whether control keys are pressed - for sure we don't need to count these pressings/releasings by ourselves.

#2:
That is right - function TabCtrl_SetCurSel() is used for changing of the wiev of tab chaption solely. (And is probably called by window control routine as a reaction to tab changing messages?) Tab chaption control view is independent from other controls in main field of the tabs - showing and hiding of corresponding controls is (another?) job of tab window control routine.

#3:
If no success with keyboard messages - may be try to simulate a mouse click over the desired tab location?
 
#4:
Look for tab control notification messages - there should be one like TC_TAB_STATE_CHANGED or something. Send it to your tab dialog.
 
Hi Mingus,

Thanks for your advice. I seem to have it working, but I don't completely understand why.

First, although the third party app changes tabs with Ctrl-Pageup/Pagedown, it also responds to Ctrl-left/right, which is apparently the "standard" way to do this with keyboard shortcuts in Windows. Second, SendMessage() does not seem to work, but PostMessage() does! Why this is the case I have no idea, since as far as I know the only difference is that SendMessage() waits for the action to be executed before returning, while PostMessage() just queues up the message and returns immediately.

Anyway, changing from pageup/down to left/right-arrow and from SendMessage() to PostMessage() made it work, and I'm now moving on to the next step. The mysteries of Windows programming ;-)
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top