青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

旅途

如果想飛得高,就該把地平線忘掉

Checkboxes in a Tree Control

Abstract

"Checkboxes in a tree control" shows how to add normal and three-state checkboxes to a tree control, and how to get notified when the checkbox changes. The sample project uses MFC, but the technique can easily be adapted to a Win32 or an ATL/WTL application.

Overview

The TreeView common control supports checkboxes since version 4.70 (distributed originally with Internet Explorer 3.0), and enabling this is supposedly easy- choose one of three:

  • use the Checkboxes option in dialog resource editor
  • specify the TVS_CHECKBOXES window style bit when creating the tree
  • Use
      treeCtrl.SetWindowStyle(0, TVS_CHECKBOXES)
    in MFC applications, or
      SetWindowLong(hwndTree, GWL_STYLE, GetWindowLong(hwndTree, GWL_STYLE) | TVS_CHECKBOXES);
    InvalidateRect(hwndTree, NULL, true)

    for Win32 applications. This must be done before the tree control is filled with items.

However, there are a few problems asociated with this:

  • How do I detect when the checkbox is changed
  • How (and when!) do I retrieve the current check state
  • How to use Three-State Checkboxes.

 

Tree Control Images

The tree control uses the state image list to implement the checkboxes. When the TVS_CHECKBOXES style is set, the tree control creates a custom state image list with the two state image buttons - unchecked & checked. When clicking on the state image, the tree control cycles through the state images.

Tree Control images: The  tree control uses two image lists: First, the 'normal' image list, with the images as they are specified in CTreeCtrl::InsertItem as nImage or nSelectedImage. (These parameters are the same as the nImage / nSelectedImage members of the TVITEM struct.) Second, there is the State image list: State images are displayed left beside the normal image. The currently displayed item is controled to the item's state mask, bits 12..15. To add to the confusion, some of the state images can be overlayed onto the "normal" images.

Retrieving and Setting State Images

void TreeCtrl_SetStateImage(CTreeCtrl & tree, HTREEITEM item, int stateImage)
            {
            tree.SetItemState(item, INDEXTOSTATEIMAGEMASK(stateImage), TVIS_STATEIMAGEMASK);
            }
int TreeCtrl_GetStateImage(CTreeCtrl & tree, HTREEITEM item)
            {
            return tree.GetItemState(item, TVIS_STATEIMAGEMASK) >> 12;
            }

Note that 0 indicates no state image; so you can use bool isChecked = (TreeCtrl_GetStateImage(...) - 1) != 0.

 

Three-State Check boxes

For three-state checkboxes, we just need to replace the default created state image list with our custom image list, windows will figure out the number of check states from the length of the image list. Remember that the first image (index 0) is unused. The sample uses the following Bitmap resource (IDB_STATEIMG in the sample):

checktree.gif (3735 bytes)

  • Add a member variable, CImageList m_ilState to the dialog
    (the image list must not be destroyed as long as the tree control is displayed)
  • In OnInitDialog, add the following:
    m_ilState.Create(IDB_STATEIMG /* resID of bitmap */,
                     16 /* width of single image */,    0 /* 0: the image list won't grow */,
                     RGB(255,255,255) /* transparent color */);
    m_treeCtrl.SetImageList(&m_ilState, TVSIL_STATE); // set state image list

The size of the bitmap affects the number of checkbox 'states'. To retrieve the current state, use TreeCtrl_GetStateImage(...) - 1. As with a checkbox, this value is 0 for unchecked, 1 for checked, and 2 for indeterminate.

This way, you could create a 'checkbox' with up to 15 states - which, on the other hand, ounds notlike fun for your users. More promising is the idea that you are not limited to checkboxes!

Being Notified when Checkbox changes

We want to know when the checkmark is clicked,so we can do something. The TreeView control does not send a separate notification, when item state changes, so we must manage both NM_CLICK wnd TVN_KEYDOWN message separately.

It's even trickier: When you get these notifications, the item state bits still indicates the old state. This wouldn't be as bad itself, but Microsoft might be tempted to change this behavior in the future. You can get the correct image (and thus, the current check state) when the current "Click" or "KeyDown"  message is completely handled. To do this, we can post a message to outselves, using PostMessage(some_unique_message_id, ..), and evaluating the new style there. With the message, I send the tree control ID in WPARAM (in case there are multiple tree controls in the dialog), and the item which has changed in LPARAM.

 

// .h:
            
            #define UWM_TV_CHECKBOX    WM_APP   // the custom message we post to ourself
            class CDlgOrWhatever
            {
            // ...
            CTreeCtrl    m_tree;
            afx_msg LRESULT OnTvCheckbox(WPARAM wp, LPARAM lp); // our message handler for the posted message
            };
