如何获取TStatusPanel(StatusBar-Delphi)的索引?
例如,我试图在如何获取TStatusPanel(StatusBar-Delphi)的索引?,delphi,statusbar,Delphi,Statusbar,例如,我试图在ondblick事件中获取TStatusPanel(一个TStatusBar面板)的索引,以便将其与ShowMessage()一起使用,但我不知道如何获取索引 我知道像OnDrawPanel这样的事件有一个Panel:TStatusPanel参数,但我在OnDblClick中需要相同的东西,但只有一个参数,发送方:TObject 例如,如果StatusBar.Panel=1,则没有类似于的命令。我可以使用StatusBar.Panels[0]但是我不知道如何比较单击的索引来显示我的
ondblick
事件中获取TStatusPanel
(一个TStatusBar
面板)的索引,以便将其与ShowMessage()
一起使用,但我不知道如何获取索引
我知道像OnDrawPanel
这样的事件有一个Panel:TStatusPanel
参数,但我在OnDblClick
中需要相同的东西,但只有一个参数,发送方:TObject
例如,如果StatusBar.Panel=1,则没有类似于的命令。我可以使用StatusBar.Panels[0]
但是我不知道如何比较单击的索引来显示我的消息
好吧,这就是我需要的简单方法:
if StatusBar.Panel = 0 then
showmessage('0')
else if StatusBar.Panel = 1 then
showmessage('1');
我知道上面的代码不起作用,它只是一个例子。应该是这样的:
if StatusBar.Panels[0].'SOMETHING' = 0 then
showmessage('0')
else if StatusBar.Panels[0].'SOMETHING' = 1 then
showmessage('1');
您可以在OnDblClick
事件处理程序中使用GetMessagePos
,在检索触发双击处理程序并转换为客户端坐标的WM_lbuttondblck
消息时获取鼠标位置。然后,您可以在状态栏的面板上迭代,以找到鼠标所在的部分。例如:
procedure TForm1.StatusBar1DblClick(Sender: TObject);
var
Pt: TPoint;
i, w: Integer;
begin
Pt := SmallPointToPoint(TSmallPoint(DWORD(GetMessagePos)));
MapWindowPoints(HWND_DESKTOP, StatusBar1.Handle, Pt, 1);
w := 0;
for i := 0 to StatusBar1.Panels.Count - 1 do begin
w := w + StatusBar1.Panels[i].Width;
if Pt.X < w then begin
ShowMessage(IntToStr(i));
Break;
end;
end;
end;
几乎相同的逻辑,但它从状态栏获取实际的面板边界。换句话说,如果单击面板之间的分隔符,它将返回-1
uses
Winapi.CommCtrl;
procedure TForm1.StatusBar1DblClick(Sender: TObject);
var
LClickPos: TPoint;
LIndex: Integer;
function GetPanelIndex: Integer;
var
I: Integer;
LRect: TRect;
begin
for I := 0 to StatusBar1.Panels.Count - 1 do
begin
if SendMessage(StatusBar1.Handle, SB_GETRECT, I, LPARAM(@LRect)) <> 0 then
begin
if PtInRect(LRect, LClickPos) then
Exit(I);
end;
end;
Result := -1;
end;
begin
LClickPos := SmallPointToPoint(TSmallPoint(GetMessagePos()));
LClickPos := StatusBar1.ScreenToClient(LClickPos);
LIndex := GetPanelIndex;
Application.MessageBox(PChar(Format('Panel %d', [LIndex])), 'Test');
end;
使用
Winapi.CommCtrl;
程序TForm1.StatusBar1DblClick(发送方:ToObject);
变量
立法会十题:TPoint ;;
LIndex:整数;
函数GetPanelIndex:整数;
变量
I:整数;
LRect:TRect;
开始
对于I:=0到StatusBar1.Panels.Count-1 do
开始
如果SendMessage(StatusBar1.Handle、SB_GETRECT、I、LPARAM(@LRect))为0,则
开始
如果PtInRect(LRect,LClickPos),则
出口(I);
结束;
结束;
结果:=-1;
结束;
开始
LClickPos:=SmallPointToPoint(TSmallPoint(GetMessagePos());
LClickPos:=StatusBar1.ScreenToClient(LClickPos);
LIndex:=GetPanelIndex;
Application.MessageBox(PChar(格式('Panel%d',[LIndex]),'Test');
结束;
我建议使用而不是。这样,您就减少了向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;
使用
…,Winapi.CommCtrl;
函数GetStatusPanelAt(StatusBar:TStatusBar;X,Y:Integer):TStatusPanel;超载;
函数GetStatusPanelAt(StatusBar:TStatusBar;const P:TPoint):TStatusPanel;超载;
...
函数GetStatusPanelAt(StatusBar:TStatusBar;X,Y:Integer):TStatusPanel;
开始
结果:=GetStatusPanelAt(状态栏,点(X,Y));
结束;
函数GetStatusPanelAt(StatusBar:TStatusBar;const P:TPoint):TStatusPanel;
变量
索引:整数;
arr:整数数组;
小组:TStatusPanel;
开始
结果:=无;
如果不是PtInRect(StatusBar.ClientRect,P),则
出口
SetLength(arr,SendMessage(StatusBar.Handle,SB_GETPARTS,0,0));
SendMessage(StatusBar.Handle、SB_GETPARTS、Length(arr)、lpram(PInteger(arr));
指数:=0;
而索引 如果(P.X我使用这个解决方案,它对我有效。简单明了
首先,为状态栏的OnMouseDown事件编写一个处理程序
procedure TfrmMain.StatusBarMouseDown(Sender: TObject; Button: TMouseButton; Shift:
TShiftState; X, Y: Integer);
begin
TComponent(Sender).Tag := X;
end;
procedure TfrmMain.StatusBarDblClick(Sender: TObject);
var
AccumelatedWidth, i : Integer;
begin
AccumelatedWidth := 0;
for i := 0 to StatusBar.Panels.Count - 1 do
begin
AccumelatedWidth := AccumelatedWidth + StatusBar.Panels[i].Width;
if StatusBar.Tag < AccumelatedWidth then
begin
ShowMessage ('You clicked panel ' + i.ToString);
Break;
end;
end;
end;
然后为状态栏的OnDoublClick事件编写一个处理程序
procedure TfrmMain.StatusBarMouseDown(Sender: TObject; Button: TMouseButton; Shift:
TShiftState; X, Y: Integer);
begin
TComponent(Sender).Tag := X;
end;
procedure TfrmMain.StatusBarDblClick(Sender: TObject);
var
AccumelatedWidth, i : Integer;
begin
AccumelatedWidth := 0;
for i := 0 to StatusBar.Panels.Count - 1 do
begin
AccumelatedWidth := AccumelatedWidth + StatusBar.Panels[i].Width;
if StatusBar.Tag < AccumelatedWidth then
begin
ShowMessage ('You clicked panel ' + i.ToString);
Break;
end;
end;
end;
过程TfrmMain.StatusBarDblClick(发送方:ToObject);
变量
累计宽度,i:整数;
开始
累计宽度:=0;
对于i:=0到StatusBar.Panels.Count-1 do
开始
AccumelatedWidth:=AccumelatedWidth+状态栏。面板[i]。宽度;
如果StatusBar.Tag
给GetMessagePos打电话,找出点击了哪个面板。谢谢你的回答,但状态栏是可调整大小的,GetMessagePos返回不同的位置。你对某人更准确,但后来放弃了对GetCursorPos的准确性。使用GetMessagePosThanks非常重要,它固定在GetMessagePosUsed上并且在我的“小故障”桌面终端上工作得很好…谢谢!
procedure TfrmMain.StatusBarMouseDown(Sender: TObject; Button: TMouseButton; Shift:
TShiftState; X, Y: Integer);
begin
TComponent(Sender).Tag := X;
end;
procedure TfrmMain.StatusBarDblClick(Sender: TObject);
var
AccumelatedWidth, i : Integer;
begin
AccumelatedWidth := 0;
for i := 0 to StatusBar.Panels.Count - 1 do
begin
AccumelatedWidth := AccumelatedWidth + StatusBar.Panels[i].Width;
if StatusBar.Tag < AccumelatedWidth then
begin
ShowMessage ('You clicked panel ' + i.ToString);
Break;
end;
end;
end;