启动时不显示 Direct2D DC 上下文呈现的图像
Direct2D DC context rendered images doesn't appear on startup
我具有带有本机Winapi窗口的简单应用程序,并且作为子窗口上的静态控制。我想用direct2d绘制子窗口。
绘图发生在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 ();
}
您是否知道如何使图纸在应用程序启动中可见?
在 WM_CREATE
窗口中尚未完整创建尚未创建,因此绘画不起作用。您应该编写适当的WM_PAINT
(和WM_ERASEBKGND
)消息处理程序,然后在那里执行所有绘画操作。然后,当您需要重新绘制作为对任何其他消息的响应(例如WM_LBUTTONDOWN
)时,您需要无效窗口并触发WM_PAINT
,而不是立即调用Paint();
。
相关文章:
- C++,OpenCV,尝试显示图像时"OpenCV(4.3.0) Error: Assertion failed (size.width>0 && size.height>0)"此错误
- #为""定义宏;静态";针对不同的上下文
- 与互斥锁相比,旋转锁可以保证上下文切换
- 如何使用OpenCV将RBG图像转换为HSV,并将H、S和V值保存为C++中的3个独立图像
- OpenCV EqualizeHist()从彩色图像创建黑白图像
- 将"打开的CV图像"中的"颜色"转换为整数格式
- 线程,如果else语句,都是错误的上下文切换后,会发生什么
- 为什么我不能使用 EGL 创建无头 OpenGl 上下文?
- 平均图像时图像损坏
- 在C++中使用GDAL可以将图像的像素坐标转换为lat,long吗
- 如何将图像传输到c++(dll)中的缓冲区,然后在c#的缓冲区中读/写
- Vulkan验证层不断在VkQueuePresentKHR()上抛出图像布局错误
- 使用FFMPEG将RGB图像序列保存到.mp4时出现问题
- 将RGB图像保存为PPM格式
- 将图像添加到资源文件夹UWP C++
- Visual Studio(或任何其他工具)能否将地址解释为调用堆栈(boost上下文)的开头
- 为什么在逗号分隔符上下文中将预增量的结果强制转换为void
- 启动时不显示 Direct2D DC 上下文呈现的图像
- 从gdiplus (GDI+)中的设备上下文或图形对象中获取图像/位图
- Windows GDI上下文-加载图像