windows应用(vc++2022)MFC基础到实战(1)

news2024/9/20 6:02:39

目录

    • vc++概述
    • MFC 框架
      • 概述
      • MFC 框架
      • SDI 和 MDI
      • 文档、视图和框架
      • 窗口对象
      • 文档/视图体系结构
    • 第一个应用
    • 自动生成的主框架类源码

vc++概述

Microsoft Visual C++(简称Visual C++、MSVC、VS或VC)是微软公司的免费C++开发工具,具有集成开发环境,可提供编辑C语言,C++以及C++/CLI等编程语言。VC++集成了便利的除错工具,特别是集成了微软Windows视窗操作系统应用程序接口(Windows API)、三维动画DirectX API,Microsoft .NET框架。
它以拥有“语法高亮”,IntelliSense(自动完成功能)以及高级除错功能而著称。比如,它允许用户进行远程调试,单步执行等。还有允许用户在调试期间重新编译被修改的代码,而不必重新启动正在调试的程序。其编译及建置系统以预编译头文件、最小重建功能及累加连结著称。这些特征明显缩短程式编辑、编译及连结花费的时间,在大型软件计划上尤其显著。
我们可以使用vs2022社区版,这个对个人是免费使用的
https://visualstudio.microsoft.com/zh-hans/vs/community/
Microsoft 基础类库是用于在 Microsoft Windows 中编程的应用程序框架。 MFC 采用 C++ 编写,它提供了执行以下操作所需的很多代码:管理窗口、菜单和对话框;执行基本输入/输出;存储数据对象的集合等。 你只需将特定于应用程序的代码添加到此框架中。 鉴于 C++ 类编程的特性,很容易扩展和重写 MFC 框架提供的基本功能。

MFC 框架

概述

MFC 框架是一种让您基于 Windows 专家程序员的工作来进行开发的有力方法。 MFC 具有以下优点:缩短开发时间;提高代码的可移植性;提供强有力的支持而不会降低编程的自由性和灵活性;降低接触“难以编程”的用户界面元素和技术(如 Active 技术、OLE 和 Internet 编程)的难度。 此外,MFC 还通过数据访问对象 (DAO) 和开放式数据库连接 (ODBC)(已过时)简化了数据库编程,并通过 Windows 套接字简化了网络编程。 MFC 使用户可以轻松对属性表(“通过 Tab 切换对话框”)、打印预览和浮动的自定义工具栏等功能进行编程。
Microsoft 基础类 (MFC) 库组成了一个“应用程序框架”,用于为 Windows 操作系统构建应用程序。 一般而言,框架定义应用程序的框架,并提供可以放置在框架上的标准用户界面实现。 程序员的工作是填写其余的框架,即特定于应用程序的内容。 可以通过使用 MFC 应用程序向导为非常彻底的初学者应用程序创建文件来入门。 可以使用 Microsoft Visual C++ 资源编辑器直观地设计用户界面元素、类视图命令,从而将这些元素连接到代码,以及用于实现特定于应用程序的逻辑的类库。

MFC 框架

MFC 框架的版本 3.0 及更高版本支持 Win32 平台(包括 Microsoft Windows 95 及更高版本)的编程,以及Windows NT 版本 3.51 及更高版本。 MFC Win32 支持包括多线程。 如果需要进行 16 位编程,请使用版本 1.5x。

使用 Microsoft 基础类 (MFC) 库框架时很大程度上基于几个主要的类和 Visual C++ 工具。 一些类封装了 Win32 应用程序编程接口 (API) 的一大部分。 其他类封装了应用程序概念,如文档、视图和应用程序本身。 还有其他类封装了 OLE 功能以及 ODBC 和 DAO 数据访问功能。 (DAO 通过 Office 2013 受到支持。DAO 3.6 是最终版本,被认为已经过时。)

例如,Win32 的窗口概念由 MFC 类 CWnd 封装。 也就是说,名为 CWnd 的 C++ 类封装或“包装”了表示 Windows 窗口的 HWND 句柄。 同样,CDialog 类封装了 Win32 对话框。

以 C++ 类 CWnd 为例,封装意味着它包含了 HWND 类型的成员变量,并且它的成员函数封装了对采用 HWND 作为参数的 Win32 函数的调用。 类成员函数通常具有与其所封装的 Win32 函数相同的名称。

SDI 和 MDI

借助 MFC,可以轻松地使用单文档界面 (SDI) 和多文档界面 (MDI) 应用程序。

SDI 应用程序一次只允许打开一个文档框架窗口。 MDI 应用程序允许在应用程序的同一实例中打开多个文档框架窗口。 MDI 应用程序有一个窗口,在该窗口中可以打开多个 MDI 子窗口(其本身就是框架窗口),每个子窗口都包含一个单独的文档。 在某些应用程序中,子窗口的类型可以不同,例如图表窗口和电子表格窗口。 在这种情况下,菜单栏可随着不同类型的 MDI 子窗口激活而改变。

文档、视图和框架

