我對使用C Builder的知識非常有限,你能給我一個例子或者指向我,教程展示如何在Delphi中使用FindNextChangeNotification,或者如果可能的話,如何在Delphi中使用C組件?檢測窗口外殼變化
檢測窗口外殼變化
回答
ReadDirectoryChanges似乎是我正在尋找的功能。這裏是我嘗試使用mghie的代碼Why does ReadDirectoryChangesW omit events?
我的目標是監視你將在Unit1中看到的目錄/路徑或文件。我只想要一個簡單的showmessage對話框,以便在檢測到位置更改時彈出。我無法找到我應該通過我的通知程序或功能的地方。 Unit2只保存了mghie中未改變的代碼。當我編譯這個項目並在目錄中做一個簡單的改變時,什麼都不會發生。我正確使用ReadDirectoryChanges?
這裏是1單元:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Unit2;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
fthread:TWatcherthread;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
//start directory or file watch here
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
fThread := TWatcherThread.Create('C:\Users\abe\Desktop\statcious\mitsu\Demo\abc.txt');
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
if fThread <> nil then begin
TWatcherThread(fThread).Shutdown;
fThread.Free;
end;
end;
end.
這裏是UNIT2:
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
type
TWatcherThread = class(TThread)
private
fChangeHandle: THandle;
fDirHandle: THandle;
fShutdownHandle: THandle;
protected
procedure Execute; override;
public
constructor Create(ADirectoryToWatch: string);
destructor Destroy; override;
procedure Shutdown;
end;
type
TForm2 = class(TForm)
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
{$R *.dfm}
constructor TWatcherThread.Create(ADirectoryToWatch: string);
const
FILE_LIST_DIRECTORY = 1;
begin
inherited Create(TRUE);
fChangeHandle := CreateEvent(nil, FALSE, FALSE, nil);
fDirHandle := CreateFile(PChar(ADirectoryToWatch),
FILE_LIST_DIRECTORY or GENERIC_READ,
FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE,
nil, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS or FILE_FLAG_OVERLAPPED, 0);
fShutdownHandle := CreateEvent(nil, FALSE, FALSE, nil);
Resume;
end;
destructor TWatcherThread.Destroy;
begin
if fDirHandle <> INVALID_HANDLE_VALUE then
CloseHandle(fDirHandle);
if fChangeHandle <> 0 then
CloseHandle(fChangeHandle);
if fShutdownHandle <> 0 then
CloseHandle(fShutdownHandle);
inherited Destroy;
end;
procedure TWatcherThread.Execute;
type
PFileNotifyInformation = ^TFileNotifyInformation;
TFileNotifyInformation = record
NextEntryOffset: DWORD;
Action: DWORD;
FileNameLength: DWORD;
FileName: WideChar;
end;
const
BufferLength = 65536;
var
Filter, BytesRead: DWORD;
InfoPointer: PFileNotifyInformation;
Offset, NextOffset: DWORD;
Buffer: array[0..BufferLength - 1] of byte;
Overlap: TOverlapped;
Events: array[0..1] of THandle;
WaitResult: DWORD;
FileName, s: string;
begin
if fDirHandle <> INVALID_HANDLE_VALUE then begin
Filter := FILE_NOTIFY_CHANGE_FILE_NAME or FILE_NOTIFY_CHANGE_DIR_NAME
or FILE_NOTIFY_CHANGE_SIZE or FILE_NOTIFY_CHANGE_LAST_WRITE;
FillChar(Overlap, SizeOf(TOverlapped), 0);
Overlap.hEvent := fChangeHandle;
Events[0] := fChangeHandle;
Events[1] := fShutdownHandle;
while not Terminated do begin
if ReadDirectoryChangesW (fDirHandle, @Buffer[0], BufferLength, TRUE,
Filter, @BytesRead, @Overlap, nil)
then begin
WaitResult := WaitForMultipleObjects(2, @Events[0], FALSE, INFINITE);
if WaitResult = WAIT_OBJECT_0 then begin
InfoPointer := @Buffer[0];
Offset := 0;
repeat
NextOffset := InfoPointer.NextEntryOffset;
FileName := WideCharLenToString(@InfoPointer.FileName,
InfoPointer.FileNameLength);
SetLength(FileName, StrLen(PChar(FileName)));
s := Format('[%d] Action: %.8xh, File: "%s"',
[Offset, InfoPointer.Action, FileName]);
OutputDebugString(PChar(s));
PByte(InfoPointer) := PByte(DWORD(InfoPointer) + NextOffset);
Offset := Offset + NextOffset;
until NextOffset = 0;
end;
end;
end;
end;
end;
procedure TWatcherThread.Shutdown;
begin
Terminate;
if fShutdownHandle <> 0 then
SetEvent(fShutdownHandle);
end;
end.
請爲您的所有代碼使用4個空格縮進,否則任何人都無法閱讀。 – jpfollenius 2009-10-14 06:15:21
你爲什麼在一個線程中而不是在主程序中這樣做?也許在發現任何變化之前,主程序會關閉。另外,什麼設置'終止'變量? – 2009-10-14 11:08:00
一個選項是使用TJvChangeNotify組件,JVCL支持Delphi和C++ Builder。
另一種選擇是使用SHChangeNotifyRegister函數。 看到這個鏈接Monitoring System Shell Changes using Delphi
再見。
- 1. 檢測窗口文本變化與pinvoke
- 2. 用戶檢測窗口時間變化
- 3. jQuery檢測窗體變化
- 4. 如何檢測窗口外點擊
- 5. 窗口外殼腳本返回碼
- 6. Solaris外殼/終端仿真器窗口
- 7. 檢測窗口在JavaScript最大化
- 8. 鉤檢測最小化窗口C#
- 9. 檢測時,前臺窗口改變
- 10. jQuery的 - 檢測窗口寬度變化,但不是一個高度變化
- 11. 自動檢測網頁瀏覽器窗口寬度變化?
- 12. 如何檢測窗口內容何時發生變化
- 13. 在樹視圖的父窗口中檢測焦點變化
- 14. SQL窗口功能檢測列變化值
- 15. 如何檢測窗口哈希的變化?
- 16. 外殼出口變量不會生效
- 17. 檢測變化
- 18. 檢測窗口版本
- 19. 檢測重疊窗口
- 20. 檢測窗口或與jquery
- 21. 64位窗口VMware檢測
- 22. 在後臺檢測窗口
- 23. 活動窗口檢測
- 24. 檢測窗口關閉
- 25. 窗口關閉時檢測?
- 26. 檢測控制檯窗口?
- 27. 檢測窗口jpeg圖標
- 28. 檢測窗口事件
- 29. Jquery - 檢測窗口寬度
- 30. 檢測StylusDown應用窗外
我會使用,而不是FindFirstChangeNotification和FindNextChangeNotification(除非你真的需要支持Windows 95/98/SE/ME ReadDirectoryChangesW )。 – 2009-10-13 19:16:58