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

旅途

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

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) 評(píng)論(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>
            欧美国产精品劲爆| 欧美日韩高清在线播放| 国产在线观看一区| 欧美一级精品大片| 性伦欧美刺激片在线观看| 国产午夜精品久久久久久免费视| 欧美影院在线播放| 欧美在线黄色| 亚洲国产精品黑人久久久| 欧美电影美腿模特1979在线看| 久久性天堂网| av成人国产| 亚洲特色特黄| 国产亚洲一区在线| 欧美成人免费网| 欧美日韩精品三区| 欧美在线电影| 欧美不卡视频| 欧美亚洲视频在线观看| 欧美一二三视频| 亚洲精品久久久久中文字幕欢迎你 | 欧美韩日视频| 午夜精品久久久久久久男人的天堂 | 久久精品水蜜桃av综合天堂| 久久精品视频一| 亚洲美女av在线播放| 99精品国产福利在线观看免费| 国产精品久久999| 久久久欧美精品sm网站| 久久麻豆一区二区| 中文在线资源观看网站视频免费不卡 | 美女精品视频一区| 亚洲在线日韩| 久久伊人亚洲| 午夜精品视频一区| 久久久久青草大香线综合精品| 一本一道久久综合狠狠老精东影业 | 亚洲综合色丁香婷婷六月图片| 国产亚洲精品久久久久动| 亚洲第一页在线| 国产精品一区二区久久久久| 欧美成黄导航| 国产日韩欧美精品一区| 亚洲激情第一页| 雨宫琴音一区二区在线| 一区二区三区欧美视频| 91久久精品视频| 久久精品在线观看| 欧美中文字幕在线观看| 欧美日韩成人在线视频| 老鸭窝毛片一区二区三区| 国产精品狠色婷| 亚洲日本视频| 亚洲精品一区二区三区婷婷月| 午夜在线电影亚洲一区| 亚洲午夜av| 欧美日韩不卡视频| 亚洲国产精品999| 亚洲国产91| 久久久蜜桃一区二区人| 欧美一区不卡| 欧美性事在线| 一区二区日韩| 亚洲欧美精品在线| 国产精品二区影院| 99成人在线| 中文日韩欧美| 欧美日韩精品国产| 99re成人精品视频| 亚洲天堂视频在线观看| 欧美日韩不卡| 一本色道久久综合亚洲精品不| 亚洲激精日韩激精欧美精品| 久久这里有精品15一区二区三区| 久久精品国产99国产精品| 国产精品视频精品视频| 亚洲午夜未删减在线观看| 亚洲一区视频在线| 国产精品无码永久免费888| 亚洲综合欧美日韩| 久久久午夜精品| 在线免费高清一区二区三区| 久久久999| 亚洲国产人成综合网站| 在线一区亚洲| 国产精品素人视频| 久久激情一区| 亚洲国产高清自拍| 亚洲视频在线观看网站| 国产精品亚洲不卡a| 久久久91精品国产| 亚洲破处大片| 亚洲欧美视频在线观看| 国内精品免费在线观看| 欧美成人在线影院| 亚洲视屏一区| 欧美成人免费小视频| 亚洲美洲欧洲综合国产一区| 欧美亚洲第一页| 欧美亚洲日本国产| 亚洲国产精品va在线观看黑人| 亚洲视频一起| 激情成人在线视频| 欧美日韩日日骚| 久久久www成人免费毛片麻豆| 你懂的国产精品| 亚洲专区在线| 亚洲电影在线播放| 国产精品福利网| 久久夜色精品国产噜噜av| 一本久道久久综合婷婷鲸鱼| 久久亚洲一区二区| 亚洲伊人伊色伊影伊综合网| 国内久久婷婷综合| 欧美色视频在线| 蜜臀a∨国产成人精品| 一区二区日韩| 亚洲电影免费观看高清完整版在线观看| 亚洲专区在线视频| 最新精品在线| 黄色小说综合网站| 国产精品入口尤物| 欧美精品免费播放| 久久综合福利| 性伦欧美刺激片在线观看| 日韩写真在线| 最近中文字幕mv在线一区二区三区四区| 久久精品九九| 亚洲欧美日本国产专区一区| 亚洲精品一区二区三区樱花 | 久久漫画官网| 香蕉视频成人在线观看| 一区二区三区精品视频在线观看| 美女在线一区二区| 久久久噜噜噜久久久| 亚洲欧美一级二级三级| 亚洲视频第一页| 99精品欧美一区| 亚洲精品欧美在线| 亚洲电影免费观看高清完整版在线观看 | 亚洲欧美中文另类| 亚洲一区二区欧美日韩| 日韩午夜三级在线| 亚洲美女在线一区| 亚洲精品网站在线播放gif| 亚洲高清不卡| 亚洲欧洲日韩在线| 亚洲国产午夜| 亚洲黄色成人| 日韩视频欧美视频| 日韩一级片网址| 99这里只有久久精品视频| 日韩午夜免费视频| 亚洲小说春色综合另类电影| 一区二区三区日韩在线观看| 日韩午夜激情| 亚洲一区欧美二区| 香蕉久久久久久久av网站| 欧美一区二视频| 久久精品一区四区| 蜜桃av综合| 亚洲精品久久久久| 一区二区三区精品在线| 亚洲尤物在线| 久久久久国色av免费观看性色| 久久精品1区| 欧美丰满高潮xxxx喷水动漫| 欧美日本在线看| 国产精品主播| 亚洲国产成人精品久久久国产成人一区| 亚洲高清色综合| 亚洲一区综合| 麻豆av一区二区三区| 亚洲缚视频在线观看| 一区二区三区日韩在线观看 | 免费成人高清视频| 亚洲精品一区二区三区四区高清| 99爱精品视频| 久久久久se| 欧美日韩国产精品专区 | 老司机67194精品线观看| 欧美精品一卡二卡| 国产日韩欧美三级| 亚洲精品色婷婷福利天堂| 亚洲一区黄色| 免费观看成人| 中文在线不卡| 蜜臀99久久精品久久久久久软件| 欧美日韩麻豆| 在线高清一区| 亚洲欧美日韩一区二区在线| 欧美α欧美αv大片| 一本一本久久| 欧美大胆a视频| 韩国精品主播一区二区在线观看| 亚洲精品视频一区| 久久亚洲综合网| 亚洲制服少妇| 欧美日韩美女在线| 在线激情影院一区|