问题
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.
回答1:
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);
回答2:
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;
}
来源:https://stackoverflow.com/questions/36501491/gdi-and-directx-rendering