您的位置:首页 > 其它

MFC中主窗口显示前启动窗口的实现

2014-01-03 14:28 531 查看
MFC程序在启动主窗口之前要首先出现一个启动界面,根据在启动界面选择的模式不同再调整主界面的菜单项。

之前以为蛮简单的,可是在做的过程中遇到了各种问题,一个个地解决,最后终于完成了。

下面是处理的流程:

1.在程序的CMainFrame类中重载ActivateFrame函数:

void CMainFrame::ActivateFrame(int nCmdShow)
{
	// TODO: 在此添加专用代码和/或调用基类
	nCmdShow=SW_HIDE;
	CFrameWnd::ActivateFrame(nCmdShow);
}
2.在CXXApp(我的工程名为CInitialWindowApp)中修改InitInstance函数:

//pFrame->ShowWindow(SW_SHOW);
	//pFrame->UpdateWindow();
	pFrame->ShowWindow(SW_HIDE);


将第一行和第二行代码注释掉,加上第三行代码

3.然后新建一个启动界面的对话框资源,在上面添加两个按钮,用来选择哪个模式,点击不同的按钮,主窗口显示,但是不同的主窗口中的菜单会不同,下面是启动界面:



两个按钮的ID分别为:IDC_MODE_ONE和IDC_MODE_TWO

4.在CInitialWindowApp的头文件中添加一个指向框架类的指针:

CMainFrame * m_pMainFrame;

注意同时也需要在CInitialWindowApp的头文件中添加#include "MainFrm.h"。

5.在CMainFrame的构造函数中初始化上面声明的这个指针:

theApp.m_pMainFrame=this;
6.生成对话框的类为CPreInitialWindow,并在这个类中添加两个按钮的事件响应函数。

void CPreInitialWindow::OnBnClickedModeOne()
{
	// TODO: 在此添加控件通知处理程序代码
	theApp.mode=MODE_ONE;
	theApp.m_pMainFrame->ShowWindow(SW_SHOW);
	ShowWindow(SW_HIDE);
}

void CPreInitialWindow::OnBnClickedModeTwo()
{
	// TODO: 在此添加控件通知处理程序代码
	theApp.mode=MODE_TWO;
	theApp.m_pMainFrame->ShowWindow(SW_SHOW);
	ShowWindow(SW_HIDE);
}
上面的代码中还有一个在CInitialWindowApp中声明的变量mode,它是一个枚举类型:

enum MODE{MODE_ONE,MODE_TWO};
这个变量用来记录在启动界面中选择的是模式一,还是模式二。

7.在CMainFrame的消息WM_CREATE的响应函数OnCreate中添加下面的代码:

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

	// 创建一个视图以占用框架的工作区
	if (!m_wndView.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,
		CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, NULL))
	{
		TRACE0("未能创建视图窗口\n");
		return -1;
	}

	CPreInitialWindow initWindow;
	initWindow.DoModal();

	return 0;
}

8.重写CMainFrame的的消息WM_CLOSE的响应函数OnClose,在其中加入一行代码,否则窗口关闭后进程将依然在执行,还没搞明白为什么。

void CMainFrame::OnClose()
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值

	//下面这行代码是必须的,进程退出
	PostQuitMessage(0);
	
	CFrameWnd::OnClose();
}


完成上面的工作后就实现了程序运行后首先出现一个启动界面,点击启动界面中的按钮弹出主窗口的功能。

9.接下来的处理是选择不同的模式时主窗口加载的菜单项不同,首先添加两个菜单资源:

IDR_MODEONE
IDR_MODETWO
10.然后在CMainFrame中添加两个成员变量:

public:
	CMenu *m_pModeOne;//模式一下的菜单指针
	CMenu *m_pModeTwo;//模式二下的菜单指针
11.在CMainFrame的方法PreCreateWindow方法中将上面的两个指针实例化:

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

	cs.style = WS_OVERLAPPED | WS_CAPTION | FWS_ADDTOTITLE;

	cs.dwExStyle &= ~WS_EX_CLIENTEDGE;
	cs.lpszClass = AfxRegisterWndClass(0);

	m_pModeOne=new CMenu;
	m_pModeTwo=new CMenu;

	m_pModeOne->LoadMenuW(IDR_MODEONE);
	m_pModeTwo->LoadMenuW(IDR_MODETWO);

	return TRUE;
}
12.在CMainFrame加入WM_SHOWWINDOW消息的响应函数OnShowWindow,添加如下代码:
void CMainFrame::OnShowWindow(BOOL bShow, UINT nStatus)
{
	CFrameWnd::OnShowWindow(bShow, nStatus);

	// TODO: 在此处添加消息处理程序代码
	/************************************************************************/
	/* bShow为真表示窗口要被显示,bShow为假表示窗口要被隐藏                                                                     */
	/************************************************************************/
	if (bShow)
	{
		if (nStatus==0)//由于ShowWindow函数的调用导致显示时nStaus为0
		{
			//根据在CPreInitialWindow窗口中选择的模式不同加载不同的菜单项或其他资源
			if (theApp.mode==MODE_ONE)
			{
				SetMenu(m_pModeOne);
			}
			else{
				SetMenu(m_pModeTwo);
			}
		}
	}
}


上面的处理完成后就可以在点击不同的模式的时候主窗口显示并加载不同的菜单资源了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: