是否可以从窗口句柄中设置另一个应用程序的窗口的最大宽度?

问题描述:

我目前有一个窗口句柄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); 
} 

我将与此修补后再次更新的问题。

+1

窗口没有任何'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

+0

可能的方法做到这一点 - set ['] WH_CALLWNDPROCRET'](https://msdn.microsoft.com/en-us/library/windows/desktop/ms644976(v = vs.85).aspx) - 实现CallWndRetProc回调函数并更改'MINMAXINFO'结构 – RbMm

+0

另一种方法是当它太大时,要监视(轮询)窗口大小和[调整大小](http://stackoverflow.com/q/8443502/1997232)。 – Sinatr

我想出的解决方案并不是纯粹的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 PassantRbMm引导我回答这个问题。