windows编程(消息机制、消息队列、消息映射、线程同步)笔记

windows编程学习笔记杂谈

  • 随意吐槽
  • PostMessage和SendMessage的区别
  • 关于消息隐射
  • 自定义消息如何实现
  • 关于__stdcall vs __cdecl
  • 常用线程同步技术

  • 随意吐槽

在选择提纲颜色的时候,不自主的选择了土豪金,学好编程能够成为土豪吗!!!

又到了每年求职的高峰期,回想去年自己找工作的经历,既有欢乐,又有无尽的痛苦;话说去年“史上最难找工作年份”,就业率反而高于前年,在我党的英明指导下,大家都“轻松”的找到了“如意”的工作,可喜可贺呀!

无意间翻到以前自己突击面试时准备的一些资料,就贴出来吧,这些文字都来自于互联网,感谢那些无私分享的人们!

  • PostMessage和SendMessage的区别

BOOL   PostMessage( 
    HWND   hWnd,             //   handle   of   destination   window 
    UINT   Msg,               //   message   to   post 
    WPARAM   wParam,     //   first   message   parameter 
    LPARAM   lParam       //   second   message   parameter 
); 
消息就是发到hWnd这个窗口

PostMessage和SendMessage的区别主要在于是否等待其他程序消息处理。PostMessage只是把消息放入队列,不管其他程序是否处理都返回,然后继续执行;而SendMessage必须等待其他程序处理消息后才返回,继续执行。这两个函数的返回值也不同,PostMessage的返回值表示PostMessage函数执行是否正确,而SendMessage的返回值表示其他程序处理消息后的返回值。

  •  自定义消息共分为3步骤:

1)  自定义消息:#defineWM_MYMSG WM_USER+1

2)  在头文件中声明函数:       afx_msg void onMyMsg();

3) 在消息映射中添加对应关系:

//BEGIN_MESSAGE_MAP(CDefMsgDemoDlg,CDialog) //END_MESSAGE_MAP()

ON_MESSAGE(WM_MYMSG,onMyMsg)

4)定义函数void onMyMsg();

核心即:函数原型、关联消息与消息响应函数的宏、函数实现。

  • 关于消息隐射
1   对于消息映射机制的理解。表面上看是A发消息到B,然后B收到消息执行相应的操作。实际上呢?消息映射的原理是:B预先设定,假如A执行了发某个消息的过程,那么B就做某一个操作。可以看出,实际上并没有什么“消息”在传递,消息映射的实质是A对B的一种函数调用。 

2   进一步理解消息映射,A调用B的函数,那么A要不要等到B的过程执行完再继续呢?这就是消息队列机制了。PostMessage只是把调用要求放进一个等待队列里(消息队列),而SendMessage一定要等到B执行完消息映射函数才能继续,这就是两个函数的本质区别。
CALLBACK是回调的意思,即由应用程序定义,供系统调用的函数. 
就实质而言,CALLBACK是一种调用方式,即__stdcall 
而C/C++的默认调用方式是__cdecl
  • 关于__stdcall vs __cdecl
__cdecl 是C Declaration的缩写(declaration,声明),表示C语言默认的函数调用方法:所有参数从右到左依次入栈,这些参数由调用者清除,称为手动清栈。被调用函数不会要求调用者传递多少参数,调用者传递过多或者过少的参数,甚至完全不同的参数都不会产生编译阶段的错误。
_stdcall 是StandardCall的缩写,是C++的标准调用方式:所有参数从右到左依次入栈,如果是调用类成员的话,最后一个入栈的是this指针。这些堆栈中的参数由被调用的函数在返回后清除,使用的指令是 retnX,X表示参数占用的字节数,CPU在ret之后自动弹出X个字节的堆栈空间。称为自动清栈。函数在编译的时候就必须确定参数个数,并且调用者必须严格的控制参数的生成,不能多,不能少,否则返回后会出错。
  • 线程同步技术
1. Critical Sections(临界段),源代码中如果有不能由两个或两个以上线程同时执行的部分,可以用临界段来使这部分的代码执行串行化。它只能在一个独立的进程或一个独立的应用程序中使用。使用方法如下:
//在窗体创建中
InitializeCriticalSection(Critical1)
//在窗体销毁中
DeleteCriticalSection(Critical1)
//在线程中
EnterCriticalSection(Critical1)
……保护的代码
LeaveCriticalSection(Critical1)

2. Mutex(互斥对象),是用于串行化访问资源的全局对象。我们首先设置互斥对象,然后访问资源,最后释放互斥对象。在设置互斥对象时,如果另一个线程(或进程)试图设置相同的互斥对象,该线程将会停下来,直到前一个线程(或进程)释放该互斥对象为止。注意它可以由不同应用程序共享。使用方法如下:
//在窗体创建中
hMutex:=CreateMutex(nil,false,nil)
//在窗体销毁中
CloseHandle(hMutex)
//在线程中
WaitForSingleObject(hMutex,INFINITE)
……保护的代码
ReleaseMutex(hMutex)

3. Semaphore(信号量),它与互斥对象相似,但它可以计数。例如可以允许一个给定资源同时同时被三个线程访问。其实Mutex就是最大计数为一的Semaphore。使用方法如下:
//在窗体创建中
hSemaphore:= CreateSemaphore(nil,lInitialCount,lMaximumCount,lpName)
//在窗体销毁中
CloseHandle(hSemaphore)
//在线程中
WaitForSingleObject(hSemaphore,INFINITE)
……保护的代码


你可能感兴趣的:(C/C++)