如何避免windows message 重入的問題 |
尚未結案
|
Snooze
一般會員 發表:18 回覆:21 積分:7 註冊:2002-06-03 發送簡訊給我 |
下面code 是當有drive letter 新增或移除的時候
會分別Add sltDevADD 與 sltDevRmv 兩個StringList
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs; const DBT_DEVICEARRIVAL = $8000; //硬體裝置完成安裝 DBT_DEVICEREMOVECOMPLETE = $8004; //硬體裝置已經移除 type PDevBroadcastVolume = ^TDevBroadcastVolume; TDevBroadcastVolume = packed record dbcv_size: DWORD; dbcv_devicetype: DWORD; dbcv_reserved: DWORD; dbcv_unitmask: DWORD; dbcv_flags: Word; end; TForm1 = class(TForm) procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } procedure WMDeviceChange(var Msg: TMessage); message WM_DeviceChange; end; var Form1: TForm1; sltDevADD: TStringList; sltDevRmv: TStringList; implementation {$R *.dfm} function GetDrive(pDBVol: PDevBroadcastVolume): string; var i: Byte; Maske: DWORD; begin // if (pDBVol^.dbcv_flags and DBTF_Media) = DBTF_Media then begin Maske := pDBVol^.dbcv_unitmask; for i := 0 to 25 do begin if (Maske and 1) = 1 then Result := Char(i Ord('A')) ':'; Maske := Maske shr 1; end; end; end; procedure TForm1.WMDeviceChange(var Msg: TMessage); begin case Msg.wParam of DBT_DeviceArrival: begin if PDevBroadcastVolume(Msg.lParam).dbcv_flags <> $0001 then sltDevADD.Add( GetDrive(PDevBroadcastVolume(Msg.lParam)) ); end; DBT_DeviceRemoveComplete: begin if PDevBroadcastVolume(Msg.lParam).dbcv_flags <> $0001 then sltDevRmv.Add( GetDrive(PDevBroadcastVolume(Msg.lParam)) ); end; end; end; procedure TForm1.FormCreate(Sender: TObject); begin sltDevADD := TStringList.Create; sltDevRmv := TStringList.Create; end; end.但問題是我發現 當新增Drive Letter 時會同時好幾筆近來的狀況 比如插入usb 隨身碟 DBT_DeviceArrival 會收到三次 我嘗試用boolean 變數阻擋重入但實際上還是太快 檔不掉,有人有愈過同樣的問題嗎? Nice to meet u
------
Nice to meet u |
dllee
站務副站長 發表:321 回覆:2519 積分:1711 註冊:2002-04-15 發送簡訊給我 |
我先聲明,我沒有寫過類似您 drive letter 新增/移除的程式,
不過,對於重入問題及 Windows Message 處理的部分,
之前有提問過以下問題: ■【問題】什麼是 Thread-Safe 及如何測試?
http://delphi.ktop.com.tw/topic.php?TOPIC_ID=49776
■【問題】如何解決多執行緒重入及鎖定的問題
http://delphi.ktop.com.tw/topic.php?TOPIC_ID=49583
■【BCB】【問題】如何防止重入? (含問題程式)
http://delphi.ktop.com.tw/topic.php?TOPIC_ID=49478 而我目前的認知是,以您的程式寫法,應該不會有重入的問題,
因為系統一次只會處理一個 Message ,在這個 Message 還沒處理完之前,
不會離開處理函式,除非在處理函式內使用了 Application.ProcessMessages
但您的程式內並沒有,所以,應該不會有重入的問題。
如果會的話,那在這篇中:
■【問題】什麼是 Thread-Safe 及如何測試?
http://delphi.ktop.com.tw/topic.php?TOPIC_ID=49776
就不能說事件以 post/send message 的方式,交由主執行緒來執行,
同時在事件中可以叫用任何 VCL 元件。 如果, Windows Message 不會重入,那只是如何設計一個方式可以解決
收到重覆 Message 的處理。
對於 sltDevADD, sltDevRmv 這兩個 TStringList 可以設定 Duplicates:=dupIgnore;
自動濾除重覆的字串,
另外,再一個 Timer 固定時間比對 sltDevADD, sltDevRmv 來判斷目前到底有多或少那些磁碟。 或是用一個 TStringList 即可,一樣設 Duplicates:=dupIgnore;
而在 DBT_DeviceArrival 作 Add(),
在 DBT_DeviceRemoveComplete 找出那個字串,然後刪除它,
這樣,這個 List 就可以是目前可移除裝置的列表了。 StatPlus2 視動科技 VMASK - ViewMove Automation Software Kernel
------
http://www.ViewMove.com |
conundrum
尊榮會員 發表:893 回覆:1272 積分:643 註冊:2004-01-06 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |