MFC相关函数介绍

来源:互联网 发布:excel数据如何恢复 编辑:程序博客网 时间:2024/04/30 22:46

1.MFC之DoDataExchange()

Never call this function directly. It is called by the UpdateData member function. Call UpdateData to initialize a dialog box’s controls or retrieve data from a dialog box.

就是说函数DoDataExchange()永远不被直接调用,它只有在调用UpdateData()函数时才会被调用


UpdataData函数内部调用了DoDataExchange。该函数只有一个布尔型参数,它决定了数据传送的方向。调用UpdateData(TRUE)将数据从对话框的控件中传送到对应的数据成员中,调用UpdateData(FALSE)则将数据从数据成员中传送给对应的控件。 

UpdateData(FALSE);//表将变量的值更新到控件进行显示。
UpdateData(TRUE);//表从控件中获取关联变量的值

参考:http://zhidao.baidu.com/link?url=rRIKxmK9M8zR5KFtOThz9sDFetOgCjjxtCfmCOnH3KvxSdAfOE8C0f9qB90G9bz8oCOgzclm_3Ksx5ekyjoIT_

-------------------------------------

MFC 提供的DDX/DDV 机制做出对话框控制组件 (control )的内容传递与内容查核。

DDX(Dialog Data eXchange )的目的在简化应用程序取得控制组件内容的过程,

DDV  (Dialog Data Validation )的目的则在加强应用程序对控制组件内容之数值合理化检查。

-----摘自《深入浅出MFC》


参考:http://blog.sina.com.cn/s/blog_6ff5d730010118cn.html

---------------------------------------------------

2.OnSysCommand()

void CTestDlg::OnSysCommand(UINT nID, LPARAM lParam):这个函数响应系统控制菜单的命令.(即左上角图标处)。

OnSysCommand:The framework calls this member function when the user selects a command from the Control menu, or when the user selects the Maximize or the Minimize button.

即点击标题栏最左边的小图标时出发的事件:


3.DoDataExchange()

DoDataExchange:当UpdateData函数被调用的时候调用该函数。

4.OnInitDialog()

OnInitDialog:对话框类已经构造,但是对话框还没有显示出来的时候被调用。

OnQueryDragIcon:The framework calls this member function by a minimized (iconic) window that does not have an icon defined for its class. The system makes this call to obtain the cursor to display while the userdrags the minimized window

参考:http://www.cppblog.com/momoxiao/archive/2009/10/22/99206.aspx

5.WPARAM和LPARAM

参考1:

WPARAM 和 LPARAM,消息响应机制
wParam和lParam 这两个是Win16系统遗留下来的产物,在Win16API中WndProc有两个参数: 
一个是WORD类型的16位整型变量;另一个是LONG类型的32位整型变量。因此根据匈牙利命名法,16位的变量就被命名为wParam, 32位的变量就被命名为lParam。 

到了Win32API中,原来的16位变量也被扩展为32位,因此此时wParam和lParam的大小完全相同。 
在Win32API的早期,为了保证和Win16API的代码可移植性MS定义了WPARAM和LPARAM两个宏。 
当时保留了w前缀的原因一方面是由于WPARAM宏也已W开头,还有也因为要提醒程序员注意到可移植性,当然到了现在Win16早已退出历史舞台,这个前缀也就约定俗成的沿用下来了。
例如:主程序MyDlg.cpp 
1.自定义消息:#define WM_TRAY WM_USER 100 
2.函数原形:afx_msg LRESULT OnTrayNotify(WPARAM wParam,LPARAM lParam); 
3.消息映射:ON_MESSAGE(WM_TRAY,OnTrayNotify) 
4.原函数: 
LRESULT CMyDlg::OnTrayNotify(WPARAM wParam,LPARAM lParam) 

return m_tray.OnTrayNotify(wParam,lParam); 


托盘类的实现程序Tray.cpp 
成员函数: 
int OnTrayNotify(WPARAM wID,LPARAM lEvent) 

