2017-03-16 84 views
0

我目前有一個窗口句柄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

回答

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**/ 

這個工作對某些應用A ns(我認爲只適用於Win32應用程序)。某些應用程序(如Metro應用程序和可能的Java小程序)無法訪問。

但現在,這可能對初學者很有幫助。

感謝Hans PassantRbMm引導我回答這個問題。

相關問題