1

我有一个代表 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 或谷歌也不是真正的帮助。我确信它在实例化但未显示时会正常运行。

PS。我添加了

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;
    }

}
4

4 回答 4

5

这个问题的文档记录很差,但这对于适用于设备的代码来说是相当正常的。他们往往需要了解即插即用事件,这需要创建一个接收 WM_DEVICECHANGE 通知消息的顶级窗口。创建一个 .NET Form 对象是不够的,您还必须为其创建本机窗口。在典型的 .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()。

于 2013-06-19T18:24:35.887 回答
1

我怀疑这是因为在调用 Show() 之前没有创建底层窗口。由于未创建窗口,因此不会调用您的自定义 WndProc。

要验证,您可以创建窗口而不显示它 - 通过查看Handle属性。正如文档所说 - 如果在您调用时尚未创建句柄,它将被创建。试试看,我敢打赌它会像你打电话Show然后Hide.

于 2013-06-19T18:20:50.790 回答
1

从您拥有的信息中很难分辨,但我认为您使用的表单应该使用类。您应该重新考虑您的程序结构并将其重新编写为一个类以根据需要保存和传输数据。正如其他一些人指出的那样,在显示表单并执行方法之前,列表框和/或其他功能不会运行。

于 2013-06-19T18:25:18.023 回答
0

因为在调用 Form onShow 事件时会调用一些必需的函数。

于 2013-06-19T18:19:30.287 回答