if(wID == TRAYNOTIFYDATA.uID) 
return 0; 
if(lEvent == WM_LBUTTONDOWN){ 
处理代码 

else if(lEvent == WM_RBUTTONDOWN){ 
处理代码 

return 0; 

WPARAM 和 LPARAM 本质上没有什么区别:都是32位数,
但是区别也还是有的:除了上面几位若仁兄说的关于16位的的历史问题外,MICROSOFT在使用时两种参数分别代表不同的含义和内容,WPARAM常常代表一些控件的ID或者高位底位组合起来分别表示鼠标的位置,如果消息的发送者需要将某种结构的指针或者是某种类型的句柄时,习惯上用LPARAM来传递,可以参考各种控件的通知消息:可以查看:EN_CHANGE (EDIT控件的一个通知消息),CBEM_INSERTITEM(可扩展组合框的可接受消息)等等来加以领会。
理论上在使用自定义消息时,WPARAM LPARAM的含义可以程序员任意指定的,但是最好遵从MFC中的习惯。在调用SendMessage()函数时,第二个参数是WPARAM,第三个参数是这个消息的LPARAM,但是你在程序中某个类中写下ON_MESSAGE()宏来处理这个消息时,处理函数SomeHandler(WPARAM,LPRAM(默认是0))中解释这两个参数时必须按照SendMessage调用中的意义来进行。

消息响应机制
1、消息的组成:一个消息由一个消息名称(UINT),和两个参数(WPARAM,LPARAM)。当用户进行了输入或是窗口的状态发生改变时系统都会发送消息到某一个窗口。例如当菜单转中之后会有WM_COMMAND消息发送,WPARAM的高字中(HIWORD(wParam))是命令的ID号,对菜单来讲就是菜单ID。当然用户也可以定义自己的消息名称,也可以利用自定义消息来发送通知和传送数据。 

2、谁将收到消息:一个消息必须由一个窗口接收。在窗口的过程(WNDPROC)中可以对消息进行分析,对自己感兴趣的消息进行处理。例如你希望对菜单选择进行处理那么你可以定义对WM_COMMAND进行处理的代码,如果希望在窗口中进行图形输出就必须对WM_PAINT进行处理。 

3、未处理的消息到那里去了:M$为窗口编写了默认的窗口过程,这个窗口过程将负责处理那些你不处理消息。正因为有了这个默认窗口过程我们才可以利用Windows的窗口进行开发而不必过多关注窗口各种消息的处理。例如窗口在被拖动时会有很多消息发送,而我们都可以不予理睬让系统自己去处理。 

4、窗口句柄:说到消息就不能不说窗口句柄,系统通过窗口句柄来在整个系统中唯一标识一个窗口,发送一个消息时必须指定一个窗口句柄表明该消息由那个窗口接收。而每个窗口都会有自己的窗口过程,所以用户的输入就会被正确的处理。例如有两个窗口共用一个窗口过程代码,你在窗口一上按下鼠标时消息就会通过窗口一的句柄被发送到窗口一而不是窗口二。 

5、示例:下面有一段伪代码演示如何在窗口过程中处理消息 

LONG yourWndProc(HWND hWnd,UINT uMessageType,WPARAM wP,LPARAM)
{
 switch(uMessageType)
 {//使用SWITCH语句将各种消息分开
  case(WM_PAINT):
   doYourWindow(...);//在窗口需要重新绘制时进行输出
  break;
  case(WM_LBUTTONDOWN):
   doYourWork(...);//在鼠标左键被按下时进行处理
  break;
  default:
   callDefaultWndProc(...);//对于其它情况就让系统自己处理
  break;
 }
}


接下来谈谈什么是消息机制:系统将会维护一个或多个消息队列,所有产生的消息都回被放入或是插入队列中。系统会在队列中取出每一条消息,根据消息的接收句柄而将该消息发送给拥有该窗口的程序的消息循环。每一个运行的程序都有自己的消息循环,在循环中得到属于自己的消息并根据接收窗口的句柄调用相应的窗口过程。而在没有消息时消息循环就将控制权交给系统所以Windows可以同时进行多个任务。下面的伪代码演示了消息循环的用法: 


while(1)
{
 id=getMessage(...);
 if(id == quit)
  break;
 translateMessage(...);
}
当该程序没有消息通知时getMessage就不会返回,也就不会占用系统的CPU时间。

参考:http://zhidao.baidu.com/link?url=DoXT_8ouhSoNJPYl0mD6j-m7vlyEZ2730vJkZx2K7ot6QTbDqQof4hWGfLG6vYG1RQ5ehLKJYd4HLp2chk42L_

---------------------------

参考2:

WPARAM 是32位无符号数,LPARAM ==long
针对不同消息,wParam,lParam代表不同意义

一般情况下,你通过消息机制进行通信的话,lparam和wparam可以用来传递你的参数,比如数据的指针和数据的长度等等

在Win32中,wParam lParam是用来传递消息数据的最常用的手段.
比如,对按键消息来说,鼠标的X和Y的坐标被压缩进lParam中
对MFC来说,消息可以用多样的类型参数来传递,对用户自定义消息来说,只能用wParam和lParam来传递。

wParam和lParam都作为函数的参数
只不过后者是16位,前者在win16中是16位,在win32中是32位
在windef.h中,有他们的定义
如下:
typedef UINT WPARAM;
typedef LONG LPARAM;

窗口可以是任何类型的屏幕对象,
因为Win32能够维护大多数可视对象的句柄(窗口、对话框、按钮、编辑框等)。
message 用于区别其他消息的常量值,这些常量可以是Windows单元中预定义的常量,也可以是自定义的常量。
wParam 通常是一个与消息有关的常量值,也可能是窗口或控件的句柄。
lParam 通常是一个指向内存中数据的指针。
由于wParam,lParam和指针都是32位的,需要时可以强制类型转换。具体表示什么,与message相关,他们是事先定义好的。
如果自定义消息:#define WM_MYMESSAGE WM_USER+100,需确定wParam,lParam的意义
(假设wParam=0时发送数据,wParam=1时接收数据,lParam为CMyClass* 指针,指向一个CMyClass对象,准备要发送的数据或接收数据
发送WM_MYMESSAGE时 SendMessage(hwnd,WM_MYMESSAGE,0,pMyClassObject)
接收消息的窗口,接收WM_MYMESSAGE中(CMyClass*)lParam参数即pMyClassObject传过来的数据

参考:http://bbs.csdn.net/topics/10216465

6.sendmessage和postmessage的区别

PostMessage只负责将消息放到消息队列中,不确定何时及是否处理
SendMessage要等到收到消息处理的返回码(DWord类型)后才继续
概括的说:
PostMessage执行后马上返回
SendMessage必须等到消息被处理后才会返回。

参考:http://zhidao.baidu.com/link?url=kCixhChAKDGJSYGY5px60iEyqX-Gef5zA5FbfkKkJsL5V6oVBuSATRXjvwhSrg2wUz7KqGeZPHQlREQeeHcpv_

7.DECLARE_DYNAMIC,IMPLEMENT_DYNAMIC


原创粉丝点击