我試圖定義一個三角形的區域并檢查滑鼠是否在其中。我可以使用下面的代碼找到滑鼠是否在某個正方形區域內。我的程式需要檢測三角形或更復雜形狀的滑鼠。
if (Mouse.CursorPos.X < 20) or (50 > tbmn.Left tbmn.Width) or (Mouse.CursorPos.Y < 20) or (Mouse.CursorPos.Y > tbmn.Top 60) then
begin
end;
所以基本上,我想要做的是在螢屏上的任何地方都有一個形狀并檢查滑鼠是否在其中。
有沒有辦法輕松計算螢屏區域并檢測其中是否存在滑鼠?
uj5u.com熱心網友回復:
假設您有一個組件,您在其中繪制了一個三角形,并且只想讓該組件在游標位于形狀的可見部分上方時檢測滑鼠點擊,那么您可以執行以下操作:
在正在繪制的組件上有一個 alpha 層。然后攔截Windows CM_HITTEST 訊息。在命中測驗訊息程序中,您然后檢查 alpha 值是否為 0。如果為 0,則滑鼠位于具有某些可見顏色值的區域上。
Type
TSomeComponent = class(TGraphicControl)
private
FPNG : TGraphic;
procedure CMHitTest(var Message: TCMHitTest); message CM_HITTEST;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Paint; Override;
end;
procedure Register;
implementation
uses
GR32, GR32_Brushes,Winapi.Windows;
procedure TSomeComponent.CMHitTest(var Message: TCMHitTest);
var
colorEntry: TColor32Entry;
bmp : TBitmap32;
begin
bmp := TBitmap32.Create();
try
try
bmp.Assign(FPNG);
colorEntry := TColor32Entry(bmp.Pixels[Message.XPos,Message.YPos]);
if colorEntry.A <> 0 then
Message.Result := HTCLIENT
else
Message.Result := HTNOWHERE;
except
Message.Result := HTCLIENT;
end;
finally
bmp.Free;
end;
end;
uj5u.com熱心網友回復:
您可以使用WinApi 中的區域函式。以下是簡單三角形的示例:
function PtInTriangle(ptX,ptY,X1,Y1,X2,Y2,X3,Y3:integer):Boolean;
var rgn:THandle; pts:array [0..2] of TPoint;
begin
pts[0].X:=X1; pts[0].Y:=Y1;
pts[1].X:=X2; pts[1].Y:=Y2;
pts[2].X:=X3; pts[2].Y:=Y3;
rgn := CreatePolygonRgn( pts[0], 3, WINDING);
Result := PtInRegion(rgn, ptX, ptY);
DeleteObject(rgn);
end;
這個函式在我的機器上需要大約 30..40us,而PtInRegion()只需要大約 10% 的時間(所以,你可以通過快取Region物件來優化它)。以下是帶有簡單基準的代碼:
function PtInTriangle(ptX,ptY,X1,Y1,X2,Y2,X3,Y3:integer):Boolean;
var rgn:THandle; pts:array [0..2] of TPoint;
t,t1,t2,t3:Int64;
begin
// Create region
QueryPerformanceCounter(t);
pts[0].X:=X1; pts[0].Y:=Y1;
pts[1].X:=X2; pts[1].Y:=Y2;
pts[2].X:=X3; pts[2].Y:=Y3;
rgn := CreatePolygonRgn( pts[0], 3, WINDING);
QueryPerformanceCounter(t1); Dec(t1,t);
// Check point
QueryPerformanceCounter(t);
Result := PtInRegion(rgn, ptX, ptY);
QueryPerformanceCounter(t2); Dec(t2,t);
// Delete region
QueryPerformanceCounter(t);
DeleteObject(rgn);
QueryPerformanceCounter(t3); Dec(t3,t);
// Debug output
QueryPerformanceFrequency(t);
OutputDebugString(PChar(Format('All:%d(%.1fus) Create:%d PtInRect:%d(%.1f%%) Delete:%d',
[t1 t2 t3,(t1 t2 t3)/t*1E6,t1,t2,t2*100/(t1 t2 t3),t3])));
end;
此外,您可以使用CreatePolyPolygonRgn()或CombineRgn()創建復雜區域。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/374797.html
標籤:德尔福
上一篇:應用11月補丁后,從在Delphi11上崩潰的EXE檔案獲取版本資訊
下一篇:在PHP中處理php查詢中的空格
