更新时间:2015-09-15 14:11:49浏览次数:1+次
学习心得之七---程序启动画面的设计
我们基于对话框创建工程项目,命名为RunForm,然后,我们为工程添加一个对话框类,我们先在资源视图类上,增加一个对话框,双击该对话框,我们为它关联一个类,名字叫CRunMode,然后在头文件中添加为这个类添加两个成员变量,并在构造函数中实例化。
COLORREF m_BkColor;//背景颜色
CRgn m_Rgn;//区域变量
CRgn:封装Windows图形设备接口(GDI)区域
CRunMode::CRunMode(CWnd* pParent /*=NULL*/)
: CDialog(CRunMode::IDD, pParent)
{
//{{AFX_DATA_INIT(CRunMode)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
m_BkColor=RGB(0,0,255);//我喜欢蓝色,初始化就设为蓝色了
}
接下来我们设置字体,画笔,启动区域,设备上下文等,我们为CRunForm类,添加WM_InitDialog消息,
BOOL CRunMode::OnInitDialog()
{
CDialog::OnInitDialog();
// TODO: Add extra initialization here
SetTimer(1,1000,NULL);
CFont font;
font.CreateFont(50, 30, 0, 0, FW_HEAVY, TRUE, FALSE,
0, ANSI_CHARSET, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
DEFAULT_PITCH | FF_SWISS, "宋体");
CDC *pDC = GetDC();
CPen pen(PS_SOLID, 2, RGB(255, 0, 0));
pDC->SelectObject(&pen); //选中画笔
pDC->BeginPath(); //开始一个路径
pDC->SetBkMode(OPAQUE );
CFont *pOldFont = pDC->SelectObject(&font); //选中创建的字体
pDC->TextOut(10, 30, "C++技术网"); //输出文本
pDC->EndPath(); //关闭路径
pen.DeleteObject();
font.DeleteObject();
pDC->SelectObject(pOldFont);
m_Rgn.CreateFromPath(pDC);
SetWindowRgn(m_Rgn,TRUE);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
我们为启动画面设置一个定时器,使得它每秒字体颜色变化一次,接着我们创建字体,调用函数CreateFont(...)
BOOL CreateFont(
int nHeight,
int nWidth,
int nEscapement,
int nOrientation,
int nWeight,
BYTE bItalic,
BYTE bUnderline,
BYTE cStrikeOut,
BYTE nCharSet,
BYTE nOutPrecision,
BYTE nClipPrecision,
BYTE nQuality,
BYTE nPitchAndFamily,
LPCTSTR lpszFacename
);
对于参数,我就不一一讲解了,我们可以查MSDN,(给网站在线查MSDN链接),然后我们创建设备上下文描述表DC,当我们需要字体,画刷,画笔,实现对窗口显示区域的GDI操作,如划线、写文本、绘制位图、填充等,就构造DC,接下来们创建画笔,并将他选入设备描述表,当然最后我们要将设备对象删除。为了使用某种GDI对象,一般来说,需要构造新的GDI对象,然后将这个新的GDI对象选入一个设备描述表进行绘制,将设备描述表中原来的GDI对象保留。当绘制工作结束时,在退出应用程序前将旧的GDI对象在选回设备描述表,将先前的GDI对象删除。我们继续为字体启动程序设计背景模式,调用函数SetBkMode():
int SetBkMode(
int nBkMode
);
nBkMode:指定将架构集。 此参数可以是下列值之一:
OPAQUE :背景用该文本,已阴影的画笔之前的当前背景色,或者绘制钢笔。 这是默认背景模式。TRANSPARENT: 背景不在绘制图像之前已更改。
简单说就是,第一个参数使得区域里的字体透明,而非字体的部分,就用颜色填充,第二个,就相反咯。
下一句就是我们把我们创建的字体选入设备描述表,并将其返回给一个字体对象,以便最后重新将字体选回给描述表,这个是好习惯,我们创建字体,画笔,画刷等,在最后的时候最好将它选回描述表,万事具备了,我们已经用笔画好了,字的字体也选好了,现在就是写字咯。
m_Rgn.CreateFromPath(pDC);创建从中选择到特定设备上下文的路径的区域。简单点就是说,根据传入这个函数的参数,我们为它建立一个区域。
SetWindowRgn(m_Rgn,TRUE);
int SetWindowRgn(
HRGN hRgn,
BOOL bRedraw
);
hRgn
对区域的句柄。
bRedraw
如果 TRUE,操作系统在设置该区域后重绘windows;否则,它不。 通常,因此,如果窗口可见,设置 bRedraw 到 TRUE。 如果设置为 TRUE,该系统发送 WM_WINDOWPOSCHANGING 和 WM_WINDOWPOSCHANGED 信息到窗口。
接下来我们设置定时器消息:
void CRunMode::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
int nRed=rand()%255;
int nGreen=rand()%255;
int nBlue=rand()%255;
Invalidate();//核心语句
m_BkColor=RGB(nRed,nGreen,nBlue);
CDialog::OnTimer(nIDEvent);
}
rand(),使得我们随机的更改字体区域的颜色。我们看看核心语句,没有这句代码,我们的启动画面不会变换多种颜色。
void Invalidate(
BOOL bErase = TRUE
);
无效 CWnd整个工作区。bErase 参数指定是将清除在更新区域内的背景,当更新区域过程。 如果 bErase 是 TRUE,清除后台,当 BeginPaint 成员函数调用时;如果 bErase 是 FALSE,背景不变。 如果 bErase 是更新区域的任何部分的TRUE,在整个区域,而不仅仅用于在给定节中,清除背景。
void CRunMode::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
CRect clientRC;
GetClientRect(clientRC);
dc.FillRect(clientRC,&CBrush(m_BkColor));
// Do not call CDialog::OnPaint() for painting messages
}
void FillRect(
LPCRECT lpRect,
CBrush* pBrush
);
查MSDN,我们看到CBrush()有四个重载函数,而其中恰好有参数是COLORREF类的重载函数,因此,我们可以为FillRect()的第二个参数传入那样的参数。我们现在做完了吗?程序代码都不缺了,该有的都有了,来,我们看看!我们直接运行试试,我们会发现压根没有出现启动画面!只是一个对话框,而且还不是我们自己新增的对话框,而是我们基于对话框创建的工程中的那个对话框,为什么?我们相信,当我们运行VC时,应用程序首先进去的是哪里?没错就是我们的CApp,因此,我们需要在这个类中写点代码,在哪写呢?那就是我们的InitInstance(),这个函数负责进行特定的应用程序的初始化我们来看看它的代码:
BOOL CRunFormApp::InitInstance()
{
AfxEnableControlContainer();
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need.
#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif
CRunFormDlg dlg;/*这里*/
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();//看这里
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
}*/
// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
// GetClientRect(clientRC);
}
我们看我所做的标记那,发现有一个DoModal()函数,我们知道他就是创建一个模态对话框的,再往前看,我们发现它是CRunFormDlg类的,因此,当我们运行时,出现的那个对话框就是我们这里创建的对话框,就是我们的工程所基于的那个对话框,那么,我们想要运行我们自己添加的那个对话框,也就是只要添加相似的代码就行了,但是你得注意位置哦!们应该放在我所标注的“这里”的前面,要不然还是没用。我们看看需要加的代码:
CRunMode runmode;
runmode.DoModal();
本来想加几张运行图片的,但不知怎么老出错,我这就不上传了,你自己可以试试运行结果。
我们应该学得更多,因此下个程序就是实现图片启动画面哦,更深入的理解,学习界面启动画面的知识。
相关资讯