MiniGUI - 列表型控件

CTRL_LISTVIEW
 
风格选项
LVS_TREEVIEW 以树型的方式来显示列表项
LVS_UPNOTIFY 指定鼠标点击操作的响应方式,默认情况下,如果没有指定 LVS_UPNOTIFY 风 格,列表型控件将在鼠标按下时发出通知消息;如果指定了该风格,控件将在鼠标抬起时发出通知消息
 
数据结构
typedef struct _LVCOLUMN
{
int nCols;     // 新增列的位置,如果小于0或者超出列次序范围则添加为最后一列
int width;     // 列宽
char *pszHeadText;    // 列的标题
int nTextMax;     // 列标题的最大长度
DWORD image;     // 列表头的图像,3.0为保留字段
PFNLVCOMPARE pfnCompare;     // 用于列排序的比较函数
DWORD colFlags;    // 列标志,LVCF_LEFTALIGN、LVCF_RIGHTALIGN 和 LVCF_CENTERALIGN,分别代表中文左对齐、居中、右对齐
} LVCOLUMN;
typedef LVCOLUMN *PLVCOLUMN;
 
列表项比较函数
typedef int (*PFNLVCOMPARE) (int nItem1, int nItem2, PLVSORTDATA sortData);    // sortData在3.0中没有意义
自定义字符串比较函数
typedef int (*STRCMP) (const char* s1, const char* s2, size_t n);
 
列表项
typedef struct _LVITEM
{
int nItem;    // 新增列表项的位置索引值,如果该值超出索引值范围的话,新增的项将被添加到列表的最后,如果 LVM_ADDITEM 消息 的 wParam 参数指定了新添节点的   
                    // 父节点,nItem 项所表示的位置值指的是新添节点在父节点中的位置
int nItemHeight;    //  列表项的高度
DWORD itemData;    // 列表项的附加数据
DWORD dwFlags;    // 列表项的状态, LVIF_FOLD,列表项可折叠
} LVITEM;
 
列表子项
typedef struct _LVSUBITEM
{
DWORD flags;    // 子项的标志,LVFLAG_BITMAP 和 LVFLAG_ICON
int nItem;     // 子项的垂直索引值
int subItem;    // 子项的水平索引值
char *pszText;     // 子项的文字内容
int nTextMax;    // 子项的文字长度
int nTextColor;    // 子项的文字颜色
DWORD image;    // 子项的图像
} LVSUBITEM;
typedef LVSUBITEM *PLVSUBITEM;
 
列表项查找信息
typedef struct _LVFINDINFO
{
DWORD flags;    // 查找标志,LVFF_TEXT和(或)LVFF_ADDDATA
int iStart;    // 查找的开始索引
int nCols;    // 表示匹配的列表项中前nCols列子项的文字内容要和pszInfo中的字符串一致
char **pszInfo;    // 查找的多个子项文字内容
DWORD addData;     // 列表项附加数据
int nItem;     // The found item's row, reserved
int nSubitem;    // The found subitem's column, reserved
} LVFINDINFO;
typedef LVFINDINFO *PLVFINDINFO;
 
 
消息
1. 列的操作
添加列: LVCOLUMN p; SendMessage (hwndListView, LVM_ADDCOLUMN, 0, (LPARAM)&p);
设置修改列属性:LVCOLUMN p; SendMessage (hwndListView, LVM_SETCOLUMN, 0, (LPARAM)&p);
设置列表头标题:LVCOLUMN p; SendMessage (hwndListView, LVM_MODIFYHEAD, 0, (LPARAM)&p); // 只需给出 nCols 和 pszHeadText 项的值
获取列属性:LVCOLUMN p; int nCols; SendMessage (hwndListView, LVM_GETCOLUMN, nCols, (LPARAM)&p);
获取列宽度:int width; int nCols; width = SendMessage (hwndListView, LVM_GETCOLUMNWIDTH, nCols, 0);
获取列数量:int count; count = SendMessage (hwndListView, LVM_GETCOLUMNCOUNT, 0, 0);
删除列:int nCols; SendMessage (hwndListView, LVM_DELCOLUMN, nCols, 0);
设置列表头高度:int newHeight; SendMessage (hwndListView, LVM_SETHEADHEIGHT, newHeight, 0);
 
2. 列表项操作
添加列表项:HLVITEM hItem; HLVITEM hParent; LVITEM lvItem; hItem = SendMessage (hwndListView, LVM_ADDITEM, hParent, (LPARAM)&lvItem);
获取列表项:LVITEM lvItem; HLVITEM hItem; SendMessage (hwndListView, LVM_GETITEM, hItem, (LPARAM)&lvItem);    // hItem 为目标列表型的句柄,如果 hItem 为 0,lvItem 结构的 nItem 域应该预设为所要获取的列表项的索引值
获取列表项数量:int count; count = SendMessage (hwndListView, LVM_GETITEMCOUNT, 0, 0);
获取列表项附加数据:DWORD addData; int nItem; HLVITEM hItem; addData = SendMessage (hwndListView, LVM_GETITEMADDDATA, nItem, hItem);
设置列表项附加数据:HLVITEM hItem; DWORD addData; SendMessage (hwndListView, LVM_SETITEMADDDATA, hItem, (LPARAM)addData);    // 如果设置成功,返回 LV_OKAY,否则返回 LV_ERR
设置列表项高度:HLVITEM hItem; int newHeight; SendMessage (hwndListView, LVM_SETITEMHEIGHT, hItem, newHeight);    // 如果设置成功,返回 TRUE,否则返 回 FALSE
删除一个列表项:HLVITEM hItem; int nItem;  SendMessage (hwndListView, LVM_DELITEM, nItem, hItem); 
删除所有列表项:SendMessage (hwndListView, LVM_DELALLITEM, 0, 0);
设置子项属性:LVSUBITEM subItem; HLVITEM hItem; SendMessage (hwndListView, LVM_SETSUBITEM, hItem, (LPARAM)&subItem);
获取子项文字:LVSUBITEM subItem; HLVITEM hItem; SendMessage (hwndListView, LVM_GETSUBITEMTEXT, hItem, (LPARAM)&subItem);
设置子项文字:LVSUBITEM subItem; HLVITEM hItem; SendMessage (hwndListView, LVM_SETSUBITEMTEXT, hItem, (LPARAM)&subItem); 
获取子项文字长度:LVSUBITEM subItem; HLVITEM hItem; int len; len = SendMessage (hwndListView, LVM_GETSUBITEMLEN, hItem, (LPARAM)&subItem);
 
选择列表项:int nItem; HLVITEM hItem; SendMessage (hwndListView, LVM_SELECTITEM, nItem, hItem);    // 选择的列表项不一定可见
获取被选中的列表项:HLVITEM hItemSelected; hItemSelected = SendMessage (hwndListView, LVM_GETSELECTEDITEM, 0, 0);
使列表项可见:HLVITEM hItem; int nItem; SendMessage (hwndListView, LVM_SHOWITEM, nItem, hItem);    // 成为可见区域中的第一个或最后一个可见条目,而且是 完全可见的
选中并使列表项可见:int nItem; HHLVITEM hItem; SendMessage (hwndListView, LVM_CHOOSEITEM, nItem, hItem);
查找列表项:HLVITEM hFound; HLVITEM hParent;  LVFINDINFO findInfo; hFound = SendMessage (hwndListView, LVM_FINDITEM, hParent, (LPARAM)&findInfo);
 
对列表项排序:SendMessage (hwndListView, LVM_SORTITEMS, 0, (LPARAM)pfnCompare);    // pfnCompare指向一个PFNLVCOMPARE类型的函数
依据某一列排序:int nCol; SendMessage (hwndListView, LVM_COLSORT, nCol, 0);
设置自定义字符串比较函数:SendMessage (hwndListView, LVM_SETSTRCMPFUNC, 0, (LPARAM)pfnStrCmp);    // 默认字符串比较函数是strcasecmp,pfnStrCmp指向STRCMP类型的函数
 
3. 树型节点的操作
获取相关节点:int related; HLVITEM hItem; HLVITEM hRelatedItem; hRelatedItem = SendMessage (hwndListView, LVM_GETRELATEDITEM, related, hItem); 
/*related 指定相关节点和目标节点的关系,包括:
• LVIR_PARENT:获取父节点
• LVIR_FIRSTCHILD:获取第一个子节点
• LVIR_NEXTSIBLING:获取下一个兄弟节点
• LVIR_PREVSIBLING:获取前一个兄弟节点*/
折叠或者展开一个包含子节点的节点项:HLVITEM hItem; BOOL bFold; SendMessage (hwndListView, LVM_FOLDITEM, bFold, hItem);    // bFold为TRUE的话折叠节点项,否则展开节点项
 
通知
1. 具有 LVS_NOTIFY 风格的列表框可能产生的通知消息
LVN_ITEMRDOWN:用户鼠标右键在列表项上按下
LVN_ITEMRUP:用户鼠标右键在列表项上抬起
LVN_HEADRDOWN:用户鼠标右键在表头上按下
LVN_HEADRUP:用户鼠标右键在表头上抬起
LVN_KEYDOWN:键按下
LVN_ITEMDBCLK:用户双击某个列表项
LVN_ITEMCLK:用户单击某个列表项(保留)
LVN_SELCHANGE:当前选择的列表项改变
LVN_FOLDED:用户鼠标点击某个列表项,使之折叠
LVN_UNFOLDED:用户鼠标点击某个列表项,使之展开
当用户鼠标右键在列表项上按下时,该项将被选中,并且产生LVN_SELCHANGE和LVN_ITEMRDOWN两个通知码
 
2. 使用SetNotificationCallback函数注册一个自定义的通知消息处理函数

 

mg-samples的列表型控件示例

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <string.h>
  4 #include <sys/stat.h>
  5 #include <sys/types.h>
  6 
  7 #include <minigui/common.h>
  8 #include <minigui/minigui.h>
  9 #include <minigui/gdi.h>
 10 #include <minigui/window.h>
 11 #include <minigui/control.h>
 12 
 13 #define IDC_LISTVIEW    10
 14 #define IDC_CTRL1       20
 15 #define IDC_CTRL2       30
 16 
 17 #define SUB_NUM      3
 18 
 19 #define COL_NR       TABLESIZE(caption)
 20 #define SCORE_NUM    TABLESIZE(scores)
 21 
 22 #define everage_score                    "Everage score" 
 23 #define getting_the_average_score        "Getting the average score"
 24 
 25 typedef struct _SCORE
 26 {
 27     char *name;
 28     int scr[SUB_NUM];
 29 } SCORE;
 30 
 31 static char * caption [] =
 32 {
 33     "Name", "Chinese", "Math", "English"
 34 };
 35 
 36 static char *classes [] =
 37 {
 38     "Grade 1", "Grade 2", "Grade 3"
 39 };
 40 
 41 static SCORE scores[] =
 42 {
 43     {"Tom", {81, 96, 75}},
 44     {"Jack", {98, 62, 84}},
 45     {"Merry", {79, 88, 89}},
 46     {"Bob", {79, 88, 89}},
 47 };
 48 
 49 static GHANDLE add_class_item (HWND hlist, PLVITEM lvItem, GHANDLE classent)
 50 {
 51     LVSUBITEM subdata;
 52     GHANDLE item = SendMessage (hlist, LVM_ADDITEM, classent, (LPARAM)lvItem);
 53 
 54     subdata.nItem = lvItem->nItem;
 55     subdata.subItem = 0;
 56     subdata.pszText = classes[lvItem->nItem];;
 57     subdata.nTextColor = PIXEL_black;
 58     subdata.flags = 0;
 59     subdata.image = 0;
 60     SendMessage (hlist, LVM_SETSUBITEM, item, (LPARAM) & subdata);
 61 
 62     return item;
 63 }
 64 
 65 static GHANDLE add_score_item (HWND hlist, PLVITEM lvItem, GHANDLE classent)
 66 {
 67     char buff[20];
 68     LVSUBITEM subdata;
 69     GHANDLE item = SendMessage (hlist, LVM_ADDITEM, classent, (LPARAM)lvItem);
 70     int i = lvItem->nItem;
 71     int j;
 72 
 73     subdata.flags = 0;
 74     subdata.image = 0;
 75     subdata.nItem = lvItem->nItem;
 76 
 77     for (j = 0; j < 4; j ++) {
 78         subdata.subItem = j;
 79         if (j == 0) {
 80             subdata.pszText = scores[i].name;
 81             subdata.nTextColor = PIXEL_black;
 82         }
 83         else {
 84             sprintf (buff, "%d", scores[i].scr[j-1]);
 85             subdata.pszText = buff;
 86             if (scores[i].scr[j-1] > 90)
 87                 subdata.nTextColor = PIXEL_red;
 88             else
 89                 subdata.nTextColor = PIXEL_black;
 90         }
 91         SendMessage (hlist, LVM_SETSUBITEM, item, (LPARAM) & subdata);
 92     }
 93 
 94     return item;
 95 }
 96 
 97 //#define CUSTOM_DRAW
 98 
 99 #ifdef CUSTOM_DRAW
