為什么要保證我們的軟件產(chǎn)品或應(yīng)用程序中的文本、圖像和字體、布局等問題呢,因?yàn)槲覀冇脩舻慕K端顯示設(shè)備通常型號(hào)和設(shè)置各異,如最近出現(xiàn)的16×9,低于8”的等最新款式移動(dòng)手提電腦,我們的應(yīng)用程序和軟件產(chǎn)品通常會(huì)在這樣的終端變得面目全非,而這顯然給用戶的使用帶來了嚴(yán)重的問題,直接導(dǎo)致的問題如:操作易用性Usability、功能可接近性Accessibility、文本可讀性Readability 等,而這樣的問題并非不可逾越,要解決如何讓我們的應(yīng)用程序在高分辨率的顯示下仍然保持正??梢?,重點(diǎn)需要解決四個(gè)方面的問題文本和字體、圖像(圖形、圖標(biāo)和鼠標(biāo)指針)、版面設(shè)置和重繪等。
前言
所有的應(yīng)用程序都可以工作在高分辨率下顯示嗎?答案當(dāng)然是否定的?,F(xiàn)在比較標(biāo)準(zhǔn)的計(jì)算機(jī)顯示器都已經(jīng)可以支持顯示大概96像素點(diǎn)/英寸的分辨率了,而且越來越多的應(yīng)用程序都可以運(yùn)行在這種分辨率下,但是卻仍然面臨分辨率日益增長(zhǎng)的帶來的危險(xiǎn)?,F(xiàn)在,我們可以輕松的買到一臺(tái)133-DPI顯示分辨率的筆記本電腦,甚至還有170DPI的,也許幾年以后200-DPI的顯示分辨率已經(jīng)隨處可見了,著名的工業(yè)雜志DisplaySearch曾經(jīng)預(yù)言在2002年底有40%的膝上電腦已經(jīng)超過100-DPI的屏幕分辨率了,而且這個(gè)數(shù)字還在增長(zhǎng)。
例圖 1.各種常見分辨率下字體外觀
例圖2. 改變分辨率帶來的影響
開發(fā)一個(gè)適應(yīng)多分辨率的應(yīng)用程序不是很簡(jiǎn)單,尤其對(duì)于一個(gè)已經(jīng)成形的應(yīng)用程序和系統(tǒng)來說,動(dòng)靜可能不小,但是它的好處是可以使我們不必再假設(shè)分辨率的各種情況,避免不能縮放帶來的質(zhì)量下降(比如說位圖和位圖字體),而且開發(fā)支持高分辨率的應(yīng)用程序有時(shí)候會(huì)覺得有些單調(diào)和乏味,但是如果我們的產(chǎn)品或應(yīng)用程序是為了服務(wù)于特定人群的(比如說視力不好、和需要長(zhǎng)時(shí)間工作的人以及視弱人群),那么我們的工作就會(huì)變得非常有必要(在高對(duì)比度下和使用擴(kuò)展大字體的情況都和高分辨率有關(guān))。
系統(tǒng)韻律
Windows平臺(tái)本身提供了幫助解決用戶系統(tǒng)高分辨率問題的解決途徑,我們可以通過一個(gè)小函數(shù)GetDeviceCaps()先獲得當(dāng)前的顯示分辨率,然后通過GetSystemMetrics()這個(gè)系統(tǒng)韻律函數(shù)和讀取系統(tǒng)信息和參數(shù)的SystemParametersInfo()函數(shù)提供的方法來改變windows中的圖形以及控件元素、和字體的尺寸,從一個(gè)3d的邊框效果乃至到一個(gè)小圖標(biāo)的尺寸,都可以隨心所欲的改變。
關(guān)鍵問題
在設(shè)計(jì)高分辨率的應(yīng)用程序過程中,我們要特別注意四個(gè)重要的方面:文本和字體、圖像(圖形、圖標(biāo)和鼠標(biāo)指針),版面設(shè)置以及重繪。
文本和字體
這里有兩種字體:位圖(光柵)字體和TrueType字體,而我們要想實(shí)現(xiàn)高分辨率的應(yīng)用程序就只能使用Truetype字體,因?yàn)槲粓D(光柵)字體只能在96-DPI的屏幕分辨率下正常,而且不能夠縮放,Windows已經(jīng)支持TrueType字體很長(zhǎng)時(shí)間了,所以找到一個(gè)很好的TrueType字體并且定義到我們的應(yīng)用系統(tǒng)中并不是什么大的問題,另外一個(gè)原因只能使用Truetype字體,因?yàn)橐恍┳钚碌募夹g(shù),比如說GDI+,但是它只支持Truetype字體的操作。
SendMessage (hwnd, WM_SETFONT, (WPARAM) font, 0);
SelectObject (hdc, font);
當(dāng)我們?cè)诖翱谏蟿?chuàng)建字體的時(shí)候,可以使用像素指定字體尺寸,然后調(diào)整分辨率。
Memset (&lf, 0, sizeof (lf));
lf.lfHeight = SCALEY (13);
HFONT font = CreateFontIndirect (&lf);
或者可以使用Windows API提供的選擇文字通用對(duì)話框,允許使用更準(zhǔn)確的像素點(diǎn)來指定字體尺寸,然后經(jīng)過一些算法后轉(zhuǎn)化字體尺寸為像素,可以指定只使用TrueType字體來顯示。
Memset (&data, 0, sizeof (data));
data.lStructSize = sizeof (data);
data.hwndOwner = form;
data.Flags = CF_TTONLY | CF_SCREENFONTS;
ChooseFont (&data);
最好的方法常常是在各種高分辨率下指定一個(gè)尺寸和一個(gè)區(qū)域的尺寸并且使用字體尺寸作為度量比例尺來指定這個(gè)頁面中的其它元素,比如說,可以設(shè)定按鈕之間的間距為缺省字體的高度的多少,使用GetTextMetrics()這個(gè)函數(shù)可以重新設(shè)定一個(gè)字體的高度。
TEXTMETRIC metrics;
GetTextMetrics (hdc, &metrics);
Int height = metrics.tmHeight;
最好不要使用TEXTMETRIC提供的tmAveCharWidth 方法,因?yàn)樗豢梢蕴幚碛⑽淖帜?,除此以外我們還可以使用GetTextExtent()的這個(gè)方法來確認(rèn)所關(guān)心的字符串的尺寸,我們可以用GetTextExtentPoint32()繪制一個(gè)環(huán)繞字符串的矩形,示例如下:
GetTextExtentPoint32 (hdc, string, strlen (string), &size);
Int paddingX = SCALEX (8);
Int paddingY = SCALEX (8);
Rectangle (hdc, x – paddingX, y – paddingY, x + size.cx
+ paddingX, y + size.cy + paddingY);
TextOut (hdc, x, y, string, strlen (string));
最后,我們意識(shí)到盡管TrueType字體縮放精細(xì),但是他們不是線性縮放,也就是說在DPI增加10%以后字符串的長(zhǎng)度不能正確的增加10%,(使用GDI+就沒有這個(gè)問題),因?yàn)橐恍┨囟ǖ淖帜钢荒茉趲讉€(gè)尺寸上看起來不錯(cuò),而TrueType卻可以自動(dòng)選擇一個(gè)近似的尺寸正確顯示,這是使用GetTextExtent這個(gè)函數(shù)的原因。
]]>