首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

Win32 使用者介面設計基礎:ListBox 控制項完整應用指南

     編輯:VC 教學

一、簡易清單方塊設計

1. 結構體陣列儲存批次資料

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")},
};

2. 對話方塊初始化時填入項目

for (int i = 0; i < 4; i++) {
    SendMessage(hList, LB_ADDSTRING, 0, (LPARAM)myCon[i].name);
}

3. 捕獲通知訊息處理選取變更

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 取得關聯資料(視風格而定)。

4. 數值轉字串顯示

TCHAR tempBuffer[32];
_itot(myCon[nIndex].age, tempBuffer, 10);      // 整數轉十進位字串
_gcvt(myCon[nIndex].aDouble, 3, tempBuffer);  // 浮點數轉字串,3 位有效數字

二、使用 ListBox 顯示檔案清單

1. 取得目前目錄路徑

TCHAR pathBuffer[256];
DWORD lenPath = GetCurrentDirectory(256, pathBuffer);
pathBuffer[lenPath] = _T('\\'); // 確保路徑結尾有反斜線

2. 初始化對話方塊時填充列表

DlgDirList(hDlg, pathBuffer, IDC_LIST, IDS_PATH, DDL_DIRECTORY);

DDL_DIRECTORY 顯示目錄與檔案,亦可用 DDL_READONLY、DDL_HIDDEN 等旗標。

3. 雙擊選取項目並刪除

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;

三、多重選取清單方塊

1. 取得選取項目數量與索引

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; }

2. 迴圈處理各選取項目

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 同理。

1. 必備風格

需設定 LBS_OWNERDRAWFIXED | LBS_HASSTRINGS。注意:LBS_OWNERDRAWFIXED 時 LB_ADDSTRING 加入的字串僅佔位,不顯示,需父視窗繪製。

2. 自訂加入項目函數(附加位圖)

void AddItem(HWND hList, LPSTR lpStr, HBITMAP hBmp) {
    UINT nItem = SendMessage(hList, LB_ADDSTRING, 0, (LPARAM)lpStr);
    SendMessage(hList, LB_SETITEMDATA, nItem, (LPARAM)hBmp); // 關聯位圖控制碼
}

3. 處理 WM_MEASUREITEM 設定項目高度

LPMEASUREITEMSTRUCT lpMis = (LPMEASUREITEMSTRUCT)lParam;
lpMis->itemHeight = 48; // 設定項目高度 48 像素
return TRUE;

4. 處理 WM_DRAWITEM 繪製項目

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 條件下。

5. 繪製文字(關鍵在定位)

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)是關鍵。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved