r2 - 01 Mar 2009 - 22:51:01 - QiJinrongYou are here: TWiki >  Products Web > MiniGUIPGV204 > MiniGUIPGV204Chapter37

37 图标型控件

图标型(IconView)控件提供一个以图标加标签文字的方式供用户浏览条目的界面。这些图标项显示在可滚动的子窗口中,用户可通过键盘及鼠标操作来选中某一项或者多个项,选中的图标项通常高亮显示。图标型控件的典型用法是作为桌面图标的容器和目录下文件的显示。

使用 CTRL_ICONVIEW 作为控件类名称,可以通过CreateWindow函数调用创建图标型控件。

我们在创建图标型控件之后,可以通过发送相应的消息来添加、删除、设置图标尺寸(必须在添加该图标之前)和获取图标标签文字等。

37.1 图标型控件风格

默认状态下,图标型控件窗口只显示图标和其标签文字,显示区域的周围没有边界。你可以在以CreateWindow函数创建控件时使用窗口风格标识号WS_BORDER来为图标型控件加上边界。另外,还可以使用窗口风格 WS_VSCROLL 和 WS_HSCROLL来增加垂直和水平滚动条,以便用鼠标来滚动显示列表型控件中的各项内容。

图标型 控件是基于ScrollView控件上的,它保留了ScrollView控件的风格。

37.2 图标型控件消息

37.2.1 图标项的操作

在创建一个图标型控件之后,下一步通常需要往该控件中添加图标项,这是由应用程序向控件发送IVM_ADDITEM消息来完成的。
IVITEMINFO ivii;
SendMessage (hIconView, IVM_ADDITEM, 0, (LPARAM)&ivii) ;
其中,ivii是一个IVITEMINFO结构,用来表示所要设置的图标项的信息。IVITEMINFO结构定义以及各项意义如下:
typedef struct _IVITEMINFO
{
        /* 图标项的索引值 */
        int nItem;
        /* 图标项的图标 */
        PBITMAP bmp;
        /* 图标项的标签文字 */
        const char *label;
        /* 图标项的附加信息 */
        DWORD addData;
        /* 保留 */
        DWORD dwFlags;
} IVITEMINFO;
图标项的索引值表示了该项在父窗口的位置。添加成功后返回该图标项的句柄,否则返回0。

在添加图标项之前可以指定图标项的宽度和高度,所有的图标项都将以这个宽高度来显示。这是由IVM_SETITEMSIZE来完成的:

int width;
int height;
SendMessage (hIconView, IVM_SETITEMSIZE, width, height) ;
其中,width是要设置的宽度,height是要设置的高度。

因为图标型控件是基于ScrollView控件的,因此,图标型控件的其余各消息基本上和ScrollView消息一一对应:

  • IVM_RESETCONTENT:对应SVM_RESETCONTENT,用于清空图标型控件中的图标项。
  • IVM_DELITEM:对应SVM_DELITEM,用于删除图标型控件中的图标项。
  • IVM_SETITEMDRAW:对应SVM_SETITEMDRAW,用于设置图标项的绘制函数。
  • IVM_SETCONTWIDTH:对应SVM_SETCONTWIDTH,用于设置滚动窗口的宽度。
  • IVM_SETCONTHEIGHT:对应SVM_SETCONTHEIGHT,用于设置滚动窗口的高度。
  • IVM_SETITEMOPS:对应SVM_ SETITEMOPS,用于设置图标项相关操作的一些回调函数。
  • IVM_GETMARGINS:对应SVM_GETMARGINS,用于获取图标型控件的边缘范围值。
  • IVM_SETMARGINS:对应SVM_SETMARGINS,用于设置图标型控件的边缘范围值。
  • IVM_GETLEFTMARGIN、IVM_GETTOPMARGIN、IVM_GETRIGHTMARGIN和IVM_GETBOTTOMMARGIN分别对应SVM_GETLEFTMARGIN、SVM_GETTOPMARGIN、SVM_GETRIGHTMARGIN、SVM_GETBOTTOMMARGIN 用于获取图标型控件中的左、上、右、下边缘值。
  • IVM_GETCONTWIDTH、IVM_GETCONTHEIGHT、IVM_GETVISIBLEWIDTH和IVM_GETVISIBLEHEIGHT 分别对应SVM_GETCONTWIDTH、
SVM_GETCONTHEIGHT、SVM_GETVISIBLEWIDTH 和SVM_GETVISIBLEHEIGHT,用来获取内容区域的宽度和高度、可视区域的宽度和高度。
  • IVM_SETCONTRANGE:对应SVM_SETCONTRANGE,用于设置滚动窗口的内容区域的大小。
  • IVM_GETCONTENTX和IVM_GETCONTENTY分别对应SVM_GETCONTENTX和SVM_GETCONTENTY,用于获取内容区域的当前位置值。
  • IVM_SETCONTPOS:对应SVM_SETCONTPOS,用于设置内容区域的当前位置值,也就是在可视区域中移动内容区域到某个指定位置。
  • IVM_GETCURSEL和IVM_SETCURSEL分别对应SVM_GETCURSEL和SVM_SETCURSEL,用于获取和设置控件的当前高亮图标项。
  • IVM_SELECTITEM:对应SVM_SELECTITEM,用于选择一个列表项,被选中的项将高亮显示。
  • IVM_SHOWITEM:对应SVM_SHOWITEM,用于显示一个图标项。
  • IVM_CHOOSEITEM:对应SVM_CHOOSEITEM,是IVM_SELECTITEM和IVM_SHOWITEM消息的组合,用来选中一个图标项并使之可见。
  • IVM_SETITEMINIT:对应SVM_SETITEMINIT,用于设置图标项的初始操作。
  • IVM_SETITEMDESTROY:对应SVM_SETITEMDESTROY,用于设置图标项的销毁操作。
  • IVM_SETITEMCMP:对应SVM_SETITEMCMP,用于设置图标型控件图标项的比较函数。
  • IVM_MAKEPOSVISIBLE:对应SVM_MAKEPOSVISIBLE,用于使内容区域中的某个位置点成为可见。
  • IVM_GETHSCROLLVAL和IVM_GETVSCROLLVAL分别对应 SVM_GETHSCROLLVAL和SVM_GETVSCROLLVAL,用来获取滚动窗口的当前水平和垂直滚动值(点击滚动条箭头的滚动范围大小)。
  • IVM_GETHSCROLLPAGEVAL和IVM_GETVSCROLLPAGEVAL 分别对应SVM_GETHSCROLLPAGEVAL和SVM_GETVSCROLLPAGEVAL,用来获取滚动窗口的当前水平和垂直页滚动值(翻页操作时的滚动范围大小)。
  • IVM_SETSCROLLVAL:对应SVM_SETSCROLLVAL,用于设置滚动窗口的水平和(或者)垂直滚动值。
  • IVM_SETSCROLLPAGEVAL:对应SVM_SETSCROLLPAGEVAL,用于设置滚动窗口的水平和(或者)垂直页滚动值。
  • IVM_SORTITEMS:对应SVM_SORTITEMS,用于对图标项进行一次性的排序。
  • IVM_GETITEMCOUNT:对应SVM_GETITEMCOUNT,用于获取当前图标项的数量。
  • IVM_GETITEMADDDATA:对应SVM_GETITEMADDDATA,用于获取当前图标项的附加信息。
  • IVM_SETITEMADDDATA:对应SVM_SETITEMADDDATA,用于设置当前图标项的附加信息。
  • IVM_REFRESHITEM:对应SVM_REFRESHITEM,用于刷新一个图标项区域。
  • IVM_GETFIRSTVISIBLEITEM:对应SVM_GETFIRSTVISIBLEITEM,用于获取第一个可见的图标项。

37.3 控件通知码

图标型控件在响应用户点击等操作和发生某些状态改变时会产生通知消息,包括:
  • LVN_SELCHANGE:对应SVN_SELCHANGE,当前高亮图表项发生改变
  • LVN_CLICKED:对应SVN_CLICKED,用户点击图标项

