DBCheckBox1: TDBCheckBox;procedure TForm1.DBCheckBox1Click(Sender: TObject);
begin
DBCheckBox1.Checked:=not DBCheckBox1.Checked;//DBCheckBox1状态不变化
end;procedure TForm1.DBCheckBox1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
DBCheckBox1.Checked:=not DBCheckBox1.Checked;//正常
end;
代码都一样结果为什么不一样?在click里写先是出错,要不就不变化,在mouseup里就正常,为什么?使用它要注意什么?
begin
DBCheckBox1.Checked:=not DBCheckBox1.Checked;//DBCheckBox1状态不变化
end;procedure TForm1.DBCheckBox1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
DBCheckBox1.Checked:=not DBCheckBox1.Checked;//正常
end;
代码都一样结果为什么不一样?在click里写先是出错,要不就不变化,在mouseup里就正常,为什么?使用它要注意什么?
你可以根据要求选用合适的事件处理。
而此时你又在CheckBox的Click事件中改变了Check的值,
所以CheckBox的Click事件实际上对在CheckBox的在Check值做了
两次反转,这样的结果就是“DBCheckBox1状态不变化”
而此时你又在CheckBox的Click事件中改变了Checked的值,
所以CheckBox的Click事件实际上对CheckBox的Checked值做了
两次反转,这样的结果就是“DBCheckBox1状态不变化”
这一句在写在onmouseup里正常,如果改用在onclick里就不行了
不是同时用
你要把checkbox請空嗎使它處於無選擇狀態嗎?
在click里写當然要出错了.因為在click中你要寫判斷是否在選擇狀態還是沒有.
不是CheckBox,TDBCheckBox也没有从TCheckBox继承
我直接放DBCheckBox在窗体上的话,单击DBCheckBox只是变灰又还原
不知道为什么
procedure TForm1.DBCheckBox1Click(Sender: TObject);
begin
DBCheckBox1.Checked:=not DBCheckBox1.Checked;//DBCheckBox1状态不变化
end;
看一下源代码吧,tdbcheckbox继承自tcustomcheckbox继承自tcontrol
onclick与onmouseup都来自wm_buttonup的消息处理。
从消息处理函数来看,先触发的是onclick后是onmouseup
procedure TControl.WMLButtonUp(var Message: TWMLButtonUp);
begin
inherited;
if csCaptureMouse in ControlStyle then MouseCapture := False;
if csClicked in ControlState then
begin
Exclude(FControlState, csClicked);
if PtInRect(ClientRect, SmallPointToPoint(Message.Pos)) then Click;//触发click
end;
DoMouseUp(Message, mbLeft);//触发mouseup
end;procedure TControl.Click;
begin
{ Call OnClick if assigned and not equal to associated action's OnExecute.
If associated action's OnExecute assigned then call it, otherwise, call
OnClick. }
if Assigned(FOnClick) and (Action <> nil) and (@FOnClick <> @Action.OnExecute) then
FOnClick(Self)
else if not (csDesigning in ComponentState) and (ActionLink <> nil) then
ActionLink.Execute(Self)
else if Assigned(FOnClick) then
FOnClick(Self);
end;procedure TControl.MouseUp(Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if Assigned(FOnMouseUp) then FOnMouseUp(Self, Button, Shift, X, Y);
end;可以看出两个触发事件之间并没做其他处理。
疑惑中
明天我再看看
另外我需要解释一下,一个click事件,是鼠标的一次down跟up的结合。
对于DBCheckBox来说,一个down以后,就马上改变状态,所以前面有人说的
两次翻转状态,是正确的。
问题恰恰出在TCustomCheckBox上,一个很不让人注意的地方--FState的赋值函数中(如下)。从中可以看到当ClicksDisabled不是False时,又触发了OnClick事件。就是说每次改变Checked的值时都会触发OnClick事件(不知算不算BUG)而不会触发OnMouseUp事件。procedure TCustomCheckBox.SetState(Value: TCheckBoxState);
begin
if FState <> Value then
begin
FState := Value;
if HandleAllocated then
SendMessage(Handle, BM_SETCHECK, Integer(FState), 0);
if not ClicksDisabled then Click;//触发OnClick事件
end;
end;
在checkbox的onclick事件中加入如下代码
checkbox1.Checked:=not checkbox1.Checked;
点击后程序陷入死循环直至报错:堆栈溢出(estackoverflow with message 'stack overflow')
在dbcheckbox中设置datasource为ADOTable及field(一Bool型字段)属性,adotable连接并Active,在onclick事件中加入同样代码
dbcheckbox1.Checked:=not dbcheckbox1.Checked;
程序启动后直接死循环直至报错:堆栈溢出(estackoverflow with message 'stack overflow')测试环境:WindowsXP+Delphi6.0 enterprise