ITPub博客

首页 > Linux操作系统 > Linux操作系统 > Delphi5学习笔记之五

Delphi5学习笔记之五

原创 Linux操作系统 作者:uuxa 时间:2007-05-05 13:01:49 0 删除 编辑

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;

[@more@]

154.TSearchRec结构:

TSearchRec是FindFirst和FindNext函数的返回值类型,它定义如下:

TSearchRec = record

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

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

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

Name: TFileName;//文件名

ExcludeAttr: Integer;//由FindFirst和FindNext内部使用,不必关心

FindHandle: THandle; //由FindFirst和FindNext内部使用,不必关心

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_DELETE,pTo成员为nil。如果将FOF_ALLOWUNDO 标志加入f Flags成员,函数将取消将文件放入回收站的操作。

157.高级消息处理

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

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

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

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

可以传递一个常量GWL_WNDPROC给Win32API函数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是一个消息;wParam、lpParam参数含有消息的附加信息。函数的返回值要依靠收到的消息确定。需要特别注意,此函数必须用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

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

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.

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/7416120/viewspace-913387/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
  • 博文量
    111
  • 访问量
    301515