吕鑫MFC学习系列九

来源:互联网 发布:音乐国家知乎 编辑:程序博客网 时间:2024/04/29 12:35
CWinApp类的基类:CObject->CCmdTarget->CWinThread->CWinApp
一、CWinApp类成员变量:
1、WinMain的四个参数:
// Startup args (do not change)
HINSTANCE m_hInstance;//进程句柄,用于加载程序内资源等功能。
HINSTANCE m_hPrevInstance;//暂时无用
LPTSTR m_lpCmdLine; //进程启动前,以字符串形式传入的一些数据。
int m_nCmdShow; //进程启动前,要求进程以什么显示状态出现。
2、应用程序名
// Running args (can be changed in InitInstance)
LPCTSTR m_pszAppName;
(a、ExeName中获取,b、AFX_IDS_APP_TITLE中获取,c、CWinApp构造函数)
//  (from constructor or AFX_IDS_APP_TITLE)
LPCTSTR m_pszExeName;       // executable name (no spaces)
LPCTSTR m_pszHelpFilePath;  // default based on module path
LPCTSTR m_pszProfileName;   // default based on app name
LPCTSTR m_pszRegistryKey;   // used for registry entries
3、基类中的成员变量:
CWnd* m_pMainWnd;       // main window (usually same AfxGetApp()->m_pMainWnd)
CWnd* m_pActiveWnd;     // active main window (may not be m_pMainWnd)
BOOL m_bAutoDelete;     // enables 'delete this' after thread termination
// only valid while running
HANDLE m_hThread;       // this thread's HANDLE
operator HANDLE() const;
DWORD m_nThreadID;      // this thread's ID
二、CWinApp类成员函数:
CWinApp(LPCTSTR lpszAppName=NULL);可以通过构造函数修改AppName。
HCURSOR LoadCursor( UINT nIDResource ) const;
HCURSOR LoadStandardCursor(LPCTSTR szCur)const;
HICON LoadIcon( UINT nIDResource ) const;
HICON LoadStandardIcon(LPCTSTR szIcon) const;
缺省保存进入app.ini,如果调用SetRegistryKey函数之后,配置数据将写入到注册表对应的键值下
UINT GetProfileInt( LPCTSTR lpszSection, LPCTSTR lpszEntry, int nDefault );
CString GetProfileString(LPCTSTR szSection, LPCTSTR szEntry, LPCTSTR szDefault = NULL );
BOOL WriteProfileInt(LPCTSTR szSection, LPCTSTR szEntry, int nValue );
BOOL WriteProfileString(LPCTSTR szSect, LPCTSTR szEntry, LPCTSTR lpszValue );
void SetRegistryKey( LPCTSTR lpszRegistryKey );
void SetDialogBkColor(COLORREF clrBk = RGB(192, 192, 192), COLORREF clrText = RGB(0, 0, 0) );
三、Afx开头的MFC全局函数:
AfxGetApp():获取theApp对象地址;
AfxGetThread():获取theApp对象地址;
AfxGetInstanceHandle():获取theApp.m_hInstance进程句柄。
AfxGetResourceHandle(): 一般情况下ResourceHandle就是InstanceHandle。  
AfxGetAppName():获取CWinApp类成员变量theApp.m_pszAppName字符串;
AfxGetMainWnd():调用了CWinApp类基类函数GetMainWnd();
优先返回m_pMainWnd,如果m_pMainWnd为空,就通过GetActiveWindow函数获取一个激活的窗口。

GetModuleFileName:API函数用于获取执行文件或者DLL模块的具体路径和文件名

=========================================================================================

前面已经介绍过CWinApp类,现在实现以下成员变量和成员函数的使用:

除了窗口显示的几个功能外,还有两个功能,关闭窗口时候保存窗口位置和不同位置不同按钮显示的光标不同。

成员变量比较简单,就直接看后面代码吧,两个功能简单说明一下。


MFC关闭窗口时候保存窗口位置:

1:保存到注册表:
关于CWinApp::SetRegistryKey方法
如果在Inistance当中执行了 SetRegisterKey()方法
那么在调用 WriteProfileInt的时候,写入的数据将会保存到注册表当中
如果没有执行SetRegisterKey()方法,则写入的数据将会保存到INI文件当中
2、窗口摧毁时候保存窗口的位置

3、初始化窗口的位置,上次关闭时候所在的位置

4、记得在InitDialog中加入InitRect()函数的调用

不同位置不同按钮显示的光标不同:

通过加载不同的ID显示不同的光标。

详细代码:

// MFCmemberDlg.cpp : 实现文件//#include "stdafx.h"#include "MFCmember.h"#include "MFCmemberDlg.h"#include "afxdialogex.h"#ifdef _DEBUG#define new DEBUG_NEW#endif// 用于应用程序“关于”菜单项的 CAboutDlg 对话框class CAboutDlg : public CDialogEx{public:CAboutDlg();// 对话框数据enum { IDD = IDD_ABOUTBOX };protected:virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持// 实现protected:DECLARE_MESSAGE_MAP()};CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD){}void CAboutDlg::DoDataExchange(CDataExchange* pDX){CDialogEx::DoDataExchange(pDX);}BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)END_MESSAGE_MAP()// CMFCmemberDlg 对话框CMFCmemberDlg::CMFCmemberDlg(CWnd* pParent /*=NULL*/): CDialogEx(CMFCmemberDlg::IDD, pParent){m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON1);}void CMFCmemberDlg::DoDataExchange(CDataExchange* pDX){CDialogEx::DoDataExchange(pDX);}BEGIN_MESSAGE_MAP(CMFCmemberDlg, CDialogEx)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_WM_MOUSEMOVE()ON_WM_SETCURSOR()ON_WM_DESTROY()END_MESSAGE_MAP()BOOL CMFCmemberDlg::OnInitDialog(){CDialogEx::OnInitDialog();//int nLeft=theApp.GetProfileIntW(L"WindowRect", L"left",10);InitRect();/*CString str;str.Format(_T("m_nCndShow=%d"), theApp.m_nCmdShow);SetWindowText(str);*/CString str;str.Format(_T("left=%d,right=%d,top=%d,bottom=%d"), theApp.GetProfileInt(L"SETTING", L"left", -1), theApp.GetProfileInt(L"SETTING", L"right", -1), theApp.GetProfileInt(L"SETTING", L"top", -1), theApp.GetProfileInt(L"SETTING", L"bottom", -1));SetWindowText(str);SetDlgItemText(IDC_APPNAME,theApp.m_pszAppName);SetDlgItemText(IDC_EXENAME, theApp.m_pszExeName);SetDlgItemText(IDC_HELPNAME, theApp.m_pszHelpFilePath);SetDlgItemText(IDC_REGISTKEY, theApp.m_pszRegistryKey);SetDlgItemText(IDC_PROFILE, theApp.m_pszProfileName);ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX < 0xF000);CMenu* pSysMenu = GetSystemMenu(FALSE);if (pSysMenu != NULL){BOOL bNameValid;CString strAboutMenu;bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);ASSERT(bNameValid);if (!strAboutMenu.IsEmpty()){pSysMenu->AppendMenu(MF_SEPARATOR);pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);}}//HICON hIcon=theApp.LoadIconW(IDI_ICON1);//HICON hIcon = AfxGetApp()->LoadIconW(IDI_ICON1);//HICON hIcon = ::LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_ICON1));//HICON hIcon = ::LoadIcon(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(IDI_ICON1));//HICON hIcon = ::LoadIcon(NULL, MAKEINTRESOURCE(IDI_QUESTION));//系统图标/*#define IDI_APPLICATION     MAKEINTRESOURCE(32512)#define IDI_HAND            MAKEINTRESOURCE(32513)#define IDI_QUESTION        MAKEINTRESOURCE(32514)#define IDI_EXCLAMATION     MAKEINTRESOURCE(32515)#define IDI_ASTERISK        MAKEINTRESOURCE(32516)*/HICON hIcon = ::LoadIcon(NULL, MAKEINTRESOURCE(IDI_QUESTION));SetIcon(hIcon, TRUE);// 设置大图标SetIcon(hIcon, FALSE);// 设置小图标//AfxMessageBox(_T("测试AppName"));//调试查看theAppCWnd* pWnd = AfxGetMainWnd();HINSTANCE hInst = AfxGetInstanceHandle();return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE}void CMFCmemberDlg::OnSysCommand(UINT nID, LPARAM lParam){if ((nID & 0xFFF0) == IDM_ABOUTBOX){CAboutDlg dlgAbout;dlgAbout.DoModal();}else{CDialogEx::OnSysCommand(nID, lParam);}}// 如果向对话框添加最小化按钮,则需要下面的代码//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,//  这将由框架自动完成。void CMFCmemberDlg::OnPaint(){if (IsIconic()){CPaintDC dc(this); // 用于绘制的设备上下文SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);// 使图标在工作区矩形中居中int cxIcon = GetSystemMetrics(SM_CXICON);int cyIcon = GetSystemMetrics(SM_CYICON);CRect rect;GetClientRect(&rect);int x = (rect.Width() - cxIcon + 1) / 2;int y = (rect.Height() - cyIcon + 1) / 2;// 绘制图标dc.DrawIcon(x, y, m_hIcon);}else{CRect rect;CPaintDC dc(this);GetClientRect(rect);dc.FillSolidRect(rect, RGB(0, 255, 0));CDialogEx::OnPaint();}}//当用户拖动最小化窗口时系统调用此函数取得光标//显示。HCURSOR CMFCmemberDlg::OnQueryDragIcon(){return static_cast<HCURSOR>(m_hIcon);}void CMFCmemberDlg::OnMouseMove(UINT nFlags, CPoint point){HCURSOR hCur = theApp.LoadCursorW(IDC_CURSOR1);SetCursor(hCur);CDialogEx::OnMouseMove(nFlags, point);}extern CMFCmemberApp theApp;#ifndef IDC_HAND#define IDC_HAND            MAKEINTRESOURCE(32649)#endif BOOL CMFCmemberDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message){if (pWnd == this){HCURSOR hCur = theApp.LoadStandardCursor(IDC_CROSS);SetCursor(hCur);return TRUE;}switch (pWnd->GetDlgCtrlID()){case IDOK:case IDCANCEL:{HCURSOR hCur = theApp.LoadStandardCursor(IDC_HAND);SetCursor(hCur);return TRUE;}}return CDialogEx::OnSetCursor(pWnd, nHitTest, message);//设置系统缺省光标}void CMFCmemberDlg::OnDestroy(){CDialogEx::OnDestroy();//theApp.WriteProfileInt(L"WindowRect",L"left",100);CRect rect;GetWindowRect(rect);theApp.WriteProfileInt(L"SETTING", L"left", rect.left);theApp.WriteProfileInt(L"SETTING", L"right", rect.right);theApp.WriteProfileInt(L"SETTING", L"top", rect.top);theApp.WriteProfileInt(L"SETTING", L"bottom", rect.bottom);}void CMFCmemberDlg::InitRect(){int nLeft = theApp.GetProfileInt(L"SETTING", L"left", -1);if (nLeft < 0)return;int nRight = theApp.GetProfileInt(L"SETTING", L"right", -1);if (nRight < 0)return;int nTop = theApp.GetProfileInt(L"SETTING", L"top", -1);if (nTop < 0)return;int nBottom = theApp.GetProfileInt(L"SETTING", L"bottom", -1);if (nBottom < 0)return;MoveWindow(nLeft, nTop, nRight - nLeft, nBottom - nTop);}
// MFCmember.cpp : 定义应用程序的类行为。#include "stdafx.h"#include "MFCmember.h"#include "MFCmemberDlg.h"#ifdef _DEBUG#define new DEBUG_NEW#endif// CMFCmemberAppBEGIN_MESSAGE_MAP(CMFCmemberApp, CWinApp)ON_COMMAND(ID_HELP, &CWinApp::OnHelp)END_MESSAGE_MAP()// CMFCmemberApp 构造CMFCmemberApp::CMFCmemberApp() :CWinApp(_T("初始化设置")){}// 唯一的一个 CMFCmemberApp 对象CMFCmemberApp theApp;// CMFCmemberApp 初始化BOOL CMFCmemberApp::InitInstance(){CWinApp::InitInstance();// 创建 shell 管理器,以防对话框包含// 任何 shell 树视图控件或 shell 列表视图控件。CShellManager *pShellManager = new CShellManager;// 激活“Windows Native”视觉管理器,以便在 MFC 控件中启用主题CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));SetRegistryKey(_T("250杀毒"));CMFCmemberDlg dlg;m_pMainWnd = &dlg;SetDialogBkColor(RGB(0, 0, 255), RGB(255, 0, 0));INT_PTR nResponse = dlg.DoModal();if (nResponse == IDOK){// TODO:  在此放置处理何时用//  “确定”来关闭对话框的代码}else if (nResponse == IDCANCEL){// TODO:  在此放置处理何时用//  “取消”来关闭对话框的代码}else if (nResponse == -1){TRACE(traceAppMsg, 0, "警告: 对话框创建失败,应用程序将意外终止。\n");TRACE(traceAppMsg, 0, "警告: 如果您在对话框上使用 MFC 控件,则无法 #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS。\n");}// 删除上面创建的 shell 管理器。if (pShellManager != NULL){delete pShellManager;}// 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,//  而不是启动应用程序的消息泵。return FALSE;}

0 0