Build XCEditor menu and status shell widgets

This commit is contained in:
2026-04-07 03:51:26 +08:00
parent 5f9f3386ab
commit 8eeb7af56e
25 changed files with 3708 additions and 106 deletions

View File

@@ -24,23 +24,29 @@ bool NativeRenderer::Initialize(HWND hwnd) {
Shutdown();
if (hwnd == nullptr) {
m_lastRenderError = "Initialize rejected a null hwnd.";
return false;
}
m_hwnd = hwnd;
if (FAILED(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, m_d2dFactory.ReleaseAndGetAddressOf()))) {
HRESULT hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, m_d2dFactory.ReleaseAndGetAddressOf());
if (FAILED(hr)) {
m_lastRenderError = HrToString("D2D1CreateFactory", hr);
Shutdown();
return false;
}
if (FAILED(DWriteCreateFactory(
hr = DWriteCreateFactory(
DWRITE_FACTORY_TYPE_SHARED,
__uuidof(IDWriteFactory),
reinterpret_cast<IUnknown**>(m_dwriteFactory.ReleaseAndGetAddressOf())))) {
reinterpret_cast<IUnknown**>(m_dwriteFactory.ReleaseAndGetAddressOf()));
if (FAILED(hr)) {
m_lastRenderError = HrToString("DWriteCreateFactory", hr);
Shutdown();
return false;
}
m_lastRenderError.clear();
return EnsureRenderTarget();
}
@@ -71,17 +77,31 @@ void NativeRenderer::Resize(UINT width, UINT height) {
bool NativeRenderer::Render(const ::XCEngine::UI::UIDrawData& drawData) {
if (!EnsureRenderTarget()) {
if (m_lastRenderError.empty()) {
m_lastRenderError = "EnsureRenderTarget failed.";
}
return false;
}
const bool rendered = RenderToTarget(*m_renderTarget.Get(), *m_solidBrush.Get(), drawData);
const HRESULT hr = m_renderTarget->EndDraw();
if (hr == D2DERR_RECREATE_TARGET) {
m_lastRenderError = HrToString("ID2D1HwndRenderTarget::EndDraw", hr);
DiscardRenderTarget();
return false;
}
return rendered && SUCCEEDED(hr);
if (!rendered || FAILED(hr)) {
m_lastRenderError = HrToString("ID2D1HwndRenderTarget::EndDraw", hr);
return false;
}
m_lastRenderError.clear();
return true;
}
const std::string& NativeRenderer::GetLastRenderError() const {
return m_lastRenderError;
}
bool NativeRenderer::CaptureToPng(
@@ -231,6 +251,7 @@ bool NativeRenderer::CaptureToPng(
bool NativeRenderer::EnsureRenderTarget() {
if (!m_hwnd || !m_d2dFactory || !m_dwriteFactory) {
m_lastRenderError = "EnsureRenderTarget requires hwnd, D2D factory, and DWrite factory.";
return false;
}
@@ -285,21 +306,26 @@ bool NativeRenderer::CreateDeviceResources() {
m_hwnd,
D2D1::SizeU(width, height));
if (FAILED(m_d2dFactory->CreateHwndRenderTarget(
const HRESULT renderTargetHr = m_d2dFactory->CreateHwndRenderTarget(
renderTargetProps,
hwndProps,
m_renderTarget.ReleaseAndGetAddressOf()))) {
m_renderTarget.ReleaseAndGetAddressOf());
if (FAILED(renderTargetHr)) {
m_lastRenderError = HrToString("ID2D1Factory::CreateHwndRenderTarget", renderTargetHr);
return false;
}
if (FAILED(m_renderTarget->CreateSolidColorBrush(
const HRESULT brushHr = m_renderTarget->CreateSolidColorBrush(
D2D1::ColorF(1.0f, 1.0f, 1.0f, 1.0f),
m_solidBrush.ReleaseAndGetAddressOf()))) {
m_solidBrush.ReleaseAndGetAddressOf());
if (FAILED(brushHr)) {
m_lastRenderError = HrToString("ID2D1HwndRenderTarget::CreateSolidColorBrush", brushHr);
DiscardRenderTarget();
return false;
}
m_renderTarget->SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE);
m_lastRenderError.clear();
return true;
}