应用程序需要使用SetNotificationCallback函数注册一个通知消息处理函数,在该函数中对收到的各个通知码进行应用程序所需的处理。

LVN_CLICKED和LVN_SELCHANGE通知消息处理函数传递的附加数据为被点击或者当前高亮的图标项句柄。

37.4 编程实例

清单 38.1 中的代码演示了使用图标型控件来构造一个简单的图标项浏览窗口。该程序的完整源代码可见本指南示例程序包 mg-samples 中的 iconview.c 程序。

清单 38.1 图标型控件示例程序
#define IDC_ICONVIEW    100
#define IDC_BT          200
#define IDC_BT2         300
#define IDC_BT3         400
#define IDC_BT4         500

#define IDC_ADD         600
#define IDC_DELETE      601

static HWND hIconView;

static BITMAP myicons [12];

static const char* iconfiles[12] =
{
        "./res/acroread.png",
        "./res/icons.png",
        "./res/looknfeel.png",
        "./res/package_games.png",
        "./res/tux.png",
        "./res/xemacs.png",
        "./res/gimp.png",
        "./res/kpilot.png",
        "./res/multimedia.png",
        "./res/realplayer.png",
        "./res/usb.png",
        "./res/xmms.png"
};

static const char *iconlabels[12] =
{
        "acroread",
        "icons",
        "looknfeel",
        "games",
        "tux",
        "xemacs",
        "gimp",
        "kpilot",
        "multimedia",
        "realplayer",
        "usb",
        "xmms"
};

