呵呵,好像是分节处出了点故障。继续努力,耐心、仔细,肯定可以的,严格按照既定思路办,一步一步验证。只要不是眉毛胡子一把抓,逐步分解确认之下,必能逼近成功。
授人以渔,不授人以鱼。
#include <Windows.h> #include <cstdio> #include <cstdlib> #include <clocale> #include <vector> #include <bitset> #include <conio.h> // 数据结构 struct hzCode { unsigned short unicode; // Unicode编码 unsigned short gbcode; // GB2312编码 }; // 全局数据 const WCHAR K_ENTER = 0x000D; // Enter键码 const size_t IMAGE_SIZE = 16; // 点阵规模 const wchar_t CodeListFileName[] = L"E:\\Projects\\test\\test_hzk\\Unicode16_GB2312.DAT"; // 汉字编码对照表文件 const wchar_t zkName[] = L"E:\\Projects\\test\\test_hzk\\HZK16K"; // 字模文件 HDC hDC = GetDC(GetConsoleWindow()); // 取当前控制台窗口为绘图设备 std::vector<struct hzCode> CodeList; // 汉字编码对照表 // 函数原型 BOOL LoadCodeList(const wchar_t* FileName); unsigned short Get_GBcode(unsigned short unicode); VOID DrawPoint(int x, int y); void ShowHzString(int row, int col, wchar_t hzString[], FILE* zk, int rotate = 0); VOID ShowHz(int x, int y, wchar_t word, FILE* zk, int roatet = 0); void Pause(void); // 程序入口 // >>>Microsoft Specific<<< // Alternatively, the main and wmain functions can be declared as returning void (no return value). // If you declare main or wmain as returning void, you cannot return an exit code to the parent // process or operating system by using a return statement. To return an exit code when main or wmain // is declared as void, you must use the exit function. // void wmain(int argc, wchar_t *argv[], wchar_t *envp[]) { setlocale(LC_ALL, "chs"); if (!LoadCodeList(CodeListFileName)) { wprintf_s(L"汉字编码对照表%s打开失败!", CodeListFileName); Pause(); return; } FILE* zk; errno_t error = _wfopen_s(&zk, zkName, L"rb"); if (error != 0) { wprintf_s(L"字库%s打开失败!", zkName); Pause(); return; } for (int i = 0; i < 4; ++i) { ShowHzString(i, 2, L"编程中国论坛小鱼儿欢迎您!", zk, i); } ShowHzString(5, 0, L"按回车键结束程序", zk); fclose(zk); Pause(); ReleaseDC(NULL, hDC); // 释放绘图设备对象 } // 功能:装入汉字编码对照表 // 参数:FileName 编码表文件名 // 返回:装入成功为真否则为假 BOOL LoadCodeList(const wchar_t* FileName) { FILE* file; errno_t error = _wfopen_s(&file, FileName, L"rb"); if (error == 0) { while (!feof(file)) { struct hzCode hz; if (fread(&hz, sizeof(hz), 1, file) == 1) { CodeList.push_back(hz); } else { error = ferror(file); break; } } fclose(file); } return (error == 0); } // 功能:根据Unicode查找对应GB2312编码 // 返回:如果没有对应的GB2312编码,则返回零 unsigned short Get_GBcode(unsigned short unicode) { unsigned short gbcode = 0; std::vector<struct hzCode>::iterator it; for (it = CodeList.begin(); it != CodeList.end(); ++it) { if (it->unicode == unicode) { gbcode = it->gbcode; break; } } return gbcode; } // 功能:在指定位置显示一个汉字字符串 // 参数:(row,col) 起始行列坐标 // hzString 需要显示的汉字字符串,用Unicode编码 // zk 已打开的字库文件句柄 // rotate 字符旋转方向 0-正常 1-顺转90度 2-顺转180度 3-顺转270度,默认为0 // 返回:无 void ShowHzString(int row, int col, wchar_t hzString[], FILE* zk, int rotate) { for (int i = 0; hzString[i] != L'\0'; ++i) { ShowHz(row, col++, hzString[i], zk, rotate); } } // 功能:在指定位置显示单个汉字 // 参数:(row,col) 起始行列坐标 // word 需要显示的汉字,用Unicode编码 // zk 已打开的字库文件句柄 // 返回:无 void ShowHz(int row, int col, wchar_t word, FILE* zk, int rotate) { unsigned short gbCode = Get_GBcode(word); if (gbCode != 0) { unsigned char quCode = (gbCode / 256) - 0xA0; // 区码 unsigned char weiCode = (gbCode % 256) - 0xA0; // 位码 unsigned long offset = ((quCode - 1) * 94 + (weiCode - 1)) * 32L; // 字模偏移量 unsigned char buffer[IMAGE_SIZE * 2]; // 字模数据 fseek(zk, offset, SEEK_SET); fread(buffer, sizeof(buffer), 1, zk); int x = col * IMAGE_SIZE; int y = row * IMAGE_SIZE; switch (rotate) { case 1: x += IMAGE_SIZE - 1; break; case 2: x += IMAGE_SIZE - 1; y += IMAGE_SIZE - 1; break; case 3: y += IMAGE_SIZE - 1; break; } for (int i = 0; i < _countof(buffer); ++i) { std::bitset<8> byte(buffer[i]); for (int j = 7; j >= 0; --j) { HPEN hPen = CreatePen(PS_SOLID, 1, byte.test(j) ? RGB(255,255,255) : RGB(0, 0, 0)); SelectObject(hDC, hPen); DrawPoint(x, y); DeleteObject(hPen); switch (rotate) { case 0: ++x; break; case 1: ++y; break; case 2: --x; break; case 3: --y; break; } } if (i % 2 != 0) { switch (rotate) { case 0: x = col * IMAGE_SIZE; ++y; break; case 1: y = row * IMAGE_SIZE; --x; break; case 2: x = col * IMAGE_SIZE + IMAGE_SIZE - 1; --y; break; case 3: ++x; y = row * IMAGE_SIZE + IMAGE_SIZE - 1; break; } } } } else { // 如果没有对应的汉字,则显示一个方框 HPEN hPen = CreatePen(PS_SOLID, 1, RGB(255,255,255)); SelectObject(hDC, hPen); Rectangle(hDC, col, row, col + IMAGE_SIZE - 1, row + IMAGE_SIZE - 1); DeleteObject(hPen); } } // 功能:描点 // 参数:(x,y) 点坐标 // 返回:无 // 注释:使用当前设置前景色 VOID DrawPoint(int x, int y) { // 利用绘制椭圆方法描点 Ellipse(hDC, x - 1, y - 1, x + 1, y + 1); } void Pause(void) { while (_getwch() != K_ENTER) { ; } }