我有一个表示 USB 设备终端的表单,它一直给我一些错误。在调试了半天没有已知来源的奇怪错误后,我以某种方式发现终端在实例化但未显示时不起作用。当我更改代码并添加 usbTerminal.Show(); 时,它会正常工作。
USBTerminal usbTouchTerminal;
public MainForm()
{
InitializeComponent();
USBSettings usbTouchSettings = new USBSettings();
usbTouchTerminal = new USBTerminal(usbTouchSettings); //Create Terminal with settings
usbTouchTerminal.StartUSB();
usbTouchTerminal.Show(); //works ONLY when show is here
}
这怎么可能,为什么?我进行了大量搜索,但我的代码都不依赖于终端或主窗体上的 .Visible 属性?
我完全不明白为什么有些表格如果不显示就不能工作。 MSDN 或谷歌也不是真正的帮助。我确信它在实例化但未显示时会正常运行。
附言。我加了
usbTerminal.Show();
usbTerminal.Hide();
并且终端运行正常。
感谢您的帮助!
编辑:
我还应注意,此 usbTerminal 使用 WndProc 覆盖。我不是这方面的专家,但我觉得这可能与此有关。
我应该注意到这是 LibUSBdotnet
public class USBSettings
{
/// <summary>
/// This is the Vender ID Number. (0x0B6A)
/// </summary>
public ushort VID { get; set; }
/// <summary>
/// This is the Product ID Number. (0x5346)
/// </summary>
public ushort PID { get; set; }
/// <summary>
/// This is the optional Serial Name. ("")
/// </summary>
public string SerialName { get; set; }
/// <summary>
/// This is the Reader USB Endpoint. (ReadEndpointID.Ep02)
/// </summary>
public ReadEndpointID ReaderEndpoint { get; set; }
/// <summary>
/// This is the Writer USB Endpoint. (WriteEndpointID.Ep01)
/// </summary>
public WriteEndpointID WriterEndpoint { get; set; }
/// <summary>
/// This is the Registry Key for USB settings. ("SOFTWARE\\DEFAULT\\USBPROPERTIES")
/// </summary>
public string SubKey { get; set; }
/// <summary>
/// This is the default read buffer size for the USB Device.
/// </summary>
public int ReadBufferSize { get; set; }
/// <summary>
/// This constructor houses default values for all properties.
/// </summary>
public USBSettings()
{
VID = 0x0B6A;
PID = 0x5346;
SerialName = "";
ReaderEndpoint = ReadEndpointID.Ep02;
WriterEndpoint = WriteEndpointID.Ep01;
SubKey = "SOFTWARE\\DEFAULT\\USBPROPERTIES";
ReadBufferSize = 100;
}
}
最佳答案
这个问题没有很好的记录,但这对于与设备一起工作的代码来说是相当正常的。他们往往需要了解即插即用事件,这需要创建一个顶层窗口来接收 WM_DEVICECHANGE 通知消息。创建一个 .NET Form 对象是不够的,您还必须为其创建 native 窗口。以典型的 .NET 惰性方式,它发生在最后可能的时刻,当您强制窗口可见时。通过调用 Show() 方法或将 Visible 属性设置为 true。获取即插即用通知的窗口实际上不必可见。
您可以创建窗口而不使其可见。这需要修改 USBTerminal 类。粘贴此代码:
protected override void SetVisibleCore(bool value) {
if (!this.IsHandleCreated) {
this.CreateHandle();
value = false;
}
base.SetVisibleCore(value);
}
然后正常调用 Show() 方法。请注意,在窗口实际变为可见之前,Load 事件不会触发,因此如有必要,请将事件处理程序中的任何代码移至此方法。如果这不是应用程序的主窗口,换句话说不是在您的 Main() 方法中传递给 Application.Run() 的窗口,那么您只需调用 this.CreateHandle() 作为表单构造函数。在这种情况下,不再需要调用 Show()。
关于c# - 除非调用 .Show(),否则表单不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17198386/