Programmingly Setup Console App Property

Programmingly Setup Console App Property

以寫程式的方式改變 console 程式的屬性,例如預設字型、codepage、視窗大小、顏色等等...

#include <stdio.h>
#include <stdarg.h>
 
// only in Win2k+  (use FindWindow for NT4)
HWND WINAPI GetConsoleWindow();
 
// Undocumented console message
#define WM_SETCONSOLEINFO         (WM_USER+201)
 
#pragma pack(push, 1)
 
//
//  Structure to send console via WM_SETCONSOLEINFO
//
typedef struct _CONSOLE_INFO
{
    ULONG      Length;
    COORD      ScreenBufferSize;
    COORD      WindowSize;
    ULONG      WindowPosX;
    ULONG      WindowPosY;
 
    COORD      FontSize;
    ULONG      FontFamily;
    ULONG      FontWeight;
    WCHAR      FaceName[32];
 
    ULONG      CursorSize;
    ULONG      FullScreen;
    ULONG      QuickEdit;
    ULONG      AutoPosition;
    ULONG      InsertMode;
   
    USHORT    ScreenColors;
    USHORT    PopupColors;
    ULONG      HistoryNoDup;
    ULONG      HistoryBufferSize;
    ULONG      NumberOfHistoryBuffers;
   
    COLORREF    ColorTable[16];
 
    ULONG      CodePage;
    HWND        Hwnd;
 
    WCHAR      ConsoleTitle[0x100];
 
} CONSOLE_INFO;
 
#pragma pack(pop)
//
//  Wrapper around WM_SETCONSOLEINFO. We need to create the
//  necessary section (file-mapping) object in the context of the
//  process which owns the console, before posting the message
//
BOOL SetConsoleInfo(HWND hwndConsole, CONSOLE_INFO *pci)
{
    DWORD   dwConsoleOwnerPid;
    HANDLE  hProcess;
    HANDLE  hSection, hDupSection;
    PVOID   ptrView = 0;
    HANDLE  hThread;
   
    //
    //  Open the process which "owns" the console
    // 
    GetWindowThreadProcessId(hwndConsole, &dwConsoleOwnerPid);
   
    hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwConsoleOwnerPid);
 
    //
    // Create a SECTION object backed by page-file, then map a view of
    // this section into the owner process so we can write the contents
    // of the CONSOLE_INFO buffer into it
    //
    hSection = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, pci->Length, 0);
 
    //
    //  Copy our console structure into the section-object
    //
    ptrView = MapViewOfFile(hSection, FILE_MAP_WRITE|FILE_MAP_READ, 0, 0, pci->Length);
 
    memcpy(ptrView, pci, pci->Length);
 
    UnmapViewOfFile(ptrView);
 
    //
    //  Map the memory into owner process
    //
    DuplicateHandle(GetCurrentProcess(), hSection, hProcess, &hDupSection, 0, FALSE, DUPLICATE_SAME_ACCESS);
 
    //  Send console window the "update" message
    SendMessage(hwndConsole, WM_SETCONSOLEINFO, (WPARAM)hDupSection, 0);
 
    //
    // clean up
    //
    hThread = CreateRemoteThread(hProcess, 0, 0, (LPTHREAD_START_ROUTINE)CloseHandle, hDupSection, 0, 0);
 
    CloseHandle(hThread);
    CloseHandle(hSection);
    CloseHandle(hProcess);
 
    return TRUE;
}
 
//
//  Fill the CONSOLE_INFO structure with information
//  about the current console window
//
static void GetConsoleSizeInfo(CONSOLE_INFO *pci)
{
    CONSOLE_SCREEN_BUFFER_INFO csbi;
 
    HANDLE hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE);
 
    GetConsoleScreenBufferInfo(hConsoleOut, &csbi);
 
    pci->ScreenBufferSize = csbi.dwSize;
    pci->WindowSize.X     = csbi.srWindow.Right - csbi.srWindow.Left + 1;
    pci->WindowSize.Y     = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
    pci->WindowPosX       = csbi.srWindow.Left;
    pci->WindowPosY       = csbi.srWindow.Top;
}
 
//
// Set palette of current console
//
//  palette should be of the form:
//
// COLORREF DefaultColors[16] =
// {
//  0x00000000, 0x00800000, 0x00008000, 0x00808000,
//  0x00000080, 0x00800080, 0x00008080, 0x00c0c0c0,
//  0x00808080,   0x00ff0000, 0x0000ff00, 0x00ffff00,
//  0x000000ff, 0x00ff00ff,   0x0000ffff, 0x00ffffff
// };
//
VOID WINAPI SetConsolePalette()
{
    CONSOLE_INFO ci = { sizeof(ci) };
    COLORREF palette[16] =
    {
       0x00000000, 0x00800000, 0x00008000, 0x00808000,
       0x00000080, 0x00800080, 0x00008080, 0x00c0c0c0,
       0x00808080,  0x00ff0000, 0x0000ff00, 0x00ffff00,
       0x000000ff, 0x00ff00ff,  0x0000ffff, 0x00ffffff
    };
    int i;
    HWND hwndConsole = GetConsoleWindow();
 
    // get current size/position settings rather than using defaults..
    GetConsoleSizeInfo(&ci);
 
    // set these to zero to keep current settings
    ci.FontSize.X            = 0;  //8;
    ci.FontSize.Y            = 0;  //12;
    ci.FontFamily            = 0;  //0x30;  //FF_MODERN|FIXED_PITCH;//0x30;
    ci.FontWeight            = 0;  //0x400;
    //lstrcpyW(ci.FaceName, L"Terminal");
    //ci.FaceName[0]         = L'\0';
 
    ci.CursorSize      = 25;
    ci.FullScreen      = FALSE;
    ci.QuickEdit       = TRUE;
    ci.AutoPosition    = 0x10000;
    ci.InsertMode      = TRUE;
    ci.ScreenColors    = MAKEWORD(0x7, 0x0);
    ci.PopupColors     = MAKEWORD(0x5, 0xf);
   
    ci.HistoryNoDup    = FALSE;
    ci.HistoryBufferSize        = 50;
    ci.NumberOfHistoryBuffers   = 4;
    lstrcpyW(ci.FaceName, L"MS Gothic");
    //ci.FaceName      = L"MS Gothic";
 
    // colour table
    for(i = 0; i <16; i++)
        ci.ColorTable[i] = palette[i];
 
    ci.CodePage     = 932;//0x352;
    ci.Hwnd      = hwndConsole;
 
    lstrcpyW(ci.ConsoleTitle, L"");
 
    SetConsoleInfo(hwndConsole, &ci);
}
 
 
void main()
{
    SetConsolePalette();
}

 

Dotblogs 的標籤: