编译出现这个错误

时间:2022-11-01 14:50:46
Error in module Unit1:Declaration of class TForm1 is missing or incorrect.

完整代码如下,用Delphi通过SetupAPI.dll列举和停用硬件设备:(代码是网上提供的,本人新手,不懂语法,请大虾们帮我修改编译通过。)
unit SetupAPI;

interface

uses
   Windows;

const
   DIGCF_PRESENT = $0002;
   DIGCF_ALLCLASSES = $0004;
   SPDRP_DEVICEDESC = 0;

   DIF_PROPERTYCHANGE = 18;

   DICS_ENABLE = 1;
   DICS_FLAG_GLOBAL = 1;
   DICS_DISABLE = 2;

type
   HDEVINFO = type Cardinal;
   DI_FUNCTION = type Cardinal;
  
   PSP_DEVINFO_DATA = ^SP_DEVINFO_DATA;
   SP_DEVINFO_DATA = record
     cbSize: DWORD;
     ClassGuid: TGUID;
     DevInst: DWORD;
     Reserved: Longint;
   end;

   PSP_CLASSINSTALL_HEADER = ^SP_CLASSINSTALL_HEADER;
   SP_CLASSINSTALL_HEADER = record
     cbSize: DWORD;
     InstallFunction: DI_FUNCTION; { (DIF code) }
   end;

   PSP_PROPCHANGE_PARAMS = ^SP_PROPCHANGE_PARAMS;
   SP_PROPCHANGE_PARAMS = record
     ClassInstallHeader: SP_CLASSINSTALL_HEADER;
     StateChange: DWORD;
     Scope: DWORD;
     HwProfile: DWORD;
   end;

   PSP_CLASSIMAGELIST_DATA = ^SP_CLASSIMAGELIST_DATA;
   SP_CLASSIMAGELIST_DATA = record
     cbSize: DWORD;
     ImageList: HWND;
     Reserved: DWORD;
   end;

function SetupDiGetClassDevs(const ClassGuid: PGUID; Enumerator: PChar;
   hwndParent: HWND; Flags: DWORD): HDEVINFO; stdcall;
   external 'Setupapi.dll' name 'SetupDiGetClassDevsA';

function SetupDiEnumDeviceInfo(DeviceInfoSet: HDEVINFO; MemberIndex: DWORD;
   DeviceInfoData: PSP_DEVINFO_DATA): BOOL; stdcall;
   external 'Setupapi.dll' name 'SetupDiEnumDeviceInfo';

function SetupDiGetDeviceRegistryProperty(DeviceInfoSet: HDEVINFO;
   DeviceInfoData: PSP_DEVINFO_DATA; Propertys: DWORD; PropertyRegDataType: PWORD;
   PropertyBuffer: PByte; PropertyBufferSize: DWORD; RequiredSize: PWORD): BOOL; stdcall;
   external 'Setupapi.dll' name 'SetupDiGetDeviceRegistryPropertyA';

function SetupDiDestroyDeviceInfoList(DeviceInfoSet: HDEVINFO): BOOL; stdcall;
   external 'Setupapi.dll' name 'SetupDiDestroyDeviceInfoList';

function SetupDiClassNameFromGuid(ClassGuid: PGUID; ClassName: PChar;
   ClassNameSize: DWORD; RequiredSize: PDWORD): BOOL; stdcall;
   external 'Setupapi.dll' name 'SetupDiClassNameFromGuidA';

function SetupDiSetClassInstallParams(DeviceInfoSet: HDEVINFO ;
   DeviceInfoData: PSP_DEVINFO_DATA; ClassInstallParams: PSP_CLASSINSTALL_HEADER;
   ClassInstallParamsSize: DWORD): BOOL stdcall;
   external 'Setupapi.dll' name 'SetupDiSetClassInstallParamsA';

function SetupDiCallClassInstaller(InstallFunction: DI_FUNCTION;
   DeviceInfoSet: HDEVINFO; DeviceInfoData: PSP_DEVINFO_DATA): BOOL; stdcall;
   external 'Setupapi.dll' name 'SetupDiCallClassInstaller';

function SetupDiGetClassImageList(ClassImageListData: PSP_CLASSIMAGELIST_DATA): BOOL;
   stdcall; external 'Setupapi.dll' name 'SetupDiGetClassImageList';

function SetupDiDestroyClassImageList(ClassImageListData: PSP_CLASSIMAGELIST_DATA):
   BOOL; stdcall; external 'Setupapi.dll' name 'SetupDiDestroyClassImageList';

function SetupDiGetClassImageIndex(ClassImageListData: PSP_CLASSIMAGELIST_DATA;
   ClassGuid: PGUID; ImageIndex: PINT): BOOL; stdcall;
   external 'Setupapi.dll' name 'SetupDiGetClassImageIndex';

implementation

end.

{ untMain.pas主窗体单元,Uses部分引用上面的pas,
再加1个BUTTON;1个TListView;1个TImageList,定义看代码 }

unit untMain;

interface

uses
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
   Dialogs, SetupAPI, StdCtrls, ComCtrls, ImgList;

type
   TForm1 = class(TForm)
     lv1: TListView;
     btn1: TButton;
     il1: TImageList;
     procedure btn1Click(Sender: TObject);
   private
     function GetDeviceClassName(aGUID: TGUID): string;
     { Private declarations }
   public
     { Public declarations }
   end;

var
   Form1: TForm1;
   ClassImageListData: SP_CLASSIMAGELIST_DATA; {设备类型图标结构,全局变量,退出时释放.}

implementation

{$R *.dfm}

procedure TForm1.btn1Click(Sender: TObject);
var
   hDevInfo: Cardinal;
   DeviceInfoData: SP_DEVINFO_DATA; {设备信息结构}
   i: Integer;
   DataT, Buffersize: DWORD;
   Buffer: PAnsiChar;
   List: TListItem;
   index: Integer;
begin
   { 获取设备信息句柄 }
   lv1.Items.BeginUpdate;
   DriverInfoData.cbSize := SizeOf(SP_DRVINFO_DATA_A);
   hDevInfo := SetupDiGetClassDevs(nil, 0, 0,
     DIGCF_PRESENT or DIGCF_ALLCLASSES);
   if hDevInfo = INVALID_HANDLE_VALUE then Exit;
   { 设备图标数据结构 }
   ClassImageListData.cbSize := SizeOf(SP_CLASSIMAGELIST_DATA);
   { 获取设备图标数据 }
   if SetupDiGetClassImageList(@ClassImageListData) then
   begin
     { 赋句柄给ImageList }
     il1.Handle := ClassImageListData.ImageList;
     { TreeView图标指定到ImageList }
     lv1.SmallImages := il1;
   end;
    
   i := 0;
   Buffersize := 256;
   DeviceInfoData.cbSize := SizeOf(SP_DEVINFO_DATA);
   GetMem(Buffer, Buffersize);
   { 枚举设备信息 }
   while SetupDiEnumDeviceInfo(hDevInfo, i, @DeviceInfoData) do
   begin

     { 获取设备信息包括GUID和名称 }
    SetupDiGetDeviceRegistryProperty(hDevInfo, @DeviceInfoData,
       SPDRP_DEVICEDESC, @DataT, PByte(Buffer), Buffersize, nil);
     Inc(i);
     List := lv1.Items.Add;
     { 获取制定GUID(设备类型)的图标索引 }
     if SetupDiGetClassImageIndex(@ClassImageListData,
       @DeviceInfoData.ClassGuid, @index) then
       { 制定显示图标 }
       List.ImageIndex := index;
     { 通过GUID获取设备类型(Class) }
     List.Caption := GetDeviceClassName(DeviceInfoData.ClassGuid);
     { 转换GUID到字符串 }
     List.SubItems.Add(GUIDToString(DeviceInfoData.ClassGuid));
     { 显示设备名称 }
     List.SubItems.Add(Buffer);
     { 设备状态 }
     if IsDisableable(i ,hDevInfo) then
       List.SubItems.Add('True')
     else
       List.SubItems.Add('False');
    
   end;
   if Buffer <> nil then FreeMem(Buffer);
   if (GetLastError() <> NO_ERROR) and
     (GetLastError() <> ERROR_NO_MORE_ITEMS) then
     Exit;
   { 释放 DeviceInfoData, hDevInfo }
   SetupDiDestroyDeviceInfoList(hDevInfo);
   lv1.Items.EndUpdate;
