2010-02-02 15 views

cevap

4

API RegisterDeviceNotification bir USB cihazı eklendiğinde size bildireceğiz. Birim ile ilgili bilgiler DEV_BROADCAST_VOLUME structure'da verilmiştir. dbcv_unitmask, sürücü harfini verir.

+1

Bir örnek önerebilir misiniz? –

+2

http://msdn.microsoft.com/en-us/library/aa363215(VS.85).aspx –

+0

Teşekkürler, bunu deneyeceğim. –

1

Değişiklik bildirimlerini (sürücü için eklenen/silinmiş) kabuktan alabilirsiniz. Sen documenattion olarak kullanmak için bu Delphi kodu kullanabilirsiniz: Windows için

unit UnitChangeNotify; 

interface 

uses 
    Windows, Messages, SysUtils, Classes, ShlObj, Types; 

type 
    SHChangeNotifyEntry = record 
     pidlPath  : PItemIDList; 
     bWatchSubtree : Boolean; 
    end; 

    TChangeEventType = (
     cnAssocchanged, 
     cnAttributes, 
     cnCreate, 
     cnDelete, 
     cnDriveAdd, 
     cnDriveAddGui, 
     cnDriveRemoved, 
     cnMediaInserted, 
     cnMediaRemoved, 
     cnMkdir, 
     cnNetShare, 
     cnNetUnshare, 
     cnRenameFolder, 
     cnRenameItem, 
     cnRmdir, 
     cnServerDisconnect, 
     cnUpdateDir, 
     cnUpdateImage, 
     cnUpdateItem); 

    TChangeNotifyEvent = procedure(Sender: TObject; Event: TChangeEventType; const Paths: TStringDynArray) of object; 

    TChangeNotify = class(TComponent) 
    private 
     FHWnd:    HWND; 
     FRegID:   THandle; 
     FEntry:   SHChangeNotifyEntry; 
     FOnChange:   TChangeNotifyEvent; 
     function GetActive  (): Boolean; 
     procedure SetActive   (const Value: Boolean); 
     procedure WndProc   (var Msg: TMessage); 
     procedure DoEvent   (Event: TChangeEventType; const Paths: TStringDynArray); virtual; 
    public 
     constructor Create   (Aowner: TComponent); override; 
     destructor Destroy;   override; 
     property Active:   Boolean   read GetActive write SetActive; 
     property OnChange:   TChangeNotifyEvent read FOnChange write FOnChange; 
    end; 

const 
    SHCNF_ACCEPT_INTERRUPTS  = $0001; 
    SHCNF_ACCEPT_NON_INTERRUPTS = $0002; 
    SHCNF_NO_PROXY    = $8000; 

function SHChangeNotifyRegister( hWnd: HWND; fSources: Integer; wEventMask: DWORD; uMsg: UINT; cItems: integer; const Items: SHChangeNotifyEntry): THandle; stdcall; 
function SHChangeNotifyDeregister(hRegID: THandle) : BOOL; stdcall; 
function SHILCreateFromPath(  Path: Pointer; PIDL: PItemIDList; var Attributes: ULONG): HResult; stdcall; 

implementation 

const Shell32DLL = 'shell32.dll'; 

function SHChangeNotifyRegister; external Shell32DLL index 2; 
function SHChangeNotifyDeregister; external Shell32DLL index 4; 
function SHILCreateFromPath;  external Shell32DLL index 28; 

{ TChangeNotify } 

constructor TChangeNotify.Create(Aowner: TComponent); 
begin 
    inherited Create(AOwner); 
end; 

destructor TChangeNotify.Destroy; 
begin 
    Active := False; 
    inherited Destroy; 
end; 

procedure TChangeNotify.DoEvent(Event: TChangeEventType; const Paths: TStringDynArray); 
begin 
    if Assigned(FOnChange) then FOnChange(Self, Event, Paths); 
end; 

function TChangeNotify.GetActive(): Boolean; 
begin 
    Result := FHWnd <> 0; 
end; 

procedure TChangeNotify.SetActive(const Value: Boolean); 
begin 
    if Value = GetActive() then Exit; 
    if Value then begin 
     FHWnd := AllocateHWnd(WndProc); 
     FEntry.pidlPath  := nil; 
     FEntry.bWatchSubtree := True; 
     FRegID := SHChangeNotifyRegister(FHWnd, SHCNF_ACCEPT_INTERRUPTS or SHCNF_ACCEPT_NON_INTERRUPTS, 
              SHCNE_ALLEVENTS, WM_USER, 1, FEntry); 
     if FRegID = 0 then begin 
      DeallocateHWnd(FHWnd); 
      FHWnd := 0; 
      RaiseLastOSError(); 
     end; 
    end else begin 
     SHChangeNotifyDeregister(FRegID); 
     FRegID := 0; 
     DeallocateHWnd(FHWnd); 
     FHWnd := 0; 
    end; 
end; 

procedure TChangeNotify.WndProc(var Msg: TMessage); 
type 
    PPITEMIDLIST = ^PITEMIDLIST; 
var 
    Event: TChangeEventType; 
    i:  Integer; 
    Paths: TStringDynArray; 
    P:  PPITEMIDLIST; 
const 
    EventBits: array [ TChangeEventType ] of DWORD = (
     SHCNE_ASSOCCHANGED, 
     SHCNE_ATTRIBUTES, 
     SHCNE_CREATE, 
     SHCNE_DELETE, 
     SHCNE_DRIVEADD, 
     SHCNE_DRIVEADDGUI, 
     SHCNE_DRIVEREMOVED, 
     SHCNE_MEDIAINSERTED, 
     SHCNE_MEDIAREMOVED, 
     SHCNE_MKDIR, 
     SHCNE_NETSHARE, 
     SHCNE_NETUNSHARE, 
     SHCNE_RENAMEFOLDER, 
     SHCNE_RENAMEITEM, 
     SHCNE_RMDIR, 
     SHCNE_SERVERDISCONNECT, 
     SHCNE_UPDATEDIR, 
     SHCNE_UPDATEIMAGE, 
     SHCNE_UPDATEITEM); 
    EventPIDLCount: array [ TChangeEventType ] of Integer = (
     2, 
     1, 
     1, 
     1, 
     1, 
     1, 
     1, 
     1, 
     1, 
     1, 
     1, 
     1, 
     2, 
     2, 
     1, 
     1, 
     1, 
     1, 
     1); 
begin 
    case Msg.Msg of 
     WM_USER: begin 
      // lParam = eventmask 
      // wParam = array of PIDLs with 
      for Event := Low(Event) to High(Event) do begin 
       if EventBits[ Event ] and msg.LParam = EventBits[ Event ] then begin 
        SetLength(Paths, EventPIDLCount[ Event ]); 
        P := PPITEMIDLIST(Msg.WParam); 
        for i := 0 to High(Paths) do begin 
         SetLength(Paths[ i ], MAX_PATH); 
         if not SHGetPathFromIDList(P^, PChar(Paths[ i ])) then Paths[ i ] := '' else Paths[ i ] := PChar(Paths[ i ]); 
         Inc(P); 
        end; 
        DoEvent(Event, Paths); 
        Break; 
       end; 
      end; 
     end; 
    end; 
    DefaultHandler(Msg); 
end; 

end. 
İlgili konular