NotifyIcon 事件未触发

发布于 2024-08-08 01:56:30 字数 591 浏览 2 评论 0原文

我是新来的,有一个非常神秘的问题要开始。我是英国的一名软件开发人员,拥有超过 15 年的经验,但在 .Net 中开发的时间只有 18 个月。我的 NotifyIcon 鼠标事件没有触发!

我正在使用 C# 编写一个应用程序,该应用程序作为 NotifyIcon(“主应用程序图标”)启动,并在鼠标右键单击时显示 ContextMenu。这工作正常:ContextMenu、表单启动和鼠标单击事件触发。

一点背景知识:应用程序应该检测 USB“设备”的插入(确实如此),询问它并创建另一个 NotifyIcon(“设备图标”)以允许用户与该设备交互。我在上一段中提到的“主应用程序图标”允许用户与数据库交互并配置软件。

为了封装这些设备交互功能,我构建了一个“设备类” 包含允许与设备交互的设备NotifyIcon、ContextMenu、表单、鼠标单击事件等。

问题 当我从 ManagementEventWatcher EventArrived 事件实例化“设备类”时,问题就开始了。如果我在程序 Main 中实例化“设备类”,那么当我单击通知图标时,事件会正确触发。

那么,请问有人可以帮助我吗?

干杯,提前

马修

I'm new here and have a really mysterious problem to start off. I'm a software developer in the UK and have over 15 years of experience but have only been developing in .Net for 18 months. My NotifyIcon mouse events are not firing!

I am using C# to write an application that starts as a NotifyIcon ('main app icon') and displays a ContextMenu on mouse right-click. This works fine: ContextMenu, forms launching and mouse click events firing.

A tiny bit of background: the application is supposed to sense the insertion of a usb 'device' (it does), interrogate it and create another NotifyIcon ('device icon') to allow the user to interact with that device. The 'main app icon', mentioned in my previous paragraph, allows the user to interact with the database and to configure the software.

To encapsulate these device interaction functions, I have constructed a 'device class' that
contains the device NotifyIcon, ContextMenu, forms, mouse click events etc which allow interaction with the device.

The Problem
The problem starts when I instantiate my 'device class' from the ManagementEventWatcher EventArrived event. If I instantiate the 'device class' in my program Main then the events fire correctly when I click the notifyicon.

So, please, can someone help me?

Cheers, in advance

Matthew

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

江湖正好 2024-08-15 01:56:30

IIRC,事件使用(而不是WaitForNextEvent)异步工作。我有兴趣知道该事件是在哪个线程上引发的。我想知道是否没有消息泵为您的图标提供服务消息。

你有表格吗?或者还有其他带有消息循环的东西?我很想调用表单(使用Control.Invoke),并要求表单显示图标 - 从那时起它应该有一个活动的消息泵。


抱歉耽搁了;阅读您的评论,听起来您已经大致找到了解决方法。唯一的问题是跨线程问题;理想情况下,您会要求 UI 在 UI 线程上进行此类更改;例如,如果您有一个 Form 正在运行(拥有图标) - 添加到您的表单类:

// not a property, as there is no need to add a complex x-thread "get"
public void SetIconVisible(bool isVisible) {
    if(this.InvokeRequired) {
        this.Invoke((MethodInvoker) delegate {
            myIcon.Visible = isVisible;
        });
    } else {
        myIcon.Visible = isVisible;
    }
}

这会对 UI 线程进行线程切换(如果需要)。有什么用吗?

IIRC, the event usage (rather than WaitForNextEvent) works async. I would be interested to know what thread the event is being raised on. I wonder if there is no message pump servicing messages for your icon.

Do you have a form anywhere? Or something else with a message loop? I would be tempted to call into the form (using Control.Invoke), and ask the form to show the icon - since then it should have an active message pump.


Sorry for the delay; reading your comments, it sounds like you've broadly got a workaround. The only gotcha is cross-threaded issues; ideally, you would ask the UI to make such a change on the UI thread; for example, if you have a Form kicking around (owning the icon) - add to your form class:

// not a property, as there is no need to add a complex x-thread "get"
public void SetIconVisible(bool isVisible) {
    if(this.InvokeRequired) {
        this.Invoke((MethodInvoker) delegate {
            myIcon.Visible = isVisible;
        });
    } else {
        myIcon.Visible = isVisible;
    }
}

This does a thread-switch (if needed) to the UI thread. Any use?

您的好友蓝忘机已上羡 2024-08-15 01:56:30

所以答案是:

只有在主线程中使 NotifyIcon 可见时,事件才会起作用。所以 Marc Gravell 给出的代码就是解决方案。

So the answer is:

The events will only work if when you make the NotifyIcon visible, you do it in the main thread. So the code given by Marc Gravell is the solution.

死开点丶别碍眼 2024-08-15 01:56:30

马克,只是为了让您知道 -

我发现我可以创建将 NotifyIcon 作为主线程成员的类实例,然后在连接 USB 设备时使 NotifyIcon 可见。

但它需要一些调整,因为 NotifyIcon 是在第一次可见时创建的,所以我必须确保(在主线程中)我将每个 Visible 设置为 true,然后设置为 false - 从而需要限制实例数。

当设备连接时,ManagementEventWatcher 线程可以将 Visible 属性设置为 true。

一个解决方法。

(查看对您评论的回复)

Mark, just to let you know -

I worked out that I could create the class instances that have the NotifyIcon as members in the main thread and then make the NotifyIcon(s) visible when the USB device(s) are connected.

It needed a bit of adjustment though because the NotifyIcon is created when it's first made visible, so I had to make sure that (in the main thread) I set Visible to true then to false for each - giving rise to the need for limiting the number of instances.

The ManagementEventWatcher thread could then set the Visible property to true when the device gets connected.

A workaround.

(see replies to your comments)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文