我設計了一個程式,打開兩個圍棋軟體,自動走棋。用SetForegroundWindow函式把其中一個視窗置頂,然后模擬滑鼠按鍵,自動在某個位置落子。程式在win XP和32位Win7系統都能運行,在64位Windows就有問題了,比如“弈城圍棋”,SetForegroundWindow函式能把弈城視窗置頂,但沒有激活,因此滑鼠動作也執行不了。
請問:在64位Windows系統,SetForegroundWindow函式該怎么用?是要補充一些代碼還是要用另外的函式?請大師提供幫助。
另:BringWindowToTop,SetActiveWindow等函式都試過,無效。網上也查過很多資料,沒找到有效的Delphi解決方案。
我附一段網上比較多見的帖子,但本人笨拙,實在看不懂。
HWND hWnd = ::FindWindow(_T("#32770"),_T(“test”));
if(hWnd)
{
HWND hForeWnd = ::GetForegroundWindow();
DWORD dwForeID = ::GetWindowThreadProcessId(hForeWnd,NULL);
DWORD dwCurID = ::GetCurrentThreadId();
::AttachThreadInput(dwCurID,dwForeID,TRUE);
::ShowWindow(hWnd,SW_SHOWNORMAL);
::SetWindowPos(hWnd,HWND_TOPMOST,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE);
::SetWindowPos(hWnd,HWND_NOTOPMOST,0,0,0,0, SWP_NOSIZE|SWP_NOMOVE);
::SetForegroundWindow(hWnd);
::AttachThreadInput(dwCurID,dwForeID,FALSE);
return 0;
}
uj5u.com熱心網友回復:
api,delphi也是可以一樣的使用uj5u.com熱心網友回復:
不清楚32位和64位下有什么區別,俺也沒有64位系統測驗uj5u.com熱心網友回復:
那可以幫我把上面的這段代碼改寫成Delphi格式嗎?HWND hWnd = ::FindWindow(_T("#32770"),_T(“test”));
if(hWnd)
{
HWND hForeWnd = ::GetForegroundWindow();
DWORD dwForeID = ::GetWindowThreadProcessId(hForeWnd,NULL);
DWORD dwCurID = ::GetCurrentThreadId();
::AttachThreadInput(dwCurID,dwForeID,TRUE);
::ShowWindow(hWnd,SW_SHOWNORMAL);
::SetWindowPos(hWnd,HWND_TOPMOST,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE);
::SetWindowPos(hWnd,HWND_NOTOPMOST,0,0,0,0, SWP_NOSIZE|SWP_NOMOVE);
::SetForegroundWindow(hWnd);
::AttachThreadInput(dwCurID,dwForeID,FALSE);
return 0;
}
uj5u.com熱心網友回復:
var
hw, hForeWnd: HWND;
dwForeID, dwCurID: DWORD;
begin
....
hw := FindWindow('#32770', 'test');
if (hw > 0) then
begin
dwForeID := GetWindowThreadProcessId(hForeWnd, nil);
dwCurID := GetCurrentThreadId;
ShowWindow(hw, SW_SHOWNORMAL);
SetWindowPos(hw, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE or SWP_NOMOVE);
SetWindowPos(hw, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE or SWP_NOMOVE);
SetForegroundWindow(hw);
AttachThreadInput(dwCurID, dwForeID, False);
Result := 0;
Exit;
end;
....
end;
uj5u.com熱心網友回復:
上面這些代碼必須是在某個函式之內,不然沒有 Resultuj5u.com熱心網友回復:
SetForegroundWindow(hd0);現在發現這個函式可以把視窗置頂并激活,但執行 t:=SetCursorPos(500,500);時,發現有些視窗T的值為true,有些視窗T的回傳值為false?
我用銀星圍棋和弈城圍棋兩個界面進行測驗,銀星圍棋T的回傳值為true;弈城圍棋t的回傳值為falsh,是SetCursorPos用得不對嗎?
uj5u.com熱心網友回復:
不認識那些銀星圍棋和弈城圍棋, 各種軟體對UI、繪圖等都可能有各自的處理方式,用api對它們控制不一定都有效,取決了那些軟體的作業方式,得弄清楚它們的作業原理然后針對性地處理。uj5u.com熱心網友回復:
發現這個論壇越來越冷清了。期待你的出現,天色已黃昏。是不是64位windows系統里弈城圍棋的視窗Style與普通視窗不同,因此導致SetCursorPos函式實效?
uj5u.com熱心網友回復:
如果你連AttachThreadInput函式也試過了,仍然解決不了。那么,我建議你在64位作業系統下,先令視窗最小化,再恢復,這樣它必然是當前視窗了。以此來代替SetForegroundWindow。一個最小化函式,一個還原視窗函式。好久沒有用delphi了,記不清最小化是什么函式了,但還原視窗是用openicon函式。uj5u.com熱心網友回復:
我現在發現問題出在SetCursorPos,而不是SetForegroundWindow
uj5u.com熱心網友回復:
幸好Windows為我們提供了AttachThreadInput,它可以將一個執行緒的輸入處理機制貼附到另一個執行緒。這樣我們就有了下面的代碼:// 獲取創建前臺視窗的執行緒
DWORD dwThread = GetWindowThreadProcessId(GetForegroundWindow(), NULL);
// 將前臺視窗執行緒貼附到當前執行緒(也就是程式A中的呼叫執行緒)
AttachThreadInput(dwThread, GetCurrentThreadId(), TRUE);
// 獲取焦點視窗句柄
HWND hFocus = GetFocus();
// 解除貼附
AttachThreadInput(dwThread, GetCurrentThreadId(), FALSE);
// 發送訊息
PostMessage(hFocus, WM_KEYDOWN, VK_TAB, 0);
......
uj5u.com熱心網友回復:
64位原則上,可以運行32位程式,但是如果程式涉及到硬體的(引數)讀寫的API,方式就不一樣了,特別是匯編方式取資料,壓根就不行,造成運行不了或死機。如果要合你的程式在64位上運行,最好的辦法,就是使用64位Delphi編譯,比如XE。上述代碼都是呼叫API,你無法改變,只有改變編譯環境。升級使用XE,一定成功。
uj5u.com熱心網友回復:
SetForegroundWindow印象中確實在64位代碼中失效,它會讓視窗在狀態行上閃,并不能讓它到前臺來剛查了一下以前的代碼,需要在這個之前執行
SetWindowPos兩次,一次用HWND_TOPMOST引數,另一次用HWND_NOTOPMOST引數,
然后再用SetForegroundWindow
這個方法應該是32位和64位暈到死中都有效
uj5u.com熱心網友回復:
好,謝謝,我試試。
uj5u.com熱心網友回復:
試試:ShowWindow(pHwnd,SW_RESTORE);
BringWindowToTop(pHwnd);
在Win8 64位,D6中編譯,可以使后面的表單在前面顯示。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/114668.html
上一篇:開發一個專案,用什么技術?
