如何通过点击窗口(点击窗口)来选择窗口(可以是任何其他应用程序的窗口),将窗口的句柄传递给Delphi鼠标就可以了。在我的Delphi应用程序中,我可以有一个用户点击的按钮,启动这个检测过程,以及一个标签,显示在Delphi应用程序中点击窗口标题。当用户满意时,他选择了正确的窗口,他可以点击我的Delphi应用程序中的按钮(这将是模式),以停止选择过程,让我的应用程序开始做另一个窗口它需要做什么...如何通过鼠标点击将另一个应用程序的窗口句柄传递给Delphi
回答
如果你知道是在窗口的标题是什么文字,这段代码就可以了你:
var
WindowList: TList;
function GetHandle (windowtitle: string): HWND;
var
h, TopWindow: HWND;
Dest: array[0..80] of char;
i: integer;
s: string;
function getWindows(Handle: HWND; Info: Pointer): BOOL; stdcall;
begin
Result:= True;
WindowList.Add(Pointer(Handle));
end;
begin
result:= 0;
try
WindowList:= TList.Create;
TopWindow:= Application.Handle;
EnumWindows(@getWindows, Longint(@TopWindow));
i:= 0;
while (i < WindowList.Count) and (result = 0) do
begin
GetWindowText(HWND(WindowList[i]), Dest, sizeof(Dest) - 1);
s:= dest;
if length(s) > 0 then
begin
if (Pos(UpperCase(Windowtitle), UpperCase(s)) >= 1) then
begin
h:= HWND(WindowList[i]);
if IsWindow(h) then
result:= h
end
end;
inc(i)
end
finally
WindowList.Free;
end;
end;
使用在你的榜样(记事本把在窗口标题打开的文件的名称):
h:= getHandle('text.txt');
if (h = 0)
// Oops not found
else
begin
// you got the handle!
end;
我用这段代码来检查我的应用程序是否是alrea加入并运行。但它可以用于任何启动的应用程序。
谢谢,我现在可以通过让用户通过使用ShellExecute procudre在我的应用程序中打开文件来使用它吗?我会通过扫描标题来获得处理? – georgelappies 2011-04-10 08:34:31
是的,这是主意。 – ToonVo 2011-04-10 11:11:10
编辑:它不见了,但你曾经可以通过delphipages.com的Eddie Shipman下载Delphi Window Spy,它已经变成了一堆无用的linkbait。
评论中概述的用户STATUS_ACCESS_DENIED可能是最简单的方法。我建议使用鼠标捕捉来挂钩,因为它实现起来更简单。
这里是什么是参与一个稍微详细的大纲:
首先要改变这种选择过程的工作方式。而不是让用户单击应用程序上的按钮来启动该过程,然后单击目标窗口,最后再次单击以确认;如果用户单击应用程序上的特定区域,然后将拖动到目标窗口,然后在目标上放开鼠标按钮,实现起来会更容易。这是因为窗户认为点击另一个应用程序属于该应用程序,并且您必须做额外的工作才能截取它。但是,有一种简单的方法 - 称为鼠标捕获 - 以获取有关拖动/释放的信息,如果它以您自己的应用程序上的点击开始。
这也是Windows SDK Spy ++工具使用的方法;所以通过这样做,你也可以与一个着名的工具保持一致。 (Pic of Spy ++ here - 注意对话框中的十字线查找工具 - 这就是你点击并拖动到目标的地方。如果你以前没有这样做,强烈建议下载Windows SDK并使用这个工具;这也是一个非常棒的看到如何其他应用程序的有效方式是这样构造的大作为Windows API的学习工具)
涉及的步骤:
- 有一定的控制在你的应用程序,响应鼠标按下事件(在Win32中WM_LBUTTONDOWN/C,OnMouseDown在delphi中)。您可能需要在此处绘制十字线图标或类似图标,以便用户知道点击的位置。
- 当您将鼠标放下时,使用SetCapture'捕捉'鼠标。这意味着控件将在鼠标移动时接收所有鼠标消息 - 直到用户释放按钮 - 即使它移出控件。
- 设置的图标看起来像一个十字线,使用户知道他们在拖曳模式
- 当用户移动鼠标时,你会得到WM_MOUSEMOVE消息(的OnMouseMove在Delphi)具有指针坐标。您需要使用ClientToScreen将它们转换为屏幕坐标,然后使用WindowFromPoint在该点查找窗口。 (请注意,此时可以找到最内层的窗口,如果需要,可以使用从桌面窗口开始的ChildWindowFromPoint来获取顶层窗口。)由您决定是否要每隔一段时间更新一次UI鼠标在整个拖动中移动,或者在用户释放鼠标按钮时移动。
- 当用户释放鼠标按钮时,您将得到一个WM_LBUTTONUP/OnMouseUp;在那个阶段,通过调用ReleaseCapture并将光标恢复到正常形状来包装。
请注意,您将在拖动过程中获得鼠标移动事件,并且如果用户恰好将鼠标指针移动到您的控件上,可能正在前往某个其他控件的路上。将这两种情况区分开来的最简单方法是在控件中使用一个标志,当您将鼠标放下时您将设置一个标志,并且在您将鼠标移开时清除,并且只有在设置该标志时才处理鼠标移动事件。
以上描述了您将从C/C++调用的纯Win32 API的过程;但它看起来像Delphi提供了对大多数或全部的直接支持。
编辑:可能Delphi实现:
type
TForm1 = class(TForm)
Label1: TLabel;
procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
procedure FormPaint(Sender: TObject);
procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private
FCacheWnd: HWND;
FCaptured: Boolean;
public
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
const // the first item, the place where the crosshair is
ClickRect: TRect = (Left: 10; Top: 10; Right: 44; Bottom: 44);
procedure TForm1.FormPaint(Sender: TObject);
begin
// draw the control and the crosshair if no capturing
if GetCapture <> Handle then begin
DrawFrameControl(Canvas.Handle, ClickRect, 0, DFCS_BUTTONPUSH);
DrawIcon(Canvas.Handle, ClickRect.Left, ClickRect.Top,
Screen.Cursors[crCross]);
end;
end;
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if (Button = mbLeft) and (Shift = [ssLeft])
and PtInRect(ClickRect, Point(X, Y)) then begin
// the second item, draw the control pressed,
// set the flag and the capture. FCacheWnd is used not to get
// window information for every mouse move - if the window under the
// mouse is not changed.
DrawFrameControl(Canvas.Handle, ClickRect, 0, DFCS_PUSHED);
FCacheWnd := 0;
FCaptured := True;
SetCapture(Handle);
Screen.Cursor := crCross; // the third item, set the cursor to crosshair.
end;
end;
function GetWndFromClientPoint(ClientWnd: HWND; Pt: TPoint): HWND;
begin
MapWindowPoints(ClientWnd, GetDesktopWindow, Pt, 1);
Result := WindowFromPoint(Pt);
end;
function GetWndInfo(Wnd: HWND): string;
var
ClassName: array [0..256] of Char;
begin
Result := '';
if IsWindow(Wnd) then begin
GetClassName(Wnd, ClassName, 256);
Result := Format('Window: %x [%s]', [Wnd, ClassName]);
if (GetWindowLong(Wnd, GWL_STYLE) and WS_CHILD) = WS_CHILD then begin
Wnd := GetAncestor(Wnd, GA_ROOT);
GetClassName(Wnd, ClassName, 256);
Result := Format(Result + sLineBreak + 'Top level: %x [%s]', [Wnd, ClassName]);
end;
end;
end;
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
var
Wnd: HWND;
begin
if FCaptured then begin
// fourth item, convert coordinates and find the window under the cursor
Wnd := GetWndFromClientPoint(Handle, Point(X, Y));
if Wnd <> FCacheWnd then
Label1.Caption := GetWndInfo(Wnd);
FCacheWnd := Wnd;
end;
end;
procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if FCaptured then begin
// fifth item
FCaptured := False;
ReleaseCapture;
InvalidateRect(Handle, @ClickRect, False); // invalidate pressed look
Screen.Cursor := crDefault;
end;
end;
我已经编辑了你的答案,包括一个样本,因为OP说他是Delphi的新手,在他对这个问题的评论中。你.. – 2011-04-10 04:32:16
@塞尔塔克 - 感谢编辑! – BrendanMcK 2011-04-10 04:38:40
非常感谢你,我非常感谢你的努力和巨大的帮助。 – georgelappies 2011-04-10 08:17:45
- 1. 将窗口句柄传递给变量
- 2. 如何将窗口句柄传递给子进程?
- 3. 如何将窗口句柄传递给wndproc?
- 4. 获取点击鼠标按钮的窗口句柄
- 5. 如何获取另一个应用程序的所有窗口的句柄
- 6. 通过C#中的点击获取一个流程窗口句柄。
- 7. 如何通过GWT从入口点传递给另一个入口点?
- 8. 可能有一个窗口,鼠标点击通过它?
- 9. 如何将DXGI共享资源的句柄传递给另一个进程?
- 10. 检索Delphi窗口句柄
- 11. 在另一个Delphi应用程序中嵌入Delphi窗口
- 12. C++ winapi通过鼠标点击子窗口到父窗口
- 13. 我该如何构建一个Windows应用程序,该应用程序拦截并将击键和鼠标点击传递给其他应用程序?
- 14. 是否可以将空窗口句柄传递给ShellExecute?
- 15. 如何将变量传递给句柄中的一个部分?
- 16. 如何通过点击NSView通过它下面的应用程序窗口?
- 17. 如何通过TLF文本传递鼠标点击?
- 18. 如何通过应用程序接口将蓝牙套接字传递给另一个活动
- 19. 虚拟鼠标点击被另一个窗口覆盖的窗口
- 20. 将CloudKit应用程序的值传递给另一个用户
- 21. 将鼠标事件传递给Java UI中的应用程序
- 22. 如何通过节点点击将调试标志传递给节点?
- 23. 一个iOS应用程序如何将数据传递给另一个?
- 24. 将消息从一个窗口传递到另一个窗口
- 25. 以编程方式在另一个窗口中单击鼠标
- 26. 给出一个窗口句柄(Native),如何使用C#关闭窗口?
- 27. 如何将参数传递给程序,通过点击按钮激活?
- 28. 将另一个对象传递给主烧瓶应用程序
- 29. 将文件传递给另一个Iphone应用程序
- 30. 是否可以从窗口句柄中设置另一个应用程序的窗口的最大宽度?
鼠标捕获或窗口挂钩,既会工作。取决于你想要它的方式。当鼠标按钮被按下时(例如在窗口上的按钮上),开始捕捉过程,然后在释放按钮时结束鼠标捕捉。在你的应用程序之间会收到有关鼠标位置的信息,所以一个足以找出你悬停的窗口。 – 0xC0000022L 2011-04-09 23:12:21
感谢您的回复,我是delphi的新手,对winapi非常非常非常新,所以如果您能够详细阐述一下代码示例,我会非常感激。 – georgelappies 2011-04-09 23:52:55
-1,@George - 你已经接受了一个不回答问题的答案,而不是其他答案。这表明你想实现的目标与你提出的问题没有多大关系。 – 2011-04-10 13:02:21