MFC 框架的核心是文档和视图的概念。 文档是用户在编辑会话中与之进行交互的数据对象。 它由“文件”菜单上的“新建”或“打开”命令创建,并且通常保存在一个文件中。 (标准 MFC 文档派生自 CDocument 类,不同于活动文档和 OLE 复合文档)。视图是用户与文档进行交互所用的窗口对象。

一个正在运行的应用程序中的关键对象有:

线程对象

如果应用程序创建不同的执行线程(例如,在后台执行计算),则你将使用从 CWinThread 派生的类。 CWinApp 本身派生自 CWinThread 并表示应用程序中的主执行线程(或主进程)。 还可以在辅助线程中使用 MFC。

应用程序对象

你的应用程序类(派生自 CWinApp)控制上面的所有对象并指定应用程序行为,如初始化和清理。 应用程序仅有的一个应用程序对象为应用程序支持的任何文档类型创建和管理文档模板。

一个或多个文档模板

文档模板可协调文档、视图和框架窗口的创建。 派生自 CDocTemplate 类的特定文档模板类创建并管理一个类型的所有打开的文档。 支持多种文档类型的应用程序具有多个文档模板。 将 CSingleDocTemplate 类用于 SDI 应用程序,或将 CMultiDocTemplate 类用于 MDI 应用程序。

框架窗口

视图显示在“文档框架窗口”内。在 SDI 应用程序中,文档框架窗口也是应用程序的“主框架窗口”。 在 MDI 应用程序中,文档窗口是显示在主框架窗口中的子窗口。 派生的主框架窗口类指定包含您的视图的框架窗口的样式和其他特性。 如果需要自定义框架窗口,请从 CFrameWnd 派生以自定义 SDI 应用程序的文档框架窗口。 从 CMDIFrameWnd 派生以自定义 MDI 应用程序的主框架窗口。 另外,请从 CMDIChildWnd 派生一个类以自定义应用程序支持的每种不同的 MDI 文档框架窗口。

一个文档或多个文档。

文档类(派生自 CDocument)指定应用程序的数据。

如果你在应用程序中需要 OLE 功能,请从 COleDocument 或其派生类之一派生文档类,这取决于你需要的功能类型。

一个视图或多个视图。

视图类(派生自 CView)是用户的“数据窗口”。视图类控制用户如何查看文档数据并与之交互。 在某些情况下,您可能希望一个文档拥有多个数据视图。

如果需要滚动,请从 CScrollView 派生。 如果视图拥有一个在对话框模板资源中布局的用户界面,请从 CFormView 派生。 对于简单的文本数据,请使用 CEditView 或从中派生。 对于基于窗体的数据访问应用程序(如数据输入程序),请从 CRecordView 派生(对于 ODBC)。 此外,还有 CTreeView、CListView 和 CRichEditView 类。

MFC 框架的核心是文档和视图的概念。 文档是用户在编辑会话中与之进行交互的数据对象。 它由“文件”菜单上的“新建”或“打开”命令创建,并且通常保存在一个文件中。 (标准 MFC 文档派生自 CDocument 类,不同于活动文档和 OLE 复合文档)。视图是用户与文档进行交互所用的窗口对象。

在一个正在运行的应用程序中,这些对象以协作方式响应用户操作(由命令和其他消息绑定在一起)。
一个应用程序对象管理一个或多个文档模板。 每个文档模板创建并管理一个或多个文档(具体取决于应用程序是 SDI 还是 MDI)。

用户通过包含在框架窗口中的视图查看和操作文档。 下图演示了 SDI 应用程序的这些对象之间的关系。
在这里插入图片描述
运行 SDI 应用程序中的对象

窗口对象

MFC 提供 CWnd 类来封装窗口的 HWND 句柄。 CWnd 对象是一个 C++ 窗口对象,与表示一个 Windows 窗口但包含它的 HWND 不同。 使用 CWnd 可派生您自己的子窗口类,或使用派生自 CWnd 的很多 MFC 类之一。 CWnd 类是所有窗口的基类,包括框架窗口、对话框、子窗口、控件和控件条(如工具栏)。 充分了解 C++ 窗口对象和 HWND 之间的关系对于使用 MFC 进行有效的编程非常重要。

MFC 提供窗口的某些默认功能和管理,但是,可以从 CWnd 派生您自己的类并使用其成员函数自定义所提供的功能。 通过构造 CWnd 对象并调用其 Create 成员函数创建子窗口,然后使用 CWnd 成员函数自定义子窗口。 可以在框架窗口中嵌入派生自 CView 的对象,如窗体视图或树视图。 可以通过由 CSplitterWnd 类提供的拆分器窗格来支持文档的多个视图。

派生自 CWnd 类的每个对象都包含一个消息映射,您可以通过它将 Windows 消息或命令 ID 映射到您自己的处理程序。

有关 Windows 编程的常规资料是了解如何使用可封装 CWnd API 的 HWND 成员函数的合适资源。
用于 CWnd 的函数

CWnd 及其派生的窗口类提供了构造函数、析构函数和成员函数来初始化对象,创建基础的 Windows 结构并访问封装的 HWND。 CWnd 还提供了可封装 Windows API 的成员函数,以用于发送消息、访问窗口的状态、转换坐标、更新、滚动、访问剪贴板以及许多其他任务。 大多数采用 HWND 参数的 Windows 窗口管理 API 都封装为 CWnd 的成员函数。 函数的名称及其参数保留在 CWnd 成员函数中。 有关 CWnd 封装的 Windows API 的详细信息,请参见 CWnd 类。
CWnd 和 Windows 消息

CWnd 的一个主要用途是提供用于处理 Windows 消息的接口,如 WM_PAINT 或 WM_MOUSEMOVE。 CWnd 的许多成员函数是标准消息的处理程序:这些成员函数以标识符 afx_msg 和前缀“On”开头,例如 OnPaint 和 OnMouseMove。 消息处理和映射详细介绍了消息和消息处理。 这些信息同样适用于框架的窗口以及您出于特殊目的自己创建的窗口。

文档/视图体系结构

默认情况下,MFC 应用程序向导会使用文档类和视图类创建应用程序主干。 MFC 将数据管理分隔到这两个类中。 文档存储数据并管理打印数据以及协调更新数据的多个视图。 视图显示数据并管理用户与数据的交互,包括选择和编辑。

在此模型中,MFC 文档对象读取数据并将数据写入持久存储。 文档还可以提供与数据的接口,无论数据驻留在何处(如数据库中)。 单独的视图对象管理数据显示(从在窗口中呈现数据到用户选择和编辑数据)。 视图从文档获取显示数据,并将任何数据更改传达回给文档。

虽然可以轻松替代或忽略文档/视图分隔,但在大多数情况下,有令人信服的理由遵循此模型。 最佳原因之一是需要相同文档的多个视图(例如电子表格和图表视图)时。 文档/视图模型允许单独的视图对象表示数据的每个视图,而对所有视图通用的代码(如计算引擎)可以驻留在文档中。 每当数据发生更改时,文档也会执行更新所有视图的任务。

借助 MFC 文档/视图体系结构,可以轻松地支持多个视图、多种文档类型、拆分窗口和其他重要的用户界面功能。

对于用户和程序员而言,最常看到的 MFC 框架部分是文档和视图。 使用该框架开发应用程序的大多数工作涉及编写文档和视图类。 此文章系列会介绍:

文档和视图的用途以及它们在框架中的交互方式。

必须执行哪些操作才能实现它们。

文档/视图的核心是四个关键类:

CDocument(或 COleDocument)类支持用于存储或控制程序数据的对象,并为程序员定义的文档类提供基本功能。 文档表示用户通常使用“文件”菜单上的“打开”命令打开并使用“文件”菜单上的“保存”命令保存的数据单元。

CView(或其许多派生类之一)可为程序员定义的视图类提供基本功能。 视图附加到文档并充当文档与用户之间的中介:视图在屏幕呈现文档的图像,并将用户输入解释为对文档的操作。 视图还呈现图像以用于打印和打印预览。

CFrameWnd(或其变体之一)支持围绕文档的一个或多个视图提供框架的对象。

CDocTemplate(或是 CSingleDocTemplate 或 CMultiDocTemplate)支持的对象可协调给定类型的一个或多个现有文档,并管理为该类型创建正确文档、视图和框架窗口对象。
在这里插入图片描述

类库中的文档/视图实现将数据本身与其显示和用户对数据的操作分隔开来。 对数据的所有更改都通过文档类进行管理。 视图调用此接口来访问和更新数据。
文档、其关联视图和围绕视图的框架窗口由文档模板创建。 文档模板负责创建和管理一种文档类型的所有文档。

第一个应用

在这里插入图片描述在这里插入图片描述

在这里插入图片描述运行
在这里插入图片描述

自动生成的主框架类源码


// MainFrm.cpp: CMainFrame 类的实现
//

#include "pch.h"
#include "framework.h"
#include "learnvc1.h"

#include "MainFrm.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// CMainFrame

IMPLEMENT_DYNAMIC(CMainFrame, CMDIFrameWndEx)

const int  iMaxUserToolbars = 10;
const UINT uiFirstUserToolBarId = AFX_IDW_CONTROLBAR_FIRST + 40;
const UINT uiLastUserToolBarId = uiFirstUserToolBarId + iMaxUserToolbars - 1;

BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWndEx)
	ON_WM_CREATE()
	ON_COMMAND(ID_WINDOW_MANAGER, &CMainFrame::OnWindowManager)
	ON_COMMAND(ID_VIEW_CUSTOMIZE, &CMainFrame::OnViewCustomize)
	ON_REGISTERED_MESSAGE(AFX_WM_CREATETOOLBAR, &CMainFrame::OnToolbarCreateNew)
	ON_COMMAND_RANGE(ID_VIEW_APPLOOK_WIN_2000, ID_VIEW_APPLOOK_WINDOWS_7, &CMainFrame::OnApplicationLook)
	ON_UPDATE_COMMAND_UI_RANGE(ID_VIEW_APPLOOK_WIN_2000, ID_VIEW_APPLOOK_WINDOWS_7, &CMainFrame::OnUpdateApplicationLook)
	ON_WM_SETTINGCHANGE()
END_MESSAGE_MAP()

static UINT indicators[] =
{
	ID_SEPARATOR,           // 状态行指示器
	ID_INDICATOR_CAPS,
	ID_INDICATOR_NUM,
	ID_INDICATOR_SCRL,
};

// CMainFrame 构造/析构

CMainFrame::CMainFrame() noexcept
{
	// TODO: 在此添加成员初始化代码
	theApp.m_nAppLook = theApp.GetInt(_T("ApplicationLook"), ID_VIEW_APPLOOK_VS_2008);
}

CMainFrame::~CMainFrame()
{
}

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CMDIFrameWndEx::OnCreate(lpCreateStruct) == -1)
		return -1;

	BOOL bNameValid;

	CMDITabInfo mdiTabParams;
	mdiTabParams.m_style = CMFCTabCtrl::STYLE_3D_ONENOTE; // 其他可用样式...
	mdiTabParams.m_bActiveTabCloseButton = TRUE;      // 设置为 FALSE 会将关闭按钮放置在选项卡区域的右侧
	mdiTabParams.m_bTabIcons = FALSE;    // 设置为 TRUE 将在 MDI 选项卡上启用文档图标
	mdiTabParams.m_bAutoColor = TRUE;    // 设置为 FALSE 将禁用 MDI 选项卡的自动着色
	mdiTabParams.m_bDocumentMenu = TRUE; // 在选项卡区域的右边缘启用文档菜单
	EnableMDITabbedGroups(TRUE, mdiTabParams);

	if (!m_wndMenuBar.Create(this))
	{
		TRACE0("未能创建菜单栏\n");
		return -1;      // 未能创建
	}

	m_wndMenuBar.SetPaneStyle(m_wndMenuBar.GetPaneStyle() | CBRS_SIZE_DYNAMIC | CBRS_TOOLTIPS | CBRS_FLYBY);

	// 防止菜单栏在激活时获得焦点
	CMFCPopupMenu::SetForceMenuFocus(FALSE);

	if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
		!m_wndToolBar.LoadToolBar(theApp.m_bHiColorIcons ? IDR_MAINFRAME_256 : IDR_MAINFRAME))
	{
		TRACE0("未能创建工具栏\n");
		return -1;      // 未能创建
	}

	CString strToolBarName;
	bNameValid = strToolBarName.LoadString(IDS_TOOLBAR_STANDARD);
	ASSERT(bNameValid);
	m_wndToolBar.SetWindowText(strToolBarName);

	CString strCustomize;
	bNameValid = strCustomize.LoadString(IDS_TOOLBAR_CUSTOMIZE);
	ASSERT(bNameValid);
	m_wndToolBar.EnableCustomizeButton(TRUE, ID_VIEW_CUSTOMIZE, strCustomize);

	// 允许用户定义的工具栏操作: 
	InitUserToolbars(nullptr, uiFirstUserToolBarId, uiLastUserToolBarId);

	if (!m_wndStatusBar.Create(this))
	{
		TRACE0("未能创建状态栏\n");
		return -1;      // 未能创建
	}
	m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT));

	// TODO: 如果您不希望工具栏和菜单栏可停靠,请删除这五行
	m_wndMenuBar.EnableDocking(CBRS_ALIGN_ANY);
	m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
	EnableDocking(CBRS_ALIGN_ANY);
	DockPane(&m_wndMenuBar);
	DockPane(&m_wndToolBar);


	// 启用 Visual Studio 2005 样式停靠窗口行为
	CDockingManager::SetDockingMode(DT_SMART);
	// 启用 Visual Studio 2005 样式停靠窗口自动隐藏行为
	EnableAutoHidePanes(CBRS_ALIGN_ANY);

	// 加载菜单项图像(不在任何标准工具栏上): 
	CMFCToolBar::AddToolBarForImageCollection(IDR_MENU_IMAGES, theApp.m_bHiColorIcons ? IDB_MENU_IMAGES_24 : 0);

	// 创建停靠窗口
	if (!CreateDockingWindows())
	{
		TRACE0("未能创建停靠窗口\n");
		return -1;
	}

	m_wndFileView.EnableDocking(CBRS_ALIGN_ANY);
	m_wndClassView.EnableDocking(CBRS_ALIGN_ANY);
	DockPane(&m_wndFileView);
	CDockablePane* pTabbedBar = nullptr;
	m_wndClassView.AttachToTabWnd(&m_wndFileView, DM_SHOW, TRUE, &pTabbedBar);
	m_wndOutput.EnableDocking(CBRS_ALIGN_ANY);
	DockPane(&m_wndOutput);
	m_wndProperties.EnableDocking(CBRS_ALIGN_ANY);
	DockPane(&m_wndProperties);

	// 基于持久值设置视觉管理器和样式
	OnApplicationLook(theApp.m_nAppLook);

	// 启用增强的窗口管理对话框
	EnableWindowsDialog(ID_WINDOW_MANAGER, ID_WINDOW_MANAGER, TRUE);

	// 启用工具栏和停靠窗口菜单替换
	EnablePaneMenu(TRUE, ID_VIEW_CUSTOMIZE, strCustomize, ID_VIEW_TOOLBAR);

	// 启用快速(按住 Alt 拖动)工具栏自定义
	CMFCToolBar::EnableQuickCustomization();

	if (CMFCToolBar::GetUserImages() == nullptr)
	{
		// 加载用户定义的工具栏图像
		if (m_UserImages.Load(_T(".\\UserImages.bmp")))
		{
			CMFCToolBar::SetUserImages(&m_UserImages);
		}
	}

	// 启用菜单个性化(最近使用的命令)
	// TODO: 定义您自己的基本命令,确保每个下拉菜单至少有一个基本命令。
	CList<UINT, UINT> lstBasicCommands;

	lstBasicCommands.AddTail(ID_FILE_NEW);
	lstBasicCommands.AddTail(ID_FILE_OPEN);
	lstBasicCommands.AddTail(ID_FILE_SAVE);
	lstBasicCommands.AddTail(ID_APP_EXIT);
	lstBasicCommands.AddTail(ID_EDIT_CUT);
	lstBasicCommands.AddTail(ID_EDIT_PASTE);
	lstBasicCommands.AddTail(ID_EDIT_UNDO);
	lstBasicCommands.AddTail(ID_APP_ABOUT);
	lstBasicCommands.AddTail(ID_VIEW_STATUS_BAR);
	lstBasicCommands.AddTail(ID_VIEW_TOOLBAR);
	lstBasicCommands.AddTail(ID_VIEW_APPLOOK_OFF_2003);
	lstBasicCommands.AddTail(ID_VIEW_APPLOOK_VS_2005);
	lstBasicCommands.AddTail(ID_VIEW_APPLOOK_OFF_2007_BLUE);
	lstBasicCommands.AddTail(ID_VIEW_APPLOOK_OFF_2007_SILVER);
	lstBasicCommands.AddTail(ID_VIEW_APPLOOK_OFF_2007_BLACK);
	lstBasicCommands.AddTail(ID_VIEW_APPLOOK_OFF_2007_AQUA);
	lstBasicCommands.AddTail(ID_VIEW_APPLOOK_WINDOWS_7);
	lstBasicCommands.AddTail(ID_SORTING_SORTALPHABETIC);
	lstBasicCommands.AddTail(ID_SORTING_SORTBYTYPE);
	lstBasicCommands.AddTail(ID_SORTING_SORTBYACCESS);
	lstBasicCommands.AddTail(ID_SORTING_GROUPBYTYPE);

	CMFCToolBar::SetBasicCommands(lstBasicCommands);

	// 将文档名和应用程序名称在窗口标题栏上的顺序进行交换。这
	// 将改进任务栏的可用性,因为显示的文档名带有缩略图。
	ModifyStyle(0, FWS_PREFIXTITLE);

	return 0;
}

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
	if( !CMDIFrameWndEx::PreCreateWindow(cs) )
		return FALSE;
	// TODO: 在此处通过修改
	//  CREATESTRUCT cs 来修改窗口类或样式

	return TRUE;
}

