该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
如果有认真阅读,相信以上代码一定不难看懂。
【 VC++ 】 获取控制台窗口的句柄(hWnd)
窗口,都有其唯一的句柄(hWnd)。得到了窗口句柄,能够做很多事情。控制台程序,若能在窗口效果上下文章,那么这个第三方工具将会很成功。
网上给出的常用方法:
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来改变程序的宿主控制台,这个时候再用前两种方法就不够好了。尽管载入的代码很长,但是通用性更高。
打开批处理,唉,左上角的图标还是一个黑黑的框,不免让人感到乏味。万千世界,每个程序运行时的窗体图标都是一个标志,好的标志能让人耳目一新。而命令行程序中,偏偏没有相应的函数能够更改窗体的图标,让人遗憾。经过一段时间的学习,已经掌握了改变命令行窗体图标的方法。本教程将教会你如何在命令行程序中更改窗体图标,让命令行更美观。
首先需要知道SendMessage这个API函数。它的功能很强大,能给窗体发送消息,实现想要的效果。
SendMessage(
HWND hWnd,
UNIT msg,
WPARAM wParam,
LPARAM lParam
)
在本篇教程中,我们要发送的消息,即msg参数,是WM_SETICON消息。字面上理解,就是设置窗体图标。当然,命令行的图标都是小一号的16×16图标,图标的大小只需要在wParam中给上ICON_SMALL参数,就会自动转换。而图标需要用HICON类型作为lParam参数。
获取命令行的hWnd,已经在多篇文章中提到过了,具体请参考:
【 VC++ 】 获取控制台窗口的句柄(hWnd)
那么,现在我们需要从文件中读取出图标,然后放置入HICON类型中,以便SendMessage调用。读取出图标可以用LoadImage这个API函数。
LoadImage(
HINSTANCE,
LPCTSTR,
UNIT,
int,
int,
UNIT
)
第一个参数为程序的实例句柄,我们需要读的是图标文件,因此可以置空。第二个则是图标文件的路径,注意转义符号\,路径中的所有\都得用\\或者/代替。第三个参数指图像类型,IMAGE_ICON常数。第四和第五个参数为图标的大小,全部填0即可。第六个参数为读取方式,LR_LOADFROMFILE常数。当然,这个API函数返回的是HANDLE,我们需要的是HICON,所以还要做强制转换。
示例代码:
从C:\a.ico中读取图标并设置为窗体图标(命令行句柄保存在变量hwnd中)
HICON hIcon;
hIcon=(HICON)LoadImage(NULL,"C:/a.ico",IMAGE_ICON,0,0,LR_LOADFROMFILE);
SendMessage(hwnd,WM_SETICON,ICON_SMALL,(LPARAM)hIcon);
当然,系统中自带了上千个图标,但是这些图标都不是保存在.ico等文件中的,而更多的是保存在.dll或者.exe的资源中。如果能够读取这些资源,就能够使用这些精美的图标了。
读取.dll或者.exe中的资源需要用到ExtractIcon这个API函数。
ExtractIcon(
HINSTANCE hInst,
LPCTSTR lpszExeFileName,
UNIT nIconIndex
)
第一个参数为程序的实例句柄,同样置空即可。第二个参数为文件名,同样需要注意转义符\。第三个参数为资源图标的索引号。
示例代码:
从C:\Windows\System32\NotePad.exe中读取记事本的图标(命令行句柄保存在变量hwnd中)
HICON hIcon;
hIcon=(HICON)ExtractIcon(NULL,"C:/Windows/System32/NotePad.exe",0);
SendMessage(hwnd,WM_SETICON,ICON_SMALL,(LPARAM)hIcon);
现在,命令行窗