0
votes

I have two windows, parent window where I'm rendering by D3D11 and second child window what I want to move over parent window.

here is code how I'm creating windows:

wcex.cbSize         = sizeof(WNDCLASSEX);
wcex.style          = 0;
wcex.lpfnWndProc    = WndProc;
wcex.cbClsExtra     = 0;
wcex.cbWndExtra     = 0;
wcex.hInstance      = hInstance;
wcex.hIcon          = LoadIcon(NULL,IDI_APPLICATION);
wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground  = (HBRUSH)0;
wcex.lpszMenuName   = 0;
wcex.lpszClassName  = L"Parent";
wcex.hIconSm        = LoadIcon(NULL,IDI_APPLICATION);

if(!RegisterClassEx(&wcex)){
    return E_FAIL;
}

if(!(hWnd = CreateWindowEx(WS_EX_COMPOSITED,L"Parent",L"WINDOW",
                           WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN |
                            WS_VISIBLE,
                            CW_USEDEFAULT,CW_USEDEFAULT,
                            WIDTH,HEIGHT,
                            NULL,NULL,
                            hInstance,NULL))){
    return E_FAIL;
}

and child window

wcex2.cbSize         = sizeof(WNDCLASSEX);
wcex2.style          = 0;
wcex2.lpfnWndProc    = WndProc2;
wcex2.cbClsExtra     = 0;
wcex2.cbWndExtra     = 0;
wcex2.hInstance      = hInstance;
wcex2.hIcon          = LoadIcon(NULL,IDI_APPLICATION);
wcex2.hCursor        = LoadCursor(NULL, IDC_ARROW);
wcex2.hbrBackground  = (HBRUSH)0;
wcex2.lpszMenuName   = 0;
wcex2.lpszClassName  = L"Child";
wcex2.hIconSm        = LoadIcon(NULL,IDI_APPLICATION);

if(!RegisterClassEx(&wcex2)){
    return E_FAIL;
}
if(!(chilWnd = CreateWindowEx(0, wcex2.lpszClassName, NULL, 
                                WS_CHILD|WS_CLIPSIBLINGS,
                                    0,0,
                                    200, 100,
                                    hWnd,NULL,
                                    hInstance,0)))
{
    return FALSE;
}

this is child window's WndProc

 case WM_LBUTTONDOWN:
 dragWindow = true;
 SetCapture(hWnd);
 break;

 case WM_LBUTTONUP:
 ReleaseCapture();
 dragWindow = false;
 break;

case WM_MOUSEMOVE:

 if (dragWindow == true)
 {  
    RECT mainWindowRect;
    POINT pos;
    int windowWidth, windowHeight;

    pos.x = (int)(short) LOWORD(lp);
    pos.y = (int)(short) HIWORD(lp);

    GetWindowRect(hWnd,&mainWindowRect);
    windowHeight = mainWindowRect.bottom - mainWindowRect.top;
    windowWidth = mainWindowRect.right - mainWindowRect.left;

    ClientToScreen(hWnd, &pos);

    HDWP hdwp = BeginDeferWindowPos(1);

    DeferWindowPos(hdwp, 
                    hWnd,
                    HWND_TOP,
                    pos.x,
                    pos.y, 
                    windowWidth,
                    windowHeight, 
                    SWP_NOZORDER);

    EndDeferWindowPos(hdwp);

    LockWindowUpdate(hWnd);
    RedrawWindow(hWnd, 0, 0, RDW_UPDATENOW);
    LockWindowUpdate(NULL);
    ....
    case WM_PAINT:
    hdc = BeginPaint(hWnd, &Ps);

    FillRect( hdc, &r, (HBRUSH)GetStockObject(GRAY_BRUSH));

    EndPaint(hWnd, &Ps);

without LockWindowUpdate() function I have child window traces when I'm moving it. so final result is that child window is black while I'm moving it . What can I do more? I tried GDI double buffering i.e draw in offscreen buffer on WM_MOUSEMOVE event and paint on window on WM_PAINT event but same result.

2
In child proc you can add case WM_NCHITTEST: return HTCAPTION; this will move the window around (remove WM_MOUSEMOVE/LBUTTONUP/DOWN) Also try changing WS_EX_COMPOSITED to zeroBarmak Shemirani
I added case WM_NCHITTEST: return HTCAPTION; and removed WM_MOUSEMOVE/LBUTTONUP/DOWN but I have traces of child window when I'm moving it , like old positions.Alatriste
There shouldn't be trailing any lines. Update your question to show what you are doing.Barmak Shemirani

2 Answers

0
votes

There is almost everything of my code. I showed to you how I'm creating windows and I have also DirectX rendering loop:

bool done = false;
MSG  msg;

while(!done)
{
    if(PeekMessage(&msg,0,0,0,PM_REMOVE))
    {
        if(msg.message == WM_QUIT)
        {
            done = true;
        }
        else
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    else
    {
        Render();
    }
}

so in this Render() function I'm just clearing render target and flipping buffers. Nothing else.

D3DXCOLOR color(0.5f,0.5f,0.85f,1.0f);
pDevContext->ClearRenderTargetView(pRenderTarget,color);


pSwapChain->Present(1,0);
0
votes

In child window, override WM_NCHITTEST to move, and override WM_WINDOWPOSCHANGING to force repaint:

LRESULT CALLBACK ChildProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_WINDOWPOSCHANGING: Render(); break;
    case WM_NCHITTEST: return HTCAPTION;    
    }
    return DefWindowProc(hWnd, message, wParam, lParam);
}

LRESULT CALLBACK WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    if (msg == WM_DESTROY)
    {
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hWnd, msg, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int)
{
    HWND hWnd;
    WNDCLASSEX wc = { sizeof(WNDCLASSEX) };
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WindowProc;
    wc.hInstance = hInstance;
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.lpszClassName = L"WindowClass";
    RegisterClassEx(&wc);

    hWnd = CreateWindow(wc.lpszClassName, L"appName", 
        WS_CLIPCHILDREN | WS_VISIBLE | WS_OVERLAPPEDWINDOW,
        0, 0, 800, 600, NULL, NULL, hInstance, NULL);

    //initialize Direct3D
    initD3D(hWnd, 800, 600);

    wc.lpfnWndProc = ChildProc;
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
    wc.lpszClassName = L"child";
    RegisterClassEx(&wc);
    CreateWindow(wc.lpszClassName, 0, 
        WS_BORDER | WS_VISIBLE | WS_CHILD, 
        0, 0, 300, 200, hWnd, 0, 0, 0);

    MSG msg = { 0 };
    while (msg.message != WM_QUIT)
    {
        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else
        {
            Render();
        }
    }

    // clean up Direct3D
    cleanD3D();

    return msg.wParam;
}