[英]Windowless tray icon application 2
這是無窗托盤圖標應用程序的延續
我終於用這個托盤圖標完成了我想要做的事情:1.托盤圖標2.單擊打開小托盤窗口3.單擊托盤窗口打開主窗口
唯一的問題是我希望中間的小窗口從托盤開始很遠。 我希望它靠近已啟動它的任務欄圖標,如下圖所示。
托盤圖標(從主窗口啟動)的代碼為:
var tim = new TrayIconMenuWindow.TrayIconMenuWindow();
tim.WindowStartupLocation = WindowStartupLocation.CenterOwner;<------
tim.ShowDialog();
this.Visibility = Visibility.Visible;
我已經嘗試了所有的啟動位置,但是都沒有幫助。 感謝名單
如果您希望窗口位於屏幕的右下角,則可以使用以下方法:
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;
如果您希望某個窗口像與該NotifyIcon關聯的ContextMenuStrip一樣出現在NotifyIcon旁邊,則需要獲取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的私有字段值,但是我不知道其他任何方式來完成此操作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.