win32, Visual C, 找 Dialog 裡面的 一個 Button 的 Handle |
答題得分者是:aftcast
|
xiaolaba
一般會員 ![]() ![]() 發表:10 回覆:17 積分:5 註冊:2010-05-15 發送簡訊給我 |
問題是這樣的, 俺要寫一個簡單的小工具, 啟動了 Cisco AnyConnect VPN 後, 希望自動登入, 所以要自動按一下那個 按鈕 [connect]. 第一步已經完成了, 用 FindWindow 成功找到了該視窗的 HANDLE. 第二步, 用 FindWindowEx, 希望找到那個按鈕 Connect 的 Handle, 結果不成功. 所以做了一下試驗, 用 Visual Studio 2012 提供 Spy , 直接提取該 BUTTON 的 HANDLE, 然後在俺的程式碼裡面直接套用那的 HANDLE, 結果表明可以成功模擬按了一下 Connect 一樣. 試驗碼如下, [code cpp] H_WndVpnUi = FindWindow (NULL, _T("Cisco AnyConnect Secure Mobility Client")); hButton = FindWindowEx(H_WndVpnUi, NULL, _T("Button"),_T("Connect")); // MG, always NULL SendMessage(hButton, BM_CLICK, 0, 0); //NG SendMessage(0x008C0F60, BM_CLICK, 0, 0); // it works [/code] 畫面大概附圖如下, 所以想請教, 如何找到一個在 Dialog 裡面的 Button 的 HANDLE. 謝謝 俺用的是 C, 不是 C , 參考以下這個建立的, http://www.codeproject.com/Articles/227831/A-dialog-based-Win-C-program
------
http://xiaolaba.wordpress.com |
aftcast
站務副站長 ![]() ![]() ![]() ![]() ![]() 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
你好,你很久會出現一次,而且每次問的都是古董技術比較多喔。 現在又用 win32sdk + c 刻windows… 真有你的。
你的程式應該沒問題,我個人判斷,可能出錯的原因先排除: 1/ spy 進去後,要進步的去看該button的「屬程偵測」中的視窗確定他的 父視窗 真的是你說的那個嗎? 它可能是別的panel或什麼windows上面的唷。 2/ 假始父視窗真的是找的那個,那就要再確認一下 Connect 這字的前後有沒有空白,或者試 不要加 _T( ) 。 ok,這第二點出錯機率是小一點,但還是提醒一下可能性。 以上先確定一下再說囉! ===================引 用 xiaolaba 文 章=================== 問題是這樣的, 俺要寫一個簡單的小工具, 啟動了 Cisco AnyConnect VPN 後, 希望自動登入, 所以要自動按一下那個 按鈕 [connect]. 第一步已經完成了, 用 FindWindow 成功找到了該視窗的 HANDLE. 第二步, 用 FindWindowEx, 希望找到那個按鈕 Connect 的 Handle, 結果不成功. 所以做了一下試驗, 用 Visual Studio 2012 提供 Spy , 直接提取該 BUTTON 的 HANDLE, 然後在俺的程式碼裡面直接套用那的 HANDLE, 結果表明可以成功模擬按了一下 Connect 一樣. 試驗碼如下, [code cpp] H_WndVpnUi = FindWindow (NULL, _T("Cisco AnyConnect Secure Mobility Client")); hButton = FindWindowEx(H_WndVpnUi, NULL, _T("Button"),_T("Connect")); // MG, always NULL SendMessage(hButton, BM_CLICK, 0, 0); //NG SendMessage(0x008C0F60, BM_CLICK, 0, 0); // it works [/code] 畫面大概附圖如下, 所以想請教, 如何找到一個在 Dialog 裡面的 Button 的 HANDLE. 謝謝 俺用的是 C, 不是 C , 參考以下這個建立的, http://www.codeproject.com/Articles/227831/A-dialog-based-Win-C-program
------
蕭沖 --All ideas are worthless unless implemented-- C++ Builder Delphi Taiwan G+ 社群 http://bit.ly/cbtaiwan |
xiaolaba
一般會員 ![]() ![]() 發表:10 回覆:17 積分:5 註冊:2010-05-15 發送簡訊給我 |
大大你好, 俺不是編程序為業, 所以也只會用抄來的修改修改. win32 已經知道超過10年, 當時就時看 win32asm 教學的. 算是win98/win32api 的編程基礎來源. 當然也學到皮毛而已, 例如 FindWindow 和 FindWindowA 的分別, 有點認識. 只是要實作一些東西, 真的要花點時間, 因為很久才要做點小工具, 所以不會知道最新的發展.
所以先在看起來 win32sdk c, 本來就很像 win32asm, 學習速度或是觀念不用轉變很多, 只是對win32api 並不熟悉. 現在大大的建議, 是不是要把每一層的 window handle 找出來, 然後傳遞到下一個 findwindowEx, 才能夠找到更底層的 BUTTON HANDLE 呢 ? 另外, 俺其實完全不明白 _T( ) 的原理, 只是搜尋網頁看到說遇到亂碼就加加看, 結果真的有用, 因此每個 UNICODE 的程序就直接用了, 因為不懂她的除錯技巧, 所以只能慢慢試驗. 謝謝你的指點. ===================引 用 aftcast 文 章=================== 你好,你很久會出現一次,而且每次問的都是古董技術比較多喔。 現在又用 win32sdk c 刻windows… 真有你的。 你的程式應該沒問題,我個人判斷,可能出錯的原因先排除: 1/ spy 進去後,要進步的去看該button的「屬程偵測」中的視窗確定他的 父視窗 真的是你說的那個嗎? 它可能是別的panel或什麼windows上面的唷。 2/ 假始父視窗真的是找的那個,那就要再確認一下 Connect 這字的前後有沒有空白,或者試 不要加 _T( ) 。 ok,這第二點出錯機率是小一點,但還是提醒一下可能性。 以上先確定一下再說囉! ===================引 用 xiaolaba 文 章=================== 問題是這樣的, 俺要寫一個簡單的小工具, 啟動了 Cisco AnyConnect VPN 後, 希望自動登入, 所以要自動按一下那個 按鈕 [connect]. 第一步已經完成了, 用 FindWindow 成功找到了該視窗的 HANDLE. 第二步, 用 FindWindowEx, 希望找到那個按鈕 Connect 的 Handle, 結果不成功. 所以做了一下試驗, 用 Visual Studio 2012 提供 Spy , 直接提取該 BUTTON 的 HANDLE, 然後在俺的程式碼裡面直接套用那的 HANDLE, 結果表明可以成功模擬按了一下 Connect 一樣. 試驗碼如下, [code cpp] H_WndVpnUi = FindWindow (NULL, _T("Cisco AnyConnect Secure Mobility Client")); hButton = FindWindowEx(H_WndVpnUi, NULL, _T("Button"),_T("Connect")); // MG, always NULL SendMessage(hButton, BM_CLICK, 0, 0); //NG SendMessage(0x008C0F60, BM_CLICK, 0, 0); // it works [/code] 畫面大概附圖如下, 所以想請教, 如何找到一個在 Dialog 裡面的 Button 的 HANDLE. 謝謝 俺用的是 C, 不是 C , 參考以下這個建立的, http://www.codeproject.com/Articles/227831/A-dialog-based-Win-C-program
------
http://xiaolaba.wordpress.com |
aftcast
站務副站長 ![]() ![]() ![]() ![]() ![]() 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
剛好有一點時間,我直接給你解答好了。 應該是可以的,不行再回報!
HANDLE hButton = 0; // need to init to 0 BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) { wchar_t buff[256] = {0}; GetWindowText(hwnd,buff, 255); //int nCtrlID = ::GetDlgCtrlID(hwnd); if (wcscmp(_T("Connect"),buff) == 0) { hButton = hwnd; return false; } return true; } H_WndVpnUi = FindWindow (NULL, _T("Cisco AnyConnect Secure Mobility Client")); ::EnumChildWindows(H_WndVpnUi ,EnumWindowsProc, 0); if(hButton) SendMessage(hButton, BM_CLICK, 0, 0);
------
蕭沖 --All ideas are worthless unless implemented-- C++ Builder Delphi Taiwan G+ 社群 http://bit.ly/cbtaiwan |
xiaolaba
一般會員 ![]() ![]() 發表:10 回覆:17 積分:5 註冊:2010-05-15 發送簡訊給我 |
謝謝你.
俺按照你的提示, 用原始的方法, 把所有的 窗口都找了一次, 用 FindWondw 和 FindWondwEx (配合 Spyxxx, Spy 不行看, 原因不明) 終於找到了. 期間還遇到3個同樣是 Edit, 但沒有 CAPTION 的, 只有一個是輸入密碼需要用到, 分辨它們還花了一點時間使用 FindWondwEx 結論是, 必須手工地一層一層像剝洋蔥的實行. 這樣俺對 WINDOWS 的編程又加了一點親自驗證過的知識. 因為還沒有消化好以下這個 CALLBACK 的用法, 還在實驗當中. ===================引 用 aftcast 文 章=================== 剛好有一點時間,我直接給你解答好了。 應該是可以的,不行再回報! HANDLE hButton = 0; // need to init to 0 BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) { wchar_t buff[256] = {0}; GetWindowText(hwnd,buff, 255); //int nCtrlID = ::GetDlgCtrlID(hwnd); if (wcscmp(_T("Connect"),buff) == 0) { hButton = hwnd; return false; } return true; } H_WndVpnUi = FindWindow (NULL, _T("Cisco AnyConnect Secure Mobility Client")); ::EnumChildWindows(H_WndVpnUi ,EnumWindowsProc, 0); if(hButton) SendMessage(hButton, BM_CLICK, 0, 0);
------
http://xiaolaba.wordpress.com
編輯記錄
xiaolaba 重新編輯於 2014-07-22 10:11:00, 註解 無‧
|
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |