ListBox 的操作: MSDN - Listbox
首先 Win32 的 Control 就是預先寫好的小Dialog Window,所以要控制 Control Item ,只有用 SendMessage 的方式。
這種已經寫好的 Control (DialogWindow),每次要送message 過去,還要先從 ID 取得 hWnd 再送,有點麻煩,所以 Win32 提供一個直接對 ID 送 Message 的 function
SendDlgItemMessage
ListBox 的控制,用在 show log 的化,簡單的就是:
- 加入Item
- 移動 List
- 刪除 Item
- 加入 Item : LB_ADDSTRING
- 移動List : LB_SETTOPINDEX
- 刪除 Item : LB_DELETESTRING
ADDSTRING default 是作 "Append",所以剛好符合 log 的動作,從後面加上去。
ListBox 雖然有 scroll bar ,但是不會自己scroll 到最後,所以要用 LB_SETTOPINDEX 來指定第一個顯示的 item,好移動 scrollbar。
但是因為要讓最後一行對齊最後,所以反而要先用 LB_GETCOUNT 取得所有 item 的數量,自己減去 list 一面的 item 數好找到最後一頁的第一個 item 的 index...
以下就是簡單的 sample code,只有兩個 button - add, clear(all) 和一個 14 行的 list。
list 只保持 30 個 item,每按一下 add,就會加一行。
#include "stdafx.h"
#include <windows.h>
#include "ListBoxTest.h"
BOOL CALLBACK DialogProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
static int i=0;
switch (uMsg)
{
case WM_INITDIALOG:
return TRUE;
case WM_CLOSE:
EndDialog(hWnd,0);
return TRUE;
case WM_COMMAND:
switch(wParam)
{
case IDC_ADD :{
TCHAR outmsg[10];
swprintf(outmsg,_T("%d"),i++);
SendDlgItemMessage(hWnd,IDC_LIST1,LB_ADDSTRING,0,LPARAM(outmsg));
int cnt=SendDlgItemMessage(hWnd,IDC_LIST1,LB_GETCOUNT,0,0);
if(cnt>30)
SendDlgItemMessage(hWnd,IDC_LIST1,LB_DELETESTRING,0,0);
cnt=SendDlgItemMessage(hWnd,IDC_LIST1,LB_GETCOUNT,0,0);
if(cnt>=14)
SendDlgItemMessage(hWnd,IDC_LIST1,LB_SETTOPINDEX,cnt-14,0);
return TRUE;
}
case IDC_CLEAR:{
int cnt=SendDlgItemMessage(hWnd,IDC_LIST1,LB_GETCOUNT,0,0);
while(cnt-->0)
SendDlgItemMessage(hWnd,IDC_LIST1,LB_DELETESTRING,0,0);
return TRUE;
}
default:
return FALSE;
}
default:
return FALSE;
}
}
WTL 有包裝 ListBox,使用 WTL 的 example 是 http://realchecko.blogspot.com/2010/08/clistbox-listbox-control-in-wtl.html
3 則留言:
ListBox 中所 Show 的 ListItem 是使用 Stack Memory, ListItem 加到某種程度時有機會引發 Stack Overflow.
這樣呀...真是糟糕 >_<
張貼留言