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

news2024/11/26 15:52:52

目录

    • 框架调用代码
    • MFC 对象之间的关系
    • 访问其他对象
    • CWinApp:应用程序类
      • initInstance 成员函数
      • 运行成员函数
      • OnIdle 成员函数
      • ExitInstance 成员函数
    • CWinApp 和 MFC 应用程序向导
    • 特殊 CWinApp 服务
      • Shell 注册
      • 文件管理器拖放
    • CWinAppEx 类
    • 用于创建 OLE 应用程序的操作顺序
    • 用于创建 ActiveX 控件的操作顺序
    • 用于创建数据库应用程序的操作顺序
    • 对话框数据交换

框架调用代码

当应用程序运行时,大多数控件流位于框架的代码中。 框架管理一个消息循环,当用户在视图中选择命令和编辑数据时,此消息循环将会从 Windows 中获取消息。 框架可以单独处理的事件根本不用依赖您的代码。 例如,框架知道如何关闭窗口以及如何退出应用程序以响应用户命令。 在处理这些任务时,框架会使用消息处理程序和 C++ 虚函数,以便为你提供响应这些事件的机会。 但是,你的代码没有控制权,控制权在框架手中。

框架将会针对应用程序特定的事件调用你的代码。 例如,当用户选择某个菜单命令时,框架会将该命令传递给一系列 C++ 对象:当前视图和框架窗口、与当前视图关联的文档、文档的文档模板和应用程序对象。 如果其中某个对象可以处理命令,则会调用相应的消息处理程序函数来进行处理。 对于任何给定的命令,调用的代码可能是你的,也可能是框架的。

MFC 对象之间的关系

为了帮助正确地对待文档/视图创建过程,请考虑正在运行的程序:文档、用于包含视图的框架窗口以及与文档关联的视图。

文档用于保留其视图的列表和指向创建它的文档模板的指针。

视图用于保留指向其文档的指针并且是其父框架窗口的子级。

文档框架窗口用于保留指向其当前活动视图的指针。

文档模板用于保留其打开的文档的列表。

应用程序用于保留其文档模板的列表。

窗口用于跟踪所有打开的窗口以便能将消息发送到这些窗口。

访问其他对象

任何对象均可通过调用全局函数 AfxGetApp 来获取指向应用程序对象的指针。
获取对应用程序中的其他对象的访问权限

文档 使用 GetFirstViewPosition 和 GetNextView 以访问文档的视图列表。

调用 GetDocTemplate 以获取文档模板。
视图 调用 GetDocument 以获取文档。

调用 GetParentFrame 以获取框架窗口。
文档框架窗口 调用 GetActiveView 以获取当前视图。

调用 GetActiveDocument 以获取附加到当前视图的文档。
MDI 框架窗口 调用 MDIGetActive 以获取当前处于活动状态的 CMDIChildWnd。

通常,框架窗口包含一个视图,但在某些情况下(例如在拆分窗口中),同一框架窗口包含多个视图。 框架窗口保留指向当前处于活动状态的视图的指针;该指针在其他视图激活时更新。

CWinApp:应用程序类

MFC 中的主应用程序类将封装 Windows 操作系统的应用程序的初始化、运行和终止。 基于框架生成的应用程序必须有且只有一个从 CWinApp 派生的类的对象。 创建窗口之前将构造此对象。

CWinApp 派生自 CWinThread,它表示应用程序的执行的主线程(可能有一个或多个线程)。 在最新版本的 MFC 中,InitInstance、Run、ExitInstance 和 OnIdle 成员函数实际上位于类 CWinThread 中。 此处将这些函数作为 CWinApp 成员进行了讨论,因为讨论的焦点是将对象的角色视为应用程序对象,而不是主线程。

应用程序类构成了应用程序的执行主线程。 使用 Win32 API 函数,还可以创建执行的辅助线程。 这些线程可使用 MFC 库。

与 Windows 操作系统的所有程序类似,框架应用程序具有 WinMain 函数。 但在框架应用程序中,您不编写 WinMain。 它由类库提供,并且在应用程序启动时调用。 WinMain 运行标准服务,如注册窗口类。 然后它调用应用程序对象的成员函数来初始化和运行该应用程序。 (您可通过重写 WinMain 调用的 CWinApp 成员函数来自定义 WinMain。)

若要初始化此应用程序,WinMain 将调用应用程序对象的 InitApplication 和 InitInstance 成员函数。 要运行应用程序的消息循环,WinMain 将调用 Run 成员函数。 终止时,WinMain 将调用应用程序对象的 ExitInstance 成员函数。

// learnvc1.cpp: 定义应用程序的类行为。
.......
.......
BOOL Clearnvc1App::InitInstance()
{
	// 如果一个运行在 Windows XP 上的应用程序清单指定要
	// 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
	//则需要 InitCommonControlsEx()。  否则,将无法创建窗口。
	INITCOMMONCONTROLSEX InitCtrls;
	InitCtrls.dwSize = sizeof(InitCtrls);
	// 将它设置为包括所有要在应用程序中使用的
	// 公共控件类。
	InitCtrls.dwICC = ICC_WIN95_CLASSES;
	InitCommonControlsEx(&InitCtrls);

	CWinAppEx::InitInstance();


	EnableTaskbarInteraction();

	// 使用 RichEdit 控件需要 AfxInitRichEdit2()
	// AfxInitRichEdit2();

	// 标准初始化
	// 如果未使用这些功能并希望减小
	// 最终可执行文件的大小,则应移除下列
	// 不需要的特定初始化例程
	// 更改用于存储设置的注册表项
	// TODO: 应适当修改该字符串,
	// 例如修改为公司或组织名
	SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
	LoadStdProfileSettings(4);  // 加载标准 INI 文件选项(包括 MRU)


	InitContextMenuManager();

	InitKeyboardManager();

	InitTooltipManager();
	CMFCToolTipInfo ttParams;
	ttParams.m_bVislManagerTheme = TRUE;
	theApp.GetTooltipManager()->SetTooltipParams(AFX_TOOLTIP_TYPE_ALL,
		RUNTIME_CLASS(CMFCToolTipCtrl), &ttParams);

	// 注册应用程序的文档模板。  文档模板
	// 将用作文档、框架窗口和视图之间的连接
	CMultiDocTemplate* pDocTemplate;
	pDocTemplate = new CMultiDocTemplate(IDR_learnvc1TYPE,
		RUNTIME_CLASS(Clearnvc1Doc),
		RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
		RUNTIME_CLASS(Clearnvc1View));
	if (!pDocTemplate)
		return FALSE;
	AddDocTemplate(pDocTemplate);

	// 创建主 MDI 框架窗口
	CMainFrame* pMainFrame = new CMainFrame;
	if (!pMainFrame || !pMainFrame->LoadFrame(IDR_MAINFRAME))
	{
		delete pMainFrame;
		return FALSE;
	}
	m_pMainWnd = pMainFrame;


	// 分析标准 shell 命令、DDE、打开文件操作的命令行
	CCommandLineInfo cmdInfo;
	ParseCommandLine(cmdInfo);



	// 调度在命令行中指定的命令。  如果
	// 用 /RegServer、/Register、/Unregserver 或 /Unregister 启动应用程序,则返回 FALSE。
	if (!ProcessShellCommand(cmdInfo))
		return FALSE;
	// 主窗口已初始化,因此显示它并对其进行更新
	pMainFrame->ShowWindow(m_nCmdShow);
	pMainFrame->UpdateWindow();

	return TRUE;
}

int Clearnvc1App::ExitInstance()
{
	//TODO: 处理可能已添加的附加资源
	return CWinAppEx::ExitInstance();
}


// learnvc1.h: learnvc1 应用程序的主头文件
//
#pragma once

#ifndef __AFXWIN_H__
	#error "在包含此文件之前包含 'pch.h' 以生成 PCH"
#endif

#include "resource.h"       // 主符号


// Clearnvc1App:
// 有关此类的实现,请参阅 learnvc1.cpp
//

class Clearnvc1App : public CWinAppEx
{
public:
	Clearnvc1App() noexcept;


// 重写
public:
	virtual BOOL InitInstance();
	virtual int ExitInstance();

// 实现
	UINT  m_nAppLook;
	BOOL  m_bHiColorIcons;

	virtual void PreLoadState();
	virtual void LoadCustomState();
	virtual void SaveCustomState();

	afx_msg void OnAppAbout();
	DECLARE_MESSAGE_MAP()
};

extern Clearnvc1App theApp;

initInstance 成员函数

Windows 操作系统允许您运行同一应用程序的多个副本(也称为“实例”)。 每当应用程序的新实例启动时,WinMain 都将调用 InitInstance。

MFC 应用程序向导创建的标准 InitInstance 实现将执行以下任务:

作为其中心操作,将创建文档模板,该模板又会创建文档、视图和框架窗口。

.ini 文件或 Windows 注册表加载标准文件选项,包括最近使用的文件的名称。

注册一个或多个文档模板。

对于 MDI 应用程序,创建主框架窗口。

处理命令行以打开命令行上指定的文档或打开新的空文档。

你可以添加自己的初始化代码或修改向导编写的代码。

MFC 应用程序必须初始化为单线程单元 (STA)。 如果在 InitInstance 替代中调用 CoInitializeEx,请指定 COINIT_APARTMENTTHREADED(而不是 COINIT_MULTITHREADED)。

运行成员函数

框架应用程序会在 CWinApp 类的 Run 成员函数中花费其大部分时间。 初始化之后,WinMain 调用 Run 来处理消息循环。

Run 循环通过一个消息循环,检查消息队列中的可用消息。 如果有可用的消息,Run 调度它进行相应的操作。 如果没有可用的消息(通常是这种情况),则 Run 调用 OnIdle 来执行你或框架可能需要进行的任何空闲时间处理。 如果没有要执行的消息和空闲处理,则应用程序将进行等待,直到发生某些情况。 应用程序终止时,Run 调用 ExitInstance。 OnIdle 成员函数中的数字显示消息循环中的操作序列

OnIdle 成员函数

当没有 Windows 消息在处理时,框架将调用 CWinApp 成员函数 OnIdle。

重写 OnIdle 以执行后台任务。 默认版本更新用户界面对象的状态(如工具栏按钮)并执行框架在其操作过程中创建的临时对象的清除。 下图演示消息循环如何在队列中没有消息时调用 OnIdle。
在这里插入图片描述

ExitInstance 成员函数

每当应用程序的副本终止(通常是因为用户退出应用程序)时,就会调用类 CWinApp 的 ExitInstance 成员函数。

如果需要特殊清理处理(如释放图形设备接口 (GDI) 资源或释放在程序执行期间使用的内存),则重写 ExitInstance。 但是,标准项(如文档和视图)的清理由框架使用用于执行特定于这些对象的特殊清理的其他可重写函数提供。

CWinApp 和 MFC 应用程序向导

创建框架应用程序时,MFC 应用程序向导声明派生自 CWinApp 的一个应用程序类。 MFC 应用程序向导还会生成包含以下项的实现文件:

应用程序类的消息映射。

空类构造函数。

声明类的唯一对象的变量。

InitInstance 成员函数的标准实现。

应用程序类放置在项目标头和主源文件中。 创建的类和文件名称基于你在 MFC 应用程序向导中提供的项目名称。 查看这些类的代码的最简单方法是通过类视图。

类视图(Visual Basic、C#、C++)

“类视图”显示为“解决方案资源管理器”的一部分并作为单独窗口 。 “类视图”显示应用程序的元素。
上部窗格显示命名空间、类型、接口、枚举和类,下部窗格显示属于在上部窗格中所选类型的成员。
通过使用此窗口,可以移到源代码(或“对象浏览器”,如果该元素在解决方案外部进行定义)中的成员定义。

不需要编译项目即可在“类视图”中查看其元素。 修改项目中的代码时,窗口进行刷新。

通过选择项目节点,然后选择“添加”按钮打开“添加新项”对话框,可以向项目添加代码 。 在单独的文件中添加代码。

如果项目签入源代码管理,则每个“类视图”元素均显示一个指示该文件源代码状态的图标。
该元素的快捷菜单上也提供常用的源代码管理命令,如“签出”、“签入”和“获取最新版本” 。

特殊 CWinApp 服务

除了运行消息循环以及支持你初始化应用程序然后进行清理之外,CWinApp 还提供了一些其他服务。

Shell 注册

默认情况下,MFC 应用程序向导使用户能够打开您的应用程序已创建的数据文件,方法是在文件资源管理器或文件管理器中打开它们。 如果你的应用程序是 MDI 应用程序,并且你为该应用程序创建的文件指定了扩展名,MFC 应用程序向导会将对 CWinApp 的 RegisterShellFileTypes 和 EnableShellOpen 成员函数的调用添加到它为你编写的 InitInstance 替代。

RegisterShellFileTypes 将您的应用程序的文档类型注册到文件资源管理器或文件管理器。 该函数可将项添加到 Windows 保留的注册数据库。 这些项注册每个文档类型、将文件扩展名与文件类型关联、指定用来打开应用程序的命令行并指定用来打开该类型的文档的动态数据交换 (DDE) 命令。

EnableShellOpen 通过以下方式完成这个过程:允许您的应用程序从文件资源管理器或文件管理器接收用来打开用户选择的文件的 DDE 命令。

CWinApp 中的此自动支持使您无需将 .reg 文件附加到您的应用程序或完成特殊安装工作。

如果要初始化应用程序的 GDI+(通过在 InitInstance 函数中调用 GdiplusStartup),则必须禁止 GDI+ 后台线程。

可通过将 GdiplusStartupInput 结构的 SuppressBackgroundThread 成员设置为 TRUE 来执行此操作。 禁止 GDI+ 后台线程时,应在进入和退出应用程序的消息循环之前调用 NotificationHook 和 NotificationUnhook。 有关这些调用的详细信息,请参阅 GdiplusStartupOutput。 因此,适合调用 GdiplusStartup 和挂钩通知函数的位置是在虚函数 CWinApp::Run 的替代中,如下所示:

int CMyWinApp::Run()
{
   GdiplusStartupInput gdiSI;
   GdiplusStartupOutput gdiSO;
   ULONG_PTR gdiToken;
   ULONG_PTR gdiHookToken;

   gdiSI.SuppressBackgroundThread = TRUE;
   GdiplusStartup(&gdiToken, &gdiSI, &gdiSO);
   gdiSO.NotificationHook(&gdiHookToken);
   int nRet = CWinApp::Run();

   gdiSO.NotificationUnhook(gdiHookToken);
   GdiplusShutdown(gdiToken);

   return nRet;
}

如果不禁止后台 GDI+ 线程,DDE 命令可能在其主窗口创建前提前发给应用程序。 shell 发出的 DDE 命令可能提前中止,从而产生错误消息。

文件管理器拖放

可从文件管理器或文件资源管理器中的文件视图将文件拖动到您的应用程序的窗口中。 例如,您可能使一个或多个文件拖动到 MDI 应用程序的主窗口,应用程序可在其中为这些文件检索文件名和打开 MDI 子窗口。

为了在应用程序中启用文件拖放,MFC 应用程序向导会在 InitInstance 中为主框架窗口编写对 CWnd 成员函数 DragAcceptFiles 的调用。 如果您不想实现拖放功能,则可以移除该调用。

您还可以使用 OLE 实现更常见的拖放功能 — 在文档之间或文档中拖动数据。 相关信息,请参阅 OLE 拖放一文。
跟踪最近使用的文档

当用户打开和关闭文件时,应用程序对象将跟踪四个最近使用的文件。 这些文件的名称将添加到“文件”菜单并在更改时更新。 框架会将这些文件名存储在与您的项目同名的注册表或 .ini 文件中,并在您的应用程序启动时从文件中读取它们。 MFC 应用程序向导创建的 InitInstance 替代包含对 CWinApp 成员函数 LoadStdProfileSettings 的调用,该调用从注册表或 .ini 文件加载信息(包括最近使用的文件名)。

这些项按如下方式进行存储:

在 Windows NT、Windows 2000 和更高版本中,值存储到注册表项。

在 Windows 3.x 中,值存储在 WIN.INI 文件中。

在 Windows 95 和更高版本中,值存储在缓存版的 WIN.INI 中。

CWinAppEx 类

CWinAppEx 处理应用程序状态,将此状态保存到注册表,从注册表加载此状态,初始化应用程序管理器,并将链接提供到同样的应用程序管理器。

公共方法
“属性” 	                                   说明
CWinAppEx::CleanState 	从 Windows 注册表中移除应用程序的相关信息。
CWinAppEx::EnableLoadWindowPlacement 	指定应用程序是否将从注册表加载主框架窗口的初始大小和位置。
CWinAppEx::EnableTearOffMenus 	为应用程序启用可拖曳菜单。
CWinAppEx::EnableUserTools 	允许用户在应用程序中创建自定义菜单命令。
CWinAppEx::ExitInstance 	由框架从 Run 成员函数内调用以退出此应用程序实例。 (重写 CWinApp::ExitInstance。)
CWinAppEx::GetBinary 	读取与指定的注册表值关联的二进制数据。
CWinAppEx::GetContextMenuManager 	返回指向全局 CContextMenuManager 对象的指针。
CWinAppEx::GetDataVersion 	
CWinAppEx::GetDataVersionMajor 	返回在 Windows 注册表中保存的应用程序的主版本。
CWinAppEx::GetDataVersionMinor 	返回在 Windows 注册表中保存的应用程序的次要版本。
CWinAppEx::GetInt 	从注册表中读取与指定值关联的数值数据。
CWinAppEx::GetKeyboardManager 	返回指向全局 CKeyboardManager 对象的指针。
CWinAppEx::GetMouseManager 	返回指向全局 CMouseManager 对象的指针。
CWinAppEx::GetObject 	从注册表中读取与指定值关联的 CObject 派生数据。
CWinAppEx::GetRegSectionPath 	返回注册表项路径的字符串。 该路径将提供的相对路径与应用程序路径连接起来。
CWinAppEx::GetRegistryBase 	返回应用程序的注册表路径。
CWinAppEx::GetSectionBinary 	从注册表中读取与指定键和值关联的二进制数据。
CWinAppEx::GetSectionInt 	从注册表中读取与指定键和值关联的数值数据。
CWinAppEx::GetSectionObject 	从注册表中读取与指定键和值关联的 CObject 数据。
CWinAppEx::GetSectionString 	从注册表中读取与指定键和值关联的字符串数据。
CWinAppEx::GetShellManager 	返回指向全局 CShellManager 对象的指针。
CWinAppEx::GetString 	从注册表中读取与指定值关联的字符串数据。
CWinAppEx::GetTooltipManager 	返回指向全局 CTooltipManager 对象的指针。
CWinAppEx::GetUserToolsManager 	返回指向全局 CUserToolsManager 对象的指针。
CWinAppEx::InitContextMenuManager 	初始化 CContextMenuManager 对象。
CWinAppEx::InitKeyboardManager 	初始化 CKeyboardManager 对象。
CWinAppEx::InitMouseManager 	初始化 CMouseManager 对象。
CWinAppEx::InitShellManager 	初始化 CShellManager 类
CWinAppEx::InitTooltipManager 	初始化 CTooltipManager 类。
CWinAppEx::IsResourceSmartUpdate 	
CWinAppEx::IsStateExists 	指示注册表中是否存在指定的键。
CWinAppEx::LoadState 	从注册表加载应用程序状态。
CWinAppEx::OnAppContextHelp 	当用户请求“自定义”对话框的上下文帮助时由框架调用。
CWinAppEx::OnViewDoubleClick 	当用户双击应用程序中的任意位置时调用用户定义的命令。
CWinAppEx::OnWorkspaceIdle 	
CWinAppEx::SaveState 	将应用程序框架状态写入 Windows 注册表。
CWinAppEx::SetRegistryBase 	设置默认注册表项的路径。 此项将用作所有后续注册表调用的根。
CWinAppEx::ShowPopupMenu 	显示弹出菜单。
CWinAppEx::WriteBinary 	将二进制数据写入指定的注册表值。
CWinAppEx::WriteInt 	将数值数据写入指定的注册表值。
CWinAppEx::WriteObject 	将从 CObject 类派生的数据写入指定的注册表值。
CWinAppEx::WriteSectionBinary 	将二进制数据写入指定的注册表项的值。
CWinAppEx::WriteSectionInt 	将数值数据写入指定的注册表项的值。
CWinAppEx::WriteSectionObject 	将从 CObject 类派生的数据写入指定的注册表项的值。
CWinAppEx::WriteSectionString 	将字符串数据写入指定的注册表项的值。
CWinAppEx::WriteString 	将字符串数据写入指定的注册表值。

用于创建 OLE 应用程序的操作顺序

下表显示了创建 OLE 链接和嵌入应用程序的角色和框架角色。 这些表示可用选项,而不是要执行的步骤序列。

创建 COM 组件。 	运行 MFC 应用程序向导。 在“复合文档支持”选项卡中选择“全服务器”或“微型服务器”。 	框架生成启用了 COM 组件功能的框架应用程序。 所有 COM 功能都可以传输到现有应用程序,只需稍作修改。
从头开始创建容器应用程序。 	运行 MFC 应用程序向导。 在“复合文档支持”选项卡中选择“容器”。使用类视图,转到源代码编辑器。 为 COM 处理程序函数填写代码。 	框架生成一个框架应用程序,该应用程序可以插入 COM 组件(服务器)应用程序创建的 COM 对象。
从头开始创建支持自动化的应用程序。 	运行 MFC 应用程序向导。 从“高级功能”选项卡中选择“自动化”。使用类视图在应用程序中公开用于自动化的方法和属性。 	框架生成可由其他应用程序激活和自动化的框架应用程序。

用于创建 ActiveX 控件的操作顺序

下表显示了在创建 ActiveX 控件(以前称为 OLE 控件)时的角色和框架的角色。

1.创建 ActiveX 控件框架。 	运行 MFC ActiveX 控件向导以创建控件。 在选项页中指定您需要的选项。 选项包括项目中控件的类型和名称、许可、子类和 About Box 方法。 	MFC ActiveX 控件向导为具有基本功能的 ActiveX 控件创建文件,包括应用程序、控件和属性页的源文件、资源文件、项目文件和其他,均根据你的规格定制。
2.无需添加自己的代码,即可查看控件和 Activ eX 控件向导提供的功能。 	生成 ActiveX 控件,并使用 Internet Explorer 或 TSTCON 示例对其进行测试。 	正在运行的控件能够调整大小并移动。 它还有一个可以调用的 About Box 方法(如果选择)。

3.实现控件的方法和属性。 	添加成员函数以提供控件数据公开接口,以实现特定于控件的方法和属性。 添加成员变量以保存数据结构,并在确定时使用事件处理程序触发事件。 	框架已经定义了一个映射以支持控件的事件、属性和方法,让你专注于属性和方法的实现方式。 默认属性页可查看,并且提供了默认 About Box 方法。

4.构造控件的属性页。 	使用 Visual C++ 资源编辑器直观地编辑控件的属性页界面:

- 创建其他属性页。
- 创建并编辑位图、图标和光标。

你还可以在对话框编辑器中测试对话框。 	MFC 应用程序向导创建的默认资源文件提供了很多您需要的资源。 利用 Visual C++,您可以轻松直观地编辑现有资源和添加新资源。

5.测试控件的事件、方法和属性。 	重新生成控件并使用测试容器来测试处理程序是否正确工作。 	可以调用控件的方法,并通过属性页接口或通过测试容器控制其属性。 此外,使用测试容器跟踪从控件触发的事件和控件容器收到的通知。

用于创建数据库应用程序的操作顺序

下表显示在编写数据库应用程序时的角色和框架角色。

Visual C++ 环境和向导不支持 DAO(尽管包含 DAO 类且你仍可以使用它们)。 Microsoft 建议将 ODBC 用于新的 MFC 项目。 应只在维护现有应用程序时使用 DAO。


决定是否使用 MFC ODBC 或 DAO 类。 	将 ODBC 用于新的 MFC 项目。 仅使用 DAO 来维护现有应用程序。 有关常规信息,请参阅数据访问编程一文。 	框架提供了支持数据库访问的类。
使用数据库选项创建主干应用程序。 	运行 MFC 应用程序向导。 选择“数据库支持”页上的选项。 如果选择创建记录视图的选项,则还应指定:

- 数据源和表名或名称
- 查询名称或名称。 	MFC 应用程序向导创建文件并指定必要包含内容。 根据指定的选项,文件可以包含记录集类。
设计数据库窗体或窗体。 	使用 Visual C++ 对话编辑器在记录视图类的对话框模板资源上放置控件。 	MFC 应用程序向导会创建一个空对话模板资源,供你填写。
根据需要创建其他记录视图和记录集类。 	使用类视图创建类以及使用对话编辑器来设计视图。 	类视图为新类创建其他文件。
根据需要在代码中创建记录集对象。 使用每个记录集来操作记录... 	记录集基于使用向导从 CRecordset 派生的类。 	ODBC 使用记录字段交换 (RFX) 在数据库与记录集的字段数据成员之间交换数据。 如果使用记录视图,对话数据交换 (DDX) 在记录集与记录视图上的控件之间交换数据。
...或在代码中为要打开的每个数据库创建一个显式 CDatabase。 	记录集对象以数据库对象为基础。 	数据库对象提供到数据源的接口。
将数据列动态绑定到记录集。 	在 ODBC 中,添加代码到派生记录集类以管理绑定。 请参阅记录集:动态绑定数据列 (ODBC) 一文。 	

对话框数据交换

对话框数据交换 (DDX) 是一种在对话框中初始化控件以及按用户收集数据输入的简单方式。 对话框数据验证 (DDV) 是一种在对话框中验证数据输入的简单方式。 若要在对话框中利用 DDX 和 DDV,请使用添加成员变量向导来创建数据成员并设置其数据类型和指定验证规则。
如果使用 DDX 机制,则可设置对话框对象的成员变量的初始值(通常在 OnInitDialog 处理程序或对话框构造函数中)。 就在显示对话框之前,框架的 DDX 机制会将成员变量的值传输到对话框中的控件,当对话框本身为响应 DoModal 或 Create 而出现时,这些控件将会显示在对话框中。 OnInitDialog 中的 CDialog 的默认实现调用 UpdateData 类的 CWnd 成员函数以在对话框中初始化控件。

当用户单击“确定”按钮时(或在你每次使用 TRUE 自变量调用 UpdateData 成员函数时),同一个机制都会将值从控件传输到成员变量。 对话框数据验证机制将验证为其指定了验证规则的所有数据项。

UpdateData 可以在两个方向进行,具体由传递给它的 BOOL 参数指定。 若要执行交换,UpdateData 将设置 CDataExchange 对象并调用对话框类的 CDialog 的 DoDataExchange 成员函数的重写。 DoDataExchange 采用 CDataExchange 类型的参数。 传递给 CDataExchange 的 UpdateData 对象表示交换的上下文,并将此类信息定义交换的方向。

当你(或代码向导)重写 DoDataExchange 时,可以指定对每个数据成员(控件)调用一个 DDX 函数。 每个 DDX 函数都了解如何基于由 CDataExchange 传递给 DoDataExchange 的 UpdateData 自变量提供的上下文双向交换数据。

MFC 提供了许多用于不同类型交换的 DDX 函数。 以下示例演示了一个 DoDataExchange 重写,其中调用两个 DDX 函数和一个 DDV 函数:

void CTestDialog::DoDataExchange(CDataExchange* pDX)
{
   CDialog::DoDataExchange(pDX);
   DDX_Check(pDX, IDC_MY_CHECKBOX, m_bVal);
   DDX_Text(pDX, IDC_MY_TEXTBOX, m_strName);
   DDV_MaxChars(pDX, m_strName, 20);
}

DDX_ 和 DDV_ 行是数据映射。 显示的示例 DDX 和 DDV 函数分别为复选框控件和编辑框控件。

如果用户取消模式对话框,OnCancel 成员函数将终止对话框,并且 DoModal 将返回 IDCANCEL 值。 在这种情况下,对话框和对话框对象之间不交换数据。

除了数据交换之外,还可以通过调用 DDV 函数指定验证,如对话框数据交换中的示例所示。 示例中的 DDV_MaxChars 调用验证在文本框控件中输入的字符串长度不超过 20 个字符。 如果验证失败,DDV 函数通常会使用消息框提醒用户,并且重点关注有问题的控件,以便用户可以重新输入数据。 给定控件的 DDV 函数必须在同一控件的 DDX 函数之后立即调用。

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

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

相关文章

【算法题目】【Python】一文刷遍贪心算法题目

文章目录介绍分配饼干K 次取反后最大化的数组和柠檬水找零摆动序列单调递增的数字介绍 贪心算法是一种基于贪心思想的算法,它每次选择当前最优的解决方案,从而得到全局最优解。具体来说,贪心算法在每一步都做出局部最优选择,希望…

Flutter——Isolate主线机制

简述 在DartFlutter应用程序启动时,会启动一个主线程其实也就是Root Isolate,在Root Isolate内部运行一个EventLoop事件循环。所以所有的Dart代码都是运行在Isolate之中的,它就像是机器上的一个小空间,具有自己的私有内存块和一个运行事件循…

Linux下LED灯驱动模板详解

一、地址映射我们先了解MMU,全称是Memory Manage Unit。在老版本的Linux中要求处理器必须有MMU,但是现在Linux内核已经支持五MMU。MMU主要完成的功能如下:1、完成虚拟空间到物理空间的映射2、内存保护,设置存储器的访问权限&#…

【Linux学习笔记】mmap-共享内存进程通信 vs 有名信号量和无名信号量

mmap和信号量实现进程间通信相关mmap1. mmap 使用的注意事项2. mmap的两种映射3. mmap调用接口以及参数4. 使用存储映射区实现父子进程间通信(有名)父子进程通信的三种方式unlink5. 创建匿名存储映射区6. 通过存储映射区实现非血缘关系进程间的通信信号量…

SiteSucker for macOS + CRACK

SiteSucker for macOS CRACK SiteSucker是一个简单的macOS应用程序,允许您下载网站。它还可以将网站、网页、背景图片、视频和许多其他文件复制到Mac的硬盘上。 SiteSucker是一个Macintosh应用程序,可以自动下载Internet上的网页。它通过将网站的页面、…

遥感影像道路提取算法——SGCN

论文介绍 Split Depth-wise Separable Graph Convolution Network for Road Extraction in Complex Environment from High-resolution Remote Sensing Imagery(TGRS) 用于从高分辨率遥感图像(TGRS)中提取复杂环境中道路的分割深…

java对象的创建与内存分配机制

文章目录对象的创建与内存分配机制对象的创建类加载检查分配内存初始化零值设置对象头指向init方法其他:指针压缩对象内存分配对象在栈上分配对象在Eden区中分配大对象直接分配到老年代长期存活的对象进入老年代对象动态年龄判断老年代空间分配担保机制对象的内存回…

Spring的核心模块:Bean的生命周期(内含依赖循环+业务场景)。

Bean的生命周期前言为什么要学习Bean的生命周期前置知识Spring Post-processor(后置处理器)Aware接口简单介绍Bean的实例化过程为什么会有bean的实例化?过程Bean的初始化阶段为什么会有Bean的初始化?Bean的初始化目的是什么&#…

线性和非线性最小二乘问题的常见解法总结

线性和非线性最小二乘问题的各种解法 先看这篇博客,非常好:线性和非线性最小二乘问题的各种解法 1. 线性最小二乘问题有最优解 但是面对大型稀疏矩阵的时候使用迭代法效率更好。 迭代法 有Jacobi迭代法、 Seidel迭代法及Sor法 【数值分析】Jacobi、Se…

[ubuntu][GCC]gcc源码编译

1.下载gcc安装包 https://ftp.gnu.org/gnu/gcc/ 选择一个需要的gcc版本,下载。 2.下载依赖包 查看下载的gcc安装包中contrib文件夹下的download_prerequisites文件,查看需要的依赖包版本。 根据download_prerequisites中红框位置的信息,在下…

JSON.stringify()的5种使用场景

JSON.stringify() 方法将一个JavaScript对象或值转换为JSON字符串,如果指定了一个replacer函数,则可以选择性地替换值,或者指定的replacer是数组,则可选择性地仅包含数组指定的属性。 语法如下: JSON.stringify(value…

电子技术课程设计基于FPGA的音乐硬件演奏电路的设计与实现

wx供重浩:创享日记 对话框发送:乐曲电路 免费获取完整无水印论文报告(包含电路图) 文章目录一、设计任务要求二、总体框图三、选择器件四、功能模块五、总体设计电路图六、结束语一、设计任务要求 1、课程设计题目 设计一个乐曲演…

【Flutter从入门到入坑之三】Flutter 是如何工作的

【Flutter从入门到入坑之一】Flutter 介绍及安装使用 【Flutter从入门到入坑之二】Dart语言基础概述 【Flutter从入门到入坑之三】Flutter 是如何工作的 本文章主要以界面渲染过程为例,介绍一下 Flutter 是如何工作的。 页面中的各界面元素(Widget&…

使数组和能被P整除[同余定理+同余定理变形]

同余定理同余定理变形前言一、使数组和能被P整除二、同余定理变形总结参考资料前言 同余定理非常经典,采用前缀和 map,当两个余数前缀和为一个值时,则中间一段子数组刚好对P整除。但是能否找到前面是否有一段子数组和可以对P整除呐&#xf…

认识CSS之元素显示模式

🌟所属专栏:前端只因变凤凰之路🐔作者简介:rchjr——五带信管菜只因一枚😮前言:该系列将持续更新前端的相关学习笔记,欢迎和我一样的小白订阅,一起学习共同进步~👉文章简…

深度学习训练营之数据增强

深度学习训练营学习内容原文链接环境介绍前置工作设置GPU加载数据创建测试集数据类型查看以及数据归一化数据增强操作使用嵌入model的方法进行数据增强模型训练结果可视化自定义数据增强查看数据增强后的图片学习内容 在深度学习当中,由于准备数据集本身是一件十分复杂的过程,…

Python 中 KeyError: 0 exception 错误

Python “KeyError: 0” 异常是在我们尝试访问不包含0 这个键的时候去访问该键而引起的。 要解决该错误,请在尝试访问字典之前在字典中设置键,或者如果键不存在,则使用 dict.get() 获取默认值。 下面是一个产生上述错误的示例 my_dict {1…

KDZD互感器二次负载测试仪

一、概述 电能计量综合误差过大是电能计量中普遍存在的一个关键问题。电压互感器二次回路压降引起的计量误差往往是影响电能计量综合误差的因素。所谓电压互感器二次压降引起的误差,就是指电压互感器二次端子和负载端子之间电压的幅值差相对于二次实际电压的百分数…

五分钟了解JumpServer V2.* 与 v3 的区别

一、升级注意项 1、梳理数据。JumpServer V3 去除了系统用户功能,将资产与资产直接绑定。当一个资产名下有多个同名账号,例如两个root用户时,升级后会自动合并最后一个root,不会同步其他root用户。升级前需保证每一个资产只拥有一…

即时通讯系列-N-客户端如何在推拉结合的模式下保证消息的可靠性展示

结论先行 原则: server拉取的消息一定是连续的原则: 端侧记录的消息的连续段有两个作用: 1. 记录消息的连续性, 即起始中间没有断层, 2. 消息连续, 同时意味着消息是最新的,消息不是过期的。同…