delphi如何获取最后插入的U盘盘符?

在写一个U盘应用,请教高手如何识别最后插入的U盘盘符?例如我的电脑插入U盘出现的第一个盘符是F1、插入第一个U盘时,程序读出来此U盘的盘符F2、不拔出第一个U盘,插入第2... 在写一个U盘应用,请教高手如何识别最后插入的U盘盘符?
例如我的电脑插入U盘出现的第一个盘符是F
1、插入第一个U盘时,程序读出来此U盘的盘符F
2、不拔出第一个U盘,插入第2个U盘时,读出来盘符G
展开
 我来答
钟阔OK
推荐于2016-04-19 · TA获得超过336个赞
知道小有建树答主
回答量:183
采纳率:0%
帮助的人:213万
展开全部
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls,registry;

type
  TForm1 = class(TForm)
    Label1: TLabel;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure checkdevice(var MSG:Tmessage); message WM_DEVICECHANGE;
  end;

var
  Form1: TForm1;
  flag:boolean;

const

  DIGCF_PRESENT = $00000002;

  DIGCF_DEVICEINTERFACE = $00000010;

  ANYSIZE_ARRAY = 1;

  SetupAPI = 'SetupAPI.DLL';



type

  HDEVINFO = Pointer;

  ULONG_PTR = DWORD;



  PSPDevInfoData = ^TSPDevInfoData;

  SP_DEVINFO_DATA = packed record

    cbSize: DWORD;

    ClassGuid: TGUID;

    DevInst: DWORD;

    Reserved: ULONG_PTR;

  end;

{$EXTERNALSYM SP_DEVINFO_DATA}

  TSPDevInfoData = SP_DEVINFO_DATA;



  PSPDeviceInterfaceData = ^TSPDeviceInterfaceData;

  SP_DEVICE_INTERFACE_DATA = packed record

    cbSize: DWORD;

    InterfaceClassGuid: TGUID;

    Flags: DWORD;

    Reserved: ULONG_PTR;

  end;

{$EXTERNALSYM SP_DEVICE_INTERFACE_DATA}

  TSPDeviceInterfaceData = SP_DEVICE_INTERFACE_DATA;



  PSPDeviceInterfaceDetailDataA = ^TSPDeviceInterfaceDetailDataA;

  SP_DEVICE_INTERFACE_DETAIL_DATA_A = packed record

    cbSize: DWORD;

    DevicePath: array[0..ANYSIZE_ARRAY - 1] of AnsiChar;

  end;

{$EXTERNALSYM SP_DEVICE_INTERFACE_DETAIL_DATA_A}

  TSPDeviceInterfaceDetailDataA = SP_DEVICE_INTERFACE_DETAIL_DATA_A;







implementation


{$R *.dfm}


  function SetupDiGetClassDevsA(ClassGuid: PGUID; const Enumerator: PAnsiChar;

  hwndParent: HWND; Flags: DWORD): HDEVINFO; stdcall; external SetupAPI;



function SetupDiEnumDeviceInterfaces(DeviceInfoSet: HDEVINFO;

  DeviceInfoData: PSPDevInfoData; const InterfaceClassGuid: TGUID;

  MemberIndex: DWORD; var DeviceInterfaceData: TSPDeviceInterfaceData): BOOL; stdcall; external SetupAPI;

{$EXTERNALSYM SetupDiEnumDeviceInterfaces}



function SetupDiGetDeviceInterfaceDetailA(DeviceInfoSet: HDEVINFO;

  DeviceInterfaceData: PSPDeviceInterfaceData;

  DeviceInterfaceDetailData: PSPDeviceInterfaceDetailDataA;

  DeviceInterfaceDetailDataSize: DWORD; var RequiredSize: DWORD;

  Device: PSPDevInfoData): BOOL; stdcall; external SetupAPI;



function SetupDiDestroyDeviceInfoList(DeviceInfoSet: HDEVINFO): BOOL; stdcall; external SetupAPI;



function GetUSBDiskID(const DiskID: string; var PID: string): Boolean;

var

  USBGuid: TGUID;

  USBHandle: HDEVINFO;

  Success: LongBool;

  Devn: Integer;

  DevData: TSPDevInfoData;

  DeviceInterfaceData: TSPDeviceInterfaceData;

  FunctionClassDeviceData: PSPDeviceInterfaceDetailDataA;

  BytesReturned: DWORD;

  Reg: TRegistry;

  RegData: array of Char;

  i, RegSize: Integer;

  Str, USBPath: string;

