2016-03-07 84 views
2

我有两个TSpeedButtonbtn1btn2。它们的属性被设置为使得它们在一组共同行动和是互斥的,这意味着,当按下一个按钮另一个按钮是自动未按下:如何在TSpeedButton已经关闭的情况下提早退出()?

AllowAllUp = False 
GroupIndex = 1 
OnClick = onSpeedButtonsClick 

我在onSpeedButtonsClick()一些代码,运行取决于一些代码哪个按钮被点击。

我想要做的就是让这个如果btn1目前Down,并且用户按下这个按钮,没有什么应该发生:

procedure frmMyForm.onSpeedButtonsClick(Sender: TObject); 
begin 
    { Don't do anything if the clicked button is already currently pressed down. } 
    if ((Sender = btn1) and btn1.Down) or 
     ((Sender = btn2) and btn2.Down) then 
    Exit(); 

    { ... some other code here that should only run when 
    the `Down` state of the buttons changes } 
end; 

的问题是,当btn1是目前下跌并且用户按btn2Down属性btn2设置为True之前onSpeedButtonsClick()执行,所以它Exit() s不管什么。

+0

不应该你的代码是'if((Sender = btn1)and btn2.D拥有)或...'。在你显示的代码中,你正在检查是否按下了与触发OnClick事件的按钮相同的按钮。 – SilverWarior

+0

@SilverWarior如果一个按钮已经是'Down',并且用户按下这个当前向下的按钮,我想让该例程'Exit()'。如果用户按下了一个当前正在运行的按钮(即未按下),那么我想让'OnClick()'处理程序运行一些代码。 – DBedrenko

+0

用户如何按下一个已经倒下的按钮?遵循由Windows定义的标准按钮点击处理,这应该是不可能的。也许在多点触控环境中。但是,为了能够在第二次按下按钮时不必先按下按钮,将按钮状态更改为“向上”,则不能再进行其他操作。或者我可能错过了一些关于你的设计的重要信息? – SilverWarior

回答

1
在表单字段

只是存储按钮状态,并设置它在这样的事件处理程序结束(我使用的位域)

bState := Ord(btn1.Down) or (Ord(btn2.Down) shl 1); 

检查:

if (bState and 1) <> 0 then 
//it would be nicer to use constants like btn1down = 1 instead of magic numbers 
     btn1 WAS down before 
    if (bState and 2) <> 0 then 
     btn2 WAS down before 
+0

好主意,谢谢!我没有看到在这里需要使用位移,所以我添加了这个表单变量:'FLastSpeedButtonPressed:TObject',我使用'OnClick'处理函数中的Sender来分配。 – DBedrenko

+2

而不是使用不透明的按位逻辑(1和2是什么意思?)你可以定义一个枚举并使用它,再加上一个方法从按钮状态变为 - >枚举结果是按下哪个按钮。我会避免使用布尔位掩码并使用基本语言项 - 它更简单,代码更清晰。 –

+1

当语言提供更多的东西时,使用魔术常量和位扭曲是很奇怪的。 –

2

我会用按钮Tag属性跟踪所需的状态,例如:

procedure frmMyForm.onSpeedButtonsClick(Sender: TObject); 
begin 
    if TSpeedButton(Sender).Tag <> 0 then Exit; 
    TSpeedButton(Sender).Tag := 1; 
    if Sender = btn1 then btn2.Tag := 0 
    else btn1.Tag := 0; 

    // code that runs when the `Down` state changes ... 
end; 
相关问题