获取控制台窗口的句柄(HWND)和程序中输出回车键
一、獲取窗口句柄基于類名或窗口名稱:?http://support.microsoft.com/kb/124103/zh-cn
Win32 API 提供用于獲取與一個(gè)控制臺(tái)應(yīng)用程序相關(guān)聯(lián)的窗口句柄沒有直接方法。但是,您可以獲得通過調(diào)用 FindWindow() 窗口句柄。此函數(shù)可檢索窗口句柄基于類名或窗口名稱。?
調(diào)用以確定當(dāng)前的控制臺(tái)標(biāo)題 GetConsoleTitle()。然后提供當(dāng)前的控制臺(tái)標(biāo)題,以 FindWindow()。
因?yàn)槎鄠€(gè)窗口可能具有相同的標(biāo)題,您應(yīng)更改當(dāng)前的控制臺(tái)窗口標(biāo)題,以一個(gè)唯一的標(biāo)題。這將有助于防止將返回錯(cuò)誤的窗口句柄。若要更改當(dāng)前的控制臺(tái)窗口標(biāo)題中使用 SetConsoleTitle()。下面是此過程:
生成的 HWND 是不能保證是適用于所有的窗口句柄操作。
示例代碼
下面的函數(shù)檢索當(dāng)前控制臺(tái)應(yīng)用程序窗口句柄 (HWND)。如果此函數(shù)成功,返回值是控制臺(tái)窗口的句柄。如果將失敗函數(shù)返回值為 NULL。某些錯(cuò)誤檢查被省略,為簡(jiǎn)潔起見。 HWND GetConsoleHwnd(void){#define MY_BUFSIZE 1024 // Buffer size for console window titles.HWND hwndFound; // This is what is returned to the caller.char pszNewWindowTitle[MY_BUFSIZE]; // Contains fabricated// WindowTitle.char pszOldWindowTitle[MY_BUFSIZE]; // Contains original// WindowTitle.// Fetch current window title.GetConsoleTitle(pszOldWindowTitle, MY_BUFSIZE);// Format a "unique" NewWindowTitle.wsprintf(pszNewWindowTitle,"%d/%d",GetTickCount(),GetCurrentProcessId());// Change current window title.SetConsoleTitle(pszNewWindowTitle);// Ensure window title has been updated.Sleep(40);// Look for NewWindowTitle.hwndFound=FindWindow(NULL, pszNewWindowTitle);// Restore original window title.SetConsoleTitle(pszOldWindowTitle);return(hwndFound);}
作者:Defanive
博客:Console.Dec.Cn(Hi.Baidu.Com/Console_App)
窗口,都有其唯一的句柄(hWnd)。得到了窗口句柄,能夠做很多事情。控制臺(tái)程序,若能在窗口效果上下文章,那么這個(gè)第三方工具將會(huì)很成功。
網(wǎng)上給出的常用方法:
HWND hw=FindWindow("ConsoleWindowClass",NULL);
這不失為一個(gè)好方法,但是單從Class方面入手保險(xiǎn)度不高。
API函數(shù)FindWindow有兩個(gè)參數(shù),類名與窗口標(biāo)題。當(dāng)不提供窗口標(biāo)題的時(shí)候,返回的句柄為同類窗口中Z序最高的窗口句柄。雖然說執(zhí)行只是一瞬間,但是保險(xiǎn)起見,還是提供下標(biāo)題窗口,更保險(xiǎn)。
char strTitle[255];
GetConsoleTitle(strTitle, 255);
HWND hw=FindWindow("ConsoleWindowClass",strTitle);
當(dāng)然,如果要精益求精,還有更保險(xiǎn)的辦法,用 Kernel32.dll 中部分未公布的API。在用 eXeScope 導(dǎo)出 Kernel32.dll 中控制臺(tái)相關(guān)的API之后,發(fā)現(xiàn)有一個(gè)名為GetConsoleWindow的API。查找參考了部分資料后,提供如下代碼,能夠動(dòng)態(tài)載入這個(gè)API并獲得窗口句柄。
首先需要全局聲明:
typedef HWND (WINAPI *PROCGETCONSOLEWINDOW)();
PROCGETCONSOLEWINDOW GetConsoleWindow;
然后再M(fèi)ain()函數(shù)開頭中輸入以下內(nèi)容:
HMODULE hKernel32 = GetModuleHandle("kernel32");
GetConsoleWindow = (PROCGETCONSOLEWINDOW)GetProcAddress(hKernel32,"GetConsoleWindow");
完成了動(dòng)態(tài)載入API函數(shù)GetConsoleWindow的任務(wù)。需要使用時(shí)可如下:
HWND cmd=GetConsoleWindow();
個(gè)人認(rèn)為,使用API函數(shù)GetConsoleWindow是最安全,也是最好的方法。在更大的控制臺(tái)編程中,可能隨時(shí)需要用到AttachConsole來改變程序的宿主控制臺(tái),這個(gè)時(shí)候再用前兩種方法就不夠好了。盡管載入的代碼很長(zhǎng),但是通用性更高。
三、控制臺(tái)中使用程序輸出回車鍵
(1):
?INPUT key[1] = {0};
? key[0].type = INPUT_KEYBOARD;
? key[0].ki.wVk = VK_RETURN;
? key[0].ki.dwFlags = 0;
? key[0].ki.time = 0;
? key[0].ki.wScan = 0;//VK_RETURN;
? key[0].ki.dwExtraInfo = 0;
? SendInput(1, key, sizeof(key));
(2):
keybd_event(0xd,0,0,0);
? ?(3):
? ?獲取控制臺(tái)的句柄(HWND)后,可以使用這個(gè)句柄,向控制臺(tái)發(fā)送Enter鍵的ASCLL消息。
??SendMessage(hwndFound,WM_CHAR,0x0d,0);
其中方法(1)(2),可能會(huì)影響到其他的應(yīng)用程序,方法(3)驗(yàn)證沒有出現(xiàn)影響其它應(yīng)用程序的現(xiàn)象。
總結(jié)
以上是生活随笔為你收集整理的获取控制台窗口的句柄(HWND)和程序中输出回车键的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: GetCurrentProcessID、
- 下一篇: 使用wcstok_s函数分割路径, 创建