孙鑫MFC视频源码(winmain)
- 格式:doc
- 大小:16.50 KB
- 文档页数:3
【干货】孙鑫MFC建立ActiveX_Clock控件属性设置Interval崩溃问题学习MFC编程第18讲ActiveX控件,然后编写了测试程序,发现在控件属性变化时,程序会崩溃,截图为:孙鑫老师或则网上的前辈们总结为:Clock控件放到VB 的Form上时,该控件的窗体已经创建,也就是说,CClockCtrl 类的OnCreate()方法被执行了,这样就设置了定时器,而在VC 的对话框上插入Clock 控件时,却没有调用CClockCtrl类的OnCreate()方法,而在修改Interval 属性时,会调用CClockCtrl 类的OnIntervalChanged() 方法,在这个方法中,调用了KillTimer(1) ,因为定时器根本就没有创建,因此就出现了非法操作。
这可能是因为对话框并不是真正的容器组件。
解决办法,用一个变量保存定时器的返回值,然后在OnIntervalChanged() 方法中对返回值进行判断。
可是经过上述说法,我更改了程序,主要有头文件int m_nTimer;// 一个变量保存定时器的返回值m_Interval;//保存定时器时间间隔OnCreate函数int CCActiveXCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct){if (COleControl::OnCreate(lpCreateStruct) == -1)return -1;// TODO: 在此添加您专用的创建代码m_nTimer = SetTimer(1,m_Interval,NULL);return 0;}定时器处理void CCActiveXCtrl::OnIntervalChanged(void){AFX_MANAGE_STATE(AfxGetStaticModuleState());// TODO: 在此添加属性处理程序代码if (m_Interval<1000 | m_Interval>6000){m_Interval = 1000;}else{m_Interval = m_Interval/1000*1000;}if (m_nTimer != 0){KillTimer(m_nTimer);}SetTimer(m_nTimer,m_Interval,NULL);BoundPropertyChanged(0x2);}更改完以后,经过不断测试,发现上述问题没有改善。
第6课,菜单及与菜单相关的编程:新建一个单文档MFC程序。
消息响应的四个顺序:VIEW类,DOC类,框架类,APP类。
⏹标准消息除WM_COMMAND之外,所有以WM_开头的消息。
从CWnd派生的类,都可以接收到这类消息。
⏹命令消息来自菜单、加速键或工具栏按钮的消息。
这类消息都以WM_COMMAND呈现。
在MFC中,通过菜单项的标识(ID)来区分不同的命令消息;在SDK中,通过消息的wParam 参数识别。
从CCmdTarget派生的类,都可以接收到这类消息。
⏹通告消息由控件产生的消息,例如,按钮的单击,列表框的选择等均产生此类消息,为的是向其父窗口(通常是对话框)通知事件的发生。
这类消息也是以WM_COMMAND形式呈现。
从CCmdTarget派生的类,都可以接收到这类消息。
从CWnd派生的类可以接收标准消息和命令消息和通告消息。
菜单消息路由过程:view—doc—view—frame—app下面是菜单:子菜单,菜单项。
在int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)中添加:GetMenu()->GetSubMenu(0)->CheckMenuItem( 0, MF_BYPOSITION|MF_CHECKED );此句是给文件/新建做个标记。
下面介绍缺省菜单项:GetMenu()->GetSubMenu(0)->SetDefaultItem( 1,TRUE);缺省项为粗体显示。
缺省项在一个子菜单中只能设置一个,分格栏也占一个ID号。
下面创建一个图形标记菜单:CBitmap *bp1=new CBitmap;CBitmap *bp2=new CBitmap;bp1->LoadBitmap(IDB_BITMAP1);bp2->LoadBitmap(IDB_BITMAP2);//下面的程序用来得到标记图标的大小,以此来做图// int x=GetSystemMetrics(SM_CXMENUCHECK);// int y=GetSystemMetrics(SM_CYMENUCHECK);// CString str;// str.Format("x=%d,y=%d",x,y);// MessageBox(str);//宽度和高度都应为13GetMenu()->GetSubMenu(0)->SetMenuItemBitmaps(1,MF_BYPOSITION,bp1,bp2);下面让菜单项不能使用。
上个月有人问过MFC中一些全局变量的问题,最近工作中也是用到了MFC,所以追踪了下MFC的一些源码,查看了网上一些资料,在此作个小记录。
首先来认识几个类view plaincopy to clipboardprint?1.class CNoTrackObject//状态基类2.{3.public:4.void* PASCAL operator new(size_t nSize);5.void PASCAL operator delete(void*);6.#if defined(_DEBUG) && !defined(_AFX_NO_DEBUG_CRT)7.void* PASCAL operator new(size_t nSize, LPCSTR, int);8.#endif9.virtual ~CNoTrackObject() { }10.};这个类就重载了operator new和operator delete操作符。
class AFX_MODULE_STATE : public CNoTrackObject列举下它的几个眼熟的成员变量:CWinApp* m_pCurrentWinApp;HINSTANCE m_hCurrentInstanceHandle;HINSTANCE m_hCurrentResourceHandle;LPCTSTR m_lpszCurrentAppName;BYTE m_bDLL; // TRUE if module is a DLL, FALSE if it is an EXEBYTE m_bSystem; // TRUE if module is a "system" module, FALSE if not 。
从这个类的部分注释和成员名称类型可以隐约判断出来实例指针,实例句柄、资源句柄、应用程序名称、是否为DLL模块、是否为系统模块等等。
第六讲菜单的结构Getmenu Cmenu::checkmenuitem索引号玉菜单项的ID去访问缺省菜单项(粗体显示)的创建Cmenu::SetDefaultItem 长的分隔栏算1
缺省菜单项一个菜单中只能有一个选项
图形标记菜单的创建Cmenu::SetMenuItemBitMap 位图把底色变掉跟变小函数GetSystemMetrics获取系统信息下面有图形标记的长度跟宽度SetMenu移走菜单,设置为空menu。
Loadmenu(ID号)
图标与菜单项关联只需要设置成相同的ID号
右键弹出菜单功能:工程-增加到工程-组件与控件
DrawMenuBar重画菜单
第七讲对话框
插入对话框insert-resource-dialog 或者点击键dialog的ID:dialog1
CDialog是类,在屏幕上显示,有模态(应用程序执行前必须被关闭掉)跟非模态的(显示对话框时可以转而运用其他)
模态的创建:有函数DoModle,enddialog关闭对话框静态文本框的处理
对话框完成加减的功能
第八讲基于对话框的应用程序。
第一课1.MFC 生成的C源文件中都有StdAfx.h,此文件包含了常用的AFX 函数的声明,其中有afxwin.h此文件包含了CRECTCPoint,CWnd 等许多类及其方法的声明。
2.Project-gtSetting-gtDebug 可以加入命令行参数。
3.在SDK 中要加入quotwindows.hquot和stdio.h。
因为LoadCursorMessageBox 等函数的声明在这个文件中。
4.创建一个完整的窗口的四个步骤SDK,1 设计窗口类,2 注册窗口类,3 创建窗口,4 显示窗口5.函数名可以代表函数代码的首地址,即可作为函数指针。
6.要查看VC 数据类型,可以在MSDN 中输入“BOOL”然后选择“DATA TYPE”。
7.atof 将字符串转化为floatatoi 将字符串转化为int 型。
8.所有从CWnd 类派生的类都有m_hWnd 句柄。
9.变量的生命周期:可以认为出了包含它的大括号,这个变量的生命周期结束。
所以全局变量的声明位于所有大括号之外。
但是用new 声明的变量和用static声明的变量除外。
10.SDK 示范程序,见下面。
11.sprintf 格式化字符,其头文件为stdio.h 在MFC 中格式化字符用CString.Format12.GetDC与ReleaseDC要成对使用,否则会内存泄漏。
同样,BeginPaint与EndPaint。
13.GetStockObject得到画笔、画刷、字体、调色板的句柄,使用时必须用类型转换。
14.什么时候用NULL,什么时候用0.答,对指针赋值时用NULL,对变量赋值时用0.15.什么是野指针?答:将指针指向的变量的内存释放后,此指针即变成野指针!如何避免野指针?答:将此指针指向NULL 即可。
pNULL16.SDK 代码流程:include quotwindows.hquot//包含头文件LoadCursorTextOut 等函数include quotstdio.hquot//包含sprintfprintf 等函数LRESULT CALLBACK MyProc...//声明回调函数int WINAPI WinMainWNDCLASS wndcls//设计窗口类wndcls.hcursorLoadCursor//初始化....RegisterClassampwndcls//注册窗口类hwndCreateWindow...//创建窗口ShowWindow..//显示窗口UpdateWindow..MSG msg//定义消息结构体whileGetMessage...//消息循环...return0LRESULT CALLBACK MyProc...//实现回调函数switchuMsgcaseWM_CHAR:break... 第2课1.定义结构体和类时别忘记在最后加入quot;quot号!例如Class Pointint xint y2.include ltxxx.hgt与include quotxxx.hquot的区别:ltgt不查找运行时目录,quotquot查找运行时目录!3.类的定义中,如果未指明成员类型,则缺省为private.而结构体中则缺省为public.4.引用:引用经常用在函数的传参上。
1,弹出菜单(Pop-up)是不能用来作命令响应的。
1,弹出菜单(Pop-up)是不能用来作命令响应的。
2,MFC中菜单项消息如果利用ClassWizard来对菜单项消息分别在上述四个类中进行响应,则菜单消息传递顺序:View类--Doc类--CMainFrame类--App类。
菜单消息一旦在其中一个类中响应则不再在其它类中查找响应函数。
具体:当点击一个菜单项的时候,最先接受到菜单项消息的是CMainFrame框架类,CMainFra me框架类将会把菜单项消息交给它的子窗口View类,由View类首先进行处理;如果View 类检测到没对该菜单项消息做响应,则View类把菜单项消息交由文档类Doc类进行处理;如果Doc类检测到Doc类中也没对该菜单项消息做响应,则Doc类又把该菜单项消息交还给View类,由View类再交还给CMainFrame类处理。
如果CMainFrame类查看到CMainFrame 类中也没对该消息做响应,则最终交给App类进行处理。
3,消息的分类:标准消息,命令消息,通告消息。
[标准消息]:除WM_COMMAND之外,所有以WM_开头的消息。
[命令消息]:来自菜单、加速键或工具栏按钮的消息。
这类消息都以WM_COMMAND呈现。
在MFC中,通过菜单项的标识(ID)来区分不同的命令消息;在SDK中,通过消息的w Param参数识别。
[通告消息]:由控件产生的消息,例如,按钮的单击,列表框的选择等均产生此类消息,为的是向其父窗口(通常是对话框)通知事件的发生。
这类消息也是以WM_COMMAND形式呈现。
说明:1)从CWnd派生的类,都可以接收到[标准消息]。
2)从CCmdTarget派生的类,都可以接收到[命令消息]和[通告消息]。
4,一个菜单拦可以有若干个子菜单,一个子菜单又可以有若干个菜单项等。
对菜单栏的子菜单由左至右建立从0开始的索引。
对特定子菜单的菜单项由上至下建立了从0开始的索引。
作为一个初学者制作的mfc计算器这个程序目前能实现加减乘除,还没有实现多个数字想加,所以有待改善,但是实现2个数字相加结果可以继续运算(建议)一下是实现代码。
对于控件,可以学习对话框(孙鑫老师的教学视频,哪里非常详细)// JISUANQI.cpp : implementation file//#include "stdafx.h"#include "计算器.h"#include "JISUANQI.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////// JISUANQI dialogJISUANQI::JISUANQI(CWnd* pParent /*=NULL*/): CDialog(JISUANQI::IDD, pParent){g=0;//{{AFX_DATA_INIT(JISUANQI)m_b=0;m_c = _T("");m_a=0;d=0;m_e=0;//}}AFX_DATA_INIT}void JISUANQI::DoDataExchange(CDataExchange* pDX){CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(JISUANQI)DDX_Text(pDX, IDC_EDIT1, m_c);//}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(JISUANQI, CDialog)//{{AFX_MSG_MAP(JISUANQI)ON_BN_CLICKED(IDC_BUTTON0, OnButton0)ON_BN_CLICKED(IDC_BUTTON1, OnButton1)ON_BN_CLICKED(IDC_BUTTON2, OnButton2)ON_BN_CLICKED(IDC_BUTTON3, OnButton3)ON_BN_CLICKED(IDC_BUTTON4, OnButton4)ON_BN_CLICKED(IDC_BUTTON5, OnButton5)ON_BN_CLICKED(IDC_BUTTON6, OnButton6)ON_BN_CLICKED(IDC_BUTTON7, OnButton7)ON_BN_CLICKED(IDC_BUTTON8, OnButton8)ON_BN_CLICKED(IDC_BUTTON9, OnButton9)ON_BN_CLICKED(IDC_CHEN, OnChen)ON_BN_CLICKED(IDC_CHU, OnChu)ON_BN_CLICKED(IDC_DENG, OnDeng)ON_BN_CLICKED(IDC_JIA, OnJia)ON_WM_CLOSE()ON_BN_CLICKED(IDC_CHONGX, OnChongx)ON_BN_CLICKED(IDC_JIAN, OnJian)//}}AFX_MSG_MAPEND_MESSAGE_MAP()///////////////////////////////////////////////////////////////////////////// // JISUANQI message handlersvoid JISUANQI::OnButton0(){// TODO: Add your control notification handler code here if(d==0){UpdateData(1);m_b=m_b*10+0;m_c.Format(_T("%d"), m_b);UpdateData(0);}if(d==1){int f;f=0;UpdateData(1);m_e=m_e*10+0;m_d.Format(_T("%d"),f);m_c=m_c+m_d;UpdateData(0);//g}}void JISUANQI::OnButton1(){// TODO: Add your control notification handler code here if(d==0){UpdateData(1);m_b=m_b*10+1;m_c.Format(_T("%d"), m_b);UpdateData(0);}if(d==1){int f;f=1;UpdateData(1);m_e=m_e*10+1;m_d.Format(_T("%d"),f);m_c=m_c+m_d;UpdateData(0);//g}}void JISUANQI::OnButton2(){// TODO: Add your control notification handler code here if(d==0){UpdateData(1);m_b=m_b*10+2;m_c.Format(_T("%d"), m_b);UpdateData(0);}if(d==1){int f;f=2;UpdateData(1);m_e=m_e*10+2;m_d.Format(_T("%d"),f);m_c=m_c+m_d;UpdateData(0);//g}}void JISUANQI::OnButton3(){// TODO: Add your control notification handler code here if(d==0){UpdateData(1);m_b=m_b*10+3;m_c.Format(_T("%d"), m_b);UpdateData(0);}if(d==1){int f;f=3;UpdateData(1);m_e=m_e*10+3;m_d.Format(_T("%d"),f);m_c=m_c+m_d;UpdateData(0);//g}}void JISUANQI::OnButton4(){// TODO: Add your control notification handler code here if(d==0){UpdateData(1);m_b=m_b*10+4;m_c.Format(_T("%d"), m_b);UpdateData(0);}if(d==1){int f;f=4;UpdateData(1);m_e=m_e*10+4;m_d.Format(_T("%d"),f);m_c=m_c+m_d;UpdateData(0);//g}}void JISUANQI::OnButton5(){// TODO: Add your control notification handler code here if(d==0){UpdateData(1);m_b=m_b*10+5;m_c.Format(_T("%d"), m_b);UpdateData(0);}if(d==1){int f;f=5;UpdateData(1);m_e=m_e*10+5;m_d.Format(_T("%d"),f);m_c=m_c+m_d;UpdateData(0);//g}}void JISUANQI::OnButton6(){// TODO: Add your control notification handler code here if(d==0){UpdateData(1);m_b=m_b*10+6;m_c.Format(_T("%d"), m_b);UpdateData(0);}if(d==1){int f;f=6;UpdateData(1);m_e=m_e*10+6;m_d.Format(_T("%d"),f);m_c=m_c+m_d;UpdateData(0);//g}}void JISUANQI::OnButton7(){// TODO: Add your control notification handler code here if(d==0){UpdateData(1);m_b=m_b*10+7;m_c.Format(_T("%d"), m_b);UpdateData(0);}if(d==1){int f;f=7;UpdateData(1);m_e=m_e*10+7;m_d.Format(_T("%d"),f);UpdateData(0);//g}}void JISUANQI::OnButton8(){// TODO: Add your control notification handler code here if(d==0){UpdateData(1);m_b=m_b*10+8;m_c.Format(_T("%d"), m_b);UpdateData(0);}if(d==1){int f;f=8;UpdateData(1);m_e=m_e*8;m_d.Format(_T("%d"),f);m_c=m_c+m_d;UpdateData(0);//g}}void JISUANQI::OnButton9(){// TODO: Add your control notification handler code here if(d==0){UpdateData(1);m_b=m_b*10+9;m_c.Format(_T("%d"), m_b);UpdateData(0);}if(d==1){int f;f=9;UpdateData(1);m_d.Format(_T("%d"),f);m_c=m_c+m_d;UpdateData(0);//g}}void JISUANQI::OnChen(){// TODO: Add your control notification handler code herem_a=3;d=1;UpdateData(1);m_c=m_c+"×";UpdateData(0);}void JISUANQI::OnChu(){// TODO: Add your control notification handler code herem_a=4;d=1;UpdateData(1);m_c=m_c+"÷";UpdateData(0);}void JISUANQI::OnDeng(){// TODO: Add your control notification handler code hereswitch(m_a){case 1:{m_b+=m_e;//这是实现结果在与重新输入的数字进行想加的算法UpdateData(1);m_c.Format(_T("%d"),m_b);//实现int转化字符串的函数// m_b=0;m_e=0;//输出结果之后,对于m_e初始化,这样的目的实现再次入数字进行运算是真实值d=2;////输出结果之后,不能再次输入数字,除非重新输入+—运算符UpdateData(0);}break;case 2:{ m_b-=m_e;if(m_b>=m_e){UpdateData(1);m_c.Format(_T("%d"),m_b); // m_b=0;m_e=0;d=2;UpdateData(0);}else{UpdateData(1);m_c.Format(_T("%d"),0);// m_b=0;m_e=0;d=2;UpdateData(0);}}break;case 3:{m_b*=m_e;UpdateData(1);m_c.Format(_T("%d"),m_b);// m_b=0;m_e=0;d=2;UpdateData(0);}break;case 4:{m_b/=m_e;UpdateData(1);m_c.Format(_T("%d"),m_b);// m_b=0;m_e=0;d=2;UpdateData(0);}break;}}void JISUANQI::OnJia(){// TODO: Add your control notification handler code herem_a=1;d=1;UpdateData(1);m_d="+";m_c=m_c+m_d;//m_b=0;UpdateData(0);// m_c.Empty();}//DEL void JISUANQI::OnJian()//DEL {//DEL // TODO: Add your control notification handler code here //DEL m_a=2;//DEL d=1;//DEL UpdateData(1);//DEL m_c=m_c+"-";//DEL//DEL UpdateData(0);//DEL }//DEL void JISUANQI::OnJisuanqi()//DEL {//DEL // TODO: Add your command handler code here//DEL//DEL JISUANQI m_jisuanqi;//DEL if(!m_jisuanqi)//DEL {//DEL m_jisuanqi.Create(IDD_DIALOG1);//DEL }//DEL m_jisuanqi.ShowWindow(SW_SHOW);//DEL m_c=0;//DEL }//DEL BOOL JISUANQI::OnInitDialog()//DEL {//DEL CDialog::OnInitDialog();//DEL // TODO: Add extra initialization here//DEL m_c=0;//DEL return TRUE; // return TRUE unless you set the focus to a control//DEL // EXCEPTION: OCX Property Pages should return FALSE //DEL }//DEL BOOL JISUANQI::OnInitDialog()//DEL {//DEL CDialog::OnInitDialog();//DEL//DEL // TODO: Add extra initialization here//DEL UpdateData(1);//DEL m_c=0;//DEL UpdateData(0);//DEL return TRUE; // return TRUE unless you set the focus to a control//DEL // EXCEPTION: OCX Property Pages should return FALSE //DEL }//DEL int JISUANQI::OnCreate(LPCREATESTRUCT lpCreateStruct)//DEL {//DEL if (CDialog::OnCreate(lpCreateStruct) == -1)//DEL return -1;//DEL//DEL // TODO: Add your specialized creation code here//DEL m_c=0;//DEL return 0;//DEL }//DEL void JISUANQI::OnCancelMode()//DEL {//DEL CDialog::OnCancelMode();//DEL//DEL // TODO: Add your message handler code here//DEL //m_c=0;//DEL//DEL }void JISUANQI::OnClose() //关闭计算器进行数据初始化{// TODO: Add your message handler code here and/or call defaultUpdateData(1);d=0;m_b=0;m_a=0;//负责加减乘除标识m_c.Format(_T("%d"), m_b);UpdateData(0);CDialog::OnClose();}//DEL void JISUANQI::OnFanhui()//DEL {//DEL // TODO: Add your control notification handler code here//DEL m_c=m_c.Left(m_c.GetLength()-1);//DEL UpdateData(1);//DEL m_c;//DEL UpdateData(0);//DEL }void JISUANQI::OnChongx() //重新开始,数据初始化。
Lesson1: Windows程序运行原理及程序编写流程窗口产生过程,句柄原理,消息队列,回调函数,窗口关闭与应用程序退出的工作关系,使用VC++的若干小技巧,stdcall与Lessonecl调用规范的比较,初学者常犯错误及注意事项。
1.Windows API与Win32 SDK操作系统提供了各种方便开发Windows应用程序的编程接口,所的函数都在Windows。
h头文件中声明。
Win32 SDK(Software Development Kit): 即Windows 32位平台下的软件开发包,包括API函数,帮助文档,微软提供的一些辅助开发工具。
2.窗口与句柄窗口是是屏幕上一块矩形区域,是Windows应用程序与用户进行交互的接口。
窗口分为客户区和非客户区。
在Windows应用程序中,窗口是通过窗口句柄(HWND)来标识的,要对某个窗口进行操作,首先就要得到这个窗口的句柄。
其它各种资源(窗口,图标,光标等),系统在创建这些资源时会为它们分配内在,并返回标识这些资源的标识号,即句柄。
-->光标句柄(HCURSOR),图标句柄(HICON)。
3.消息与消息队列Windows程序设计是一种基于消息的事件驱动方式的程序设计模式。
消息:在Windows中由结构体MSG来表示,typedef struct tagMSG{HWND hwnd;//消息所属的窗口句柄UINT message;//消息本身标识符,由一数值表示,系统对消息定//义为WM_XXX宏(WM为Windows Message缩写)WPARAM wParam; //随消息的不同附加信息也不同LPARAM lParam; //消息的附加参数DWORD time; //消息投递的时间POINT pt; //鼠标当前位置}消息队列:每当一个Windows应用程序创建后,系统都会为该程序创建一个消息队列,这个消息队列用来存放该程序一的窗口的消息,消息产生后被投递到消息队列中,应用程序通过一个消息循环不断的消息队列中取出消息进行响应。
Windows编程一、#define的几个注意点①#与##的用法;#xxx将后面的参数xxx字符串化xxx##yyy,将两个参数连接②\ 的用法一行结束使用,表示一行未结束。
二、函数调用约定_stdcall_stdcall是Pascal方式清理C方式压栈,通常用于Win32 Api中,函数采用从右到左的压栈方式,堆栈由它自己清理。
在win32应用程序里,宏APIENTRY,WINAPI,都表示_stdcall,非常常见。
相对应的_cdecl,堆栈由main()函数或者其他函数清理。
C和C++程序的缺省调用方式则为__cdecl,下图为VC++6.0的默认设置,因此在不显式写明调用约定的情况下,一般都是采用__cdecl方式,而在与Windows API打交道的场景下,通常都是显式的写明使用__stdcall,才能与Windows API保持一致。
另外,还要注意的是,如printf此类支持可变参数的函数,由于不知道调用者会传递多少个参数,也不知道会压多少个参数入栈,因此函数本身内部不可能清理堆栈,只能由调用者清理了。
三、防止头文件重复包含----预编译在写好的类的首位加上预编译代码,例如:#ifndef xxx_h#define xxx_hClass xxx{...};#endif四、HDC、CDC、CClientDC、CWindowDCHDC是平台SDK提供的全局类,与设备上下文相关CDC则是类似于封装在CWnd中的一个HDC。
CClientDC:继承于CDC,构造函数完成获取DC,析构函数完成释放DC。
CWindowDC:继承于CDC,构造函数完成获取DC,析构函数完成释放DC,在整个窗口上绘图CMetaFileDC:图元文件设备描述环境类创建:CMetaFileDC dc;dc.Create();接下来用一般dc的绘图操作,绘图的内容均会保存至图元文件中;HMETAFILE m_hMetaFile=dc.Close(); //图元文件赋予数据成员显示图元文件:用一般dc的PlayMetaFile(m_hMetaFile)显示图元文件窗口销毁时删除图元文件SDK函数::DeleteMetaFile(m_hMetaFile)五、OnDraw函数、OnCreate函数OnDraw函数:窗口重绘的时候被框架类FrameWnd调用,响应WM_PAINT消息。
孙鑫VC++视频笔记列表(全)简介第一课Windows程序内部运行机制第二课MFC程序框架的剖析第三课MFC消息映射机制和DC的获取第四课简单字处理软件第五课菜单编程第六课对话框编程 1第七课对话框编程 2第八课MFC中各类指针的获取第九课应用程序外观修改第十课图形绘制与通用对话框第十一课图形保存和重绘第十二课文件操作第十三课文档和串行化第十四课网络编程第十五课多线程和简单聊天室制作第十六课线程同步与异步套接字编程第十七课进程间通信第十八课ActiveX 控件第十九课动态链接库第二十课Hook钩子函数第0章简介Lesson1:Windows程序运行原理及程序编写流程,窗口产生过程,句柄原理,消息队列,回调函数,窗口关闭与应用程序退出的工作关系,使用VC++的若干小技巧,stdcall与cdecl 调用规范的比较,初学者常犯错误及注意事项。
Lesson2:C++经典语法与应用,类的编写与应用,构造与析构函数,函数的重载,类的继承,函数覆盖,基类与派生类的构造函数、析构函数先后调用顺序,如何在派生类构造函数中向基类的构造函数传递参数,this成员变量,类型转换的内幕,虚拟函数与多态性,引用和指针变量的区别与共同处。
VC工程的编译原理与过程,将工程中不同的类拆分到不同的文件中,每一个类由一个.h和.cpp文件共同完成,头文件重复定义问题的解决,培养了学员良好的编程习惯,也为以后分析MFC AppWizard生成的工程奠定了良好基础。
Lesson3:讲述MFC AppWizard的原理与MFC程序框架的剖析。
AppWizard是一个源代码生成工具,是计算机辅助程序设计工具,WinMain在MFC程序中是如何从源程序中被隐藏的,theApp全局变量是如何被分配的,MFC框架中的几个类的作用与相互关系,MFC框架窗口是如何产生和销毁的,对窗口类的PreCreateWidow和OnCreate两个函数的着重分析,Windows窗口与C++中的CWnd类的关系。
孙鑫MFC+CSXBtn类源码以及CButtonST类源码SXBtn.h文件#if !defined(AFX_WEIXINBUTTON_H__6A1ADB4D_B745_4F9B_B7BD_D0B151046A0A__INCLUDE D_)#defineAFX_WEIXINBUTTON_H__6A1ADB4D_B745_4F9B_B7BD_D0B151046A0A__INCLUDED_#if _MSC_VER > 1000 #pragma once#endif // _MSC_VER > 1000 // SXBtn.h : header file /////////////////////////////////////////////////////////////////////////////// // CSXBtn windowclass CSXBtn : public CButton {// Construction public: CSXBtn();// Attributes public:// Operations public:// Overrides // ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(CSXBtn) //}}AFX_VIRTUAL// Implementation public: void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct); virtual ~CSXBtn(); // Generated message map functions protected: //{{AFX_MSG(CSXBtn) // NOTE - the ClassWizard will add and remove member functions here. //}}AFX_MSGDECLARE_MESSAGE_MAP() };///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}}// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif// !defined(AFX_WEIXINBUTTON_H__6A1ADB4D_B745_4F9B_B7BD_D0B151046A0A__INCLUDED _)SXBtn.cpp文件// SXBtn.cpp : implementation file //#include \#include \#include \#ifdef _DEBUG#define new DEBUG_NEW #undef THIS_FILEstatic char THIS_FILE[] = __FILE__; #endif///////////////////////////////////////////////////////////////////////////// // CSXBtnCSXBtn::CSXBtn() { }CSXBtn::~CSXBtn() { }BEGIN_MESSAGE_MAP(CSXBtn, CButton) //{{AFX_MSG_MAP(CSXBtn)// NOTE - the ClassWizard will add and remove mapping macros here.//}}AFX_MSG_MAP END_MESSAGE_MAP()///////////////////////////////////////////////////////////////////////////// // CSXBtn message handlersvoid CSXBtn::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { UINT uStyle = BS_DEFPUSHBUTTON ;//DFCS_BUTTONPUSH; // This code only works with buttons.ASSERT(lpDrawItemStruct->CtlType == ODT_BUTTON); // If drawing selected,add the pushed style to DrawFrameControl. if (lpDrawItemStruct->itemState &ODS_SELECTED) uStyle |= DFCS_PUSHED; // Draw the buttonframe. ::DrawFrameControl(lpDrawItemStruct->hDC, &lpDrawItemStruct->rcItem, DFC_BUTTON, uStyle); CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);// Get the button's text. CString strText; GetWindowText(strText); //Draw the button text using the text color red. CBrush B; CRect rect; CRect focusRect; focusRect.CopyRect(&lpDrawItemStruct->rcItem);DrawFocusRect(lpDrawItemStruct->hDC, (LPRECT)&focusRect); focusRect.left += 4; focusRect.right -= 4; focusRect.top += 4; focusRect.bottom -= 4;rect.CopyRect(&lpDrawItemStruct->rcItem); pDC->Draw3dRect(rect, ::GetSysColor(COLOR_BTNSHADOW), ::GetSysColor(COLOR_BTNHILIG HT));B.CreateSolidBrush(RGB(0,255,0)); ::FillRect(lpDrawItemStruct->hDC,&rect, (HBRUSH)B.m_hObject);::SetBkMode(lpDrawItemStruct->hDC,TRANSPARENT); COLORREF crOldColor= ::SetTextColor(lpDrawItemStruct->hDC,RGB(255,0,0)); ::DrawText(lpDrawItemStruct->hDC, strText, strText.GetLength(), &lpDrawItemStruct->rcItem,DT_SINGLELINE|DT_VCENTER|DT_CENTER); ::SetTextColor(lpDrawItemStruct->hDC, crOldColor); }BtnST.h文件#ifndef _BTNST_H #define _BTNST_H #if _MSC_VER >= 1000 #pragma once#endif // _MSC_VER >= 1000 // CBtnST.h : header file //// Comment this if you don't want that CButtonST hilights itself// also when the window is inactive (like happens in Internet Explorer)#define ST_LIKEIE// Comment this if you don't want to use CMemDC class #define ST_USE_MEMDC/////////////////////////////////////////////////////////////////////////////// CButtonST windowclass CButtonST : public CButton {// Construction public:CButtonST(); ~CButtonST();enum {ST_ALIGN_HORIZ, ST_ALIGN_VERT}; // Attributes public:// Operations public: // Overrides// ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(CButtonST) public:virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);protected:virtual void PreSubclassWindow(); //}}AFX_VIRTUAL // Implementation public:BOOL SetBtnCursor(int nCursorId = -1);void SetFlatFocus(BOOL bDrawFlatFocus, BOOL bRepaint = FALSE); BOOL GetFlatFocus();void SetDefaultActiveFgColor(BOOL bRepaint = FALSE);void SetActiveFgColor(COLORREF crNew, BOOL bRepaint = FALSE); const COLORREF GetActiveFgColor();void SetDefaultActiveBgColor(BOOL bRepaint = FALSE);void SetActiveBgColor(COLORREF crNew, BOOL bRepaint = FALSE); const COLORREF GetActiveBgColor();void SetDefaultInactiveFgColor(BOOL bRepaint = FALSE);void SetInactiveFgColor(COLORREF crNew, BOOL bRepaint = FALSE); const COLORREF GetInactiveFgColor();void SetDefaultInactiveBgColor(BOOL bRepaint = FALSE);void SetInactiveBgColor(COLORREF crNew, BOOL bRepaint = FALSE); const COLORREF GetInactiveBgColor(); void SetShowText(BOOL bShow = TRUE); BOOL GetShowText(); void SetAlign(int nAlign); int GetAlign();void SetFlat(BOOL bState = TRUE); BOOL GetFlat();void DrawBorder(BOOL bEnable = TRUE);void SetIcon(int nIconInId, int nIconOutId = NULL, BYTE cx = 32, BYTE cy = 32); static const short GetVersionI(); static const char* GetVersionC(); protected://{{AFX_MSG(CButtonST)afx_msg void OnCaptureChanged(CWnd *pWnd);afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message); afx_msg void OnKillFocus(CWnd* pNewWnd);afx_msg void OnMouseMove(UINT nFlags, CPoint point); //}}AFX_MSGDECLARE_MESSAGE_MAP() private:void DrawTheIcon(CDC* pDC, CString* title, RECT* rcItem, CRect* captionRect, BOOL IsPressed, BOOL IsDisabled);int m_nAlign;感谢您的阅读,祝您生活愉快。
#include <windows.h>
#include <stdio.h>
LRESULT CALLBACK WinMyProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
int WINAPI WinMain(
HINSTANCE hInstance, // handle to current instance
HINSTANCE hPrevInstance, // handle to previous instance
LPSTR lpCmdLine, // command line
int nCmdShow // show state
)
{
WNDCLASS wndcls;
wndcls.cbClsExtra=0;
wndcls.cbWndExtra=0;
wndcls.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
wndcls.hCursor=LoadCursor(NULL,IDC_CROSS);
wndcls.hIcon=LoadIcon(NULL,IDI_ERROR);
wndcls.hInstance=hInstance;
wndcls.lpfnWndProc=WinMyProc;
wndcls.lpszClassName="MyWinMain";
wndcls.lpszMenuName=NULL;
wndcls.style=CS_HREDRAW | CS_VREDRAW;
RegisterClass(&wndcls);
HWND hwnd3660;
hwnd3660=CreateWindow("MyWinMain","软件学院",WS_OVERLAPPEDWINDOW, 200,200,600,400,NULL,NULL,hInstance,NULL);
ShowWindow(hwnd3660,SW_SHOWNORMAL);
UpdateWindow(hwnd3660);
MSG msg;
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK WinMyProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
switch(uMsg)
{
case WM_CHAR:
char szChar[20];
sprintf(szChar,"char is %c",wParam);
MessageBox(hwnd,szChar,"neu",0);
break;
case WM_LBUTTONDOWN:
MessageBox(hwnd,"mouse clicked","neu",0);
HDC hdc;
hdc=GetDC(hwnd);
TextOut(hdc,0,50,"C++与MFC语言学习",strlen("C++与MFC语言学习"));
ReleaseDC(hwnd,hdc);
break;
case WM_PAINT:
HDC hDC;
PAINTSTRUCT ps;
hDC=BeginPaint(hwnd,&ps);
TextOut(hDC,0,0,"东北大学",strlen("东北大学"));
EndPaint(hwnd,&ps);
break;
case WM_CLOSE:
if(IDYES==MessageBox(hwnd,"是否真的结束?","neu",MB_YESNO))
{
DestroyWindow(hwnd);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
return 0;
}
//东北大学软件学院信息安全专业。