我目前有一个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);
}
我在修补此问题后再次更新问题。
答案 0 :(得分:0)
我提出的解决方案不仅仅是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**/
这适用于某些应用程序(我认为仅适用于Win32应用程序)。某些应用程序(如Metro Apps和可能的Java小程序)无法访问。
但就目前而言,这对初学者来说可能是个好消息。
感谢Hans Passant和RbMm指导我这个答案。