// .cpp
            #include "windowsx.h"  // required for GET_X_LPARAM, GET_Y_LPARAM)
// ----- Message map ------
            BEGIN_MESSAGE_MAP(...)
            ON_MESSAGE(UWM_TV_CHECKBOX, OnTvCheckbox)
              // ... and, of course, the message handlers for NM_CLICK and TVN_KEYDOWN notifications
            END_MESSAGE_MAP()
// ----- NM_CLICK Message Handler: ------
            void CCheckTreeDlg::OnClickTree1(NMHDR* pNMHDR, LRESULT* pResult)
            {
            DWORD dw = GetMessagePos();                   // retrieve mouse cursor position when msg was sent
            CPoint p(GET_X_LPARAM(dw), GET_Y_LPARAM(dw)); // ..and put into point structure
            m_tree.ScreenToClient(&p);                    // make coords local to tree client area
            UINT htFlags = 0;
            HTREEITEM it = m_tree.HitTest(p, &htFlags);   // See where the click was on
            if (it != NULL && ( htFlags & TVHT_ONITEMSTATEICON)) {
                // the check box was hit - we just post a message for later processing
                PostMessage(UWM_TV_CHECKBOX, pNMHDR->idFrom, (LPARAM) it);
            }
            *pResult = 0;
            }
// ----- Handle checkbox changed here: ------
            LRESULT CCheckTreeDlg::OnTvCheckbox(WPARAM wp, LPARAM lp)
            {
            CTreeCtrl & tree = GetDlgItem(wp);  // if we have multiple trees
            HTREEITEM hitem = (HTREEITEM) lp;
            int checked = (tree.GetItemState(hitem, TVIS_STATEIMAGEMASK) >> 12) - 1;
              // "checked" now contains the check state.
            // the sample does the following:
              CString s = tree.GetItemText(hitem);
            if (checked==0) s += " unchecked";
            else if (checked==1) s+= " checked";
            else if (checked==2) s+= " dunno";
            else s+= " ???";
            SetDlgItemText(IDC_INFO, s);
            return 0;
            }
            

Notes:

19.2.2002: brushed up formatting. Fixed an alignment error in the resource bitmap 8the image on this page is still wrong, but that doesn#t mater much I guess). Added the TVN_KEYDOWN handler to the sample to catch the state change correctly when a key is hit.

30.11.2002: fiexd a bug in the OnClick Handler (thanks Michael!)

