第2讲Windows消息机制
华为C++面试题、笔试题及答案经典
(一) 初级题1. 什么是预编译,何时需要预编译:答:(1) 总是使用不经常改动的大型代码体(2) 程序由多个模块组成,所有模块都使用一组标准的包含文件和相同的编译选项。
在这种情况下,可以将所有包含文件预编译为一个预编译头<<预编译又称为预处理,是做些代码文本的替换工作处理#开头的指令,比如拷贝#include包含的文件代码,#define宏定义的替换,条件编译等就是为编译做的预备工作的阶段主要处理#开始的预编译指令预编译指令指示了在程序正式编译前就由编译器进行的操作,可以放在程序中的任何位置。
常见的预编译指令有:>>2. char * const pchar const * pconst char *p上述三个有什么区别?答:char * const p; //常量指针,p的值不可以修改char const * p;//指向常量的指针,指向的常量值不可以改const char *p;//和char const *p3.char str1[] = "abc";char str2[] = "abc";const char str3[] = "abc";const char str4[] = "abc";const char *str5 = "abc";const char *str6 = "abc";char *str7 = "abc";char *str8 = "abc";cout << ( str1 == str2 ) << endl;cout << ( str3 == str4 ) << endl;cout << ( str5 == str6 ) << endl;cout << ( str7 == str8 ) << endl;结果是:0 0 1 1str1,str2,str3,str4是数组变量,它们有各自的内存空间;而str5,str6,str7,str8是指针,它们指向相同的常量区域。
Windows的DDE原理
Windows的DDE原理Windows的DDE机制基于Windows的消息机制。
两个Windows应用程序通过相互之间传递DDE消息进行DDE会话(Conversation),从而完成数据的请求、应答、传输。
这两个应用程序分别称为服务器(Server)和客户(Client)。
服务器是数据的提供者,客户是数据的请求和接受者。
DDE会话由客户程序启动。
客户程序把一条消息(WM_DDE_INITIATE)传播给当前运行的所有Windows程序。
这条消息指明了客户程序所需要的一般数据(应用程序、主题)。
拥有这些数据的DDE服务器可以响应这条被传播的消息。
此时,DDE会话就开始了。
由于在每个主题中,DDE服务器可以支持一个或多个数据项,所以在客户请求数据时应同时指明应用程序名、主题名和项目名。
应用程序、主题、项目是DDE中三个最基本的概念。
利用Windows本身提供的DDE消息和API进行DDE编程是一件相当棘手的问题。
虽然使用DDE管理库(ddeml.dll)可以一定程度上减轻开发者的工作负担,但开发DDE程序仍不是一件轻松的事情。
此时Delphi出现了!Delphi通过其自身巧妙的设计使开发一个DDE应用程序同开发一个普通程序一样地快捷、方便。
7.2.2Delphi的DDE实现机制简介Delphi把所有的DDE功能做到四个部件中,它们是:●TDDEClientConv:用于客户程序建立和维护一个DDE会话●TDDEClientItem:用于客户程序建立和维护数据交换通道●TDDEServerConv:用于服务器程序响应DDE会话●TDDEServerItem:用于服务器程序维护数据交换通道前两个部件用于生成一个DDE客户程序,后两个部件用于生成一个DDE服务器程序。
如果一个应用程序同时拥有这些部件,则这一程序既可以充当DDE客户,也可以充当DDE 服务器。
会话部件TDDEClientConv、TDDEServerConv用于建立和维护一个DDE会话。
消息映射机制的剖析
完成画线的功能
方法一:用API函数
从CWnd派生出来的类中都有 一个数据成员m_hWnd保存了 跟C++类对象相关的窗口句柄
在MFC中如果要调用SDK的函数的话,要加::前缀
hdc=::GetDC(m_hWnd);
MoveToEx(hdc,m_ptOrigin.x,m_ptOrigin.y,NULL);
完成画线的功能
实现画笔中画线的功能,就是鼠标移动过程中画一系 列临时的直线,鼠标左键释放时画一条永久直线。 【作图模式及应用】 SetRop2可设置作图模式 作图模式R2_NOT下画的直线是通过反转屏幕当前颜色 作出的;在某一位置首次画一条直线时,它是可见的, 但是在相同的位置第二次画直线时,就变为不可见的。
完成画线的功能
实现画笔中画线的功能,就是鼠标移动过程中画一系 列临时的直线,鼠标左键释放时画一条永久直线。 在OnMouseMove中
if(m_bDraw==TRUE) { dc.SetROP2(R2_NOT); dc.MoveTo(m_ptOrigin); dc.LineTo(m_ptOld); dc.MoveTo(m_ptOrigin); dc.LineTo(point); m_ptOld=point; }
LineTo(hdc,point.x,point.y); ::ReleaseDC(m_hWnd,hdc);
完成画线的功能
方法二:用CDC类 有一个数据成员m_hDC,它保存设备描述表,也就是 与CDC这个类相关的句柄,就像m_hWnd保存窗口句柄 一样。
CDC *pDC=GetDC(); /* CWnd中的成员函数 */ pDC->MoveTo(m_ptOrigin); pDC->LineTo(point); ReleaseDC(pDC); /* CWnd类的成员函数 */
WindowsAPI编程
吉林大学远程教育课件
Windows A P I编 程
While(1) {
id=getMessage(…); if(id==quit)
break; translateMessage(…); }
当该程序没有消息通知时,getMessage就不会返回,也就不会占用系
统的CPU时间。
二、协同式多任务与抢先式多任务系统
在16位的操作系统中只有一个消息队列,所以系统必须等待当 前任务处理消息后才可以发送下一消息到相应程序,如果一个 程序陷入死循环或是操作超时,系统就得不到控制权。这种多 任务系统被称为协同式多任务系统。 Windows 3.x就是这种系 统。
Windows API程序设计。
第二节 Windows 程序
工作原理
Windows 程序设计是一种完全不同于传统的DOS方式的程序 设计方法,它是一种事件驱动方式的程序设计模式。在程序提供 给用户的界面中有许多可操作的可视对象。用户从所有可能的操 作中任意选择,被选择的操作会产生某些特定的事件,这些事件 发生后的结果是向程序中的某些对象发出消息,然后这些对象调 用相应的消息处理函数来完成特定的操作。Windows应用程序最 大的特点就是程序没有固定的流程,而只是针对某个事件的处理 有特定的子流程,Windows应用程序就是由许多这样的子流程构 成的。
前 言 (二)
Windows操作系统同时也是一个大的函数库,其中包 含了数以千计的函数,这些函数能完成各种各样的功 能,包括窗口管理、图形设备接口、媒体控制、内存 管理和系统扩展,这些函数都被封装在一个接口中, 这 个 接 口 就 是 Windows 应 用 程 序 编 程 接 口 ( Windows Application Progrmming Interface),简称Windows API。 可以说,用户需要实现的所有功能通过Windows API都 能实现。而且, Windows API作为操作系统不可分割 的一部分,很好地体现了 Windows操作系统的特色。 并且基于 Windows API的应用程序具有和 Windows操 作系统的良好整合性,从而大大提高了软件的运行性 能。
Windows消息机制含义
Windows消息机制含义Windows系统是一个消息驱动的OS,什么是消息呢?接下来是小编为大家收集的Windows消息机制含义,希望能帮到大家。
Windows消息机制含义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,UINTuMessageType,WPARAM wP,LPARAM){ switch(uMessageType) {//使用SWITCH语句将各种消息分开case(WM_PAINT): doYourWindow(...);//在窗口需要重新绘制时进行输出break; case(WM_LBUTTONDOWN): doYourWork(...);//在鼠标左键被按下时进行处理break; default: callDefaultWndProc(...);//对于其它情况就让系统自己处理 break; }}接下来谈谈什么是消息机制:系统将会维护一个或多个消息队列,所有产生的消息都回被放入或是插入队列中。
windows程序消息机制(Winform界面更新有关)
windows程序消息机制(Winform界⾯更新有关)1. Windows程序消息机制Windows GUI程序是基于消息机制的,有个主线程维护着消息泵。
这个消息泵让windows程序⽣⽣不息。
Windows程序有个消息队列,窗体上的所有消息是这个队列⾥⾯消息的最主要来源。
这⾥的While循环使⽤了GetMessage() 这个⽅法,这是个阻塞⽅法,也就是队列为空时⽅法就会阻塞,从⽽这个While循环停⽌运动,这避免了⼀个程序把cpu⽆缘⽆故的耗尽,让其他程序难以得到响应。
当然在某些需要cpu最⼤限度运动的程序⾥⾯就可以使⽤另外的⽅法,例如某些3d游戏或者及时战略游戏中,⼀般会使⽤PeekMessage()这个⽅法,它不会被windows阻塞,从⽽保证整个游戏的流畅和⽐较⾼的帧速。
(PeekMessage是⼀个Windows API函数。
该函数为⼀个消息检查线程消息队列,并将该消息(如果存在)放于指定的结构。
DispatchMessage功能是发送消息给窗⼝,窗⼝收到消息,执⾏事件)。
这个主线程维护着整个窗体以及上⾯的⼦控件。
当它得到⼀个消息,就会调⽤DispatchMessage()⽅法派遣消息,这会引起对窗体上的窗⼝过程的调⽤。
窗⼝过程⾥⾯当然是程序员提供的窗体数据更新代码和其它代码。
2. dotnet⾥⾯的消息循环public static void Main(string[] args){Form f = new Form();Application.Run(f);}Dotnet窗体程序封装了上述的while循环,这个循环就是通过Application.Run⽅法启动的。
3、线程外操作GUI控件的问题如果从另外⼀个线程操作windows窗体上的控件,就会和主线程产⽣竞争,造成不可预料的结果,甚⾄死锁。
因此windows GUI编程有⼀个规则,就是只能通过创建控件的线程来操作控件的数据,否则就可能产⽣不可预料的结果。
Visual C++MFC入门教程(经典版)
Visual C++MFC入门教程(经典版)visual-c++mfc入门教程(经典版)木有页眉visualc++mfc入门教程目录+--第一章vc入门|------1.1如何学好vc|------1.2认知windows消息机制|------1.3利用visualc++/mfc开发windows程序的优势|------1.4利用mfc进行开发的通用方法介绍|------1.5mfc中常用类,宏,函数介绍+--第二章图形输出|------2.1和gui有关的各种对象|------2.2在窗口中输入文字|------2.3使用点,刷子,笔进行绘图|------2.4在窗口中绘制设备有关图形,图标,设备毫无关系图形|------2.5采用各种态射方式|------2.6多边形和剪贴区域+--第三章文档视结构|------3.1文档视图框架窗口间的关系和消息传送规律|------3.2接收用户输入|------3.3使用菜单|------3.4文档,视,框架之间相互作用|------3.5利用序列化展开文件读取|------3.6mfc中所提供更多的各种视类了解+--第四章窗口控件|------4.1button|------4.2staticbox|------4.3editbox|------4.4scrollbar|------4.d利用appwizard创建并使用toolbarstatusbardialogbar|------4.egeneralwindow|------4.f关于wm_notify的采用方法+--第五章对话框|------5.1使用资源编辑器编辑对话框|------5.2创建有模式对话框|------5.3创建无模式对话框|------5.4在对话框中展开消息态射|------5.5在对话框中进行数据交换和数据检查1木有页眉|------5.6采用属性对话框|------5.7采用通用型对话框|------5.8建立以对话框为基础的应用|------5.9使用对话框作为子窗口+--第六章网络通信开发|------6.1winsock介绍|------6.2利用winsock展开并无相连接的通信+------6.3利用winsock创建存有相连接的通信《visualc++开发指南》闻怡洋/文第一章vc入门1.1如何努力学习vc这个问题很多朋友都问过我,当然流汗是必须的,但同时如果按照某种思路进行有计划的学习就会起到更好的效果。
IT知识库
}
if (::PeekMessage(&message,NULL,0,0,PM_REMOVE)){
::TranslateMessage(&message);anslateMessage(&message);
::DispatchMessage(&message);
WSAStartup(tSocketVerNo, &tVerData);
2. 创建一个Socket
SOCKET ServerSock;
ServerSock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP);
?事件的使用方法
HANDLEg_hCloseEvent = NULL;
g_hCloseEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (g_hCloseEvent == NULL)
Cevent类是一个事件类,刚定义时处于"非信号"状态, 可以调用SetEvent()成员函数置它为"信号"状态.
下面的代码: 线程首先等待开始信号, 如果没有置开始信号会一直挂起等待, 同时在运行的过程中等待结束信号,
如果结束信号发生就终止线程.
Cevent g_eventStart,g_eventKill;
Volatile int nTemp;//使变更不保存在寄存器中, 因为变量如果保存在寄存器中, 在线程的切换过程中可能会出现值的错误.
For (m_nCount=0;m_nCount<nMaxCount;m_nCount++){
Windows消息循环机制研究
2 消息驱动 : no s ) Widw 应用程序 的另一特点就是基于消息驱动 。用户通过应用程序界面上的菜单栏 、 工具栏进 行各 种操作 , 这 些操作触 发各种事件 , 事件 以消息的形式交给应用程序来处理 , 应用程序通过对这些消息的响应来 实现用户 的需求。 Wid w 应用程序的这些特点很适合于用户 的操作习惯 , nos 软件的使用变得简单灵活 , 同时 , 了方便 Widw 平 台下 的应用程 为 nos 序开发 , 微软对操作 系统 的功能进行 了封装 , 提供 了一套完整的接 口函数供软件开发人员使用 , 这就是 Widw 应用程序接 口( n no s wi
3操作 系统捕获事件 , ) 将其封装成消息 , 并放 到与该应用程序相关的消息队列 中。 4 应用程序从消息队列获取消息 , ) 然后转换消息 , 派遣消息 。 . 5 应用程序将消息派遣给操作 系统 , ) 操作 系统调用应用程序注册 的回调 函数对消息进行处理 。
在 整个 应 用 程 序 运 行 过 程 中需 要 强 调 以下 两 点 :
消息呢?可以调用 系统 函数 P s u Mesg( ; ot i sae ) Q t 0 来触发 WM— U T Q I 消息 。 2 消息处理机制 : ) 消息 的处理是在 回调函数中进行 的 , 需要注意的是 回调函数是在设计 窗 E类时 由软件开发人员指定的 , l 回调
关 键 词 : 息循 环 ; 消 图形 用 户界 面 ; 调 函数 ; 息 队 列 回 消 中图 分 类 号 : P 1 文 献标 识 码 : 文章 编 号 :0 9 3 4 (0 22 — 0 6 0 T 36 A 10 — 042 1 )5 6 3 — 4
常用的十三种hook类型
本文将试图以下面的顺序讲解HOOK的大部分内容:1、 WINDOWS的消息机制2、 HOOK介绍3、 HOOK链4、 HOOK钩子的作用范围5、 HOOK类型6、回调函数7、 HOOK钩子的安装与卸载8、 HOOK实例演示+++++++++++++++++++WINDOWS的消息机制+++++++++++++++++++Windows系统是以消息处理为其控制机制,系统通过消息为窗口过程(windowsprocedure)传递输入。
系统和应用两者都可以产生消息。
对于每个输入事件,例如用户按下了键盘上的某个键、移动了鼠标、单击了一个控件上的滚动条,等等,系统都将产生一系列消息。
此外,对于应用带给系统的变化,如字体资源的改变、应用本身窗口的改变,系统都将通过消息以响应这种变化。
应用通过产生消息指示应用的窗口完成特定的任务,或与其他应用的窗口进行通信。
每个窗口都有一个处理Windows系统发送消息的处理程序,称为窗口程序。
它是隐含在窗口背后的一段程序脚本,其中包含对事件进行处理的代码。
Windows系统为每条消息指定了一个消息编号,例如当一个窗口变为活动窗口时,它事实上是收到一条来自Windows系统的WM_ACTIVATE消息,该消息的编号为6,它对应于VB窗口的Activate事件。
对于窗口来说,诸如Open、Activate、MouseDown、Resize 等事件,实际上对应的是窗口内部的消息处理程序,这些程序对于用户来讲是不可见的。
类似地,命令按钮也有消息处理程序,它的处理程序响应诸如WM_LBUTTONDOWN和WM_RBUTTONDOWN之类的消息,即激活命令按钮的MouseDown事件。
WINDOWS的消息处理机制为了能在应用程序中监控系统的各种事件消息,提供了挂接各种回调函数(HOOK)的功能。
这种挂钩函数(HOOK)类似扩充中断驱动程序,挂钩上可以挂接多个反调函数构成一个挂接函数链。
MFC消息机制详解
消息映射的实现Windows消息概述Windows应用程序的输入由Windows系统以消息的形式发送给应用程序的窗口。
这些窗口通过窗口过程来接收和处理消息,然后把控制返还给Windows。
消息的分类队列消息和非队列消息从消息的发送途径上看,消息分两种:队列消息和非队列消息。
队列消息送到系统消息队列,然后到线程消息队列;非队列消息直接送给目的窗口过程。
这里,对消息队列阐述如下:Windows维护一个系统消息队列(System message queue),每个GUI线程有一个线程消息队列(Thread message queue)。
鼠标、键盘事件由鼠标或键盘驱动程序转换成输入消息并把消息放进系统消息队列,例如WM_MOUSEMOVE、WM_LBUTTONUP、WM_KEYDOWN、WM_CHAR等等。
Windows 每次从系统消息队列移走一个消息,确定它是送给哪个窗口的和这个窗口是由哪个线程创建的,然后,把它放进窗口创建线程的线程消息队列。
线程消息队列接收送给该线程所创建窗口的消息。
线程从消息队列取出消息,通过Windows把它送给适当的窗口过程来处理。
除了键盘、鼠标消息以外,队列消息还有WM_PAINT、WM_TIMER和WM_QUIT。
这些队列消息以外的绝大多数消息是非队列消息。
系统消息和应用程序消息从消息的来源来看,可以分为:系统定义的消息和应用程序定义的消息。
系统消息ID的范围是从0到WM_USER-1,或0X80000到0XBFFFF;应用程序消息从WM_USER(0X0400)到0X7FFF,或0XC000到0XFFFF;WM_USER到0X7FFF范围的消息由应用程序自己使用;0XC000到0XFFFF范围的消息用来和其他应用程序通信,为了ID的唯一性,使用::RegisterWindowMessage来得到该范围的消息ID。
消息结构和消息处理消息的结构为了从消息队列获取消息信息,需要使用MSG结构。
(完整word版)常用的十三种hook类型
本文将试图以下面的顺序讲解HOOK的大部分内容:1、 WINDOWS的消息机制2、 HOOK介绍3、 HOOK链4、 HOOK钩子的作用范围5、 HOOK类型6、回调函数7、 HOOK钩子的安装与卸载8、 HOOK实例演示+++++++++++++++++++WINDOWS的消息机制+++++++++++++++++++Windows系统是以消息处理为其控制机制,系统通过消息为窗口过程(windowsprocedure)传递输入。
系统和应用两者都可以产生消息。
对于每个输入事件,例如用户按下了键盘上的某个键、移动了鼠标、单击了一个控件上的滚动条,等等,系统都将产生一系列消息。
此外,对于应用带给系统的变化,如字体资源的改变、应用本身窗口的改变,系统都将通过消息以响应这种变化。
应用通过产生消息指示应用的窗口完成特定的任务,或与其他应用的窗口进行通信。
每个窗口都有一个处理Windows系统发送消息的处理程序,称为窗口程序。
它是隐含在窗口背后的一段程序脚本,其中包含对事件进行处理的代码。
Windows系统为每条消息指定了一个消息编号,例如当一个窗口变为活动窗口时,它事实上是收到一条来自Windows系统的WM_ACTIVATE消息,该消息的编号为6,它对应于VB窗口的Activate事件。
对于窗口来说,诸如Open、Activate、MouseDown、Resize等事件,实际上对应的是窗口内部的消息处理程序,这些程序对于用户来讲是不可见的。
类似地,命令按钮也有消息处理程序,它的处理程序响应诸如WM_LBUTTONDOWN和WM_RBUTTONDOWN之类的消息,即激活命令按钮的MouseDown事件.WINDOWS的消息处理机制为了能在应用程序中监控系统的各种事件消息,提供了挂接各种回调函数(HOOK)的功能.这种挂钩函数(HOOK)类似扩充中断驱动程序,挂钩上可以挂接多个反调函数构成一个挂接函数链.系统产生的各种消息首先被送到各种挂接函数,挂接函数根据各自的功能对消息进行监视、修改和控制等,然后交还控制权或将消息传递给下一个挂接函数以致最终达到窗口函数。
Microsoft Foundation Classes初学教程
1.1 怎样学好VC这个疑问许多兄弟都问过我,当然流汗是有必要的,但一同如果按照某种思路进行有计划的学习就会起到非常好的效果。
万事开头难,为了帮忙兄弟们更快的掌握VC开发,下面我将自个的一点体会讲一下:1、需要有好的C/C++基础。
正所谓“磨刀不误砍柴工”,最初步接触VC时不要急于初步Windows程序开发,而是大约进行一些字符界面程序的编写。
这样做的目的主要是增加对言语的晓得程度,一同也操练自个的思维和晓得一些在编程中常犯的差错。
更重要的是晓得并能运用C++的各种特性,这些在往后的开发中都会有很大的帮忙,特别是运用MFC进行开发的兄弟对C++一定要能熟练运用。
2、晓得Windows的消息机制,窗口句柄和其他GUI句柄的意义和用途。
晓得和MFC各个类功用邻近的API函数。
3、一定要晓得MFC中消息映射的效果。
4、操练自个在编写代码时不运用参考书而是运用Help Online。
5、记住一些常用的消息称谓和参数的意义。
6、学会看别人的代码。
7、多看书,少买书,买书前一定要慎重。
8、闲下来的时分就看参考书。
9、多来我的主页。
^O^后边几条是我自个的一点定见,你可以根据需要和本身的情况选用适用于自个的方法。
此外我将一些我在选择参考书时的原则:关于初学者:大约选择一些内容比较悉数的书本,并且书本中的内容大约以合理的方法安排,在运用该书时可以抵达墨守成规的效果,书中的代码要有详细的说明。
尽量买翻译的书,因为这些书一般都比较易懂,并且言语比较轻松。
买书前一定要慎重如果买到不好用的书可以会对自个的学习积极性发生冲击。
关于现已掌握了VC的兄弟:这种程度的开发者大约加深自个对系统原理,技术要害的晓得。
需要选择一些对原晓得说的比较透彻的书本,这样一来才会对新技术有更多的晓得,最佳书中对技术的运用有一定的论说。
尽量选择演示代码必较精简的书,可以节约银子。
此外最佳涉猎一些辅助性的书本。
1.2 晓得Windows消息机制Windows系统是一个消息驱动的OS,啥是消息呢?我很难说得理解,也很难下一个定义(谁在嘘我),我下面从不相同的几个方面说明一下,希望我们看了后有一点晓得。
小邪
2009-2010第二学期《Windows程序设计》实验报告班级小邪姓名小邪学号_小邪一、实验目的1. 熟悉VC++集成开发环境2. 掌握Windows消息机制原理3. 熟悉MSDN的使用方法二、实验内容参考教材例子及课堂讲授,用API编写简单的Windows程序。
在程序编写过程中注意以下几点:(1) 建立工程的类型(Win32 Application)及需要包含的头文件(Windows.h)(2) WinMain函数的使用(Win32下程序的入口)(3) 完成Windows窗口产生的四个步骤:A.设计窗口类,即WNDCLASS结构体的填充, 其中注意窗口函数的指定和类名的命名B.注册窗口类,即RegisterClass(…) 函数的使用C.创建窗口,即CreateWindow(…) 函数的使用D.显示及更新窗口,即ShowWindow(…) 及UpdateWindow(…) 的使用(4) 进行消息循环,用GetMessage(…) 取出消息,分别用TranslateMessage(…) 和DispatchMessage(…) 进行消息的转换和分发。
注意消息的格式(MSG结构体)(5) 对窗口函数进行编写(窗口函数是一个回调(CALLBACK)函数,操作系统会自动调用该函数对窗口的消息进行处理),用一个switch…case语句对从消息队列中取出的消息进行处理,注意各个消息在switch中都要找到归宿,否则程序无法结束。
三、实验源码exp1.h#include <windows.h>extern char szTitle[];extern char szWindowclass[];int WINAPI WinMain( HINSTANCE, HINSTANCE,LPSTR,int); LRESULT CALLBACK WndProc(HWND,UINT, WPARAM,LPARAM);exp1.cpp#include "exp1.h"LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);char szMenuName[]="NULL";char szTitle[]="欢迎程序";char szWindowclass[]="win32";int WINAPI WinMain(HINSTANCE hInstance, // handle to current instance HINSTANCE hPrevInstance, // handle to previous instanceLPSTR lpCmdLine, // command lineint nCmdShow // show state){WNDCLASS w;w.style =CS_VREDRAW | CS_HREDRAW;w.lpszMenuName = szMenuName;w.cbClsExtra =0;w.cbWndExtra =0;w.hInstance =hInstance;w.hIcon = LoadIcon(NULL ,IDI_WINLOGO);w.hbrBackground =(HBRUSH)GetStockObject(DKGRAY_BRUSH);w.hCursor = LoadCursor(NULL ,IDC_WAIT);w.lpfnWndProc = WndProc;;w.lpszClassName =szWindowclass;RegisterClass(&w);HWND hwnd;hwnd=CreateWindow(szWindowclass,szTitle ,WS_OVERLAPPEDWINDOW ,//CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_US EDEFAULT,NULL,NULL, hInstance ,NULL);100,100,200,200,NULL,NULL, hInstance ,NULL);ShowWindow(hwnd ,SW_SHOW);UpdateWindow(hwnd);MSG msg;while(GetMessage(&msg , NULL ,0,0)){TranslateMessage(&msg);DispatchMessage(&msg);}return msg.wParam;}LRESULT CALLBACK WndProc(HWND hwnd, UINT message,WPARAM wParam, LPARAM lParam){PAINTSTRUCT ps;HDC hdc;char szHello[]="欢迎";switch(message){case WM_PAINT:hdc=BeginPaint(hwnd, &ps);TextOut(hdc ,80,80,szHello,strlen(szHello));EndPaint(hwnd, &ps);break;case WM_CLOSE:PostQuitMessage(0);break;default:return DefWindowProc(hwnd, message, wParam,lParam);}return 0;}四、实验总结通过本次实验,完成了实验任务,达到了实验目的,进行了基础知识的学习,再通过上机实践,加深了对知识的理解,起初毫无头绪,后来在做出来同学的帮助下完成实验,其中还有许多不足,在以后的学习中加以改正,更加努力。
Windows窗口开发原理(窗口的创建消息机制)
Windows窗⼝开发原理(窗⼝的创建消息机制)在windows应⽤程序中,窗⼝是其⾮常重要的⼀个元素。
并且窗⼝是通过窗⼝句柄来标识的。
句柄(HANDLE)是windows程序中⼀个重要的概念,其标识各种资源,包括图标句柄(HICON)、光标句柄(HCURSOR)和画刷句柄(HBRUSH)。
下⾯以⼀个带有⾃定义的画刷、光标和图标的windows窗⼝为例,讲解win32窗⼝的创建过程。
windows消息机制windows程序是基于事件驱动⽅式的程序设计模式,主要是基于消息的。
⽐如当⽤户在窗⼝中画图的时候,按下⿏标左键,此时os会感知到这⼀事件,于是将此事件包装成⼀个消息,投递到应⽤程序的消息队列中,然后应⽤程序从消息队列中取出消息,经过transltor翻译、分发消息,然后交由os调⽤窗⼝过程函数(应⽤程序注册的回调函数)或(DefWindowProc系统默认的回调处理函数)进⾏处理。
创建⼀个窗⼝的基本流程设计窗⼝类窗⼝的特征是由WNDCLASS结构体来定义的,其定义了这个窗⼝的基本属性,所以我们只需填充结构体各成员信息即可。
typedef struct tagWNDCLASSW {UINT style;WNDPROC lpfnWndProc;int cbClsExtra;int cbWndExtra;HINSTANCE hInstance;HICON hIcon;HCURSOR hCursor;HBRUSH hbrBackground;LPCWSTR lpszMenuName;LPCWSTR lpszClassName;} WNDCLASSWtypedef WNDCLASSW WNDCLASS;//WNDCLASS是WNDCLASSW的别名View Code这⾥要⾸先说明下各类型定义//LRESULT :long// UINT:unsigned int//WPARAM:unsigned int//LPARAM:unsigned int//LPCWSTR:const w_chart_t *;// typedef WORD ATOM; //BUGBUG - might want to remove this from minwin// typedef unsigned short WORD;// typedef unsigned long DWORD;//LPCWSTR const w_char_t * 宽字符//LPCSTR const char *wchar_t szAppclassName[] = _T("FirstWin32");WNDCLASS wc;wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;//窗⼝类的样式(要让窗⼝在⽔平和垂直尺⼨发⽣变化时发⽣重绘,我们可以使⽤⽤位或|操作符将其组合起来) //WNDPROC 函数指针类型wc.lpfnWndProc = WindowProc;//窗⼝回调函数/窗⼝处理函数wc.cbClsExtra = 0;//窗⼝类的附加内存⼤⼩wc.cbWndExtra = 0;//窗⼝附加内存⼤⼩wc.hInstance = hInstance;//当前应⽤程序实例句柄wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));//加载⾃定义的图标句柄//wc.hCursor = LoadCursor(NULL,IDC_CROSS);//光标句柄;加载系统光标,也可以采⽤下⾯的⽅式加载⾃定义的光标wc.hCursor = LoadCursor(hInstance, MAKEINTRESOURCE(IDC_CURSOR1));wc.hbrBackground = CreateSolidBrush(RGB(255, 255, 0));//红绿蓝三原⾊0~255,[0最暗,255最亮]wc.lpszMenuName = NULL;//菜单名wc.lpszClassName = szAppclassName;//窗⼝类型名 spy++(vs->⼯具选项)其中的第⼆个成员变量lpfnWndProc是⼀个函数指针,指向窗⼝过程函数,窗⼝过程函数时⼀个回调函数。
Windows消息机制详解
Windows消息机制详解消息是指什么?消息系统对于⼀个win32程序来说⼗分重要,它是⼀个程序运⾏的动⼒源泉。
⼀个消息,是系统定义的⼀个32位的值,他唯⼀的定义了⼀个事件,向 Windows发出⼀个通知,告诉应⽤程序某个事情发⽣了。
例如,单击⿏标、改变窗⼝尺⼨、按下键盘上的⼀个键都会使Windows发送⼀个消息给应⽤程序。
消息本⾝是作为⼀个记录传递给应⽤程序的,这个记录中包含了消息的类型以及其他信息。
例如,对于单击⿏标所产⽣的消息来说,这个记录中包含了单击⿏标时的坐标。
这个记录类型叫做MSG,MSG含有来⾃windows应⽤程序消息队列的消息信息,它在Windows中声明如下:消息可以由系统或者应⽤程序产⽣。
系统在发⽣输⼊事件时产⽣消息。
举个例⼦, 当⽤户敲键, 移动⿏标或者单击控件。
系统也产⽣消息以响应由应⽤程序带来的变化, ⽐如应⽤程序改变系统字体改变窗体⼤⼩。
应⽤程序可以产⽣消息使窗体执⾏任务,或者与其他应⽤程序中的窗⼝通讯。
消息中有什么?我们给出了上⾯的注释,是不是会对消息结构有了⼀个⽐较清楚的认识?如果还没有,那么我们再试着给出下⾯的解释:hwnd 32位的窗⼝句柄。
窗⼝可以是任何类型的屏幕对象,因为Win32能够维护⼤多数可视对象的句柄(窗⼝、对话框、按钮、编辑框等)。
message⽤于区别其他消息的常量值,这些常量可以是Windows单元中预定义的常量,也可以是⾃定义的常量。
消息标识符以常量命名的⽅式指出消息的含义。
当窗⼝过程接收到消息之后,他就会使⽤消息标识符来决定如何处理消息。
例如、WM_PAINT告诉窗⼝过程窗体客户区被改变了需要重绘。
符号常量指定系统消息属于的类别,其前缀指明了处理解释消息的窗体的类型。
wParam 通常是⼀个与消息有关的常量值,也可能是窗⼝或控件的句柄。
lParam 通常是⼀个指向内存中数据的指针。
由于WParam、lParam和Pointer都是32位的,因此,它们之间可以相互转换。
VC++入门教程(windows入门程序详解)
本文由LOner芒川贡献 不是我写的. 第一讲:预备知识与概念介绍 注:我写这个专题目的是为VC初学者提供一个思路,我本人很菜,但我认为对于VC初学者来讲,可能有点帮助,当然,对于WinSDK编程,我也是刚刚接触。
如果你对WinSDK编程较熟,请与我联系,咱们共同来把这个专题做好,如果你发现了什么错误,也麻烦你给我留言指正。
我写的内容也基本上是我自己的一些理解,错误是肯定有的,如果你发现我的理解偏差很大的话,麻烦你提醒一下。
小朱! 什么是WinSDK: 大致说来windows编程有两种方法: 1.windwos c方式(SDK), 2.c++方式:即对SDK函数进行包装,如VC的MFC,BCB的OWL等,如果要深入 下去,还是要熟悉SDK。
两种方法有哪些区别呢:SDK编程就是直接调用windows的API进行编程,但是有上千个API组成(win95的API有两千多个),这种数目太大了,对于编程显然不利。
而MFC把这些API封闭起来,共有一百多个类组成。
一般只需20多个windows类和另外20多个通用的非windows类就可"干活"了,这一改变无疑是有很大好处的。
尽管MFC如此方便,但是要学VC,直接去学MFC却是不明智的选择。
只有在熟悉了MFC的运行机制的情况下,才有可能深入下去。
那些如多少天精通什么什么的书籍其实讲的全是些如怎么使用VC这种工具的话题,学来学去学会了怎么会使用VC这种工具,而不能深入MFC编程。
象VB这类工具就更令人感觉到太闷了,不过各有各的好处。
MFC虽然提高了程序员编程的效率,但是也失去了SDK编程的灵活性……不好意思,跑题了…… 本专题假定: C语言是windows的源语言,用C进行SDK编程是最合适的,你应该至少学过C语言,知道C语言的各种语法等,当我说到指针等类似概念的时候,你不至于茫然就行了。
你还应该安装了Visual C++6.0,低版本的就不用用了吧,D版的才几块钱吗? 推荐与参考资料: 1.Petzold的[programming windows by petzold],这是我看过的一本书(电子书),不过是E文的,我只看了一半,"下载空间"一栏能供了该电子书。
C#消息机制
C#消息机制C#消息机制⼀、消息概述Windows下应⽤程序的执⾏是通过消息驱动的。
消息是整个应⽤程序的⼯作引擎,我们需要理解掌握我们使⽤的编程语⾔是如何封装消息的原理。
1 什么是消息(Message)消息就是通知和命令。
在.NET框架类库中的System.Windows.Forms命名空间中微软采⽤⾯对对象的⽅式重新定义了Message。
新的消息(Message)结构的公共部分属性基本与早期的⼀样,不过它是⾯对对象的。
公共属性:HWnd 获取或设定消息的处理函数Msg 获取或设定消息的ID号Lparam 指定消息的LParam字段Wparam 指定消息的WParam字段Result 指定为响应消息处理函数⽽向OS系统返回的值2 消息驱动的过程所有的外部事件,如键盘输⼊、⿏标移动、按动⿏标都由OS系统转换成相应的消息发送到应⽤程序的消息队列。
每个应⽤程序都有⼀段相应的程序代码来检索、分发这些消息到对应的窗体,然后由窗体的处理函数来处理。
⼆、C#中的消息的封装C#对消息重新进⾏了⾯对对象的封装,在C#中消息被封装成了事件。
System.Windows.Forms.Application类具有⽤于启动和停⽌应⽤程序和线程以及处理Windows消息的⽅法。
调⽤Run以启动当前线程上的应⽤程序消息循环,并可以选择使其窗体可见。
调⽤Exit或ExitThread来停⽌消息循环。
C#中⽤Application类来处理消息的接收和发送的。
消息的循环是由它负责的。
从本质上来讲,每个窗体⼀般都对应⼀个窗体过程处理函数。
那么,C#的⼀个Form实例(相当于⼀个窗体)收到消息后是如何处理消息的?其实,这个问题的分析也就是展⽰了C#的消息封装原理。
实现⿏标左键按下的消息的响应(WM_LBUTTONDOWN)this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.Form1_MouseDown1);this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.Form1_MouseDown2);private void Form1_MouseDown1(object sender, System.Windows.Forms.MouseEventArgs e){if(e.Button==System.Windows.Forms.MouseButtons.Left)System.Windows.Forms.MessageBox.Show("消息被Form1_MouseDown1函数响应");}private void Form1_MouseDown2(object sender, System.Windows.Forms.MouseEventArgs e){if(e.Button==System.Windows.Forms.MouseButtons.Left)System.Windows.Forms.MessageBox.Show("消息被Form1_MouseDown2函数响应");}上⾯this.MouseDown是C#中的⼀个事件。
Windows消息机制与C++Builder消息处理及应用
Windows消息机制与C++Builder消息处理及应用张道新【期刊名称】《电脑技术信息》【年(卷),期】2000(000)012【摘要】@@C++Builder作为-RAD方式的程序开发工具,其全新的可视化编程环境,面向组件的开发模式无疑会大大地提高编程效率。
其对繁杂的Windows消息及api作了较全面的封装,编程者在大多数情况下不需理会Windows消息的细节,只要将心思放在组件的事件处理函数上即可。
然而,毕竟Windows操作系统是一个以消息驱动的系统,运行其上的应用程序,自然无法置处于系统之外,因此掌握并运用消息处理,对一些的问题的处理会有事半功倍的效果。
再说,尽管C++Builder(vcl)封装了大多数常用的消息,C++Builder所提供的事件处理能力已具备了相当程度的完备性,但当处理C++Builder未定义Windows消息,或自定义消息时,掌握C++BUILDER的内部消息处理机制还是十分必要的。
下面,从WINDOWS操作系统消息驱动机制开始,进而探讨C++BUILDER VCL中消息的封装、传递、处理机制,最后从新增消息处理过程的应用实例作为对所讲内容的印证和实践。
【总页数】3页(P30-31,32)【作者】张道新【作者单位】中国建设银行山东省滨州市分行科技部,山东滨州 256600【正文语种】中文【中图分类】TP3【相关文献】1.基于DLL的数据共享技术和Windows消息机制在摩托车整车检测系统中的应用 [J], 王亚晓;劳奇成2.C++Builder中的消息处理机制 [J], 杨国强3.深入.NET控件开发——System.Windows.Forms中的Windows窗口消息机制 [J], 唐泉4.在Windows消息机制下的应用程序远程监测系统 [J], 杨尊程;蒋泽军;王丽芳5.Borland C++Builder响应Windows消息机制的分析 [J], 唐艳华因版权原因,仅展示原文概要,查看原文内容请购买。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
在类头文件中也必须包含相应的函数原型说明: afx_msg void OnLButtonDown(UINT nFlags, CPoint point); 在代码文件中还需要消息映射宏,将 OnLButtonDown函数与应用程序框架联系在一起: BEGIN_MESSAGE_MAP(CMyFirstView, CView) //{{AFX_MSG_MAP(CMyFirstView) ON_WM_LBUTTONDOWN() //}}AFX_MSG_MAP // Standard printing commands END_MESSAGE_MAP()
键盘消息
Windows对每个按键定义了与设备无关的 编码,这种编码就叫做虚拟码。有了这个虚 拟码,Windows程序员就可以不必理睬扫 描码,而使用虚拟码来编写程序了
扫描码 虚 拟 码
2.4
MFC预定义宏
BEGIN_MESSAGE_MAP END_MESSAGE_MAP DECLARE_DYNAMIC IMPLEMENT_DYNAMIC ASSERT
2.3
MFC基本类
根类CObject
序列化支持 运行时类信息 对象诊断输出 与集合类的兼容性
2.3.1
2.3.2
命令目标类CCmdTarget
由CCmdTarget派生出的主框架类,包括
CWinApp CDocTemplate CDocument CView CWnd CFrameWnd等。
【例2-1】 鼠标左键消息
【例2-1】 鼠标左键消息
void CMyView::OnLButtonDown(UINT nFlags, CPoint point) { CDC *pDC=GetDC();//得到客户区设备指针 CString s; s.Format("X= %d, Y= %d",point.x,point.y); pDC->TextOut(10,10,s); CView::OnLButtonDown(nFlags, point); }
【例2-2】键盘消息
【例2-2】键盘消息
void CMyView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { // TODO: 在此添加消息处理程序代码 CDC *pDC=GetDC();//得到客户区设备环境指针 CString s; s.Format("用户按下键 %c, 键值为 %d",nChar,nChar); pDC->TextOut(10,10,s); CView::OnKeyDown(nChar, nRepCnt, nFlags); }
1.消息映射宏
2.运行时对象模型服务宏
3.诊断宏
4.异常宏
CATCH、CATCH_ALL、AND_CATCH
【例2-3】 简易计数器程序
要点分析
class CMyView : public CView { CMyView(); CMyDoc* GetDocument() const; int m_nCount; //计数指示 public: virtual void OnDraw(CDC* pDC); // 重写以绘制该视图 protected:// 生成的消息映射函数 DECLARE_MESSAGE_MAP() public: afx_msg void OnLButtonDown(UINT nFlags, CPoint point afx_msg void OnRButtonDown(UINT nFlags, CPoint point afx_msg void OnTimer(UINT nIDEvent); };
CWnd类的消息处理成员函数为:
void OnLButtonDown (UINT nFlags, CPoint point); void OnLButtonUp (UINT nFlags, CPoint point); void OnLButtonDblClk (UINT nFlags, CPoint point); 其中参数nFlags是几个控制键的状态 MK_CONTROL CTRL键被按下
取得当前被处理的消息
向本窗口发送消息,不通过消息循环, 直接调用窗口函数处理消息。窗口函 数执行完毕,该函数才返回。 向本窗口寄送消息,将消息放入消息 队列,立即返回。
PostMessage
5.窗口大小和位置函 数 GetClientRect GetWindowRect MoveWindow SetWindowPos
2 利用ClassWizard编制消息处理函数
虽然可以通过手工逐行编制消息处理函数,但
要记住上面那些语句确实是一件很困难的事。所 以实际工作中通常是利用MFC的ClassWizard 工具来自动编制消息处理函数。 在“类视图”窗口中,用鼠标右击CMyView项, 从弹出的快捷中选择“属性”窗口。在该窗口中, 选择“消息”选项页,从中为CMyView类添加 定时器消息WM_LBUTTONDOWN的响应函数 OnLButtonDown。
void CMyFirstView::OnLButtonDown(UINT nFlags, CPoint poin { // TODO: Add your message handler code here CView::OnLButtonDown(nFlags, point); }
消息映射
2.3.3
窗口类CWnd
CWnd类封装了窗口的主要操作
包括窗口的建立与销毁 窗口风格 窗口状态 窗口子类化 获取指定窗口等。
表2-1 CWnd类主要成员函数
1.更新和绘制窗口函 数 GetDC GetWindowDC Invalidate InvalidateRect ReleaseDC 取得客户区显示设备环境 取得整个窗口的显示设备环境 重绘整个客户区 重绘客户区的一个矩形范围 释放设备环境
取得窗口客户区的大小 取得整个窗口的大小 改变窗口的位置和大小 改变窗口的位置、大小和叠放层次
6.输入消息处理函数
OnKeyDown OnKeyUp OnLButtonDblClk OnLButtonDown OnLButtonUp OnMouseMove OnTimer
在按下一个非系统键时被调用 在按下一个非系统键弹起时被调 用 双击鼠标左键时被调用 单击鼠标左键按下时被调用 单击鼠标左键弹起时被调用 当鼠标移动时被调用 在用SetTimer设置定时器后被调 用
消息的分类
根据消息来源的不同 标准Windows消息
WM_PAINT WM_QUIT WM_CHARD等 BM表示按钮控件消息 CB表示组合框控件消息 DM表示默认下压式按钮控件消息 EM表示编辑控件消息 LB表示列表框控件消息 SBM表示滚动条控件消息
控制消息
命令消息
创建消息循环
MSG msg;//消息 …… while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam;
//消息结构 //接收消息句柄 //最低消息 //最高消息 //翻译消息 //传输消息
消息队列
这几条语句组成主消息循环,是Windows应 用程序的关键所在。Windows为每一个正在 运行的应用程序保持一个消息队列。 当任一键或鼠标按钮被按下时,Windows将 输入的事件翻译成一个消息,并将此消息放在 该程序的消息队列中去。 应用程序从消息循环接受消息。Windows程 序大量引用Windows函数,目前Windows函 数有600多种,大大方便了用户。
ID_SHOW等
2.2 标准的Windows消息
Hale Waihona Puke 1.WM_LBUTTONDOWN 2.WM_KEYDOWN 3.WM_CHAR 4.WM_CREATE 5.WM_CLOSE 6.WM_DESTROY 7.WM_QUIT 8.WM_PAINT
2.2 编制消息处理函数
所谓消息映射,就是让程序员指定要某个有消 息处理能力的MFC类处理某个消息,通过消 息映射,消息和它的处理函数才能对应起来。 当用户在窗口中单击鼠标左键时,Windows 系统就会自动发送WM_LBUTTONDOWN消 息给该窗口,如果程序需要对此消息有所反应 的话,则程序中应包含类似的函数:
MK_LBUTTON
MK_RBUTTON MK_SHIFT
鼠标左键被按下
鼠标右键被按下 SHIFT键被按下
例如,“MK_SHIFT|MK_LBUTTON”表示同时按下了 SHIFT键和鼠标左键。
处理鼠标消息
MFC中,鼠标消息响应函数的原型一般 为:
afx_msg void OnLButtonDown( UINT nFlags, CPoint point );
Visual C++程序设计
杨琦 计算机教学实验中心 西安交通大学
授课内容
2.1 事件驱动与消息循环机制 2.2 标准的Windows消息 2.3 MFC基本类 2.4 MFC预定义宏 2.5 基本范例
2.1 事件驱动与消息循环机制
所有的Windows应用程序都是消息驱动的; 消息处理是windows应用程序的核心; 消息就是操作系统通知应用程序某件事情已经 发生的一种方式; 当用户键入、移动鼠标或双击鼠标,或者用户 改变窗口的大小,都将向适当的窗口发送消息 一个窗口可以向另一个窗口发送消息,并且大 多数窗口通过向其他窗口发送一个稍有不向的 消息来响应消息。