end;

{最后在退出程序时释放 SetupDiDestroyClassImageList(@ClassImageListData); }


{ 获取设备类型 }
function TForm1.GetDeviceClassName(aGUID: TGUID): string;
var
   ClassName: PChar;
   ClassNameSize: DWORD;
begin
   ClassNameSize := 0;
   GetMem(ClassName, ClassNameSize);
   { 利用GUID返回设备类型名 }
   while not SetupDiClassNameFromGuid(@aGUID, ClassName, ClassNameSize,
     @ClassNameSize) do
   begin
     if GetLastError() = ERROR_INSUFFICIENT_BUFFER then
     begin
       if ClassName <> nil then FreeMem(ClassName);
       GetMem(ClassName, ClassNameSize);
     end else
       Break;
   end;
   Result := ClassName;
   if ClassName <> nil then FreeMem(ClassName);
end;

end.



{设备禁用的代码,是从网上改些一个C++代码的,还没来得及加注解,先看着,以后加.}

function ChangeDeviceState(hDevInfo: HDEVINFO; NewStatus: DWORD;
   SelectedItem: DWORD): Boolean;
var
   PropChangeParams: SP_PROPCHANGE_PARAMS;
   DeviceInfoData: SP_DEVINFO_DATA;
begin
   Result := False;

   DeviceInfoData.cbSize := SizeOf(SP_DEVINFO_DATA);
   if not SetupDiEnumDeviceInfo(hDevInfo, SelectedItem, @DeviceInfoData) then Exit;

   // Set the PropChangeParams structure.
   PropChangeParams.ClassInstallHeader.cbSize := SizeOf(SP_CLASSINSTALL_HEADER);
   PropChangeParams.ClassInstallHeader.InstallFunction := DIF_PROPERTYCHANGE;
   PropChangeParams.Scope := DICS_FLAG_GLOBAL;
   PropChangeParams.StateChange := NewStatus;

   if not SetupDiSetClassInstallParams(hDevInfo, @DeviceInfoData,
     PSP_CLASSINSTALL_HEADER(@PropChangeParams), SizeOf(PropChangeParams)) then
     Exit;

   // Call the ClassInstaller and perform the change.
   if not SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, hDevInfo,
     @DeviceInfoData) then
     Exit;

   Result := True;
end;

function ControlDisk(nStatus, nIndex: Integer): Boolean;
var
   Guid: TGUID ;
   GUIDString: string;
   hDevInfo: Cardinal;
   i: DWORD;
   DeviceInfoData: SP_DEVINFO_DATA;
begin
   Result := False;
   if (nStatus = -1) then Exit;

   ZeroMemory(@Guid, sizeof(TGUID));
   case nIndex of
     0: // 0 代表软驱
       GUIDString := '{4D36E980-E325-11CE-BFC1-08002BE10318}';
     1: // 1 代表光驱
       GUIDString := '{4D36E965-E325-11CE-BFC1-08002BE10318}';
     2: // 2 代表USB
       GUIDString := '{36FC9E60-C465-11CF-8056-444553540000}';
   end;
   Guid := StringToGUID(GUIDString);

   hDevInfo := SetupDiGetClassDevs(@Guid, nil, HWND(nil), DIGCF_PRESENT);
   if (hDevInfo = INVALID_HANDLE_VALUE) then Exit;

   ZeroMemory(@DeviceInfoData, SizeOf(SP_DEVINFO_DATA));
   DeviceInfoData.cbSize := SizeOf(SP_DEVINFO_DATA);

   i := 0;
   while SetupDiEnumDeviceInfo(hDevInfo, i, @DeviceInfoData) do
   begin
     if nStatus   = 1 then
       Result := ChangeDeviceState(hDevInfo, DICS_ENABLE, i)
     else if nStatus = 2 then
       Result := ChangeDeviceState(hDevInfo, DICS_DISABLE, i);
     Inc(i);
   end;

   SetupDiDestroyDeviceInfoList(hDevInfo);