posted on 2007-07-18 16:49 旅途 閱讀(2683) 評論(0)  編輯 收藏 引用 所屬分類: 深入windows

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            **欧美日韩vr在线| 欧美日韩卡一卡二| 精久久久久久| 免费在线观看成人av| 蜜桃精品久久久久久久免费影院| 亚洲电影天堂av| 亚洲精品一区二区三区在线观看| 国产精品成人在线观看| 久久久久久久久综合| 美日韩精品免费观看视频| 99国产精品国产精品毛片| 亚洲愉拍自拍另类高清精品| 黄色欧美成人| 日韩一级视频免费观看在线| 国产欧美大片| 亚洲国产欧美一区| 欧美午夜精品一区| 久久综合久久综合久久| 欧美日韩三级电影在线| 久久久久国产精品厨房| 欧美激情综合亚洲一二区| 亚久久调教视频| 欧美freesex8一10精品| 欧美在现视频| 欧美日韩精品免费| 久久一区二区三区国产精品| 欧美日韩国产在线播放| 久久综合精品一区| 国产精品日韩在线一区| 亚洲第一网站免费视频| 国产欧美在线看| 亚洲精品久久久久中文字幕欢迎你| 国产美女精品免费电影| 日韩网站在线观看| 亚洲国内欧美| 久久精品亚洲| 午夜国产一区| 欧美日韩国语| 亚洲成人在线网站| 激情久久一区| 欧美亚洲视频一区二区| 亚洲影院色无极综合| 欧美黑人国产人伦爽爽爽| 玖玖综合伊人| 国产综合精品| 午夜视频在线观看一区| 亚洲欧美日韩直播| 欧美日韩国产二区| 亚洲黄色影院| 亚洲精品一区二区三区不| 久久久成人精品| 久久五月激情| 黑人巨大精品欧美一区二区 | 欧美伊人影院| 国产精品国产三级国产aⅴ浪潮 | 国产一区二区三区四区三区四| 99视频超级精品| 夜夜精品视频| 欧美精品三级日韩久久| 亚洲激情网址| 一区二区三区蜜桃网| 欧美激情二区三区| 最近中文字幕日韩精品| 亚洲精品在线免费| 欧美日韩伦理在线| 在线视频亚洲一区| 麻豆国产精品va在线观看不卡| 美女网站久久| 亚洲精品视频在线观看网站| 欧美韩日一区二区| aa日韩免费精品视频一| 午夜精品视频| 国产一区二区三区精品久久久| 久久久久国内| 亚洲电影免费观看高清完整版| 亚洲精品乱码久久久久久黑人| 欧美精品激情在线| 亚洲自拍偷拍福利| 麻豆国产精品va在线观看不卡| 亚洲激情一区二区| 欧美日韩一区二区在线观看视频| 亚洲一区在线播放| 久久久一区二区| 亚洲人成绝费网站色www| 欧美三级在线视频| 性欧美xxxx大乳国产app| 欧美成年人网站| 亚洲一二三区在线| 黄色日韩网站视频| 欧美日韩视频在线观看一区二区三区| 亚洲一区二区综合| 免费欧美视频| 亚洲欧美在线一区| 一区二区视频免费完整版观看| 欧美福利视频网站| 欧美亚洲网站| 亚洲欧洲日本一区二区三区| 亚洲女女做受ⅹxx高潮| 1769国产精品| 国产精品羞羞答答xxdd| 欧美成人精品在线| 亚洲综合视频网| 国产精品欧美日韩一区| 免费视频一区| 性欧美大战久久久久久久免费观看| 欧美国产免费| 久久久久久**毛片大全| 亚洲视频在线二区| 亚洲电影下载| 国产亚洲欧美色| 欧美日韩一二三四五区| 快射av在线播放一区| 亚洲男人的天堂在线aⅴ视频| 亚洲黄色片网站| 久久综合一区二区| 校园春色国产精品| 国产精品99久久久久久白浆小说| 在线日韩中文| 伊甸园精品99久久久久久| 国产精品美女久久久浪潮软件| 欧美精品在线一区| 免费视频最近日韩| 久久九九99视频| 欧美一区二区三区四区在线| 亚洲社区在线观看| 亚洲美女毛片| 日韩视频在线观看免费| 亚洲人成绝费网站色www| 男男成人高潮片免费网站| 久久久99久久精品女同性| 午夜精品福利在线观看| 亚洲一品av免费观看| 一区二区精品在线| 久久精品一区中文字幕| 欧美在线精品一区| 欧美在线观看天堂一区二区三区| 亚洲欧美日韩电影| 亚洲欧美制服中文字幕| 午夜电影亚洲| 小黄鸭视频精品导航| 欧美一区在线直播| 久久国产欧美| 久久深夜福利| 欧美国产先锋| 欧美日韩国产页| 国产精品美女999| 国产日韩在线亚洲字幕中文| 国内精品久久久| 精品福利免费观看| 亚洲日本一区二区| 日韩亚洲一区在线播放| 亚洲午夜国产成人av电影男同| 中文国产一区| 欧美中文字幕精品| 免费国产自线拍一欧美视频| 亚洲国产精品一区二区久| 亚洲人成网站色ww在线| 亚洲特黄一级片| 久久aⅴ乱码一区二区三区| 久久综合伊人| 欧美日韩一区二区三区在线看 | 欧美日韩精品在线| 国产精品高清网站| 国语自产精品视频在线看一大j8| 亚洲国产精品福利| 亚洲性夜色噜噜噜7777| 久久视频精品在线| 亚洲黄色一区二区三区| 亚洲一区在线直播| 久久亚洲电影| 国产精品qvod| 在线精品亚洲| 亚洲尤物视频网| 玖玖玖国产精品| 99视频精品全部免费在线| 久久er99精品| 欧美日韩一区二区三| 红桃视频国产一区| 亚洲午夜精品一区二区| 玖玖国产精品视频| 亚洲视频在线观看三级| 久久青草欧美一区二区三区| 欧美视频亚洲视频| 亚洲国产精品久久久久秋霞蜜臀| 亚洲综合视频一区| 欧美成人日本| 羞羞答答国产精品www一本| 欧美激情亚洲综合一区| 国产一区二区三区直播精品电影| av成人免费在线观看| 老司机亚洲精品| 亚洲欧美日韩精品久久久久| 欧美激情一区二区三区不卡| 狠狠色综合播放一区二区| 亚洲欧美变态国产另类| 亚洲欧洲一区二区天堂久久 | 欧美在线观看视频| 国产精品久久久久久久久动漫| 亚洲青涩在线| 欧美成人中文|