1. 编写控制台程序,获得标准输入输出的窗口句柄
GetStdHandle
HANDLE GetStdHandle(
DWORD nStdHandle
);
GetStdHandle()返回标准的输入、输出或错误的设备的句柄,也就是获得输入、输出 /错误的屏幕缓冲区的句柄。
其参数nStdHandle的值为下面几种类型的一种:
STD_INPUT_HANDLE 标准输入的句柄
STD_OUTPUT_HANDLE 标准输出的句柄
STD_ERROR_HANDLE 标准错误的句柄
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来改变程序的宿主控制台,这个时候再用前两种方法就不够好了。尽管载入的代码很长,但是通用性更高。
2. SetConsoleTextAttribute是设置控制台字体颜色和背景色。
BOOL SetConsoleTextAttribute(
HANDLE hConsoleOutput, // 使用GetStdHandle取得的句柄
WORD wAttributes // 设置文本、背景色
);
wAttributes可以取下面的值
FOREGROUND_BLUE Text color contains blue.
FOREGROUND_GREEN Text color contains green.
FOREGROUND_RED Text color contains red.
FOREGROUND_INTENSITY Text color is intensified.
BACKGROUND_BLUE Background color contains blue.
BACKGROUND_GREEN Background color contains green.
BACKGROUND_RED Background color contains red.
BACKGROUND_INTENSITY Background color is intensified.
COMMON_LVB_LEADING_BYTE Leading byte.
COMMON_LVB_TRAILING_BYTE Trailing byte.
COMMON_LVB_GRID_HORIZONTAL Top horizontal.
COMMON_LVB_GRID_LVERTICAL Left vertical.
COMMON_LVB_GRID_RVERTICAL Right vertical.
COMMON_LVB_REVERSE_VIDEO Reverse foreground and background attributes.
COMMON_LVB_UNDERSCORE Underscore.
3. CONSOLE_CURSOR_INFO用于存放控制光标信息
typedef struct _CONSOLE_CURSOR_INFO {
DWORD dwSize;
BOOL bVisible;
} CONSOLE_CURSOR_INFO, *PCONSOLE_CURSOR_INFO;
dwSize:光标大小,1-100的值
bVisible:光标是否可见
4. SetConsoleCursorInfo设置光标的信息
BOOL SetConsoleCursorInfo(
HANDLE hConsoleOutput, // 使用GetStdHandle取得的句柄
CONST CONSOLE_CURSOR_INFO *lpConsoleCursorInfo // 光标信息
);
5. _CONSOLE_SCREEN_BUFFER_INFO: contains information about a console screen buffer
typedef struct _CONSOLE_SCREEN_BUFFER_INFO {
COORD dwSize; // Size, in character columns and rows, of the screen buffer.
COORD dwCursorPosition; // 当前光标在屏幕的位置
WORD wAttributes; // 控制台相当于显示屏的坐标,左上和右下的坐标
SMALL_RECT srWindow; // 字符背景属性,同SetConsoleTextAttribute
COORD dwMaximumWindowSize; // 控制台窗口的大小
} CONSOLE_SCREEN_BUFFER_INFO ;
6. GetConsoleScreenBufferInfo取得控制台屏幕信息
BOOL GetConsoleScreenBufferInfo(
HANDLE hConsoleOutput, // GetStdHandle取得的句柄
PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo // screen buffer information
);
7. SetConsoleCursorPosition设置光标位置
BOOL SetConsoleCursorPosition(
HANDLE hConsoleOutput, // handle to screen buffer
COORD dwCursorPosition // new cursor coordinates
);
8. WriteConsoleOutput直接写输入缓冲区。可以写入键盘、鼠标等任何Console能够接收的事件(Event)都可以写进去。键盘操作如果是一些可显示字符可以直接写 ASCII字符,否则的话可能要用键盘扫描码(scan code)了
BOOL WriteConsoleOutput(
HANDLE hConsoleOutput, // handle to screen buffer
CONST CHAR_INFO *lpBuffer, // data buffer
COORD dwBufferSize, // size of data buffer
COORD dwBufferCoord, // cell coordinates
PSMALL_RECT lpWriteRegion // rectangle to write
);
9. SetConsoleTitle设置控制台的标题
BOOL SetConsoleTitle(
LPCTSTR lpConsoleTitle // new console title
);