기본 Winapi 창을 사용한 간단한 응용 프로그램과 하위 창인 정적 컨트롤이 있습니다. Direct2D를 사용하여 자식 윈도우를 그립니다.Direct2D DC 컨텍스트 렌더링 이미지가 시작시 나타나지 않습니다.
드로잉은 WM_PAINT 메시지 외부에서 발생하므로 ID2D1DCRenderTarget
을 사용하기로 결정했습니다. 한 가지는 제외하고 모든 것이 작동합니다. 응용 프로그램이 시작될 때 도면을 보이게 할 수 없습니다.
어떤 경우에도 (예 : WM_LBUTTONDOWN
) 그림을 그리면 그림이 나타납니다. 그러나 내가 그림을 그리면 WM_CREATE
나는 화면에 아무 것도 볼 수 없다. 여기
#include <iostream>
#include <windows.h>
#include <windowsx.h>
#include <d2d1.h>
#pragma comment(lib, "d2d1.lib")
HWND windowHandle = NULL;
HWND childWindowHandle = NULL;
ID2D1Factory* direct2DFactory = nullptr;
ID2D1DCRenderTarget* renderTarget = nullptr;
static void InitDirect2D()
{
D2D1CreateFactory (D2D1_FACTORY_TYPE_SINGLE_THREADED, &direct2DFactory);
D2D1_RENDER_TARGET_PROPERTIES props = D2D1::RenderTargetProperties(
D2D1_RENDER_TARGET_TYPE_DEFAULT,
D2D1::PixelFormat(
DXGI_FORMAT_B8G8R8A8_UNORM,
D2D1_ALPHA_MODE_IGNORE),
0,
0,
D2D1_RENDER_TARGET_USAGE_NONE,
D2D1_FEATURE_LEVEL_DEFAULT
);
direct2DFactory->CreateDCRenderTarget (&props, &renderTarget);
renderTarget->SetAntialiasMode (D2D1_ANTIALIAS_MODE_ALIASED);
}
static void Paint()
{
ID2D1SolidColorBrush* blackBrush = nullptr;
renderTarget->CreateSolidColorBrush (
D2D1::ColorF (D2D1::ColorF::Black),
&blackBrush
);
renderTarget->BeginDraw();
renderTarget->SetTransform (D2D1::Matrix3x2F::Identity());
renderTarget->Clear (D2D1::ColorF (D2D1::ColorF::LightGray));
D2D1_RECT_F rect = D2D1::RectF (10.0f, 10.0f, 100.0f, 100.0f);
renderTarget->DrawRectangle (&rect, blackBrush);
renderTarget->EndDraw();
}
static LRESULT CALLBACK ChildWindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg) {
case WM_CREATE:
{
RECT rc;
GetClientRect (hwnd, &rc);
renderTarget->BindDC (GetDC (hwnd), &rc);
Paint();
}
break;
case WM_LBUTTONDOWN:
Paint();
break;
case WM_PAINT:
break;
case WM_SIZE:
{
RECT rc;
GetClientRect (hwnd, &rc);
renderTarget->BindDC (GetDC (hwnd), &rc);
Paint();
}
break;
case WM_CLOSE:
DestroyWindow (hwnd);
break;
case WM_DESTROY:
PostQuitMessage (0);
break;
break;
}
LRESULT res = DefWindowProc (hwnd, msg, wParam, lParam);
return res;
}
static void CreateChildWindow (HWND parentHandle)
{
WNDCLASSEX windowClass;
memset (&windowClass, 0, sizeof (WNDCLASSEX));
windowClass.cbSize = sizeof(WNDCLASSEX);
windowClass.style = 0;
windowClass.lpfnWndProc = ChildWindowProc;
windowClass.style = CS_DBLCLKS;
windowClass.cbClsExtra = 0;
windowClass.cbWndExtra = 0;
windowClass.hInstance = NULL;
windowClass.hCursor = LoadCursor (NULL, IDC_ARROW);
windowClass.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
windowClass.lpszMenuName = NULL;
windowClass.lpszClassName = L"ChildWindowClass";
RegisterClassEx (&windowClass);
childWindowHandle = CreateWindowEx (
0, windowClass.lpszClassName, L"", WS_CHILD,
CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, parentHandle, NULL, NULL, nullptr
);
ShowWindow (childWindowHandle, SW_SHOW);
UpdateWindow (childWindowHandle);
MoveWindow (childWindowHandle, 10, 10, 780, 580, TRUE);
}
static LRESULT CALLBACK MainWindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
if (msg == WM_CREATE) {
CreateChildWindow (hwnd);
InvalidateRect (hwnd, NULL, FALSE);
}
switch (msg) {
case WM_SIZE:
{
int newWidth = LOWORD (lParam);
int newHeight = HIWORD (lParam);
MoveWindow (childWindowHandle, 10, 10, newWidth - 20, newHeight - 20, TRUE);
}
break;
case WM_CLOSE:
DestroyWindow (hwnd);
break;
case WM_DESTROY:
PostQuitMessage (0);
break;
}
return DefWindowProc (hwnd, msg, wParam, lParam);
}
static int CreateMainWindow()
{
WNDCLASSEX windowClass;
memset (&windowClass, 0, sizeof (WNDCLASSEX));
windowClass.cbSize = sizeof (WNDCLASSEX);
windowClass.style = 0;
windowClass.lpfnWndProc = MainWindowProc;
windowClass.style = CS_DBLCLKS;
windowClass.cbClsExtra = 0;
windowClass.cbWndExtra = 0;
windowClass.hInstance = NULL;
windowClass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
windowClass.hCursor = LoadCursor (NULL, IDC_ARROW);
windowClass.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
windowClass.lpszMenuName = NULL;
windowClass.lpszClassName = L"WindowClass";
windowClass.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
RegisterClassEx (&windowClass);
RECT requiredRect = { 0, 0, 800, 600 };
HWND windowHandle = CreateWindowEx (
WS_EX_WINDOWEDGE, windowClass.lpszClassName, L"Example", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, requiredRect.right - requiredRect.left, requiredRect.bottom - requiredRect.top, NULL, NULL, NULL, nullptr
);
if (windowHandle == NULL) {
return 1;
}
ShowWindow (windowHandle, SW_SHOW);
UpdateWindow (windowHandle);
MSG msg;
while (GetMessage (&msg, NULL, 0, 0)) {
TranslateMessage (&msg);
DispatchMessage (&msg);
}
return 0;
}
int main (int argc, char* argv[])
{
InitDirect2D();
return CreateMainWindow();
}
내가이 (가) 응용 프로그램 시작에 표시 그리기 할 수있는 방법 어떤 생각을 가지고 있습니까?
저는 Direct2D를 오프 스크린 컨텍스트로 사용하고 싶습니다. 그래서 이것이 Hwnd 렌더 타겟 대신 DC 렌더 타겟을 사용하는 이유입니다. 따라서 일반적으로 드로잉은 WM_PAINT에서는 발생하지 않지만 코드의 어디에서나 발생합니다. WM_PAINT에서 GDI 오프 스크린 DC 및 BitBlt와 비슷한 작업을하고 싶지만 Direct2D를 사용하고 싶습니다. – kovacsv
더블 버퍼링을 위해 D2D를 사용하여 비트 맵 렌더 타겟을 생성하려면 WM_PAINT 핸들러에서 내용을 화면 타겟에 복사하십시오. – SoronelHaetir
@kovacsv 오프 스크린 컨텍스트를 만들려면 GDI 장치 컨텍스트를 사용하거나 창을 전혀 만들지 않아도됩니다. – VTT