【问题标题】:Windowless tray icon application 2无窗口托盘图标应用程序 2
【发布时间】:2015-12-17 09:28:32
【问题描述】:

这是Windowless tray icon application的延续

我终于可以用这个托盘图标做我想做的事了: 1.托盘中的图标 2.点击打开小托盘窗口 3.点击托盘窗口打开主窗口

唯一的问题是我希望小的中间窗口开始远离托盘。我希望它靠近启动它的托盘图标,如下图所示。

托盘图标的代码(从主窗口启动)是:

 var tim = new TrayIconMenuWindow.TrayIconMenuWindow();
 tim.WindowStartupLocation = WindowStartupLocation.CenterOwner;<------
 tim.ShowDialog();
 this.Visibility = Visibility.Visible;

我已经尝试了所有的启动位置,但没有任何帮助。 谢谢

【问题讨论】:

  • 'tim.Location = new Point(x, y);'怎么样
  • 从哪里获得位置?如何从托盘图标中获取它?此外我没有位置或位置成员
  • 关注我的回答,希望对您有所帮助

标签: c# wpf window location trayicon


【解决方案1】:

如果你想要屏幕右下角的窗口,你可以使用这样的东西:

Rectangle workingArea = Screen.GetWorkingArea(this);
this.Location = new Point(workingArea.Right - Size.Width,
                                  workingArea.Bottom - Size.Height);

编辑
我刚刚意识到您正在使用 WPF。如果是这种情况,请使用以下代码:

var screenSize = System.Windows.SystemParameters.WorkArea;
this.Left = screenSize.Right - this.Width;
this.Top = screenSize.Bottom - this.Height;

【讨论】:

    【解决方案2】:

    如果您希望在 NotifyIcon 旁边显示一个窗口,例如与 NotifyIcon 关联的 ContextMenuStrip,您将需要获取 NotifyIcon 在屏幕中的确切位置,然后调整窗口的位置。您可以在以下位置找到示例:

    这很长,但获取 NotifyIcon 位置的代码可以更短,如下所示:

    using System;
    using System.Reflection;
    using System.Runtime.InteropServices;
    using System.Windows;
    using System.Windows.Forms;
    
    public static class NotifyIconRect
    {
        #region Win32
    
        [DllImport("Shell32.dll", SetLastError = true)]
        private static extern int Shell_NotifyIconGetRect(
            [In] ref NOTIFYICONIDENTIFIER identifier,
            out RECT iconLocation);
    
        [StructLayout(LayoutKind.Sequential)]
        private struct NOTIFYICONIDENTIFIER
        {
            public uint cbSize;
            public IntPtr hWnd;
            public uint uID;
            public GUID guidItem; // System.Guid can be used.
        }
    
        [StructLayout(LayoutKind.Sequential)]
        private struct GUID
        {
            public uint Data1;
            public ushort Data2;
            public ushort Data3;
    
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
            public byte[] Data4;
        }
    
        [StructLayout(LayoutKind.Sequential)]
        private struct RECT
        {
            public int left;
            public int top;
            public int right;
            public int bottom;
    
            public static implicit operator Rect(RECT rect)
            {
                if ((rect.right - rect.left < 0) || (rect.bottom - rect.top < 0))
                    return Rect.Empty;
    
                return new Rect(
                    rect.left,
                    rect.top,
                    rect.right - rect.left,
                    rect.bottom - rect.top);
            }
        }
    
        #endregion
    
        public static Rect GetNotifyIconRect(NotifyIcon notifyIcon)
        {
            NOTIFYICONIDENTIFIER identifier;
            if (!TryGetNotifyIconIdentifier(notifyIcon, out identifier))
                return Rect.Empty;
    
            RECT iconLocation;
            int result = Shell_NotifyIconGetRect(ref identifier, out iconLocation);
    
            switch (result)
            {
                case 0: // 0 means S_OK.
                case 1: // 1 means S_FALSE.
                    return iconLocation;
                default:
                    return Rect.Empty;
            }
        }
    
        private static bool TryGetNotifyIconIdentifier(NotifyIcon notifyIcon, out NOTIFYICONIDENTIFIER identifier)
        {
            identifier = new NOTIFYICONIDENTIFIER { cbSize = (uint)Marshal.SizeOf(typeof(NOTIFYICONIDENTIFIER))    };
    
            int id;
            if (!TryGetFieldValue(notifyIcon, "id", out id))
                return false;
    
            NativeWindow window;
            if (!TryGetFieldValue(notifyIcon, "window", out window))
                return false;
    
            identifier.uID = (uint)id;
            identifier.hWnd = window.Handle;
            return true;
        }
    
        private static bool TryGetFieldValue<T>(object instance, string fieldName, out T fieldValue)
        {
            fieldValue = default(T);
    
            var fieldInfo = instance.GetType().GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance);
            if (fieldInfo == null)
                return false;
    
            var value = fieldInfo.GetValue(instance);
            if (!(value is T))
                return false;
    
            fieldValue = (T)value;
            return true;
        }
    }
    

    这段代码有点棘手,因为它通过反射获取 NotifyIcon 的私有字段值,但我不知道有任何其他方式来完成此操作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多