100 
101 static void my_draw_hdr_bk (HWND hWnd, HLVHDR hlvhdr, HDC hdc, RECT *rcDraw)
102 {
103     SetBrushColor (hdc, PIXEL_yellow);
104     FillBox (hdc, rcDraw->left, rcDraw->top, RECTWP(rcDraw), RECTHP(rcDraw));
105 }
106 
107 static void my_draw_hdr_item (HWND hWnd, int idx, HDC hdc, RECT *rcDraw)
108 {
109     Rectangle (hdc, rcDraw->left, rcDraw->top, rcDraw->right, rcDraw->bottom);
110     SetBkMode (hdc, BM_TRANSPARENT);
111     TextOut (hdc, rcDraw->left+4, rcDraw->top+4, caption[idx]);
112 }
113 #endif
114 
115 static int
116 ScoreProc (HWND hDlg, int message, WPARAM wParam, LPARAM lParam)
117 {
118     HWND hListView;
119     hListView = GetDlgItem (hDlg, IDC_LISTVIEW);
120 
121     switch (message)
122     {
123 
124     case MSG_INITDIALOG:
125     {
126         int i, j;
127         LVITEM item;
128         LVCOLUMN lvcol;
129         GHANDLE hitem;
130 #ifdef CUSTOM_DRAW
131         LVCUSTOMDRAWFUNCS myfuncs = {my_draw_hdr_bk, my_draw_hdr_item};
132 
133         SendMessage (hListView, LVM_SETCUSTOMDRAW, 0, (LPARAM) &myfuncs);
134 #endif
135 
136         for (i = 0; i < COL_NR; i++) {
137             lvcol.nCols = i;
138             lvcol.pszHeadText = caption[i];
139             lvcol.width = 75;
140             lvcol.pfnCompare = NULL;
141             lvcol.colFlags = 0;
142             SendMessage (hListView, LVM_ADDCOLUMN, 0, (LPARAM) &lvcol);
143         }
144 
145         item.dwFlags &= ~LVIF_FOLD;
146         item.nItemHeight = 25;
147 
148         SendMessage (hListView, MSG_FREEZECTRL, TRUE, 0);
149         hitem = 0;
150         for (i = 0; i < 3; i++) {
151             item.nItem = i;
152             hitem = add_class_item (hListView, &item, 0);
153 
154             for (j = 0; j < SCORE_NUM; j++) {
155                 item.nItem = j;
156                 add_score_item (hListView, &item, hitem);
157             }
158 
159         }
160 
161         SendMessage (hListView, MSG_FREEZECTRL, FALSE, 0);
162         break;
163     }
164 
165     case MSG_COMMAND:
166     {
167         int id = LOWORD (wParam);
168         int i, j;
169 
170         if (id == IDC_CTRL2) {
171             float average = 0;
172             char buff[20];
173             for (i = 0; i < SCORE_NUM; i++) {
174                 for (j = 0; j < SUB_NUM; j++) {
175                     average += scores[i].scr[j];
176                 }
177             }
178             average = average / (SCORE_NUM * SUB_NUM);
179 
180             sprintf (buff, "%4.1f", average);
181             SendDlgItemMessage (hDlg, IDC_CTRL1, MSG_SETTEXT, 0, (LPARAM)buff);
182             printf("selected column%d\n", SendDlgItemMessage(hDlg, IDC_LISTVIEW,  LVM_GETSELECTEDCOLUMN, 0,0));
183         }
184         break;
185     }
186 
187     case MSG_CLOSE:
188     {
189         EndDialog (hDlg, 0);
190         break;
191     }
192 
193     }
194 
195     return DefaultDialogProc (hDlg, message, wParam, lParam);
196 }
197 
198 static CTRLDATA CtrlScore[] =
199 {
200     {
201         "button",
202         WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
203          110, 255, 100, 30,
204         IDC_CTRL2,
205         everage_score,
206         0
207     },
208     {
209         "edit",
210         WS_CHILD | WS_VISIBLE | WS_BORDER,
211          10, 260, 50, 20,
212         IDC_CTRL1,
213         "",
214         0
215     },
216     {
217         "listview",
218         /*WS_BORDER |*/ WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | LVS_TREEVIEW,
219          10, 10, 320, 220,
220         IDC_LISTVIEW,
221         "score table",
222         0
223     },
224 };
225 
226 static DLGTEMPLATE DlgScore =
227 {
228     WS_BORDER | WS_CAPTION,
229     WS_EX_NONE,
230     0, 0, 350, 340,
231     getting_the_average_score,
232     0, 0,
233     0, NULL,
234     0
235 };
236 
237 int MiniGUIMain (int argc, const char* argv[])
238 {
239 #ifdef _MGRM_PROCESSES
240     JoinLayer(NAME_DEF_LAYER , "listview" , 0 , 0);
241 #endif
242     
243     DlgScore.controls = CtrlScore;
244     DlgScore.controlnr = TABLESIZE(CtrlScore);
245     
246     DialogBoxIndirectParam (&DlgScore, HWND_DESKTOP, ScoreProc, 0L);
247 
248     return 0;
249 }
250 
251 #ifdef _MGRM_THREADS
252 #include <minigui/dti.c>
253 #endif

posted @ 2014-04-15 10:46  paullam  阅读(3290)  评论(0编辑  收藏  举报