2012-02-17 82 views
0

我在想如何實現水平(或垂直)捕捉鼠標光標到一行。例如,在Facebook時間軸功能上,將鼠標懸停在中心線上時,會將光標對準中心。將鼠標靠近線條也會捕捉它。將鼠標光標對準Delphi自定義控件中的一行

我想包裹在一個自定義控件的內部,而不是一個窗體的控件。將會有一條垂直線或水平線,並且它必須在鼠標光標靠近時將它捕捉到它。我將添加返回被點擊的行的位置的事件。此控件還會有一個垂直或水平滾動條,與此行平行,並且兩個滾動條不會同時顯示。有一個主屬性是否顯示此行垂直水平

鼠標實際上不應該移動位置,但只是將光標的顯示調整爲顯示它位於該行的中心,而實際的X(或Y)位置從不改變。我不想移動光標,我想顯示光標在這行的中心,如果它接近任何地方。當光標處於此捕捉位置時,它將顯示另一個自定義光標,而不是標準(或默認)箭頭。

我只需要知道的是如何在此控件中處理鼠標指針在此行附近的事件,並將光標的顯示調整爲位於此行的中心。

+0

儘管聽起來很愚蠢,但爲了防止任何人想要爲我演示這個功能而建立一個控制外殼,請提前通知我,以便我知道要等待它。否則,我仍然接受任何有關如何處理此問題的建議。 – 2012-02-17 02:03:03

+0

我沒有投票你,但我很困惑這個問題。標題說「捕捉鼠標光標」,但文字說「鼠標實際上不應該移動位置,但應該調整光標的顯示」。你是什​​麼意思光標不應該移動,但它應該移動?我是唯一一個發現這種矛盾的人嗎?我只是看了一下Facebook的時間表,我不明白。圖片? – 2012-02-19 03:55:37

+0

@WarrenP X,Y位置(用戶指向鼠標的位置)永遠不會改變,但光標顯示位置的視圖會改變。因此,對於檢查,你可以指向60,100,但它顯示在55,100,並指向它50,100也顯示在55,100。 – 2012-02-19 12:32:44

回答

5

貼緊需要你拍下東西

  • AutoCAD中的「光標」,實際上是水平和垂直線相交,其中「光標」是
  • Photoshop使用Windows的鼠標,但卡的效果來指引
  • Facebook的卡一點點+標誌,以一個點在時間軸上

你需要跟蹤鼠標的位置(即OnMouseMove)如果光標是「足夠接近」然後你可以決定做什麼。

這裏有一個小示例程序,其中我有一個從左邊150px的假想垂直線。如果我得到足夠接近該線,一點點的Facebook +出現:

enter image description here

const 
    centerLine = 150; //"line" is at 150px from the left 
    tolerance = 15; //15px on either size is about good. 

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); 
begin 
    if IsMouseNearLine(x, y) then 
    begin 
     //We're on the centerline-ish. React by... 
     //...changing the cursor to a <-> 
     Self.Cursor := crSizeWE; 

     //and maybe let's put a "+" there, like Facebook 
     if (FPlusLabel = nil) then 
     begin 
      FPlusLabel := TLabel.Create(Self); 
      FPlusLabel.Parent := Self; 
      FPlusLabel.Caption := '+'; 
      FPlusLabel.Alignment := taCenter; 
      FPlusLabel.Font.Color := $00996600; //Windows UX "Main Instruction" color 
      FPlusLabel.Font.Style := FPlusLabel.Font.Style + [fsBold]; 
     end; 

     FPlusLabel.Left := centerLine-(FPlusLabel.Width div 2); 
     FPlusLabel.Top := Y-(FPlusLabel.Height div 2); 
     FPlusLabel.Visible := True; 
    end 
    else 
    begin 
     Self.Cursor := crDefault; 
     if Assigned(FPlusLabel) then 
      FPlusLabel.Visible := False; 
    end; 
end; 

function TForm1.IsMouseNearLine(X, Y: Integer): Boolean; 
begin 
    if (x >= (centerLine-tolerance)) and (x <= (centerLine+tolerance)) then 
    begin 
     //we're close-ish to the line 
     Result := true; 
    end 
    else 
     Result := False; 
end; 

事情開始變得毛茸茸的,當你有其他控件,每個需要與MouseMove消息一起玩。但它也不是如果您將它們全部轉發給單個處理程序,那麼它也不好用;在執行之前執行客戶端到屏幕到客戶端的客戶端。

注意:任何代碼被釋放到公共領域。無需歸屬。

+0

謝謝,除了我要求將其包裝在自己的自定義控件中(需要完全不同的方法),並且我還需要有關如何顯示光標而不是識別其位置的更多幫助。另外,我看到你正在創建'FPlusLabel',但我沒有看到它在哪裏被釋放... – 2012-02-17 16:20:18

+0

你的孩子控制需要它坐在窗體上的幫助。當鼠標實際上不在表單上時,它不會獲取「MouseMove」或「Click」事件。你不需要釋放'FPlusLabel';當* owner *被釋放時它被釋放。 ('FPlusLabel:= TLabel.Create(theOwner);')。或者你可以把它寫成代碼示例,儘可能地省略代碼以儘可能保持答案的清晰。標籤的文字顏色也不符合用戶的顏色偏好。 – 2012-02-17 16:46:05

1

我能看到的最簡單的方法是讓與它自己的光標屬性TPaintBox控制,使您隱藏內置的窗口的光標,你老闆在其「啪」位置上繪製的「+」符號。

鼠標指針永遠不會真正移動,但當真正的鼠標指針位於TPaintBox的控件邊界內時,它會被所有者繪製的光標圖像「替換」。

相關問題