Notifying a message in Action center.
Revision | eb8b95171697a477a93a5863691ea84449c967ee (tree) |
---|---|
Time | 2015-09-13 13:03:49 |
Author | JeffyTS <JeffyTS@outl...> |
Commiter | JeffyTS |
Improved code and added to remember a former window pos until exitting program.
@@ -28,7 +28,7 @@ namespace VMwPlayerTaskTray | ||
28 | 28 | "\r\n" + |
29 | 29 | " Option:\r\n" + |
30 | 30 | " /gui | /nogui | (none)\r\n" + |
31 | - " /pos num_left num_top"; | |
31 | + " /pos num_left num_top | (none)"; | |
32 | 32 | private const string MSG_RUN_DUP = PROGRAM_NAME + " has been already running with \r\n" + |
33 | 33 | "same guest OS.\r\n" + |
34 | 34 | "\r\n" + |
@@ -10,6 +10,8 @@ using System.Reflection; // Add | ||
10 | 10 | using System.Management; // Add |
11 | 11 | using System.Diagnostics; // Add |
12 | 12 | using System.IO; // Add |
13 | +using System.Runtime.InteropServices; // Add DLL Import | |
14 | + | |
13 | 15 | |
14 | 16 | namespace VMwPlayerTaskTray |
15 | 17 | { |
@@ -138,6 +140,9 @@ namespace VMwPlayerTaskTray | ||
138 | 140 | case VMCTRL.GO_NOGUI: |
139 | 141 | if ((vmState == VMSTATE.POWERED_ON) && (Vix.CheckRunningMode(vmxFilePath) == Constants.RUNNING_MODE.GUI)) |
140 | 142 | { |
143 | + // get & save current window pos | |
144 | + getPlayerWindowPos(out Program.moveWindow_left, out Program.moveWindow_top); | |
145 | + | |
141 | 146 | // Go to Suspend mode |
142 | 147 | if (!Vix.VMOperation(vmxFilePath, CtrlVix.Constants.POWEROP.SUSPEND)) return false; |
143 | 148 | //@@@for (int i = 0; i < 10; i++) |
@@ -160,6 +165,11 @@ namespace VMwPlayerTaskTray | ||
160 | 165 | if (!Vix.VMOperation(vmxFilePath, CtrlVix.Constants.POWEROP.POWER_ON_NOGUI)) return false; |
161 | 166 | break; |
162 | 167 | case VMCTRL.GO_SUSPEND: |
168 | + if ((vmState == VMSTATE.POWERED_ON) && (Vix.CheckRunningMode(vmxFilePath) == Constants.RUNNING_MODE.GUI)) | |
169 | + { | |
170 | + // get & save current window pos | |
171 | + getPlayerWindowPos(out Program.moveWindow_left, out Program.moveWindow_top); | |
172 | + } | |
163 | 173 | // Go to Suspend mode |
164 | 174 | if (!Vix.VMOperation(vmxFilePath, CtrlVix.Constants.POWEROP.SUSPEND)) return false; |
165 | 175 | break; |
@@ -168,10 +178,20 @@ namespace VMwPlayerTaskTray | ||
168 | 178 | if (!Vix.VMOperation(vmxFilePath, CtrlVix.Constants.POWEROP.ACPI_RESET)) return false; |
169 | 179 | break; |
170 | 180 | case VMCTRL.GO_ACPI_POWER_OFF: |
181 | + if ((vmState == VMSTATE.POWERED_ON) && (Vix.CheckRunningMode(vmxFilePath) == Constants.RUNNING_MODE.GUI)) | |
182 | + { | |
183 | + // get & save current window pos | |
184 | + getPlayerWindowPos(out Program.moveWindow_left, out Program.moveWindow_top); | |
185 | + } | |
171 | 186 | // ACPI shutdown |
172 | 187 | if (!Vix.VMOperation(vmxFilePath, CtrlVix.Constants.POWEROP.ACPI_POWER_OFF)) return false; |
173 | 188 | break; |
174 | 189 | case VMCTRL.GO_RESET: |
190 | + if ((vmState == VMSTATE.POWERED_ON) && (Vix.CheckRunningMode(vmxFilePath) == Constants.RUNNING_MODE.GUI)) | |
191 | + { | |
192 | + // get & save current window pos | |
193 | + getPlayerWindowPos(out Program.moveWindow_left, out Program.moveWindow_top); | |
194 | + } | |
175 | 195 | // Harware reset |
176 | 196 | if (!Vix.VMOperation(vmxFilePath, CtrlVix.Constants.POWEROP.HW_RESET)) return false; |
177 | 197 | break; |
@@ -528,37 +548,71 @@ namespace VMwPlayerTaskTray | ||
528 | 548 | |
529 | 549 | if (pid != 0) |
530 | 550 | { |
531 | - if (move_window(pid, left, top, "VMPlayerFrame")) // Windowを移動する | |
551 | + if (moveWindow(pid, left, top, "VMPlayerFrame")) // Windowを移動する | |
552 | + { | |
553 | + return true; | |
554 | + } | |
555 | + } | |
556 | + return false; | |
557 | + } | |
558 | + | |
559 | + private bool getPlayerWindowPos(out int left, out int top) | |
560 | + { | |
561 | + CtrlVIX Vix = new CtrlVIX(); | |
562 | + int pid = Vix.GetVMProcessID(vmxFilePath); | |
563 | + | |
564 | + if (pid != 0) | |
565 | + { | |
566 | + if (getWindowPos(pid, out left, out top, "VMPlayerFrame")) // Windowの top, leftを取得する | |
532 | 567 | { |
533 | 568 | return true; |
534 | 569 | } |
535 | 570 | } |
571 | + left = 0; top = 0; | |
536 | 572 | return false; |
537 | 573 | } |
538 | 574 | |
539 | - [System.Runtime.InteropServices.DllImport("user32.dll")] private extern static IntPtr GetParent(IntPtr hwnd); | |
540 | - [System.Runtime.InteropServices.DllImport("user32.dll")] private extern static IntPtr GetWindow(IntPtr hWnd, int wCmd); | |
541 | - [System.Runtime.InteropServices.DllImport("user32.dll")] private extern static IntPtr FindWindow(String lpClassName, String lpWindowName); | |
542 | - [System.Runtime.InteropServices.DllImport("user32.dll")] private extern static IntPtr GetWindowThreadProcessId(IntPtr hWnd, out int lpdwprocessid); | |
543 | - [System.Runtime.InteropServices.DllImport("user32.dll")] private extern static int IsWindowVisible(IntPtr hWnd); | |
544 | - [System.Runtime.InteropServices.DllImport("user32.dll")] private extern static IntPtr GetAncestor(IntPtr hWnd, uint gaFlags); | |
545 | - private struct RECT | |
575 | + [StructLayout(LayoutKind.Sequential, Pack = 4)] | |
576 | + public struct RECT | |
546 | 577 | { |
547 | 578 | public int Left { get; set; } |
548 | 579 | public int Top { get; set; } |
549 | 580 | public int Right { get; set; } |
550 | 581 | public int Bottom { get; set; } |
551 | 582 | } |
552 | - [System.Runtime.InteropServices.DllImport("user32.dll")] private extern static bool GetWindowRect(IntPtr hWnd, out RECT lpRect); | |
553 | - [System.Runtime.InteropServices.DllImport("user32.dll")] private extern static bool MoveWindow(IntPtr hWnd, int x, int y, int nWidth, int nHeight, int bRepaint); | |
554 | - [System.Runtime.InteropServices.DllImport("user32.dll")] private extern static IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, int wParam, StringBuilder lParam); | |
555 | - [System.Runtime.InteropServices.DllImport("user32.dll")] private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount); | |
556 | - [System.Runtime.InteropServices.DllImport("user32.dll")] private static extern int GetWindowTextLength(IntPtr hWnd); | |
557 | - [System.Runtime.InteropServices.DllImport("user32.dll")] private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount); | |
558 | - [System.Runtime.InteropServices.DllImport("user32.dll")] private extern static IntPtr FindWindowEx(IntPtr hWndParent, IntPtr hWndChildAfter, String lpszClass, String lpszWindow); | |
583 | + | |
584 | + internal class NativeMethods | |
585 | + { | |
586 | + [DllImport("user32.dll", EntryPoint = "GetParent", SetLastError = true)] | |
587 | + public static extern IntPtr GetParent(IntPtr hwnd); | |
588 | + [DllImport("user32.dll", EntryPoint = "GetWindow", SetLastError = true)] | |
589 | + public static extern IntPtr GetWindow(IntPtr hWnd, int wCmd); | |
590 | + [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true, BestFitMapping = false, ThrowOnUnmappableChar = true)] | |
591 | + public static extern IntPtr FindWindow(String lpClassName, String lpWindowName); | |
592 | + [DllImport("user32.dll", EntryPoint = "GetWindowThreadProcessId", SetLastError = true)] | |
593 | + public static extern Int32 GetWindowThreadProcessId(IntPtr hWnd, out int lpdwprocessid); | |
594 | + [DllImport("user32.dll", EntryPoint = "IsWindowVisible", SetLastError = true)] | |
595 | + public static extern int IsWindowVisible(IntPtr hWnd); | |
596 | + [DllImport("user32.dll", EntryPoint = "GetAncestor", SetLastError = true)] | |
597 | + public static extern IntPtr GetAncestor(IntPtr hWnd, uint gaFlags); | |
598 | + [DllImport("user32.dll", EntryPoint = "GetWindowRect", SetLastError = true)] | |
599 | + public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect); | |
600 | + [DllImport("user32.dll", EntryPoint = "MoveWindow", SetLastError = true)] | |
601 | + public static extern bool MoveWindow(IntPtr hWnd, int x, int y, int nWidth, int nHeight, int bRepaint); | |
602 | + [DllImport("user32.dll", EntryPoint = "SendMessage", SetLastError = true, BestFitMapping = false, ThrowOnUnmappableChar = true)] | |
603 | + public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, StringBuilder lParam); | |
604 | + [DllImport("user32.dll", EntryPoint = "GetWindowText", SetLastError = true, BestFitMapping = false, ThrowOnUnmappableChar = true)] | |
605 | + public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount); | |
606 | + [DllImport("user32.dll", EntryPoint = "GetWindowTextLength", SetLastError = true)] | |
607 | + public static extern int GetWindowTextLength(IntPtr hWnd); | |
608 | + [DllImport("user32.dll", EntryPoint = "GetClassName", SetLastError = true, BestFitMapping = false, ThrowOnUnmappableChar = true)] | |
609 | + public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount); | |
610 | + [DllImport("user32.dll", EntryPoint = "FindWindowEx", SetLastError = true, BestFitMapping = false, ThrowOnUnmappableChar = true)] | |
611 | + public static extern IntPtr FindWindowEx(IntPtr hWndParent, IntPtr hWndChildAfter, String lpszClass, String lpszWindow); | |
612 | + } | |
559 | 613 | |
560 | 614 | // 指定したPIDのWindowを移動させる |
561 | - private bool move_window(int pid, int left, int top, string classname) | |
615 | + private bool moveWindow(int pid, int left, int top, string classname) | |
562 | 616 | { |
563 | 617 | RECT rect = new RECT(); |
564 | 618 | rect.Left = 0; rect.Top = 0; rect.Right = 0; rect.Bottom = 0; |
@@ -570,16 +624,16 @@ namespace VMwPlayerTaskTray | ||
570 | 624 | { |
571 | 625 | return false; |
572 | 626 | } |
573 | - if (!GetWindowRect(hWnd, out rect)) | |
627 | + if (!NativeMethods.GetWindowRect(hWnd, out rect)) | |
574 | 628 | { |
575 | 629 | return false; |
576 | 630 | } |
577 | - if (!MoveWindow(hWnd, left, top, rect.Right - rect.Left, rect.Bottom - rect.Top, bRepaint_TRUE)) | |
631 | + if (!NativeMethods.MoveWindow(hWnd, left, top, rect.Right - rect.Left, rect.Bottom - rect.Top, bRepaint_TRUE)) | |
578 | 632 | { |
579 | 633 | return false; |
580 | 634 | } |
581 | 635 | System.Threading.Thread.Sleep(1000); |
582 | - if (!GetWindowRect(hWnd, out rect)) | |
636 | + if (!NativeMethods.GetWindowRect(hWnd, out rect)) | |
583 | 637 | { |
584 | 638 | return false; |
585 | 639 | } |
@@ -590,6 +644,28 @@ namespace VMwPlayerTaskTray | ||
590 | 644 | return true; |
591 | 645 | } |
592 | 646 | |
647 | + // 指定したPIDのWindowのleft topを取得する | |
648 | + private bool getWindowPos(int pid, out int left, out int top, string classname) | |
649 | + { | |
650 | + RECT rect = new RECT(); | |
651 | + rect.Left = 0; rect.Top = 0; rect.Right = 0; rect.Bottom = 0; | |
652 | + IntPtr hWnd = IntPtr.Zero; | |
653 | + IntPtr hWndChildAfter = IntPtr.Zero; | |
654 | + | |
655 | + left = 0; top = 0; | |
656 | + | |
657 | + if ((hWnd = getHwndFromPid(pid, classname)) == IntPtr.Zero) | |
658 | + { | |
659 | + return false; | |
660 | + } | |
661 | + if (!NativeMethods.GetWindowRect(hWnd, out rect)) | |
662 | + { | |
663 | + return false; | |
664 | + } | |
665 | + left = rect.Left; top = rect.Top; | |
666 | + return true; | |
667 | + } | |
668 | + | |
593 | 669 | // プロセスID(pid)をウィンドウハンドル(hWnd)に変換する |
594 | 670 | private IntPtr getHwndFromPid(int pid, string classname) |
595 | 671 | { |
@@ -602,14 +678,14 @@ namespace VMwPlayerTaskTray | ||
602 | 678 | // IntPtr parent = IntPtr.Zero, root = IntPtr.Zero, rootowner=IntPtr.Zero; |
603 | 679 | StringBuilder csb = new StringBuilder(256); |
604 | 680 | |
605 | - hWnd = FindWindow(null, null); | |
681 | + hWnd = NativeMethods.FindWindow(null, null); | |
606 | 682 | while (hWnd != IntPtr.Zero) |
607 | 683 | { |
608 | - if (GetParent(hWnd) == IntPtr.Zero && IsWindowVisible(hWnd) != 0) | |
684 | + if (NativeMethods.GetParent(hWnd) == IntPtr.Zero && NativeMethods.IsWindowVisible(hWnd) != 0) | |
609 | 685 | { |
610 | 686 | if (pid == getPidFromHwnd(hWnd)) |
611 | 687 | { |
612 | - GetClassName(hWnd, csb, csb.Capacity); | |
688 | + NativeMethods.GetClassName(hWnd, csb, csb.Capacity); | |
613 | 689 | if (0 <= csb.ToString().IndexOf(classname)) |
614 | 690 | { |
615 | 691 | #if DEBUG |
@@ -624,7 +700,7 @@ namespace VMwPlayerTaskTray | ||
624 | 700 | // parent = GetAncestor(hWnd, GA_PARENT); |
625 | 701 | // root = GetAncestor(hWnd, GA_ROOT); |
626 | 702 | // rootowner = GetAncestor(hWnd, GA_ROOTOWNER); |
627 | - hWnd = GetWindow(hWnd, GW_HWNDNEXT); | |
703 | + hWnd = NativeMethods.GetWindow(hWnd, GW_HWNDNEXT); | |
628 | 704 | } |
629 | 705 | return IntPtr.Zero; |
630 | 706 | } |
@@ -634,10 +710,8 @@ namespace VMwPlayerTaskTray | ||
634 | 710 | { |
635 | 711 | int pid; |
636 | 712 | |
637 | - GetWindowThreadProcessId(hWnd, out pid); | |
713 | + NativeMethods.GetWindowThreadProcessId(hWnd, out pid); | |
638 | 714 | return pid; |
639 | 715 | } |
640 | - | |
641 | - | |
642 | 716 | } |
643 | 717 | } |
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices; | ||
32 | 32 | // すべての値を指定するか、下のように '*' を使ってビルドおよびリビジョン番号を |
33 | 33 | // 既定値にすることができます: |
34 | 34 | // [assembly: AssemblyVersion("1.0.*")] |
35 | -[assembly: AssemblyVersion("1.1.5.*")] | |
36 | -[assembly: AssemblyFileVersion("1.1.5.0")] | |
35 | +[assembly: AssemblyVersion("1.1.6.*")] | |
36 | +[assembly: AssemblyFileVersion("1.1.6.0")] |
@@ -21,8 +21,8 @@ | ||
21 | 21 | [NOTE] |
22 | 22 | You might be better to use shortcut files. See sample.lnk property. |
23 | 23 | Option: |
24 | - /gui | (none) | |
25 | - /pos left top | (none) | |
24 | + /gui | /nogui | (none) | |
25 | + /pos num_left num_top | (none) | |
26 | 26 | |
27 | 27 | Thanks to VMware,Inc and Microsoft Corporation. |
28 | 28 | This program has been developed on |
@@ -50,6 +50,7 @@ Rlease & modify | ||
50 | 50 | Windows10 Professional 64bit. |
51 | 51 | 2015/09/10 1.1.4 Add /pos option, changed Icons. |
52 | 52 | 2015/09/11 1.1.5 Enabled GO NoGUI but diplaying an error message and going on running. |
53 | + 2015/09/13 1.1.6 Improved code and added to remember a former window pos until exitting program. | |
53 | 54 | |
54 | 55 | |
55 | 56 |