Скопируйте растровое изображение в буфер обмена в Win 10 с активным GDI Scaling - PullRequest
0 голосов
/ 23 февраля 2019

У меня есть настольное приложение MFC, которое генерирует графическое изображение, и я хочу, чтобы пользователь мог копировать его в буфер обмена как растровое изображение.Я использую стандартные процедуры буфера обмена API, и они до сих пор работали нормально.Однако теперь я активировал GDI Scaling (через манифест), чтобы программа могла работать (достаточно хорошо) на дисплеях HiDPI, и я обнаружил, что изображение, помещенное в буфер обмена, является только верхним левым квадрантом фактического изображения.Вероятно, это связано с внутренним масштабированием изображения - дисплей работает на 200%.Как мне скопировать все изображение?

1 Ответ

0 голосов
/ 23 февраля 2019

Ключ дан в ответе на предыдущий вопрос: Сохранение растровых изображений в Windows 10 с активным масштабированием GDI , но мне потребовалось некоторое время, чтобы адаптировать этот ответ к моей конкретной проблеме, поэтому я подумал:Поделюсь, если это будет полезно для других.(Отказ от ответственности - я не эксперт, поэтому могут быть лучшие способы ...)

bool CopyRectToClipboard(CWnd *pW, CRect rctCopy)
{
    if (!pW->OpenClipboard())
        return false;
    if (!EmptyClipboard())
        return false;

    CClientDC dc(pW);
    CDC dcMem;
    VERIFY(dcMem.CreateCompatibleDC(&dc));

    CBitmap bmTrial;    // need a trial bitmap to get GDI Scaled size
    VERIFY(bmTrial.CreateCompatibleBitmap(&dc, rctCopy.Width(), rctCopy.Height()));
// see /10426809/sohranenie-rastrovyh-izobrazhenii-v-windows-10-s-aktivnym-masshtabirovaniem-gdi
    BITMAPINFO bi = {};
    bi.bmiHeader.biSize = sizeof(bi);
    int result = GetDIBits(dc.GetSafeHdc(), (HBITMAP)bmTrial.GetSafeHandle(), 0, 0, NULL, &bi, DIB_RGB_COLORS);

    CBitmap bm;
    VERIFY(bm.CreateCompatibleBitmap(&dc, bi.bmiHeader.biWidth, bi.bmiHeader.biHeight));
    ASSERT(bm.m_hObject != NULL);
    CBitmap* pbmOld = dcMem.SelectObject(&bm);

    //dcMem.PatBlt(0, 0, bi.bmiHeader.biWidth, bi.bmiHeader.biHeight, WHITENESS);  // legacy
    VERIFY(dcMem.BitBlt(0, 0, bi.bmiHeader.biWidth, bi.bmiHeader.biHeight,
        &dc, rctCopy.left - 1, rctCopy.top - 1, SRCCOPY));

    HGDIOBJ hBM = bm.Detach();
    VERIFY(::EmptyClipboard());
    VERIFY(::SetClipboardData(CF_BITMAP, hBM));
    VERIFY(::CloseClipboard());

    dcMem.SelectObject(pbmOld);
    dcMem.DeleteDC();
    return true;
}


...