BOOL CMainFrame::CreateDockingWindows()
{
	BOOL bNameValid;

	// 创建类视图
	CString strClassView;
	bNameValid = strClassView.LoadString(IDS_CLASS_VIEW);
	ASSERT(bNameValid);
	if (!m_wndClassView.Create(strClassView, this, CRect(0, 0, 200, 200), TRUE, ID_VIEW_CLASSVIEW, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CBRS_LEFT | CBRS_FLOAT_MULTI))
	{
		TRACE0("未能创建“类视图”窗口\n");
		return FALSE; // 未能创建
	}

	// 创建文件视图
	CString strFileView;
	bNameValid = strFileView.LoadString(IDS_FILE_VIEW);
	ASSERT(bNameValid);
	if (!m_wndFileView.Create(strFileView, this, CRect(0, 0, 200, 200), TRUE, ID_VIEW_FILEVIEW, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CBRS_LEFT| CBRS_FLOAT_MULTI))
	{
		TRACE0("未能创建“文件视图”窗口\n");
		return FALSE; // 未能创建
	}

	// 创建输出窗口
	CString strOutputWnd;
	bNameValid = strOutputWnd.LoadString(IDS_OUTPUT_WND);
	ASSERT(bNameValid);
	if (!m_wndOutput.Create(strOutputWnd, this, CRect(0, 0, 100, 100), TRUE, ID_VIEW_OUTPUTWND, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CBRS_BOTTOM | CBRS_FLOAT_MULTI))
	{
		TRACE0("未能创建输出窗口\n");
		return FALSE; // 未能创建
	}

	// 创建属性窗口
	CString strPropertiesWnd;
	bNameValid = strPropertiesWnd.LoadString(IDS_PROPERTIES_WND);
	ASSERT(bNameValid);
	if (!m_wndProperties.Create(strPropertiesWnd, this, CRect(0, 0, 200, 200), TRUE, ID_VIEW_PROPERTIESWND, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CBRS_RIGHT | CBRS_FLOAT_MULTI))
	{
		TRACE0("未能创建“属性”窗口\n");
		return FALSE; // 未能创建
	}

	SetDockingWindowIcons(theApp.m_bHiColorIcons);
	return TRUE;
}

