Delphi5学习笔记之五

153.使用函数GetWindowsDirectory时的常用方法:

var

Wdir: String;

Begin

SetLength(Wdir,144);

If GetWindowsDirectory(Pchar(Wdir),144) <> 0 then

SetLenth(Wdir,StrLen(Pchar(Wdir)))这里要调用SetLength的目的:是因为在调用GetWindowsDirectory时传递给它的第一个参数是一个长字符类型的字符串,在执行完GetWindowsDirectory后,Delphi不知道字符串Wdir是否被修改,这样就不能对字符串进行及时的更新,所以这里使用了SetLength手动设置一下字符串,实现自动更新。

Else RaiseLastWin32Error;

End;


154.TSearchRec结构:

TSearchRecFindFirstFindNext函数的返回值类型,它定义如下:

TSearchRec = record

Time: Integer;//创建和修改文件的时间

Size: Integer;//文件大小(字节数)

Attr: Integer;//文件属性(faOnlyRead,faHidden,faSysFile)

Name: TFileName;//文件名

ExcludeAttr: Integer;//FindFirstFindNext内部使用,不必关心

FindHandle: THandle; //FindFirstFindNext内部使用,不必关心

FindData: TWin32FindData;

End;

结构TWin32FindData包含了找到的文件或子目录的信息,它的定义如下:

TWin32FindData = record

dwFileAttributes: DWORD;

ftCreationTime: TFileTime;

ftLastAccessTime: TFileTime;

ftLastWriteTime: TFileTime;

nFileSizeHigh: DWORD;

nFileSizeLow: DWORD;

dwReserved0: DWORD;//保留

dwReserved1: DWORD; //保留

cFileName: Array[0..MAX_PATH - 1] of AnsiChar;//null结尾的文件名

cAlternateFileName: Array[0..13] of AnsiChar;//8.3格式的文件名

End;

 

155.拷贝全目录

Procedure CopyDirectoryTree(AHandle: THandle;const AFromDirectory,AToDirectory: String);

Var

SHFileOpStruct: TSHFileOpStruct;

FromDir: PChar;

ToDir: PChar;

Begin

GetMem(FromDir,Length(AFromDirectory) + 2);

Try

GetMem(ToDir,Length(AToDirectory) + 2);

try

FillChar(FromDir^,Length(AFromDirectory) + 2);

FillChar(ToDir^,Length(AToDirectory) + 2);

StrCopy(FromDir,PChar(AFromDirectory));

StrCopy(ToDir,PChar(AToDirectory));

With SHFileOpStruct do

Begin

Wnd := AHandle;

wFunc := FO_COPY;

pFrom := FromDir;

pTo := ToDir;

fFlags := FOF_NOCONFIRMATION or FOF_RENAMEONCOLLISION;

fAnyOperationsAborted := False;

hNameMappings := nil;

lpszProgressTitle := nil;

if SHFileOperation(SHFileOpStruct) <> 0 then

RaiseLastWin32Error;

End;

Finally

FreeMem(ToDir,Length(AToDirectory) + 2);

End;

Finally

FreeMem(FromDir,Length(AFromDirectory) + 2);

End;

End;

 

CopyDirectoryTree参数说明:

AHandle:是一个用来显示源目录和目标目录的对话框的句柄。

另外两个参数是源目录和目标目录。

156.将文件或目录删除到回收站

Procedure ToRecycle(AHandle: THandle;const ADirName: String);

Var

SHFileOpStruct: TSHFileOpStruct;

DirName: PChar;

BufferSize: Cardinal;

Begin

BufferSize := Length(ADirName) + 2;

GetMem(DirName,BufferSize);

Try

FillChar(DirName^,BufferSize,0);

StrCopy(DirName,PChar(ADirName));

With SHFileOpStruct do

Begin

Wnd := AHandle;

wFunc := FO_DELETE;

pFrom := DirName;

pTo := nil;

fFlags := FOF_ALLOWUNDO;

fAnyOperationsAborted := False;

hNameMappings := nil;

lpszProgressTitle := nil;

End;

If SHFileOperation(SHFileOpStruct) <> 0 then

RaiseLastWin32Error;

Finally

FreeMem(DirName,BufferSize);

End;

End;

过程ToRecycle中的wFunc成员为FO_DELETEpTo成员为nil。如果将FOF_ALLOWUNDO 标志加入f Flags成员,函数将取消将文件放入回收站的操作。

157.高级消息处理

窗口过程是一种函数,当一个窗口收到消息时由Windows来调用它。在每个应用程序对象中都包含一个窗口过程,应用程序对象利用它来接收所有被发送到应用程序的消息。

