I'm trying to change a tab in a page control in another application's window using the WinAPI.
I sent a TCM_SETCURSEL message to the page control, that did change the tab but didn't changed the tab contents. Ex: The Pagecontrol is on tab 0, I send a TCM_SETCURSEL Index: 1 to the page control, the page control is now on tab 1, but keep showing tab 0's contents instead of tab 1's.
I have tried:
I'm using delphi 2010 and the target application is also a delphi app.
This is the last code iteration, which sends the notifications to the page control's parent:
procedure ChangeTab(PageControlHandle: HWND; TabIndex: Integer);
var
Info: TNMHdr;
begin
Info.hwndFrom := PageControlHandle;
Info.idFrom := GetWindowLongPtr(PageControlHandle, GWL_ID);
Info.code := TCN_SELCHANGING;
if SendMessage(GetParent(PageControlHandle), WM_NOTIFY, PageControlHandle, lParam(@Info)) <> 0 then
raise Exception.Create('Page control didn''t allow tab to change.');
if SendMessage(PageControlHandle, TCM_SETCURSEL, TabIndex, 0) = -1 then
raise Exception.Create('Failed to change tab.');
Info.code := TCN_SELCHANGE;
SendMessage(GetParent(PageControlHandle), WM_NOTIFY, PageControlHandle, lParam(@Info))
end;
When I click on tab 1 WinSpy shows that it receives these messages:
<000001> 001D0774 S WM_WINDOWPOSCHANGING lpwp:0018F308
<000002> 001D0774 R WM_WINDOWPOSCHANGING
<000003> 001D0774 S WM_CHILDACTIVATE
<000004> 001D0774 R WM_CHILDACTIVATE
<000005> 001D0774 S WM_WINDOWPOSCHANGED lpwp:0018F308
<000006> 001D0774 R WM_WINDOWPOSCHANGED
<000007> 001D0774 S WM_WINDOWPOSCHANGING lpwp:0018EF7C
<000008> 001D0774 R WM_WINDOWPOSCHANGING
<000009> 001D0774 S WM_NCPAINT hrgn:00000001
<000010> 001D0774 R WM_NCPAINT
<000011> 001D0774 S WM_ERASEBKGND hdc:33011920
<000012> 001D0774 R WM_ERASEBKGND fErased:True
<000013> 001D0774 S WM_WINDOWPOSCHANGED lpwp:0018EF7C
<000014> 001D0774 R WM_WINDOWPOSCHANGED
<000015> 001D0774 P WM_PAINT hdc:00000000
<000016> 001D0774 S WM_CTLCOLORSTATIC hdcStatic:FB01097B hwndStatic:001507D0
<000017> 001D0774 R WM_CTLCOLORSTATIC hBrush:261011F7
<000018> 001D0774 S WM_CTLCOLORSTATIC hdcStatic:FB01097B hwndStatic:001507D0
<000019> 001D0774 R WM_CTLCOLORSTATIC hBrush:261011F7
<000020> 001D0774 S WM_CTLCOLORSTATIC hdcStatic:530112DB hwndStatic:000608C2
<000021> 001D0774 R WM_CTLCOLORSTATIC hBrush:261011F7
<000022> 001D0774 S WM_CTLCOLORSTATIC hdcStatic:530112DB hwndStatic:000608C2
<000023> 001D0774 R WM_CTLCOLORSTATIC hBrush:261011F7
<000024> 001D0774 S WM_DRAWITEM idCtl:395458 lpdis:0018F728
<000025> 001D0774 R WM_DRAWITEM fProcessed:False
<000026> 001D0774 S WM_CTLCOLOREDIT hdcEdit:FB01097B hwndEdit:000808A8
<000027> 001D0774 R WM_CTLCOLOREDIT hBrush:3810149A
<000028> 001D0774 S WM_CTLCOLOREDIT hdcEdit:FB01097B hwndEdit:000808A8
<000029> 001D0774 R WM_CTLCOLOREDIT hBrush:3810149A
<000030> 001D0774 S WM_DRAWITEM idCtl:526504 lpdis:0018F728
<000031> 001D0774 R WM_DRAWITEM fProcessed:False
<000032> 001D0774 S WM_CTLCOLORSTATIC hdcStatic:530112DB hwndStatic:001A06F2
<000033> 001D0774 R WM_CTLCOLORSTATIC hBrush:261011F7
<000034> 001D0774 S WM_CTLCOLORSTATIC hdcStatic:530112DB hwndStatic:001A06F2
<000035> 001D0774 R WM_CTLCOLORSTATIC hBrush:261011F7
Found out that using the TCM_SETCURFOCUS message instead of the TCM_SETCURSEL is enough to change the tab's contents.
procedure ChangeTab(PageControlHandle: HWND; TabIndex: Integer);
begin
SendMessage(PageControlHandle, TCM_SETCURFOCUS, TabIndex, 0);
end;
However this will not work if the page control is in button mode (has the TCS_BUTTONS style), because the buttons can receive focus without changing the contents.