是否可以通过其 window 句柄设置另一个应用程序的 window 的最大宽度?
Is it possible to set another application's window's maximum width from its window handle?
我目前有一个 window 句柄的 IntPtr
,我尝试使用 HwndSource.FromHwnd 获取它的 Window
但它 returns null
.如果检索到 Window
元素,则可以设置其 MaxWidth
属性。
是否有其他方法仅通过 window 外部应用程序句柄来设置最大宽度?
编辑:
尝试查看 RbMm 的方法是否有效。问题已标记为 C#,但使用 C++ 自定义 DLL 可能值得一试:
bool InitializeMaxWidthHook(int threadID, HWND destination)
{
if (g_appInstance == NULL)
{
return false;
}
SetProp(GetDesktopWindow(), "WILSON_HOOK_HCBT_MINMAX", destination);
hookMaxWidth = SetWindowsHookEx(WH_CBT, (HOOKPROC)MinMaxHookCallback, g_appInstance, threadID);
return hookMaxWidth != NULL;
}
void UninitializeMaxWidthHook()
{
if (hookMaxWidth != NULL)
UnhookWindowsHookEx(hookMaxWidth);
hookMaxWidth = NULL;
}
static LRESULT CALLBACK MinMaxHookCallback(int code, WPARAM wparam, LPARAM lparam)
{
if (code >= 0)
{
UINT msg = 0;
if (code == HCBT_MINMAX)
msg = RegisterWindowMessage("WILSON_HOOK_HCBT_MINMAX");
HWND dstWnd = (HWND)GetProp(GetDesktopWindow(), "WILSON_HOOK_HCBT_MINMAX");
if (msg != 0)
SendNotifyMessage(dstWnd, msg, wparam, lparam);
}
return CallNextHookEx(hookMaxWidth, code, wparam, lparam);
}
我会在修改这个问题后再次更新这个问题。
我想出的解决方案不是纯粹的 C#,所以这并不完全符合问题标签,但我还是 post 它。
我为 WndProc
钩子创建了一个带有初始化函数的第三方 DLL 来监听 GETMINMAXINFO
(为了隐私我删除了部分代码,但这是 [=13] =]:
#include "stdafx.h"
#include <windows.h>
HINSTANCE g_appInstance = NULL;
typedef void (CALLBACK *HookProc)(int code, WPARAM w, LPARAM l);
HHOOK hookWndProc = NULL;
static LRESULT CALLBACK WndProcHookCallback(int code, WPARAM wparam, LPARAM lparam);
bool InitializeWndProcHook(int threadID, HWND destination)
{
if (g_appInstance == NULL)
{
return false;
}
SetProp(GetDesktopWindow(), "WILSON_HOOK_HWND_WND_PROC", destination);
hookWndProc = SetWindowsHookEx(WH_CALLWNDPROC, (HOOKPROC)WndProcHookCallback, g_appInstance, threadID);
return hookWndProc != NULL;
}
void UninitializeWndProcHook()
{
if (hookWndProc != NULL)
UnhookWindowsHookEx(hookWndProc);
hookWndProc = NULL;
}
static LRESULT CALLBACK WndProcHookCallback(int code, WPARAM wparam, LPARAM lparam)
{
if (code >= 0)
{
UINT msg = 0;
WPARAM newWPARAM;
LPARAM newLPARAM;
if (code == HC_ACTION)
{
CWPSTRUCT *wndProc = (CWPSTRUCT *)lparam;
if (shouldSendMessageOnWindow(wndProc->hwnd))
{
// if the message is from other process, the value of wparam is null
UINT wndProcMessage = wndProc->message;
if (wndProcMessage == WM_GETMINMAXINFO)
{
newWPARAM = (WPARAM)wndProc->hwnd;
newLPARAM = (LPARAM)wndProc->lParam;
msg = RegisterWindowMessage("WILSON_HOOK_HC_ACTION_WND_PROC_WM_GETMINMAXINFO");
}
}
}
if (msg != 0)
{
HWND dstWnd = (HWND)GetProp(GetDesktopWindow(), "WILSON_HOOK_HWND_WND_PROC");
SendNotifyMessage(dstWnd, msg, newWPARAM, newLPARAM);
}
}
return CallNextHookEx(hookWndProc, code, wparam, lparam);
}
然后我在我的 C# 代码中初始化了这个挂钩并等待 MINMAX
消息,然后将信息设置为我想要的大小。
private struct POINT
{
public int x;
public int y;
}
private struct MINMAXINFO
{
public POINT ptReserved;
public POINT ptMaxSize;
public POINT ptMaxPosition;
public POINT ptMinTrackSize;
public POINT ptMaxTrackSize;
}
/**Other Code**/
MINMAXINFO* minMaxInfo = (MINMAXINFO*) lParam;
int currentMaxSize = minMaxInfo->ptMaxSize.x;
Debug.WriteLine("Updated max" + currentMaxSize);
minMaxInfo->ptMaxSize.x = screenWidth;
minMaxInfo->ptMaxSize.y = screenHeight;
User32.SetWindowPos(wParam, User32.SpecialWindowHandles.HWND_TOP, 0, 0, screenWidth, screenHeight, User32.SetWindowPosFlags.SWP_DRAWFRAME | User32.SetWindowPosFlags.SWP_ASYNCWINDOWPOS);
/**Other Code**/
这适用于某些应用程序(我认为仅适用于 Win32 应用程序)。无法访问某些应用程序,例如 Metro Apps 和 Java 小程序。
但就目前而言,这可能适合初学者。
感谢 Hans Passant and RbMm 指导我找到这个答案。
我目前有一个 window 句柄的 IntPtr
,我尝试使用 HwndSource.FromHwnd 获取它的 Window
但它 returns null
.如果检索到 Window
元素,则可以设置其 MaxWidth
属性。
是否有其他方法仅通过 window 外部应用程序句柄来设置最大宽度?
编辑: 尝试查看 RbMm 的方法是否有效。问题已标记为 C#,但使用 C++ 自定义 DLL 可能值得一试:
bool InitializeMaxWidthHook(int threadID, HWND destination)
{
if (g_appInstance == NULL)
{
return false;
}
SetProp(GetDesktopWindow(), "WILSON_HOOK_HCBT_MINMAX", destination);
hookMaxWidth = SetWindowsHookEx(WH_CBT, (HOOKPROC)MinMaxHookCallback, g_appInstance, threadID);
return hookMaxWidth != NULL;
}
void UninitializeMaxWidthHook()
{
if (hookMaxWidth != NULL)
UnhookWindowsHookEx(hookMaxWidth);
hookMaxWidth = NULL;
}
static LRESULT CALLBACK MinMaxHookCallback(int code, WPARAM wparam, LPARAM lparam)
{
if (code >= 0)
{
UINT msg = 0;
if (code == HCBT_MINMAX)
msg = RegisterWindowMessage("WILSON_HOOK_HCBT_MINMAX");
HWND dstWnd = (HWND)GetProp(GetDesktopWindow(), "WILSON_HOOK_HCBT_MINMAX");
if (msg != 0)
SendNotifyMessage(dstWnd, msg, wparam, lparam);
}
return CallNextHookEx(hookMaxWidth, code, wparam, lparam);
}
我会在修改这个问题后再次更新这个问题。
我想出的解决方案不是纯粹的 C#,所以这并不完全符合问题标签,但我还是 post 它。
我为 WndProc
钩子创建了一个带有初始化函数的第三方 DLL 来监听 GETMINMAXINFO
(为了隐私我删除了部分代码,但这是 [=13] =]:
#include "stdafx.h"
#include <windows.h>
HINSTANCE g_appInstance = NULL;
typedef void (CALLBACK *HookProc)(int code, WPARAM w, LPARAM l);
HHOOK hookWndProc = NULL;
static LRESULT CALLBACK WndProcHookCallback(int code, WPARAM wparam, LPARAM lparam);
bool InitializeWndProcHook(int threadID, HWND destination)
{
if (g_appInstance == NULL)
{
return false;
}
SetProp(GetDesktopWindow(), "WILSON_HOOK_HWND_WND_PROC", destination);
hookWndProc = SetWindowsHookEx(WH_CALLWNDPROC, (HOOKPROC)WndProcHookCallback, g_appInstance, threadID);
return hookWndProc != NULL;
}
void UninitializeWndProcHook()
{
if (hookWndProc != NULL)
UnhookWindowsHookEx(hookWndProc);
hookWndProc = NULL;
}
static LRESULT CALLBACK WndProcHookCallback(int code, WPARAM wparam, LPARAM lparam)
{
if (code >= 0)
{
UINT msg = 0;
WPARAM newWPARAM;
LPARAM newLPARAM;
if (code == HC_ACTION)
{
CWPSTRUCT *wndProc = (CWPSTRUCT *)lparam;
if (shouldSendMessageOnWindow(wndProc->hwnd))
{
// if the message is from other process, the value of wparam is null
UINT wndProcMessage = wndProc->message;
if (wndProcMessage == WM_GETMINMAXINFO)
{
newWPARAM = (WPARAM)wndProc->hwnd;
newLPARAM = (LPARAM)wndProc->lParam;
msg = RegisterWindowMessage("WILSON_HOOK_HC_ACTION_WND_PROC_WM_GETMINMAXINFO");
}
}
}
if (msg != 0)
{
HWND dstWnd = (HWND)GetProp(GetDesktopWindow(), "WILSON_HOOK_HWND_WND_PROC");
SendNotifyMessage(dstWnd, msg, newWPARAM, newLPARAM);
}
}
return CallNextHookEx(hookWndProc, code, wparam, lparam);
}
然后我在我的 C# 代码中初始化了这个挂钩并等待 MINMAX
消息,然后将信息设置为我想要的大小。
private struct POINT
{
public int x;
public int y;
}
private struct MINMAXINFO
{
public POINT ptReserved;
public POINT ptMaxSize;
public POINT ptMaxPosition;
public POINT ptMinTrackSize;
public POINT ptMaxTrackSize;
}
/**Other Code**/
MINMAXINFO* minMaxInfo = (MINMAXINFO*) lParam;
int currentMaxSize = minMaxInfo->ptMaxSize.x;
Debug.WriteLine("Updated max" + currentMaxSize);
minMaxInfo->ptMaxSize.x = screenWidth;
minMaxInfo->ptMaxSize.y = screenHeight;
User32.SetWindowPos(wParam, User32.SpecialWindowHandles.HWND_TOP, 0, 0, screenWidth, screenHeight, User32.SetWindowPosFlags.SWP_DRAWFRAME | User32.SetWindowPosFlags.SWP_ASYNCWINDOWPOS);
/**Other Code**/
这适用于某些应用程序(我认为仅适用于 Win32 应用程序)。无法访问某些应用程序,例如 Metro Apps 和 Java 小程序。
但就目前而言,这可能适合初学者。
感谢 Hans Passant and RbMm 指导我找到这个答案。