Delphi直接用Windows API编程(2)

2019-03-04 13:38

WS_POPUPWINDOW WS_OVERLAPPED WS_POPUP WS_BORDER WS_CAPTION WS_CHILD WS_DISABLED WS_HSCROLL WS_ICONIC WS_MAXIMIZE WS_MAXIMIZEBOX WS_MINIMIZE WS_MINIMIZEBOX WS_SIZEBOX WS_SYSMENU WS_THICKFRAME WS_TILED WS_VISIBLE WS_VSCROLL WS_CAPTION, WS_SYSMENU, WS_THICKFRAME, WS_MINIMIZEBOX, WS_MAXIMIZEBOX 创建一个弹出式窗口,是以下几种风格的集合: WS_BORDER,WS_POPUP,WS_SYSMENU。WS_CAPTION与WS_POPUPWINDOW风格必须一起使用才能使窗口菜单可见 创建一个层叠式窗口,它有标题栏和边框,与WS_TILED风格一样 该窗口为弹出式窗口,不能与WS_CHILD同时使用 窗口有单边框 窗口有标题栏 该窗口为子窗口,不能与WS_POPUP同时使用 该窗口为无效,即对用户操作不产生任何反应 窗口有水平滚动条 窗口初始化为最小化 窗口初始化为最大化 窗口有最大化按钮 与WS_MAXIMIZE一样 窗口有最小化按钮 边框可进行大小控制的窗口 创建一个有系统菜单的窗口,必须与WS_CAPTION风格同时使用 创建一个大小可控制的窗口,与WS_SIZEBOX 风格一样. 创建一个层叠式窗口,有标题栏 窗口为可见 窗口有垂直滚动条

显示窗口用ShowWindow函数显示窗口。其在windows.pas的声明如下:

function ShowWindow(hWnd: HWND; nCmdShow: Integer): BOOL; stdcall; 其第一个参数hWnd是窗口句柄。

第二个参数nCmdShow决定了如何显示窗口,其取值含义如下表: 值 S W_FORCEMINIMIZE 含义 在WindowNT5.0中最小化窗口,即使拥有窗口的线程被挂起也会最小化。在从其他线程最小化窗口时才使用这个参数。 隐藏窗口并激活其他窗口。 最大化指定的窗口。 最小化指定的窗口并且激活在Z序中的下一个顶层窗口。 激活并显示窗口。如果窗口最小化或最大化,则系统将6

SW_MIOE SW_MAXIMIZE SW_MINIMIZE SW_RESTORE

SW_SHOW SW_SHOWDEFAULT SW_SHOWMAXIMIZED SW_SHOWMINIMIZED SW_SHOWMINNOACTIVATE SW_SHOWNA SW_SHOWNOACTIVATE SW_SHOWNOMAL: 窗口恢复到原来的尺寸和位置。在恢复最小化窗口时,应用程序应该指定这个标志。 在窗口原来的位置以原来的尺寸激活和显示窗口。 依据在STARTUPINFO结构中指定的SW_FLAG标志设定显示状态,STARTUPINFO 结构是由启动应用程序的程序传递给CreateProcess函数的。 激活窗口并将其最大化。 激活窗口并将其最小化。 窗口最小化,激活窗口仍然维持激活状态。 以窗口原来的状态显示窗口。激活窗口仍然维持激活状态。 以窗口最近一次的大小和状态显示窗口。激活窗口仍然维持激活状态。 激活并显示一个窗口。如果窗口被最小化或最大化,系统将其恢复到原来的尺寸和大小。应用程序在第一次显示窗口的时候应该指定此标志。

四、建立消息循环。

前面在叙述回调函数时,已经讨论了部分消息循环这方面的内容,在这我们再详细阐述这方面的内容。先看代码63-67行:

63 64 65 66 67

: : : : :

while(GetMessage(w_msg, w_Handle, 0, 0)) do begin

TranslateMessage(w_msg); DispatchMessage(w_msg); end;

我们已经知道GetMessage函数的功能是程序从消息队列中取出消息,其在windows.pas中的声明如下:

function GetMessage(var lpMsg: TMsg; hWnd: HWND; wMsgFilterMin, wMsgFilterMax: UINT): BOOL; stdcall;

第一个参数是要接收消息的MSG结构变量,其声明为: tagMSG = packed record hwnd: HWND; message: UINT; wParam: WPARAM; lParam: LPARAM; time: DWORD; pt: TPoint; end;

7

{$EXTERNALSYM tagMSG} TMsg = tagMSG; MSG = tagMSG;

{$EXTERNALSYM MSG} 其各域的说明如下:

? hwnd接收消息的窗口句柄,如果一个应用程序中有多个窗口,此参数就可决定让哪个窗口接收消息。

? message是一个32位无符号整数,它唯一标识了一种消息类型。每种消息类型都在Messages.PAS文件中定义了,这些常量都以WM_开头。比如说当窗口建立时,Windows就向应用程序发送一条WM_CREATE消息。

? wParam副消息值,其具体含义依赖于主消息值。 ? lParam副消息值,其具体含义依赖于主消息值。 ? time消息放入消息队列中的时间,是从Windows启动后所测量的时间值。Windows用这个域来使用消息保持正确的顺序。 ? pt消息放入消息队列时的鼠标坐标。

