相关文章推荐
玩滑板的柚子  ·  What does %~d0 mean ...·  11 月前    · 
彷徨的机器人  ·  ssh - SSHing into EC2 ...·  1 年前    · 

树视图控件是一个窗口,用于显示项的分层列表,例如文档中的标题、索引中的条目或磁盘上的文件和目录。 每个项包含一个标签和一个可选位图图像,且每个项可以有一个与之关联的子项列表。 通过单击某个项,用户可以展开或折叠关联的子项列表。

下图显示了具有根节点、展开节点和折叠节点的简单树视图控件。 该控件将一个位图用于所选项,另一位位图用于其他项。

创建树视图控件后,可以通过向控件发送消息来添加、删除、排列或其他操作项。 每个消息都有一个或多个相应的宏,可以使用该宏,而不是显式发送消息。

本部分将讨论以下主题。

  • 树视图样式
  • 父项和子项
  • 树视图标签编辑
  • 树视图项位置
  • 树视图项状态概述
  • 树视图图像列表
  • 树视图控件通知消息
  • 默认Tree-View控制消息处理
  • Tree-View样式

    树视图样式控制树视图控件外观的各个方面。 创建树视图控件时设置初始样式。 可以使用 GetWindowLong SetWindowLong 函数在创建树视图控件后检索和更改样式。

    TVS_HASLINES 样式通过绘制将子项链接到其父项的线条来增强树视图控件层次结构的图形表示形式,如下图所示。

    本身,此样式不会在层次结构的根目录中绘制线条。 为此,需要组合 TVS_HASLINES TVS_LINESATROOT 样式。 下图显示了结果。

    用户可以通过双击父项展开或折叠父项的子项列表。 具有 TVS_HASBUTTONS 样式的树视图控件将按钮添加到每个父项的左侧。 用户可以单击按钮一次,而不是双击父项展开或折叠子项。 TVS_HASBUTTONS 不会向层次结构根目录中的项添加按钮。 为此,必须合并 TVS_HASLINES TVS_LINESATROOT TVS_HASBUTTONS 。 下图显示了此样式组合。

    TVS_CHECKBOXES 样式创建每个项旁边的复选框。 如果要使用复选框样式,则必须在创建树视图控件以及填充树之前,使用 SetWindowLong ) 设置 TVS_CHECKBOXES 样式 (。 否则,复选框可能会不选中,具体取决于计时问题。 下图显示了复选框样式。

    TVS_FULLROWSELECT 样式会导致选择突出显示在控件的完整宽度上扩展,而不仅仅是项目本身。 下图显示了此样式。

    TVS_EDITLABELS 样式使用户能够编辑树视图项的标签。 有关编辑标签的详细信息,请参阅 树视图标签编辑

    有关这些样式和其他样式的详细信息,请参阅 树视图控件窗口样式

    父项和子项

    树视图控件中的任何项都可以包含与其关联的子项列表(称为 子项 )。 具有一个或多个子项的项称为 父项 。 子项显示在其父项下方,并缩进以指示它属于父项。 没有父项的项显示在层次结构顶部,称为 根项

    若要将项添加到树视图控件,请将 TVM_INSERTITEM 消息发送到控件。 该消息返回 HTREEITEM 类型的句柄,该类型唯一标识项。 添加项时,必须指定新项的父项的句柄。 如果指定 NULL 或TVI_ROOT值,而不是 TVINSERTSTRUCT 结构中的父项句柄,则将该项添加为根项。

    在任何给定时间,子项的父项列表的状态都可以为展开或折叠。 在状态为展开时,子项将显示在父项下。 当状态为折叠时,子项不会显示。 当用户双击父项时,列表会在展开状态和折叠状态之间自动切换,或者,如果用户单击与父项关联的按钮,则父项具有 TVS_HASBUTTONS 样式。 应用程序可以使用 TVM_EXPAND 消息展开或折叠子项。

    当父项的子项列表即将展开或折叠时,树视图控件会向父窗口发送 一条TVN_ITEMEXPANDING 通知消息。 通知使应用程序有机会防止更改或设置依赖于子项列表状态的父项的任何属性。 更改列表状态后,树视图控件会向父窗口发送 一条TVN_ITEMEXPANDED 通知消息。

    子项列表展开后,则将相对于父项缩进。 可以使用 TVM_SETINDENT 消息设置缩进量,也可以使用 TVM_GETINDENT 消息检索当前量。

    树视图控件使用从创建树视图控件的进程堆分配的内存。 树视图中的最大项数取决于堆中可用内存量。

    在将项添加到树视图控件时,通常指定项标签的文本。 TVM_INSERTITEM 消息包括定义项属性的 TVITEM 结构,包括包含标签文本的字符串。

    树视图控件分配用于存储每个项的内存;项标签的文本占用此内存的一个重要部分。 如果应用程序在树视图控件中保留字符串的副本,则可以通过在 TVITEM pszText 成员中指定LPSTR_TEXTCALLBACK值来减少控件的内存要求,而不是将实际字符串传递给树视图。 使用LPSTR_TEXTCALLBACK会导致树视图控件在需要重绘项目时从父窗口中检索项标签的文本。 若要检索文本,树视图控件会发送 TVN_GETDISPINFO 通知消息,其中包括 NMTVDISPINFO 结构的地址。 父窗口必须填充包含结构的相应成员。

    Tree-View标签编辑

    用户可以直接编辑具有 TVS_EDITLABELS 样式的树视图控件中项的标签。 用户通过单击具有焦点的项的标签开始编辑。 应用程序将使用 TVM_EDITLABEL 消息开始编辑。 树视图控件在编辑开始时以及取消或完成时通知父窗口。 编辑完成后,父窗口负责根据需要更新项目的标签。

    标签编辑开始时,树视图控件会向其父窗口发送 一条TVN_BEGINLABELEDIT 通知消息。 通过处理此通知,应用程序可以允许编辑某些标签并阻止编辑其他标签。 返回零允许编辑,并且返回非零会阻止它。

    当标签编辑取消或完成时,树视图控件会向其父窗口发送 一条TVN_ENDLABELEDIT 通知消息。 lParam 参数是 NMTVDISPINFO 结构的地址。 参数是一个 TVITEM 结构,用于标识项目并包括编辑的文本。 如果希望保留新标签,父窗口负责更新项目的标签。 如果取消编辑, TVITEM pszText 成员为零。

    在标签编辑期间,通常响应 TVN_BEGINLABELEDIT 通知消息,可以使用 TVM_GETEDITCONTROL 消息检索用于标签编辑的编辑控件的句柄。 可以将编辑控件发送到 EM_SETLIMITTEXT 消息,以限制用户可输入的文本量或编辑控件的子类以截获和丢弃无效字符。 但是,请注意,编辑控件仅在发送TVN_BEGINLABELEDIT 显示。

    Tree-View项位置

    使用 TVM_INSERTITEM 消息将项添加到树视图控件时,将设置项的初始位置。 该消息包括 一个 TVINSERTSTRUCT 结构,该结构指定要插入新项的父项的句柄和项的句柄。 第二个句柄必须标识给定父项的子项或以下值之一:TVI_FIRST、TVI_LAST或TVI_SORT。

    指定TVI_FIRST或TVI_LAST时,树视图控件会将新项置于给定父项子项列表的开头或末尾。 指定TVI_SORT时,树视图控件会根据项标签的文本按字母顺序将新项插入子项列表中。

    可以使用 TVM_SORTCHILDREN 消息按字母顺序放置父项的子项列表。 该消息包含一个参数,指定是否按字母顺序对给定父项降序的所有子项级别进行排序。

    TVM_SORTCHILDRENCB消息 允许根据定义的条件对子项进行排序。 使用此消息时,请指定一个应用程序定义的回调函数,每当需要确定两个子项的相对顺序时,树视图控件都可以调用该函数。 回调函数接收要比较的项的两个 32 位应用程序定义值,以及发送 TVM_SORTCHILDRENCB 时指定的第三个 32 位值。

    Tree-View项状态概述

    树视图控件中的每个项都具有当前状态。 每个项的状态信息包括一组位标志以及指示项的状态图像和覆盖图像的图像列表索引。 位标志指示该项是否已选中、禁用、展开等。 在大多数情况下,树视图控件会自动设置项的状态以反映用户操作,例如选择项。 但是,还可以使用 TVM_SETITEM 消息设置项的状态,还可以使用 TVM_GETITEM 消息检索项的当前状态。 有关项状态的完整列表,请参阅 树视图控件项状态

    项目的当前状态由 TVITEM 结构 的状态 成员指定。 树视图控件可能会更改项的状态以反映用户操作,例如选择项目或将焦点设置为项目。 此外,应用程序可能更改项的状态来禁用或隐藏项,或指定覆盖图像或状态图像。

    指定或更改项的状态时, TVITEM 的状态掩码 成员指定要设置的状态位, 状态 成员包含这些位的新值。

    若要设置项的覆盖图像, 状态掩码 必须包含 TVIS_OVERLAYMASK 值, 并且状态 必须使用 INDEXTOOVERLAYMASK 宏包含覆盖图像向左移动 8 位的基于一个依据的索引。 索引可以为零,无法指定覆盖图像。

    状态图像显示在项图标旁边,以指示应用程序定义的状态。 状态映像包含在通过发送 TVM_SETIMAGELIST 消息指定的 状态映像列表中 。 若要设置项的状态图像,请在 TVITEM 结构 的状态掩码 成员中包含 TVIS_STATEIMAGEMASK 值。 结构状态成员的位 12 到 15 位指定要绘制的图像 的状态 图像列表中的索引。

    若要设置状态映像索引,请使用 INDEXTOSTATEIMAGEMASK 。 此宏采用索引,并相应地设置位 12 到 15。 若要指示该项没有状态图像,请将索引设置为零。 此约定意味着状态映像列表中的图像零不能用作状态映像。 若要隔离 状态 成员的 12 到 15 位,请使用 TVIS_STATEIMAGEMASK 掩码。 有关覆盖和状态图像的详细信息,请参阅 树视图图像列表

    树视图控件通过发送 TVN_SELCHANGING TVN_SELCHANGED 通知消息,通知父窗口从一个项目更改为另一个项目。 这两个通知包括指定更改是鼠标单击还是击键的结果的值。 通知还包括有关将获取选择的项和将失去选择的项的信息。 您可以使用此信息设置依赖项的选择状态的项特性。 返回 TRUE 以响应TVN_SELCHANGING可防止选择发生更改,返回 FALSE 允许更改。

    应用程序可以通过发送 TVM_SELECTITEM 消息来更改选择。

    树视图控件支持许多消息,这些消息检索有关控件中的项的信息。

    TVM_GETITEM 消息可以检索项的句柄和属性。 项的属性包括其当前状态、控件的选定图像和非选定的位图图像列表中的索引、指示该项是否具有子项、项标签字符串的地址以及项的应用程序定义的 32 位值的标志。

    TVM_GETNEXTITEM 消息检索树视图项,该项具有与当前项的指定关系。 该消息可以检索项目的父项、下一个或上一个可见项、第一个子项等。

    TVM_GETITEMRECT 消息检索树视图项的边界矩形。 TVM_GETCOUNT TVM_GETVISIBLECOUNT 消息检索树视图控件中的项计数,以及树视图控件窗口中可完全可见的项计数。 可以使用 TVM_ENSUREVISIBLE 消息确保特定项可见。

    Tree-View图像列表

    树视图控件中的每个项都可以有四个与之关联的位图图像。

  • 选定项目时显示的图像,例如打开的文件夹。
  • 未选择项目时显示的图像,例如关闭的文件夹。
  • 在所选或非选定图像上以透明方式绘制的覆盖图像。
  • 状态图像,这是显示在所选图像或非选定图像左侧的其他图像。 可以使用状态图像(如已选中和清除的复选框)来指示应用程序定义的项状态。
  • 默认情况下,树视图控件不显示项图像。 若要显示项图像,必须创建图像列表并将其与控件相关联。 有关图像列表的详细信息,请参阅 图像列表

    树视图控件可以有两个图像列表:普通图像列表和状态图像列表。 普通图像列表存储所选图像、非选定图像和覆盖图像。 状态映像列表存储状态映像。 使用 ImageList_Create 函数创建图像列表,并使用其他图像列表函数将位图添加到图像列表。 然后,若要将图像列表与树视图控件相关联,请使用 TVM_SETIMAGELIST 消息。 TVM_GETIMAGELIST 消息检索树视图控件图像列表之一的句柄。 如果需要向列表添加更多图像,此消息非常有用。

    除了所选图像和非选定图像之外,树视图控件的普通图像列表最多可以包含四个覆盖图像。 覆盖图像由一个基于一个索引标识,旨在以透明方式在所选和非选定图像上绘制。 若要将覆盖掩码索引分配给普通图像列表中的图像,请调用 ImageList_SetOverlayImage 函数。

    默认情况下,所有项都显示选定状态和非选定状态正常图像列表中的第一个图像。 此外,默认情况下,项不显示覆盖图像或状态图像。 可以通过发送 TVM_INSERTITEM TVM_SETITEM 消息来更改项目的这些默认行为。 这些消息使用 TVITEM 结构指定项的图像列表索引。

    若要指定项目的选定图像和非选定图像,请在 TVITEM 结构的 掩码 成员中设置TVIF_SELECTEDIMAGE和TVIF_IMAGE位,并在 iSelectImage iImage 成员的控件的普通图像列表中指定索引。 或者,可以在 iSelectImage iImage 中指定I_IMAGECALLBACK值,而不是指定索引。 这会导致控件在每次重绘项目时查询其父窗口以获取图像列表索引。 控件发送 TVN_GETDISPINFO 通知消息以检索索引。

    若要将覆盖图像与项相关联,请使用 INDEXTOOVERLAYMASK 宏在项目的 TVITEM 结构 的状态 成员中指定覆盖掩码索引。 还必须在 stateMask 成员中设置 TVIS_OVERLAYMASK 位。 覆盖掩码索引基于一个;零的索引指示未指定覆盖图像。

    状态映像存储在单独的状态映像列表中,并由其索引标识。 若要指定状态映像列表,请发送 TVM_SETIMAGELIST 消息。 与列表视图控件不同,该控件使用基于一个索引标识状态图像,树视图控件状态图像由从零开始的索引标识。 但是,索引为零表示该项没有状态图像。 因此,图像零不能用作状态映像。 有关项状态和状态图像的进一步讨论,请参阅 树视图项状态概述

    当用户开始拖动项时,树视图控件会通知父窗口。 当用户开始使用鼠标左键拖动项目时,父窗口会收到 一条TVN_BEGINDRAG 通知消息,当用户开始使用右侧按钮拖动时 TVN_BEGINRDRAG 通知消息。 可以通过向树视图控件提供 TVS_DISABLEDRAGDROP 样式来阻止树视图控件发送这些通知。

    可以使用 TVM_CREATEDRAGIMAGE 消息在拖动操作期间获取要显示的图像。 树视图控件基于要拖动的项的标签创建拖动位图。 然后,树视图控件创建图像列表,将位图添加到其中,并将句柄返回到图像列表。

    必须提供实际拖动项的代码。 这通常涉及使用图像列表函数的拖动功能以及处理WM_MOUSEMOVE和 WM_LBUTTONUP ( WM_RBUTTONUP ) 在拖动操作开始后发送到父窗口的消息。

    如果树视图控件中的项是拖放操作的目标,则需要知道鼠标指针何时位于目标项上。 可以使用 TVM_HITTEST 消息来了解这一点。 指定包含鼠标指针当前坐标的 TVHITTESTINFO 结构的地址。 SendMessage 函数返回时,结构包含一个标志,指示鼠标指针相对于树视图控件的位置。 如果指针位于树视图控件中的项上,则结构也包含项的句柄。

    可以通过使用 TVM_SETITEM 消息将状态设置为 TVIS_DROPHILITED 值来指示项是拖放操作的目标。 使用用于指示拖放目标的样式绘制具有此状态的项。

    Tree-View控制通知消息

    树视图控件以 WM_NOTIFY 消息的形式将以下通知消息发送到其父窗口。

    WM_KEYDOWN 将所有密钥的 TVN_KEYDOWN 通知消息发送到父窗口。 当用户按下 Enter 键时,发送 NM_RETURN (树视图) 通知消息。 当用户按下方向键或 PAGE UP、PAGE DOWN、HOME、END 或 BACKSPACE 键时,它会移动插入符号。 当用户按下 CTRL 键与这些键结合使用时,它会滚动树视图控件。 如果处理密钥,则返回 TRUE ;否则返回 FALSE WM_KILLFOCUS 重新绘制焦点项(如果有)并将 NM_KILLFOCUS (树视图) 通知消息发送到父窗口。 WM_LBUTTONDBLCLK 取消标签编辑,如果双击某个项,则向父窗口发送 NM_DBLCLK (树视图) 通知消息。 如果父窗口返回 0,则树视图控件将切换项目的展开状态,将父窗口发送到 TVN_ITEMEXPANDING TVN_ITEMEXPANDED 通知消息。 没有返回值。 WM_LBUTTONDOWN 如果用户单击与父项关联的按钮,则切换展开状态。 如果用户单击了项标签,则树视图控件将选择并将焦点设置为该项。 如果用户在释放鼠标按钮之前移动鼠标,则树视图控件将开始拖放操作。 没有返回值。 WM_PAINT 绘制树视图控件的无效区域。 它返回零。 如果 wParam 参数为非 NULL ,则控件假定该值是设备上下文的句柄, (HDC) 并使用该设备上下文进行绘制。 WM_RBUTTONDOWN 检查是否单击了某个项,并开始拖动操作。 如果操作已开始,它会向父窗口发送 TVN_BEGINRDRAG 通知消息,并突出显示放置目标。 否则,它会将 NM_RCLICK (树视图) 通知消息发送到父窗口。 没有返回值。 WM_SETFOCUS 重新绘制焦点项(如果有)并将 NM_SETFOCUS 通知消息发送到父窗口。 WM_SETFONT 保存指定的字体句柄,并使用新字体重新绘制树视图控件。 WM_SETREDRAW 设置或清除重绘标志。 设置重绘标志后,将重绘树视图控件。 它返回零。 WM_SIZE 重新计算取决于树视图控件的工作区大小的内部变量。 它返回 TRUE WM_STYLECHANGED 使用新样式取消标签编辑和重绘树视图控件。 它返回零。 WM_SYSCOLORCHANGE 如果设置了重绘标志,请使用新颜色重新绘制树视图控件。 没有返回值。 WM_TIMER 开始编辑项目标签。 如果用户单击焦点项的标签,则树视图控件会设置计时器,而不是立即进入编辑模式。 如果用户双击标签,则计时器可以避免树视图进入编辑模式。 它返回零。 WM_VSCROLL 滚动树视图控件。 如果发生滚动,则返回 TRUE ;否则返回 FALSE