Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 创建对象时出现运行时错误_Delphi_Usb_Pascal_Lazarus_Freepascal - Fatal编程技术网

Delphi 创建对象时出现运行时错误

Delphi 创建对象时出现运行时错误,delphi,usb,pascal,lazarus,freepascal,Delphi,Usb,Pascal,Lazarus,Freepascal,我尝试使用lazarus IDE“Free Pascal”,我需要使用上一个线程中讨论过的代码,如下所示: 这段代码在delphi中运行良好,但当我尝试在pascal和lazarus IDE中使用它时,在创建USB对象时出现了运行时错误 我使用已经存在的转换工具将此代码转换为免费的pascal 存在于lazarus IDE中 在Lazarus文档中,我发现了运行时错误217的含义 217发生未处理的异常 发生异常,并且不存在异常处理程序。这个 sysutils单元安装一个默认的异常处理程序,它

我尝试使用lazarus IDE“Free Pascal”,我需要使用上一个线程中讨论过的代码,如下所示:

这段代码在delphi中运行良好,但当我尝试在pascal和lazarus IDE中使用它时,在创建USB对象时出现了运行时错误

我使用已经存在的转换工具将此代码转换为免费的pascal 存在于lazarus IDE中

在Lazarus文档中,我发现了运行时错误217的含义

217发生未处理的异常

发生异常,并且不存在异常处理程序。这个 sysutils单元安装一个默认的异常处理程序,它捕获所有 异常和退出优雅

但我什么都做不了,解决不了问题, 我怎样才能解决这个问题

