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

旅途

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

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 旅途 閱讀(2693) 評論(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>
            欧美精品在线观看91| 欧美日韩国产小视频在线观看| 亚洲欧美日韩中文视频| 欧美刺激性大交免费视频| 国产综合在线看| 欧美一区二区三区日韩| 99精品福利视频| 狂野欧美一区| 亚洲激情专区| 亚洲黄色一区二区三区| 玖玖精品视频| 亚洲精品久久久久久久久久久久| 久久男人av资源网站| 欧美中日韩免费视频| 国产一区二区精品久久91| 久久精品视频在线观看| 欧美在线地址| 在线成人性视频| 欧美国产视频日韩| 欧美精品一区二区三区蜜桃| 亚洲一二三区视频在线观看| 亚洲天堂第二页| 国产日韩精品一区观看 | 欧美在线看片| 午夜视频久久久| 黑人中文字幕一区二区三区 | 亚洲在线视频| 国产欧美在线| 久久最新视频| 欧美激情综合网| 亚洲在线免费| 久久精品卡一| 亚洲精品美女91| 亚洲夜间福利| 亚洲电影专区| 亚洲视频一二三| 精品91视频| 亚洲九九爱视频| 国产午夜精品一区二区三区视频| 久热这里只精品99re8久| 欧美国产日产韩国视频| 午夜综合激情| 欧美成人国产va精品日本一级| 亚洲午夜激情| 久久免费偷拍视频| 亚洲午夜久久久久久尤物| 欧美专区日韩视频| 亚洲午夜精品在线| 久久久久一区| 午夜久久福利| 欧美 日韩 国产 一区| 亚洲欧美日韩人成在线播放| 久久久久五月天| 亚洲欧美日韩第一区| 亚洲第一页中文字幕| 亚洲一区二区三区涩| 在线免费观看欧美| 一区二区三区四区精品| 精品99视频| 中文在线资源观看网站视频免费不卡| 国内伊人久久久久久网站视频| 亚洲人成网站777色婷婷| 国内精品伊人久久久久av影院| 99re6这里只有精品视频在线观看| 狠狠色伊人亚洲综合网站色| 亚洲一区二区动漫| 一区二区三区高清在线| 久久久精品日韩欧美| 午夜国产精品视频| 欧美日产一区二区三区在线观看| 猛干欧美女孩| 国内精品久久久久久影视8 | 国产精品色婷婷| 亚洲成色777777女色窝| 激情懂色av一区av二区av| 亚洲在线一区二区| 亚洲一区区二区| 欧美日韩国产另类不卡| 亚洲国产精品久久91精品| 在线观看av一区| 久久精品99国产精品酒店日本| 午夜精品久久久久影视 | 最新国产成人av网站网址麻豆 | 国产精品一级| 亚洲视频一区在线| 亚洲综合欧美| 欧美午夜寂寞影院| 亚洲视频在线观看三级| 亚洲已满18点击进入久久| 欧美日韩精品一二三区| 日韩一区二区免费高清| 农村妇女精品| 欧美成人乱码一区二区三区| 欧美性生交xxxxx久久久| 亚洲精品在线电影| 亚洲人成亚洲人成在线观看图片| 久久国产福利国产秒拍| 久久精品一区二区三区不卡| 国产日产欧美精品| 久久精品中文| 欧美国产精品一区| 亚洲欧洲精品一区二区| 欧美激情网站在线观看| 99精品黄色片免费大全| 午夜欧美精品| 国语自产精品视频在线看抢先版结局 | 亚洲肉体裸体xxxx137| 日韩亚洲成人av在线| 欧美日韩国产区| 亚洲精品视频中文字幕| 国产主播精品在线| 亚洲欧美激情精品一区二区| 亚洲在线视频| 国产日韩精品视频一区| 久久久99久久精品女同性| 欧美国产日本韩| 99精品免费| 国产精品乱码一区二三区小蝌蚪| 午夜精品短视频| 欧美波霸影院| 亚洲一区二区少妇| 国模私拍视频一区| 欧美好吊妞视频| 亚洲一区二区动漫| 裸体素人女欧美日韩| 99精品久久久| 国产日韩专区| 欧美激情一区二区三区在线| 亚洲午夜久久久久久久久电影网| 久久久99精品免费观看不卡| 亚洲经典三级| 国产精品午夜在线| 久热成人在线视频| 日韩视频专区| 牛夜精品久久久久久久99黑人| 亚洲视频在线一区| 激情成人av在线| 国产精品高清在线| 另类天堂视频在线观看| 亚洲午夜一二三区视频| 免费成人小视频| 亚洲欧美一区二区三区在线| 亚洲高清成人| 国产美女精品视频| 欧美精品在线免费观看| 久久精品国产91精品亚洲| 亚洲视频观看| 亚洲国产欧美另类丝袜| 久久亚洲综合网| 欧美一区二区精品久久911| 99香蕉国产精品偷在线观看| 一区二区三区亚洲| 国产欧美91| 国产精品激情| 欧美日韩国产一区精品一区| 麻豆成人av| 久久精品国产一区二区三区| 亚洲午夜一二三区视频| 亚洲免费av片| 亚洲国产婷婷| 免费在线亚洲| 蜜臀91精品一区二区三区| 久久成人国产| 欧美亚洲一区| 新67194成人永久网站| 亚洲综合999| 亚洲一区二区三区久久| 中文在线资源观看网站视频免费不卡| 亚洲黄色免费| 亚洲精品国久久99热| 亚洲欧洲一区二区三区久久| 在线日韩中文字幕| 亚洲第一在线| 在线观看欧美视频| 影音先锋久久精品| 在线观看一区| 亚洲国产综合91精品麻豆| ●精品国产综合乱码久久久久| 国内偷自视频区视频综合| 国产日韩欧美在线| 国产主播一区二区三区| 国产最新精品精品你懂的| 国产日韩亚洲欧美精品| 国产一区二区三区高清播放| 国产婷婷色综合av蜜臀av| 国产欧美日韩麻豆91| 国产亚洲在线观看| 国产揄拍国内精品对白| 欧美顶级少妇做爰| 欧美日韩性视频在线| 亚洲人成在线观看网站高清| 亚洲高清在线观看| 蜜桃av一区二区在线观看| 欧美在线观看网址综合| 国产资源精品在线观看| 久久精品国语| 亚洲福利av| 在线视频欧美精品| 欧美成人四级电影| 亚洲国产aⅴ天堂久久|