void CMainFrame::SetDockingWindowIcons(BOOL bHiColorIcons)
{
	HICON hFileViewIcon = (HICON) ::LoadImage(::AfxGetResourceHandle(), MAKEINTRESOURCE(bHiColorIcons ? IDI_FILE_VIEW_HC : IDI_FILE_VIEW), IMAGE_ICON, ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON), 0);
	m_wndFileView.SetIcon(hFileViewIcon, FALSE);

	HICON hClassViewIcon = (HICON) ::LoadImage(::AfxGetResourceHandle(), MAKEINTRESOURCE(bHiColorIcons ? IDI_CLASS_VIEW_HC : IDI_CLASS_VIEW), IMAGE_ICON, ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON), 0);
	m_wndClassView.SetIcon(hClassViewIcon, FALSE);

	HICON hOutputBarIcon = (HICON) ::LoadImage(::AfxGetResourceHandle(), MAKEINTRESOURCE(bHiColorIcons ? IDI_OUTPUT_WND_HC : IDI_OUTPUT_WND), IMAGE_ICON, ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON), 0);
	m_wndOutput.SetIcon(hOutputBarIcon, FALSE);

	HICON hPropertiesBarIcon = (HICON) ::LoadImage(::AfxGetResourceHandle(), MAKEINTRESOURCE(bHiColorIcons ? IDI_PROPERTIES_WND_HC : IDI_PROPERTIES_WND), IMAGE_ICON, ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON), 0);
	m_wndProperties.SetIcon(hPropertiesBarIcon, FALSE);

	UpdateMDITabbedBarsIcons();
}

// CMainFrame 诊断

#ifdef _DEBUG
void CMainFrame::AssertValid() const
{
	CMDIFrameWndEx::AssertValid();
}

void CMainFrame::Dump(CDumpContext& dc) const
{
	CMDIFrameWndEx::Dump(dc);
}
#endif //_DEBUG


// CMainFrame 消息处理程序

void CMainFrame::OnWindowManager()
{
	ShowWindowsDialog();
}

void CMainFrame::OnViewCustomize()
{
	CMFCToolBarsCustomizeDialog* pDlgCust = new CMFCToolBarsCustomizeDialog(this, TRUE /* 扫描菜单*/);
	pDlgCust->EnableUserDefinedToolbars();
	pDlgCust->Create();
}

LRESULT CMainFrame::OnToolbarCreateNew(WPARAM wp,LPARAM lp)
{
	LRESULT lres = CMDIFrameWndEx::OnToolbarCreateNew(wp,lp);
	if (lres == 0)
	{
		return 0;
	}

	CMFCToolBar* pUserToolbar = (CMFCToolBar*)lres;
	ASSERT_VALID(pUserToolbar);

	BOOL bNameValid;
	CString strCustomize;
	bNameValid = strCustomize.LoadString(IDS_TOOLBAR_CUSTOMIZE);
	ASSERT(bNameValid);

	pUserToolbar->EnableCustomizeButton(TRUE, ID_VIEW_CUSTOMIZE, strCustomize);
	return lres;
}

void CMainFrame::OnApplicationLook(UINT id)
{
	CWaitCursor wait;

	theApp.m_nAppLook = id;

	switch (theApp.m_nAppLook)
	{
	case ID_VIEW_APPLOOK_WIN_2000:
		CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManager));
		break;

	case ID_VIEW_APPLOOK_OFF_XP:
		CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerOfficeXP));
		break;

	case ID_VIEW_APPLOOK_WIN_XP:
		CMFCVisualManagerWindows::m_b3DTabsXPTheme = TRUE;
		CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));
		break;

	case ID_VIEW_APPLOOK_OFF_2003:
		CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerOffice2003));
		CDockingManager::SetDockingMode(DT_SMART);
		break;

	case ID_VIEW_APPLOOK_VS_2005:
		CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerVS2005));
		CDockingManager::SetDockingMode(DT_SMART);
		break;

	case ID_VIEW_APPLOOK_VS_2008:
		CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerVS2008));
		CDockingManager::SetDockingMode(DT_SMART);
		break;

	case ID_VIEW_APPLOOK_WINDOWS_7:
		CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows7));
		CDockingManager::SetDockingMode(DT_SMART);
		break;

	default:
		switch (theApp.m_nAppLook)
		{
		case ID_VIEW_APPLOOK_OFF_2007_BLUE:
			CMFCVisualManagerOffice2007::SetStyle(CMFCVisualManagerOffice2007::Office2007_LunaBlue);
			break;

		case ID_VIEW_APPLOOK_OFF_2007_BLACK:
			CMFCVisualManagerOffice2007::SetStyle(CMFCVisualManagerOffice2007::Office2007_ObsidianBlack);
			break;

		case ID_VIEW_APPLOOK_OFF_2007_SILVER:
			CMFCVisualManagerOffice2007::SetStyle(CMFCVisualManagerOffice2007::Office2007_Silver);
			break;

		case ID_VIEW_APPLOOK_OFF_2007_AQUA:
			CMFCVisualManagerOffice2007::SetStyle(CMFCVisualManagerOffice2007::Office2007_Aqua);
			break;
		}

		CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerOffice2007));
		CDockingManager::SetDockingMode(DT_SMART);
	}

	m_wndOutput.UpdateFonts();
	RedrawWindow(nullptr, nullptr, RDW_ALLCHILDREN | RDW_INVALIDATE | RDW_UPDATENOW | RDW_FRAME | RDW_ERASE);

	theApp.WriteInt(_T("ApplicationLook"), theApp.m_nAppLook);
}

void CMainFrame::OnUpdateApplicationLook(CCmdUI* pCmdUI)
{
	pCmdUI->SetRadio(theApp.m_nAppLook == pCmdUI->m_nID);
}


BOOL CMainFrame::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle, CWnd* pParentWnd, CCreateContext* pContext)
{
	// 基类将执行真正的工作

	if (!CMDIFrameWndEx::LoadFrame(nIDResource, dwDefaultStyle, pParentWnd, pContext))
	{
		return FALSE;
	}


	// 为所有用户工具栏启用自定义按钮
	BOOL bNameValid;
	CString strCustomize;
	bNameValid = strCustomize.LoadString(IDS_TOOLBAR_CUSTOMIZE);
	ASSERT(bNameValid);

	for (int i = 0; i < iMaxUserToolbars; i ++)
	{
		CMFCToolBar* pUserToolbar = GetUserToolBarByIndex(i);
		if (pUserToolbar != nullptr)
		{
			pUserToolbar->EnableCustomizeButton(TRUE, ID_VIEW_CUSTOMIZE, strCustomize);
		}
	}

	return TRUE;
}


void CMainFrame::OnSettingChange(UINT uFlags, LPCTSTR lpszSection)
{
	CMDIFrameWndEx::OnSettingChange(uFlags, lpszSection);
	m_wndOutput.UpdateFonts();
}

未完下一节继续

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/393733.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring Security OAuth2实现多用户类型认证、刷新Token

原本的OAuth2登录支持用户名密码登录&#xff0c;现在还想支持另外用id号码和密码登录。但是OAuth2默认提供的UserDetailsService只允许传入一个参数&#xff1a;想要实现多种用户登录&#xff0c;是不是可以考虑loadUserByUsername方法携带多个参数呢&#xff1f;接下来记录一…

Docker安装和Docker安装Nginx及其他常用操作

一、Docker简介 Docker 是一个开源的应用容器引擎&#xff0c;基于Go 语言并遵从 Apache2.0 协议开源。 Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上&#xff0c;也可以实现虚拟化。 容器是完全…

机器学习与目标检测作业:连通块算法

机器学习与目标检测作业&#xff1a;连通块算法一、连通块算法题目描述二、连通块算法文件结构三、连通块算法程序编写3.1、连通块算法conBlock.h头文件内容3.2、conBlock.cpp源文件内容3.3.3、mian.h头文件内容3.3.4、main.cpp源文件内容如下四、连通块算法程序运行结果一、连…

【JS知识点】——原型和原型链

文章目录原型和原型链构造函数原型显式原型&#xff08;prototype&#xff09;隐式原型&#xff08;\_\_proto\_\_&#xff09;原型链总结原型和原型链 在js中&#xff0c;原型和原型链是一个非常重要的知识点&#xff0c;只有理解原型和原型链&#xff0c;才能深刻理解JS。在…

云上办公系统项目

云上办公系统项目1、云上办公系统1.1、介绍1.2、核心技术1.3、开发环境说明1.4、产品展示后台前台1.5、 个人总结2、后端环境搭建2.1、建库建表2.2、创建Maven项目pom文件guigu-oa-parentcommoncommon-utilservice-utilmodelservice-oa配置数据源、服务器端口号application.yml…

D2-Net: A Trainable CNN for Joint Description and Detection of Local Features精读

开源代码&#xff1a;D2-Net 1 摘要 在这项工作中&#xff0c;我们解决了在困难的成像条件下寻找可靠的像素级对应的问题。我们提出了一种由单一卷积神经网络发挥双重作用的方法&#xff1a;它同时是一个密集的特征描述符和一个特征检测器。通过将检测推迟到后期阶段&#xf…

统计代码量

一 windows 在 Windows 系统上&#xff0c;您可以使用 PowerShell 命令行工具来统计项目的代码量。下面是使用 PowerShell 统计项目代码量的步骤&#xff1a; 打开 PowerShell 终端&#xff1a;按下 Win X 键&#xff0c;选择「Windows PowerShell&#xff08;管理员&#xf…

SQL分库分表

什么是分库分表&#xff1f; 分库分表是两种操作&#xff0c;一种是分库&#xff0c;一种是分表。 分库分表又分为垂直拆分和水平拆分两种。 &#xff08;1&#xff09;分库&#xff1a;将原来存放在单个数据库中的数据&#xff0c;拆分到多个数据库中存放。 &#xff08;2&…

【三.项目引入axios、申明全局变量、设置跨域】

根据前文《二.项目使用vue-router,引入ant-design-vue的UI框架&#xff0c;引入less》搭建好脚手架后使用 需求&#xff1a; 1.项目引入axios 2.申明全局变量 3.设置跨域 简介&#xff1a;axios本质上还是对原生XMLHttpRequest的封装&#xff0c;可用于浏览器和nodejs的HTTP客…

物理层概述(二)重点

目录前言编码与调制&#xff08;1&#xff09;基带信号与宽带信号编码与调制编码与调制&#xff08;2&#xff09;数字数据编码为数字信号非归零编码【NRZ】曼斯特编码差分曼彻斯特编码数字数据调制为模拟信号模拟数据如何编码为数字信号模拟数据调制为模拟信号物理层传输介质导…

Go语言学习的第一天(对于Go学习的认识和工具选择及环境搭建)

首先学习一门新的语言&#xff0c;我们要知道这门语言可以帮助我们做些什么&#xff1f;为什么我们要学习这门语言&#xff1f;就小wei而言学习这门语言是为了区块链&#xff0c;因为自身是php出身&#xff0c;因为php的一些特性只能通过一些算法模拟的做一个虚拟链&#xff0c…

IT服务管理(ITSM) 中的大数据

当我们谈论IT服务管理&#xff08;ITSM&#xff09;领域的大数据时&#xff0c;我们谈论的是关于两件不同的事情&#xff1a; IT 为业务提供的大数据工具/服务 - 对业务运营数据进行数字处理。IT 运营中的大数据 – 处理和利用复杂的 IT 运营数据。 面向业务运营的大数据服务…

Hadoop节点的分类与作用

文件的数据类型文件有一个stat命令元数据信息-->描述文件的属性文件有一个vim命令查看文件的数据信息分类元数据File 文件名 Size 文件大小&#xff08;字节&#xff09; Blocks 文件使用的数据块总数 IO Block 数据块的大小 regular file&#xff1a;文件类型&#xff…

YOLOV5中添加CBAM模块详解——原理+代码

目录一、前言二、CAM1. CAM计算过程2. 代码实现3. 流程图三、SAM1. SAM计算过程2. 代码实现3. 流程图四、YOLOv5中添加CBAM模块参考文章一、前言 由于卷积操作通过融合通道和空间信息来提取特征&#xff08;通过NNNNNN的卷积核与原特征图相乘&#xff0c;融合空间信息&#xff…

模板学堂丨妙用Tab组件制作多屏仪表板并实现自动轮播

DataEase开源数据可视化分析平台于2022年6月正式发布模板市场&#xff08;https://dataease.io/templates/&#xff09;。模板市场旨在为DataEase用户提供专业、美观、拿来即用的仪表板模板&#xff0c;方便用户根据自身的业务需求和使用场景选择对应的仪表板模板&#xff0c;并…

2021年MathorCup数学建模D题钢材制造业中的钢材切割下料问题全过程文档及程序

2021年第十一届MathorCup高校数学建模 D题 钢材制造业中的钢材切割下料问题 原题再现 某钢材生产制造商的钢材切割流程如图 1 所示。其中开卷上料环节将原材料钢卷放在开卷机上&#xff0c;展开放平送至右侧操作区域&#xff08;见图 2&#xff09;。剪切过程在剪切台上完成&…

如何使用 NFTScan NFT API 检索单个 NFT 资产

一、什么是 NFT API API 是允许两个应用组件使用一组定义和协议相互通信的机制。一般来说&#xff0c;这是一套明确定义的各种软件组件之间的通信方法。API 发送请求到存储数据的服务器&#xff0c;接着把调用的数据信息返回。开发者可以通过调用 API 函数对应用程序进行开发&…

Qt 单例模式第一次尝试

文章目录摘要单例模式如何使用Qt 的属性系统总结关键字&#xff1a; Qt、 单例、 的、 Q_GLOBAL_STATIC、 女神节摘要 世界上第一位电脑程序设计师是名女性&#xff1a;Ada Lovelace (1815-1852)是一位英国数学家兼作家&#xff0c;她是第一位主张计算机不只可以用来算数的人…

【安装mxnet】

安装mxnet 通过创建python3.6版本的虚拟环境安装mxnet 1、安装anaconda 2、打开Anaconda prompt 3、查看环境 conda env list conda info -e 4、创建虚拟环境 conda create -n your_env_name python3.6 5、激活或者切换虚拟环境 activate your_env_name 6、安装mxnet,下面两…

规划数据指标体系方法(中)——UJM 模型

上文我跟大家分享了关于规划数据指标体系的 OSM 模型&#xff0c;从目标-战略-度量的角度解读了数据指标的规划方法&#xff0c;今天来跟大家讲一讲另一种规划数据指标体系的方法——UJM 模型。 了解 UJM UJM 模型&#xff0c;全称为 User-Journey-Map 模型&#xff0c;即用户…