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;
[@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部落格 ” ,連結:http://blog.itpub.net/7416120/viewspace-913387/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Delphi5學習筆記之四筆記
- Delphi5學習筆記之三筆記
- hive學習筆記之五:分桶Hive筆記
- TypeScript學習筆記之五類(Class)TypeScript筆記
- JVM 學習筆記(五)JVM筆記
- cmake學習筆記(五)筆記
- Javascript 學習 筆記五JavaScript筆記
- ReactNative學習筆記五之生命週期React筆記
- 小五思科技術學習筆記之SSH筆記
- 《Mastering Delphi 6》學習筆記之五 (轉)AST筆記
- Java IO學習筆記五Java筆記
- android學習筆記五Android筆記
- Spss 學習筆記(五)SPSS筆記
- c++學習筆記(五)C++筆記
- 【Java學習筆記之五】java陣列詳解Java筆記陣列
- 字典--Python學習筆記(五)Python筆記
- 大資料學習筆記(五)大資料筆記
- Android學習筆記(五)——FragmentAndroid筆記Fragment
- 《機器學習》西瓜書學習筆記(五)機器學習筆記
- Kubernetes學習筆記(五):卷筆記
- Activiti 學習筆記五:流程變數筆記變數
- Qt學習筆記(五)QString 字串QT筆記字串
- Jenkinsant介紹(學習筆記五)Jenkins筆記
- OS學習筆記五:儲存模型筆記模型
- Python3.6學習筆記(五)Python筆記
- python學習筆記(五)——語句Python筆記
- node學習筆記之39筆記
- 學習筆記之測試筆記
- Swoft 學習筆記之配置筆記
- Boltdb學習筆記之〇--概述筆記
- flask學習筆記之blueprintFlask筆記
- JS學習筆記之this指向JS筆記
- Java學習筆記之staticJava筆記
- oracle之awr學習筆記Oracle筆記
- Web之http學習筆記WebHTTP筆記
- HexMap學習筆記(五)——更大的地圖筆記地圖
- Java IO學習筆記五:BIO到NIOJava筆記
- Netty學習筆記(五)NioEventLoop啟動Netty筆記OOP