首页 > 代码库 > windows API之控制台界面

windows API之控制台界面

windows API之控制台界面

tkorays (tkorays@hotmail.com)

    在windows里面,用户界面包括控制台(Console)形式的和窗口(Window)形式的。控制台形式的界面我们也是经常接触的,不就是那个黑色的框框吗?但是我们并没有直接使用Windows API,通常我们调用printf来输出、scanf来输入。实际上,这个c语言函数也是通过Windows API来实现的。不信的话,可以打开crtdll.dll查看里面的字符串。

    关于Console的API不是很多,主要包括,获取控制台句柄,控制台输入输出,控制台样式设置。下面逐一介绍:

1) HANDLE WINAPI GetStdHandle(_in_ DWORD nStdHandle);
    根据参数获取句柄。标准输入句柄为STD_INPUT_HANDLE,标准输出句柄为STD_OUTPUT_HANDLE,或者设置为错误句柄STD_ERROR_HANDLE。

2) BOOL WINAPI WriteConsole(
    _in_ HANDLE hConsoleOutput,    // 标准输出句柄
    _in_ const VOID* lpBuffer,        // 输出内容缓冲区指针
    _in_ DWORD nNumberOfCahrsToWrite,  // 缓冲区内容大小
    _out_ LPDWORD lpNumberOfCharsWriten // 实际输出字符数
    LPVOID lpReseverd); // 保留参数,置为NULL即可

3) BOOL WINAPI ReadConsole(
    _in_ HANDLE hConsoleInput, // 标准输入句柄
    _out_ LPVOID lpBuffer, // 保存读入字符的缓冲区指针
    _in DWORD nNumberOfCharsToRead, // 缓冲区大小
    out_ LPDWORD lpNumberOfCharsRead, // 实际读入字符
    _in_opt_ LPVOID pInoutControl // 输入控制在,这是一个指向CONSOLE_READCONSOLE_CONTROL结构体的指针,可置为NULL
);

4) BOOL WINAPI GetConsoleScreenBufferInfo
     _In_   HANDLE hConsoleOutput, // 标准输出句柄
     _Out_  PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo // CONSOLE_SCREEN_BUFFER_INFO结构体指针,用于保存控制台字体颜色等信息,这个可以用来恢复初始设置,即先获取保存控制台信息,在之后修改后还可以通过这个变量来恢复设置
    );
     CONSOLE_SCREEN_BUFFER_INFO结构体定义如下:
    typedef struct _CONSOLE_SCREEN_BUFFER_INFO {
      COORD      dwSize;
      COORD      dwCursorPosition;
      WORD       wAttributes;
      SMALL_RECT srWindow;
      COORD      dwMaximumWindowSize;
     } CONSOLE_SCREEN_BUFFER_INFO;

5) BOOL WINAPI SetConsoleTextAttribute(
    _In_  HANDLE hConsoleOutput, // 标准输出句柄
    _In_  WORD wAttributes // 文字属性的组合,前景色、背景色等
    );
    比如设置前景色红色,颜色加强:
    SetConsoleTextAttribute(hStdout, FOREGROUND_RED | FOREGROUND_INTENSITY)
     注意几种颜色组合会变成其他颜色

6) BOOL WINAPI FillConsoleOutputAttribute(
  _In_   HANDLE hConsoleOutput, // 输出句柄
  _In_   WORD wAttribute, // 颜色
  _In_   DWORD nLength, // 填充单元格数量
  _In_   COORD dwWriteCoord, // 填充坐标
  _Out_  LPDWORD lpNumberOfAttrsWritten // 实际改变情况
);

7) 其他
    GetConsoleTitle/SetConsoleTitle 获取/设置控制台标题
    FillConsoleOutputAttribute 设置文字单元的属性,从Fill一词可以看出,这个是填充效果
    FillConsoleOutputCharacter 填充字符
    SetConsoleCursorPosition 设置光标位置
    获取、设置字体等。

更多用法请参考msdn:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682073%28v=vs.85%29.aspx 


示例:

#include <stdio.h>
#include <Windows.h>

int main(int argc, char** argv){
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE); // 获取输出句柄
HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE); // 获取输入句柄

CONSOLE_SCREEN_BUFFER_INFO backInfo;
GetConsoleScreenBufferInfo(hStdout, &backInfo); // 保存原始信息

DWORD dwSize;

// 设置颜色
WriteConsoleA(hStdout, "I'm tkorays.\n", 13, &dwSize, NULL); // 未设置字体颜色,内容为ASCII编码
SetConsoleTextAttribute(hStdout, FOREGROUND_RED | FOREGROUND_INTENSITY);
WriteConsole(hStdout, L"hello\n", 6, &dwSize, NULL); // 设置颜色后输出,UNICODE编码
SetConsoleTextAttribute(hStdout, FOREGROUND_GREEN | FOREGROUND_INTENSITY);
system("pause"); // 暂停下,看前面的效果


LPWSTR lpChar = (LPWSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 2048);
COORD coord; // 相对坐标
coord.X = 0;
coord.Y = 0;
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(hStdout, &csbi); // 获取此时屏幕缓存
ReadConsoleOutputCharacter(hStdout, lpChar, 2047, coord, &dwSize); // 获取屏幕缓存

// 颜色数组,用于后面设置
WORD wColors[3];
wColors[0] = BACKGROUND_BLUE | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN;
wColors[1] = BACKGROUND_RED | BACKGROUND_GREEN;
wColors[2] = BACKGROUND_GREEN;

// 修改屏幕缓存
DWORD dwLen;
for (size_t i = 0; i < dwSize; i++){
// 屏幕中的小写字母改变样式
if (lpChar[i] >= 'a'&&lpChar[i] <= 'z'){
// 计算字符坐标
coord.Y = i / csbi.dwSize.X;
coord.X = i%csbi.dwSize.X;
WriteConsoleOutputAttribute(hStdout, wColors, 1, coord, &dwLen);
}
}

// 恢复原始字体颜色
SetConsoleTextAttribute(hStdout, backInfo.wAttributes);
return 0;
}

结果:
运行到system("pause");处:


修改小写字母样式后:





windows API之控制台界面