-
Jon © (25.05.09 15:31) [0]I am experiencing a problem using TabControl. Here is a minimum program to demonstrate the bug:
program TabTest;
uses KOL;
var TabControl: PControl;
procedure btnCloseClick(Dummy: Pointer; Sender: PObj);
begin
TabControl.TC_Delete(TabControl.CurIndex);
TabControl.CurIndex := 0; // <--- Error!
end;
procedure btnNewClick(Dummy: Pointer; Sender: PObj);
var
TabPage: PControl;
begin
TabPage := TabControl.TC_Insert(TabControl.Count,Int2Str(TabControl.Count),0);
with NewButton(TabPage,'Close')^ do
OnClick := TOnEvent(MakeMethod(nil,@btnCloseClick));
TabControl.CurIndex := TabControl.Count -1;
end;
begin
Applet := NewForm(nil,'TabTest').SetSize(320,240);
TabControl := NewTabControl(Applet,[''],[],nil,0).SetAlign(caClient);
with NewButton(TabControl.Pages[0],'New')^ do
OnClick := TOnEvent(MakeMethod(nil,@btnNewClick));
Run(Applet);
end.
A runtime error occurs in the tab close procedure and is marked above.
Using Windows XP SP3, KOL 2.88, Delphi 7. No conditional defines, tried with PAS_VERSION too. Can anyone confirm? -
Galkov (10.06.09 23:04) [1]Владимир, есть такая фигня...
В своей "правленной" версии я обнаружил отличие в TControl.SetCurIndex, и отсутствие баги (AV при удалении последнего таба)
У меня это выглядит так:{$IFDEF ASM_VERSION}
//[procedure TControl.SetCurIndex]
procedure TControl.SetCurIndex(const Value: Integer);
asm
MOVZX ECX, [EAX].fCommandActions.aSetCurrent
JECXZ @@set_item_sel
PUSH ECX //+aSetCurrent
PUSH EAX //+self
PUSH 0
PUSH EDX
PUSH ECX
PUSH EAX
CALL Perform
POP EDX //+self
POP ECX //+aSetCurrent
CMP CX, TCM_SETCURSEL
JNE @@exit
MOV [EDX].fCurIndex,EAX
PUSH TCN_SELCHANGE // NMHdr.code
PUSH EDX // NMHdr.idfrom - doesn't matter
PUSH [EDX].fHandle // NMHdr.hwndFrom
PUSH ESP
PUSH 0
PUSH WM_NOTIFY
PUSH EDX
CALL Perform
ADD ESP,12 //NMHdr destroy
@@exit:
RET
@@set_item_sel:
INC ECX
CALL SetItemSelected
end;
{$ELSE ASM_VERSION} //Pascal
procedure TControl.SetCurIndex(const Value: Integer);
var NMHdr: TNMHdr; idx:integer;
begin
if fCommandActions.aSetCurrent <> 0 then
begin
idx := Perform( fCommandActions.aSetCurrent, Value, 0 );
if fCommandActions.aSetCurrent = TCM_SETCURSEL then begin
fCurIndex := idx;
NMHdr.code := TCN_SELCHANGE;
NMHdr.hwndFrom := fHandle;
Perform( WM_NOTIFY, 0, Integer( @NMHdr ) );
end;
end else
ItemSelected[ Value ] := True;
end;
{$ENDIF ASM_VERSION}
когда правил, и по какому поводу - не помню уже.... -
D[u]fa (11.06.09 11:12) [2]Сталкивался с такой проблемой.. просто перед удалением делал TabControl.CurIndex := 0;
Но лучше ипользовать фикс