TApplication类利用OnMessage ()事件通知消息的到来。TApplication.OnMessage只在应用程序的消息队列接收到一个消息时才被触发。一般应用程序接收到的消息是与窗口管理有关的消息 (例如WM_PAINTWM_SIZE) ,或由PostMessage()PostAppMessage()BroadcastSy stemMessage()API函数发送出的消息。但是,由于WindowsSendMessage()有可能会绕过消息队列直接将消息发送给窗口过程。当发生这种情况时,TApplication.OnMessage就不会被触发。

1.子类化窗口(也就是“截取应用程序窗体消息”)

为了知道什么时候一个消息被发送到应用程序,必须用自己的窗口过程代替Application的窗口过程。当在自己的窗口过程中对消息处理完后,要把消息再传递给原窗口过程。这样的过程就叫做子类化窗口

可以传递一个常量GWL_WNDPROCWin32API函数SetWindowLong()来指定一个新的窗口过程。

窗口过程可以是以下两种格式:

一是利用A P I定义;

二是利用D e l p h i使窗口方法作为窗口过程。

1. 一个Win32 API的窗口过程

一个A P I的窗口过程必须像这样声明:

Function AWndProc(AHandle: hWnd;Msg,wParam,lParam: Longint): Longint;stdcall;

声明中,Handle参数用于标识目标窗口;Msg是一个消息;wParamlpParam参数含有消息的附加信息。函数的返回值要依靠收到的消息确定。需要特别注意,此函数必须用stdcall作为调用约定。

可以这样使用SetWindowLong()函数给应用程序的窗口指定窗口过程:

Var

WProc: Pointer;

Begin

WProc := Pointer(SetWindowLong(Application.Handle,GWL_WNDPROC,Integer(@NewWndProc)));

End;

在此调用后,返回一个指针类型的WProc指向旧的窗口过程。对这个值的保留是很必要的,因为有些消息可能需要传递给旧的窗口过程。下面是一个窗口过程的实现示例:

Function NewWndProc(AHandle: hWnd;Msg,wParam,lParam: Longint): Longint; stdcall;

Begin

Result := CallWindowProc(WProc,Application.Handle,Msg,wParam,lParam);

End;

一定要把SetWindowLong()函数值保存起来。如果你在自定义的窗口过程中不把该值返还给旧窗口过程,有可能导致应用程序甚至操作系统的崩溃。

下面是具体使用示例:

unit ScWndPrc;

interface

uses Forms,Messages;

Const

DDGM_FOOMGM = WM_USER;

implementation

uses Windows,SysUtils,Dialogs;

var

WProc: Pointer;

function NewWndProc(AHandle: hWnd;Msg,wParam,lParam: Longint): Longint; stdcall;

begin

if Msg = DDGM_FOOMGM then

ShowMessage(Format('Message seen by WndProc! Value is: $%x',[Msg]));

Result := CallWindowProc(WProc,AHandle,Msg,wParam,lParam);

end;

initialization

WProc := Pointer(SetWindowLong(Application.Handle,

GWL_WNDPROC,Integer(@NewWndProc)));

end.

2). Delphi的窗口方法 此方法不好,暂不记录。

2.HookMainWindow

使用TApplicationHookMainWindow()方法也可以截取窗体消息。这种方法可以把一个自定义的方法放到TApplicationWndProc前面执行。

HookMainWindow的声明:

Procedure HookMainWindow(Hook: TWinowHook);

其中的参数Hook的类型TWindowHook是一个方法,它是如下声明的,

Type

TWindowHook = function (var Message: TMessage): Boolean of Object;

如果此方法返回True,表示消息已经处理,WndProc会立即返回。

在处理消息时,可以使用UnHookMainWindow,它的声明如下,

Procedure UnHookMainWindow(Hook: TWindowHook);

下面是一个小小例子:

unit MainFrm;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls;

type

THookForm = class(TForm)

cbDoLog: TCheckBox;

lstBoxLog: TListBox;

btnSend: TButton;

btnClose: TButton;

procedure FormCreate(Sender: TObject);

procedure FormDestroy(Sender: TObject);

procedure btnCloseClick(Sender: TObject);

procedure btnSendClick(Sender: TObject);

private

{ Private declarations }

function AppWindowHook(var Message: TMessage): Boolean;

public

{ Public declarations }

end;

var

HookForm: THookForm;

implementation

{$R *.dfm}

function THookForm.AppWindowHook(var Message: TMessage): Boolean;

const

LogStr = 'Message ID: $%x,wParam: $%x,lParam: $%x';

begin

Result := true;

if cbDoLog.Checked then

with Message do

begin

lstBoxLog.Items.Add(Format(LogStr,[Msg,wParam,lParam]));

end;

end;

procedure THookForm.FormCreate(Sender: TObject);

begin

Application.HookMainWindow(AppWindowHook);

end;

procedure THookForm.FormDestroy(Sender: TObject);

begin

Application.UnhookMainWindow(AppWindowHook);

end;

procedure THookForm.btnCloseClick(Sender: TObject);

begin

Close;

end;

procedure THookForm.btnSendClick(Sender: TObject);

begin

SendMessage(Application.Handle,WM_CLOSE,0,0);

end;

end

 
第一部分 快速开发的基础 第1章 Delphi 5下的Windows编程 1 1.1 Delphi产品家族 1 1.2 Delphi是什么 3 1.2.1 可视化开发环境 3 1.2.2 编译器的速度和已编译代码的效 率 4 1.2.3 编程语言的功能及其复杂性 4 1.2.4 数据库结构的灵活性和可扩展性 5 1.2.5 框架对设计和使用模式的扩充 5 1.3 历史回顾 5 1.3.1 Delphi 1 5 1.3.2 Delphi 2 6 1.3.3 Delphi 3 6 1.3.4 Delphi 4 7 1.3.5 Delphi 5 7 1.3.6 未来 7 1.4 Delphi 5的IDE 7 1.4.1 主窗口 8 1.4.2 窗体设计器 9 1.4.3 Object Inspector 9 1.4.4 代码编辑器 9 1.4.5 代码浏览器 10 1.4.6 源代码生成器 10 1.5 创建一个简单的应用程序 11 1.6 事件机制的优势在哪里 12 1.7 加速原型化 13 1.8 可扩展的组件和环境 13 1.9 IDE最重要的十点功能 13 1.10 总结 15 第2章 Object Pascal语言 16 2.1 注解 16 2.2 新的过程和函数特征 17 2.2.1 圆括号 17 2.2.2 重载 17 2.2.3 缺省值参数 17 2.3 变量 18 2.4 常量 19 2.5 运算符 20 2.5.1 赋值运算符 20 2.5.2 比较运算符 20 2.5.3 逻辑表达式 21 2.5.4 算术运算符 21 2.5.5 按位运算符 22 2.5.6 加减运算过程 22 2.6 Object Pascal类型 23 2.6.1 类型的比较 23 2.6.2 字符 24 2.6.3 字符串 24 2.6.4 变体类型 32 2.6.5 Currency 39 2.7 用户自定义类型 39 2.7.1 数组 39 2.7.2 动态数组 40 2.7.3 记录 41 2.7.4 集合 42 2.7.5 对象 43 2.7.6 指针 44 2.7.7 类型别名 46 2.8 强制类型转换和类型约定 46 2.9 字符串资源 47 2.10 测试条件 47 2.10.1 if语句 47 2.10.2 case语句 48 2.11 循环 49 2.11.1 for循环 49 2.11.2 while循环 49 2.11.3 repeat...until 50 2.11.4 Break()过程 50 2.11.5 Continue()过程 50 2.12 过程和函数 50 2.13 作用域 50 2.14 单元 55 2.14.1 uses子句 55 2.14.2 循环单元引用 56 2.15 包 56 2.15.1 使用Delphi的包 56 2.15.2 包的语法 56 2.16 面向对象编程 57 2.17 使用Delphi对象 58 2.17.1 声明和实例化 58 2.17.2 析构 59 2.18 方法 59 2.18.1 方法的类型 60 2.18.2 属性 61 2.18.3 可见性表示符 62 2.18.4 友类 62 2.18.5 对象的秘密 63 2.18.6 TObject:所有对象的祖先 63 2.18.7 接口 63 2.19 结构化异常处理 66 2.19.1 异常类 68 2.19.2 执行的流程 70 2.19.3 重新触发异常 71 2.20 运行期类型信息 72 2.21 总结 72 第3章 Win32 API 73 3.1 对象:以前和现在 73 3.1.1 内核对象 73 3.1.2 GDI和用户对象 75 3.2 多任务和多线程 75 3.3 Win32内存管理 76 3.3.1 什么是线性内存模式 76 3.3.2 Win32系统是怎样管理内存的 76 3.4 Win32的错误处理 78 3.5 总结 78 第4章 应用程序框架和设计 79 4.1 理解Delphi环境和项目的体系结构 79 4.2 构成Delphi 5项目的文件 79 4.2.1 项目文件 80 4.2.2 单元文件 80 4.2.3 窗体文件 8
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值