设置目标窗口的大小(Windows,C++)

有时候要准确设置一个窗口的大小,没有找到合适的工具,自己写了一个。

命令行程序(70 行代码 C++):

#include <windows.h>
#include <iostream>

#define IsKeyDown(VK_NAME) ((GetAsyncKeyState(VK_NAME) & 0x8000) ? true:false)   

int main()
{
    POINT point;        // 鼠标所在位置

    HWND target;        // 目标窗口句柄
    HWND parent;        // 目标父窗口句柄
    INT width, height;  // 窗口新宽高

    // 软件用法
    std::cout << "\n功能:设置目标窗口的大小\n\n";
    std::cout << "用法:输入参数后,将鼠标移到要设置的窗口上,然后按下 Ctrl 键 1 秒钟即可\n";
    std::cout << "      按下 Shift 键可重新输入\n";
    std::cout << "      按下  Alt  键可退出程序\n";

    BOOL start = true;  // 是否开始循环
    while(start)
    {
        std::cout << "\n请输入窗口宽度:";
        std::cin >> width;
        std::cout << "请输入窗口高度:";
        std::cin >> height;
        std::cout << "\n移动鼠标,然后按键(Ctrl/Shift/Alt)...\n";

        BOOL listen = true;  // 是否开始监听用户按键
        while (listen)
        {
            // Ctrl 键确认窗口
            if IsKeyDown(VK_CONTROL)
            {
                // 获取鼠标位置
                GetCursorPos(&point);
                // 获取鼠标位置的窗口句柄
                target = WindowFromPoint(point);
                // 合法性判断
                if (target != NULL && target != INVALID_HANDLE_VALUE) {
                    // 获取顶层窗口句柄
                    parent = GetParent(target);
                    while (parent != NULL && parent != INVALID_HANDLE_VALUE)
                    {
                        target = parent;
                        parent = GetParent(target);
                    }
                    // 获取窗口原始大小
                    RECT rect;
                    GetWindowRect(target, &rect);
                    // 重新设置窗口大小
                    MoveWindow(target, rect.left, rect.top, width, height, true);
                    // 停止监听
                    listen = false;
                }
            }
            // Shift 键停止监听
            else if (IsKeyDown(VK_SHIFT))
            {
                listen = false;
            }
            // Alt 键退出程序
            else if (IsKeyDown(VK_MENU))
            {
                listen = false;
                start = false;
            }
            Sleep(200);
        }
        std::cout << "\n----------\n";
    }
    return 0;
}

 

以下是一个使用 DirectX Graphics Infrastructure (DXGI) 捕获鼠标指针位置的示例代码: ```cpp #include <Windows.h> #include <d3d11.h> #include <dxgi.h> #include <iostream> #pragma comment(lib, "d3d11.lib") #pragma comment(lib, "dxgi.lib") int main() { // 创建 DXGI 工厂 IDXGIFactory* dxgiFactory = nullptr; HRESULT hr = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&dxgiFactory); if (FAILED(hr)) { std::cerr << "Failed to create DXGI factory." << std::endl; return 1; } // 获取默认显示适配器 IDXGIAdapter* adapter = nullptr; hr = dxgiFactory->EnumAdapters(0, &adapter); if (FAILED(hr)) { std::cerr << "Failed to get adapter." << std::endl; return 1; } // 创建 D3D11 设备和设备上下文 ID3D11Device* device = nullptr; ID3D11DeviceContext* context = nullptr; hr = D3D11CreateDevice( adapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr, 0, nullptr, 0, D3D11_SDK_VERSION, &device, nullptr, &context ); if (FAILED(hr)) { std::cerr << "Failed to create D3D11 device and context." << std::endl; return 1; } // 释放 DXGI 工厂和显示适配器 adapter->Release(); dxgiFactory->Release(); // 创建一个窗口并使其可见 HWND hwnd = CreateWindowEx( 0, L"STATIC", L"DXGI Mouse Capture", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, nullptr, nullptr, nullptr, nullptr ); ShowWindow(hwnd, SW_SHOWDEFAULT); // 获取窗口客户区域大小 RECT clientRect; GetClientRect(hwnd, &clientRect); UINT width = clientRect.right - clientRect.left; UINT height = clientRect.bottom - clientRect.top; // 创建 DXGI 交换链 DXGI_SWAP_CHAIN_DESC swapChainDesc = {}; swapChainDesc.BufferCount = 1; swapChainDesc.BufferDesc.Width = width; swapChainDesc.BufferDesc.Height = height; swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; swapChainDesc.BufferDesc.RefreshRate.Numerator = 60; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.OutputWindow = hwnd; swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; swapChainDesc.Windowed = TRUE; IDXGISwapChain* swapChain = nullptr; hr = dxgiFactory->CreateSwapChain(device, &swapChainDesc, &swapChain); if (FAILED(hr)) { std::cerr << "Failed to create DXGI swap chain." << std::endl; return 1; } // 释放 D3D11 设备上下文 context->Release(); // 获取 DXGI 捕获鼠标指针的设备 IDXGIDevice* dxgiDevice = nullptr; hr = device->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice); if (FAILED(hr)) { std::cerr << "Failed to get DXGI device." << std::endl; return 1; } // 获取 DXGI 设备的父对象(通常是 ID3D11DeviceContext) IUnknown* parent = nullptr; hr = dxgiDevice->GetParent(__uuidof(IUnknown), (void**)&parent); if (FAILED(hr)) { std::cerr << "Failed to get DXGI device parent." << std::endl; return 1; } // 释放 DXGI 设备和 D3D11 设备 dxgiDevice->Release(); device->Release(); // 获取 DXGI 父对象的设备上下文 ID3D11DeviceContext* dxgiContext = nullptr; hr = parent->QueryInterface(__uuidof(ID3D11DeviceContext), (void**)&dxgiContext); if (FAILED(hr)) { std::cerr << "Failed to get DXGI context." << std::endl; return 1; } // 创建后备缓冲区并设置为渲染目标 ID3D11Texture2D* backBuffer = nullptr; hr = swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&backBuffer); if (FAILED(hr)) { std::cerr << "Failed to get back buffer." << std::endl; return 1; } ID3D11RenderTargetView* renderTargetView = nullptr; hr = device->CreateRenderTargetView(backBuffer, nullptr, &renderTargetView); if (FAILED(hr)) { std::cerr << "Failed to create render target view." << std::endl; return 1; } backBuffer->Release(); dxgiContext->OMSetRenderTargets(1, &renderTargetView, nullptr); // 设置视口 D3D11_VIEWPORT viewport = {}; viewport.Width = (float)width; viewport.Height = (float)height; viewport.MaxDepth = 1.0f; dxgiContext->RSSetViewports(1, &viewport); // 清除后备缓冲区 float clearColor[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; dxgiContext->ClearRenderTargetView(renderTargetView, clearColor); // 显示后备缓冲区 swapChain->Present(1, 0); // 捕获鼠标指针位置 POINT point; GetCursorPos(&point); ScreenToClient(hwnd, &point); std::cout << "Mouse position: " << point.x << ", " << point.y << std::endl; // 释放资源 renderTargetView->Release(); swapChain->Release(); dxgiContext->Release(); return 0; } ``` 这个示例代码创建了一个窗口和一个 DXGI 交换链,并捕获了鼠标指针位置。需要注意的是,DXGI 只能捕获指针位置,而不能捕获指针形状或其他信息。如果需要获取更多鼠标信息,可以考虑使用 Windows 消息循环或 DirectInput API。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值