可用MinGW编译的win32绘图框架

本文介绍了如何在Windows环境下,利用MinGW编译器和GDI库创建一个简单的win32绘图框架。通过避免复杂的win32API直接操作,作者实现了基于内存图片的重绘策略,减少了闪烁问题,并提供了键盘响应功能。文章详细讲解了主入口、消息循环、定时器、重绘、双缓冲以及线程和临界区的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

鉴于Microsoft Visual Studio体积巨大,我坚持不愿意安装,故在windows下编程一直都用MinGW和TCC作为编译器,用Codebocks作为开发环境。MinGW对于C/C++标准库支持很好,但是对于windows API就没那么好了。由于windows家族从win32API-> MFC->WPF->.net,体积庞大演变复杂,第三方库显然无法承载。
对于我个人工作,console下的操作使用标准库函数已经足够,文件操作使用.bat批处理,网路操作使用Python,唯一需要win32系统函数的地方就是图形界面了。这次在编写botzone的贪吃蛇程序时,平台规定用cpp+jsoncpp,为了方便调试,只好使用MinGW调用win32API库做一个简单的绘图框架。
由于GDI库过于底层,使用起来很庞杂,我的思路是写一个固定的框架代码,每隔30ms显示某内存中的固定图片(别忘了加锁),其他所有的绘制过程都归结到对于图片的图形绘制上去。这样最大限度地隔离了win32系统。

首先建立基本的主入口和消息循环函数WinMain:

#include <windows.h>
int WINAPI WinMain (HINSTANCE hThisInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpszArgument,
                    int nCmdShow)
{
    HWND hwnd;               /* This is the handle for our window */
    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */

    /* The Window structure */
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
    wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
    wincl.cbSize = sizeof (WNDCLASSEX);

    /* Use default icon and mouse-pointer */
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;                 /* No menu */
    wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
    wincl.cbWndExtra = 0;                      /* structure or the window instance */
    /* Use Windows's default colour as the background of the window */
    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

    /* Register the window class, and if it fails quit the program */
    if (!RegisterClassEx (&wincl))
        return 0;

    /* The class is registered, let's create the program*/
    hwnd = CreateWindowEx (
               0,                   /* Extended possibilites for variation */
               szClassName,         /* Classname */
               "Double Snake Game Simulator",       /* Title Text */
               WS_OVERLAPPEDWINDOW, /* default window */
               CW_USEDEFAULT,       /* Windows decides the position */
               CW_USEDEFAULT,       /* where the window ends up on the screen */
               800,                 /* The programs width */
               600,                 /* and height in pixels */
               HWND_DESKTOP,        /* The window is a child-window to desktop */
               NULL,                /* No menu */
               hThisInstance,       /* Program Instance handler */
               NULL                 /* No Window Creation data */
           );

    /* Make the window visible on the screen */
    ShowWindow (hwnd, nCmdShow);


    /* Run the message loop. It will run until GetMessage() returns 0 */
    while (GetMessage (&messages, NULL, 0, 0))
    {
        /* Translate virtual-key messages into character messages */
        TranslateMessage(&messages);
        /* Send message to WindowProcedure */
        DispatchMessage(&messages);
    }


    /* The program return-value is 0 - The value that PostQuitMessage() gave */
    return messages.wParam;
}


