zoukankan      html  css  js  c++  java
  • Win32++:可替代MFC的Windows桌面应用开发框架

    写在前面

    有过Win32编程经验的朋友都知道,使用Windows提供的API开发桌面应用是相当繁琐的,创建一个功能简单能接收并处理消息的窗口至少也得几百行代码。创建一个可视化的窗口一般要以下几个步骤:

    • 第一步:定义入口函数WinMain
    • 第二步:注册窗口类,在这一步你可以指定窗口类的菜单、光标、窗口过程函数等属性。
    • 第三步:定义窗口过程函数。
    • 第四步:创建窗口、显示窗口、更新窗口。
    • 第五步:消息循环。

    虽然这些步骤向导会为我们完成,但是由于windows系统是基于消息的,而且消息种类繁多,我们不得不通过大量的switch…case语句对不同的消息进行处理。

    为了方便程序员编写Windows应用,微软提供了一套基类库,简称MFC,使用MFC框架结合强大的集成开发工具Visual Studio,大大的简化了Windows桌面应用开发的难度。MFC对Windows API做了较深层次的封装,导致部分程序员对MFC的理解仅仅局限于工具的使用,他们只知道如何使用向导创建项目,如何使用向导添加一个消息处理函数,对MFC的消息映射、动态创建、文档视图结构等完全不了解。MFC目前在处于绝对垄断的地位,市面上绝大多数windows应用都使用MFC编写,Windows桌面应用开发第三方框架也比较少,其中Win32++是非常不错的一款。

    使用Win32++优势

    官网中提到,对于专业的开发人员来说,MFC无疑是最好的程序库,而且有微软这样强大的后盾。win32++面向的则是想使用更接近底层API编程方式的用户,对与想学习Win32 API的封装技巧以及Windows应用工作原理的新手来说,win32++也是不错的选择。

    对于新手来说Win32++有以下几方面的优势:

    • Win32++入门较为简单,MFC试图使用向导自动生成一些代码并且使用宏来隐藏一些复杂的操作,对于经验丰富的程序员来说效率非常高,但是对于新手来说他们对这些生成的代码并不能够理解,这并不是什么好事情。

    • 这套库本身是对Win32 API做了轻量级的封装,提供源码,代码相当整洁,而MFC显得过于庞大。

    • 我们无需过多学习就可以使用这套库,而MFC的学习难度远远大于Win32++.

    • 除了Visual Studio,Win32++可以使用免费的编译器编译。MFC依赖于Visual Studio,而且Visual Studio不便宜,从节省开发成本的角度考虑,Win32++也是不错的选择。Win32++集成开发工具可使用开源的Code::Blocks或Dev-C++等。

    Win32++下载与使用

    win32++官方网站:http://win32-framework.sourceforge.net/

    下载地址:http://sourceforge.net/projects/win32-framework/

    下载后解压,进入include目录,如下图所示,这便是Win32++框架的全部,相关类的声明和定义都写在头文件中,源码阅读起来较为方便,使用起来也比较方便,无需编译成lib文件,项目中直接引入这些头文件即可。

    这里写图片描述

    创建对话框应用

    1.新建Win32应用,在stdafx.h引入win32++头文件。
    2.创建对话框资源ID为IDD_DIALOG1 ,添加相应控件,如下图所示。
    这里写图片描述

    3.编写程序代码。

    // main.cpp
    #include "stdafx.h"
    #include "resource.h"
    
    // 定义CMyDialog对话框类
    class CMyDialog : public CDialog
    {
    public:
        CMyDialog(UINT nResID);
        virtual ~CMyDialog();
    
    protected:
        virtual void OnDestroy();
        virtual BOOL OnInitDialog();
        virtual INT_PTR DialogProc(UINT uMsg, WPARAM wParam, LPARAM lParam);
        virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
        virtual void OnOK();
    
    private:
        void OnButton();
    
        HMODULE m_hInstRichEdit;
    };
    
    
    class CDialogApp : public CWinApp
    {
    public:
        CDialogApp(); 
        virtual ~CDialogApp();
        virtual BOOL InitInstance();
        CMyDialog* GetDialog() {return &m_MyDialog;}
    
    private:
        CMyDialog m_MyDialog;
    };
    inline CDialogApp* GetDialogApp() { return static_cast<CDialogApp*>(GetApp()); }
    CDialogApp::CDialogApp() : m_MyDialog(IDD_DIALOG1)
    {
    }
    BOOL CDialogApp::InitInstance()
    {
        //显示模态对话框
        m_MyDialog.DoModal();
        return TRUE;
    }
    CDialogApp::~CDialogApp()
    {
    }
    
    CMyDialog::CMyDialog(UINT nResID) : CDialog(nResID)
    {
        m_hInstRichEdit = ::LoadLibrary(_T("RICHED32.DLL"));
        if (!m_hInstRichEdit)
            ::MessageBox(NULL, _T("CMyDialog::CRichView  Failed to load RICHED32.DLL"), _T(""), MB_ICONWARNING);
    }
    
    CMyDialog::~CMyDialog()
    {
        ::FreeLibrary(m_hInstRichEdit);
    }
    
    void CMyDialog::OnDestroy()
    {
        // 退出应用程序
        ::PostQuitMessage(0);
    }
    
    INT_PTR CMyDialog::DialogProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        return DialogProcDefault(uMsg, wParam, lParam);
    }
    
    BOOL CMyDialog::OnCommand(WPARAM wParam, LPARAM lParam)
    {
        UNREFERENCED_PARAMETER(lParam);
    
        switch (LOWORD(wParam))
        {
        case IDC_BUTTON1:   OnButton();     return TRUE;
        }
    
        return FALSE;
    }
    
    BOOL CMyDialog::OnInitDialog()
    {
        // 设置图标
        SetIconLarge(IDW_MAIN);
        SetIconSmall(IDW_MAIN);
        // 在Listbox中添加数据
        for (int i = 0 ; i < 8 ; i++)
            SendDlgItemMessage(IDC_LIST1, LB_ADDSTRING, 0, (LPARAM) _T("List Box"));
        return true;
    }
    
    void CMyDialog::OnOK()
    {
        MessageBox(_T("OK Button Pressed.  Program will exit now."), _T("Button"), MB_OK);
        CDialog::OnOK();
    }
    void CMyDialog::OnButton()
    {
        SetDlgItemText(IDC_STATIC3, _T("Button Pressed"));
        TRACE("Button Pressed
    ");
    }
    
    
    int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
    {
        try
        {
            // 启动Win32++
            CDialogApp theApp;
            // 运行应用程序
            return theApp.Run();
        }
        // 捕捉异常
        catch (std::exception &e)
        {
            // 打印异常信息
            e.what();
            return -1;
        }
    }
    

    Win32++大多数类都和MFC重名,这样我们就不需要花时间去记忆这些类名。这里我们自己定义了两个类CMyDialog和CDialogApp分别从CDialog和CWinApp继承。

    在CMyDialog类中重写父类的OnInitDialog和OnCommand函数,这两个函数都是虚函数,OnInitDialog用于完成对话框的初始化工作,例如在文本框中增加文字、在ListBox中添加一些数据等操作,OnCommand函数则是用于处理对话框消息,在本例中我们將ID为IDC_BUTTON1的案例的消息交由CMyDialog类的成员函数OnButton处理。

    CDialogApp中定义了CMyDialog类型成员变量m_MyDialog。

    CDialogApp::CDialogApp() : m_MyDialog(IDD_DIALOG1)
    {
    }

    CDialogApp构造函数中,为m_MyDialog成员变量指定对话框资源ID为IDD_DIALOG1,在CDialogApp类的对象构造时同时也会初始化m_MyDialog对象。

    BOOL CDialogApp::InitInstance()
    {
        //显示模态对话框
        m_MyDialog.DoModal();
        return TRUE;
    }

    CDialogApp类重写了父类的InitInstance函数,并在InitInstance函数中调用m_MyDialog的DoModal函数显示模态对话框。

    int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
    {
        try
        {
            // 启动Win32++
            CDialogApp theApp;
            // 运行应用程序
            return theApp.Run();
        }
        // 捕捉异常
        catch (std::exception &e)
        {
            // 打印异常信息
            e.what();
            return -1;
        }
    }

    在入口函数WinMain中定义CDialogApp 对象theApp,调用父类的Run函数运行程序。

    编译运行

    效果如下:

    这里写图片描述

  • 相关阅读:
    LeetCode 109 Convert Sorted List to Binary Search Tree
    LeetCode 108 Convert Sorted Array to Binary Search Tree
    LeetCode 107. Binary Tree Level Order Traversal II
    LeetCode 106. Construct Binary Tree from Inorder and Postorder Traversal
    LeetCode 105. Construct Binary Tree from Preorder and Inorder Traversal
    LeetCode 103 Binary Tree Zigzag Level Order Traversal
    LeetCode 102. Binary Tree Level Order Traversal
    LeetCode 104. Maximum Depth of Binary Tree
    接口和多态性
    C# 编码规范
  • 原文地址:https://www.cnblogs.com/lanzhi/p/6468982.html
Copyright © 2011-2022 走看看