У меня проблема при рисовании как с GDI, так и с GDI + взаимозаменяемо.Преобразование страницы - в частности масштабирование - кажется, немного между этими двумя.Какие свойства контекста GDI влияют на масштабирование вывода, отличное от SetViewportExt
и SetWindowExt
?
Код использует почти исключительно GDI для рисования, но использует GDI + в некоторых случаях, когда его функции (полупрозрачность) необходимы.Он использует SetViewportExt
, SetWindowExt
и SetViewportOrg
для включения масштабирования и прокрутки.
Когда требуется GDI +, я создаю объект Gdiplus::Graphics
вокруг HDC и выполняю рисование.Я предполагаю, что это заставляет графический контекст обернуть контекст устройства и передать его рендеринг контексту устройства.Если я извлекаю матрицу преобразования графического контекста GDI +, я вижу, что это матрица идентичности, поэтому масштабирование выполняется в другом месте (в контексте устройства, я думаю).
Я разработал простой тест, в котором я рисуюодин и тот же массив прямоугольников с GDI и GDI +, чтобы быть уверенным, что все преобразования одинаковы в обоих случаях.Ниже приведен фрагмент кода:
CRect rect = ...;
// Draw the rectangle using GDI
CPen cpen(PS_DASH, 0, RGB(0,0,255));
pDC->SelectObject(&cpen);
pDC->Rectangle(rect);
{
// Draw the rectangle using GDI+
Gdiplus::Graphics graphics(pDC->m_hDC);
Gdiplus::Pen pen(Gdiplus::Color(180,180,180));
graphics.DrawRectangle(
&pen,
Gdiplus::Rect(rect.left, rect.top, rect.Width(), rect.Height()));
}
И вот результат: (синяя пунктирная линия нарисована GDI, а серая - GDI +)
Я ясно вижу, что две системы координат разные.Я ожидал некоторых ошибок округления, но не ошибки масштабирования, как показано здесь.Кроме того, когда я изменяю коэффициент масштабирования, GDI + перемещается в пределах ± 4 пикселя в обоих направлениях в зависимости от масштаба.Это также показано на скриншоте, так как прямоугольник GDI + имеет положительное смещение по оси X и отрицательное смещение по оси Y по сравнению с прямоугольником GDI.
Кто-нибудь знает, чточто здесь происходит?
Как мне заняться расследованием / отладкой этого?Это происходит в недрах окон, поэтому я, к сожалению, не могу его отладить.
Для справки, вот как выглядит мой viewport / window org / ext:
Window Ext: (134000, 80500)
Window Org: (0, 0)
Viewport Ext: (1452 872)
Viewport Org: (35 35)
Обновление:
Я исправил проблему, но это не красиво.Основной подход:
Возьмите две координаты (начальную и вторую подходящую точку) в пространстве экрана и преобразуйте их в логические координаты, используя GDI (функция DPtoLP
).
Сброс преобразования GDI на MM_TEXT
.
Используйте преобразованные точки для построения матрицы преобразования для GDI +, представляющей то же преобразование
И, наконец, используйте эту матрицу для построения контекста GDI + с правильным преобразованием.
Это что-то вроде хака, но это работает.Я до сих пор не знаю, почему между ними есть разница.По крайней мере, это показывает, что возможно иметь контекст GDI +, имитирующий преобразование GDI.