我的Delphi应用程序(使用XE3)需要处理删除USB串行端口时发生的EInOutError异常.应用程序在测试环境中使用,因此不能依赖运算符单击“确定”按钮来关闭“应用程序错误”对话框.
我尝试过以下方法:
>“try .. except”方法 – 这不会捕获这些异常.我认为这不起作用,因为异常不是由“try”块中的代码引起的.它似乎是一个较低级别的“系统级”例外.
>我尝试在表单中添加“ApplicationEvents”组件. OnException方法捕获由我的应用程序生成的“自定义”异常,但不捕获系统级异常.
>我还尝试添加一个全局异常挂钩(如Is it possible to have a global exception hook?中所述).这部分工作 – 它允许我在“应用程序错误”对话框之前执行操作,但不会停止错误对话框.
我很感激任何想法!
解决方法
USB-Com移除引起的异常非常烦人.所以我建议消除它们的大部分原因.
您必须处理Windows消息WM_DEVICECHANGE并检测端口删除.然后设置特殊标志,不要对带有此标志的端口进行任何操作!如果再次插入USB-Com,则重新启动串口.一些代码可以帮助:
const DBT_DEVICEARRIVAL = $8000; DBT_DEVICEREMOVECOMPLETE = $8004; DBT_DEVICEQUERYREMOVE = $8001; DBT_DEVTYP_PORT = 3; type PDevBroadcastHdr = ^TDevBroadcastHdr; TDevBroadcastHdr = packed record dbcd_size: DWORD; dbcd_devicetype: DWORD; dbcd_reserved: DWORD; end; PDEV_BROADCAST_PORT = ^TDEV_BROADCAST_PORT; TDEV_BROADCAST_PORT = packed record dbcp_size: DWord; dbcp_devicetype: DWord; dbcp_reserved: DWord; dbcp_name: array[0..MAX_PATH] of Char; end; ... procedure WMDEVICECHANGE(var Msg: TMessage); message WM_DEVICECHANGE; ... procedure TForm1.WMDEVICECHANGE(var Msg: TMessage); var prt: PDEV_BROADCAST_PORT; s: string; begin if Msg.wparam = DBT_DEVICEREMOVECOMPLETE then if PDevBroadcastHdr(Msg.lParam)^.dbcd_devicetype = DBT_DEVTYP_PORT then begin b_PortRemoved := True; //check this flag before each operation with port. prt := PDEV_BROADCAST_PORT(PDEV_BROADCAST_PORT(Msg.lParam)); s := prt.dbcp_name; ShowMessage('ComPort ' + s + ' has been removed. What can I do?'); end; if Msg.wparam = DBT_DEVICEARRIVAL then if PDevBroadcastHdr(Msg.lParam)^.dbcd_devicetype = DBT_DEVTYP_PORT then begin // USB-COM plugged,you can find it and make some reinitialisation end; end;