简体   繁体   English

WM_MOVING,LPARAM 在气动快照上给出错误的值

[英]WM_MOVING, LPARAM Gives Wrong values on aero snap

I Was working on a win32 project which uses the WM_MOVING message from WndProc to detect the new position where window is moved.我正在开发一个 win32 项目,该项目使用来自WndProcWM_MOVING消息来检测新的 position,其中 window 被移动。 but when i try to snap the window to left side the LPARAM gives wrong values for just a millisecond and gives the real value after that.但是当我尝试将 window 捕捉到左侧时,LPARAM 仅在一毫秒内给出错误值,然后给出实际值。

Please have a look into the output:请查看 output:

Left: 0, Right:683
Left: -205, Right:295
Left: 0, Right:683
Left: -205, Right:295
Left: 0, Right:683
Left: -205, Right:295

The real output is -205 but in between I get zero which cause the content of my window to flicker.真正的 output 是 -205 但在两者之间我得到零,这导致我的 window 的内容闪烁。 In my case the position of the content is depend on the window position, so it causes flicker if I receive a wrong value.在我的情况下,内容的 position 取决于 window position,因此如果我收到错误的值,它会导致闪烁。

Here is what i am trying to achieve: Manually creating acrylic effect这是我想要实现的目标:手动创建丙烯酸效果

IMG 航空按扣

When ever I move the window in this mode (just before the aero snap mode) the value will get changed to zero.每当我在此模式下(就在航空快照模式之前)移动 window 时,该值将变为零。

This is only affecting The Top and Left coordinates of the window and also flickers when aero snapping to any sides.这仅影响 window 的TopLeft坐标,并且在气动捕捉到任何侧面时也会闪烁。

Here is a simple reproduceable example:这是一个简单的可复制示例:

#ifndef UNICODE
#define UNICODE
#endif 

#include <windows.h>
#include <stdio.h>

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
RECT* hostRect;
char buffer[200];

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
{

    const wchar_t CLASS_NAME[] = L"Sample Window Class";
    WNDCLASS wc = { };

    wc.lpfnWndProc = WindowProc;
    wc.hInstance = hInstance;
    wc.lpszClassName = CLASS_NAME;

    RegisterClass(&wc);

    HWND hwnd = CreateWindowEx(0,CLASS_NAME,L"Learn to Program Windows",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,NULL,NULL,hInstance,NULL);

    if (hwnd == NULL)
    {
        return 0;
    }

    ShowWindow(hwnd, nCmdShow);

    MSG msg = { };
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return 0;
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_MOVING:
    {
        hostRect = reinterpret_cast<RECT*>(lParam);
        sprintf_s(buffer, "Left: %d, Top:%d, Right:%d, Bottom:%d\n", hostRect->left, hostRect->top, hostRect->right, hostRect->bottom);
        OutputDebugStringA(buffer);
    }
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;

    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hwnd, &ps);

        FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));
        EndPaint(hwnd, &ps);
    }
    return 0;

    }
    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

Run this program and check the value in output while you move the window to any side for aero snap.运行此程序并检查 output 中的值,同时将 window 移动到任何一侧以进行气动捕捉。

Note: In my case i will not be able to use GetWindowRect() in WM_MOVING , because calling GetWindowRect() slow down the render() function (just a directx painting) in my window.注意:在我的情况下,我将无法在WM_MOVING中使用GetWindowRect() ,因为调用GetWindowRect()会减慢我的 window 中的 render() function(只是一个 directx 绘画)。

You can try to make temporary changes to the style of the window.您可以尝试对 window 的样式进行临时更改。

Here is an example:这是一个例子:

#ifndef UNICODE
#define UNICODE
#endif 

#include <windows.h>
#include <stdio.h>
#define WM_RESTOREORIGINALSTYLE WM_USER + 1

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
RECT* hostRect;
char buffer[200];

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
{

    const wchar_t CLASS_NAME[] = L"Sample Window Class";
    WNDCLASS wc = { };

    wc.lpfnWndProc = WindowProc;
    wc.hInstance = hInstance;
    wc.lpszClassName = CLASS_NAME;

    RegisterClass(&wc);

    HWND hwnd = CreateWindowEx(0, CLASS_NAME, L"Learn to Program Windows", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);

    if (hwnd == NULL)
    {
        return 0;
    }

    ShowWindow(hwnd, nCmdShow);

    MSG msg = { };
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return 0;
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_MOVING:
    {
        hostRect = reinterpret_cast<RECT*>(lParam);
        sprintf_s(buffer, "Left: %d, Top:%d, Right:%d, Bottom:%d\n", hostRect->left, hostRect->top, hostRect->right, hostRect->bottom);
        OutputDebugStringA(buffer);
        break;
    }

    case WM_SYSCOMMAND:
    {
        if (wParam == (SC_MOVE | 2)) wParam = SC_SIZE | 9;
        if ((wParam & 0xFFE0) == SC_SIZE && (wParam & 0x000F)) // handles MOVE and SIZE in one "if"
        {
            long int oldStyle = GetWindowLongW(hwnd, GWL_STYLE);
            PostMessageW(hwnd, WM_RESTOREORIGINALSTYLE, GWL_STYLE, oldStyle);
            SetWindowLongW(hwnd, GWL_STYLE, oldStyle & 0xFEFEFFFF); // disable WS_MAXIMIZE and WS_MAXIMIZEBOX
            DefWindowProcW(hwnd, WM_SYSCOMMAND, wParam, lParam);
            return 0;
        }
        return DefWindowProcW(hwnd, WM_SYSCOMMAND, wParam, lParam);
    }
    case WM_RESTOREORIGINALSTYLE:
    {
        if ((long int)wParam == GWL_STYLE)
            SetWindowLongW(hwnd, GWL_STYLE, lParam);
        return 0;
    }
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;

    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hwnd, &ps);

        FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));
        EndPaint(hwnd, &ps);
    }
    return 0;

    }
    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

More reference: Win32 prevent window “snap”更多参考: Win32 防止 window “snap”

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM