나는 SB_GETPARTS
대신 SB_GETRECT
의를 사용하는 것이 좋습니다 것입니다. 그런 식으로, 당신은 TStatusBar
에 적은 메시지를 보내는 :
이
uses
..., Winapi.CommCtrl;
function GetStatusPanelAt(StatusBar: TStatusBar; X, Y: Integer): TStatusPanel; overload;
function GetStatusPanelAt(StatusBar: TStatusBar; const P: TPoint): TStatusPanel; overload;
...
function GetStatusPanelAt(StatusBar: TStatusBar; X, Y: Integer): TStatusPanel;
begin
Result := GetStatusPanelAt(StatusBar, Point(X, Y));
end;
function GetStatusPanelAt(StatusBar: TStatusBar; const P: TPoint): TStatusPanel;
var
index: Integer;
arr: array of Integer;
Panel: TStatusPanel;
begin
Result := nil;
if not PtInRect(StatusBar.ClientRect, P) then
Exit;
SetLength(arr, SendMessage(StatusBar.Handle, SB_GETPARTS, 0, 0));
SendMessage(StatusBar.Handle, SB_GETPARTS, Length(arr), LPARAM(PInteger(arr)));
index := 0;
while index < Length(arr) do
begin
if (P.X <= arr[index]) or (arr[index] = -1) then
begin
Result := StatusBar.Panels[index];
Exit;
end;
Inc(index);
end;
end;
그럼 당신은이 작업을 수행 할 수 있습니다
이
uses
..., System.Types, Winapi.Windows;
procedure TForm5.StatusBar1DblClick(Sender: TObject);
var
Pt: TPoint;
Panel: TStatusPanel;
begin
Pt := SmallPointToPoint(TSmallPoint(GetMessagePos()));
Pt := StatusBar1.ScreenToClient(Pt);
Panel := GetStatusPanelAt(StatusBar1, Pt);
if Panel <> nil then
ShowMessage('Click on Panel ' + IntToStr(Panel.Index))
else
ShowMessage('No click on a Panel');
end;
Alternativly, 당신은 D2006 이상을 사용하는 경우, 당신은 클래스로 논리를 포장 할 수 있습니다 대신 도우미 :
uses
..., Winapi.CommCtrl;
type
TStatusBarHelper = class helper for TStatusBar
public
function GetPanelAt(X, Y: Integer): TStatusPanel; overload;
function GetPanelAt(const P: TPoint): TStatusPanel; overload;
end;
...
function TStatusBarHelper.GetPanelAt(X, Y: Integer): TStatusPanel;
begin
Result := GetPanelAt(Point(X, Y));
end;
function TStatusBarHelper.GetPanelAt(const P: TPoint): TStatusPanel;
var
index: Integer;
arr: array of Integer;
Panel: TStatusPanel;
begin
Result := nil;
if not PtInRect(Self.ClientRect, P) then
Exit;
SetLength(arr, SendMessage(Self.Handle, SB_GETPARTS, 0, 0));
SendMessage(Self.Handle, SB_GETPARTS, Length(arr), LPARAM(PInteger(arr)));
index := 0;
while index < Length(arr) do
begin
if (P.X <= arr[index]) or (arr[index] = -1) then
begin
Result := Self.Panels[index];
Exit;
end;
Inc(index);
end;
end;
uses
..., System.Types, Winapi.Windows;
procedure TForm5.StatusBar1DblClick(Sender: TObject);
var
Pt: TPoint;
Panel: TStatusPanel;
begin
Pt := SmallPointToPoint(TSmallPoint(GetMessagePos()));
Pt := StatusBar1.ScreenToClient(Pt);
Panel := StatusBar1.GetPanelAt(Pt);
if Panel <> nil then
ShowMessage('Click on Panel ' + IntToStr(Panel.Index))
else
ShowMessage('No click on a Panel');
end;
,
GetMessagePos를 호출하여 어떤 패널을 클릭했는지 확인합니다. –
David Heffernan, 답변 주셔서 감사합니다.하지만 StatusBar는 크기를 조정할 수있는 형식이므로 GetMessagePos는 다른 위치를 반환합니다. – SisMaster
그래서 뭐. 패널 위치를 알아야합니다. 그리고 당신이 속한 운동을 찾으십시오. –