单元usb;
{$modedelphi}
接口
使用LCLIntf、LCLType、lmessage、Messages、sysutil、类、注册表、掩码、窗口;
类型
{事件类型}
TOnUsbChangeEvent=过程(AOObject:ToObject;
const ADevType,ADriverName,
对象的AFriendlyName(字符串);
{USB类}
TUsbClass=类(TObject)
私有的
FHandle:HWND;
福努斯布雷莫瓦尔,
FOnUsbInsertion:TOnUsbChangeEvent;
过程GetUsbInfo(const ADeviceString:string;
输出ADevType,ADriverDesc,
AFriendlyName:string);
过程WinMethod(var-AMessage:TMessage);
程序寄存器处理程序;
程序WMDeviceChange(变量A消息:TMessage);
公众的
构造函数创建;
毁灭者毁灭;推翻
属性OnUsbInsertion:TONUSBCHANGEVENT read FONUSBINERTION
写FOnUsbInsertion;
属性OnUsbRemoval:TONUSBCHANGEVENT read FOnUsbRemoval
写下福努斯布雷莫瓦尔;
结束;
// -----------------------------------------------------------------------------
实施
使用JwaWinUser、JwaDbt;
类型
//WinAPI定义
PDevBroadcastDeviceInterface=^DEV\u BROADCAST\u DEVICEINTERFACE;
设备接口=记录
dbcc_大小:DWORD;
dbcc_设备类型:DWORD;
dbcc_保留:DWORD;
dbcc_类GUID:TGUID;
dbcc_名称:char;
结束;
常数
//杂
GUID_devicentf_USB_DEVICE:TGUID='{A5DCBF10-6530-11D2-901F-00C04FB951ED}';
USB_接口=$00000005;//设备接口类
USB_插入=$8000;//系统检测到一个新设备
USB_移除=8004美元;//设备不见了
//注册表项
USBKEY='SYSTEM\CurrentControlSet\Enum\USB\%s\%s';
USBSTORKEY='SYSTEM\CurrentControlSet\Enum\USBSTOR';
SUBKEY1=USBSTORKEY+“\%s”;
SUBKEY2=SUBKEY1+“\%s”;
构造函数TUsbClass.Create;
开始
继承创造;
FHandle:=AllocateHWnd(WinMethod);
注册表处理程序;
结束;
析构函数TUsbClass.Destroy;
开始
解除分配HWND(FHandle);
继承性破坏;
结束;
过程TUsbClass.GetUsbInfo(const ADeviceString:string;
输出ADevType,ADriverDesc,
AFriendlyName:string);
var-sWork,sKey1,sKey2:string;
oKeys,oSubKeys:TStringList;
oReg:树木学;
i、 ii:整数;
bFound:布尔型;
开始
ADevType:='';
ADriverDesc:='';
AFriendlyName:='';
如果是“限制”,则开始
b发现:=假;
oReg:=TRegistry.Create;
oReg.RootKey:=HKEY\U LOCAL\U机器;
//提取注册表所需的字符串部分。如。
//\\?\USB\Vid#U 4146和Pid#U d2b5#000505040044#{a5dcbf10-…-54334fb951ed}
//我们需要sKey1='Vid_4146&Pid_d2b5'和sKey2='000505040044'
宣誓书:=副本(ADeviceString,pos(“#”,ADeviceString)+11026);
sKey1:=副本(sWork,1,位置(“#”,sWork)-1);
sWork:=副本(sWork,位置(“#”,sWork)+11026);
sKey2:=副本(sWork,1,位置(“#”,sWork)-1);
//从\USB密钥获取设备类型说明
如果oReg.OpenKeyReadOnly(格式为(USBKEY,[skey1,sKey2]),则开始
ADevType:=oReg.ReadString('DeviceDesc');
oReg.CloseKey;
oKeys:=TStringList.Create;
oSubKeys:=TStringList.Create;
//获取\USBSTOR中的键列表并枚举每个键
//与sKey2='000505040044'匹配的钥匙
//注意:我们正在查找的条目通常有“&0”
//附加在其上,如“000505040044&0”
如果是oReg.OpenKeyReadOnly(USBSWorkey),则开始
oReg.GetKeyNames(oKeys);
oReg.CloseKey;
//反复浏览列表以找到我们的sKey2
对于i:=0到oKeys。计数-1开始
如果oReg.OpenKeyReadOnly(格式(SUBKEY1[oKeys[i]]),则开始
oReg.GetKeyNames(oSubKeys);
oReg.CloseKey;
对于ii:=0到oSubKeys。计数-1开始
如果匹配任务(oSubKeys[ii],sKey2+'*'),则开始
//找到匹配项了吗?,获取实际描述和友好名称
如果oReg.OpenKeyReadOnly(格式(SUBKEY2[oKeys[i],
然后开始
ADriverDesc:=oReg.ReadString('DeviceDesc');
AFriendlyName:=oReg.ReadString('FriendlyName');
oReg.CloseKey;
结束;
b结果:=真;
结束;
结束;
结束;
如果找到了,就断开;
结束;
结束;
FreeAndNil(oKeys);
FreeAndNil(oSubKeys);
结束;
FreeAndNil(oReg);
结束;
结束;
过程TUsbClass.WMDeviceChange(var-AMessage:TMessage);
var-iDevType:integer;
sDevString,sDevType,
sDriverName,sFriendlyName:string;
pData:PDevBroadcastDeviceInterface;
开始
如果(AMessage.wParam=USB_插入)或
(AMessage.wParam=USB_删除)然后开始
pData:=PDevBroadcastDeviceInterface(AMessage.LParam);
iDevType:=pData^.dbcc_设备类型;
//它是USB接口设备吗?
if iDevType=
  USB:= TUsbClass.Create;
  USB.OnUsbChange:= Self.ChangeEvent;
  USB.OnDevVolume:= Self.VolumeEvent;
unit usb;

{$MODE Delphi}

interface
uses LCLIntf, LCLType, LMessages, Messages, SysUtils, Classes, Registry, Masks,windows;

type
  { Event Types }
  TOnUsbChangeEvent = procedure(AObject : TObject;
                                const ADevType,ADriverName,
                                      AFriendlyName : string) of object;

  { USB Class }
  TUsbClass = class(TObject)
  private
    FHandle : HWND;
    FOnUsbRemoval,
    FOnUsbInsertion : TOnUsbChangeEvent;
    procedure GetUsbInfo(const ADeviceString : string;
                         out ADevType,ADriverDesc,
                            AFriendlyName : string);
    procedure WinMethod(var AMessage : TMessage);
    procedure RegisterUsbHandler;
    procedure WMDeviceChange(var AMessage : TMessage);
  public
    constructor Create;
    destructor Destroy; override;
    property OnUsbInsertion : TOnUsbChangeEvent read FOnUsbInsertion
                                           write FOnUsbInsertion;
    property OnUsbRemoval : TOnUsbChangeEvent read FOnUsbRemoval
                                         write FOnUsbRemoval;
  end;



// -----------------------------------------------------------------------------
implementation
uses JwaWinUser, JwaDbt;

type
  // Win API Definitions
  PDevBroadcastDeviceInterface  = ^DEV_BROADCAST_DEVICEINTERFACE;
  DEV_BROADCAST_DEVICEINTERFACE = record
    dbcc_size : DWORD;
    dbcc_devicetype : DWORD;
    dbcc_reserved : DWORD;
    dbcc_classguid : TGUID;
    dbcc_name : char;
  end;

const
  // Miscellaneous
  GUID_DEVINTF_USB_DEVICE : TGUID = '{A5DCBF10-6530-11D2-901F-00C04FB951ED}';
  USB_INTERFACE                = $00000005; // Device interface class
  USB_INSERTION                = $8000;     // System detected a new device
  USB_REMOVAL                  = $8004;     // Device is gone

  // Registry Keys
  USBKEY  = 'SYSTEM\CurrentControlSet\Enum\USB\%s\%s';
  USBSTORKEY = 'SYSTEM\CurrentControlSet\Enum\USBSTOR';
  SUBKEY1  = USBSTORKEY + '\%s';
  SUBKEY2  = SUBKEY1 + '\%s';


constructor TUsbClass.Create;
begin
  inherited Create;
  FHandle := AllocateHWnd(WinMethod);
  RegisterUsbHandler;
end;


destructor TUsbClass.Destroy;
begin
  DeallocateHWnd(FHandle);
  inherited Destroy;
end;


procedure TUsbClass.GetUsbInfo(const ADeviceString : string;
                               out ADevType,ADriverDesc,
                                   AFriendlyName : string);
var sWork,sKey1,sKey2 : string;
    oKeys,oSubKeys : TStringList;
    oReg : TRegistry;
    i,ii : integer;
    bFound : boolean;
begin
  ADevType := '';
  ADriverDesc := '';
  AFriendlyName := '';

  if ADeviceString <> '' then begin
    bFound := false;
    oReg := TRegistry.Create;
    oReg.RootKey := HKEY_LOCAL_MACHINE;

    // Extract the portions of the string we need for registry. eg.
    // \\?\USB#Vid_4146&Pid_d2b5#0005050400044#{a5dcbf10- ..... -54334fb951ed}
    // We need sKey1='Vid_4146&Pid_d2b5' and sKey2='0005050400044'
    sWork := copy(ADeviceString,pos('#',ADeviceString) + 1,1026);
    sKey1 := copy(sWork,1,pos('#',sWork) - 1);
    sWork := copy(sWork,pos('#',sWork) + 1,1026);
    sKey2 := copy(sWork,1,pos('#',sWork) - 1);

    // Get the Device type description from \USB key
    if oReg.OpenKeyReadOnly(Format(USBKEY,[skey1,sKey2])) then begin
      ADevType := oReg.ReadString('DeviceDesc');
      oReg.CloseKey;
      oKeys := TStringList.Create;
      oSubKeys := TStringList.Create;

      // Get list of keys in \USBSTOR and enumerate each key
      // for a key that matches our sKey2='0005050400044'
      // NOTE : The entry we are looking for normally has '&0'
      // appended to it eg. '0005050400044&0'
      if oReg.OpenKeyReadOnly(USBSTORKEY) then begin
        oReg.GetKeyNames(oKeys);
        oReg.CloseKey;

        // Iterate through list to find our sKey2
        for i := 0 to oKeys.Count - 1 do begin
          if oReg.OpenKeyReadOnly(Format(SUBKEY1,[oKeys[i]])) then begin
            oReg.GetKeyNames(oSubKeys);
            oReg.CloseKey;

            for ii := 0 to oSubKeys.Count - 1 do begin
              if MatchesMask(oSubKeys[ii],sKey2 + '*') then begin
                // Got a match?, get the actual desc and friendly name
                if oReg.OpenKeyReadOnly(Format(SUBKEY2,[oKeys[i],
                                        oSubKeys[ii]])) then begin
                  ADriverDesc := oReg.ReadString('DeviceDesc');
                  AFriendlyName := oReg.ReadString('FriendlyName');
                  oReg.CloseKey;
                end;

                bFound := true;
              end;
            end;
          end;

          if bFound then break;
        end;
      end;

      FreeAndNil(oKeys);
      FreeAndNil(oSubKeys);
    end;

    FreeAndNil(oReg);
  end;
end;


procedure TUsbClass.WMDeviceChange(var AMessage : TMessage);
var iDevType : integer;
    sDevString,sDevType,
    sDriverName,sFriendlyName : string;
    pData : PDevBroadcastDeviceInterface;
begin
  if (AMessage.wParam = USB_INSERTION) or
     (AMessage.wParam = USB_REMOVAL) then begin
    pData := PDevBroadcastDeviceInterface(AMessage.LParam);
    iDevType := pData^.dbcc_devicetype;

    // Is it a USB Interface Device ?
    if iDevType = USB_INTERFACE then begin
      sDevString := PChar(@pData^.dbcc_name);
      GetUsbInfo(sDevString,sDevType,sDriverName,sFriendlyName);

      // Trigger Events if assigned
      if (AMessage.wParam = USB_INSERTION) and
        Assigned(FOnUsbInsertion) then
          FOnUsbInsertion(self,sDevType,sDriverName,sFriendlyName);
      if (AMessage.wParam = USB_REMOVAL) and
        Assigned(FOnUsbRemoval) then
          FOnUsbRemoval(self,sDevType,sDriverName,sFriendlyName);
    end;
  end;
end;



procedure TUsbClass.WinMethod(var AMessage : TMessage);
begin
  if (AMessage.Msg = WM_DEVICECHANGE) then
    WMDeviceChange(AMessage)
  else
    AMessage.Result := DefWindowProc(FHandle,AMessage.Msg,
                                     AMessage.wParam,AMessage.lParam);
end;


procedure TUsbClass.RegisterUsbHandler;
var rDbi : DEV_BROADCAST_DEVICEINTERFACE;
    iSize : integer;
begin
  iSize := SizeOf(DEV_BROADCAST_DEVICEINTERFACE);
  ZeroMemory(@rDbi,iSize);
  rDbi.dbcc_size := iSize;
  rDbi.dbcc_devicetype := USB_INTERFACE;
  rDbi.dbcc_reserved := 0;
  rDbi.dbcc_classguid  := GUID_DEVINTF_USB_DEVICE;
  rDbi.dbcc_name := #0;
  RegisterDeviceNotification(FHandle,@rDbi,DEVICE_NOTIFY_WINDOW_HANDLE);
end;


end.