typedef struct {
TCHAR name[25];
BOOL gender;
UINT age;
TCHAR country[25];
TCHAR email[25];
} Contactors;
Contactors myCon[] = {
{_T("SINOASTEROID"), TRUE, 22, _T("CHINA"), _T("sinoasteroid@sina.com")},
{_T("SMITH"), TRUE, 21, _T("AMERICA"), _T("smith@gsoft.com")},
{_T("ROSE"), FALSE, 20, _T("GERMEN"), _T("rose@psoftware.com")},
{_T("LICHADE"), TRUE, 21, _T("KOREA"), _T("lich@korea.com")},
};
for (int i = 0; i < 4; i++) {
SendMessage(hList, LB_ADDSTRING, 0, (LPARAM)myCon[i].name);
}
switch (LOWORD(wParam)) {
case IDC_LIST1:
switch (HIWORD(wParam)) {
case LBN_SELCHANGE:
int nItem = SendMessage(hList, LB_GETCURSEL, 0, 0);
int nIndex = SendMessage(hList, LB_GETITEMDATA, nItem, 0);
// 取得對應資料並顯示
break;
}
break;
}
LB_GETCURSEL 取得目前選取項目索引(以 0 為基底),LB_GETITEMDATA 取得關聯資料(視風格而定)。
TCHAR tempBuffer[32];
_itot(myCon[nIndex].age, tempBuffer, 10); // 整數轉十進位字串
_gcvt(myCon[nIndex].aDouble, 3, tempBuffer); // 浮點數轉字串,3 位有效數字
TCHAR pathBuffer[256];
DWORD lenPath = GetCurrentDirectory(256, pathBuffer);
pathBuffer[lenPath] = _T('\\'); // 確保路徑結尾有反斜線
DlgDirList(hDlg, pathBuffer, IDC_LIST, IDS_PATH, DDL_DIRECTORY);
DDL_DIRECTORY 顯示目錄與檔案,亦可用 DDL_READONLY、DDL_HIDDEN 等旗標。
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDC_FILELIST:
if (HIWORD(wParam) == LBN_DBLCLK) {
DWORD nItem = SendMessage(hList, LB_GETCURSEL, 0, 0);
TCHAR lpText[256];
SendMessage(hList, LB_GETTEXT, nItem, (LPARAM)lpText);
SendMessage(hList, LB_DELETESTRING, nItem, 0);
}
break;
}
break;
int nItems = SendMessage(hList, LB_GETSELCOUNT, 0, 0);
int nBuffer[256];
int nItemsSel = SendMessage(hList, LB_GETSELITEMS, 256, (LPARAM)nBuffer);
if (nItemsSel > 256) { MessageBox(_T("選取項目過多")); return; }
TCHAR outChar[256];
for (int i = nItemsSel - 1; i >= 0; i--) {
SendMessage(hList, LB_GETTEXT, nBuffer[i], (LPARAM)outChar);
MessageBox(hDlg, outChar, outChar, MB_OK);
}
自繪製可顯示圖片、自訂項目高度。ComboBox 同理。
需設定 LBS_OWNERDRAWFIXED | LBS_HASSTRINGS。注意:LBS_OWNERDRAWFIXED 時 LB_ADDSTRING 加入的字串僅佔位,不顯示,需父視窗繪製。
void AddItem(HWND hList, LPSTR lpStr, HBITMAP hBmp) {
UINT nItem = SendMessage(hList, LB_ADDSTRING, 0, (LPARAM)lpStr);
SendMessage(hList, LB_SETITEMDATA, nItem, (LPARAM)hBmp); // 關聯位圖控制碼
}
LPMEASUREITEMSTRUCT lpMis = (LPMEASUREITEMSTRUCT)lParam;
lpMis->itemHeight = 48; // 設定項目高度 48 像素
return TRUE;
LPDRAWITEMSTRUCT lpDis = (LPDRAWITEMSTRUCT)lParam;
HDC hMem = CreateCompatibleDC(lpDis->hDC);
HBITMAP hTmpBmp = (HBITMAP)SendMessage(lpDis->hwndItem, LB_GETITEMDATA, lpDis->itemID, 0);
SelectObject(hMem, hTmpBmp);
// 繪製位圖
BitBlt(lpDis->hDC, lpDis->rcItem.left, lpDis->rcItem.top,
lpDis->rcItem.right, lpDis->rcItem.bottom, hMem, 0, 0, SRCCOPY);
DeleteDC(hMem);
上述程式碼應置於 ODA_DRAWENTIRE 條件下。
TCHAR tmpBuffer[256];
SendMessage(lpDis->hwndItem, LB_GETTEXT, lpDis->itemID, (LPARAM)tmpBuffer);
// 文字垂直置中於項目矩形內
TextOut(lpDis->hDC, 48, (lpDis->rcItem.top + lpDis->rcItem.bottom) / 2,
tmpBuffer, _tcslen(tmpBuffer));
ListBox 從簡單字串列表到檔案系統瀏覽、多重選取、自繪製圖文混排,靈活運用訊息機制與擁有者繪製技術,可構建豐富互動介面。掌握核心訊息(LB_ADDSTRING、LB_GETCURSEL、WM_MEASUREITEM、WM_DRAWITEM)與資料關聯(LB_SETITEMDATA/LB_GETITEMDATA)是關鍵。