為ListBox控制元件新增水平滾動條
阿新 • • 發佈:2019-01-26
Win32的標準控制元件之中,列表控制元件(ListBox)並沒有和列表檢視(ListView)一樣提供水平滾動條,所以如果列表項的長度超過列表的寬度的話,那麼超出的部分將無法顯示。在本文中我將以一個簡單的例子來說明如何使用SDK來解決這一問題,在這個例子中,我將為一個列表控制元件新增100行如下格式的文字:
case WM_INITDIALOG:
{
int i;
TCHAR str[100];
for(i = 0; i < 100; i++)
{
wsprintf(str, "This is a very very very very very long sentence - line %d", i + 1);
SendDlgItemMessage(hDlg, IDC_LIST, LB_ADDSTRING, 0, (LPARAM)str);
}
}
break;
當然,在新增水平滾動條之前,就是下圖這樣的效果:
下面為這個列表控制元件來新增水平滾動條,首先需要在資源的設計中為這個列表控制元件設定水平滾動條,然後就可以通過向列表控制元件傳送一條LB_SETHORIZONTALEXTENT訊息來向它新增水平滾動條了。在這條訊息的附加引數中,wParam引數就是以畫素為單位的水平滾動條長度,lParam不使用。那麼,可以為這個滾動條設定一個足夠的長度(假設為500),有以下的程式碼:
case WM_INITDIALOG: { HDC hdc; int i; TCHAR str[100]; for(i = 0; i < 100; i++) { wsprintf(str, "This is a very very very very very long sentence - line %d", i + 1); SendDlgItemMessage(hDlg, IDC_LIST, LB_ADDSTRING, 0, (LPARAM)str); } SendDlgItemMessage(hDlg, IDC_LIST, LB_SETHORIZONTALEXTENT, 500, 0); // 設定長度為500畫素的水平滾動條 } break; |
這段程式碼執行完畢後,效果如下圖:
如你所見,我們已經成功地為列表控制元件添加了水平滾動條。然而美中不足的是,500這一長度似乎太長,很不美觀。那麼我們所需要的,就是一種方法,我們能通過這種方法來將字串的長度換算成為一個適當的畫素長度,這樣就可以使這個介面較為美觀了。幸運的是,Win32 API之中的確有這麼一個函式:
BOOL GetTextExtentPoint32( HDC hdc, // 相關裝置控制代碼 LPCTSTR lpString, // 字串 int cbString, // 字串的字元數(即長度) LPSIZE lpSize // 用來接收字串的尺寸 ); |
也許你會很納悶:這個函式為什麼要和HDC扯上關係?其實原因很簡單:Windows是一個基於圖形的
case WM_INITDIALOG: { HDC hdc; SIZE s; int i; TCHAR str[100]; hdc = GetDC(hDlg); // 獲得相關裝置控制代碼 for(i = 0; i < 100; i++) { wsprintf(str, "This is a very very very very very long sentence - line %d", i + 1); GetTextExtentPoint32(hdc, str, lstrlen(str), &s); // 獲取字串的畫素大小 // 如果新的字串寬度大於先前的水平滾動條寬度,則重新設定滾動條寬度 if (s.cx > (LONG)SendDlgItemMessage(hDlg, IDC_LIST, LB_GETHORIZONTALEXTENT, 0, 0)) SendDlgItemMessage(hDlg, IDC_LIST, LB_SETHORIZONTALEXTENT, (WPARAM)s.cx, 0); SendDlgItemMessage(hDlg, IDC_LIST, LB_ADDSTRING, 0, (LPARAM)str); } ReleaseDC(hDlg, hdc); } break; |
看看效果吧:
你可能還會問,為什麼右邊的部分還有一點空白?對於這個問題,GetTextExtentPoint32的備註是這麼解釋的:“由於有的裝置緊縮字元,因此一個字串裡字元的範圍之和或許不等於字串的範圍,計算的字元寬度考慮了由SetTextCharacterExtra裝置的字元間隔。”
在MSDN中的列表控制元件訊息裡發現了LB_GETTEXTLEN這個訊息,它可以用來獲得列表項的字元長度。獲得列表項的畫素長度也許也能夠通過字元長度來換算。