GDI和DirectX渲染 [英] GDI and DirectX rendering

查看:412
本文介绍了GDI和DirectX渲染的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个窗口,父窗口是我要通过D3D11渲染的窗口,第二个子窗口是我想在父窗口上移动的窗口。

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

这是我的代码正在创建Windows:

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;
}

和子窗口

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;
}

这是子窗口的WndProc

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);

没有LockWindowUpdate()函数移动子窗口时有子窗口痕迹。
,所以最终结果是我移动子窗口时它是黑色的。我还能做些什么?
我尝试了GDI双缓冲,即在WM_MOUSEMOVE事件
上绘制屏幕外缓冲区,在WM_PAINT事件上在窗口上绘制,但结果相同。

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.

推荐答案

在子窗口中,覆盖 WM_NCHITTEST 进行移动,并覆盖 WM_WINDOWPOSCHANGING 强制重新绘制:

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;
}

这篇关于GDI和DirectX渲染的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