Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 当任何应用程序窗口被拖到屏幕顶部时检测_C++_Windows_Winapi_Windows 10 - Fatal编程技术网

C++ 当任何应用程序窗口被拖到屏幕顶部时检测

C++ 当任何应用程序窗口被拖到屏幕顶部时检测,c++,windows,winapi,windows-10,C++,Windows,Winapi,Windows 10,在Windows 10上,我一直在尝试替换“窗口捕捉”功能,以便更好地使用超宽显示器。虽然捕获Windows键+箭头光标来处理键盘快捷键没有问题,但现在我想检测另一个应用程序窗口何时被拖到当前监视器的顶部/右侧/左侧/底部 当前代码: #include <iostream> #include <Windows.h> HHOOK _hook_keyboard; KBDLLHOOKSTRUCT kbdStruct; CONST int HORIZONTAL_SLOTS =

在Windows 10上,我一直在尝试替换“窗口捕捉”功能,以便更好地使用超宽显示器。虽然捕获Windows键+箭头光标来处理键盘快捷键没有问题,但现在我想检测另一个应用程序窗口何时被拖到当前监视器的顶部/右侧/左侧/底部

当前代码:

#include <iostream>
#include <Windows.h>

HHOOK _hook_keyboard;
KBDLLHOOKSTRUCT kbdStruct;

CONST int HORIZONTAL_SLOTS = 4;
CONST int VERTICAL_SLOTS = 1;

// horizontalPosition/verticalPosition specifies which "slot" starting at 0 to place Window in
// horizontalSlots/verticalSlots specifies how many slots to divide the screen into
void MoveAndResizeActiveWindow(int horizontalPosition, int verticalPosition, int horizontalSlots, int verticalSlots)
{
    // get work area on primary monitor
    HWND currentWindow = GetForegroundWindow();
    if (currentWindow != NULL)
    {
        HMONITOR currentMonitor = MonitorFromWindow(currentWindow, MONITOR_DEFAULTTONEAREST);
        MONITORINFO monitorInfo;
        monitorInfo.cbSize = sizeof(MONITORINFO);
        if (GetMonitorInfo(currentMonitor, &monitorInfo))
        {
            long width = monitorInfo.rcWork.right - monitorInfo.rcWork.left;
            long height = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top;
            long snappedWidth = width / horizontalSlots;
            long snappedHeight = height / verticalSlots;
            long snappedLeft = (snappedWidth * horizontalPosition) + monitorInfo.rcWork.left;
            long snappedTop = (snappedHeight * verticalPosition) + monitorInfo.rcWork.top;
            MoveWindow(currentWindow, snappedLeft, snappedTop, snappedWidth, snappedHeight, true);
        }
    }
}
LRESULT __stdcall HookCallbackKeyboard(int nCode, WPARAM wParam, LPARAM lParam)
{
    BOOL bEatkeystroke = false;
    short keyState;

    if (nCode >= 0)
    {
        kbdStruct = *((KBDLLHOOKSTRUCT*)lParam);

        switch (wParam)
        {
        case WM_KEYDOWN:
            keyState = GetAsyncKeyState(VK_LWIN);
            if (keyState)
            {
                switch (kbdStruct.vkCode)
                {
                    case VK_LEFT:
                        bEatkeystroke = true;
                        break;
                    case VK_RIGHT:
                        bEatkeystroke = true;
                        break;
                    case VK_UP:
                        bEatkeystroke = true;
                        break;
                    case VK_DOWN:
                        bEatkeystroke = true;
                        break;
                };
            };
            break;
        case WM_KEYUP:
            keyState = GetAsyncKeyState(VK_LWIN);
            if (keyState)
            {
                switch (kbdStruct.vkCode)
                {
                case VK_LEFT:
                    MoveAndResizeActiveWindow(0, 0, 4, 1);
                    bEatkeystroke = true;
                    break;
                case VK_RIGHT:
                    MoveAndResizeActiveWindow(3, 0, 4, 1);
                    bEatkeystroke = true;
                    break;
                    break;
                case VK_UP:
                    MoveAndResizeActiveWindow(1, 0, 4, 1);
                    bEatkeystroke = true;
                    break;
                case VK_DOWN:
                    MoveAndResizeActiveWindow(2, 0, 4, 1);
                    bEatkeystroke = true;
                    break;
                };
            }
            break;
        };
    }
    if (bEatkeystroke)
    {
        return 1;
    }
    else
    {
        return CallNextHookEx(_hook_keyboard, nCode, wParam, lParam);
    }
}

void SetHook()
{
    if (!(_hook_keyboard = SetWindowsHookEx(WH_KEYBOARD_LL, HookCallbackKeyboard, NULL, 0)))
    {
        MessageBox(NULL, L"Failed to install hook on keyboard!", L"Error", MB_ICONERROR);
    }
}


int main(int argc, char** argv[])
{
    SetHook();
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}
虽然使用EVENT\u SYSTEM\u MOVESIZESTART和EVENT\u SYSTEM\u MOVESIZEEND可以轻松跟踪Windows移动的开始或结束,但在这里我看不到跟踪EVENT\u SYSTEM\u MOVESIZEEND之前窗口移动的事件


虽然这是一个好的选择,但理想情况下,我希望能够从事件\系统\移动大小开始到事件\系统\移动大小结束检测窗口位置。使用记事本进行测试移动过程中引发的唯一事件是event_OBJECT_NAMECHANGE,它似乎在窗口移动过程中不断触发,至少使用记事本是如此。但是,根据中的描述,我不确定这是否适合我的用例:“对象的名称属性已更改。系统为以下用户界面元素发送此事件:复选框、光标、列表视图控件、按钮、单选按钮、状态栏控件、树视图控件和窗口对象。服务器应用程序为其可访问对象发送此事件。”

谢谢,在测试该API的基础上添加了一些附加信息,如果您有进一步的想法,请告诉我。您确定您得到的是
event\u OBJECT\u NAMECHANGE
而不是
event\u OBJECT\u LOCATIONCHANGE
?在任何情况下,
SetWindowsHookEx()
还有可以跟踪窗口移动的挂钩,例如
WH\u CBT
WH\u CALLWNDPROC/RET
g_hook_winevent = SetWinEventHook(
        EVENT_MIN, EVENT_MAX, 
        NULL,                                          // Handle to DLL.
        HandleWinEvent,                                // The callback.
        0, 0,              // Process and thread IDs of interest (0 = all)
        WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS); // Flags.
}

void CALLBACK HandleWinEvent(HWINEVENTHOOK hook, DWORD event, HWND hwnd,
    LONG idObject, LONG idChild,
    DWORD dwEventThread, DWORD dwmsEventTime)
{
    // process event here

}