吕鑫MFC学习系列九

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张图片

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

1:保存到注册表:
关于CWinApp::SetRegistryKey方法
如果在Inistance当中执行了 SetRegisterKey()方法
那么在调用 WriteProfileInt的时候,写入的数据将会保存到注册表当中
如果没有执行SetRegisterKey()方法,则写入的数据将会保存到INI文件当中
吕鑫MFC学习系列九_第2张图片
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"));//调试查看theApp

	CWnd* 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
// CMFCmemberApp
BEGIN_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;
}

你可能感兴趣的:(吕鑫MFC学习系列九)