CBT Hook dll,拦截窗口被调整大小

Posted

技术标签:

【中文标题】CBT Hook dll,拦截窗口被调整大小【英文标题】:CBT Hook dll, to intercept window from being resized 【发布时间】:2021-09-03 05:14:26 【问题描述】:

我正在尝试编写一个 dll 来拦截调整大小的窗口,但我无法理解在这种情况下如何正确指定 lParam。

来自docs:

HCBT_MOVESIZE:指定一个长指针,指向一个 RECT 结构,包含 窗口的坐标。通过更改中的值 结构,一个 CBTProc 钩子程序可以设置的最终坐标 窗户。

当前代码:

#include "pch.h"
#include <Windows.h>

extern "C" __declspec(dllexport) LRESULT CALLBACK CBTProc(
    _In_ int    nCode,
    _In_ WPARAM wParam,
    _In_ LPARAM lParam
)

    if (nCode < 0) return CallNextHookEx(nullptr, nCode, wParam, lParam);
    
    switch(nCode)
    
    case HCBT_MOVESIZE: // A window is about to be moved or sized.

        /*
            For operations corresponding to the following CBT hook codes, the return value must be 0 to allow the operation, or 1 to prevent it.
            HCBT_ACTIVATE
            HCBT_CREATEWND
            HCBT_DESTROYWND
            HCBT_MINMAX
            HCBT_MOVESIZE
            HCBT_SETFOCUS
            HCBT_SYSCOMMAND
        */

        /*
        switch(LOWORD(lParam)) //
        
        case EVENT_SYSTEM_MOVESIZESTART:
            return 1; // Prevent
        
        */
    
    return 0;

【问题讨论】:

【参考方案1】:

对于HCBT_MOVESIZElParam 包含RECT 的内存地址,因此只需将lParam 类型转换为RECT* 指针,例如:

extern "C" __declspec(dllexport) LRESULT CALLBACK CBTProc(
    _In_ int    nCode,
    _In_ WPARAM wParam,
    _In_ LPARAM lParam
)

    if (nCode < 0) return CallNextHookEx(nullptr, nCode, wParam, lParam);
    
    switch(nCode)
    
        case HCBT_MOVESIZE: // A window is about to be moved or sized.
        
            HWND hwnd = reinterpret_cast<HWND>(wParam);
            RECT *rc = reinterpret_cast<RECT*>(lParam);

            // use hwnd and *rc as needed...

            if (should not resize)
                return 1;

            break;
        

        ...
    

    return 0;

【讨论】:

如何在“事件”之间正确切换,以防窗口的宽度/高度与给定值不同,重新调整大小?我得到的 atm:pastebin.com/mhuj8EE9 窗口没有调整到所需的宽度/高度,只是重置为她的初始大小。 HCBT_MOVESIZE 中没有“事件”,它不会告诉您为什么要移动/调整窗口大小。 EVENT_SYSTEM_MOVESIZESTART 仅与SetWinEventHook() 一起使用,而不与SetWindowsHookEx() 一起使用。在HCBT_MOVESIZE 中,您可以查看RECT 的内容以检查它是否在您想要的范围内,如果不是,那么您可以修改RECT 的内容(而不是使用@987654335 @) 和 return 0 接受更改,或 return 1 完全阻止移动/大小。【参考方案2】:

LPARAM 是一个指针大小的值。它可以保存任何适合指针的值。值的含义通常取决于上下文。

在处理 HCBT_MOVESIZE callback 时,它指定

指向RECT 结构的长指针

要使用它,客户端代码需要将值转换为相应类型的值。在 C++ 中,这是使用强制转换完成的,例如

switch(nCode)

case HCBT_MOVESIZE: 
    auto pRect reinterpret_cast<RECT*>(lParam) ;
    // Use `pRect` to read from or write to the rectangle

    break;

// ...

【讨论】:

以上是关于CBT Hook dll,拦截窗口被调整大小的主要内容,如果未能解决你的问题,请参考以下文章

使用窗口调整自定义视图的大小

调整窗口大小会导致位图被覆盖

调整显示自定义字体大小的 MessageBox 窗口的大小?

MFC 网格是绝对布局,在调整窗口大小时会被剪裁

如何调整UIPickerView,UISwitch等无法通过frame调整大小的大小

当被调整大小的窗口的图像尺寸的缩小