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

旅途

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

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>
            久久精品国产亚洲一区二区三区| 亚洲欧美日韩在线高清直播| 久久aⅴ国产欧美74aaa| 欧美视频免费在线| 9色porny自拍视频一区二区| 亚洲第一精品夜夜躁人人躁 | 国产日韩欧美一区二区| 亚洲欧美在线aaa| 亚洲综合色在线| 国产美女精品视频免费观看| 久久国产精品72免费观看| 亚洲欧美卡通另类91av| 国产视频久久| 久久久久欧美| 亚洲第一中文字幕| 欧美韩日精品| 欧美日韩国产综合网| 亚洲欧美综合精品久久成人| 亚洲自拍偷拍一区| 在线精品视频一区二区三四| 久久一区精品| 欧美激情综合在线| 亚洲欧美国产高清va在线播| 欧美亚洲综合另类| 18成人免费观看视频| 亚洲国产日韩精品| 欧美性做爰猛烈叫床潮| 久久精品亚洲精品| 欧美国产日韩一二三区| 午夜视频一区二区| 久久久水蜜桃| 亚洲午夜黄色| 久久精品在线| 亚洲视频一起| 久久久777| 亚洲在线视频观看| 老司机精品久久| 午夜精品久久久久影视| 免费高清在线一区| 午夜亚洲福利| 欧美黄色视屏| 老司机久久99久久精品播放免费| 欧美激情精品久久久久久| 欧美一区二区三区日韩| 欧美成人资源| 久久久久国产免费免费| 欧美日韩一区二区三区免费看| 久久精品国产精品| 国产精品v日韩精品| 欧美成人久久| 黑人巨大精品欧美黑白配亚洲| 一二三区精品福利视频| 亚洲国产精品专区久久 | 一区二区三区日韩欧美精品| 久久精品一区二区国产| 亚洲欧美成人一区二区在线电影| 免费一级欧美片在线播放| 久久久国产精品亚洲一区| 国产精品二区三区四区| 亚洲精品美女| 日韩午夜剧场| 欧美岛国在线观看| 欧美不卡福利| 亚洲电影av| 久久亚洲私人国产精品va媚药| 久久精品国产精品| 国产日韩亚洲| 先锋影音网一区二区| 欧美一区二区三区免费看| 欧美午夜不卡视频| 亚洲精品自在久久| 一区二区三区回区在观看免费视频| 另类激情亚洲| 亚洲第一精品在线| 亚洲精品资源美女情侣酒店| 欧美不卡在线| 亚洲激情欧美| 一区二区高清视频| 欧美婷婷六月丁香综合色| 亚洲美女av在线播放| 一区二区三区精品在线| 欧美调教vk| 亚洲欧美影音先锋| 久久久99免费视频| 国产综合色产在线精品| 久久国产日韩| 久久综合中文字幕| 亚洲黄色影院| 欧美日韩国产一区二区| 中文欧美在线视频| 久久激情久久| 亚洲春色另类小说| 欧美精品性视频| 一区二区三区欧美| 久久久精彩视频| 亚洲激情午夜| 国产精品国产| 久久激情综合| 亚洲激情欧美激情| 欧美与黑人午夜性猛交久久久| 国内精品国产成人| 欧美精品一区二区蜜臀亚洲| 一本大道久久精品懂色aⅴ| 亚洲欧美在线高清| 在线观看久久av| 欧美色一级片| 久久先锋资源| 中日韩美女免费视频网址在线观看| 久久精品国产免费看久久精品| 在线欧美亚洲| 国产精品久久久久久久久搜平片 | 欧美主播一区二区三区美女 久久精品人 | 欧美一区二区三区四区在线观看地址| 久久不见久久见免费视频1| 极品少妇一区二区三区精品视频| 欧美福利在线| 久久激情视频| 一区二区日韩| 欧美激情精品久久久久久久变态| 亚洲一区国产视频| 亚洲高清视频在线观看| 国产精品普通话对白| 欧美a级片一区| 欧美一区日本一区韩国一区| 亚洲精品黄色| 欧美成人69av| 久久动漫亚洲| 亚洲欧美www| 一区二区欧美国产| 亚洲欧洲在线免费| 国语自产精品视频在线看8查询8| 欧美日韩视频在线第一区| 久久亚洲综合色一区二区三区| 亚洲一区高清| 99亚洲一区二区| 亚洲国产精品视频一区| 免费久久精品视频| 久久亚洲私人国产精品va| 亚洲欧美大片| 亚洲一区二区三区午夜| 亚洲精品一区二区在线观看| 一区二区三区在线看| 国产伦精品一区二区三区免费| 欧美精品一区二区三区四区| 蜜臀a∨国产成人精品 | 久久综合99re88久久爱| 翔田千里一区二区| 小处雏高清一区二区三区| 亚洲欧美日韩在线一区| 亚洲午夜在线| 亚洲一区二区高清视频| 亚洲午夜精品久久| 亚洲一区欧美激情| 亚洲欧美日韩电影| 香蕉精品999视频一区二区| 先锋影音网一区二区| 欧美一级淫片aaaaaaa视频| 亚洲欧美日韩一区二区| 欧美尤物一区| 久久一日本道色综合久久| 久久视频国产精品免费视频在线| 久久成人精品电影| 久久在线免费观看视频| 欧美成人午夜| 91久久综合| 一区二区三区国产在线| 一区二区三区高清| 欧美一区91| 麻豆亚洲精品| 欧美日韩美女一区二区| 国产精品成人一区二区三区夜夜夜| 国产精品成人一区二区| 国产免费成人av| 在线不卡中文字幕播放| 9i看片成人免费高清| 亚洲欧美在线一区二区| 久久久精品欧美丰满| 欧美国产免费| 99re66热这里只有精品4 | 久久久成人网| 亚洲第一综合天堂另类专| 日韩视频免费观看| 欧美亚洲免费电影| 欧美国产精品久久| 国产精品久久国产愉拍| 好男人免费精品视频| 日韩一级视频免费观看在线| 欧美一区二区视频免费观看| 欧美华人在线视频| 亚洲私人黄色宅男| 久久全球大尺度高清视频| 欧美日韩性视频在线| 国产一区二区三区日韩| 日韩一区二区精品视频| 欧美在线免费| 亚洲精选成人| 欧美成人国产| 国产一区二区精品久久99| 一区二区三区久久精品| 欧美成人精品一区|