#include "stdafx.h" #include "DLUConv.h" static int _GetAverageCharacterDimension(HDC hdc, BYTE bX) { // "How To Calculate Dialog Base Units with Non-System-Based Font" // http://support.microsoft.com/kb/125681/EN-US int result = 0; TEXTMETRIC tm = {0}; BYTE br = (GetTextMetrics(hdc, &tm) != 0); if(br) { static const WCHAR s[] = L"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; size_t length = sizeof(s) / sizeof(WCHAR); SIZE size = {0}; if((br = GetTextExtentPoint32(hdc, s, length, &size))) result = (bX ? (size.cx / (length >> 1) + 1) >> 1 : tm.tmHeight); } return result; } inline int _Convert(HFONT hFont, int value, BYTE bX, int (*pf)(HDC, int, BYTE)) { int result = 0; HWND hwnd = 0; HDC hdc = GetDC(hwnd); if(hdc) { HGDIOBJ hFontOld = SelectObject(hdc, (HGDIOBJ)hFont); if(hFontOld) { result = (pf)(hdc, value, bX); SelectObject(hdc, hFontOld); } ReleaseDC(hwnd, hdc); } return result; } inline int _Convert(const LOGFONT &crlf, int value, BYTE bX, int (*pf)(HFONT, int, BYTE)) { int result = 0; HFONT hFont = CreateFontIndirect(&crlf); if(hFont) { result = (*pf)(hFont, value, bX); DeleteObject((HGDIOBJ)hFont); } return result; } ///////////////////////////////////////////////////////////////////////////////////////////// inline int _DLU2Px(HDC hdc, int cDLU, BYTE bX) { return MulDiv(cDLU, _GetAverageCharacterDimension(hdc, bX), (bX ? 4 : 8)); } inline int _DLU2Px(HFONT hFont, int cDLU, BYTE bX) { return _Convert(hFont, cDLU, bX, _DLU2Px); } inline int _DLU2Px(const LOGFONT &crlf, int cDLU, BYTE bX) { return _Convert(crlf, cDLU, bX, _DLU2Px); } inline int _Px2DLU(HDC hdc, int cPx, BYTE bX) { return MulDiv(cPx, (bX ? 4 : 8), _GetAverageCharacterDimension(hdc, bX)); } inline int _Px2DLU(HFONT hFont, int cPx, BYTE bX) { return _Convert(hFont, cPx, bX, _Px2DLU); } inline int _Px2DLU(const LOGFONT &crlf, int cPx, BYTE bX) { return _Convert(crlf, cPx, bX, _Px2DLU); } ///////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////// int DLUConv::DLU2PxX(const LOGFONT &crlf, int cxDLU) { return _DLU2Px(crlf, cxDLU, 1); } int DLUConv::DLU2PxX(HFONT hFont, int cxDLU) { return _DLU2Px(hFont, cxDLU, 1); } int DLUConv::DLU2PxX(HDC hdc, int cxDLU) { return _DLU2Px(hdc, cxDLU, 0); } int DLUConv::DLU2PxY(const LOGFONT &crlf, int cyDLU) { return _DLU2Px(crlf, cyDLU, 0); } int DLUConv::DLU2PxY(HFONT hFont, int cyDLU) { return _DLU2Px(hFont, cyDLU, 0); } int DLUConv::DLU2PxY(HDC hdc, int cyDLU) { return _DLU2Px(hdc, cyDLU, 0); } int DLUConv::Px2DLUX(const LOGFONT &crlf, int cxPx) { return _Px2DLU(crlf, cxPx, 1); } int DLUConv::Px2DLUX(HFONT hFont, int cxPx) { return _Px2DLU(hFont, cxPx, 1); } int DLUConv::Px2DLUX(HDC hdc, int cxPx) { return _Px2DLU(hdc, cxPx, 1); } int DLUConv::Px2DLUY(const LOGFONT &crlf, int cyPx) { return _Px2DLU(crlf, cyPx, 0); } int DLUConv::Px2DLUY(HFONT hFont, int cyPx) { return _Px2DLU(hFont, cyPx, 0); } int DLUConv::Px2DLUY(HDC hdc, int cyPx) { return _Px2DLU(hdc, cyPx, 0); }