wpf notifyicon上下文菜单不以100%dpi的托盘图标为中心

时间:2015-01-30 15:13:49

标签: wpf dpi notifyicon

我正在使用wpf notifyicon(http://www.hardcodet.net/wpf-notifyicon

当我的笔记本电脑处于100%dpi缩放比例时,上下文菜单的左侧将按照预期位于托盘图标的中心位置。

当笔记本电脑不是100%时,上下文菜单会被推到最右边。

在高分辨率笔记本电脑显示器上,100%缩放不是默认设置。

无论我的托盘图标位于何处,即距离时钟不远,菜单总是会在时钟上弹出,尽可能远离屏幕的右下角,同时保持可见。

注意:我正在测试Windows 8.1的默认安装。此外,我正在使用的NotifyIcon是通常推荐给在WPF中尝试托盘功能的任何人使用的NotifyIcon。

重现:hardcodet提供的无窗口样本中存在问题。我在没有窗口的情况下使用wpf NotifyIcon,并且可以在代码或xaml中轻松复制。事实上,我无法停止复制它。当打开dpi缩放时,即当1080p显示实际上显示较低的分辨率时,就会发生这种情况,这就是Windows阻止文本太小而无法读取的应用程序。

关于如何使上下文菜单出现在预期位置的任何想法,无论dpi如何?

kennyzx建议的屏幕截图:

好的行为。刚刚右键单击红色背景上的m(MEGAsync)

不良行为。刚刚右键单击绿色刻度,我的通知图标,菜单显示在时钟上

good behaviour. the m on red background (MEGAsync) has just been right-clicked

bad behaviour. the green tick, my notifyicon, has just been right-clicked and the menu appears over the clock

和一些代码:

var n = new TaskbarIcon();
n.Icon=new System.Drawing.Icon(@"C:\window - 64 - tick.ico");
n.ContextMenu = new System.Windows.Controls.ContextMenu();
n.ContextMenu.Items.Add(new System.Windows.Controls.MenuItem {Header="E_xit" });

1 个答案:

答案 0 :(得分:0)

在此处找到解决方案:http://www.codeproject.com/Messages/4929452/Problem-with-context-menu-position.aspx

感谢codeproject用户Igorious:

获取Wpf Notifyicon(http://www.hardcodet.net/wpf-notifyicon)的代码。

在Hardcodet.Wpf.TaskbarNotification.TaskbarIcon.ShowContextMenu()

替换

ContextMenu.HorizontalOffset = cursorPosition.X;
ContextMenu.VerticalOffset = cursorPosition.Y;

var g = Graphics.FromHwnd(IntPtr.Zero);
var scaleX = g.DpiX / 96.0;
var scaleY = g.DpiY / 96.0;

ContextMenu.HorizontalOffset = cursorPosition.X / scaleX;
ContextMenu.VerticalOffset = cursorPosition.Y / scaleY;

解释(感谢codeproject用户游艇):

这是必需的,因为WinApi.GetPhysicalCursorPos以像素为单位返回鼠标位置, 但是WPF的测量单位是与设备无关的像素(根据定义,它是1/96英寸) 您需要通过DPI(每英寸点数)设置调整GetPhysicalCursorPos的返回值, 否则,如果用户将DPI设置为默认值96以外,则上下文菜单的位置将不正确。