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

旅途

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

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 旅途 閱讀(2704) 評論(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>
            奶水喷射视频一区| 欧美色图五月天| 激情偷拍久久| 免费观看日韩av| 免费观看成人网| 亚洲精品一二三区| 日韩网站免费观看| 国产精品久久久久毛片软件 | 欧美成人亚洲成人| 亚洲精品国产精品乱码不99 | 欧美高清不卡在线| 欧美国产第一页| 亚洲欧美日韩另类| 欧美一区二区视频网站| 亚洲国产精品电影| 亚洲麻豆av| 国内精品国产成人| 亚洲电影自拍| 国产精品a久久久久久| 欧美一区二区性| 久久综合影音| 亚洲女同精品视频| 久久久久久久久久看片| 日韩一二三区视频| 午夜一区二区三区不卡视频| 亚洲国产精品va在线观看黑人| 亚洲免费播放| 在线日韩av永久免费观看| 亚洲精品日韩在线| 黄色一区二区在线| 亚洲深夜福利| 亚洲国产高清在线| 亚洲一区二区av电影| 亚洲国产你懂的| 亚洲免费小视频| 一本色道久久综合亚洲二区三区| 亚洲欧美成人精品| 日韩视频在线观看免费| 久久久国产91| 欧美在线观看视频一区二区三区| 欧美高清不卡| 免费在线观看日韩欧美| 国产精品高潮视频| 亚洲国产成人精品久久| 国产一区二区三区免费观看| 亚洲日本中文字幕区| 在线欧美小视频| 欧美在线3区| 香蕉国产精品偷在线观看不卡| 欧美国产亚洲另类动漫| 蜜桃久久精品乱码一区二区| 国产精品天美传媒入口| 日韩一区二区高清| 日韩一级二级三级| 欧美国产在线电影| 亚洲大片在线| 亚洲国产精品一区二区久| 香蕉久久夜色| 午夜一区二区三视频在线观看| 欧美日韩国产一区二区| 亚洲电影在线播放| 亚洲欧洲日韩综合二区| 免费亚洲电影在线| 欧美激情第9页| 亚洲国产一区二区三区在线播| 久久久精品国产99久久精品芒果| 久久se精品一区精品二区| 国产精品你懂的在线欣赏| 国产精品99久久久久久宅男 | 中文高清一区| 欧美日韩成人综合天天影院| 亚洲日本中文字幕免费在线不卡| 亚洲日本理论电影| 欧美肥婆bbw| 亚洲精品专区| 性一交一乱一区二区洋洋av| 国产精品国码视频| 午夜精品区一区二区三| 久久精品日产第一区二区三区| 国产欧美日韩专区发布| 久久激情综合网| 欧美高清视频在线| 亚洲伦理自拍| 欧美视频在线观看 亚洲欧| 一区二区欧美亚洲| 亚洲欧美自拍偷拍| 国精品一区二区| 你懂的视频一区二区| 亚洲精品小视频| 午夜久久美女| 在线欧美亚洲| 欧美色图天堂网| 欧美影视一区| 亚洲电影下载| 欧美一区二区高清| 亚洲激情在线| 国产精品美女午夜av| 久久久噜噜噜久久中文字免 | 亚洲综合二区| 国产综合精品| 欧美精品在线免费| 亚洲欧美日韩精品久久亚洲区 | 99综合视频| 国产性天天综合网| 欧美韩日一区| 欧美诱惑福利视频| 亚洲精品久久7777| 久久精品在线播放| 在线亚洲欧美| 亚洲国产另类久久久精品极度| 欧美久久久久久久久| 欧美在线视频一区| 一区二区免费看| 免费看成人av| 亚洲欧美中日韩| 99综合电影在线视频| 精品粉嫩aⅴ一区二区三区四区| 欧美日韩调教| 欧美成人亚洲成人日韩成人| 欧美与欧洲交xxxx免费观看| 一本一本久久a久久精品综合妖精| 免费高清在线视频一区·| 亚洲专区欧美专区| 日韩一级大片在线| 亚洲高清免费在线| 黄色成人在线免费| 国产美女精品视频| 国产精品成人在线| 欧美日韩国产欧| 欧美大尺度在线| 六月丁香综合| 久久久一区二区| 欧美在线播放视频| 亚洲欧美日韩久久精品 | 欧美va亚洲va国产综合| 久久国产精品网站| 亚洲免费影视| 亚洲一级一区| 亚洲性av在线| 午夜精品久久久久久久白皮肤| 亚洲人成在线影院| 亚洲精品乱码久久久久久黑人| 亚洲承认在线| 亚洲人屁股眼子交8| 亚洲人成在线影院| 亚洲日韩欧美视频| 999亚洲国产精| 亚洲色图自拍| 欧美一级视频精品观看| 久久精品av麻豆的观看方式| 欧美有码视频| 久久美女性网| 免费日本视频一区| 欧美激情在线播放| 亚洲欧洲精品一区二区三区不卡 | 亚洲国产成人在线视频| 亚洲国产成人午夜在线一区| 欧美激情中文字幕一区二区| 欧美黄色日本| 99精品欧美一区二区三区 | 久久久www成人免费毛片麻豆| 久久久精品免费视频| 鲁大师影院一区二区三区| 欧美国产成人在线| 亚洲精品免费在线播放| 一区二区冒白浆视频| 欧美一级播放| 女同一区二区| 国产精品久久一区主播| 国产欧美亚洲一区| 在线观看亚洲a| 99在线精品免费视频九九视| 亚洲欧美日韩成人| 裸体素人女欧美日韩| 欧美激情久久久久| 亚洲专区国产精品| 免费亚洲电影在线观看| 国产精品mm| 国产一区二区三区最好精华液| 亚洲国产专区| 欧美亚洲视频在线看网址| 欧美顶级少妇做爰| 亚洲一品av免费观看| 久热精品视频在线观看| 国产精品第一页第二页第三页| 黄色成人av网站| 亚洲在线观看| 欧美激情亚洲| 香港成人在线视频| 欧美日韩成人一区二区| 一区二区三区在线免费观看| 在线性视频日韩欧美| 麻豆国产精品777777在线 | 欧美激情一区二区三区不卡| 亚洲一区二区三区乱码aⅴ| 免费观看成人鲁鲁鲁鲁鲁视频 | 欧美激情成人在线| 国内精品久久久久久 | 免费日韩av| 亚洲一区影院|