是否可以从窗口句柄中设置另一个应用程序的窗口的最大宽度?
问题描述:
我目前有一个窗口句柄IntPtr
,我尝试使用HwndSource.FromHwnd得到它的Window
,但它返回null
。如果检索到Window
元素,则可以设置其MaxWidth
属性。是否可以从窗口句柄中设置另一个应用程序的窗口的最大宽度?
是否有其他方法来设置最大宽度只是从外部应用程序的窗口句柄?
编辑: 试图看看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#,所以这并不完全适合问题标签,但是我会发布它。
我创建了初始化功能的第三方DLL的WndProc
钩听GETMINMAXINFO
(我删除隐私的代码的某些部分,但是这是一个GETMINMAXINFO
:
#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**/
这个工作对某些应用A ns(我认为只适用于Win32应用程序)。某些应用程序(如Metro应用程序和可能的Java小程序)无法访问。
但现在,这可能对初学者很有帮助。
感谢Hans Passant和RbMm引导我回答这个问题。
窗口没有任何'MaxWidth'属性。窗口过程句柄['WM_GETMINMAXINFO'](https://msdn.microsoft.com/en-us/library/windows/desktop/ms632626(v = vs.85).aspx)消息并返回['MINMAXINFO中的'ptMaxSize' '](https://msdn.microsoft.com/en-us/library/windows/desktop/ms632605(v = vs.85).aspx) - so only way control window procedure – RbMm
可能的方法做到这一点 - set ['] WH_CALLWNDPROCRET'](https://msdn.microsoft.com/en-us/library/windows/desktop/ms644976(v = vs.85).aspx) - 实现CallWndRetProc回调函数并更改'MINMAXINFO'结构 – RbMm
另一种方法是当它太大时,要监视(轮询)窗口大小和[调整大小](http://stackoverflow.com/q/8443502/1997232)。 – Sinatr