GDI和DirectX渲染 [英] GDI and DirectX rendering
问题描述
我有两个窗口,父窗口是我要通过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屋!