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

C 語言繪圖程式實作:從鍵盤控制到檔案存取完整教學

     編輯:C++ 入門

程式功能總覽

本程式在 Turbo C 2.0 環境下開發,提供一個互動式繪圖環境:

  • 黃色邊框定義繪圖區域
  • 畫筆狀態:提起(V)、落下繪圖(W)、擦除(R)
  • 方向鍵控制畫筆移動(8 方向)
  • 功能鍵:畫圓(C)、存檔(S)、讀檔(E)
  • 畫筆狀態以圖示即時顯示於畫面頂端

按鍵對照表

按鍵功能畫筆圖示
V提起畫筆(移動不留痕)□
W落下畫筆(移動繪製線條)■
R擦除模式(移動清除像素)◆
C以當前位置為圓心畫半徑 20 像素的圓—
S將當前畫面存入 pic.dat—
E從 pic.dat 讀取畫面繼續編輯—

核心原始碼解析

初始化與畫筆圖示準備

#include <graphics.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>

void save(char*), load(char*);

void *wg, *rg, *vg, *fy;  // 畫筆圖示緩衝區
int driver, mode;
int c = RED;
int x = 320, y = 225;    // 畫筆初始座標
int x1, y1, x2, y2;
int k, k1, k2;

void main() {
    /* 初始化繪圖系統 */
    detectgraph(&driver, &mode);
    initgraph(&driver, &mode, "c:\\tc");

    /* 繪製三種畫筆圖示:提起、繪圖、擦除 */
    bar(200,10,206,16);           // 提起:方框
    line(203,7,200,10); line(203,7,206,10);
    line(243,7,240,16); line(243,7,246,16);  // 繪圖:筆尖
    line(283,7,280,10); line(283,7,286,10); line(283,7,283,16); // 擦除:橡皮擦

    /* 將圖示存入記憶體緩衝區 */
    wg = malloc(imagesize(200,7,206,16));
    rg = malloc(imagesize(240,7,246,16));
    vg = malloc(imagesize(280,7,286,16));
    fy = malloc(imagesize(200,7,206,16));
    getimage(200,7,206,16,wg);
    getimage(240,7,246,16,rg);
    getimage(280,7,286,16,vg);
    cleardevice();

    /* 繪製黃色繪圖邊框 */
    setcolor(YELLOW);
    rectangle(4,19,637,447);

    /* 畫筆初始顯示(提起狀態) */
    x1 = x-3; y1 = y+1; x2 = x+3; y2 = y+10;
    getimage(x1,y1,x2,y2,fy);      // 備份畫筆下方背景
    putimage(x1,y1,vg,XOR_PUT);    // XOR 顯示提起圖示

主迴圈:鍵盤事件處理


/* 主事件迴圈 */
for (;;) {
    while (bioskey(1) == 0);       // 等待按鍵
    k = bioskey(0);                // 讀取鍵碼
    putimage(x1,y1,fy,AND_PUT);    // 恢復背景(清除舊畫筆)

    if (((k & 0x00ff) | 0x00) == 0) {   // 功能鍵(掃描碼在高位元組)
        k1 = k & 0xff ? 0 : k >> 8;
    } else {                          // 一般字元鍵
        k2 = k & 0x00ff;
    }

    /* 功能鍵處理:方向移動 */
    if (((k & 0x00ff) | 0x00) == 0) {
        switch(k1) {
            case 45: restorecrtmode(); exit(0);      // X 鍵退出
            case 72: if (y > 20) y--; break;         // 上
            case 75: if (x > 5) x--; break;          // 左
            case 77: if (x < 636) x++; break;        // 右
            case 80: if (y < 446) y++; break;        // 下
            case 71: if (x > 5 && y > 20) { x--; y--; } break;   // 左上
            case 79: if (x > 5 && y < 446) { x--; y++; } break;  // 左下
            case 73: if (x < 636 && y > 20) { x++; y--; } break; // 右上
            case 81: if (x < 636 && y < 446) { x++; y++; } break;// 右下
        }
    }

    /* 更新畫筆位置並重繪 */
    x1 = x-3; y1 = y+1; x2 = x+3; y2 = y+10;
    getimage(x1,y1,x2,y2,fy);

    /* 一般字元鍵處理 */
    switch(k2) {
        case 118: case 86:  // V/v - 提起
            putimage(x1,y1,vg,OR_PUT); break;
        case 119: case 87:  // W/w - 繪圖
            putimage(x1,y1,wg,OR_PUT); putpixel(x,y,c); break;
        case 114: case 82:  // R/r - 擦除
            putimage(x1,y1,rg,OR_PUT); putpixel(x,y,BLACK); break;
        case 115: case 83:  // S/s - 存檔
            save("pic.dat"); break;
        case 101: case 69:  // E/e - 讀檔
            load("pic.dat"); break;
        case 99: case 67:   // C/c - 畫圓
            setcolor(RED); circle(x,y,20); break;
        default: continue;
    }
}

螢幕存取檔案實作(直接操作顯示記憶體)


/* 存檔:將 VGA 顯示記憶體 4 個平面逐一寫入檔案 */
void save(char *fname) {
    FILE *fp = fopen(fname, "wb");
    char far *ptr = (char far *)0xA0000000L;
    for (int i = 0; i < 4; i++) {
        outportb(0x3CE, 4); outportb(0x3CF, i);  // 選擇平面
        for (register long j = 0; j < 38400L; j++)
            putc(*ptr++, fp);
    }
    fclose(fp);
    outportb(0x3CF, 0);
}

/* 讀檔:從檔案還原 4 個平面到顯示記憶體 */
void load(char *fname) {
    FILE *fp = fopen(fname, "rb");
    char far *ptr = (char far *)0xA0000000L;
    int k4 = 1;
    for (int i = 0; i < 4; i++) {
        outportb(0x3C4, 2); outportb(0x3C5, k4); // 選擇平面
        for (register long j = 0; j < 38400L; j++)
            *ptr++ = getc(fp);
        k4 *= 2;
    }
    fclose(fp);
    outportb(0x3C5, 0xF);
}

總結與擴充方向

程式在 Turbo C 2.0 驗證通過,展示了 DOS 時代直接操作硬體的經典技法。可擴充方向:

  • 增加顏色選擇、線條寬度、幾何圖形(矩形、多邊形)
  • 支援滑鼠輸入
  • 實作圖層、撤銷/重做功能
  • 移植至現代圖形庫(SDL、SFML)保留相同交互邏輯
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved