WM_MOVING, LPARAM Gives Wrong values on aero snap

  aero-snap, c++, winapi

I Was working on a win32 project which uses the WM_MOVING message from WndProc to detect the new position where window is moved. 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.

Please have a look into the 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. In my case the position of the content is depend on the window position, so it causes flicker if I receive a wrong value.

Here is what i am trying to achieve : Manually creating acrylic effect

IMG Aero snap

When ever I move the window in this mode (just before the aero snap mode) the value will get changed to zero.

This is only affecting The Top and Left coordinates of the window and also flickers when aero snapping to any sides.

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:%dn", 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.

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.

Source: Windows Questions C++

LEAVE A COMMENT