WIN32汇编 Richedit控件的使用
Posted 小哈龙
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WIN32汇编 Richedit控件的使用相关的知识,希望对你有一定的参考价值。
这次来介绍一下一个独特的控件------Richedit 说实话这次也是第一次接触到这个控件,以前虽然听说过但是不知道具体它是干什么的,从字面上看好像是edit控件的扩展一样,其实这样只说对了一半,Richedit控件确实比edit控件功能强大丰富,但是它们的使用位置不同,edit控件以前在学习控件的时候,就出现了许多edit控件,那时候用edit控件主要是实现向一个小的文本框中输入文本而且基本都是用在对话框中,而且大小也有限制,在单行模式下能容纳的文本不能超过32KB,在多行模式下也不能超过64KB,加上这个限制想要实现多文本的输入那就有点麻烦了,而且不能实现文本格式,大小颜色等属性的设置,出于此种原因,Richedit控件就有了大显身手的机会,它可以实现多文本的输入,但是需要指定大小(发送EM_EXLIMITTEXT,因为默认情况下控件还是将最大字符数限制为64KB),这个控件因为功能复杂,代码量较大,微软给它独立使用一个动态链接库存储(Riched32.dll 1.0版,Riched20.dll(2.0和3.0版)),具体功能看一下下表(罗云斌老师书中的一张介绍图)
1.0版 | 2.0版 | 3.0版 | |
DLL库文件名 | Riched32.dll | Riched32.dll | Riched32.dll |
控件的类名 | Richedit | Richedit20A Richedit20W |
Richedit20A Richedit20W |
拖放编辑 | 支持 | 支持 | 支持 |
流输入输出 | 支持 | 支持 | 支持 |
Unicode编辑 | 不支持 | 支持 | 支持 |
非窗口操作 | 不支持 | 支持 | 支持 |
自动URL识别 | 不支持 | 支持 | 支持 |
加速键 | 不支持 | 支持 | 支持 |
分行符 | CR+LF | CR | CR(可模拟1.0版) |
撤销/重做 | 支持单级 | 支持多级 | 支持多级 |
文本搜索 | 向前搜索 | 向前/向后搜索 | 向前/向后搜索 |
知道了Richedit控件的大致功能,接下来就需要知道怎么来实现相关的功能,分为如下几步来实现:
菜单 | IDR_MENU1 |
加速键 | IDR_ACCELERATOR1 |
光标 | IDI_ICON1 |
控件的流操作 | _ProcStream() |
文件的保存 | _SaveFile() |
打开文件 | _OpenFile() |
检测文件修改 | _CheckModify() |
查找文字 | _FindText() |
实时改变菜单项状态 | _SetStatus() |
窗口内容初始化 | _Init() |
退出程序 | _Quit() |
窗口过程 | _ProcWinMain() |
主函数 | _WinMain() |
下面来回顾一下写程序的时候遇见的一些问题:
首先是资源文件,依然使用ResEdit编写,这次的资源文件需要定义的有图标,菜单,另外一个就是加速键(这个加速键好久没有写过了感觉有点陌生了,以前还是和菜单一起学习的,菜单现在已经非常熟练了,要写加速键还要再翻一下以前的文章。。。)下面简单总结一下:
键名-----表示加速键对应的按钮可以有3种方式定义:
1.“^字母”: 表示Ctrl加上字母键
2.“字母” : 表示字母,这时的类型必须指明是VIRTKEY
3. 数值 :表示ASCII码为该数值的字母,这是类型必须指明为ASCII
(在使用ResEdit编写的时候直接在键名这一项输入相应的字母,就可以了,工具已经自动处理过了)
命令ID------按下加速键后,windows向程序发送的命令ID,如果要把加速键和菜单关联起来,这里就是要关联菜单项的命令ID。这个容易理解其实就是命令ID
类型---------用来指定键的定义方式,可以是VIRKEY和 ASCII,分别用来表示“键名”字段定义的是虚拟键还是ASCII码
选项-------- 可以是ALt,Control或Shift中的单个或多个,如果指定多个,则中间用逗号隔开,表示加速键是按键加上这些控制键的组合键。
这样就清楚多了。
在使用ResEdit工具添加图标资源的时候,在创建新的图标资源的时候程序总会崩溃(有时候不会),这个我也没有解决,工具出错退出,一开始我以为是误删了什么文件但是从新安装之后还是如此,但是在创建资源文件的时候首先定义图标文件,创建新图标这样一般可以。下面看一下资源代码:
// Generated by ResEdit 1.6.6
// Copyright (C) 2006-2015
// http://www.resedit.net
#include <windows.h>
#include <commctrl.h>
#include <richedit.h>
#include "resource.h"
//
// Menu resources
//
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDR_MENU1 MENU
{
POPUP "文件(&F)"
{
MENUITEM "打开文件(&O)...\tCtrl+O", IDM_OPEN
MENUITEM "保存文件(&S)\tCtrl+S", IDM_SAVE
MENUITEM SEPARATOR
MENUITEM "退出(&X)", IDM_EXIT
}
POPUP "编辑(&E)"
{
MENUITEM "撤销(&Z)\tCtrl+Z", IDM_UNDO
MENUITEM "重复(&Y)\tCtrl+Y", IDM_REDO
MENUITEM SEPARATOR
MENUITEM "全选(&A)\tCtrl+A", IDM_SELALL
MENUITEM "拷贝(&C)\tCtrl+C", IDM_COPY
MENUITEM "剪切(&X)\tCtrl+X", IDM_CUT
MENUITEM "粘贴(&V)\tCtrl+V", IDM_PASTE
MENUITEM SEPARATOR
MENUITEM "查找(&F)\tCtrl+F", IDM_FIND
MENUITEM "查找上一个(&P)\tF2", IDM_FINDPREV
MENUITEM "查找下一个(&N)\tF3", IDM_FINDNEXT
}
}
// Accelerator resources
//
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDR_ACCELERATOR1 ACCELERATORS
{
VK_F2, IDM_FINDPREV, VIRTKEY
VK_F3, IDM_FINDNEXT, VIRTKEY
"O", IDM_OPEN, ASCII
"S", IDM_SAVE, ASCII
"Z", IDM_UNDO, ASCII
"Y", IDM_REDO, ASCII
"A", IDM_SELALL, ASCII
"C", IDM_COPY, ASCII
"X", IDM_CUT, ASCII
"V", IDM_PASTE, ASCII
"F", IDM_FIND, ASCII
}
//
// Icon resources
//
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDI_ICON1 ICON ".\\IDI_ICON1.ico"
下面来看一下程序实现过称中遇见的问题:
首先是一个以前接触很少的问题:文本流(流入流出),说到流操作首先我想到的是C++里面的流输入输出(我接触的编程语言比较少。。只懂点C/C++和汇编)文件流的基本操作:1、打开文件 2、读取数据 3、处理数据 4、数据写回 5、关闭文件。WIN32汇编语言中文件流的操作的相关函数有两个(读入流入:ReadFile() 写出流出:WriteFile() ),其他的就涉及到需要发送的windows消息。当需要将文件读入到控件的时候,可以向控件发送EM_STREAMIN消息,当需要将文件从控件保存到文本文件时发送EM_STREAMOUT,消息的参数中附带需要流入的文本内容格式,以及回调函数(提前自定义的函数实现读写文件的功能模块)等信息,Richedit控件会循环调用回调函数直到处理完全部的文本内容,在控件每次调用回调函数的时候,控件通过参数(控件会将流操作函数中需要的参数指定,然后再传递给回调函数,我感觉那些参数是控件内部整理的,不需要我们来指定)告诉回调函数要读写的字节数和缓冲区的地址,在程序中流入流出操作的回调函数使用的是同一个子程序_ProcStream(),在该子程序中通过判断 向控件发送的消息中的lParam参数中的lpStream指向的一个EDITSTREAM结构中的dwCookie字段(这个字段可以由我们自己定义程序中定义的是TRUE和FALSE,这些定义都无所谓,都是一样的)来确定是要进行流入(TRUE)还是流出(FALSE)操作,接下来就要使用上面介绍的那两个API函数了,这个问题刚接触很不好理解,有些地方现在依然理解的不到位。
下一个问题就是在查找文字子函数_FindText()中,在设置查找选项的时候程序代码入如下:
mov @stFindText.lpstrText,offset szFindText ;将szFindText变量的地址传递给
FINDTEXTEX结构体类型的变量@stFindText的lpstrText字段
mov ecx,stFind.Flags ;将stFind结构体变量查找标识字段内容传递给ecx
andecx,FR_MATCHCASE or FR_DOWN or FR_WHOLEWORD ;将stFind结构体变量中的所有查找字符标示屏蔽除了 FR_MATCHCASE
or FR_DOWN or FR_WHOLEWORD这几个标识.
在上面的代码中使用了and运算(按位相与 1 and 1 =1 1 and 0 =0)将其他不需要的标识屏蔽掉(不同的位代表不同的标识)这是我的理解,可能也有错误。
下面就是在保存文件功能模块中遇见的问题
使用两个函数将文件清空,代码如下:
invoke SetFilePointer,hFile,0,0,FILE_BEGIN
invoke SetEndOfFile,hFile
利用SetFilePointer函数返回当前的文件指针,然后再使用SetEndOfFile函数从当前文件指针处截断,除去后面的内容,从而达到将文件清空的目的。这个有点不容易理解。
下面看一下程序源代码:
.386
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
include comdlg32.inc
includelib comdlg32.lib
IDR_MENU1 equ 100
IDR_ACCELERATOR1 equ 101
IDI_ICON1 equ 103
IDM_OPEN equ 40000
IDM_SAVE equ 40001
IDM_COPY equ 40002
IDM_EXIT equ 40003
IDM_UNDO equ 40004
IDM_REDO equ 40005
IDM_SELALL equ 40006
IDM_CUT equ 40007
IDM_PASTE equ 40008
IDM_FIND equ 40009
IDM_FINDPREV equ 40010
IDM_FINDNEXT equ 40011
.data?
hInstance dd ?
hWinMain dd ?
hMenu dd ?
hWinEdit dd ?
hFile dd ?
hFindDialog dd ?
idFindMessage dd ?
szFileName db MAX_PATH dup (?)
szFindText db 100 dup (?)
.data
stFind FINDREPLACE <sizeof FINDREPLACE,0,0,FR_DOWN,szFindText,0,sizeof szFindText,0,0,0,0>
.const
FINDMSGSTRING db ‘commdlg_FindReplace‘,0
szClassName db ‘wordpad‘,0
szCaptionMain db ‘记事本‘,0
szDllEdit db ‘RichEd20.dll‘,0
szClassEdit db ‘RichEdit20A‘,0
szNotFound db ‘字符串未找到!‘,0
szFilter db ‘Text Files(*.txt)‘,0,‘*.txt‘,0
db ‘All Files(*.*)‘,0,‘*.*‘,0,0
szDefaultExt db ‘txt‘,0
szErrOpenFile db ‘无法打开文件!‘,0
szModify db ‘文件已修改,是否保存?‘,0
szFont db ‘宋体‘,0
.code
_ProcStream proc uses ebx edi esi _dwCookie,_lpBuffer,_dwBytes,_lpBytes
.if _dwCookie
invoke ReadFile,hFile,_lpBuffer,_dwBytes,_lpBytes,0 ;读入
.else
invoke WriteFile,hFile,_lpBuffer,_dwBytes,_lpBytes,0 ;读出
.endif
xor eax,eax
ret
_ProcStream endp
_SaveFile proc
LOCAL @stES:EDITSTREAM
invoke SetFilePointer,hFile,0,0,FILE_BEGIN
invoke SetEndOfFile,hFile
mov @stES.dwCookie,FALSE
mov @stES.pfnCallback,offset _ProcStream
invoke SendMessage,hWinEdit,EM_STREAMOUT,SF_TEXT,addr @stES
invoke SendMessage,hWinEdit,EM_SETMODIFY,FALSE,0
ret
_SaveFile endp
_OpenFile proc
LOCAL @stOF:OPENFILENAME
LOCAL @stES:EDITSTREAM
invoke RtlZeroMemory,addr @stOF,sizeof @stOF
mov @stOF.lStructSize,sizeof @stOF
push hWinMain
pop @stOF.hWndOwner
mov @stOF.lpstrFilter,offset szFilter
mov @stOF.lpstrFile,offset szFileName
mov @stOF.nMaxFile,MAX_PATH
mov @stOF.Flags,OFN_FILEMUSTEXIST or OFN_PATHMUSTEXIST
mov @stOF.lpstrDefExt,offset szDefaultExt
invoke GetOpenFileName,addr @stOF
.if eax ;0
invoke CreateFile,addr szFileName,GENERIC_READ or GENERIC_WRITE,FILE_SHARE_READ or FILE_SHARE_WRITE,\
0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0
.if eax == INVALID_HANDLE_VALUE
invoke MessageBox,hWinMain,addr szErrOpenFile,NULL,MB_OK or MB_ICONSTOP
ret
.endif
push eax
.if hFile
invoke CloseHandle,hFile
.endif
pop eax
mov hFile,eax
mov @stES.dwCookie,TRUE
mov @stES.dwError,NULL
mov @stES.pfnCallback,offset _ProcStream
invoke SendMessage,hWinEdit,EM_STREAMIN,SF_TEXT,addr @stES
invoke SendMessage,hWinEdit,EM_SETMODIFY,FALSE,0
.endif
ret
_OpenFile endp
_CheckModify proc
LOCAL @dwReturn
mov @dwReturn,TRUE
invoke SendMessage,hWinEdit,EM_GETMODIFY,0,0
.if eax && hFile
invoke MessageBox,hWinMain,addr szModify,addr szCaptionMain,MB_YESNOCANCEL or MB_ICONQUESTION
.if eax == IDYES
call _SaveFile
.elseif eax == IDCANCEL
mov @dwReturn,FALSE
.endif
.endif
mov eax,@dwReturn
ret
_CheckModify endp
_FindText proc
local @stFindText:FINDTEXTEX
invoke
SendMessage,hWinEdit,EM_EXGETSEL,0,addr @stFindText.chrg
.if stFind.Flags & FR_DOWN
push @stFindText.chrg.cpMax
pop @stFindText.chrg.cpMin
.endif
mov @stFindText.chrg.cpMax,-1
mov @stFindText.lpstrText,offset szFindText
mov ecx,stFind.Flags
and ecx,FR_MATCHCASE or FR_DOWN or FR_WHOLEWORD
invoke
SendMessage,hWinEdit,EM_FINDTEXTEX,ecx,addr @stFindText
.if eax ==-1
mov ecx,hWinMain
.if hFindDialog
mov ecx,hFindDialog
.endif
invoke
MessageBox,ecx,addr szNotFound,NULL,MB_OK or MB_ICONINFORMATION
ret
.endif
invoke
SendMessage,hWinEdit,EM_EXSETSEL,0,addr @stFindText.chrgText
invoke
SendMessage,hWinEdit,EM_SCROLLCARET,NULL,NULL
ret
_FindText endp
_SetStatus proc
local @stRange:CHARRANGE
invoke
SendMessage,hWinEdit,EM_EXGETSEL,0,addr @stRange
mov eax,@stRange.cpMin
.if eax ==@stRange.cpMax
invoke
EnableMenuItem,hMenu,IDM_COPY,MF_GRAYED
invoke
EnableMenuItem,hMenu,IDM_CUT,MF_GRAYED
.else
invoke
EnableMenuItem,hMenu,IDM_COPY,MF_ENABLED
invoke
EnableMenuItem,hMenu,IDM_CUT,MF_ENABLED
.endif
invoke
SendMessage,hWinEdit,EM_CANPASTE,0,0
.if eax
invoke
EnableMenuItem,hMenu,IDM_PASTE,MF_ENABLED
.else
invoke
EnableMenuItem,hMenu,IDM_PASTE,MF_GRAYED
.endif
invoke
SendMessage,hWinEdit,EM_CANREDO,0,0
.if eax
invoke
EnableMenuItem,hMenu,IDM_REDO,MF_ENABLED
.else
invoke
EnableMenuItem,hMenu,IDM_REDO,MF_GRAYED
.endif
invoke
SendMessage,hWinEdit,EM_CANUNDO,0,0
.if eax
invoke
EnableMenuItem,hMenu,IDM_UNDO,MF_ENABLED
.else
invoke
EnableMenuItem,hMenu,IDM_UNDO,MF_GRAYED
.endif
invoke
GetWindowTextLength,hWinEdit
.if eax
invoke
EnableMenuItem,hMenu,IDM_SELALL,MF_ENABLED
.else
invoke
EnableMenuItem,hMenu,IDM_SELALL,MF_GRAYED
.endif
invoke
SendMessage,hWinEdit,EM_GETMODIFY,0,0
.if eax && hFile
invoke
EnableMenuItem,hMenu,IDM_SAVE,MF_ENABLED
.else
invoke
EnableMenuItem,hMenu,IDM_SAVE,MF_GRAYED
.endif
.if szFindText
invoke
EnableMenuItem,hMenu,IDM_FINDNEXT,MF_ENABLED
invoke
EnableMenuItem,hMenu,IDM_FINDPREV,MF_ENABLED
.else
invoke
EnableMenuItem,hMenu,IDM_FINDNEXT,MF_GRAYED
invoke
EnableMenuItem,hMenu,IDM_FINDPREV,MF_GRAYED
.endif
ret
_SetStatus endp
_Init proc
local @stCf:CHARFORMAT
push hWinMain
pop stFind.hwndOwner
invoke
RegisterWindowMessage,addr FINDMSGSTRING
mov idFindMessage,eax
invoke
CreateWindowEx,WS_EX_CLIENTEDGE,offset szClassEdit,NULL,\
WS_CHILD OR WS_VISIBLE OR WS_VSCROLL ORWS_HSCROLL \
OR ES_MULTILINE or ES_NOHIDESEL,\
0,0,0,0,\
hWinMain,0,hInstance,NULL
mov hWinEdit,eax
invoke
SendMessage,hWinEdit,EM_SETTEXTMODE,TM_PLAINTEXT,0
invoke
RtlZeroMemory,addr @stCf,sizeof @stCf
mov @stCf.cbSize,sizeof @stCf
mov @stCf.yHeight,9 * 20
mov @stCf.dwMask,CFM_FACE or CFM_SIZE or CFM_BOLD
invoke
lstrcpy,addr @stCf.szFaceName,addr szFont
invoke
SendMessage,hWinEdit,EM_SETCHARFORMAT,0,addr @stCf
invoke
SendMessage,hWinEdit,EM_EXLIMITTEXT,0,-1
ret
_Init endp
_Quit proc
invoke
_CheckModify
.if eax
invoke
DestroyWindow,hWinMain
invoke
PostQuitMessage,NULL
.if hFile
invoke
CloseHandle,hFile
.endif
.endif
ret
_Quit endp
_ProcWinMain procuses ebx edi esi hWnd,uMsg,wParam,lParam
local @stRange:CHARRANGE
local @stRect:RECT
mov eax,uMsg
.if eax ==WM_SIZE
invoke
GetClientRect,hWinMain,addr @stRect
invoke
MoveWindow,hWinEdit,0,0,@stRect.right,@stRect.bottom,TRUE
.elseif
eax == WM_COMMAND
mov eax,wParam
movzx eax,ax
.if eax ==IDM_OPEN
invoke
_CheckModify
.if eax
call _OpenFile
.endif
.elseif
eax == IDM_SAVE
call _SaveFile
.elseif
eax == IDM_EXIT
invoke
_Quit
.elseif
eax == IDM_UNDO
invoke
SendMessage,hWinEdit,EM_UNDO,0,0
.elseif
eax == IDM_REDO
invoke
SendMessage,hWinEdit,EM_REDO,0,0
.elseif
eax == IDM_SELALL
mov @stRange.cpMin,0
mov @stRange.cpMax,-1
invoke
SendMessage,hWinEdit,EM_EXSETSEL,0,addr @stRange
.elseif
eax == IDM_COPY
invoke
SendMessage,hWinEdit,WM_COPY,0,0
.elseif
eax == IDM_CUT
invoke
SendMessage,hWinEdit,WM_CUT,0,0
.elseif
eax == IDM_PASTE
invoke
SendMessage,hWinEdit,WM_PASTE,0,0
.elseif
eax == IDM_FIND
and stFind.Flags,not FR_DIALOGTERM
invoke
FindText,addr stFind
.if eax
mov hFindDialog,eax
.endif
.elseif
eax == IDM_FINDPREV
and stFind.Flags,not FR_DOWN
invoke
_FindText
.elseif
eax == IDM_FINDNEXT
or stFind.Flags,FR_DOWN
invoke
_FindText
.endif
.elseif
eax == WM_INITMENU
call _SetStatus
.elseif
eax == idFindMessage
.if stFind.Flags & FR_DIALOGTERM
mov hFindDialog,0
.else
invoke
_FindText
.endif
.elseif
eax == WM_ACTIVATE
mov eax,wParam
.if (ax ==WA_CLICKACTIVE ) || (ax == WA_ACTIVE)
invoke
SetFocus,hWinEdit
.endif
.elseif
eax == WM_CREATE
push hWnd
pop hWinMain
invoke
_Init
.elseif
eax == WM_CLOSE
call _Quit
.else
invoke
DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.endif
xor eax,eax
ret
_ProcWinMain endp
_WinMain proc
local @stWndClass:WNDCLASSEX
local @stMsg:MSG
local @hAccelerator,@hRichEdit
invoke
LoadLibrary,offset szDllEdit
mov @hRichEdit,eax
invoke
GetModuleHandle,NULL
mov hInstance,eax
invoke
LoadMenu,hInstance,IDR_MENU1
mov hMenu,eax
invoke
LoadAccelerators,hInstance,IDR_ACCELERATOR1
mov @hAccelerator,eax
invoke
RtlZeroMemory,addr @stWndClass,sizeof @stWndClass
invoke
LoadIcon,hInstance,IDI_ICON1
mov @stWndClass.hIcon,eax
mov @stWndClass.hIconSm,eax
invoke
LoadCursor,0,IDC_ARROW
mov @stWndClass.hCursor,eax
push hInstance
pop @stWndClass.hInstance
mov @stWndClass.cbSize,sizeof WNDCLASSEX
mov @stWndClass.style,CS_HREDRAW or CS_VREDRAW
mov @stWndClass.lpfnWndProc,offset _ProcWinMain
mov @stWndClass.hbrBackground,COLOR_BTNFACE+1
mov @stWndClass.lpszClassName,offset szClassName
invoke
RegisterClassEx,addr @stWndClass
invoke
CreateWindowEx,NULL,\
offset szClassName,offset szCaptionMain,\
WS_OVERLAPPEDWINDOW,\
CW_USEDEFAULT,CW_USEDEFAULT,700,500,\
NULL,hMenu,hInstance,NULL
mov hWinMain,eax
invoke
ShowWindow,hWinMain,SW_SHOWNORMAL
invoke
UpdateWindow,hWinMain
.while
TRUE
invoke
GetMessage,addr @stMsg,NULL,0,0
.break
.if eax == 0
invoke
TranslateAccelerator,hWinMain,@hAccelerator,addr @stMsg
.if eax == 0
invoke
TranslateMessage,addr @stMsg
invoke
DispatchMessage,addr @stMsg
.endif
.endw
invoke
FreeLibrary,@hRichEdit
ret
_WinMain endp
start:
call _WinMain
invoke
ExitProcess,NULL
end start
下面介绍一下一些陌生的结构和API函数以及几个消息:
结构:
EDITSTREAM STRUCT
dwCookie DWORD ? ;用户自定义值
dwError DWORD ? ;用来返回流操作过程中的错误信息
pfnCallback DWORD ? ; 回调函数地址
EDITSTREAM ENDS
dwCookie
用户值作为第一个参数传递给回调。指定富编辑控件的应用程序定义的值传递到指定的 pfnCallback 成员的 EditStreamCallback 回调函数。
dwError
指示流入 (读取) 或流出 (写入) 操作的结果。值为 0 表示没有错误。一个非零值,可以是 EditStreamCallback 函数或一个代码,指示该控件遇到一个错误的返回值。
pfnCallback
回调函数的地址
FINDTEXTEX STRUCT
chrg CHARRANGE <> ;查找区域
lpstrText DWORD ? ;查找字符串地址
chrgtext CHARRANGE <> ; 如果找到则在这里返回找到文字的起始/结束位置
FINDTEXTEX ENDS
CHARRANGE STRUCT
cpMin DWORD ? ;选择区域的起始位置
cpMax DWORD ? ;选择区域的结束位置
CHARRANGE ENDS
CHARFORMAT2 STRUCT
cbSize DWORD ? ;结构的长度
dwMask DWORD ? ;字段掩码
dwEffects DWORD ? ;字段效果
yHeight DWORD ? ;文字的高度
yOffset DWORD ? ;
crTextColor DWORD ? ;文本的颜色
bCharSet BYTE ? ;
bPitchAndFamily BYTE ? ;
szFaceName BYTE LF_FACESIZE dup(?) ;字体名称
;CHARFORMAT 结构的定义到此结束
wWeight WORD ?
sSpacing WORD ?
以上是关于WIN32汇编 Richedit控件的使用的主要内容,如果未能解决你的问题,请参考以下文章
riched32.dll riched20.dll msftedit.dll 解析