static void myDrawItem (HWND hWnd, GHANDLE hsvi, HDC hdc, RECT *rcDraw)
{
        const PBITMAP pbmp = (PBITMAP)iconview_get_item_bitmap (hsvi);
        const char *label = (const char*)iconview_get_item_label (hsvi);
        
        SetBkMode (hdc, BM_TRANSPARENT);
        SetTextColor (hdc, PIXEL_black);
        
        if (iconview_is_item_hilight(hWnd, hsvi)) {
                SetBrushColor (hdc, PIXEL_blue);
        }
        else {
                SetBrushColor (hdc, PIXEL_lightwhite);
        }
        FillBox (hdc, rcDraw->left, rcDraw->top, RECTWP(rcDraw), RECTHP(rcDraw));
        SetBkColor (hdc, PIXEL_blue);
        
        if (label) {
                RECT rcTxt = *rcDraw;
                rcTxt.top = rcTxt.bottom - GetWindowFont (hWnd)->size * 2;
                rcTxt.left = rcTxt.left - (GetWindowFont (hWnd)->size) + 2;
                
                DrawText (hdc, label, -1, &rcTxt, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
        }
        FillBoxWithBitmap (hdc, rcDraw->left, rcDraw->top, 0, 0, pbmp);
}

static int
BookProc (HWND hDlg, int message, WPARAM wParam, LPARAM lParam)
{
        switch (message)
        {
                
                case MSG_INITDIALOG:
                {
                        IVITEMINFO ivii;
                        static int i = 0, j = 0;
                        
                        hIconView = GetDlgItem (hDlg, IDC_ICONVIEW);
                        SetWindowBkColor (hIconView, PIXEL_lightwhite);
                        //SendMessage (hIconView, IVM_SETITEMDRAW, 0, (LPARAM)myDrawItem);
                        SendMessage (hIconView, IVM_SETITEMSIZE, 55, 65);
                        //SendMessage (hIconView, IVM_SETITEMSIZE, 35, 35);
                        for (j = 0; j < 3; j ++) {
                                for (i = 0; i < TABLESIZE(myicons); i++) {
                                        memset (&ivii, 0, sizeof(IVITEMINFO));
                                        ivii.bmp = &myicons[i];
                                        ivii.nItem = 12 * j + i;
                                        ivii.label = iconlabels[i];
                                        ivii.addData = (DWORD)iconlabels[i];
                                        SendMessage (hIconView, IVM_ADDITEM, 0, (LPARAM)&ivii);
                                }
                        }
                        break;
                }
                
                case MSG_COMMAND:
                {
                        int id = LOWORD (wParam);
                        int code = HIWORD (wParam);
                        
                        switch (id) {
                                case IDC_ICONVIEW:
                                if (code == IVN_CLICKED) {
                                        int sel;
                                        sel = SendMessage (hIconView, IVM_GETCURSEL, 0, 0);
                                        printf ("clicking %d\n", sel);
                                }
                                break;
                                case IDC_ADD:
                                {
                                        IVITEMINFO ivii;
                                        char buff [10];
                                        int idx;
                                        int count = SendMessage (hIconView, IVM_GETITEMCOUNT, 0, 0);
                                        
                                        sprintf (buff, "NewIcon%i", count);
                                        memset (&ivii, 0, sizeof (IVITEMINFO));
                                        ivii.bmp = &myicons [0];
                                        ivii.nItem = count;
                                        ivii.label = buff;
                                        ivii.addData = (DWORD)"NewIcon";
                                        
                                        idx = SendMessage (hIconView, IVM_ADDITEM, 0, (LPARAM)&ivii);
                                        SendMessage (hIconView, IVM_SETCURSEL, idx, 1);
                                        break;
                                }
                                
                                case IDC_DELETE:
                                {
                                        int sel = SendMessage (hIconView, IVM_GETCURSEL, 0, 0);
                                        int count = SendMessage (hIconView, IVM_GETITEMCOUNT, 0, 0);
                                        char *label = NULL;
                                        
                                        if (sel >= 0){
                                                label = (char *) SendMessage (hIconView, IVM_GETITEMADDDATA, sel, 0); 
                                                if (label && strlen (label))
                                                printf ("delelete item:%s\n", label);
                                                SendMessage (hIconView, IVM_DELITEM, sel, 0);
                                                if (sel == count - 1)
                                                sel --;
                                                SendMessage (hIconView, IVM_SETCURSEL, sel, 1);
                                        }
                                        break;
                                }
                                
                        } /* end command switch */
                        break;
                }
                
                case MSG_KEYDOWN:
                if (wParam == SCANCODE_REMOVE) {
                        int cursel = SendMessage (hIconView, IVM_GETCURSEL, 0, 0);
                        
                        if (cursel >= 0){
                                SendMessage (hIconView, IVM_DELITEM, cursel, 0);
                                SendMessage (hIconView, IVM_SETCURSEL, cursel, 0);
                        }
                }
                break;
                
                case MSG_CLOSE:
                {
                        EndDialog (hDlg, 0);
                        return 0;
                }
                
        } /* end switch */
        
        return DefaultDialogProc (hDlg, message, wParam, lParam);
}

static CTRLDATA CtrlBook[] =
{
        {
                CTRL_ICONVIEW,
                WS_BORDER | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL,
                10, 10, 290, 300,
                IDC_ICONVIEW,
                "",
                0
        },
        {
                CTRL_BUTTON,
                WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON | WS_TABSTOP,
                90, 330, 50, 30,
                IDC_ADD,
                "Add",
                0
        },
        {
                CTRL_BUTTON,
                WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON,
                170, 330, 50, 30,
                IDC_DELETE,
                "Delete",
                0
        }
};

static DLGTEMPLATE DlgIcon =
{
        WS_BORDER | WS_CAPTION,
        WS_EX_NONE,
        0, 0, 310, 400,
        "My Friends",
        0, 0,
        TABLESIZE(CtrlBook), CtrlBook,
        0
};

38.1.jpeg
图 38.1 图标型控件

-- QiJinrong - 26 Feb 2009

Topic attachments
I Attachment Action Size Date Who Comment
jpgjpeg 38.1.jpeg manage 24.0 K 26 Feb 2009 - 14:54 QiJinrong  
Edit | Attach | Printable | Raw View | Backlinks: Web, All Webs | History: r2 < r1 | More topic actions
 
Powered by TWiki
This site is powered by the TWiki collaboration platformCopyright © by the Feynman Software and/or the contributing authors. All material on this collaboration platform is the property of Feynman Software and/or the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback