2010年12月13日 星期一

取得螢幕 DPI 設定值

在寫 Windows 視窗軟體時,顯示文字資訊有幾項方法,
第一就是使用控制項例如 Static Text、Edit Control 等顯示文字訊息,
另一種很常用的就是將文字利用 DC.DrawText() 等方式畫在視窗上。

先前寫了一個小東西幫助客服人員收集用戶的資訊,
因為只是要列出現在正在儲存哪些設定,所以就簡單的在畫面上畫出資訊,
測試沒什麼問題,於是將工具寄給另一位同事幫忙在不同的環境跑跑看,
該同事說我畫在視窗上的資訊會超出視窗的大小,
查了以後發現原來我同事有老花的症狀 XD
他在 XP 下將文字顯示比例調為 120 DPI ,高於一般用戶預設的 96 DPI

於是就發生同一個軟體,我看起來在視窗上剛好可以畫 10 行資訊的,
在他的 PC 上由於字體會較大,同樣的軟體卻只能畫出 7.5 行,

當下沒有想到什麼好的解決方法,就只有針對用戶端的 DPI 去做動態調整字體大小,
使用 Windows API 取得用戶端螢幕 DPI 設定值的方法如下


DEVMODE dm;
dm.dmSize = sizeof(DEVMODE);
::EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm);
int nFontHeight = 0; // 字體高度
if(dm.dmLogPixels <= 96)
{
  // 一般預設值的用戶為 96 dpi
  nFontHeight = 15;
}
else if(dm.dmLogPixels > 96 && dm.dmLogPixels <= 120)
{
  // 我的老花同事
  nFontHeight = 13;
}
else
{
  // 再大就統一字 10 點字體
  nFontHeight = 10;
}

// Init LOGFONT m_logfontSet;
m_logfontSet.lfHeight = nFontHeight;
m_logfontSet.lfWidth = 0;
m_logfontSet.lfEscapement = 0;
m_logfontSet.lfOrientation = 0;
m_logfontSet.lfWeight = FW_NORMAL;
m_logfontSet.lfItalic = 0;
m_logfontSet.lfUnderline = 0;
m_logfontSet.lfStrikeOut = 0;
m_logfontSet.lfCharSet = DEFAULT_CHARSET;
m_logfontSet.lfOutPrecision = OUT_DEFAULT_PRECIS;
m_logfontSet.lfClipPrecision = CLIP_DEFAULT_PRECIS;
m_logfontSet.lfQuality = DEFAULT_QUALITY;
m_logfontSet.lfPitchAndFamily = FIXED_PITCH;
_tcscpy(m_logfontSet.lfFaceName, _T("Arial"));
m_fontSet.CreateFontIndirect(&m_logfontSet);


除了改變視窗上的字體外,改變視窗大小或許也是好方法,
或者是改用較簡單的 Edit Control 等控制項來裝資訊,
就可以自動產生 Scroll Bar ,超出控制項大小就產生捲軸供用戶翻頁,
除以上方法外,目前為止我想不到其他讓全部用戶看起來都好看的方法,
也許有更聰明的方法也說不定,以後想到再補上。

沒有留言:

張貼留言