从 Win32 转到 MFC

编写简单的 win32 程序

HWND:窗口句柄类型(可以理解为窗口的ID),不能写 HINSTANCE (应用程序实例句柄类型,理解为代表这个exe,程序只能有一个 exe,但一个 exe 可以有多个窗口)

传入 NULL 表示没有父窗口句柄,窗口是独立的

Windows --- 第一个Windows窗口程序_小雪菜本菜的博客-CSDN博客_窗口程序

#include <Windows.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, LPSTR lpCmdLine, int nCmdShow)
{
    //父窗口句柄
	MessageBox(NULL, L"这是一个Win32程序", L"温馨提示", MB_OK);
	return 0;
}

学习的目的:

了解 Windows 程序运行的原理,图形是怎么绘制的,窗口是怎么产生的

MFC:微软封装的Windows的面向对象的C++类库,封装了Windows API

MFC 全称微软基础类库,英文全称 Microsoft Foundation Classes

把操作一系列窗口的函数封装到窗口类,把操作一系列菜单的函数封装到菜单类,把操作一系列绘图的函数封装到绘图类

优点:可重用性,不需要重复造轮子、简单

缺点:①做界面比较丑 ②如果要做漂亮的程序比较复杂 ③工业应用比较多

我们也可以自己封装一个简单的界面库

duilib 比较优秀的界面库(迅雷、百度音乐),底层就是 win32

easyX 不太完善,不太符合编程规范,内部采用 c++,官网案例都是以 c 语言写的,实现按钮比较麻烦,需要自己绘制,自己判断点击范围,没有控件的概念

学习 MFC 后可以自己编写界面库

MFC 三部曲

一、建立 CWinApp 派生类

#include <Windows.h>
//CwinAPP 由 MFC 框架实现 需要包含头文件
#include <afxwin.h>

//派生类公有继承 CwinAPP
class CMyAPP :public CWinApp
{

};

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, LPSTR lpCmdLine, int nCmdShow)
{
	MessageBox(NULL, L"这是一个Win32程序", L"温馨提示", MB_OK);
	return 0;
}

二、重写 CWinApp 里面的 InitInstance 虚函数

虚函数的作用就是为了让你实现多态:从基类执行到派生类,调用派生类中重写的功能

class CMyAPP :public CWinApp
{
public:
    //在基类里面声明了是一个虚函数 在派生类里面可以不加virtual修饰
    virtual BOOL InitInstance()
    {
        //弹框
        MessageBox(NULL,L"这是一个MFC程序",L"温馨提示",MB_OK);
        return TRUE;
    }
};

afx:application framework 团队开发的 MFC 工程

三、定义 CWinPP 派生类的全局对象,这个全局变量的名字一般写为 theAPP

CMyAPP theApp;

fatal error C1189: #error:  Building MFC application with /MD[d] (CRT dll version) requires MFC shared dll version. Please #define _AFXDLL or do not use /MD[d]

 

fatal error C1189: #error:  WINDOWS.H already included.  MFC apps must not #include <Windows.h>

 

 

在 mfc 工程中不再需要写 WinMain 函数

#include <afxwin.h>

class CMyAPP : public CWinApp
{
public:
    //MFC的初始化过程/启动管理,相当于main函数/入口
    BOOL InitInstance()
    {
        MessageBox(NULL, L"这是一个MFC程序", L"温馨提示", MB_OK);
        //返回TRUE表示初始化成功
        return TRUE;
    }

};

//MFC应用程序核心 一个MFC应用程序有且只有一个应用程序核心对象
CMyAPP theApp;
#include <afxwin.h>

class CMyAPP :public CWinApp
{
public:
    BOOL InitInstance()
    {
        MessageBox(NULL, L"这是一个MFC程序", L"温馨提示", MB_OK);
        //返回TRUE表示初始化成功
        return TRUE;
    }
    //退出实例:执行完之后做的一些清理工作
    //派生类调用基类的ExitInstance
    int ExitInstance()
    {
        //返回值是WinMain函数提供的退出代号 一般return 0;
        return CWinApp::ExitInstance();
    }
};

//MFC应用程序核心 一个MFC应用程序有且只有一个应用程序核心对象
CMyAPP theApp;

重写:在派生类中重写基类的函数

重载:函数名相同,参数类型、参数个数不一样

通过调试发现:首先执行 CMyAPP theApp;再执行 MessageBox(NULL, L"这是一个MFC程序", L"温馨提示", MB_OK);

#include <iostream>
using namespace std;
class CTest
{
public:
	CTest() 
	{
		cout << "这是构造函数" << endl;
	}
};
//定义一个全局对象
CTest t;
int main()
{
	cout << "这是main函数" << endl;

	return 0;
}

先执行构造函数,再执行 main 函数

全局变量的生命周期是从程序开始到程序结束

当 Windows 程序加载器去读代码的时候,首先会给所有的全局变量分配内存,最终才会调用 main 函数入口进入程序

这是一个对象,对象的定义首先需要构造,先执行构造函数,才会到 main 函数

MFC 的内部是有 WinMain 函数的

接下来给程序做一个对话框

 CDialog 类 | Microsoft Docs

//构造函数重载
explicit CDialog(
    LPCTSTR lpszTemplateName,    //字符串资源模板/资源ID的字符串
    CWnd* pParentWnd = NULL);    //父窗口句柄

explicit CDialog(
    UINT nIDTemplate,            //资源ID的整数类型
    CWnd* pParentWnd = NULL);    //父窗口句柄

CDialog();

#include <afxwin.h>
#include "resource.h"
class CMyAPP :public CWinApp
{
public:
    BOOL InitInstance()
    {
        //专门定义对话框的类 构造函数做了重载不需要MAKEINTRESOURCE 父窗口句柄可以缺省
        CDialog dlg(IDD_MAIN_DLG);
        //弹出一个模态对话框
        dlg.DoModal();
        return TRUE;
       
    }
    //退出实例:执行完之后做的一些清理工作
    //派生类调用基类的ExitInstance
    int ExitInstance()
    {
        //返回值是WinMain函数提供的退出代号 一般return 0;
        return CWinApp::ExitInstance();
    }
};

CMyAPP theApp;

如果需要更改标题、设置图标不好操作,需要建立 CDialog 的派生类,用类封装然后调用,比较简单、简洁

用派生类也可以弹出一个对话框

#include <afxwin.h>
#include"resource.h"

//派生类继承 CDialog 类
class CMyDlg : public CDialog
{
public:
    //CMyDlg绑定了这个资源模板
    CMyDlg() : CDialog(IDD_MAIN_DLG)
    {

    }

};

class CMyAPP :public CWinApp
{
public:
    BOOL InitInstance()
    {
        //专门定义对话框的类 构造函数做了重载不需要MAKEINTRESOURCE 父窗口句柄可以缺省
        CMyDlg dlg;
        //弹出一个模态对话框
        dlg.DoModal();
        return TRUE;
       
    }
    //退出实例:执行完之后做的清理工作
    //派生类调用基类的ExitInstance
    int ExitInstance()
    {
        //返回值是WinMain函数提供的退出代号 一般return 0;
        return CWinApp::ExitInstance();
    }
};

CMyAPP theApp;
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qiuqiuyaq

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值