/* Make mem DC + mem bitmap */
HDC hdcScreen = ::GetDC(NULL);
HDC hDC = CreateCompatibleDC(hdcScreen);
// assume that m_nOriginalWidth & m_nOriginalHeight has been defined
HBITMAP hBmp = CreateCompatibleBitmap(hdcScreen, m_nOriginalWidth, m_nOriginalHeight);
HBITMAP hBmpOld = (HBITMAP)SelectObject(hDC, hBmp);
/* Draw background image */
if (m_pImgBackground)
m_pImgBackground->Draw(hDC, 0, 0);
/* Draw text */
CRect textRect(68, 10, 638, 50);
CImage *pTextImage = GreateTextImage(m_strWarnMessage, 14, L"Segoe UI", RGB(255, 255, 255), textRect, DT_LEFT | DT_NOFULLWIDTHCHARBREAK | DT_VCENTER | DT_WORDBREAK | DT_WORD_ELLIPSIS);
if (pTextImage)
{
pTextImage->Save(L"test.bmp"); // this file looks fine
pTextImage->TransparentBlt(hDC, textRect, RGB(0, 0, 0)); // when I draw this on DC, it looks not smooth
}
SAFEDELETE(pTextImage);
/* Call UpdateLayeredWindow */
BLENDFUNCTION blend = {0};
blend.BlendOp = AC_SRC_OVER;
blend.SourceConstantAlpha = m_nAlpha;
blend.AlphaFormat = AC_SRC_ALPHA;
POINT ptPos = {nDrawPositionX, nDrawPositionY};
SIZE sizeWnd = {nDrawWidth, nDrawHeight};
POINT ptSrc = {nDrawPositionX - nCurrentPositionX, nDrawPositionY - nCurrentPositionY};
::UpdateLayeredWindow(hwnd, hdcScreen, &ptPos, &sizeWnd, hDC, &ptSrc, 0, &blend, ULW_ALPHA);
// Assume the above code run well since I ignore some parameters
SelectObject(hDC, hBmpOld);
DeleteObject(hBmp);
DeleteDC(hDC);
::ReleaseDC(NULL, hdcScreen);
CImage* CDlgWarn::GreateTextImage(CString strText, int nFontSize, LPCWSTR pszFaceName, COLORREF crColor, const RECT &rect, DWORD dwFlags)
{
int nWidth = rect.right - rect.left;
int nHeight = rect.bottom - rect.top;
if (nWidth <= 0 || nHeight <= 0 || nFontSize <= 0)
return NULL;
if (pszFaceName == NULL)
return NULL;
/* Create Image */
CImage* pImage = new CImage();
if (!pImage)
return NULL;
if (!pImage->Create(nWidth, nHeight, 32))
{
SAFEDELETE(pImage);
return NULL;
}
HDC hDC = pImage->GetDC();
CDC *pDC = CDC::FromHandle(hDC);
pDC->SetBkMode(TRANSPARENT);
//pDC->SetBkColor(RGB(0, 0, 0));
pDC->SetTextColor(crColor);
/* Create font */
CFont font;
LOGFONT lf;
memset(&lf, 0, sizeof(LOGFONT));
lf.lfHeight = -MulDiv(nFontSize, GetDeviceCaps(hDC, LOGPIXELSY), 72);
wcscpy(lf.lfFaceName, pszFaceName);
VERIFY(font.CreateFontIndirect(&lf));
CFont* def_font = pDC->SelectObject(&font);
/* Calculate neccessary boundings */
RECT drawRect = {0, 0, nWidth, nHeight};
RECT tmpRect = drawRect;
dwFlags &= ~DT_CALCRECT;
if (!pDC->DrawText(strText, -1, &tmpRect, dwFlags | DT_CALCRECT))
{
font.DeleteObject();
pImage->ReleaseDC();
SAFEDELETE(pImage);
return NULL;
}
drawRect.top += (nHeight - (tmpRect.bottom - tmpRect.top)) / 2;
if (!pDC->DrawText(strText, -1, &drawRect, dwFlags))
{
font.DeleteObject();
pImage->ReleaseDC();
SAFEDELETE(pImage);
return NULL;
}
pDC->SelectObject(def_font);
// Done with the font. Delete the font object.
font.DeleteObject();
pImage->ReleaseDC();
return pImage;
}
LyogTWFrZSBtZW0gREMgKyBtZW0gYml0bWFwICovCkhEQyBoZGNTY3JlZW4gPSA6OkdldERDKE5VTEwpOwpIREMgaERDID0gQ3JlYXRlQ29tcGF0aWJsZURDKGhkY1NjcmVlbik7Ci8vIGFzc3VtZSB0aGF0IG1fbk9yaWdpbmFsV2lkdGggJiBtX25PcmlnaW5hbEhlaWdodCBoYXMgYmVlbiBkZWZpbmVkCkhCSVRNQVAgaEJtcCA9IENyZWF0ZUNvbXBhdGlibGVCaXRtYXAoaGRjU2NyZWVuLCBtX25PcmlnaW5hbFdpZHRoLCBtX25PcmlnaW5hbEhlaWdodCk7CkhCSVRNQVAgaEJtcE9sZCA9IChIQklUTUFQKVNlbGVjdE9iamVjdChoREMsIGhCbXApOwoKLyogRHJhdyBiYWNrZ3JvdW5kIGltYWdlICovCmlmIChtX3BJbWdCYWNrZ3JvdW5kKQoJbV9wSW1nQmFja2dyb3VuZC0+RHJhdyhoREMsIDAsIDApOwoKLyogRHJhdyB0ZXh0ICovCkNSZWN0IHRleHRSZWN0KDY4LCAxMCwgNjM4LCA1MCk7CkNJbWFnZSAqcFRleHRJbWFnZSA9IEdyZWF0ZVRleHRJbWFnZShtX3N0cldhcm5NZXNzYWdlLCAxNCwgTCJTZWdvZSBVSSIsIFJHQigyNTUsIDI1NSwgMjU1KSwgdGV4dFJlY3QsIERUX0xFRlQgfCBEVF9OT0ZVTExXSURUSENIQVJCUkVBSyB8IERUX1ZDRU5URVIgfCBEVF9XT1JEQlJFQUsgfCBEVF9XT1JEX0VMTElQU0lTKTsKaWYgKHBUZXh0SW1hZ2UpCnsKCXBUZXh0SW1hZ2UtPlNhdmUoTCJ0ZXN0LmJtcCIpOyAvLyB0aGlzIGZpbGUgbG9va3MgZmluZQoJcFRleHRJbWFnZS0+VHJhbnNwYXJlbnRCbHQoaERDLCB0ZXh0UmVjdCwgUkdCKDAsIDAsIDApKTsgLy8gd2hlbiBJIGRyYXcgdGhpcyBvbiBEQywgaXQgbG9va3Mgbm90IHNtb290aAp9ClNBRkVERUxFVEUocFRleHRJbWFnZSk7CgkKLyogQ2FsbCBVcGRhdGVMYXllcmVkV2luZG93ICovCkJMRU5ERlVOQ1RJT04gYmxlbmQgPSB7MH07CmJsZW5kLkJsZW5kT3AgPSBBQ19TUkNfT1ZFUjsKYmxlbmQuU291cmNlQ29uc3RhbnRBbHBoYSA9IG1fbkFscGhhOwpibGVuZC5BbHBoYUZvcm1hdCA9IEFDX1NSQ19BTFBIQTsKUE9JTlQgcHRQb3MgPSB7bkRyYXdQb3NpdGlvblgsIG5EcmF3UG9zaXRpb25ZfTsKU0laRSBzaXplV25kID0ge25EcmF3V2lkdGgsIG5EcmF3SGVpZ2h0fTsKUE9JTlQgcHRTcmMgPSB7bkRyYXdQb3NpdGlvblggLSBuQ3VycmVudFBvc2l0aW9uWCwgbkRyYXdQb3NpdGlvblkgLSBuQ3VycmVudFBvc2l0aW9uWX07Cjo6VXBkYXRlTGF5ZXJlZFdpbmRvdyhod25kLCBoZGNTY3JlZW4sICZwdFBvcywgJnNpemVXbmQsIGhEQywgJnB0U3JjLCAwLCAmYmxlbmQsIFVMV19BTFBIQSk7Ci8vIEFzc3VtZSB0aGUgYWJvdmUgY29kZSBydW4gd2VsbCBzaW5jZSBJIGlnbm9yZSBzb21lIHBhcmFtZXRlcnMKClNlbGVjdE9iamVjdChoREMsIGhCbXBPbGQpOwpEZWxldGVPYmplY3QoaEJtcCk7CkRlbGV0ZURDKGhEQyk7Cjo6UmVsZWFzZURDKE5VTEwsIGhkY1NjcmVlbik7CgoKQ0ltYWdlKiBDRGxnV2Fybjo6R3JlYXRlVGV4dEltYWdlKENTdHJpbmcgc3RyVGV4dCwgaW50IG5Gb250U2l6ZSwgTFBDV1NUUiBwc3pGYWNlTmFtZSwgQ09MT1JSRUYgY3JDb2xvciwgY29uc3QgUkVDVCAmcmVjdCwgRFdPUkQgZHdGbGFncykKewoJaW50IG5XaWR0aCA9IHJlY3QucmlnaHQgLSByZWN0LmxlZnQ7CglpbnQgbkhlaWdodCA9IHJlY3QuYm90dG9tIC0gcmVjdC50b3A7CglpZiAobldpZHRoIDw9IDAgfHwgbkhlaWdodCA8PSAwIHx8IG5Gb250U2l6ZSA8PSAwKQoJCXJldHVybiBOVUxMOwoKCWlmIChwc3pGYWNlTmFtZSA9PSBOVUxMKQoJCXJldHVybiBOVUxMOwoKCS8qIENyZWF0ZSBJbWFnZSAqLwoJQ0ltYWdlKiBwSW1hZ2UgPSBuZXcgQ0ltYWdlKCk7CglpZiAoIXBJbWFnZSkKCQlyZXR1cm4gTlVMTDsKCglpZiAoIXBJbWFnZS0+Q3JlYXRlKG5XaWR0aCwgbkhlaWdodCwgMzIpKQoJewoJCVNBRkVERUxFVEUocEltYWdlKTsKCQlyZXR1cm4gTlVMTDsKCX0KCUhEQyBoREMgPSBwSW1hZ2UtPkdldERDKCk7CglDREMgKnBEQyA9IENEQzo6RnJvbUhhbmRsZShoREMpOwoJcERDLT5TZXRCa01vZGUoVFJBTlNQQVJFTlQpOwoJLy9wREMtPlNldEJrQ29sb3IoUkdCKDAsIDAsIDApKTsKCXBEQy0+U2V0VGV4dENvbG9yKGNyQ29sb3IpOwoJLyogQ3JlYXRlIGZvbnQgKi8KCUNGb250IGZvbnQ7CglMT0dGT05UIGxmOwoJbWVtc2V0KCZsZiwgMCwgc2l6ZW9mKExPR0ZPTlQpKTsKCWxmLmxmSGVpZ2h0ID0gLU11bERpdihuRm9udFNpemUsIEdldERldmljZUNhcHMoaERDLCBMT0dQSVhFTFNZKSwgNzIpOwoJd2NzY3B5KGxmLmxmRmFjZU5hbWUsIHBzekZhY2VOYW1lKTsKCVZFUklGWShmb250LkNyZWF0ZUZvbnRJbmRpcmVjdCgmbGYpKTsKCUNGb250KiBkZWZfZm9udCA9IHBEQy0+U2VsZWN0T2JqZWN0KCZmb250KTsKCgkvKiBDYWxjdWxhdGUgbmVjY2Vzc2FyeSBib3VuZGluZ3MgKi8KCVJFQ1QgZHJhd1JlY3QgPSB7MCwgMCwgbldpZHRoLCBuSGVpZ2h0fTsKCVJFQ1QgdG1wUmVjdCA9IGRyYXdSZWN0OwoJZHdGbGFncyAmPSB+RFRfQ0FMQ1JFQ1Q7CglpZiAoIXBEQy0+RHJhd1RleHQoc3RyVGV4dCwgLTEsICZ0bXBSZWN0LCBkd0ZsYWdzIHwgRFRfQ0FMQ1JFQ1QpKQoJewoJCWZvbnQuRGVsZXRlT2JqZWN0KCk7CgkJcEltYWdlLT5SZWxlYXNlREMoKTsKCQlTQUZFREVMRVRFKHBJbWFnZSk7CgkJcmV0dXJuIE5VTEw7Cgl9CglkcmF3UmVjdC50b3AgKz0gKG5IZWlnaHQgLSAodG1wUmVjdC5ib3R0b20gLSB0bXBSZWN0LnRvcCkpIC8gMjsKCWlmICghcERDLT5EcmF3VGV4dChzdHJUZXh0LCAtMSwgJmRyYXdSZWN0LCBkd0ZsYWdzKSkKCXsKCQlmb250LkRlbGV0ZU9iamVjdCgpOwoJCXBJbWFnZS0+UmVsZWFzZURDKCk7CgkJU0FGRURFTEVURShwSW1hZ2UpOwoJCXJldHVybiBOVUxMOwoJfQoJcERDLT5TZWxlY3RPYmplY3QoZGVmX2ZvbnQpOwoJLy8gRG9uZSB3aXRoIHRoZSBmb250LiBEZWxldGUgdGhlIGZvbnQgb2JqZWN0LgoJZm9udC5EZWxldGVPYmplY3QoKTsKCXBJbWFnZS0+UmVsZWFzZURDKCk7CgoJcmV0dXJuIHBJbWFnZTsKfQ==