2016-03-07 51 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; 
相關問題