我想写一个程序,它允许我隐藏打开的窗口。
为实现这一目标,我使用GetForegroundWindow()
获取并ShowWindowAsync(hWnd, 0)
隐藏它。
这在大多数窗口上工作得很好,但全屏应用程序存在一些问题。
例如,VLC媒体播放器仅部分隐藏:全屏窗口消失,但原始窗口保持可见。或者英雄联盟客户永远不会被隐藏。
我已经尝试通过在WindowFromPoint(Screen.PrimaryScreen.Bounds.Width/2, Screen.PrimaryScreen.Bounds.Height/2)
没有返回窗口的情况下调用GetForegroundWindow()
来尝试获取全屏窗口来解决此问题,但这并没有解决问题。< / p>
以下是完整的课程:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace HideMyPrograms {
class Window {
private bool visible = true;
private bool wasMax = false;
private IntPtr window;
public Window(IntPtr t) {
this.window = t;
}
public int PID {
get {
return GetWindowProcessID(window);
}
}
public string Title {
get {
return GetActiveApplTitle(window);
}
}
public IntPtr Handle {
get {
return window;
}
}
public Image Image {
get {
return GetSmallWindowIcon(window);
}
}
public string ProcessName {
get {
return GetWindowProcessName(window);
}
}
public string ClassName {
get {
return GetWindowClassName(window);
}
}
public Rectangle Rectangle {
get {
return GetWindowRectangle(window);
}
}
public bool Visible {
get {
return visible;
}
set {
if(value) {
if (wasMax) {
if (ShowWindowAsync(window, 3)) { //showmax
visible = true;
}
} else {
if (ShowWindowAsync(window, 1)) { //shownormal
visible = true;
}
}
} else {
wasMax = IsZoomed(window);
if (ShowWindowAsync(window, 0)) { //hide
visible = false;
}
}
}
}
public static Window getForegroundWindow() {
string[] blacklist = new string[] { "Progman", "Shell_TrayWnd", "BaseBar", "SideBar_AppBarWindow", "DV2ControlHost", "Button", "MSTaskListWClass", "SysListView32", "WorkerW" };
IntPtr window = GetForegroundWindow();
if (window.Equals(IntPtr.Zero) || IsWindowClassBlacklisted(window, blacklist)) {
window = GetForegroundWindowByMiddlePoint();
if (window.Equals(IntPtr.Zero) || IsWindowClassBlacklisted(window, blacklist)) {
return null;
}
}
return new Window(window);
}
private static Int32 GetWindowProcessID(IntPtr hwnd) {
Int32 pid;
GetWindowThreadProcessId(hwnd, out pid);
return pid;
}
private static string GetActiveApplTitle(IntPtr hwnd) {
const int nChars = 256;
StringBuilder Buff = new StringBuilder(nChars);
if (GetWindowText(hwnd, Buff, nChars) > 0) {
return Buff.ToString();
}
return null;
}
private static Image GetSmallWindowIcon(IntPtr hWnd) {
try {
IntPtr hIcon = default(IntPtr);
hIcon = SendMessage(hWnd, 0x007f, new IntPtr(2), IntPtr.Zero);
if (hIcon != IntPtr.Zero) {
return new Bitmap(Icon.FromHandle(hIcon).ToBitmap(), 16, 16);
} else {
return new Bitmap(Icon.ExtractAssociatedIcon(Process.GetProcessById(GetWindowProcessID(hWnd)).MainModule.FileName).ToBitmap(), 16, 16); ;
}
} catch (Exception) {
return null;
}
}
private static string GetWindowProcessName(IntPtr hWnd) {
return Process.GetProcessById(GetWindowProcessID(hWnd)).ProcessName;
}
private static bool IsWindowProcessBlacklisted(IntPtr hWnd, string[] blacklist) {
string name = GetWindowProcessName(hWnd);
foreach(string s in blacklist){
if (name.Equals(s)) {
return true;
}
}
return false;
}
private static string GetWindowClassName(IntPtr hWnd) {
StringBuilder ClassName = new StringBuilder(256);
GetClassName(hWnd, ClassName, ClassName.Capacity);
return ClassName.ToString();
}
private static bool IsWindowClassBlacklisted(IntPtr hWnd, string[] blacklist) {
string name = GetWindowClassName(hWnd);
foreach (string s in blacklist) {
if (name.Equals(s)) {
return true;
}
}
return false;
}
private static Rectangle GetWindowRectangle(IntPtr hWnd) {
RECT rect = new RECT();
GetWindowRect(hWnd, out rect);
return new Rectangle(rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top);
}
private static IntPtr GetForegroundWindowByMiddlePoint() {
return WindowFromPoint(Screen.PrimaryScreen.Bounds.Width/2, Screen.PrimaryScreen.Bounds.Height/2);
}
[DllImport("user32.dll")]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
static extern IntPtr LoadIcon(IntPtr hInstance, IntPtr lpIconName);
[DllImport("user32.dll")]
private static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);
[DllImport("user32.dll")]
private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
[DllImport("user32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern bool IsIconic(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern bool IsZoomed(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
private static extern IntPtr GetActiveWindow();
[DllImport("user32.dll")]
private static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd, out Int32 ProcessId);
[DllImport("user32.dll")]
private static extern IntPtr AttachThreadInput(IntPtr idAttach, IntPtr idAttachTo, int fAttach);
[DllImport("user32.dll")]
private static extern IntPtr GetParent(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern IntPtr GetDesktopWindow();
[DllImport("user32.dll")]
static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
[DllImport("user32.dll")]
static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
[DllImport("user32.dll")]
static extern IntPtr WindowFromPoint(int xPoint, int yPoint);
[StructLayout(LayoutKind.Sequential)]
public struct RECT {
public int Left; // x position of upper-left corner
public int Top; // y position of upper-left corner
public int Right; // x position of lower-right corner
public int Bottom; // y position of lower-right corner
}
}
}
编辑:我发现了英雄联盟的错误。问题不是我的Window类,而是我的Hotkey类。似乎LoL阻止了用RegisterHotkey()创建的Hotkey。所以我转向setWindowsHookEx(),现在我的程序正在运行。