end;


{ 调用如下: 禁用光驱: if ControlDisk(DICS_DISABLE, 1) then ShowMessage('成功禁用!'); }

{ 启用光驱: if ControlDisk(DICS_ENABLE, 1) then ShowMessage('启用成功!'); }

{ 注意USB要调用2次 ControlDisk(DICS_ENABLE, 2)才能完成启用. }

11 个解决方案

#1


这都什么跟什么啊

#2


你直接Copy过来的,一个个建立就行了

#3


建立什么?把2个UNIT建立在2个PAS文件里吗?麻烦说得详细点,我新手,谢谢。

#4


新建一个工程,再新建一个unit,把setupapi拷贝过去,保存为setupapi,然后拖几个一样的控件到窗体上,并命相同的名,然后就可以把from1上的代码拷贝过来了

#5


我在保存setupapi的时候还是弹出上面那个出错信息:Error in module Unit1:Declaration of class TForm1 is missing or incorrect.

#6


拷贝过来的代码很容易出错啊!

#7


你是不是没有建立Form?用的不是Console Application吧?

#8


是不是缺少 DFM(窗体)文件

#9


dll文件,你做几个接口,在外边调用就好了!

#10


谢谢回复的朋友。我新建了一个Console Application,又新建了2个unit,分别是SetupAPI.pas和untMain.pas,我把这两个加到项目里,在Project1.dpr里写入以下内容:uses SetupAPI in 'SetupAPI.pas',untMain in 'untMain.pas';然后编译,提示一个错误:IsDisableable Undeclared Identifier.IsDisableable是untMain.pas里调用的一个API,调用如下:
if IsDisableable(i ,hDevInfo) then
       List.SubItems.Add('True')
     else
       List.SubItems.Add('False');
我搜了MSDN也没找到这个API,不解。

#11


那是判断设备状态的函数,如果对你没用的话,可以注释掉
Console Application的话你自己要创建可视控件,
另外,你可以参考
http://www.delphibbs.com/delphibbs/dispq.asp?lid=3334771

#1


这都什么跟什么啊

#2


你直接Copy过来的,一个个建立就行了

#3


建立什么?把2个UNIT建立在2个PAS文件里吗?麻烦说得详细点,我新手,谢谢。

#4


新建一个工程,再新建一个unit,把setupapi拷贝过去,保存为setupapi,然后拖几个一样的控件到窗体上,并命相同的名,然后就可以把from1上的代码拷贝过来了

#5


我在保存setupapi的时候还是弹出上面那个出错信息:Error in module Unit1:Declaration of class TForm1 is missing or incorrect.

#6


拷贝过来的代码很容易出错啊!

#7


你是不是没有建立Form?用的不是Console Application吧?

#8


是不是缺少 DFM(窗体)文件

#9


dll文件,你做几个接口,在外边调用就好了!

#10


谢谢回复的朋友。我新建了一个Console Application,又新建了2个unit,分别是SetupAPI.pas和untMain.pas,我把这两个加到项目里,在Project1.dpr里写入以下内容:uses SetupAPI in 'SetupAPI.pas',untMain in 'untMain.pas';然后编译,提示一个错误:IsDisableable Undeclared Identifier.IsDisableable是untMain.pas里调用的一个API,调用如下:
if IsDisableable(i ,hDevInfo) then
       List.SubItems.Add('True')
     else
       List.SubItems.Add('False');
我搜了MSDN也没找到这个API,不解。

#11


那是判断设备状态的函数,如果对你没用的话,可以注释掉
Console Application的话你自己要创建可视控件,
另外,你可以参考
http://www.delphibbs.com/delphibbs/dispq.asp?lid=3334771