首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

顛覆認知:在 Windows 主控台應用程式中繪製圖形與顯示圖片

     編輯:關於C語言

許多開發者以為主控台應用程式只能輸出文字。實則不然,Windows 主控台視窗同樣擁有視窗控制代碼,可像 GUI 視窗一樣進行 GDI 繪圖、顯示位圖、處理滑鼠訊息。本文揭示主控台視窗的隱藏能力,並提供完整程式碼示範在主控台顯示 BMP 圖片。

主控台視窗的秘密:它也是一個 HWND

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;
}

實戰:在主控台顯示 BMP 圖片

#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;
}

主控台進階 API 速查表

取得 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 函數

實務應用場景

  1. 除錯視覺化:在主控台直接繪製資料結構圖、算法動畫(排序、樹遍歷)。
  2. 輕量級工具:無需建立 GUI 專案,快速撰寫帶圖形介面的測試工具。
  3. 舊系統移植:逐步將主控台程式圖形化,平滑遷移至 GUI。
  4. 教學示範:直觀展示 GDI、座標系統、雙緩衝繪圖原理。

注意事項

  • 主控台視窗大小固定時,繪圖區域受限;可用 SetConsoleWindowInfo 調整緩衝區大小。
  • 主控台關閉時系統自動釋放 DC,但良好習慣仍應 ReleaseDC。
  • 頻繁重繪會造成閃爍,需實作雙緩衝(記憶體 DC 繪圖後一次 BitBlt)。
  • Windows 10 新版主控台對 GDI 繪圖支援良好,舊版可能有相容性問題。

打破「主控台只能文字」的迷思,善用 GetConsoleWindow 開啟主控台圖形程式設計的新世界!

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved