【问题标题】:Position form above the clicked notify icon在单击的通知图标上方放置表单
【发布时间】:2011-09-03 18:00:32
【问题描述】:

有没有办法在 windows 7 和 windows Vista 中将窗体放置在单击的通知图标上方?

【问题讨论】:

  • 这对你有帮助吗? codetechnic.blogspot.com/2009/03/…
  • 不将表单定位在任务栏上方的右下角。我需要将它放在通知图标上方。
  • 您不能,如 dup 中所述。您确实知道一件事:鼠标所在的位置。它不会远离图标。不要忘记任务栏可以位于屏幕的 4 个侧面中的任何一个。
  • 哈哈好的,谢谢,我怎么知道任务栏的位置?

标签: c# winforms position notifyicon


【解决方案1】:

这是一个更简单的方法。

您可以在触发 OnClick 事件时获取鼠标的 X、Y 位置。 您还可以通过这些对象Screen.PrimaryScreen.BoundsScreen.PrimaryScreen.WorkingArea 的一些检查来获取任务栏位置。

    private void OnTrayClick(object sender, EventArgs e)
    {
        _frmMain.Left = Cursor.Position.X;
        _frmMain.Top = Screen.PrimaryScreen.WorkingArea.Bottom -_frmMain.Height;
        _frmMain.Show();        
    }

【讨论】:

  • 这是我见过的最好的解决方案,除了托盘位于屏幕右侧而不是底部的情况......
  • 这让我很开心! :) 多个屏幕的小增强:trayIcon.ContextMenuStrip.Show(Cursor.Position); // 应该是第一个,因为高度最初不正确...trayIcon.ContextMenuStrip.Left = Math.Min(Cursor.Position.X, Screen.PrimaryScreen.WorkingArea.Right - trayIcon.ContextMenuStrip.Width); // 对于多显示器和任务栏的不同位置trayIcon.ContextMenuStrip.Top = Screen.PrimaryScreen.WorkingArea.Bottom - trayIcon.ContextMenuStrip.Height;
【解决方案2】:

关于您的评论:“我怎么知道任务栏的位置?”

查看以下文章,其中包含一个类,该类公开了为托盘检索 Rectangle Structure 的方法:[c#] NotifyIcon - Detect MouseOut

使用这个类,您可以像这样检索托盘的Rectangle Structure

Rectangle trayRectangle = WinAPI.GetTrayRectangle();

这将为您提供托盘的顶部、左侧、右侧和底部坐标以及托盘的宽度和高度。

我已经包含了以下课程:

using System;
using System.Runtime.InteropServices;
using System.Drawing;
using System.ComponentModel;

public class WinAPI
{
    public struct RECT
    {
        public int left;
        public int top;
        public int right;
        public int bottom;

        public override string ToString()
        {
            return "(" + left + ", " + top + ") --> (" + right + ", " + bottom + ")";
        }
    }

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr FindWindow(string strClassName, string strWindowName);

    [DllImport("user32.dll", SetLastError = true)]
    public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, IntPtr windowTitle);

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);


    public static IntPtr GetTrayHandle()
    {
        IntPtr taskBarHandle = WinAPI.FindWindow("Shell_TrayWnd", null);
        if (!taskBarHandle.Equals(IntPtr.Zero))
        {
            return WinAPI.FindWindowEx(taskBarHandle, IntPtr.Zero, "TrayNotifyWnd", IntPtr.Zero);
        }
        return IntPtr.Zero;
    }

    public static Rectangle GetTrayRectangle()
    {
        WinAPI.RECT rect;
        WinAPI.GetWindowRect(WinAPI.GetTrayHandle(), out rect);
        return new Rectangle(new Point(rect.left, rect.top), new Size((rect.right - rect.left) + 1, (rect.bottom - rect.top) + 1));
    }
}

希望这会有所帮助。

【讨论】:

  • 这是一个怪诞的 hack。为什么你会这样做而不是从右键单击事件中读出光标位置?当你可以正确地做黑客时,为什么还要求助于黑客?
  • @David Heffernan 获取任务栏位置的正确方法是什么?我只需要知道它是否在左/右/上/下。
  • @blejzz Hans 已经解释过您找不到您的图标。您可以做的是获取调用图标上下文菜单的事件的光标位置。从中您可以计算出哪个角落。
  • 任何一种方法都可以。我发布的代码将检索托盘的坐标,鼠标光标位置将为您提供托盘图标的大致位置。在我看来,您可以将两者结合起来定位您的表格。可以从坐标或鼠标位置推断确定任务栏的位置。
  • @jdavies 不同之处在于您的方法依赖于未记录的实现细节,这就是我对它嗤之以鼻的原因。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多