GetMessage函数第二个参数表示窗口句柄,NULL则表示要获取该应用程序创建的所有窗口的消息;第三,四参数指定消息范围。后面三个参数被设置为默认值(0,0,0),这就是表示程序将接收所有属于它的任何一个窗口的所有消息。在接收到WM_QUIT消息后GetMessage函数返回假(FALSE),除了WM_QUIT消息GetMessage函数对其余消息都返回TRUE。因此,在接收到WM_QUIT之前,程序中的消息循环(63-67行)可以一直循环下去。在接收到WM_QUIT之后意味着程序消息循环结束,终止程序。

在GetMessage函数执行后是TranslateMessage函数,此函数进行一些键盘消息转换(以后在详细讨论)。

然后是DispatchMessage函数将消息结构回传给Windows,Windows再调用程序本身的回调函数来完成各种消息的处理,以便程序实现各种功能。在此我们详细看一下回调函数的结构。本程序的回调函数是从14行到35行:

14 15 16 17 18 19 20

:function WindowProc(h_Wnd,u_Msg,w_Param,l_Param: LONGINT):LRESULT;stdcall; ://回调函数 :var p_hdc:hdc; : p_rect:trect;

: ps : PAINTSTRUCT ; :begin :

8

21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 :

:case u_msg of

: WM_DESTROY : PostQuitMessage (0);

: WM_CREATE :PlaySound(pchar('hellowin.wav'#0),0,SND_FILENAME or SND_ASYNC) ; : WM_PAINT :begin

: p_hdc := BeginPaint (h_wnd, ps) ; : GetClientRect (h_wnd, p_rect);

: DrawText (p_hdc, pchar('Hello, Windows!'#0), -1, p_rect, : DT_SINGLELINE or DT_CENTER or DT_VCENTER) ; : EndPaint (h_wnd, ps) ; : end; : : end;

: Result := DefWindowProc(h_Wnd, u_Msg, w_Param, l_Param); :end;

回调函数(本例是WindowProc)的参数格式是固定的,四个32位长整数: ? h_wnd是接收消息窗口的句柄(实际上就是32位长整数) ? u_Msg是主消息值 ? w_Param是副消息值 ? l_Param是副消息值

容易看出本程序处理了三个消息:

? WM_DESTROY:注销窗口消息,第23行,施行停机处理。此消息只出

现一次,即窗口关闭时。 ? WM_CREATE:窗口建立消息,第24行用PlaySound函数播放一段.wav

声音文件文件。此消息只出现一次,即窗口创建时。

? WM_PAINT:窗口重画消息,第25行到第31行,在窗口的用户区当

中位置显示“Hello, Windows!”。此消息发生的比较频繁,当窗口被调整大小时,被遮挡重新显示时等都发生此消息。此段程序的原理在下一节详细论述。

由程序结构可以知道,回调函数主要用了case语句解析判断u_msg中的消息,做分门别类的处理。以上程序只处理了三条消息,实际上在消息队列中还有很多消息,比如:WM_MOVE(窗口移动)、WM_KEYDOWN(键盘消息)、WM_RBUTTONDOWN(鼠标按键消息)等等,这些消息需要Windows进行处理,为此在函数的最后,需要调用DefWindowProc函数让Windows来对所有消息进行缺省处理。

综合以上所述,一个标准的Windows程序分成两部分:

9

一、 主程序建立程序框架,即初始化窗口,并建立消息循环。 二、 回调函数响应Windows消息,在相应的消息处理过程中实现程序功

能。

Windows中的句柄、标识符和数据类型:

另外我们在以上的叙述中经常看到一个词“句柄”。什么是句柄呢?句柄是一个32位的数,它在Windows中代表了一个对象。句柄的值主要是Windows分配提供的,如程序的窗口句柄就是CreateWindow函数返回的。应用程序需要保存这些句柄,以便以后调用API函数使用。在Windows定义了很多种类的句柄,下表示一些常用的句柄类型:

句柄类型 HANDLE HBITMAP HBRUSH HCTR HCURSOR HDC HDLG HFONT HICON HINSTANCE HMENU HMODULE HPALETTE HPEN HRGN HTASK HWND 说明 指向对象的句柄 保存位图信息的内存域的句柄 画刷句柄 子窗口控件句柄 鼠标光标句柄 设备描述表句柄 对话框句柄 字体句柄 图标句柄 应用程序的实例句柄 菜单句柄 模块句柄 颜色调色板句柄 在设备上画图时用于指明线型的笔的句柄 剪贴区域句柄 独立于已执行任务的句柄 窗口句柄

另外在Windows.PAS和Messages.PAS中定义了很多常量标识符,用以表示Windows中用到的数据信息。比如窗口重画消息:WM_DESTORY,再如窗口风格:WS_OVERLAPPEDWINDOW,可见有些标识符是由两个或三个字母组成并后跟下划线作为前缀,下表列出了常用的标识符前缀:

类别 前缀 CS CW 窗口类风格(窗口类设置) 创建窗口选项 10

DT IDI IDC MB SND WM WS 绘制文本选项 图标ID号 光标ID号 信息框选项 声音选项 窗口消息选项 窗口风格选项

本实例,讲述一个窗口应用程序的基本框架,和一些基本的API函数、数据结构的用法。读者至此应该对Windows的运营机制有了一个初步的了解,更可以体会到直接用API编程的威力,生成的程序只有9K左右,如果你用VCL建立一个同样的程序大概生成的程序要有二三百K。这不表明VCL编程就没用了,VCL编程是一种快速,功能强大的开发手段。而用API编程可以在一些对代码执行效率要求很高和实现一些特殊功能时大有用武之地。并且对程序员提高编程水平和认识Windows程序的本质有很大帮助。

11


Delphi直接用Windows API编程(2).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:证券投资学计算题练习

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: