关于编辑控件
编辑控件是一个矩形控件窗口,通常用于对话框中,使用户能够输入和编辑文本。
编辑控件既支持字符为两个字节的 Unicode 字符集,也支持字符为一个字节的 ANSI 字符集。 有关 Unicode 和 ANSI 字符集的详细信息,请参阅 Unicode 和字符集。
Rich Edit 控件支持许多系统编辑控件中不可用的功能。 有关详细信息,请参阅 Rich Edit 控件。
本概述将讨论以下主题。
编辑控件功能
选中后,编辑控件会显示一个闪烁的插入符号,指示插入点。 然后,用户可以使用键盘或鼠标输入文本、移动插入点或选择要编辑的文本。 编辑控件以 WM_COMMAND 消息的形式将通知代码发送到其父窗口。 有关编辑控件中消息的详细信息,请参阅编辑控件通知消息。 父窗口可以通过调用 SendDlgItemMessage 函数向对话框中的编辑控件发送消息。 某些消息也可以通过使用预定义的宏来发送。
系统同时提供单行编辑控件和多行编辑控件。 编辑控件属于 EDIT 窗口类。
组合框是一种将编辑控件和列表框的大部分功能组合在一起的控件。 在组合框中,编辑控件显示当前选择,列表框显示用户可以选择的选项。 有关组合框的详细信息,请参阅组合框。
许多开发人员使用公共对话框库 (Comdlg32.dll) 中提供的对话框来执行其他可能需要自定义编辑控件的任务。 有关通用对话框的信息,请参阅通用对话框库。
编辑控件类型和样式
单个编辑控件可以同时具有多个样式。 大多数开发人员使用工具开发对话框,因此可能不需要显式指定编辑控件样式。 但是,如果应用程序使用 CreateWindow 或 CreateWindowEx 函数创建编辑控件,则必须指定这些编辑控件样式。 有关编辑控件样式表,请参阅编辑控件样式。
每个编辑控件都指定一组样式值,这些样式值定义编辑控件的外观和功能。 样式值可以建立单行或多行编辑控件的外观;对齐控件中的文本;并确定文本在编辑控件中的显示方式,甚至是否显示。
多行样式
编辑控件有两种行样式。 默认为单行编辑控件。 应用程序还可以使用 ES_MULTILINE 样式创建多行编辑控件。
滚动样式
ES_AUTOHSCROLL 样式告知编辑控件在用户输入文本时水平滚动文本。 如果未指定此样式,则编辑控件无法水平滚动。 对于没有 ES_AUTOHSCROLL 的单行编辑控件,仅接受填充控件可见区域的字符。 对于没有 ES_AUTOHSCROLL 的多行编辑控件,当用户输入的文本多于单个行中显示的文本时,文本将换行到下一行。 如果为多行编辑控件指定了 ES_AUTOHSCROLL,则当用户输入的文本数超过单个行中显示的文本时,该控件将水平滚动;文本不会换行。
ES_AUTOHSCROLL 自动应用于具有 WS_HSCROLL 样式的左对齐多行编辑控件。 换句话说,具有水平滚动条的任何左对齐的多行编辑控件都将自动水平滚动。
ES_AUTOHSCROLL 被未左对齐的多行编辑控件忽略。 居中和右对齐的多行编辑控件不能水平滚动
ES_AUTOVSCROLL 样式告知编辑控件当用户输入的文本多于可在编辑控件中显示的文本时垂直滚动文本。 此样式仅适用于多行编辑控件。 如果未为多行编辑控件指定此样式,则当输入的文本多于可以显示时,编辑控件将不接受输入。
对齐样式
有三种样式可使系统对齐编辑控件中的文本。 ES_LEFT、ES_CENTER 和 ES_RIGHT 样式分别确定文本是左对齐、居中对齐还是右对齐。 右对齐和居中多行编辑控件不能具有 ES_AUTOHSCROLL 样式;也就是说,它们不能水平滚动。
尽管无法动态更改编辑控件的对齐样式,但以下技术可用于解决此限制:
- 创建多个编辑控件,一个用于应用程序所需的每个样式,并根据需要在它们之间切换。
- 根据需要创建具有所需样式的新编辑控件,然后切换到新控件。
文本和输入样式
应用程序可以使用样式指定编辑控件显示文本的方式。 ES_LOWERCASE 样式会将输入编辑控件的所有大写字符转换为小写。 同样,ES_UPPERCASE 样式会将所有小写字符转换为大写。
有关字符集的详细信息,请参阅 Unicode 和字符集。
ES_NUMBER 样式仅在编辑控件中将输入限制为数字。
ES_READONLY 样式将编辑控件更改为只读状态。
ES_PASSWORD 样式将单行编辑控件中的所有字符显示为星号。 应用程序可以通过使用 EM_SETPASSWORDCHAR 消息来定义要显示的不同字符,如本主题后面所述。
如果编辑控件来自 Comctl32.dll 版本 6,则黑色圆圈是 ES_PASSWORD 样式的默认字符。 在以前版本的常用控件的编辑控件中,默认字符是星号。
ES_OEMCONVERT 样式使输入到编辑控件中的文本从 Windows 字符集转换为 OEM 字符集,然后转换回 Windows 字符集。 当应用程序调用 CharToOem 函数将编辑控件中的 Windows 字符串转换为 OEM 字符时,这可确保正确的字符转换。 ES_OEMCONVERT 最适用于包含将在不支持 Unicode 的文件系统上使用的文件名的编辑控件。
对于对话框中的多行编辑控件,当用户在输入文本时按 ENTER 键时,ES_WANTRETURN 样式会使控件插入回车符。 如果未指定此样式,则按 Enter 键的效果与按对话框中的默认按钮的效果相同。 如果没有 ES_WANTRETURN,用户必须按 Ctrl+Enter 插入回车符。 有关自动换行和换行符的信息,请参阅处理自动换行和换行符。
视觉样式
当编辑控件没有焦点时,ES_NOHIDESEL 样式会使所选文本保持高亮显示。 如果没有此样式,所选文本将在控件失去焦点时丢失突出显示。
默认情况下,编辑控件没有边框。 若要提供一个,应用程序可以使用 WS_BORDER 窗口样式。
若要对这些编辑控件使用视觉样式,应用程序必须包含清单,并且必须在程序开头调用 InitCommonControls 函数。 有关视觉样式的信息,请参阅视觉样式。 有关清单信息,请参阅启用视觉样式。
文本缓冲区
系统将编辑控件文本存储在缓冲区中,并根据需要将其复制到控件。
以下主题讨论系统如何分配和初始化缓冲区并更改其特征:
分配文本缓冲区
当系统创建编辑控件时,它会自动创建文本缓冲区,设置其初始大小,并根据需要增加大小。 对于单行编辑控件,大小可以高达大约 32 千字节 (KB) 的预定义限制。 由于此限制可能会更改,因此称为软限制。 应用程序可以通过将 EM_SETLIMITTEXT 消息发送到编辑控件来设置缓冲区大小的硬限制。 如果缓冲区超出任一限制,系统会向应用程序发送 EN_ERRSPACE 通知代码。 应用程序可以通过发送 EM_GETLIMITTEXT 消息来检索当前文本限制。
系统通常使用应用程序数据段外的内存在对话框中创建编辑控件缓冲区。 应用程序可以在创建编辑控件时抑制此默认分配行为,并使用 DS_LOCALEDIT 样式(请参阅关于对话框中的“对话框模板样式”)从其本地堆创建缓冲区。 使用 DS_LOCALEDIT 样式的应用程序负责所有缓冲区分配。 若要进行初始分配,应用程序可以调用 LocalAlloc 函数,并通过向其发送EM_SETHANDLE 消息将返回的缓冲区句柄传递给编辑控件。 若要进行后续分配(例如,响应 EN_ERRSPACE 通知代码),应用程序应保存当前缓冲区内容(如有必要),并获取如下所示的新缓冲区。
若要保存当前缓冲区并获取新缓冲区,请遵循此过程。
- 通过向控件发送 EM_GETHANDLE 消息,检索多行编辑控件中当前为文本分配的内存句柄。
- 通过调用 LocalFree 函数释放缓冲区。
- 通过调用 LocalAlloc 获取新的缓冲区(和缓冲区句柄)。
- 通过向系统发送 EM_SETHANDLE 消息,为系统提供缓冲区句柄。
EM_SETHANDLE 和 EM_GETHANDLE 消息仅适用于多行编辑控件。
使用默认分配行为(即不使用 DS_LOCALEDIT 样式(请参阅关于对话框中的“对话框模板样式”))的应用程序不得将 EM_SETHANDLE 和 EM_GETHANDLE 消息发送到编辑控件。
发送 EM_SETHANDLE 消息会产生多种副作用:清除撤消标志(使 EM_CANUNDO 消息返回零),清除修改标志(使 EM_GETMODIFY 消息返回零),并重新绘制编辑控制窗口。
初始化文本缓冲区
应用程序可以通过调用 SetDlgItemText 函数初始化或重新初始化编辑控件的文本缓冲区。 应用程序可以通过调用 GetDlgItemText 函数来检索文本缓冲区的内容。
将文本缓冲区设置为只读
对于每个编辑控件,系统都会维护一个只读标志,用于指示控件的文本是读/写(默认值)还是只读。 应用程序可以通过向控件发送 EM_SETREADONLY 消息来设置文本的读/写标志或只读标志。 若要确定编辑控件是否为只读,应用程序可以使用 GWL_STYLE 常量调用 GetWindowLong 函数。 EM_SETREADONLY 消息适用于单行和多行编辑控件。
更改格式化矩形
编辑控件文本的可见性由其窗口矩形及其格式矩形的尺寸控制。 窗口矩形是包含编辑控件的窗口的工作区。 格式矩形是由系统维护的构造,用于设置窗口矩形中显示的文本的格式。 首次显示编辑控件时,屏幕上的两个矩形完全相同。 应用程序可以使格式矩形大于窗口矩形(从而限制编辑控件文本的可见性),或小于窗口矩形(从而在文本周围创建额外的空白)。
应用程序可以通过发送 EM_SETRECT 消息来设置编辑控件格式矩形的坐标。 EM_SETRECT 消息还会自动重绘编辑控件的文本。 若要在不重绘控件文本的情况下建立格式矩形的坐标,应用程序可以向控件发送 EM_SETRECTNP 消息。 若要检索格式矩形的坐标,应用程序可以向控件发送 EM_GETRECT 消息。 这些消息仅适用于多行编辑控件。
编辑控件通知消息
用户通过使用键盘和鼠标发出编辑请求。 系统以 WM_COMMAND 消息的形式将每个请求发送到编辑控件的父窗口。 该消息包括 wParam 参数的低位字中的编辑控件标识符、 lParam 参数中编辑控件的句柄,以及 wParam 参数的高位字中对应于用户动作的编辑控件通知代码。
应用程序检查每个通知消息随附的通知代码并相应地做出响应。 下表列出了每个编辑控件通知代码以及生成它的操作。
通知代码 | 用户操作 |
---|---|
EN_CHANGE | 用户在编辑控件中修改了文本。 系统在发送此通知代码之前更新显示(与 EN_UPDATE 不同)。 |
EN_ERRSPACE | 编辑控件无法分配足够的内存来满足特定请求。 |
EN_HSCROLL | 用户单击编辑控件的水平滚动条。 系统在更新屏幕之前发送此通知代码。 |
EN_KILLFOCUS | 用户选择了另一个控件。 |
EN_MAXTEXT | 插入文本时,用户已超过编辑控件的指定字符数。 插入已被截断。 当编辑控件没有 ES_AUTOHSCROLL 样式且要插入的字符数超过编辑控件的宽度或编辑控件没有 ES_AUTOVSCROLL 样式且要插入的行总数超过编辑控件的高度时,也会发送此通知代码。 |
EN_SETFOCUS | 用户已选择此编辑控件。 |
EN_UPDATE | 用户已更改编辑控件中的文本,并且系统将显示新文本。 系统在设置文本格式之后发送此通知代码,但在显示文本之前,以便应用程序可以调整编辑控件窗口的大小。 |
EN_VSCROLL | 用户单击了编辑控件的垂直滚动条,或者将鼠标滚轮滚动到编辑控件上。 系统在更新屏幕之前发送此通知代码。 |
EN_SEARCHWEB | 用户已单击“搜索 Web”上下文菜单项。 系统在启动浏览器后发送此通知。 |
此外,在绘制编辑控件之前,系统将 WM_CTLCOLOREDIT 消息发送到编辑控件的父窗口。 此消息包含编辑控件的显示上下文 (DC) 的句柄和子窗口的句柄。 父窗口可以使用这些句柄更改编辑控件的文本和背景色。
编辑控件默认消息处理
预定义编辑控件窗口类的窗口过程对编辑控件过程不处理的所有消息执行默认处理。 当编辑控件过程对任何消息返回 FALSE 时,预定义的窗口过程会检查消息并执行以下默认操作。
Message | 默认操作 |
---|---|
EM_CANUNDO | 如果可以撤消编辑控件操作,则返回 TRUE。 |
EM_CHARFROMPOS | 返回离指定点最近的字符的字符索引和行索引。 |
EM_EMPTYUNDOBUFFER | 清空撤消缓冲区,并将 EM_CANUNDO 消息检索的撤消标志设置为 FALSE。 每当编辑控件收到 WM_SETTEXT 或 EM_SETHANDLE 消息时,系统会自动清除撤消标志。 |
EM_FMTLINES | 在多行编辑控件中,将软换行符(两个回车符和换行符)添加到换行符的末尾。 它不由单行编辑控件处理。 |
EM_GETFIRSTVISIBLELINE | 返回单行编辑控件中第一个可见字符的从零开始的索引,或多行编辑控件中最上面可见行的从零结束的索引。 |
EM_GETHANDLE | 返回一个句柄,该句柄标识包含多行编辑控件的文本的缓冲区。 它不由单行编辑控件处理。 |
EM_GETLIMITTEXT | 以字符为单位返回当前文本限制。 |
EM_GETLINE | 将单行编辑控件中的字符复制到缓冲区,并返回复制的字符数。 在多行编辑控件中,从控件中检索文本行并返回复制的字符数。 |
EM_GETLINECOUNT | 返回编辑控件中的行数。 |
EM_GETMARGINS | 返回左右边距的宽度。 |
EM_GETMODIFY | 返回一个标志,指示编辑控件的内容是否已修改。 |
EM_GETPASSWORDCHAR | 返回编辑控件与 ES_PASSWORD 样式结合使用的字符。 |
EM_GETRECT | 返回编辑控件中格式矩形的坐标。 |
EM_GETSEL | 返回编辑控件中当前所选内容的起始和结束字符位置。 |
EM_GETTHUMB | 返回多行编辑控件中滚动框在垂直滚动条中的位置。 |
EM_GETWORDBREAKPROC | 返回编辑控件中当前 Wordwrap 函数的地址。 |
EM_LINEFROMCHAR | 返回包含指定字符索引的多行编辑控件中的行的从零开始的数字。 此消息是 EM_LINEINDEX 消息的反向消息。 它不由单行编辑控件处理。 |
EM_LINEINDEX | 返回多行编辑控件中的行的字符。 此消息是 EM_LINEFROMCHAR 消息的反向消息。 它不由单行编辑控件处理。 |
EM_LINELENGTH | 返回单行编辑控件的长度(以字符为单位)。 在多行编辑控件中,返回指定行的长度(以字符为单位)。 |
EM_LINESCROLL | 在单行编辑控件中垂直滚动文本,或在多行编辑控件中水平滚动(当控件具有 ES_LEFT 样式时)。 lParam 参数指定要从当前行开始垂直滚动的行数。 wParam 参数指定要从当前字符开始水平滚动的字符数。 |
EM_POSFROMCHAR | 返回指定字符的客户端坐标。 |
EM_REPLACESEL | 将当前所选内容替换为应用程序提供的缓冲区中的文本,向父窗口发送 EN_UPDATE 和 EN_CHANGE 通知代码,并更新撤消缓冲区。 |
EM_SCROLL | 在多行编辑控件中垂直滚动文本。 此消息等效于将 WM\_VSCROLL 消息发送到编辑控件。 它不由单行编辑控件处理。 |
EM_SCROLLCARET | 将插入符号滚动到编辑控件的视图中。 |
EM_SETFONT | 不支持。 |
EM_SETHANDLE | 设置用作文本缓冲区的内存的句柄,清空撤消缓冲区,将滚动位置重置为零,并重绘窗口。 |
EM_SETLIMITTEXT | 设置用户可以在编辑控件中输入的最大字符数。 对于单行编辑控件,此值为 0x7FFFFFFE 或 wParam 参数的值(以较小者为准)。 对于多行编辑控件,此值为 1 或 wParam 参数的值(以较小者为准)。 |
EM_SETMARGINS | 设置左右边距的宽度,并重新绘制编辑控件以反映新的边距。 |
EM_SETMODIFY | 设置或清除修改标志,以指示编辑控件是否已被修改。 |
EM_SETPASSWORDCHAR | 定义编辑控件与 ES_PASSWORD 样式结合使用的字符。 |
EM_SETREADONLY | 设置或删除编辑控件的只读样式 (ES_READONLY)。 |
EM_SETRECT | 设置多行编辑控件的格式矩形并重绘窗口。 它不由单行编辑控件处理。 |
EM_SETRECTNP | 设置多行编辑控件的格式矩形,但不重绘窗口。 它不由单行编辑控件处理。 |
EM_SETSEL | 通过设置要选择的起始位置和结束位置,在编辑控件中选择一系列字符。 |
EM_SETTABSTOPS | 设置多行编辑控件中的制表位位置。 它不由单行编辑控件处理。 |
EM_SETWORDBREAKPROC | 将默认 Wordwrap 函数替换为应用程序定义的 Wordwrap 函数。 |
EM_UNDO | 删除刚刚插入的任何文本或插入任何已删除的字符,并将所选内容设置为插入的文本。 如有必要,将 EN_UPDATE 和 EN_CHANGE 通知代码发送到父窗口。 |
WM_CHAR | 将字符写入单行编辑控件,并将 EN_UPDATE 和 EN_CHANGE 通知代码发送到父窗口。 将字符写入多行编辑控件。 处理标准函数的快捷键,例如用于复制的 Ctrl+C 和用于粘贴的 Ctrl+V。 在多行编辑控件中,还处理 TAB 和 Ctrl+TAB 键击,以在对话框中的控件之间移动,并将制表符插入多行编辑控件。 对非法字符使用 MessageBeep 函数。 |
WM_CLEAR | 清除编辑控件中的当前选定内容(如果有)。 如果没有当前选择,请删除插入符号右侧的字符。 如果用户按 Shift 键,则会将所选内容剪切到剪贴板,或者在没有选定内容时删除插入点左侧的字符。 如果用户按 Ctrl 键,则这会删除所选内容,或者在没有选择时将其删除到行尾。 |
WM_COPY | 除非样式为 ES_PASSWORD,否则将文本复制到剪贴板,在这种情况下,消息返回零。 |
WM_CREATE | 创建编辑控件,并用 TRUE 表示成功 或 1 表示失败通知父窗口。 |
WM_CUT | 将所选内容剪切到剪贴板,或者删除光标左侧的字符(如果没有选择)。 |
WM_ENABLE | 使单行编辑控件的矩形重新绘制为灰色。 返回单行和多行编辑控件的启用状态。 |
WM_ERASEBKGND | 使用编辑控件的当前颜色填充多行编辑控件窗口。 |
WM_GETDLGCODE | 返回以下值:DLGC_WANTCHARS、DLGC_HASSETSEL 和 DLGC_WANTARROWS。 在多行编辑控件中,还返回 DLGC_WANTALLKEYS。 如果用户按 Alt+BACKSPACE,则还返回 DLGC_WANTMESSAGE。 |
WM_GETFONT | 返回控件使用的字体句柄;如果控件使用系统字体,则返回 NULL。 |
WM_GETTEXT | 将指定的字符数复制到缓冲区,并返回复制的字符数。 |
WM_GETTEXTLENGTH | 返回编辑控件中文本的长度(以字符为单位)。 长度不包括 null 终止字符。 |
WM_HSCROLL | 水平滚动多行编辑控件中的文本并处理滚动框移动。 |
WM_KEYDOWN | 对虚拟密钥代码执行标准处理。 |
WM_KILLFOCUS | 删除编辑控件窗口的键盘焦点,销毁插入符号,隐藏当前选定内容,并通知父窗口编辑控件已失去焦点。 |
WM_LBUTTONDBLCLK | 清除当前选定内容并选择光标下的单词。 如果 SHIFT 键处于低位,请将所选内容扩展到光标下的单词。 |
WM_LBUTTONDOWN | 更改当前插入点。 如果 SHIFT 键处于低位,请将所选内容扩展到光标的位置。 在多行编辑控件中,还设置计时器,当用户按住多行编辑控件窗口外的鼠标按钮时自动滚动。 |
WM_LBUTTONUP | 释放鼠标捕获并在单行编辑控件中设置文本插入点。 在多行编辑控件中,还会终止 WM_LBUTTONDOWN 消息中的计时器集。 |
WM_MOUSEMOVE | 如果鼠标按钮关闭,则更改单行编辑控件中的当前选定内容。 在多行编辑控件中,还设置计时器,如果用户按住多行编辑控件窗口外的鼠标按钮则自动滚动。 |
WM_NCCREATE | 指向窗口的 CREATESTRUCT 结构的指针。 首次创建窗口时,此消息会发送到 WM_CREATE 消息。 |
WM_NCDESTROY | 释放与编辑控件窗口关联的所有内存,包括文本缓冲区、撤消缓冲区、制表位缓冲区和突出显示画笔。 |
WM_PAINT | 擦除背景,用编辑控件窗口的当前颜色填充窗口,绘制边框(如果有),设置字体并绘制任何文本,并显示文本插入插入符号。 |
WM_PASTE | 将文本从剪贴板粘贴到插入符号位置的编辑控件窗口中。 |
WM_SETFOCUS | 设置编辑控件窗口的键盘焦点(显示当前所选内容,如果它已被隐藏),并创建插入符号。 |
WM_SETFONT | 设置字体,并选择性地重绘编辑控件。 |
WM_SETTEXT | 将文本复制到单行编辑控件,在内存不足时通知父窗口,清空撤消缓冲区,并将 EN_UPDATE 和 EN_CHANGE 通知代码发送到父窗口。 在多行编辑控件中,还重新包装行(如有必要),并设置滚动位置。 |
WM_SIZE | 设置编辑控件窗口的大小,确保大小适应字符的高度和宽度。 |
WM_SYSCHAR | 如果用户按下 Alt+BACKSPACE,则返回 TRUE;否则不执行任何操作。 |
WM_SYSKEYDOWN | 如果用户按下 ALT+BACKSPACE,则撤消最后一个操作;否则不执行任何操作。 |
WM_TIMER | 如果用户按住多行编辑控件窗口外的鼠标按钮,则滚动编辑控件窗口中的文本。 |
WM_UNDO | 删除刚刚插入的任何文本或插入任何已删除的字符,并将所选内容设置为插入的文本。 如有必要,将 EN_UPDATE 和 EN_CHANGE 通知代码发送到父窗口。 |
WM_VSCROLL | 垂直滚动多行编辑控件并处理滚动框移动。 它不由单行编辑控件处理。 |
预定义的编辑控件窗口过程将所有其他消息传递到 DefWindowProc 函数,以便进行默认处理。