Link to home
Start Free TrialLog in
Avatar of peterharris
peterharrisFlag for United Kingdom of Great Britain and Northern Ireland

asked on

Selecting page in TPageControl using Windows API

I need to access a particular page in a TPageControl in another application.

I can get the handle of the Remote aps Tpagecontrol and presume that I can use SendMessage to select a particular tab/page but cannot work out how to do it

Can anyone help please?

Peter Harris
Avatar of Lukasz Zielinski
Lukasz Zielinski
Flag of Poland image

const
  TCM_FIRST = $1300;
  TCM_SETCURSEL = TCM_FIRST + 12;

procedure TForm1.Button1Click(Sender: TObject);
var h: THandle;
      pageindex: Integer;
begin
  h := page control handle;
  pageindex := index of page to be selected
  SendMessage(h, TCM_SETCURSEL, pageindex, 0);
end;

ziolko.
Avatar of peterharris

ASKER

Thanks

That selects the tab OK but doesnt update the page control to show the correct page

Peter
try this:

procedure TForm1.Button1Click(Sender: TObject);
var notify: NMHDR;
    hnd: THandle;
    pageindex: Integer;
begin
  hnd :=
  pageindex :=
  notify.hwndFrom := hnd;
  notify.idFrom := 0;
  notify.code := TCN_SELCHANGING;
  SendMessage(hnd, CN_NOTIFY, 0, Integer(@notify));
  SendMessage(hnd, TCM_SETCURSEL, pageindex, 0);
  notify.code := TCN_SELCHANGE;
  SendMessage(hnd, CN_NOTIFY, 0, Integer(@notify));
  SendMessage(hnd, CM_RECREATEWND, 0, 0);

end;

note that CM_RECREATEWND will cause TabControl to alloc new handle, so once you call that routine you HAVE to read TabControl Handle again

ziolko
Sadly that still doesnt work properly
It selects the wrong tab.
When I step through it,  it is fine as far as SendMessage(hnd, TCM_SETCURSEL, pageindex, 0);
and has selected the correct tab.  However it then changes to a different tab after the   SendMessage(hnd, CM_RECREATEWND, 0, 0); line.

I tried it with different values for pageindex and 1 seems to work OK.  The other values all give unpredictable results and sometimes cause an AV error in the target application.

Peter
I seem to have found a solution with a bit of googling

This seems to work:

SendMessage(hnd, TCM_SETCURFOCUS, pageindex,0);
SendMessage(hnd, TCM_SETCURSEL, pageindex, 0);

What do you think?

Peter
ASKER CERTIFIED SOLUTION
Avatar of Lukasz Zielinski
Lukasz Zielinski
Flag of Poland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Shame I can't give points to myself ;-)
did you figure out yourself that you need TCM_SETCURSEL ? ;)

ziolko.
I got the clue from this discussionlist http://www.autohotkey.com/forum/topic10861.html

It doesnt relate exactly to Delphi/WinAPI programming but there was a post that suggested that both calls were needed

I tried the sleep(0) line but i doesnt seem to be necessary.  However I can now do a few more tests and check that this solution is reliable for me

Thanks for the help

Here is the quote fom the Autohotkey list that gave me the clue:

"The method of selecting a specific tab that is mentioned seems to be incomplete unfortunately. On this system (Win XP pro SP2) it seems that a couple calls are necessary to switch to a specific tab. TCM_SETCURSEL will switch to the tab by itself but the contents of the tab won't change. Sending a TCM_SETCURFOCUS message and sleep, 0 first seems to work well in most cases. This method doesn't seem to work when the tab control has TCS_BUTTONS style though so it seems to be necessary to temporarily modify the style. "