Board index » delphi » TPageControl bug in D4 - still in D6?

TPageControl bug in D4 - still in D6?

Everytime I have to deal with TPageControl in Delphi 4 it seems I find a bug.
This one is easy to reproduce.

Create a new application.
Put a TPageControl on Form1 and set DockSite = True for the TPageControl.
Add two pages (TTabsheets). Create a second form (Form2), set Visible = True,
DragKind = dkDock and DragMode = dmAutomatic.
Create a button on Form1 with the following code:

procedure TForm1.Button1Click(Sender: TObject);
begin
  TabSheet1.TabVisible := False;
end;

Where Tabsheet1 is the first page on the TPageControl.
Run the project.
Dock Form2 on the TPageControl;
Click the button.
Now you cannot undock Form2 anymore.

I have traced the bug down to this function in the ComCtrls unit:

function TPageControl.GetDockClientFromMousePos(MousePos: TPoint): TControl;
var
  HitIndex: Integer;
  HitTestInfo: TTCHitTestInfo;
  Page: TTabSheet;
begin
  Result := nil;
  if DockSite then
  begin
    HitTestInfo.pt := MousePos;
    HitIndex := SendMessage(Handle, TCM_HITTEST, 0, Longint(@HitTestInfo));
    if HitIndex >= 0 then
    begin
      Page := Pages[HitIndex];
      if not Page.TabVisible then Page := FindNextPage(Page, True, True);
      if (Page <> nil) and (Page.ControlCount > 0) then
      begin
        Result := Page.Controls[0];
        if Result.HostDockSite <> Self then Result := nil;
      end;
    end;
  end;
end;

This function obviously maps the HitIndex to the wrong TTabsheet,
if one of the pages with an index < HitIndex is not visible (TabVisible = False),
since the TCM_HITTEST message returns an index into the visible pages.
Has this bug been fixed in D6?

It can be fixed by the following code:

function TPageControl.GetDockClientFromMousePos(MousePos: TPoint): TControl;
var
  HitIndex, PageIndex, VisibleIndex: Integer;
  HitTestInfo: TTCHitTestInfo;
  Page: TTabSheet;
begin
  Result := nil;
  if DockSite then
  begin
    HitTestInfo.pt := MousePos;
    HitIndex := SendMessage(Handle, TCM_HITTEST, 0, Longint(@HitTestInfo));
    if HitIndex >= 0 then
    begin
      VisibleIndex := -1;
      for PageIndex := 0 to PageCount - 1 do
      begin
        Page := Pages[PageIndex];
        if Page.TabVisible then Inc(VisibleIndex);
        if VisibleIndex = HitIndex then
        begin
          if Page.ControlCount > 0 then
          begin
            Result := Page.Controls[0];
            if Result.HostDockSite <> Self then Result := nil;
          end;
          Break;
        end;
      end;
    end;
  end;
end;

Karl

 

Re:TPageControl bug in D4 - still in D6?


Quote
In article <3bf1cd76$1_1@dnews>, Karl Waclawek wrote:
> Everytime I have to deal with TPageControl in Delphi 4 it seems I find a bug.
> This one is easy to reproduce.

-snip-

Has been fixed in D6.

Peter Below (TeamB)  100113.1...@compuserve.com)
No e-mail responses, please, unless explicitly requested!
Note: I'm unable to visit the newsgroups every day at the moment,
so be patient if you don't get a reply immediately.

Re:TPageControl bug in D4 - still in D6?


"Peter Below (TeamB)" <100113.1...@compuXXserve.com> wrote in message
news:VA.00007d5f.0112adfc@antispam.compuserve.com...

Quote
> In article <3bf1cd76$1_1@dnews>, Karl Waclawek wrote:
> > Everytime I have to deal with TPageControl in Delphi 4 it seems I find a bug.
> > This one is easy to reproduce.

> -snip-

> Has been fixed in D6.

Thanks.
More reasons to get my boss to upgrade.

Karl

Other Threads