Я знаю место где она может быть, но что бы я не пробовал применить туда, утечка не пропадает.
Происходит в методе resize()
где производится перерасчет rect
для отрисовки текста, при всем при этом я уже было подумал сделать отдельный класс для управления указателями, т.к. ни один из указателей из библиотеки std
не помог.
Вот сам кусок кода в котором по моему мнению происходит утечка:
void graphics::resize()
{
IDWriteTextLayout* layout;
GetClientRect(window_handle_, &window_rect_);
InvalidateRect(window_handle_, &window_rect_, false);
HRESULT result = dwrite_factory_->CreateTextLayout(copy_of_str_.c_str(),
copy_of_str_.length(),
dw_text_format_,
window_rect_.right - window_rect_.left,
window_rect_.bottom - window_rect_.top, reinterpret_cast<IDWriteTextLayout**>(&layout));
check_hr(result);
result = hwnd_render_target_->Resize(D2D1::SizeU(window_rect_.right - window_rect_.left,
window_rect_.bottom - window_rect_.top));
DWRITE_TEXT_METRICS met;
layout->GetMetrics(&met);
metrycs_ = met;
if (FAILED(result))
{
_com_error err = result;
MessageBoxW(window_handle_, err.ErrorMessage(), L"Error", MB_OK | MB_ICONERROR);
return;
}
std::wstringstream string_stream;
string_stream << L"Client size — Width: " << window_rect_.right - window_rect_.left << ", Height: " << window_rect_.
bottom - window_rect_.top;
copy_of_str_ = string_stream.str();
render();
layout->Release();
}
Так же ниже приведу полный код класса.
#pragma once
#include <d2d1.h>
#include <dwrite.h>
#include <map>
#include <string>
#include "button_base.h"
class graphics
{
public:
struct dpi_data { float x; float y; };
private:
gui::button_base* button_;
ID2D1Factory* factory_;
ID2D1HwndRenderTarget* hwnd_render_target_;
ID2D1RenderTarget* render_target_;
IDWriteTextLayout* dwrite_text_layout_;
IDWriteTextFormat* dw_text_format_;
IDWriteFactory* dwrite_factory_;
ID2D1SolidColorBrush* black_brush_;
HWND window_handle_;
RECT window_rect_;
dpi_data current_dpi_data_;
std::map<std::wstring, IDWriteTextFormat*> fonts_;
static bool check_hr(HRESULT hr);
DWRITE_TEXT_METRICS metrycs_;
std::wstring copy_of_str_;
public:
graphics();
~graphics();
bool init(HWND hwnd);
void begin_draw() const;
void end_draw() const;
void render();
IDWriteTextFormat* get_text_format(std::wstring font_name);
void draw_text(std::wstring font_name, std::wstring text, int x, int y) const;
void resize();
dpi_data get_dpi_data();
};
#include "graphics.h"
#include <comdef.h>
#include <locale>
#include <vector>
#include <algorithm>
#include <sstream>
#include <memory>
bool graphics::check_hr(HRESULT hr)
{
if (FAILED(hr))
{
_com_error err = hr;
MessageBoxW(nullptr, err.ErrorMessage(), L"Error", MB_OK | MB_ICONERROR);
return false;
}
return true;
}
graphics::graphics() : button_(nullptr), factory_(nullptr), hwnd_render_target_(nullptr), render_target_(nullptr),
dwrite_text_layout_(nullptr), dw_text_format_(nullptr),
dwrite_factory_(nullptr),
black_brush_(nullptr), window_handle_(nullptr)
{
window_rect_ = {0,0,0,0};
}
graphics::~graphics()
{
if (black_brush_)
{
black_brush_->Release();
black_brush_ = nullptr;
}
if (factory_)
{
factory_->Release();
factory_ = nullptr;
}
if (hwnd_render_target_)
{
hwnd_render_target_->Release();
hwnd_render_target_ = nullptr;
}
if (!fonts_.empty())
{
for (auto font : fonts_)
{
font.second->Release();
}
fonts_.clear();
}
if (dwrite_text_layout_)
{
dwrite_text_layout_->Release();
dwrite_text_layout_ = nullptr;
}
if (dwrite_factory_)
{
dwrite_factory_->Release();
dwrite_factory_ = nullptr;
}
}
bool graphics::init(const HWND hwnd)
{
window_handle_ = hwnd;
HRESULT result = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &factory_);
if (!check_hr(result))
{
return false;
}
RECT rect;
GetClientRect(window_handle_, &rect);
result = factory_->CreateHwndRenderTarget(D2D1::RenderTargetProperties(),
D2D1::HwndRenderTargetProperties(
window_handle_,
D2D1::SizeU(rect.right - rect.left, rect.bottom - rect.top)),
&hwnd_render_target_);
if (!check_hr(result))
{
return false;
}
result = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(dwrite_factory_),
reinterpret_cast<IUnknown **>(&dwrite_factory_));
if (!check_hr(result))
{
return false;
}
result = dwrite_factory_->CreateTextFormat(L"Ubuntu", nullptr, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL,
DWRITE_FONT_STRETCH_NORMAL, 14, L"", &dw_text_format_);
if (!check_hr(result))
{
return false;
}
result = dw_text_format_->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_NEAR);
if (!check_hr(result))
{
return false;
}
result = dw_text_format_->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_NEAR);
if (!check_hr(result))
{
return false;
}
result = hwnd_render_target_->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Gray), &black_brush_);
if (!check_hr(result))
{
return false;
}
GetClientRect(window_handle_, &window_rect_);
get_dpi_data();
button_ = new gui::button_base(&hwnd_render_target_, &dwrite_factory_, L"Button Text", &dw_text_format_);
button_->init(10, 10, 0, 0, {5,5,5,5});
std::wstringstream string_stream;
string_stream << L"Client size — Width: " << window_rect_.right - window_rect_.left << ", Height: " << window_rect_.
bottom - window_rect_.top;
copy_of_str_ = string_stream.str();
resize();
return true;
}
void graphics::begin_draw() const
{
hwnd_render_target_->BeginDraw();
}
void graphics::end_draw() const
{
hwnd_render_target_->EndDraw();
}
void graphics::render()
{
begin_draw();
hwnd_render_target_->Clear(D2D1::ColorF(D2D1::ColorF::WhiteSmoke));
draw_text(L"ubuntu", copy_of_str_, (window_rect_.right - window_rect_.top) - metrycs_.width - 10, 10);
draw_text(L"ubuntu", L"Text Clipped to left bottom. Test Unicode: 特にあなたのために。", 10,
window_rect_.bottom - window_rect_.top - 25);
button_->draw();
end_draw();
}
IDWriteTextFormat* graphics::get_text_format(const std::wstring font_name)
{
const std::map<std::wstring, IDWriteTextFormat*>::iterator it = std::find_if(
fonts_.begin(), fonts_.end(), [&](const std::pair<const std::wstring, IDWriteTextFormat*>& p)
{
return p.first == font_name && p.second != nullptr;
});
if (it != fonts_.end())
{
return (*it).second;
}
return nullptr;
}
void graphics::draw_text(const std::wstring font_name, std::wstring text, const int x, const int y) const
{
hwnd_render_target_->DrawTextW(text.c_str(), text.length(), dw_text_format_,
D2D1::RectF(float(x), float(y), window_rect_.right, window_rect_.bottom), black_brush_,
D2D1_DRAW_TEXT_OPTIONS_CLIP);
}
void graphics::resize()
{
IDWriteTextLayout* layout;
GetClientRect(window_handle_, &window_rect_);
InvalidateRect(window_handle_, &window_rect_, false);
HRESULT result = dwrite_factory_->CreateTextLayout(copy_of_str_.c_str(),
copy_of_str_.length(),
dw_text_format_,
window_rect_.right - window_rect_.left,
window_rect_.bottom - window_rect_.top, reinterpret_cast<IDWriteTextLayout**>(&layout));
check_hr(result);
result = hwnd_render_target_->Resize(D2D1::SizeU(window_rect_.right - window_rect_.left,
window_rect_.bottom - window_rect_.top));
DWRITE_TEXT_METRICS met;
layout->GetMetrics(&met);
metrycs_ = met;
if (FAILED(result))
{
_com_error err = result;
MessageBoxW(window_handle_, err.ErrorMessage(), L"Error", MB_OK | MB_ICONERROR);
return;
}
std::wstringstream string_stream;
string_stream << L"Client size — Width: " << window_rect_.right - window_rect_.left << ", Height: " << window_rect_.
bottom - window_rect_.top;
copy_of_str_ = string_stream.str();
render();
layout->Release();
}
graphics::dpi_data graphics::get_dpi_data()
{
dpi_data tmpp;
memset(&tmpp, 0, sizeof(dpi_data));
factory_->GetDesktopDpi(&tmpp.x, &tmpp.y);
current_dpi_data_ = tmpp;
return current_dpi_data_;
}
Ну, вот, например, возможность для утечки.
Вы создаёте layout
через CreateTextLayout
, затем переписываете result
возвращаемым значением hwnd_render_target_->Resize
. Если это возвращаемое значение не пройдёт проверку if (FAILED(result))
, вы выходите из функции, не освободив layout
.
Оборудование для ресторана: новинки профессиональной кухонной техники
Частный дом престарелых в Киеве: комфорт, забота и профессиональный уход
При наведении на ссылку из главного меню, загорается подсветка, но при отведения мыши от этой ссылки подсветка исчезаетКак сделать так что...
Подскажите, пожалуйста самый простой способ выбрать 3-х потомков от одинаковых родителейПриведу пример
ПриветНе могу понять как сделать так, чтобы поверх изображения отцентрировать текст относительно самого изображения, чтобы при ресайзе...