消息处理函数

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)                  /* handle the messages */
    {
    case WM_TIMER:
        RedrawWindow(hwnd,NULL,NULL,RDW_ERASE|RDW_INVALIDATE);
    
<think>嗯,用户提到在Qt中调用#include <afxwin.h>时出现报错。首先,我需要确定问题的根源。可能的情况有几个方面: 首先,AFXWIN.H是Microsoft的MFC(Microsoft Foundation Classes)头文件,而Qt是一个跨平台的框架,通常不与MFC混合使用。所以用户可能在尝试将MFC代码集成到Qt项目中,这可能导致兼容性问题。 接着,检查编译环境。MFC只能在Windows平台上使用,并且需要Visual Studio的支持。如果用户使用的是其他编译器(比如MinGW),那么MFC库可能不可用,导致头文件找不到的错误。例如,错误信息可能是“无法打开源文件afxwin.h”或者类似的编译错误。 另外,项目配置也可能有问题。在Qt项目中,默认不会包含MFC所需的库和头文件路径。用户可能需要手动配置.pro文件,添加包含路径和链接库,尤其是在使用MSVC编译器的情况下。 还需要考虑许可证和兼容性。MFC是微软的专有库,而Qt有自己的许可证,混合使用可能需要用户注意两者的许可协议是否冲突,尤其是在商业项目中。 可能的解决方案包括:建议用户避免在Qt项目中使用MFC,转而使用Qt自身的类库实现相应功能;如果必须使用MFC,确保使用Visual Studio作为编译器,并正确配置项目设置;或者将MFC相关代码封装成独立的DLL,在Qt中调用。 另外,用户可能需要检查他们的开发环境是否安装了MFC组件。例如,在安装Visual Studio时,是否勾选了MFC相关的选项。如果未安装,需要重新运行安装程序添加该组件。 最后,如果用户的具体需求是某些特定的功能(如窗口处理、界面元素等),可以推荐使用Qt的对应模块来替代MFC,从而避免兼容性问题,并保持项目的跨平台特性。</think>在Qt项目中直接包含`#include <afxwin.h>`报错,通常是由于以下几个原因及解决方案: --- ### **1. 框架冲突:Qt与MFC不兼容** - **问题根源**:`afxwin.h`是微软MFC框架的头文件,而Qt是独立的跨平台框架,二者设计目的不同,**无法直接混合使用**。 - **典型错误**:`fatal error: afxwin.h: No such file or directory` - **解决方案**: - **推荐做法**:放弃MFC,使用纯Qt实现功能。例如: - 窗口类:用`QMainWindow`替代`CFrameWnd` - 消息映射:用Qt信号槽替代`BEGIN_MESSAGE_MAP` - **不得已情况**:若必须同时使用: 1. 确保项目使用**Visual Studio编译器**(MSVC),因为MFC仅支持MSVC。 2. 在`.pro`文件中添加MFC库: ```qmake win32:LIBS += mfc140.lib # 根据VS版本调整(如mfc120、mfc140u等) ``` --- ### **2. 编译器不匹配** - **问题现象**:使用MinGW编译时报错,因为MinGW**不包含MFC库**。 - **解决方案**: - **切换编译器**:在Qt Creator中改用**MSVC编译器套件**。 - **配置环境**: 1. 安装Visual Studio(勾选“C++ MFC”组件)。 2. 在Qt Creator中设置Kit,选择MSVC编译器。 --- ### **3. 头文件路径未包含** - **问题现象**:编译器找不到`afxwin.h`。 - **解决方案**: - 在`.pro`文件中显式添加MFC头文件路径: ```qmake win32:INCLUDEPATH += "C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.29.30133/atlmfc/include" ``` (路径需根据实际VS安装目录调整) --- ### **4. 项目类型配置错误** - **关键点**:Qt默认创建**GUI应用程序项目**,而MFC需要**Windows桌面项目**配置。 - **解决方案**: - 对于`qmake`项目,在`.pro`中添加: ```qmake win32:CONFIG += console win32:CONFIG -= qt ``` - 对于CMake项目,设置`WIN32`选项。 --- ### **替代方案建议** 如果目标是实现特定功能(如窗口嵌入、COM调用等),优先使用Qt原生方法: - **替代ActiveX**:使用`QAxObject`或`QAxWidget` - **替代GDI绘图**:使用`QPainter` - **替代Win32 API调用**:使用`QWindow::winId()`获取HWND后操作 --- ### **验证步骤** 1. 确认编译器为MSVC:Qt Creator → 项目 → Build → 选择MSVC套件。 2. 检查VS是否安装MFC:通过Visual Studio Installer添加“C++ MFC”组件。 3. 在纯Win32 API项目中测试`#include <afxwin.h>`是否正常,排除环境问题。 --- 通过上述调整,应能解决Qt中调用MFC头文件的问题。但长远来看,保持Qt项目的纯粹性更利于维护和跨平台特性。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值