begin

  Result := false;

  Pid := '';

  Reg := TRegistry.Create;

  try

    Reg.RootKey := HKEY_LOCAL_MACHINE;

    Reg.OpenKey('SYSTEM\MountedDevices', false);

    RegSize := Reg.GetDataSize(Format('\DosDevices\%s', [DiskID]));

    SetLength(RegData, RegSize + 1);

    Reg.ReadBinaryData(Format('\DosDevices\%s', [DiskID]), RegData[0], RegSize + 1);

    for i := 0 to RegSize - 1 do if RegData[i] <> #0 then Str := Str + RegData[i];

    Str := Copy(Str, Pos('#RemovableMedia#', Str) + 16, Length(Str));

    Str := Copy(Str, 1, Pos('RM', Str) - 2);

    Str := UpperCase(Str);

    Reg.CloseKey;

    USBGuid := StringToGUID('{53f56307-b6bf-11d0-94f2-00a0c91efb8b}');

    USBHandle := SetupDiGetClassDevsA(@USBGuid, nil, 0, DIGCF_PRESENT or DIGCF_DEVICEINTERFACE);

    if USBHandle = Pointer(INVALID_HANDLE_VALUE) then Exit;

    Devn := 0;

    repeat

    DeviceInterfaceData.cbSize := SizeOf(TSPDeviceInterfaceData);

    Success := SetupDiEnumDeviceInterfaces(USBHandle, nil, USBGuid, Devn, DeviceInterfaceData);

    if Success then begin DevData.cbSize := SizeOf(DevData); BytesReturned := 0;

    SetupDiGetDeviceInterfaceDetailA(USBHandle, @DeviceInterfaceData, nil, 0, BytesReturned, @DevData);

    if (BytesReturned <> 0) and (GetLastError = ERROR_INSUFFICIENT_BUFFER) then begin FunctionClassDeviceData := AllocMem(BytesReturned);

    FunctionClassDeviceData^.cbSize := SizeOf(TSPDeviceInterfaceDetailDataA);

    if SetupDiGetDeviceInterfaceDetailA(USBHandle, @DeviceInterfaceData, FunctionClassDeviceData, BytesReturned, BytesReturned, @DevData) then begin

    USBPath := StrPas(PChar(@FunctionClassDeviceData.DevicePath));

    if Reg.OpenKeyReadOnly(Format('SYSTEM\CurrentControlSet\Enum%s', [StringReplace(Copy(USBPath, 4, Pos('{', USBPath) - 5), '#', '\', [rfReplaceAll])])) then

    if UpperCase(Reg.ReadString('ParentIdPrefix')) = Str then begin Delete(USBPath, 1, Pos('#', USBPath));

    PID := Copy(USBPath, Pos('#', USBPath) + 1, Length(USBPath));

    PID := Copy(PID, 1, Pos('#{', PID) - 1);

    PID := UpperCase(StringReplace(PID, '&', '', [rfReplaceAll]));

    Result := True; Break; end; Reg.CloseKey; Inc(Devn); end;

    FreeMem(FunctionClassDeviceData); end; end;

    until not Success;

    SetupDiDestroyDeviceInfoList(USBHandle);

    finally Reg.Free; end; end;

procedure Tform1.checkdevice(var msg: TMessage);
const
  DBT_DEVICEARRIVAL = $8000;
  DBT_DEVICEREMOVECOMPLETE = $8004;
  DBT_DEVNODES_CHANGED = $0007;
var i,j:longint;   ssss,idd:string;
begin
  if flag then exit;
  case msg.WParam of
    DBT_DEVICEARRIVAL:begin
      for i:=1 to 26 do begin
        if directoryexists(chr(64+i)+':\') and (GetDriveType(PChar(chr(64+i)+':\')) = DRIVE_REMOVABLE)
        then begin
            showmessage('');
        end;
      end;
    end;//增加了新硬件
    DBT_DEVICEREMOVECOMPLETE:begin
  ShowMessage('') ;//移除硬件
end;
    DBT_DEVNODES_CHANGED:
    begin
        showmessage('');
    end;
  end;
end;
end.

以上代码在增加硬件时检测有多少个盘符,将新增的记录下来,移除硬件时将记录删去就好了

更多追问追答
追问
谢谢您的答复。但是您给的代码跟我自己的代码差不多,只能识别插入了几个U盘,但是不知道哪个是最后插入的。并不是盘符越大就是越后面插入的。
追答
不是,一开始队列为空,每次arrival就检测多了哪些,并且将新增的进队列,下一次arrival就看队列里什么是没有的而实际上是有的,那么这些就是新增的,同理,remove就删掉队列中相应元素
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式