WIN32汇编 Richedit控件的使用

来源:互联网 发布:天津seo建站 编辑:程序博客网 时间:2024/05/17 05:17

这次来介绍一下一个独特的控件------Richedit    说实话这次也是第一次接触到这个控件,以前虽然听说过但是不知道具体它是干什么的,从字面上看好像是edit控件的扩展一样,其实这样只说对了一半,Richedit控件确实比edit控件功能强大丰富,但是它们的使用位置不同,edit控件以前在学习控件的时候,就出现了许多edit控件,那时候用edit控件主要是实现向一个小的文本框中输入文本而且基本都是用在对话框中,而且大小也有限制,在单行模式下能容纳的文本不能超过32KB,在多行模式下也不能超过64KB,加上这个限制想要实现多文本的输入那就有点麻烦了,而且不能实现文本格式,大小颜色等属性的设置,出于此种原因,Richedit控件就有了大显身手的机会,它可以实现多文本的输入,但是需要指定大小(发送EM_EXLIMITTEXT,因为默认情况下控件还是将最大字符数限制为64KB),这个控件因为功能复杂,代码量较大,微软给它独立使用一个动态链接库存储(Riched32.dll  1.0版,Riched20.dll(2.0和3.0版)),具体功能看一下下表(罗云斌老师书中的一张介绍图)

不同版本Richedit控件之间的区别 1.0版2.0版3.0版DLL库文件名Riched32.dllRiched32.dllRiched32.dll控件的类名RicheditRichedit20A
Richedit20WRichedit20A
Richedit20W拖放编辑支持支持支持流输入输出支持支持支持 Unicode编辑不支持支持支持非窗口操作不支持支持支持自动URL识别不支持支持支持加速键不支持支持支持分行符CR+LFCRCR(可模拟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_NEUTRALIDR_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_NEUTRALIDR_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_NEUTRALIDI_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结构体变量查找标识字段内容传递给ecxandecx,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.incinclude          user32.incincludelib       user32.libinclude          kernel32.incincludelib       kernel32.libinclude          comdlg32.incincludelib       comdlg32.libIDR_MENU1        equ        100IDR_ACCELERATOR1 equ        101IDI_ICON1        equ        103IDM_OPEN         equ        40000IDM_SAVE         equ        40001IDM_COPY         equ        40002IDM_EXIT         equ        40003IDM_UNDO         equ        40004IDM_REDO         equ        40005IDM_SELALL       equ        40006IDM_CUT          equ        40007IDM_PASTE        equ        40008IDM_FIND         equ        40009IDM_FINDPREV     equ        40010IDM_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   (?)                 .datastFind           FINDREPLACE <sizeof FINDREPLACE,0,0,FR_DOWN,szFindText,0,sizeof szFindText,0,0,0,0>                 .constFINDMSGSTRING    db          'commdlg_FindReplace',0szClassName      db          'wordpad',0szCaptionMain    db          '记事本',0szDllEdit        db          'RichEd20.dll',0szClassEdit      db          'RichEdit20A',0szNotFound       db          '字符串未找到!',0szFilter        db          'Text Files(*.txt)',0,'*.txt',0                 db          'All  Files(*.*)',0,'*.*',0,0szDefaultExt     db          'txt',0szErrOpenFile    db          '无法打开文件!',0szModify         db          '文件已修改,是否保存?',0szFont           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         .endifret_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 proclocal @stFindText:FINDTEXTEXinvoke SendMessage,hWinEdit,EM_EXGETSEL,0,addr @stFindText.chrg.if stFind.Flags & FR_DOWNpush @stFindText.chrg.cpMaxpop @stFindText.chrg.cpMin.endifmov @stFindText.chrg.cpMax,-1mov @stFindText.lpstrText,offset szFindTextmov ecx,stFind.Flagsand ecx,FR_MATCHCASE or FR_DOWN or FR_WHOLEWORDinvoke SendMessage,hWinEdit,EM_FINDTEXTEX,ecx,addr @stFindText.if eax ==-1mov ecx,hWinMain.if hFindDialogmov ecx,hFindDialog.endifinvoke MessageBox,ecx,addr szNotFound,NULL,MB_OK or MB_ICONINFORMATIONret.endifinvoke SendMessage,hWinEdit,EM_EXSETSEL,0,addr @stFindText.chrgTextinvoke SendMessage,hWinEdit,EM_SCROLLCARET,NULL,NULLret_FindText endp_SetStatus proclocal @stRange:CHARRANGEinvoke SendMessage,hWinEdit,EM_EXGETSEL,0,addr @stRangemov eax,@stRange.cpMin.if eax ==@stRange.cpMaxinvoke EnableMenuItem,hMenu,IDM_COPY,MF_GRAYEDinvoke EnableMenuItem,hMenu,IDM_CUT,MF_GRAYED.elseinvoke EnableMenuItem,hMenu,IDM_COPY,MF_ENABLEDinvoke EnableMenuItem,hMenu,IDM_CUT,MF_ENABLED.endifinvoke SendMessage,hWinEdit,EM_CANPASTE,0,0.if eaxinvoke EnableMenuItem,hMenu,IDM_PASTE,MF_ENABLED.elseinvoke EnableMenuItem,hMenu,IDM_PASTE,MF_GRAYED.endifinvoke SendMessage,hWinEdit,EM_CANREDO,0,0.if eaxinvoke EnableMenuItem,hMenu,IDM_REDO,MF_ENABLED.elseinvoke EnableMenuItem,hMenu,IDM_REDO,MF_GRAYED.endifinvoke SendMessage,hWinEdit,EM_CANUNDO,0,0.if eaxinvoke EnableMenuItem,hMenu,IDM_UNDO,MF_ENABLED.elseinvoke EnableMenuItem,hMenu,IDM_UNDO,MF_GRAYED.endifinvoke GetWindowTextLength,hWinEdit.if eaxinvoke EnableMenuItem,hMenu,IDM_SELALL,MF_ENABLED.elseinvoke EnableMenuItem,hMenu,IDM_SELALL,MF_GRAYED.endifinvoke SendMessage,hWinEdit,EM_GETMODIFY,0,0.if eax && hFileinvoke EnableMenuItem,hMenu,IDM_SAVE,MF_ENABLED.elseinvoke EnableMenuItem,hMenu,IDM_SAVE,MF_GRAYED.endif.if szFindTextinvoke EnableMenuItem,hMenu,IDM_FINDNEXT,MF_ENABLEDinvoke EnableMenuItem,hMenu,IDM_FINDPREV,MF_ENABLED.elseinvoke EnableMenuItem,hMenu,IDM_FINDNEXT,MF_GRAYEDinvoke EnableMenuItem,hMenu,IDM_FINDPREV,MF_GRAYED.endifret_SetStatus endp_Init proclocal @stCf:CHARFORMATpush hWinMainpop stFind.hwndOwnerinvoke RegisterWindowMessage,addr FINDMSGSTRINGmov idFindMessage,eaxinvoke 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,NULLmov hWinEdit,eaxinvoke SendMessage,hWinEdit,EM_SETTEXTMODE,TM_PLAINTEXT,0invoke RtlZeroMemory,addr @stCf,sizeof @stCfmov @stCf.cbSize,sizeof @stCfmov @stCf.yHeight,9 * 20mov @stCf.dwMask,CFM_FACE or CFM_SIZE or CFM_BOLDinvoke lstrcpy,addr @stCf.szFaceName,addr szFontinvoke SendMessage,hWinEdit,EM_SETCHARFORMAT,0,addr @stCfinvoke SendMessage,hWinEdit,EM_EXLIMITTEXT,0,-1ret_Init endp_Quit procinvoke _CheckModify.if eaxinvoke DestroyWindow,hWinMaininvoke PostQuitMessage,NULL.if hFileinvoke CloseHandle,hFile.endif.endifret_Quit endp_ProcWinMain procuses ebx edi esi hWnd,uMsg,wParam,lParamlocal @stRange:CHARRANGElocal @stRect:RECTmov eax,uMsg.if eax ==WM_SIZEinvoke GetClientRect,hWinMain,addr @stRectinvoke MoveWindow,hWinEdit,0,0,@stRect.right,@stRect.bottom,TRUE.elseif eax == WM_COMMANDmov eax,wParammovzx eax,ax.if eax ==IDM_OPENinvoke _CheckModify.if eaxcall _OpenFile.endif.elseif eax == IDM_SAVEcall _SaveFile.elseif eax == IDM_EXITinvoke _Quit.elseif eax == IDM_UNDOinvoke SendMessage,hWinEdit,EM_UNDO,0,0.elseif eax == IDM_REDOinvoke SendMessage,hWinEdit,EM_REDO,0,0.elseif eax == IDM_SELALLmov @stRange.cpMin,0mov @stRange.cpMax,-1invoke SendMessage,hWinEdit,EM_EXSETSEL,0,addr @stRange.elseif eax == IDM_COPYinvoke SendMessage,hWinEdit,WM_COPY,0,0.elseif eax == IDM_CUTinvoke SendMessage,hWinEdit,WM_CUT,0,0.elseif eax == IDM_PASTEinvoke SendMessage,hWinEdit,WM_PASTE,0,0.elseif eax == IDM_FINDand stFind.Flags,not FR_DIALOGTERMinvoke FindText,addr stFind.if eaxmov hFindDialog,eax.endif.elseif eax == IDM_FINDPREVand stFind.Flags,not FR_DOWNinvoke _FindText.elseif eax == IDM_FINDNEXTor stFind.Flags,FR_DOWNinvoke _FindText.endif.elseif eax == WM_INITMENUcall _SetStatus.elseif eax == idFindMessage.if stFind.Flags & FR_DIALOGTERMmov hFindDialog,0.elseinvoke _FindText.endif.elseif eax == WM_ACTIVATEmov eax,wParam.if (ax ==WA_CLICKACTIVE ) || (ax == WA_ACTIVE)invoke SetFocus,hWinEdit.endif.elseif eax == WM_CREATEpush hWndpop hWinMaininvoke _Init.elseif eax == WM_CLOSEcall _Quit.elseinvoke DefWindowProc,hWnd,uMsg,wParam,lParamret.endifxor eax,eaxret_ProcWinMain endp_WinMain proclocal @stWndClass:WNDCLASSEXlocal @stMsg:MSGlocal @hAccelerator,@hRichEditinvoke LoadLibrary,offset szDllEditmov @hRichEdit,eaxinvoke GetModuleHandle,NULLmov hInstance,eaxinvoke LoadMenu,hInstance,IDR_MENU1  mov hMenu,eaxinvoke LoadAccelerators,hInstance,IDR_ACCELERATOR1mov @hAccelerator,eaxinvoke RtlZeroMemory,addr @stWndClass,sizeof @stWndClassinvoke LoadIcon,hInstance,IDI_ICON1 mov @stWndClass.hIcon,eaxmov @stWndClass.hIconSm,eaxinvoke LoadCursor,0,IDC_ARROWmov @stWndClass.hCursor,eaxpush hInstancepop @stWndClass.hInstancemov @stWndClass.cbSize,sizeof WNDCLASSEXmov @stWndClass.style,CS_HREDRAW or CS_VREDRAWmov @stWndClass.lpfnWndProc,offset _ProcWinMainmov @stWndClass.hbrBackground,COLOR_BTNFACE+1mov @stWndClass.lpszClassName,offset szClassNameinvoke RegisterClassEx,addr @stWndClassinvoke CreateWindowEx,NULL,\offset szClassName,offset szCaptionMain,\WS_OVERLAPPEDWINDOW,\CW_USEDEFAULT,CW_USEDEFAULT,700,500,\NULL,hMenu,hInstance,NULLmov hWinMain,eaxinvoke ShowWindow,hWinMain,SW_SHOWNORMALinvoke UpdateWindow,hWinMain.while TRUEinvoke GetMessage,addr @stMsg,NULL,0,0.break .if eax == 0invoke TranslateAccelerator,hWinMain,@hAccelerator,addr @stMsg.if eax == 0invoke TranslateMessage,addr @stMsginvoke DispatchMessage,addr @stMsg.endif.endwinvoke FreeLibrary,@hRichEditret_WinMain endpstart:call _WinMaininvoke ExitProcess,NULLend 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        ?

  crBackColor            DWORD        ?

  lcid                            DWORD       ?

  dwReserved            DWORD       ?

   sStyle                       WORD         ?

   wKerning                 WORD          ?

   bUnderlineType       BYTE          ?

   bAnimation               BYTE          ?

  bRevAuthor               BYTE           ?

   bReservedl               BYTE          ?

CHARFORMAT2           ENDS       


字段解释:

成员
cbSize:

结构的大小,由于控件使用该字段来判断结构的版本是CHARFORMAT还是CHARFORMAT2,所以在将结构传递给控件前必须将这个字段设置为正确的的数值。


dwMask:

字段掩码,用来指定结构中哪些字段是有效的,如果没有使用对应的标志,即使某些字段的内容被被设置,控件也不会使用它,dwMask中可以使用的标志可以是下列数值的组合:
CFM_BOLD------dwEffects字段中CFE_BOLDZ值是有效的。

CFM_CHARSET---------bCharSet字段是有效的。

CFM_COLOR---------crTextColor字段和dwEffects中的CFE_AUTOCOLOR值是有效的。

CFM_FACE-----------szFaceName字段的值是有效的。

CFM_ITALIC---------dwEffects字段中CFE_ITATIC值是有效的。

CFM_OFFSET--------yOffset字段是有效的。

CFM_PROTECTED-----dwEffects字段中的CFE_PROTECTED值是有效的。

CFM_SIZE------------yHeight字段是有效的。

CFM_STRIKEOUT-------dwEffects字段中的CFE_STRIKEOUT值是有效的。

CFM_UNDERLINE-------dwEffects字段中的CFE_UNDERLINE值是有效的。


dwEffects:

字符效果,可以是下列值的组合

CFE_AUTOCOLOR------使用系统正文颜色

CFE_BOLD,CFE_ITALIC,CFE_STRIKEOUT和CFE_UNDERLINE--------粗体字符,斜体字符,带删除线和带下划线。

CFE_PROTECTED--------字符是受保护的,企图改变字符的话,控件会向父窗口发送一个EN_PROTECTED通知消息

yHeight:

字符高度,单位是1/1440英寸(或1/20磅),如果这里是180,换算到“字体选择”通用对话框中的尺寸就是9磅(180* 1/20=9)。

yOffset:

从基线算起的字符偏移,单位同上,如果该成员是正值,字符显示为上标;如果是负值,字符显示为下标。


crTextColor:

正文颜色,如果在dwEffects字段中指定了CFE_AUTOCOLOR标志,那么这个值就会被忽略。


bCharSet:
字符集
bPitchAndFamily
字符集
szFaceName
用字符串表示的字体名字。


下面总结一下使用的陌生的API函数

ReadFile()
功能:
文件指针指向的位置开始将数据读入到一个文件中
原型及参数:

BOOL ReadFile(

HANDLE hFile, //文件的句柄

LPVOID lpBuffer, //用于保存读入数据的一个缓冲区

DWORD nNumberOfBytesToRead, //要读入的字节数

LPDWORD lpNumberOfBytesRead, //指向实际读取字节数的指针

LPOVERLAPPED lpOverlapped) //如文件打开时指定了FILE_FLAG_OVERLAPPED,那么必须,用这个参数引用一个特殊的结构。该结构定义了一次异步读取操作。否则,应将这个参数设为NULL  

FILE_FLAG_OVERLAPPED

文件或设备被打开或创建异步I / O。

当后续的I / O操作完成这个句柄,OVERLAPPED结构中指定的事件 将被设置为有信号状态。

如果这个标志被指定,该文件可用于同时读取和写入操作。

如果没有指定这个标志,然后被序列化I / O操作,即使调用读写函数指定一个OVERLAPPED结构。

返回值:

调用成功,返回非0

调用不成功,返回为0




WriteFile()
功能:
从文件指针指向的位置开始将数据写入到一个文件中(读出)
原型及参数:

BOOL WriteFile(

HANDLE hFile, // 文件句柄

LPCVOID lpBuffer, // 数据缓存区指针

DWORD nNumberOfBytesToWrite, // 你要写的字节数

LPDWORD lpNumberOfBytesWritten, // 用于保存实际写入字节数的存储区域的指针

LPOVERLAPPED lpOverlapped // OVERLAPPED结构体指针

);

返回值:

调用成功,返回非0

调用不成功,返回为0



CreateFile()

功能:

CreateFile函数创建或打开以下对象并返回一个句柄,可以用来访问对象:文件、管道、mailslots、通信资源、磁盘设备(Windows NT只有)、consoles、目录(只开放)

原型:

HANDLE CreateFile(

LPCTSTR lpFileName, //指向文件名的指针

DWORD dwDesiredAccess, //访问模式(写/读)

DWORD dwShareMode, //共享模式

LPSECURITY_ATTRIBUTES lpSecurityAttributes, //指向安全属性的指针

DWORD dwCreationDisposition, //如何创建

DWORD dwFlagsAndAttributes, //文件属性

HANDLE hTemplateFile //用于复制文件句柄

);

参数:

lpFileName String要打开的文件的名或设备名。这个字符串的最大长度在ANSI版本中为MAX_PATH,在unicode版本中为32767。

dwDesiredAccess指定类型的访问对象。如果为 GENERIC_READ 表示允许对设备进行读访问;如果为 GENERIC_WRITE 表示允许对设备进行写访问(可组合使用);如果为零,表示只允许获取与一个设备有关的信息 。

另外,还可以指定下面的控制标志:

标准控制权限(16-23位掩码):

DELETE 删除对象的权限。

READ_CONTROL 从对象的安全描述符中读取信息的权限,但不包括SACL(系统访问控制列表)中的信息。

WRITE_DAC 修改对象安全描述符中的DACL(随机访问控制列表)的权限

WRITE_OWNER 修改对象安全描述符中的属主的权限

SYNCHRONIZE 同步化使用对象的权限,即可以创建一个线程等待信号量释放(但有些对象不支持这个权限)。

STANDARD_RIGHTS_REQUIRED 等价于前面四种权限的总合(通常这四种是必须具有的权限)。

STANDARD_RIGHTS_READ 一般等价于READ_CONTROL

STANDARD_RIGHTS_WRITE 一般等价于READ_CONTROL

STANDARD_RIGHTS_EXECUTE 一般等价于READ_CONTROL

STANDARD_RIGHTS_ALL 等价于前面五种权限的总合。

特殊控制权限(0-15位掩码):

SPECIFIC_RIGHTS_ALL

ACCESS_SYSTEM_SECURITY

MAXIMUM_ALLOWED

GENERIC_READ

GENERIC_WRITE

GENERIC_EXECUTE

GENERIC_ALL

注:实质上是通过ACCESS_MASK结构体的一个双字值来设置标准权限、特殊权限和一般权限的。

dwShareModeLong, 如果是零表示不共享; 如果是FILE_SHARE_DELETE表示随后打开操作对象会成功只要删除访问请求;如果是FILE_SHARE_READ随后打开操作对象会成功只有请求读访问;如果是FILE_SHARE_WRITE 随后打开操作对象会成功只有请求写访问。

lpSecurityAttributesSECURITY_ATTRIBUTES, 指向一个SECURITY_ATTRIBUTES结构的指针,定义了文件的安全特性(如果操作系统支持的话)

dwCreationDispositionLong,下述常数之一:

CREATE_NEW 创建文件;如文件存在则会出错

CREATE_ALWAYS 创建文件,会改写前一个文件

OPEN_EXISTING 文件必须已经存在。由设备提出要求

OPEN_ALWAYS 如文件不存在则创建它

TRUNCATE_EXISTING 将现有文件缩短为零长度

dwFlagsAndAttributesLong:

 一个或多个下述常数

FILE_ATTRIBUTE_ARCHIVE 标记归档属性

FILE_ATTRIBUTE_COMPRESSED 将文件标记为已压缩,或者标记为文件在目录中的默认压缩方式

FILE_ATTRIBUTE_NORMAL 默认属性

FILE_ATTRIBUTE_HIDDEN 隐藏文件或目录

FILE_ATTRIBUTE_READONLY 文件为只读

FILE_ATTRIBUTE_SYSTEM 文件为系统文件

FILE_FLAG_WRITE_THROUGH 操作系统不得推迟对文件的写操作

FILE_FLAG_OVERLAPPED 允许对文件进行重叠操作

FILE_FLAG_NO_BUFFERING 禁止对文件进行缓冲处理。文件只能写入磁盘卷的扇区块

FILE_FLAG_RANDOM_ACCESS 针对随机访问对文件缓冲进行优化

FILE_FLAG_SEQUENTIAL_SCAN 针对连续访问对文件缓冲进行优化

FILE_FLAG_DELETE_ON_CLOSE 关闭了上一次打开的句柄后,将文件删除。特别适合临时文件

也可在Windows NT下组合使用下述常数标记:

SECURITY_ANONYMOUS, SECURITY_IDENTIFICATION, SECURITY_IMPERSONATION, SECURITY_DELEGATION, SECURITY_CONTEXT_TRACKING, SECURITY_EFFECTIVE_ONLY

返回值:

如执行成功,则返回文件句柄。

INVALID_HANDLE_VALUE表示出错,会设置GetLastError。即使函数成功,但若文件存在,且指定了CREATE_ALWAYS 或 OPEN_ALWAYS,GetLastError也会设为ERROR_ALREADY_EXISTS



CloseHandle()

功能:

关闭一个内核对象。其中包括文件、文件映射、进程、线程、安全和同步对象等

原型:

BOOL CloseHandle(

HANDLE hObject

);

参数:

hObject :代表一个已打开对象handle。

返回值:

TRUE:执行成功;

FALSE:执行失败



SetFilePointer()

功能:
在一个文件中设置当前的读取位置。
原型:

DWORD SetFilePointer(

HANDLE hFile, // 文件句柄

LONG lDistanceToMove, // 偏移量(低位)

PLONG lpDistanceToMoveHigh, // 偏移量(高位)

DWORD dwMoveMethod // 基准位置FILE_BEGIN:文件开始位置 FILE_CURRENT:文件当前位置 FILE_END:文件结束位置

说明:移动一个打开文件的指针

返回值:
Long,返回一个新位置,它采用从文件起始处开始算起的一个字节偏移量。HFILE_ERROR意味着出错。会设置GetLastError


SetEndOfFile()

功能:
针对一个打开的文件,将当前文件位置设为文件末尾
原型:
BOOL WINAPI SetEndOfFile(
  _In_ HANDLE hFile
);
参数:
hFile Long,一个文件指定句柄。文件的当前位置设为文件尾,文件会根据需要缩短

返回值:
Long(32位整数),非零表示成功,零表示失败


SetFocus()
功能:
该函数对指定的窗口设置键盘焦点。该窗口必须与调用线程的消息队列相关。
原型:
HWND SetFocus(HWND hWnd)
参数:
hWnd:接收键盘输入的窗口指针。若该参数为NULL,则击键被忽略
返回值:
若函数调用成功,则返回原先拥有键盘焦点的窗口句柄。若hWnd参数无效或窗口未与调用线程的消息队列相关,则返回值为NULL。


LoadLibrary()
功能:
载入指定的动态链接库,并将它映射到当前进程使用的地址空间。一旦载入,即可访问库内保存的资源
原型;
HMODULE WINAPI LoadLibrary( _In_ LPCTSTR lpFileName);
参数:
lpFileName:要载入文件的名称.
一旦不需要,用FreeLibrary函数释放DLL
返回值:
Long,成功则返回库模块的句柄,零表示失


RegisterWindowMessage()
功能:
函数定义一个新的窗口消息,保证该消息在系统范围内是唯一的。通常调用SendMessage或者PostMessage函数时,可以使用该函数返回的消息值。
原型:
UINT RegisterWindowMessage( lpString);
参数:
lpString ------- String,(被注册)消息的名字
返回值:
Long,& C000 到 & FFFF之间的一个消息编号。零意味着出错(注册消息失败)




消息:

EM_GETMODIFY
功能:
得到一个编辑控件的状态的修改标记。表明编辑控件的内容是否已经被修改。你可以发送这个消息到一个编辑控件或丰富的编辑控件

参数:

按钮

未使用,必须为零。

lParam

未使用,必须为零。

返回值:

如果编辑控件的内容已经修改,返回值非零;否则,它是零。


WM_ACTIVATE

参数: 
fActive  = LOWORD(wParam);   // activation flag 
fMinimized = (BOOL)HIWORD(wParam); // minimized flag 
hwndPrevious= (HWND)lParam;   // window handle
fActive 参数主要定义了该窗口发生了什么事情,即该窗口是被激活还是被取消。该
信息保存在 wParam 的低阶字中,可以取以下的值:
WA_CLICKACTIVE       通过鼠标单击激活了该窗口 
WA_ACTIVE                   通过鼠标以外的工具(如键盘)激活了该窗口 
WA_INACTIVE               取消该窗口的激活 
示例代码:
case WM_ACTIVATE: 

     // test if window is being activated 
     if(LOWORD(wParam)!=WA_INACTIVE) 
     { 
          // application is being activated 
     } 
     else 
     { 
          // application is being deactivated 
     } 

break;















1 0