experiment to move taskbar

This commit is contained in:
Kang Yu 2020-03-06 13:20:49 -08:00
parent 523d4ba0e3
commit 7cf8a152fc
3 changed files with 163 additions and 4 deletions

View file

@ -10,6 +10,10 @@ namespace Ninjacrab.PersistentWindows.Common.Models
public uint ProcessId { get; set; } public uint ProcessId { get; set; }
public string ClassName { get; set; } public string ClassName { get; set; }
public string ApplicationName { get; set; } public string ApplicationName { get; set; }
public bool IsTaskbar { get; set; }
public Shell32.APP_BAR_DATA TaskBarPos { get; set; }
public RECT ScreenPosition { get; set; } public RECT ScreenPosition { get; set; }
public WindowPlacement WindowPlacement { get; set; } public WindowPlacement WindowPlacement { get; set; }
public bool NeedUpdateWindowPlacement { get; set; } //non-persistent data used for tmp argument passing only public bool NeedUpdateWindowPlacement { get; set; } //non-persistent data used for tmp argument passing only

View file

@ -64,6 +64,20 @@ namespace Ninjacrab.PersistentWindows.Common
#endif #endif
public void Start() public void Start()
{ {
/*
RECT screenPosition = new RECT();
//IntPtr hTaskMan = User32.FindWindowA(null, "Untitled - Notepad");
IntPtr hTaskMan = User32.FindWindowA(null, "Task Manager");
User32.GetWindowRect(hTaskMan, ref screenPosition);
User32.SetCursorPos(screenPosition.Left + 200, screenPosition.Top + 20);
User32.SetForegroundWindow(hTaskMan);
User32.SetActiveWindow(hTaskMan);
User32.mouse_event(MouseAction.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, UIntPtr.Zero);
Thread.Sleep(1000); // wait to be activated
User32.SetCursorPos(screenPosition.Left + 200, screenPosition.Top - 100);
User32.mouse_event(MouseAction.MOUSEEVENTF_LEFTUP, 0, 0, 0, UIntPtr.Zero);
*/
monitorApplications = new Dictionary<string, Dictionary<string, ApplicationDisplayMetrics>>(); monitorApplications = new Dictionary<string, Dictionary<string, ApplicationDisplayMetrics>>();
databaseLock = new object(); databaseLock = new object();
validDisplayKeyForCapture = GetDisplayKey(); validDisplayKeyForCapture = GetDisplayKey();
@ -406,6 +420,10 @@ namespace Ninjacrab.PersistentWindows.Common
{ {
monitorApplications[displayKey].Add(curDisplayMetrics.Key, curDisplayMetrics); monitorApplications[displayKey].Add(curDisplayMetrics.Key, curDisplayMetrics);
} }
else if (curDisplayMetrics.IsTaskbar)
{
monitorApplications[displayKey][curDisplayMetrics.Key].TaskBarPos = curDisplayMetrics.TaskBarPos;
}
else else
{ {
monitorApplications[displayKey][curDisplayMetrics.Key].WindowPlacement = curDisplayMetrics.WindowPlacement; monitorApplications[displayKey][curDisplayMetrics.Key].WindowPlacement = curDisplayMetrics.WindowPlacement;
@ -540,14 +558,16 @@ namespace Ninjacrab.PersistentWindows.Common
private IEnumerable<SystemWindow> CaptureWindowsOfInterest() private IEnumerable<SystemWindow> CaptureWindowsOfInterest()
{ {
return SystemWindow.AllToplevelWindows return SystemWindow.AllToplevelWindows
.Where(row => row.Parent.HWnd.ToInt64() == 0 .Where(row =>
{
return row.Parent.HWnd.ToInt64() == 0
//&& !string.IsNullOrEmpty(row.Title) //&& !string.IsNullOrEmpty(row.Title)
//&& !row.Title.Equals("Program Manager") //&& !row.Title.Equals("Program Manager")
//&& !row.Title.Contains("Task Manager") //&& !row.Title.Contains("Task Manager")
//&& row.Position.Height != 0 //&& row.Position.Height != 0
//&& row.Position.Width != 0 //&& row.Position.Width != 0
&& row.Visible && row.Visible;
); });
} }
private bool IsWindowMoved(string displayKey, SystemWindow window, User32Events eventType, DateTime now, out ApplicationDisplayMetrics curDisplayMetrics) private bool IsWindowMoved(string displayKey, SystemWindow window, User32Events eventType, DateTime now, out ApplicationDisplayMetrics curDisplayMetrics)
@ -559,10 +579,15 @@ namespace Ninjacrab.PersistentWindows.Common
return false; return false;
} }
bool isTaskBar = false;
Shell32.APP_BAR_DATA abd = new Shell32.APP_BAR_DATA();
if (window.ClassName.Contains("Shell_TrayWnd")) if (window.ClassName.Contains("Shell_TrayWnd"))
{ {
// capture task bar // capture task bar
int i = 0; isTaskBar = true;
abd.cbSize = (uint)Marshal.SizeOf(abd);
abd.hWnd = window.HWnd;
Shell32.SHAppBarMessage(Shell32.ABM_GETTASKBARPOS, ref abd);
} }
else if (string.IsNullOrEmpty(window.Title)) else if (string.IsNullOrEmpty(window.Title))
{ {
@ -597,11 +622,31 @@ namespace Ninjacrab.PersistentWindows.Common
ClassName = window.ClassName, ClassName = window.ClassName,
ProcessId = processId, ProcessId = processId,
IsTaskbar = isTaskBar,
TaskBarPos = abd,
WindowPlacement = windowPlacement, WindowPlacement = windowPlacement,
NeedUpdateWindowPlacement = false, NeedUpdateWindowPlacement = false,
ScreenPosition = screenPosition ScreenPosition = screenPosition
}; };
if (isTaskBar)
{
IntPtr hReBar = User32.FindWindowEx(hwnd, IntPtr.Zero, "ReBarWindow32", null);
User32.GetWindowRect(hReBar, ref screenPosition);
//User32.SetCursorPos(screenPosition.Left + 50, screenPosition.Top + 1650);
User32.SetCursorPos(screenPosition.Left + 3, screenPosition.Top + 3);
User32.SetForegroundWindow(hReBar);
User32.SetActiveWindow(hReBar);
User32.mouse_event(MouseAction.MOUSEEVENTF_LEFTDOWN,
0, 0, 0, UIntPtr.Zero);
Thread.Sleep(2000); // wait to be activated
User32.SetCursorPos(screenPosition.Left + 200, - (screenPosition.Top + 3));
User32.mouse_event(MouseAction.MOUSEEVENTF_LEFTUP,
0, 0, 0, UIntPtr.Zero);
int i = 0;
}
bool moved = false; bool moved = false;
if (!monitorApplications[displayKey].ContainsKey(curDisplayMetrics.Key)) if (!monitorApplications[displayKey].ContainsKey(curDisplayMetrics.Key))
{ {
@ -622,6 +667,10 @@ namespace Ninjacrab.PersistentWindows.Common
// when close/reopen session, OS/user may activate existing window (possibly with different position) // when close/reopen session, OS/user may activate existing window (possibly with different position)
// just ignore it // just ignore it
} }
else if (isTaskBar)
{
return !prevDisplayMetrics.TaskBarPos.Equals(curDisplayMetrics.TaskBarPos);
}
else if (!prevDisplayMetrics.EqualPlacement(curDisplayMetrics)) else if (!prevDisplayMetrics.EqualPlacement(curDisplayMetrics))
{ {
/* /*
@ -767,6 +816,7 @@ namespace Ninjacrab.PersistentWindows.Common
{ {
sWindows = CaptureWindowsOfInterest(); sWindows = CaptureWindowsOfInterest();
} }
foreach (var window in sWindows) foreach (var window in sWindows)
{ {
if (!window.IsValid() || string.IsNullOrEmpty(window.ClassName)) if (!window.IsValid() || string.IsNullOrEmpty(window.ClassName))
@ -798,6 +848,40 @@ namespace Ninjacrab.PersistentWindows.Common
} }
bool success = true; bool success = true;
if (curDisplayMetrics.IsTaskbar)
{
// simulate mouse drag, assuming taskbar is unlocked
/*
ControlGetPos x, y, w, h, MSTaskListWClass1, ahk_class Shell_TrayWnd
MouseMove x+1, y+1
MouseClickDrag Left, x+1, y+1, targetX, targetY, 10
*/
IntPtr hTaskBar = User32.FindWindowEx(hwnd, IntPtr.Zero, "MSTaskListWClass1", "Running applications");
/*
Shell32.APP_BAR_DATA abd = prevDisplayMetrics.TaskBarPos;
abd.cbSize = (uint)Marshal.SizeOf(abd);
//abd.hWnd = window.HWnd;
//abd.uEdge = Shell32.ABE_TOP;
UIntPtr result = Shell32.SHAppBarMessage(Shell32.ABM_SETPOS, ref abd);
Log.Info("Set TaskBar pos ({0} [{1}x{2}]-[{3}x{4}]) - {5}",
window.Process.ProcessName,
abd.rc.Left,
abd.rc.Top,
abd.rc.Width,
abd.rc.Height,
result);
User32.SetWindowPos(hwnd, IntPtr.Zero, abd.rc.Left, abd.rc.Top, abd.rc.Width, abd.rc.Height,
//SWP_NOSENDCHANGING);
SetWindowPosFlags.DoNotSendChangingEvent);
User32.ShowWindow(hwnd, 5); //SW_SHOW
User32.UpdateWindow(hwnd);
*/
continue;
}
if (restoreTimes >= MinRestoreTimes || curDisplayMetrics.NeedUpdateWindowPlacement) if (restoreTimes >= MinRestoreTimes || curDisplayMetrics.NeedUpdateWindowPlacement)
{ {
// recover NormalPosition (the workspace position prior to snap) // recover NormalPosition (the workspace position prior to snap)

View file

@ -49,6 +49,18 @@ namespace Ninjacrab.PersistentWindows.Common.WinApiBridge
WINEVENT_INCONTEXT = 0x0004 WINEVENT_INCONTEXT = 0x0004
} }
public enum MouseAction : uint
{
MOUSEEVENTF_ABSOLUTE = 0x8000,
MOUSEEVENTF_LEFTDOWN = 0x0002,
MOUSEEVENTF_LEFTUP = 0x0004,
MOUSEEVENTF_RIGHTDOWN = 0x0008,
MOUSEEVENTF_RIGHTUP = 0x0010,
MOUSEEVENTF_MOVE = 0x0001,
}
public class User32 public class User32
{ {
#region EnumDisplayMonitors #region EnumDisplayMonitors
@ -96,10 +108,37 @@ namespace Ninjacrab.PersistentWindows.Common.WinApiBridge
[return: MarshalAs(UnmanagedType.Bool)] [return: MarshalAs(UnmanagedType.Bool)]
public static extern bool IsWindow(IntPtr hWnd); public static extern bool IsWindow(IntPtr hWnd);
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ShowWindow(IntPtr hWnd, int cmd);
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool UpdateWindow(IntPtr hWnd);
[DllImport("user32.dll", SetLastError = true)] [DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)] [return: MarshalAs(UnmanagedType.Bool)]
public static extern bool IsTopLevelWindow(IntPtr hWnd); public static extern bool IsTopLevelWindow(IntPtr hWnd);
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindowA(string lpClassName, string lpWindowName);
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);
[DllImport("user32.dll")]
public static extern void mouse_event(MouseAction dwFlags, int dx, int dy, uint dwData, UIntPtr dwExtraInfo);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetCursorPos(int x, int y);
[DllImport("user32.dll")]
public static extern bool SetForegroundWindow (IntPtr hWnd);
[DllImport("user32.dll", SetLastError=true)]
public static extern IntPtr SetActiveWindow(IntPtr hWnd);
#region Hooks #region Hooks
[DllImport("user32.dll")] [DllImport("user32.dll")]
public static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam); public static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
@ -130,4 +169,36 @@ namespace Ninjacrab.PersistentWindows.Common.WinApiBridge
#endregion #endregion
} }
public class Shell32
{
[DllImport("Shell32.dll", CharSet = CharSet.Auto)]
public static extern UIntPtr SHAppBarMessage(int dwMessage, ref APP_BAR_DATA abd);
public const int ABM_NEW = 0x00;
public const int ABM_REMOVE = 0x01;
public const int ABM_QUERYPOS = 0x02;
public const int ABM_SETPOS = 0x03;
public const int ABM_GETTASKBARPOS = 0x05;
public const int ABM_SETAUTOHIDEBAR = 0x08;
public const int ABM_SETSTATE = 0x0000000a;
public const int ABE_LEFT = 0;
public const int ABE_TOP = 1;
public const int ABE_RIGHT = 2;
public const int ABE_BOTTOM = 3;
public const int ABS_AUTOHIDE = 0x01;
public const int ABS_ALWAYSONTOP = 0x02;
[StructLayout(LayoutKind.Sequential)]
public struct APP_BAR_DATA
{
public uint cbSize;
public IntPtr hWnd;
public int uCallbackMessage;
public int uEdge;
public RECT rc;
public IntPtr lParam;
}
}
} }