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

旅途

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

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>
            久久精品99久久香蕉国产色戒| 亚洲国产一区二区三区高清| 久久免费精品视频| 欧美三级视频| 亚洲精品国产欧美| 在线观看视频欧美| 久久精品水蜜桃av综合天堂| 久久精品一区蜜桃臀影院| 国产精品一区视频| 亚洲欧美日韩一区二区| 久久精品国产69国产精品亚洲 | 欧美成人午夜激情| 一区二区在线观看视频| 久久久久久久久久久一区| 久久天堂国产精品| 亚洲国产精品va在线观看黑人| 久久久亚洲一区| 欧美电影在线免费观看网站| 亚洲国产精品一区| 欧美国产视频在线| 一区二区欧美国产| 性娇小13――14欧美| 国产在线播精品第三| 久久婷婷国产综合尤物精品| 欧美黄色aaaa| 一区二区三区四区五区在线 | 亚洲一级黄色av| 久久都是精品| 一区在线视频| 欧美极品在线观看| 中文有码久久| 久久久天天操| 最新亚洲一区| 欧美网站在线| 欧美中文字幕久久| 欧美黄污视频| 亚洲一区在线免费观看| 国产日韩欧美中文| 麻豆国产精品777777在线| 99国内精品久久| 久久久久久久久久久一区| 亚洲国产mv| 国产精品国产一区二区| 久久精品视频在线| 亚洲激情在线| 久久国产一区二区| 亚洲美女精品成人在线视频| 国产精品久久久999| 欧美专区福利在线| 亚洲看片网站| 浪潮色综合久久天堂| 中文av字幕一区| 精品二区视频| 国产精品你懂的| 欧美+亚洲+精品+三区| 亚洲欧美韩国| 欧美性猛交xxxx免费看久久久| 久久人人97超碰精品888| 老司机精品视频网站| 99re6热在线精品视频播放速度 | 亚洲一区久久| 欧美高清在线视频| 欧美一区二区三区精品电影| 亚洲精品久久久久久久久| 国产欧美日韩在线视频| 欧美另类变人与禽xxxxx| 久久se精品一区精品二区| 亚洲美女黄色片| 男女精品视频| 久久国产一区| 亚洲欧美一区二区三区久久| 91久久午夜| 狠狠色丁香久久婷婷综合_中| 国产精品大全| 欧美激情一区| 麻豆av一区二区三区久久| 亚洲欧美电影在线观看| 亚洲免费成人| 亚洲三级电影全部在线观看高清| 久久婷婷国产综合精品青草| 午夜精品一区二区三区在线| 一本大道久久a久久精二百| 揄拍成人国产精品视频| 国产日韩欧美视频| 国产精品久久久久久久久| 欧美高清视频| 免费成人av在线看| 久久视频在线免费观看| 欧美在线你懂的| 亚欧美中日韩视频| 亚洲欧美日韩国产另类专区| 一区二区三区高清在线观看| 亚洲人成网站影音先锋播放| 亚洲成色www久久网站| 美国成人直播| 快she精品国产999| 久久综合999| 老司机精品视频一区二区三区| 久久国产精品一区二区三区四区| 午夜精品一区二区三区在线视| 亚洲欧美日本伦理| 午夜精品免费在线| 欧美综合国产精品久久丁香| 欧美中文字幕不卡| 久久久久亚洲综合| 另类尿喷潮videofree | 一级成人国产| 亚洲视频福利| 亚洲在线观看视频网站| 亚洲一区欧美| 欧美一区二区私人影院日本| 欧美一区午夜视频在线观看| 久久精品国产久精国产一老狼| 性欧美video另类hd性玩具| 欧美一级午夜免费电影| 久久久久9999亚洲精品| 老色鬼久久亚洲一区二区| 欧美成人高清| 亚洲区一区二区三区| 亚洲免费电影在线| 亚洲素人在线| 久久精品国产91精品亚洲| 麻豆亚洲精品| 欧美日本在线| 国产麻豆91精品| 伊人婷婷久久| 夜夜夜精品看看| 欧美中文字幕视频在线观看| 免费成人av| 日韩一级免费| 久久国产精品久久国产精品| 欧美高清视频在线播放| 一区二区久久久久| 久久精品国语| 欧美不卡一区| 国产精品成人一区二区| 很黄很黄激情成人| 亚洲精品欧美激情| 欧美一区2区三区4区公司二百| 久久久精品999| 亚洲精品黄色| 午夜宅男欧美| 欧美精选在线| 国产一区二区三区在线免费观看| 亚洲国产婷婷香蕉久久久久久99| 亚洲综合成人在线| 你懂的视频一区二区| 正在播放欧美视频| 老司机一区二区三区| 国产精品理论片在线观看| 亚洲高清视频在线观看| 亚洲欧美日本另类| 欧美黄色大片网站| 欧美一区2区三区4区公司二百 | 夜夜精品视频| 久久久视频精品| 国产精品一区二区在线观看网站 | 亚洲国产精品成人一区二区| 亚洲欧美自拍偷拍| 欧美夫妇交换俱乐部在线观看| 亚洲一区欧美一区| 欧美韩国日本一区| 狠狠干成人综合网| 午夜精品视频网站| 亚洲美女网站| 美日韩精品视频免费看| 国产日韩欧美一区二区| 亚洲伊人一本大道中文字幕| 欧美福利电影在线观看| 欧美在线视频日韩| 国产精品系列在线播放| 在线视频精品一区| 亚洲电影在线播放| 久久午夜视频| 国产在线高清精品| 久久黄色小说| 亚洲自拍三区| 欧美丝袜一区二区| 99热在这里有精品免费| 亚洲大片免费看| 久久偷窥视频| 伊人久久婷婷| 老鸭窝91久久精品色噜噜导演| 亚洲欧美在线免费| 国产精品日日摸夜夜添夜夜av| 亚洲午夜久久久久久久久电影院 | 中文亚洲欧美| 欧美视频第二页| 正在播放欧美视频| 亚洲人成精品久久久久| 欧美激情按摩| 亚洲日韩欧美视频| 欧美韩日视频| 免费在线日韩av| 亚洲日本欧美日韩高观看| 另类亚洲自拍| 美女日韩欧美| 亚洲麻豆av| 亚洲精品日产精品乱码不卡| 欧美精品v日韩精品v国产精品 |