gpt4 book ai didi

delphi - WMDeviceChange函数调用其他函数/过程时的Delphi Pascal问题

转载 作者:行者123 更新时间:2023-12-03 18:29:48 35 4
gpt4 key购买 nike

解决了

我正在使用delphi2009。我的程序侦听已连接并卸下的USB驱动器。在过去的一年中,Ive在10个应用程序中使用了非常相似的代码。它一直都运行良好。当我迁移时,我不得不放弃使用thddinfo来获取驱动器模型。已使用WMI代替。 WMI查询需要物理磁盘号,而我恰好在应用程序中已经具有执行此操作的功能。

当我测试时,我将其放在一个按钮中并运行它,它成功确定了psp是物理驱动器4并返回了模型(全部在调试器中检查,并在另一个示例中使用show message):

function IsPSP(Drive: String):Boolean;
var
Model: String;
DriveNum: Byte;
begin
Result := False;
Delete(Drive, 2, MaxInt);
DriveNum := GetPhysicalDiskNumber(Drive[1]);
Model := (MagWmiGetDiskModel(DriveNum));
if Pos('PSP',Model) > 0 then Result := True;
end;

procedure TfrmMain.Button1Click(Sender: TObject);
var DriveNum: Byte;
begin
IsPSP('I');
end;


直到我允许我已经使用了一年的WMDeviceChange调用getphysicaldisknumber和wmi查询语句,它才可以正常工作。我自己尝试过它们,它们都是问题。当GetPhysicalDiskNumber在逻辑磁盘上执行CloseHandle时,冻结会很糟糕,但最终会返回该数字。 WMI查询失败,没有错误,只是将''调试器点返回到从未发生过连接的wbemscripting_tlb中。请记住,一年中唯一发生的变化是即时通讯正在调用以获取我以前使用api调用的模型,而现在即时通讯正在使用其他内容。

下面是此时所涉及的其余代码,没有上面显示的ispsp:

procedure TfrmMain.WMDeviceChange(var Msg: TMessage);
var Drive: String;
begin
case Msg.wParam of
DBT_DeviceArrival: if PDevBroadcastHdr(Msg.lParam)^.dbcd_devicetype = DBT_DevTyp_Volume then
begin
Drive := GetDrive(PDevBroadcastVolume(Msg.lParam)) + '\';
OnDeviceInsert(Drive);
end;
DBT_DeviceRemoveComplete: if PDevBroadcastHdr(Msg.lParam)^.dbcd_devicetype = DBT_DevTyp_Volume then
begin
Drive := GetDrive(PDevBroadcastVolume(Msg.lParam)) + '\';
OnDeviceRemove(Drive);
end;
end;
end;

Procedure TfrmMain.OnDeviceInsert(Drive: String);
var PreviousIndex: Integer;
begin
if (getdrivetype(Pchar(Drive))=DRIVE_REMOVABLE) then
begin
PreviousIndex := cbxDriveList.Items.IndexOf(cbxDriveList.Text);
cbxDriveList.Items.Append(Drive);
if PreviousIndex = -1 then //If there was no drive to begin with then set index to 0
begin
PreviousIndex := 0;
cbxDriveList.ItemIndex := 0;
end;
if isPSP(Drive) then
begin
if MessageDlg('A PSP was detect @ ' + Drive + #10#13 + 'Would you like to select this drive?',mtWarning,[mbYes,mbNo], 0) = mrYes then
cbxDriveList.ItemIndex := cbxDriveList.Items.IndexOf(Drive)
else cbxDriveList.ItemIndex := PreviousIndex;
end
else if MessageDlg('USB Drive ' + Drive + ' Detected' + #10#13 + 'Is this your target drive?',mtWarning,[mbYes,mbNo], 0) = mrYes then
cbxDriveList.ItemIndex := cbxDriveList.Items.IndexOf(Drive)
else cbxDriveList.ItemIndex := PreviousIndex;
end;
end;

Procedure TfrmMain.OnDeviceRemove(Drive: String);
begin
if not (getdrivetype(Pchar(Drive)) = DRIVE_CDROM) then
begin
if cbxDriveList.Text = (Drive) then ShowMessage('The selected drive (' + Drive + ') has been removed');
cbxDriveList.Items.Delete(cbxDriveList.Items.IndexOf(Drive));
if cbxDriveList.Text = '' then cbxDriveList.ItemIndex := 0;
if Drive = PSPDrive then //Check Detect PSP and remove reference if its been removed
begin
PSPDrive := '';
end;
end;
end;


Rob在下面说了一些有关im不调用继承的消息处理程序的信息,在阅读文档时我看到了我可以返回的几件事...但是我不确定我是否可以理解,但我会仔细研究。我不是一个很好的Pascal程序员,但我一直在学习很多东西。过渡到2009年也遇到了一些困难。

USB驱动器检测以及所有功能都可以完美运行。如果我从psp中删除了两件事,则立即向用户打招呼,然后将I:\添加到列表中。它只是应用程序中已更改的两个新事物,它们在被wmdevicechange调用时失败,并且如前所述那样独立运行。

编辑-解决

好吧,即时消息按建议使用计时器,问题似乎已解决。需要注意的一点是,在wmd​​evicechange更改之后不久由计时器调用时,获取物理磁盘号似乎仍然很慢。我将此归因于仍连接到系统的设备。

关于这一点,我在常规上使用P2 450。我将PSP和应用程序挂接到1.8Ghz双核笔记本电脑上,程序检测到psp并很快通知了用户。因此,除非在非常慢的计算机上运行,​​并且在这种缓慢的运行中,它仅停留几秒钟,并且不会影响程序的运行,但它并不是很酷,否则该应用程序不会冻结。但是我觉得所有现代计算机都将快速运行检测,特别是因为它们可以更快地连接设备。

最佳答案

您查询的信息可能只有在WMDeviceChange消息处理程序运行后才可用。如果从按钮调用时使用相同的代码,请尝试以下操作:


将WMDeviceChange处理程序代码重构为一个或多个单独的方法。
在WMDeviceChange处理程序中,激活一个预先创建的计时器,并使其在一秒钟后触发,或类似的操作。
从计时器处理程序代码中调用以前的WMDeviceChange处理程序代码。

关于delphi - WMDeviceChange函数调用其他函数/过程时的Delphi Pascal问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/646023/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com