XHtmlTree - Tree control with support for HTML, XML, Smart Checkboxes, and Drag & Drop
来源:互联网 发布:淘宝的数据魔方在哪里 编辑:程序博客网 时间:2024/06/16 06:46
XHtmlTree - Tree control with support for HTML, XML, Smart Checkboxes, and Drag & Drop
By Hans DietrichXHtmlTreeis an MFC control based on CTreeCtrl, with support for HTML text, weblinks, APP: links, XML load/save, Smart Checkboxes, and Drag & Drop.
- Download demo project - 501.13 KB
Winner August 2007
Monthly Competition
Introduction
Everyone is familiar with tree controls: every time you open WindowsExplorer, you see file system hierarchy as a tree. Another kind of treeis used by some programs, such as installers, to allow you to selectoptions to install. When all options of a particular subtree areselected, you will see checkbox with a check mark (); when no options in a subtree are selected, the checkbox next to the subtree root displays an unchecked checkbox (); and when only some of the options in a subtree are selected, you will see what is known as tri-state checkbox ().
Surprisingly, there is no direct support for tri-state checkboxes in MFC's CTreeCtrl.The closest you can get is to create a tri-state image list for yourtree. While this will work, it does not give you the complete visualeffect of XP themed checkboxes, such as hot-state appearance () when the mouse is hovering.
While I was researching tree controls and how to add tri-statecheckboxes, I came to understand that the tree control - like the listcontrol - can be enhanced with many useful features and nice UI effectsby mechanism of custom draw.This led me to take next step: adding HTML support to tree items. Itwas easy to see how this would be possible, since I had just completedmy XHtmlDraw article.
Before long I sketched out requirements of my new tree control:
Checkboxes with theme support- I wanted notification messages sent to parent when checkbox wastoggled, and full theme support; this means hover (hot) support, withcheckboxes drawn exactly like themed XP checkboxes. Of course, onVista, checkboxes should have Vista appearance:Smart Checkboxes - thisis a term I started using (but did not invent) to describe how checkingparent item will also checkmark the children of that item - and,conversely, unchecking a child item will display parent with tri-statecheckbox, if any other children are still checkmarked. Here is quickdemo of how it works:
Of course, Smart Checkboxes are optional - you can have checkboxes without using Smart Checkboxes.
HTML - I wanted to include XHtmlDraw functionality, including support for web links and APP: links. Enhanced tree navigation and status - reading Zafir Anjum's articlesgave me ideas for improving the programmatic interface of the treecontrol, and I also wanted to implement better management features,like determining how many items are checked, how many children an itemhas, etc., and sending notification message to parent when item isexpanded. Loading and saving tree data using XML - this is a common requirement as XML is adopted in more applications.XHtmlTree Features
To begin with, let me show you the demo app:
This dialog allows you to choose source of data for tree. It can betext file or XML file (files are stored as resources, see my XResFile articlefor details). There are two choices for each file type - one iscomplete list, the second is partial list with ten items in each mainnode, to make debugging easy.
When you click on button, here is what you see:
Here are main features:
- The Options checkboxes allow to display tree with various options that are tree-wide in scope - i.e., they affect all items.
- The Show Checked button displays modeless dialog that shows list of currently checked items:
Image has been reduced in size. To refresh list, just click button again.
- The Find button displays Find dialog:
This dialog uses built-in
CXHtmlTree::FindItem()
function to search for item text. An option on dialog lets you checkmark all matching items, which you can observe using Show Checked dialog. - The Colors button displays Colors dialog:
Note that background color will be set as background of the entire tree control (via
SetBkColor()
). However, individual items can have their backgrounds set independently of this, either by usingSetItemTextBkColor()
, or by using HTML: - These are indicators of scrolling speed for drag & drop scrolling.
- These are three buttons that allow you to toggle checkmark of all items, expand all items, and collapse all items.
- The tree control shows one item checkmarked. Note that its parent (Collies) is shown with tri-state checkmark, indicating one of its children - but not all - is checked. Its parent (Herding Dogs) also has tri-state checkmark.
- The edit box contains item text, which you can modify, and then use Update button to write new text to tree item.
- The Tree Info displays information about entire tree.
- The Item Info displays information about an item - either the currently selected item, or item that was just expanded.
- Tree breadcrumb trail is displayed by using
GetItemPath()
function and XBreadCrumbBar. When you click on active breadcrumb, that tree node will be selected. - The Log displays information when notification messages (
TVN_SELCHANGED
,WM_XHTMLTREE_CHECKBOX_CLICKED
, andWM_XHTMLTREE_ITEM_EXPANDED
) are received from control. You can enable or disable the Log with checkbox.
Implementation Notes
HTML
To see full list of supported HTML tags, including how to use web links and APP: links, please refer to my XHtmlDraw article.
Colors and Text Attributes
The following functions support item and tree colors and text attributes:
Checkboxes
You can enable checkboxes for tree (using SetHasCheckBoxes()
) independently of enabling Smart Checkboxes (using SetSmartCheckBox()
).When checkboxes are enabled, an internal state image list is createdfor various checkbox states. This creation is performed in CreateCheckboxImageList()
(see CreateCheckboxImageList.cpp). For each possible state, a bitmap is created (using David Zhao's excellent CVisualStylesXP class), for both cold and hot states. Obviously this implies modal processing, but since I can use CTreeCtrl::SetItemState()
,keeping track of item state is not too complicated. Furthermore, I havedesigned image list so that common state transitions are simple. Infollowing table, you can see that going from "cold" state to "hot"state involves OR'ing with 8, and going from "normal" state to"disabled" state involves OR'ing with 4.
Here are functions implemented to support XHtmlTree checkboxes:
Keyboard Shortcuts
XHtmlTree supports standard Windows keyboard navigation techniques:
Tree Navigation and Management
Here are functions implemented to support XHtmlTree navigation:
Initializing the Tree
It is easy to initialize XHtmlTree in one statement:
m_Tree.Initialize(m_bCheckBoxes, TRUE)
.SetSmartCheckBox(m_bSmartCheckBoxes)
.SetHtml(m_bHtml)
.SetStripHtml(m_bStripHtml)
.SetImages(m_bImages);
Tooltips
XHtmlTree supports standard tooltips via CToolTipCtrl, and also supports HTML tooltips, displayed with Eugene Pustovoyt's excellent CPPToolTip class. Here is example of how HTML tooltips can be used:
Here is HTML used for this tooltip:
<br><hr color=lightsteelblue><br>
<table>
<tr>
<td><bmp idres=133 cx=110 cy=92 mask></td>
<td> </td>
<tdwidth=180>The Golden Retriever is a popular breed of dog, originallydeveloped to retrieve game during hunting. It is one of the most commonfamily dogs as it is naturally very friendly and amenable totraining.</td>
</tr>
</table>
This is all standard HTML, except for the <bmp idres=133 cx=110 cy=92 mask>, which specifies bitmap to be read from resource id 133.
OK, so where is HTML coming from, since it is obviously not the item text? XHtmlTree provides a new SetItemNote()
function, which attaches optional note text to an item. The note text(when it exists) is used instead of item text for tooltips. This istrue for both standard tooltips and HTML tooltips. However, keep inmind that standard tooltips have hard limit of 80 characters.
#define XHTMLTOOLTIPS
If you include HTML tooltips, you must include additional files in your project - see How To Use section below for details.
One final point about tooltips: you have option of dynamicallychanging a tooltip when it is about to be displayed. A notificationmessage (WM_XHTMLTREE_DISPLAY_TOOLTIP
- see Notification Messages below) gives you chance to use SetItemNote()
right before tooltip is displayed. To give example, in XHtmlTreeTestDlg.cpp, you will see this code (condensed here):
LRESULT CXHtmlTreeTestDlg::OnDisplayTreeToolTip(WPARAM wParam, LPARAM)
{
XHTMLTREEMSGDATA *pData = (XHTMLTREEMSGDATA *)wParam;
HTREEITEM hItem = pData->hItem;
CString strText = m_Tree.GetItemText(hItem);
// check if this is 'Galgo Español (Spanish Greyhound)'
if (_tcsncmp(strText, _T("Galgo"), 5) == 0)
{
// set new note for this item --
// zero tip width will use default width
m_Tree.SetItemNote(hItem,
_T("This is alternate text. ")
_T("For standard tooltip, it is limited to 80 characters."),
0);
}
return 0; // return 0 to allow tooltip to be displayed,
// 1 to prevent display
}
In the demo app, this is what you will see:
Notification Messages
For all notification messages, the wParam
parameter is pointer to XHTMLTREEMSGDATA
struct:
struct XHTMLTREEMSGDATA
{
HWND hCtrl; // hwnd of XHtmlTree
UINT nCtrlId; // id of XHtmlTree
HTREEITEM hItem; // current item
};
The lParam
parameter depends on specific message. The following messages are sent to XHtmlTree parent:
CToolTipCtrl
or CPPToolTip
)WM_XHTMLTREE_INIT_TOOLTIPSent when tooltip control is being initializedPointer to tooltip control (CToolTipCtrl
or CPPToolTip
)WM_XHTMLTREE_ITEM_EXPANDEDSent when an item has been expanded or collapsedNew item state (TRUE = expanded)Drag & Drop
Starting with version 1.4, XHtmlTree supports drag & drop. The following drag & drop facilities and operations are implemented:
- There is new compile-time symbol to enable inclusion of drag & drop code: Collapse
#define XHTMLDRAGDROP
Defining (or not defining) this symbol also takes care of settingTVS_DISABLEDRAGDROP
style correctly. - Drag & drop is implemented using
CTreeCtrl::SetInsertMark()
API. This is what is used, for example, for FireFox bookmarks. As anitem is being dragged, what you will see is a solid thin bar - calledthe insert mark - that is displayed between items in the tree. Theinsert mark indicates where item will be inserted into the tree if itis dropped. - By design, traditional OLE-style drag image animation has not been implemented, and there are no current plans to do so.
- In addition to display of insert mark, you have option of displaying (via
SetDropCursors()
function) three custom cursors: the no-drop cursor, the drop move cursor, and the drop copy cursor. The demo app includes examples of each:Cursor Demo Image Description No dropUsed to indicate a no-drop zone; either an area outside the tree control, or an item that is not an allowed drop target.Drop MoveUsed to indicate the dragged item will be moved when left mouse button is released.Drop CopyUsed to indicate the dragged item will be copied when left mouse button is released. - Drop Copy vs. Drop Move - There are several ways to control whether dragged item will be copied or moved: The user can use Ctrl key to toggle between copy and move, before or during drag. The application can control whether Ctrl key is recognized by setting/resetting
XHTMLTREE_DO_CTRL_KEY
drag operations flag. The application can change default behavior of Ctrl key by setting/resettingXHTMLTREE_DO_COPY_DRAG
drag operations flag. - The application can control each stage of a drag by handling following notification messages:
WM_XHTMLTREE_BEGIN_DRAG
- This message is sent when a drag is initiated, and includes the dragged item and the state of theXHTMLTREE_DO_COPY_DRAG
flag bit. Note that in demo app, attempting to drag Longdog in Sight Hounds group will be rejected (see demo Log).WM_XHTMLTREE_END_DRAG
- This message is sent when a drag is terminated, either by a drop or by other user action (such as hitting the ESC key,right-clicking the mouse, dropping an item back onto itself, ordropping outside tree control). If the drag ends because of a drop on avalid tree item (other than itself), this message will include theproposed drop target. If the drop terminates for any other reason, avalue of 0 will be sent aslParam
parameter. Note that in demo app, dropping on Longdog in Sight Hounds group will be rejected (see demo Log).WM_XHTMLTREE_DROP_HOVER
-This message is sent when the cursor is over a tree item, and includesthe tree item that could be a drop target, Note that in demo app,hovering over Longdog in Sight Hounds group will display a "no-drop" cursor.For all above messages, a pointer to
XHTMLTREEDRAGMSGDATA
struct is sent aslParam
parameter (this might be NULL in the case ofWM_XHTMLTREE_END_DRAG
message).Collapsestruct XHTMLTREEDRAGMSGDATA
{
HTREEITEM hItem; // item being dragged
HTREEITEM hNewParent; // proposed new parent
HTREEITEM hAfter; // drop target - item being dragged will
// either sequentially follow this item,
// or hAfter specifies the relationship
// (TVI_FIRST, TVI_LAST, etc.) the
// dragged item will have with hNewParent.
// Note that TVI_xxxx constants are all
// defined as 0xFFFFnnnn, with the 16
// high-order bits set.
BOOL bCopyDrag; // TRUE = dropped item will be copied;
// FALSE = dropped item will be moved
};The application may respond to these messages with either
FALSE
(indicating that proposed action may continue), orTRUE
, indicating that proposed action is not permitted. When sent in response toWM_XHTMLTREE_BEGIN_DRAG
andWM_XHTMLTREE_END_DRAG
messages, a return code ofTRUE
will terminate drag. When sent in response toWM_XHTMLTREE_DROP_HOVER
message, a return code ofTRUE
will cause the no-drop cursor to be displayed.Since the default return code - in the absence of a message handler - is 0 or
FALSE
, it is not necessary to implement handlers for any of these messages in order to enable drag & drop. - Bydefault, during a drag the tree will auto-scroll when cursor approachestop or bottom of control. The tree scrolls at three different speeds,depending on how close the cursor is to the edge. In addition, theapplication can select one of two overall speed settings - normal orfast - and can also completely disable drag scrolling. Drag scrollingis controlled by drag operations flags
XHTMLTREE_DO_SCROLL_NORMAL
andXHTMLTREE_DO_SCROLL_FAST
. If both of these flag bits are 0, no scrolling will occur. - By default, during drag the tree willauto-expand a node when cursor hovers over it. This behavior may bedisabled with drag operations flag bit
XHTMLTREE_DO_AUTO_EXPAND
. - By using
SetInsertMark()
API in conjunction with auto-expand, the user may drop an item (orbranch) after any existing node. However, these two mechanisms do notallow for drop-under, where the drop results in creation of a childitem. To accommodate this, the user may use Shift key before or during drag. Holding down Shift keycauses drop to become drop-under: the insert mark is removed, andinstead the drop target (the proposed new parent) is highlighted. Thisbehavior may be disabled with drag operations flag bitXHTMLTREE_DO_SHIFT_KEY
. - Drag operations involving disabled or read-only items are not explicitly disallowed by XHtmlTree. If you want to prevent dragging of disabled or read-only items, you should set up handler for
WM_XHTMLTREE_BEGIN_DRAG
message. See XHtmlTreeTestDlg.cpp for example. - There is known problem that when Ctrl key is down, the ESC key will not terminate drag.
Separators
Starting with version 1.6, XHtmlTreesupports item separators. Separators are simply visual indicators thatare meant to set apart or divide tree items. In the followingscreenshot, the three "Australian" dogs are enclosed in two separators:
To try out separators yourself, you can use right-click menu in demo app:
The following separator facilities and operations are implemented:
- The function
InsertSeparator()
inserts a separator after the specified item. There is no limit on the number of separators. - The function
IsSeparator()
allows you to test whether a tree item is separator. - You can change the color of individual separators by using
SetItemTextColor()
, or you can useSetSeparatorColor()
to change the color of all separators. The default separator color is that returned byGetSysColor(COLOR_GRAYTEXT)
. - Separators can be selected just like any other tree item.
- Separators can be dragged just like any other tree item.
- Separators cannot have text.
- Separators cannot have children.Attempting to drop an item on a separator will always cause item to beinserted after separator ("drop under" is not allowed). However, it is allowed to drop a separator under a non-separator item.
- Separators cannot be edited via
TVN_BEGINLABELEDIT
. - Separators are included in count of children, but have no effect on Smart Checkboxes.
- You can specify separators to be loaded from XML file by using attribute separator=1.
How To Use
To integrate XHtmlTree into your own app, you first need to add following files to your project:
- CreateCheckboxImageList.cpp
- CreateCheckboxImageList.h
- VisualStylesXP.cpp
- VisualStylesXP.h
- XHtmlDraw.cpp
†
- XHtmlDraw.h
- XHtmlDrawLink.cpp
†
- XHtmlDrawLink.h
- XHtmlTree.cpp
- XHtmlTree.h
- XNamedColors.cpp
†
- XNamedColors.h
- XString.cpp
†
- XString.h
Files marked with †
must be set in Visual Studio to Not Using Precompiled headers.
If you want to use HTML tooltips, then you must also include these files:
- CeXDib.cpp
- CeXDib.h
- PPDrawManager.cpp
- PPDrawManager.h
- PPHtmlDrawer.cpp
- PPHtmlDrawer.h
- PPTooltip.cpp
- PPTooltip.h
And finally, if you want to include XML functions, then you must include these two files:
- XmlDocument.cpp
- XmlDocument.h
Then declare variable for CTreeCtrl
object, and change its type to CXHtmlTree
:
CXHtmlTree m_Tree;
Now you are ready to use CXHtmlTree
in your project.
XHtmlTree Compile-time Options
There are three compile-time options that control what XHtmlTree features are included. These options may be selected by editing XHtmlTree.h, by including them as #define
statements (for example, in stdafx.h), or by defining them via IDE (in VS2005, go to Project | Properties | Configuration Properties | C/C++ | Preprocessor | Preprocessor Definitions; be sure to do this for All Configurations).
XHTMLHTML
- when defined, this option will enable use of HTML in tree items.XHTMLTOOLTIPS
- when defined, this option will enable use of HTML tooltips.XHTMLXML
- when defined, this option will enable loading/saving XML data.XHTMLDRAGDROP
- when defined, this option will enable drag & drop.
The following table shows what source modules need to be includedfor each compile-time option (including the case where no options areselected, which is what is used in MinDialog demo):
†
XHtmlDraw.hXHtmlDrawLink.cpp †
XHtmlDrawLink.hXHtmlTree.cppXHtmlTree.hXmlDocument.cppXmlDocument.hXNamedColors.cpp †
XNamedColors.hXString.cpp †
XString.h†
must be set in Visual Studio to Not Using Precompiled headers.The files needed for drag & drop (XHTMLDRAGDROP
) are the same ones listed under None.
Using XML
You can load tree the way you are currently doing it, or - if you defineXHTMLXML
in XHtmlTree.h - you can use LoadXmlFromXXXX
functions - see XHtmlTreeTestDlg.cpp for example. The XML parser used by XHtmlTree is extremely simple, and does not perform any strict error checking. In this condensed snippet of XML from dogs.xml, note that HTML tags must be escaped with character entities: Here are attribute names expected by LoadXmlFromXXXX
functions:
- name - this is the item text that will be inserted in the tree. It can include HTML formatting.
- checked - gives the item an initial checked state (if "1") or unchecked state ("0"). Default is unchecked.
- enabled - gives the item an initial enabled state (if "1") or unchecked state ("0"). Default is enabled.
- separator - specifies that item is separator (if "1") or not a separator ("0"). Default is not a separator.
- image - associates image from image list with item. Use
SetImageList()
to set the image list. - text-color - text color of item; overrides the global tree text color.
- text-background-color - text background color of item; overrides the global tree text background color.
- note-width - tooltip width for this item. Default of 0 means that a heuristic will be used to determine appropriate width.
- note - this text will be displayed instead of the standard tooltip text. This can include HTML tags, if
XHTMLTOOLTIPS
has been defined (see XHtmlTree.h).
You can load XML from a resource, a file, or a memory buffer, and you can save XML to a file.
Here are functions implemented to support XML:
References
Here are links I have mentioned in this article. I have alsoincluded links to my articles on CodeProject, which I have used in demoapp.
- Tree Control Drag-and-Drop Operations from MSDN
- Customizing a Control's Appearance Using Custom Draw from MSDN
- Tree control articles by Zafir Anjum
- CTreeComboBox: A Multiline Tree Combo Box that supports XML by John Melas. This article contains the
CXmlDocument
class that I use in XHtmlTree. - Add XP Visual Style Support to OWNERDRAW Controls by David Y. Zhao. I use this to create the checkbox bitmaps.
- CPPToolTip by Eugene Pustovoyt. I use this class for the HTML tooltips.
- XBreadCrumbBar - Draw breadcrumb trail with hyperlinks and HTML
- XColourPicker - yet another colour picker control
- XEditPrompt - CEdit-derived control with web-like prompt
- XGlyphButton - a simple image button control
- XHtmlDraw - Draw text with HTML tags and anchor links - I use this to draw tree items that contain HTML formatting.
- XHyperLink - yet another hyperlink control
- XListBox - Owner-draw CListBox with selectable text and background colors
- XResFile - Files stored in resources: Part 1 - Text and Binary
- XString - non-MFC non-STL string functions
Revision History
Version 1.6 - 2007 December 19
- Added support for separators.
- Fixed bug with multiple roots - dropping a root node always created child node instead of root node.
- Added multiple-root sample to demo app.
Version 1.5 - 2007 November 7
- Fixed bug with XML input (crash if no image list); reported by Berni Slootbeek.
- Updated to XHtmlDraw v1.2.
Version 1.4 - 2007 November 4
- Added support for drag & drop, suggested by David McMinn. Thanks for your help, David!
Version 1.3 - 2007 October 16
- Added demo project for "minimum dialog". This project shows how to use XHtmlTree with Smart Checkboxes, but without HTML, XML, or HTML tooltips. This reduces size of executable by about 130Kb.
Version 1.2 - 2007 October 14
- Tweaked display performance.
- Minor changes to demo app.
- Added handler for
WM_CONTEXTMENU
to demo app. - Added
CXHtmlTree::EnableBranch(HTREEITEM hItem, BOOL bEnabled)
- Fixed problem with using spacebar to check item, reported by David McMinn.
- Fixed problem with in-place edit box not closing, reported by David McMinn.
- Fixed several problems with in-place editing, using code supplied by David McMinn.
Version 1.1 - 2007 October 10
- Added demo project for MDI app.
- Eliminated flickering of desktop icons, reported by Greg Cadmes.
- Fixed version problem with system color definitions, reported by Graham Shanks.
- Fixed compile problem with
CVisualStylesXP::UseVisualStyles()
, reported by Graham Shanks. - Smart checkboxes now default to off (FALSE); suggested by Graham Shanks.
- Added color support for disabled tree, suggested by Graham Shanks.
- Fixed
CheckAll()
to handle multiple root nodes, reported by Rolando E. Cruz-Marshall. - Fixed problem with
SetCheck()
, reported by Graham Shanks. - Added
Get/SetReadOnly()
functions, suggested by Graham Shanks. TheSetReadOnly()
function toggles all checkboxes between active (read/write) andinactive (read-only), and also allows/prevents in-place editing. Whenset to read-only, there is no automatic visual indication that the treeis read-only. You can use theSetBkColor()
function toset the background of read-only tree to indicate read-only state. Alsoadded option to demo app to set read-only state. - Added Shih Tzu to dog list, suggested by bolivar123.
Version 1.0 - 2007 August 9
- Initial public release
Usage
This software is released into the public domain. You are free touse it in any way you like, except that you may not sell this sourcecode. If you modify it or extend it, please to consider posting newcode here for everyone to share. This software is provided "as is" withno expressed or implied warranty. I accept no liability for any damageor loss of business that this software may cause.
License
This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)
About the Author
Hans DietrichMvp I attended St. Michael's College of the University of Toronto,with the intention of becoming a priest. A friend in the University'sComputer Science Department got me interested in programming, and Ihave been hooked ever since.
Recently, I have moved to Los Angeles where I am doing consulting and development work.
Occupation: Software Developer (Senior)Location: United States
From: http://www.codeproject.com/KB/tree/XHtmlTree.aspx
- XHtmlTree - Tree control with support for HTML, XML, Smart Checkboxes, and Drag & Drop
- Drag and Drop support for column reordering in DataGrid control
- Drag and drop with Javascript
- Drag and Drop For IconJLable
- QTP HELP - Web Drag and Drop Support
- D3.js Drag and Drop, Zoomable, Panning, Collapsible Tree with auto-sizing
- Checkboxes in a Tree Control
- Drag and Drop
- 学习drag and drop
- 关于drag and drop
- html5 Drag and drop
- Ajax Drag and Drop
- QT5 drag and drop
- HTML5 Drag and Drop
- drag and drop学习
- android - Drag and Drop
- html5 Drag and Drop
- Qt Drag and Drop
- JTable
- 令网站打开提高速度的7大秘方
- Oracle中的日期格式
- 14.1 EXPDP 和 IMPDP 简介
- 阮宇发的东西,以后看看
- XHtmlTree - Tree control with support for HTML, XML, Smart Checkboxes, and Drag & Drop
- SELECT INTO 和 INSERT INTO SELECT 两种表复制语句
- (Step 4)解码 XML 和 DTD
- 根据给定路径,隐藏路径外所有节点(未完)
- 网站为何打开速度慢原因分析
- XML入门精解之文件格式定义(DTD)
- C#正则表达式整理备忘
- XML Schema 与 XML DTD的技术比较与分析
- .NET与JavaScript操作CheckBox控件