在Windows中,句柄是一個系統內部數據結構的引用。
比如當你操作一個窗體。或說是一個Delphi窗體時,系統會給你一個該窗體的句柄,系統會通知你:你正在操作142號窗體。就此你的應用程序就能要求系統對142號窗體進行操作——移動窗體、改變窗體大小、把窗體極小化為圖標等。
實際上很多Windows API函數把句柄作為它的第一個參數,如GDI(圖形設備接口)句柄、菜單句柄、實例句柄、位圖句柄等。不只局限於窗體函數。
換句話說,句柄是一種內部代碼,通過它能引用受系統控制的特殊元素,如窗體、位圖、圖標、內存塊、光標、字體、菜單等。
控制台程序也有窗體句柄。而且他能夠操作其它程序的窗體句柄。
經常用法:
HWND hw=FindWindow("ConsoleWindowClass",NULL);
這不失為一個好方法。可是單從Class方面入手保險度不高。
API函數FindWindow有兩個參數,類名與窗體標題。當不提供窗體標題的時候,返回的句柄為同類窗體中Z序最高的窗體句柄。盡管說運行僅僅是一瞬間。可是保險起見,還是提供下標題窗體,更保險。
char strTitle[255];
GetConsoleTitle(strTitle, 255);
HWND hw=FindWindow("ConsoleWindowClass",strTitle);
當然,假設要精益求精,還有更保險的辦法,用 Kernel32.dll 中部分未發布的API。在用 eXeScope 導出 Kernel32.dll 中控制台相關的API之后。發現有一個名為GetConsoleWindow的API。查找參考了部分資料后。提供例如以下代碼,可以動態加載這個API並獲得窗體句柄。
首先須要全局聲明:
typedef HWND (WINAPI *PROCGETCONSOLEWINDOW)(); PROCGETCONSOLEWINDOW GetConsoleWindow;
然后再Main()函數開頭中輸入下面內容:
HMODULE hKernel32 = GetModuleHandle("kernel32");
GetConsoleWindow = (PROCGETCONSOLEWINDOW)GetProcAddress(hKernel32,"GetConsoleWindow");
完畢了動態加載API函數GetConsoleWindow的任務。須要使用時可例如以下:
HWND cmd=GetConsoleWindow();
個人覺得。使用API函數GetConsoleWindow是最安全,也是最好的方法。
在更大的控制台編程中,可能隨時須要用到AttachConsole來改變程序的宿主控制台,這個時候再用前兩種方法就不夠好了。雖然加載的代碼非常長,可是通用性更高。
