許多開發者以為主控台應用程式只能輸出文字。實則不然,Windows 主控台視窗同樣擁有視窗控制代碼,可像 GUI 視窗一樣進行 GDI 繪圖、顯示位圖、處理滑鼠訊息。本文揭示主控台視窗的隱藏能力,並提供完整程式碼示範在主控台顯示 BMP 圖片。
Windows 為每個視窗分配唯一控制代碼。主控台視窗雖由系統建立,但同樣擁有 HWND。關鍵在於取得此控制代碼:
#include
#include
typedef HWND (WINAPI *PROC_GETCONSOLEWINDOW)();
int main() {
HMODULE hKernel32 = GetModuleHandle(TEXT("kernel32"));
PROC_GETCONSOLEWINDOW GetConsoleWindow =
(PROC_GETCONSOLEWINDOW)GetProcAddress(hKernel32, "GetConsoleWindow");
HWND hConsole = GetConsoleWindow(); // 取得主控台視窗 HWND
if (!hConsole) return 1;
// 取得裝置內容 (DC),即可進行 GDI 繪圖
HDC hdc = GetDC(hConsole);
// 範例:畫一個紅色圓
HPEN hPen = CreatePen(PS_SOLID, 2, RGB(255,0,0));
HGDIOBJ oldPen = SelectObject(hdc, hPen);
Ellipse(hdc, 100, 100, 300, 300);
SelectObject(hdc, oldPen);
DeleteObject(hPen);
ReleaseDC(hConsole, hdc);
system("pause");
return 0;
}
#include
#include
typedef HWND (WINAPI *PROC_GETCONSOLEWINDOW)();
int main() {
// 1. 取得主控台 HWND
HMODULE hKernel32 = GetModuleHandle(TEXT("kernel32"));
auto GetConsoleWindow = (PROC_GETCONSOLEWINDOW)GetProcAddress(hKernel32, "GetConsoleWindow");
HWND hConsole = GetConsoleWindow();
if (!hConsole) { printf("GetConsoleWindow failed\n"); return 1; }
// 2. 取得 DC
HDC hdc = GetDC(hConsole);
// 3. 載入位圖 (需將 1.bmp 放在專案執行目錄)
HBITMAP hBitmap = (HBITMAP)LoadImage(
NULL, TEXT("1.bmp"), IMAGE_BITMAP, 0, 0,
LR_LOADFROMFILE | LR_CREATEDIBSECTION
);
if (!hBitmap) { printf("LoadImage failed\n"); ReleaseDC(hConsole, hdc); return 1; }
// 4. 建立相容 DC 並選入位圖
HDC hMemDC = CreateCompatibleDC(hdc);
HGDIOBJ oldBmp = SelectObject(hMemDC, hBitmap);
// 5. 取得位圖尺寸
BITMAP bm;
GetObject(hBitmap, sizeof(bm), &bm);
// 6. 繪製到主控台視窗 (座標 100,100 寬高 300x300)
BitBlt(hdc, 100, 100, 300, 300, hMemDC, 0, 0, SRCCOPY);
// 7. 清理資源
SelectObject(hMemDC, oldBmp);
DeleteDC(hMemDC);
DeleteObject(hBitmap);
ReleaseDC(hConsole, hdc);
printf("圖片已繪製至主控台視窗 (100,100) 處,按任意鍵結束...\n");
getchar();
return 0;
}
取得 HWND/HDC 後,以下 API 皆可使用:
| 功能類別 | API 範例 |
|---|---|
| 系統選單控制 | GetSystemMenu, EnableMenuItem |
| 標準控制代碼 | GetStdHandle (STD_INPUT/OUTPUT/ERROR_HANDLE) |
| 游標/顯示控制 | SetConsoleCursorPosition, SetConsoleDisplayMode (全螢幕) |
| 滾動緩衝區 | ScrollConsoleScreenBuffer |
| 文字/背景顏色 | SetConsoleTextAttribute, FillConsoleOutputAttribute |
| 滑鼠/鍵盤輸入 | ReadConsoleInput, GetConsoleMode (啟用 ENABLE_MOUSE_INPUT) |
| 模擬輸入 | mouse_event, keybd_event / SendInput |
| GDI 繪圖 | LineTo, Rectangle, TextOut, BitBlt, StretchBlt 等所有 GDI 函數 |
SetConsoleWindowInfo 調整緩衝區大小。ReleaseDC。BitBlt)。打破「主控台只能文字」的迷思,善用 GetConsoleWindow 開啟主控台圖形程式設計的新世界!