我试图使用WinAPI更改另一应用程序窗口中的页面控件中的选项卡。如何在TCM_SETCURSEL消息后更新选项卡的内容
我发送了一个TCM_SETCURSEL消息给页面控件,它确实改变了标签,但没有改变标签的内容。例如:Pagecontrol位于选项卡0上,我向页面控件发送一个TCM_SETCURSEL索引:1,页面控件现在位于选项卡1上,但继续显示选项卡0的内容而不是选项卡1的内容。
我曾尝试:
- 发送WM_PAINT到标签1 TCM_SETCURSEL后。
- 发送WM_NCPAINT到TCM_SETCURSEL后面的选项卡1。
- 在TCM_SETCURSEL和WM_NOTIFY + TCN_SELCHANGE之后发送WM_NOTIFY + TCN_SELCHANGING到页面控制之后。
- 对页面控件的父项做上述操作。
我使用的是delphi 2010,目标应用程序也是delphi应用程序。
这是最后的代码迭代,这将通知发送到页面控件的父:
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;
当我点击选项卡1 WinSpy表明,它接收到这些信息:
<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
如果您正在窥探PageControl窗口本身,您将看不到WM_NOTIFY消息,因为它们不是直接发送到PageControl窗口,而是发送到其父窗口。然而,'CN_NOTIFY'消息直接发送到PageControl窗口,但Spy ++不明白这些消息,因为它们是VCL特定的(但只要你没有过滤它们,Spy ++仍然会显示它们被接收到)。 –