如何通過點擊窗口(點擊窗口)來選擇窗口(可以是任何其他應用程序的窗口),將窗口的句柄傳遞給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. 如何獲取另一個應用程序的所有窗口的句柄
- 7. 通過C#中的點擊獲取一個流程窗口句柄。
- 8. 檢索Delphi窗口句柄
- 9. 如何通過GWT從入口點傳遞給另一個入口點?
- 10. 如何將DXGI共享資源的句柄傳遞給另一個進程?
- 11. 可能有一個窗口,鼠標點擊通過它?
- 12. 在另一個Delphi應用程序中嵌入Delphi窗口
- 13. 如何將customer_id從一個窗口傳遞給另一個窗口?
- 14. C++ winapi通過鼠標點擊子窗口到父窗口
- 15. 我該如何構建一個Windows應用程序,該應用程序攔截並將擊鍵和鼠標點擊傳遞給其他應用程序?
- 16. 是否可以將空窗口句柄傳遞給ShellExecute?
- 17. 共享鼠標點擊的按鍵事件通過窗口(或手柄)
- 18. 如何將變量傳遞給句柄中的一個部分?
- 19. 如何通過點擊NSView通過它下面的應用程序窗口?
- 20. 從另一個應用程序窗口獲取專注控制的句柄
- 21. 如何通過TLF文本傳遞鼠標點擊?
- 22. 如何通過應用程序接口將藍牙套接字傳遞給另一個活動
- 23. 將CloudKit應用程序的值傳遞給另一個用戶
- 24. 將鼠標事件傳遞給Java UI中的應用程序
- 25. 虛擬鼠標點擊被另一個窗口覆蓋的窗口
- 26. Android通過單擊recyclerview將jsonObject傳遞給另一個活動
- 27. Node.js將響應對象句柄的句柄傳遞給子進程
- 28. 通過點擊應用程序窗口獲取進程ID
- 29. 將數據傳遞給Android中的另一個應用程序
- 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