请问如何获取鼠标所在位置的控件名称?(50分)

  • 主题发起人 主题发起人 aloze
  • 开始时间 开始时间
A

aloze

Unregistered / Unconfirmed
GUEST, unregistred user!
如题 ,控件是自动生成的
 
如果不是VCL的控件呢?
 
来自:地质灾害, 时间:2008-8-28 9:25:31, ID:3917273
如果不是VCL的控件呢?
--------------------------------那只能写WINDOWS消息控制
 
如果是VCL控件,下面可供参考
function TForm1.GetComponent: TComponent;
var
i: Integer;
TempPoint: TPoint;
begin
GetCursorPos(TempPoint);
for i := 0 to Self.ComponentCount - 1do
begin
with Self.Components, TempPointdo
begin
if (Left <= x) and ((Left + Width) >= x) and (Top <= y) and ((Top + Height) >= y) then
begin
Result := Self.Components;
Break;
end;
end;
end;
end;
 
初学者,请问下何为
----------------------
如果不是VCL的控件呢?
----------------------
指的是第三方控件?还是别的,不太懂...指的是什么?
楼主说:控件是自动生成的
也就是说是在ide用拖拽的方式产生的,肯定会是vcl或者第三方的控件,
deardragon_2002的代码是可行的
 
PWindowInfo = ^TWindowInfo;
TWindowInfo = record
Handle:THandle;
IsVCLWindow:Boolean;
VCLObject:TWinControl;
WndClass:string;
WndText:string;
end;

const
MAX_WND_CLASS = 256;
MAX_WND_TEXT = 1024;
function IsVCLWindow(aWnd:THandle;var aObj:TWinControl):Boolean;
var
sWndAtom,sCtrlAtom:string;
CM_GET_OBJECT:Cardinal;
ThreadID,ProcID:Cardinal;
begin
Result:=False;
ThreadID:=GetWindowThreadProcessId(aWnd,ProcID);
if ThreadID=0 then
Exit;
sWndAtom := Format('Delphi%.8X',[ProcID]);
sCtrlAtom := Format('ControlOfs%.8X%.8X', [HInstance, ThreadID]);
CM_GET_OBJECT := RegisterWindowMessage(PChar(sCtrlAtom));
aObj := Pointer(GetProp(aWnd, MakeIntAtom(GlobalFindAtom(PChar(sCtrlAtom)))));
if (aObj = nil) and (CM_GET_OBJECT<>0) then
aObj:=Pointer(SendMessage(aWnd, CM_GET_OBJECT, 0, 0));
Result:=(aObj<>nil);
if GetCurrentProcessId<>ProcID then
aObj:=nil;
end;

function ClassNameOfWindow(aWnd:THandle):string;
begin
SetLength(Result,MAX_WND_CLASS+1);
SetLength(Result,RealGetWindowClass(aWnd,PAnsiChar(Result),MAX_WND_CLASS+1));
end;

function TextOfWindow(aWnd:THandle):string;
begin
SetLength(Result,MAX_WND_TEXT+1);
SetLength(Result,GetWindowText(aWnd,PAnsiChar(Result),MAX_WND_TEXT+1));
end;

function GetControlAtCursor(var wi:TWindowInfo):Boolean;
var
cur,rel:TPoint;
hChild:THandle;
begin
Result:=GetCursorPos(cur);
if not Result then
Exit;
hChild:=WindowFromPoint(cur);
if hChild=0 then
Exit;
while hChild<>0do
begin
rel:=cur;
ScreenToClient(hChild,rel);
wi.Handle:=hChild;
hChild:=ChildWindowFromPoint(hChild,rel);
if hChild=wi.Handle then
Break;
end;
wi.WndClass:=ClassNameOfWindow(wi.Handle);
wi.WndText:=TextOfWindow(wi.Handle);
wi.IsVCLWindow:=IsVCLWindow(wi.Handle,wi.VCLObject);
end;
 
我用了 deardragon_2002,的方法 ,结果不行,以下是我的代码。
procedure TForm1.btn1Click(Sender: TObject);
var
i: Integer;
begin
scrbox := TScrollBox.Create(self);
scrbox.Color := clWhite;
scrbox.AutoScroll := true;
scrbox.Align := alClient;
scrbox.Parent := Self;
hleft := 10;
ltop := 10;
pHeight := 64;
pwidth := 60;
hangcount := 10;
// 10行
liecount := 16;
//16列
spac := 2;//间隔
for hang := 0 to hangcount - 1do
begin
lie := 0;
for lie := 0 to liecount - 1do
begin
i := lie + hang * hangcount - (hangcount - liecount) * hang;
shp := TShape.Create(self);
with shpdo
begin
Width := pwidth;
Height := pHeight;
shape := stRoundRect;
Left := hleft + (pWidth + spac) * lie;
Top := ltop + (pHeight + spac) * hang;
tag := i;
ShowHint := true;
Brush.Color := $00FFC8C8;
OnClick := N1Click;
//点击事件
Parent := scrbox;
Hint := IntToStr(i);
end;
end;
end;
end;
procedure TForm1.N1Click(Sender: TObject);
var
s: TComponent;
begin
s := GetComponent;
ShowMessage(TShape(s).Name);
ShowMessage(IntToStr(TShape(s).Tag));
TShape(s).Brush.Color := clRed;
end;
 
timer控件
GetCursorPos 获取鼠标位置
WindowFromPoint 获取鼠标位置下句柄

procedure TForm1.Timer1Timer(Sender: TObject);
var lpPoint: TPoint;
hwn:hwnd;
begin

GetCursorPos(lpPoint) ;
hwn:=WindowFromPoint(lpPoint) ;
caption:=IntToStr(hwn)
end;
 
楼上的windowFromPoint只能获得顶层窗口。不能获得子控件。不信试试看。
 
[h1]TO 地质灾害[/h1]
以下代码怎么用?可以再帮帮我?我是新手,不搞懂,deardragon_2002的代码不行,谢谢!
===================================
PWindowInfo = ^TWindowInfo;
TWindowInfo = record
Handle:THandle;
IsVCLWindow:Boolean;
VCLObject:TWinControl;
WndClass:string;
WndText:string;
end;

const
MAX_WND_CLASS = 256;
MAX_WND_TEXT = 1024;
function IsVCLWindow(aWnd:THandle;var aObj:TWinControl):Boolean;
var
sWndAtom,sCtrlAtom:string;
CM_GET_OBJECT:Cardinal;
ThreadID,ProcID:Cardinal;
begin
Result:=False;
ThreadID:=GetWindowThreadProcessId(aWnd,ProcID);
if ThreadID=0 then
Exit;
sWndAtom := Format('Delphi%.8X',[ProcID]);
sCtrlAtom := Format('ControlOfs%.8X%.8X', [HInstance, ThreadID]);
CM_GET_OBJECT := RegisterWindowMessage(PChar(sCtrlAtom));
aObj := Pointer(GetProp(aWnd, MakeIntAtom(GlobalFindAtom(PChar(sCtrlAtom)))));
if (aObj = nil) and (CM_GET_OBJECT<>0) then
aObj:=Pointer(SendMessage(aWnd, CM_GET_OBJECT, 0, 0));
Result:=(aObj<>nil);
if GetCurrentProcessId<>ProcID then
aObj:=nil;
end;

function ClassNameOfWindow(aWnd:THandle):string;
begin
SetLength(Result,MAX_WND_CLASS+1);
SetLength(Result,RealGetWindowClass(aWnd,PAnsiChar(Result),MAX_WND_CLASS+1));
end;

function TextOfWindow(aWnd:THandle):string;
begin
SetLength(Result,MAX_WND_TEXT+1);
SetLength(Result,GetWindowText(aWnd,PAnsiChar(Result),MAX_WND_TEXT+1));
end;

function GetControlAtCursor(var wi:TWindowInfo):Boolean;
var
cur,rel:TPoint;
hChild:THandle;
begin
Result:=GetCursorPos(cur);
if not Result then
Exit;
hChild:=WindowFromPoint(cur);
if hChild=0 then
Exit;
while hChild<>0do
begin
rel:=cur;
ScreenToClient(hChild,rel);
wi.Handle:=hChild;
hChild:=ChildWindowFromPoint(hChild,rel);
if hChild=wi.Handle then
Break;
end;
wi.WndClass:=ClassNameOfWindow(wi.Handle);
wi.WndText:=TextOfWindow(wi.Handle);
wi.IsVCLWindow:=IsVCLWindow(wi.Handle,wi.VCLObject);
end;
 
请联系QQ 283680636。要赚这50分还真是麻烦。
 
程序测试通过的
procedure TForm1.btn2Click(Sender: TObject);
var pt :TPoint;
i:Integer;
begin
//
GetCursorPos(pt) ;
//ShowMessage(IntToStr(pt.X ));
for i := 0 to Self.ComponentCount - 1do
begin
with Self.Components, ptdo
begin
if (Left <= x) and ((Left + Width) >= x) and (Top <= y) and ((Top + Height) >= y) then
begin
ShowMessage( Self.Components.Name);
Break;
end;
end;
end;

end;
procedure TForm1.btn1Click(Sender: TObject);
var btn:tbutton;
begin
btn:=tbutton.Create(self);
btn.Parent :=Self;
btn.Left :=100;
btn.Top :=100;
btn.width:=200;
btn.Left :=30;
btn.Name :='btn2';
btn.Caption :='clickme';
btn.onClick :=self.btn2Click;
end;
 
来自:地质灾害, 时间:2008-8-28 18:06:51, ID:3917446
楼上的windowFromPoint只能获得顶层窗口。不能获得子控件。不信试试看。
我用了一个自动生成在groupbox里面的控件,然后通过WindowFromPoint 好像也获得了这个button的handle值,请不吝赐教,谢谢
procedure TForm1.btn2Click(Sender: TObject);
var pt :TPoint;
hwn:Integer;
text:string;
begin
//
GetCursorPos(pt) ;
hwn:=WindowFromPoint(pt) ;
ShowMessage(IntToStr(hwn));
SetLength (text,255);
GetWindowText(hwn,PChar(text),256);
ShowMessage(PChar(text));
end;
procedure TForm1.btn1Click(Sender: TObject);
var btn:tbutton;
begin
btn:=tbutton.Create(self.grp1 );
btn.Parent :=Self.grp1;
btn.Left :=100;
btn.Top :=100;
btn.width:=200;
btn.Left :=30;
btn.Name :='btn2';
btn.Caption :='clickme';
btn.onClick :=self.btn2Click;
end;
 
结帖了,用地质灾害的方法成功了。
同时了感谢楼上的兄弟们。谢谢了
 
后退
顶部