专栏导航
上一篇:第5章,[Win32 章节] :练习程序,LittleFontPic
回到目录
下一篇:第5章,[Win32 章节] :椭圆教学插图绘制程序
本专栏课件
关于本专栏课件的获取方法,请参考下述课节。
参考课节:MFC笔记:本专栏课件
本节前言
对于本节所讲解的知识,有可能,你会需要时不时地参考本专栏的其它文章。真的遇到了需要参考之前的文章的知识点,请你自行查阅。
我呢,也会提到一部分的参考课节。但是呢,你不应该依赖于我的主动提及。最好呢,你自己能够多去了解和查看本专栏目录。
本节,我们主要的工作,仅仅是展示一个代码而已。对于本节代码的分析工作,请大家自行完成。因此,本节,其实是一个思考题,而不是一个详细的讲解。
但是呢,我们也不是说,让大家直接就去分析这么一个程序。
在上一节,我们分析了 LittleFontPic 程序的代码逻辑。
本节代码的逻辑,与 LittleFontPic 十分相似。所以呢,请大家在理解 LittleFontPic 程序、理解上一节课的基础上,来自行分析本节程序代码。
我们,仅给出少量的必要说明。剩下的,请大家自行分析。
上一节课的链接,我们再次贴出来。
参考课节:第5章,[Win32 章节] :练习程序,LittleFontPic
本节内容,是我的原创内容,而非佩措尔德原教材的内容。
一. 本节说明
在之前的某个课节,我们在课节中给出了下述的图片。
这个课节的链接如下。
参考课节:第5章,[标签 Win32] :设备的尺寸(三)
接下来,我来将佩措尔德原教材的图片内容给截图,然后贴在下面。
佩措尔德原教材中的插图,我没有通过截图的方式,将其放置在参考课节中,而是通过编程的方式,将它的基本的东西绘制出来,然后通过 PhotoShop 进行补充绘制。绘制好了以后,放在了课节里面。
下面的图片,是我用编程的方式,绘制出来的基本图。
在编程之前,我是自己用铅笔,结合着观察,去给佩措尔德的原教材的插图查数,查出了原插图中,一行里面,有多少个像素方格,一列里面,有多少个像素方格。
查询的结果是,佩措尔德原教材的插图中,一行有 20 个像素方格,一列有 20 个方格。
想要将其绘制出来,我需要绘制一个方格矩阵,一个 20 行、20 列的方格矩阵。
到了这里,我想,基本信息我已经作出了必要的说明了。剩下的分析,请大家参考着上一节课的内容,来对照着,自行分析本节的代码。
如果,上一节课你认真看了,并且学会了,那么,本节课的代码,我相信它难不倒你。
加油。
二. 本节代码
(一)头文件 FontPic.h
代码如下。
#ifndef _FONTPIC_H_ #define _FONTPIC_H_ BOOL Square[20][20] = { 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1 }; #endif //(二)源文件 WinMain.cpp
代码如下。
/*--------------------------------------------------------- 字体点阵图画 水饺编程,2026 ---------------------------------------------------------*/ #include <windows.h> #include "FontPic.h" LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static TCHAR szAppName[] = TEXT("BigFontPic"); HWND hwnd; MSG msg; WNDCLASS wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szAppName; if (!RegisterClass(&wndclass)) { MessageBox(NULL, TEXT("注册窗口类失败"), szAppName, MB_ICONERROR); return 0; } hwnd = CreateWindow(szAppName, TEXT("大字体点阵图画"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); ShowWindow(hwnd, iCmdShow); UpdateWindow(hwnd); while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static int xStart, xEnd, yStart, yEnd, nLength; HDC hdc; int i, j, x, y; PAINTSTRUCT ps; static COLORREF clrLine, clrSquare; HPEN hPen, hPenOld; HBRUSH hBrush, hOldBrush; RECT rect; switch (message) { case WM_CREATE: nLength = 27; xStart = 200; xEnd = xStart + 20 * nLength; yStart = 60; yEnd = yStart + 20 * nLength; clrLine = RGB(255, 0, 0); clrSquare = RGB(0, 0, 255); return 0; case WM_PAINT: hdc = BeginPaint(hwnd, &ps); // 创建并选入画笔 hPen = CreatePen(PS_DASHDOT, 0, clrLine); hPenOld = (HPEN)SelectObject(hdc, hPen); // 绘制点线方格,21个横线,21个竖线。 for (i = 0, y = yStart; i < 21; i++) { MoveToEx(hdc, xStart, y, NULL); LineTo(hdc, xEnd, y); y += nLength; } for (i = 0, x = xStart; i < 21; i++) { MoveToEx(hdc, x, yStart, NULL); LineTo(hdc, x, yEnd); x += nLength; } // 创建画刷并选入设备环境 hBrush = CreateSolidBrush(clrSquare); hOldBrush = (HBRUSH)SelectObject(hdc, hBrush); // 将画笔选出设备环境,并销毁,然后新建一个备用画笔 NULL_PEN。 SelectObject(hdc, hPenOld); DeleteObject(hPen); hPen = (HPEN)GetStockObject(NULL_PEN); hPenOld = (HPEN)SelectObject(hdc, hPen); for (i = 0; i < 20; i++) for (j = 0; j < 20; j++) if (Square[i][j]) { rect.left = xStart + j * nLength + 2; rect.right = xStart + (j + 1) * nLength - 1; rect.top = yStart + i * nLength + 2; rect.bottom = yStart + (i + 1) * nLength - 1; FillRect(hdc, &rect, hBrush); } // 将画刷选出设备环境并销毁 SelectObject(hdc, hOldBrush); DeleteObject(hBrush); // 将画笔选出设备环境,由于此时 hPen 是备用 // 画笔,因而不能销毁。 SelectObject(hdc, hPenOld); EndPaint(hwnd, &ps); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, message, wParam, lParam); }代码就这些了。
程序的编译和运行方法,如果你忘了,可以参照下述的两篇文章。
参考课节:使用 VS2010 编写 C语言程序
参考课节:用 VS2019 编写C语言程序
程序的运行结果,差不多就是图3 。
我们再次将图3 给贴在下面。
为啥是差不多呢?
因为,我一开始在用编程的方式来绘制图3 的时候,我给模拟像素方格涂色时所用的函数,是在以后的课节中会讲到的 FillRect 函数。而此时,我在给大家讲解 GDI 绘图代码时,我给模拟像素方格涂色时所用的函数,是应用了 NULL_PEN 备用画笔的 Rectangle 函数。
也就是,我们在绘制图3 时实际使用的函数,是 FillRect 函数。而本节代码中,我们为了不超纲,为了早一点给大家演示 GDI 绘图代码,我们临时将 FillRect 函数替换为应用了 NULL_PEN 备用画笔的 Rectangle 函数。
应用了 NULL_PEN 备用画笔的 Rectangle 函数的行为与 FillRect 函数的行为略有不同,所以,在你那里,实际运行结果会与图3 略有不同。此时,请不要深抠这点细节。
结束语
请大家务必完成本节代码的分析任务。
我还是第一次在课节中设置思考题。本节课,算是一个思考题了。
以后,我可能也会设置类似的思考题课节。
专栏导航
上一篇:第5章,[Win32 章节] :练习程序,LittleFontPic
回到目录
下一篇:第5章,[Win32 章节] :椭圆教学插图绘制程序