Windows SDK编程(Delphi版) 之 消息处理
- 博客分类:
- 技术杂绘
Windows SDK编程(Delphi版) 之 消息处理
2010年06月17日
之前,已经讲了如何进行SDK编程,以及SDK运行的一些机理条件,同时还给出了一个SDK的Delphi编程模板,大家可以通过那个模板来实现一个简单的SDK框架。
这回就记录一下SDK里面的消息处理。Windows的应用处理核心就在消息上,而这个消息的处理就在对应的窗口的窗口过程中,之前,我给的模板中,就有一些消息处理,只是很少,比如说WM_DESTROY,这个消息就是在窗口释放的时候会触发,然后我发送了一个退出程序的消息。
Windows是一个交互式及时响应操作系统,那么每步的操作都会产生大量的消息。每条消息由一个唯一的32位整型值来表示,并且每条消息相当于某个事件。例如WM_LBUTTONDOWN表示鼠标左键按下,WM_LBUTTONUP表示鼠标左键弹起等等。WM_LBUTTONDOWN这个在C中实际上,都被叫做宏名,是用#define定义的,而在Delphi中就是我们定义的常量,用Const关键字标记,一般的系统消息,我们可以在 Messages单元中看到。比如一些常用的消息:
WM_CHAR,WM_PAINT,WM_MOVE,WM_CLOSE,WM_LBUTTONDOWN,WM_LBUTTONUP等。每条消息,都伴随着其他两个值,这两个值获得与具体消息相关的消息。其中一个值是WPARAM类型,另一个是LPARAM类型。实际上这两个类型就是LongInt类型。通常,他们保存着消息的一些附加信息,比如保存光标或者鼠标的坐标、按键值或与系统相关的值。
消息都是由程序的窗口函数来处理的,窗口函数有4个参数,以前说过,分别为消息所服务的窗口的句柄、消息本身和两个附加信息wparam,lparam。有时,附加消息被译成两个包含wparam和lparam参数的字。为了便于访问wParam和lParam,在C中有LOWORD和HiWORD这两个宏,而在Delphi中也可以使用loword()强制转型与hiWOrd这个函数来实现一样的功能。比如x := loword(lparam); y := hiword(lparam);
分别返回低位和高位。
现在来举例一些常见的Windows消息,比如我们用键盘输入时产生的按键消息,WM_Char,实际上WM_CHAR是被 TranslateMessage这个转换过来的(这个在之前已经说过)。当我们每按键一次,WM_CHAR消息就被送到活动窗口中,然后系统会调用本活动窗口的窗口过程来处理这个按键值。每次发送WM_CHAR时,wParam中就包含了所按键的ASCII码值。loword(lparam)中包含由于持续按键锁导致的重复按键的次数。HIWORD(lparam)中的每一个位表示的信息为:
位 意义
15 如果正被释放则为1,如果正被按下则为0
14 如果在发送消息前则为1,否则为0
13 ALT被按下时为1,否则为0
12 ~9 Windows使用,我们不管
8 如果按下的键是由增强键盘提供的扩充键则为1,否则0
7~0 依赖于生产厂家的键盘代码(既扫描代码)
通过上面的这个,可以知道WParam中保存的就是我们需要的ASCII代码,那么就可以通过这个来获得用户的按键信息了。于是,在那个模板的窗口过程中,我们可以添加一个消息的处理过程为
WM_CHAR:
begin
MessageBox(hwnd,pchar('消息:您按下了 '+inttostr(wParam)+' ASCII:'+CHAR(wParam)),'消息',64);
end;
这样,就能够获得你输入的按键的编码和按键信息了。
现在,再来看看另一个消息,WM_Paint,这个消息主要是在绘制界面的时候产生,通过对这个消息进行处理,可以在界面上绘制出任何我们想要的效果。现在说他的目的就是将我们上面说的按键信息通过这个WM_PAINT绘制显示在界面上,而且让他一直存在!为什么,我这里会说一直存在!这个与 Windows的一个显示机制有关系,这个后面再说。WM_PAINT的主要目的是用来绘制界面的,那么这个绘制如何来与界面屏幕进行交互呢?这里有另外一个概念就是设备描述表。通过设备描述表,用户的程序就能够和屏幕之间建立一个链路。所谓的设备描述表实际上是一个描述窗口输出显示环境的结构体,它包括了设备驱动程序和不同的现实参数,如当前的字体类型等。所以,我们要想将用户的按键信息显示在界面上,那么首先,我们需要在界面屏幕与程序之间建立一个链路,也就是要获得界面的设备描述表,获得设备界面描述表有几种方式。不过在WM_PAINT消息中,获得对应窗口的设备描述表,我们只能使用 BeginPaint这个API函数。其原型为:
HDC BeginPaint(Hwnd hwnd,LPPAINTSTRUCT lpPS);
Delphi的为
function BeginPaint(hWnd: HWND; var lpPaint: TPaintStruct): HDC; stdcall;
这个函数,就返回一个hwnd句柄所对应的窗口的设备描述表句柄,如果函数成功返回句柄,失败,返回0第二个参数返回时所对应的结构体中将包含程序用来重画窗口的信息。
typedef struct tagPAINTSTRUCT{
HDC hdc;
BOOL fErase;
RECT rcPaint;
BOOL fRestore;
Bool fIncUpdate;
Bool rgbReserved[32];
}PAINTSTRUCT;
Delphi中对应的结构在Windows单元中,可以看到,中hdc就包含被重画的窗口设备描述表句柄。此DC也是通过BeginPaint() 返回的。如果需要擦出窗口的背景,则fErase为非0值。不过只要在窗口创建时指定了一个背景画刷,就可以忽略fErase,系统会自动擦除窗口。 RECT类型是一个指定矩形区左上角和右下角的结构体。一旦我们获得了设备描述表,就可以像窗口中输出内容和绘制我们的信息。完成我们信息的绘制之后,必须调用EndPaint来释放设备描述表。
BOOL EndPaint(HWND hwnd,CONST PAINTSTRUCT *lpPS);
EndPaint返回非0值(它不可能失败)。hwnd指定重画窗口的句柄,第二个参数就是beginPaint的第二个参数。这里有两点需要主要,首先就是WM_PAINT中必须使用BeginPaint函数来获得设备描述表,然后就是使用BeginPaint获得设备描述表之后,必须使用 EndPaint来释放设备描述表。
另外获得设备描述表还有一个方法GetDC(HWND hwnd)用来获得指定窗口的设备描述表,释放设备描述表使用ReleaseDC(Hwnd,DC)。在不使用设备描述表的时候,释放它是必须的,因为设备描述表的数目只由自由内存的大小来决定,其数目有限,如果用户程序都不释放设备描述表,那么最终可用的设备描述表就会被耗尽,从而导致获得设备描述失败。
通过上面的描述,那么现在,我们就可将我们的按键信息一直显示在界面上,直到用户按下下一个按键位置。实现方式如下:
先定义一个LastChar: longint=-1,在winMain的时候初始化为-1,表示无效值
代码 WM_CHAR:
begin
//MessageBox(hwnd,pchar('消息:您按下了 '+inttostr(wParam)+' ASCII:'+CHAR(wParam)),'消息',64);
LastCHar := wParam;
r.Left := 30;
r.Top := 20;
r.Bottom := 50;
r.Right := 250;
Dc := GetDC(hwnd);
FillRect(Dc,r,GetStockObject(WHITE_BRUSH));
DrawText(Dc,Pchar('ASCII: '+inttostr(LastCHar)+' 字符:'+CHar(LastCHar)),-1,r,DT_CENTER or DT_SINGLELINE or DT_VCENTER);
ReleaseDC(Hwnd,Dc)
end;
此时将WM_CHar换成这样,然后用户在按键的时候,就会在界面上显示用户的按键信息了。里面用到了FillRect这个函数,这个函数是填充区域,使用它的目的是刷新界面为白色,去掉上次绘制的文字信息。但是现在这个有个问题,就是当用户将程序最小化在恢复的时候,我们记录的文字信息就丢失了。前面,我已经说过,这是由于Windows的显示机制决定的,Windows并不帮我们恢复窗口内所包含的记录,所以这种情况下,我们必须自己保存记录,然后重新显示窗口的内容,窗口每次恢复的时候,都会向用户的程序发送一个WM_Paint消息,每次接收到这个消息,他都必须重新显示窗口中的内容,于是我们需要在窗口中处理我们自己的绘制消息。这里实际上在模板中,我已经写了一个hello word的wm_Paint模板,现在我们只用将WM_CHar中的稍微修改,搬到WM_Paint的实现中去,就能够实现永久记录了。
WM_PAINT:
begin
GetWindowRect(hwnd,r1);
r.Left := 0;
r.Top := 0;
r.Right := r1.Right - r1.Left;
r.Bottom := r1.Bottom - r1.Top;
Dc := BeginPaint(hwnd,PaintStruct);
try
SetBkMode(Dc,TRANSPARENT);
DrawText(Dc,'Hello World!',-1,r,DT_CENTER or DT_SINGLELINE or DT_VCENTER);
if LastCHar > -1 then
begin
r.Left := 30;
r.Top := 20;
r.Bottom := 50;
r.Right := 250;
Dc := GetDC(hwnd);
FillRect(Dc,r,GetStockObject(WHITE_BRUSH));
DrawText(Dc,Pchar('ASCII: '+inttostr(LastCHar)+' 字符:'+CHar(LastCHar)),-1,r,DT_CENTER or DT_SINGLELINE or DT_VCENTER);
ReleaseDC(Hwnd,Dc)
end;
finally
EndPaint(hwnd,PaintStruct);
end;
end;
然后还有一些其他的非常多的消息,其处理过程都是根据自己的需要,在窗口过程中的Case结构中添加需要的消息,加上自己的处理过程就好了。我这里不再一一讲述,具体的消息参考可以去找《Microsoft Win32程序员参考大全(五)----消息、结构和宏》这本书看看!里面记录了所有Windows的消息信息以及参考资料。
发表评论
-
VBS脚本常用经典代码收集
2012-01-20 02:13 714VBS脚本常用经典代码收集 2010年06月21日 1. ... -
多线程加速图像模板匹配
2012-01-20 02:13 655多线程加速图像模板匹 ... -
Java编程思想――并发(3)
2012-01-20 02:13 1001Java编程思想――并发(3) 2010年07月28日 ... -
ORACLE PL/SQL编程详解之七 程序包的创建与应用
2012-01-20 02:13 671ORACLE PL/SQL编程详解之七 ... -
fread函数和fwrite函数
2012-01-20 02:13 852fread函数和fwrite函数 2010年06月28日 ... -
[耀湾/微亚细亚] 夜降り萃梦乡 FIN.
2012-01-19 10:03 660[耀湾/微亚细亚] 夜降り萃梦乡 FIN. 2009年02月 ... -
她为我写的 ..........你就是我的天使…………
2012-01-19 10:03 552她为我写的 ..........你就是我的天使………… 2 ... -
D---的记忆3
2012-01-19 10:03 641D---的记忆3 2008年10月12日 一、洞察 ... -
《因为是你》--2
2012-01-19 10:03 641《因为是你》--2 2012年01月13日 兼职保姆 ... -
如何有效维护和发布“Windows + Android SDK + Eclipse”开发环境下的apk和代码
2012-01-17 02:44 1026如何有效维护和发布“Windows + Android SDK ... -
Kinect for Windows SDK beta 放出
2012-01-17 02:43 576Kinect for Windows SDK beta 放出 ... -
Windows Mobile 6 SDK及中文版模拟器下载地址
2012-01-17 02:43 1518Windows Mobile 6 SDK及中文版模拟器下载地址 ... -
SDK 问题
2012-01-17 02:43 686SDK 问题 5小时前 问题:点击AVD Manager ... -
回顾日志_20110609
2012-01-15 22:20 485回顾日志_20110609 2011年06月09日 先来 ... -
笔记66-67
2012-01-15 22:19 608笔记66-67 2010年06月02日 ... -
FLEX网站收集
2012-01-15 22:19 925FLEX网站收集 2009年12月19日 1.FLEX网 ... -
ActionScript3.0 垃圾回收机制 2010-4-19 雨
2012-01-15 22:19 637ActionScript3.0 垃圾回收机制 2010-4-1 ... -
SNS网站设计的几大技术支持
2012-01-15 22:19 742SNS网站设计的几大技术支持 2010年04月04日 第 ...
相关推荐
在RemObjects SDK中,RO(RemObjects)代表了“Remote Objects”,这是SDK的主要组件之一,它提供了一种强大的面向对象的编程模型,用于处理跨网络的远程方法调用。RO支持接口、类和结构体的透明传输,使得开发者...
海康SDK包含了一系列接口函数,这些函数允许开发者用编程语言(例如Delphi)与海康的设备进行交互。它提供了丰富的API,涵盖了视频流处理、设备控制、报警管理等多个方面,旨在简化开发过程,提高效率。 2. **...
这意味着开发者无需直接处理复杂的Android SDK接口,而是通过一个预先设计好的Delphi类来调用百度地图的功能。以下是关键步骤和知识点: 1. **集成百度地图SDK**:首先,你需要下载百度地图Android SDK,并将其库...
在这个案例中,海康SDK是为了帮助开发者利用Delphi编程语言来开发与海康设备相关的应用程序。 Delphi是一种基于Object Pascal的集成开发环境(IDE),它以其高效的编译器和VCL(Visual Component Library)框架而...
2. **Delphi编程环境**:Delphi是一款强大的面向对象的可视化编程工具,基于Pascal语言,适合快速开发Windows应用程序。使用Delphi配合海康SDK,开发者可以构建高效、稳定的监控系统应用。 3. **设备网络**:在这个...
在这个"海康威视SDK调用抓图、车牌解析-DELPHI版.zip"压缩包中,包含的是使用Delphi编程语言实现的源代码示例,主要涵盖了以下几个关键知识点: 1. **SDK登录**:在使用SDK进行任何操作之前,都需要先进行登录验证...
3. **多平台支持**:除了Windows,RemObjects SDK还支持iOS、Android、Mac OS X、Linux等操作系统,这使得Delphi开发者可以构建真正意义上的跨平台应用。 4. **强大的网络通信库**:SDK包含了高效的网络通信库,...
首先,我们需要准备好 Delphi XE5 的开发环境,包括 Delphi XE5 Update2 和 Windows 7 64bit。同时,我们还需要准备好第三方 SDK 的 Jar 包,例如中国气象的天气预报 Android SDK,它提供了一个 Jar 文件:...
"VFW.pas_Delphi版VFW SDK"是将VFW SDK的功能转换为Delphi语言的头文件(vfw.h)对应的单元文件(.pas)。这个转换使得Delphi开发者能够利用VFW SDK的功能来创建多媒体应用,而无需借助其他编程语言或进行复杂的接口...
由于Delphi的跨平台特性,RealThinClient SDK开发的应用程序可以轻松部署到不同的操作系统,如Windows、Linux、macOS等。这大大增强了软件的适应性和市场潜力。 **7. 性能优化** RealThinClient SDK针对HTTP(S)协议...
1. **跨平台支持**:RemObjects SDK Delphi支持多种操作系统,包括Windows、Mac OS X、iOS、Android、Linux等,这使得开发者可以构建能在不同平台上运行的应用程序。 2. **数据流对象(DataSnap)替代**:...
在本文中,我们将深入探讨"MySql SDK 编程1 之简单连接查询"这一主题,了解如何使用MySQL SDK进行数据库连接和执行基本查询。MySQL是一个广泛使用的开源关系型数据库管理系统,而MySQL SDK提供了与MySQL服务器交互的...
Delphi是一种流行的面向对象的编程语言,常用于开发Windows桌面应用。"海康威视 3.0SDK Delphi Demo" 是一个使用Delphi编写的示例项目,旨在帮助开发者理解如何利用海康威视的SDK来实现特定功能。 这个Demo包含了...
DirectX SDK 2006 for Delphi 是一个专为Delphi开发者设计的工具包,它包含了使用DirectX API在Windows平台上开发图形、音频和游戏应用程序所需的各种库、头文件、示例代码和文档。DirectX是微软推出的一套应用程序...
在本文中,我们将深入探讨如何使用Delphi编程环境来调用微信的Android SDK,特别是实现微信支付功能。2018年3月18日的这篇文档和代码将为我们提供宝贵的指导,帮助开发者在这个过程中遇到的问题。 首先,让我们理解...
海康威视是全球知名的安防监控设备制造商,其提供的SDK(Software Development Kit)允许...通过深入研究和学习这个Demo,开发者不仅可以掌握如何利用海康威视的SDK,还能提升自己的Delphi编程技能和视频处理能力。
在这个"海康-设备网络SDK-VB Java Delphi C# Demo"中,包含了针对C#、Delphi、VB和Java这四种主流编程语言的示例代码,帮助开发者快速理解和接入海康设备的网络功能。 首先,我们来看VB(Visual Basic)预览DEMO,...
本文将基于给定的标题“一个speech SDK编程的例子”和描述“VC++和speech SDK写的一个语音阅读的例子,很适合初学者”,深入探讨如何使用VC++结合Speech SDK进行语音编程。 首先,我们要了解什么是Speech SDK。...
综上所述,“海康威视2次开发delphi demo”项目展示了如何利用Delphi和海康威视SDK实现安防监控系统的定制功能,涉及到了图像处理、实时视频流、网络通信等多个IT领域的知识。这样的项目有助于提升开发者在Windows...
在本案例中,我们将探讨如何使用Delphi 7编程环境,通过调用海康威视提供的SDK(Software Development Kit),来实现对海康威视数字摄像头的功能控制,如浏览图像和图像抓拍。 首先,了解SDK的基本概念是必要的。...