记录的源文件,篇幅有点长
工具栏资源图片
bmp格式
notepad.h文件
// NOTEPAD_H_INCLUDED /* ** Copyright (C) name:notepad author:suju 日期:2012-10-04 */ #ifndef NOTEPAD_H_INCLUDED #define NOTEPAD_H_INCLUDED /*定义工具栏图标坐标数据*/ #define BNEW 2 #define BOPEN 4 #define BSAVE 0 #define BREVO 1 #define BRECOVERY 3 #define BSHEAR 7 #define BCOPY 8 #define BPASTE 9 #define BFIND 5 #define BREPLACE 10 #define BCENTER 11 #define BLEFT 12 #define BRIGHT 13 #define BBOLD 14 #define BITALIC 15 #define BUNDERLINE 16 #define BFONTSTYLE 6 //工具栏样式图标 #define BOLD 0 #define ITALIC 1 #define UNDERLINE 2 //文本编码 #define TXT_UNICODE 1 #define TXT_ASCII 0 // #define IF_FALSE(bool,sta1,sta2) bool!=0?sta1:sta2 #endif /*include*/ #include <windows.h> #include <stdio.h> #include <richedit.h> #include <commctrl.h> #include "resource.h" /*声明函数*/ /******start function********/ void setStatus(); /*设置状态栏*/ long getLength(); /*获取文本长度*/ void textChange(); /*文本改变处理函数*/ void findText(); /*查找*/ void savetofile(); /*保存文件*/ void checkFormat(); //工具栏图标匹配选中文本格式 void close(HWND hwnd); /*关闭退出程序*/ void newfile(HWND hwnd); /*新建文件*/ void readfile(HWND hwnd); /*读取文件*/ void openfile(HWND hwnd); /*打开文件*/ void menuChange(HWND hwnd); /*菜单和工具栏按钮初始化*/ void moveStatus(HWND hwnd); /*移动状态栏*/ void setFont(HWND hwndrich); /*设置字体样式*/ void initToolbar(HWND hwnd); /*初始化工具栏*/ void createStatus(HWND hwnd); /*创建状态栏*/ void setAlignment(int style); //设置样式(加粗,斜体,下划线) void setWindowSize(HWND hwnd); /*设置窗体大小*/ void quickSetFormat(int STYLE); //工具栏设置样式 int savefiledialog(HWND hwndrich); /*保存文件处理函数*/ void clickfile(HWND hwnd,LPSTR name); //桌面拖放打开文件 void savefile(HWND hwnd,int savemodel); /*保存文件*/ HWND getFindDialog(HWND hwnd,int model); /*打开/替换对话框*/ void notifyChange(HWND hwnd,LPARAM lParam); /*notify消息处理*/ TCHAR* substring(TCHAR* ch,int pos,int length); //字符串截取 void selText(TCHAR* lpchar,int index,TCHAR* defext); /*文件后缀判断函数*/ void getCHARFORMAT(HWND hwndrich,CHARFORMAT* cformat,CHOOSEFONT* cf); /*获取格式化结构变量*/ void initOpn(OPENFILENAME* opn,TCHAR* filename,LPCSTR Title,DWORD filterIndex); /*初始化opn结构*/ DWORD CALLBACK StreamCallback(DWORD dwCookie,LPBYTE pbBuff,LONG cb,LONG *pcb); /*输入流回调函数*/ void initEidtStream(EDITSTREAM* stream,LPCSTR type,EDITSTREAMCALLBACK callback); /*初始化读写流结构*/ LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam); /*主程序回调函数*/ DWORD CALLBACK SaveStreamCallback(DWORD dwCookie,LPBYTE pbBuff,LONG cb,LONG *pcb); /*输出流回调函数*/ BOOL CALLBACK AboutDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); /*对话框回调函数*/ /******end funciton********/ /*声明全局变量*/ /*******Statement Parameters*********/ HINSTANCE hInst; /*应用程序句柄*/ HWND hwndrich; /*richedit句柄*/ HWND hwndfind; /*查找对话框句柄*/ HWND hwndStatus; /*状态栏句柄*/ HWND hWndToolBar; /*工具栏句柄*/ UINT uFindReplaceMsg; //FINDMSGSTRING消息 自定义查找消息 /*定义文件后缀*/ TCHAR filtername[MAX_PATH]=TEXT("rtf\0*.rtf\0txt\0*.txt\0all\0*.*\0"); TCHAR filename[MAX_PATH]=""; /*初始文件名*/ TCHAR defext[MAX_PATH]; /*初始文件后缀*/ TCHAR szFindWhat[80]=""; /*初始查找文本*/ TCHAR szReplaceWhat[80]=""; /*初始替换文本*/ FINDREPLACE fr; /*替换/查找对话框 结构变量*/ const int FIND=0; /*查找FIND常量*/ const int REPLACE=1; /*替换REPLACE常量*/ const int SAVE=0; /*保存SAVE常量*/ const int SAVEAS=1; /*另存为SAVES常量*/ const int F_OPEN=0; /*打开文件F_OPEN常量*/ const int F_CHANGE=1; /*改变文件内容F_CHANGE常量*/ TCHAR defaultname[]="未命名"; /*默认标题名*/ TCHAR SaveFileName[MAX_PATH]=""; /*默认保存文件名*/ TCHAR staformat[MAX_PATH]=TEXT("行%d 列%d"); /*状态栏格式化文本*/ TCHAR sizeformat[MAX_PATH]=TEXT("字数 %ld"); /*状态栏格式化文本*/ TCHAR status_line[MAX_PATH]=""; /*状态栏行列数*/ TCHAR status_size[MAX_PATH]=""; /*状态栏文本总长度*/ TCHAR szBuf[MAX_PATH]; /*提示消息字符缓冲*/ int isSave=TRUE; /*修改状态*/ OPENFILENAME opfn; /*OPENFILENAME打开文件结构*/ long size=0; /*文件大小*/ DWORD filterIndex=2; //默认文件后缀索引 TCHAR szAppName[]=TEXT("DLG_MAIN"); //窗口类名称 FILE* file=NULL; //文件指针 CHARFORMAT cformat; //格式化结构 PARAFORMAT paraformat; //段落格式结构 int txtcode=TXT_ASCII; //默认文件编码 int textmode; /********Statement Parameters****************/
resource.h资源头文件
#ifndef IDC_STATIC #define IDC_STATIC (-1) #define DLG_MAIN 101 #define IDR_MENU1 102 #define IDD_DIALOG1 103 #define ID_ACCE 106 #define IDI_ICON1 107 #define IDB_BITMAP1 108 #define IDC_RICHEDIT1 1000 #define IDM_OPEN 40000 #define IDM_EXIT 40001 #define IDM_ABOUT 40002 #define IDM_SAVE 40003 #define IDM_STYLE 40004 #define IDM_FIND 40005 #define IDM_REPLACE 40006 #define IDM_SAVEAS 40007 #define IDM_NEW 40008 #define IDM_REVO 40009 #define IDM_SHEAR 40010 #define IDM_COPY 40011 #define IDM_PASTE 40012 #define IDM_RECOVERY 40013 #define IDM_TAB 40014 #define IDR_TOOLBAR1 40015 #define IDM_BOLD 40016 #define IDM_ITALIC 40017 #define IDM_UNDERLINE 40018 #define IDM_CENTER 40019 #define IDM_LEFT 40020 #define IDM_RIGHT 40021 #endif
resource.rc
//include 编译h文件 #include <windows.h> #include <commctrl.h> #include <richedit.h> #include "resource.h" // // Bitmap resources图片 // LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL IDB_BITMAP1 BITMAP ".\\notepad.bmp" LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL IDR_TOOLBAR1 BITMAP "bitmap.bmp" // // Menu resources菜单 // LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL IDR_MENU1 MENU { POPUP "文件(&F)" { MENUITEM "新建(&N) Ctrl+N", IDM_NEW MENUITEM "打开(&O) Ctrl+O", IDM_OPEN MENUITEM "保存(&S) Ctrl+S", IDM_SAVE MENUITEM "另存为(&A)", IDM_SAVEAS MENUITEM SEPARATOR MENUITEM "退出(&E)", IDM_EXIT } POPUP "编辑(&E)" { MENUITEM "查找(&F) Ctrl+F", IDM_FIND MENUITEM "替换(&R) Ctrl+H", IDM_REPLACE MENUITEM SEPARATOR MENUITEM "撤销(&U) Ctrl+Z", IDM_REVO MENUITEM "恢复(&Y)Ctrl+Y", IDM_RECOVERY MENUITEM SEPARATOR MENUITEM "剪切(&T) Ctrl+x", IDM_SHEAR MENUITEM "复制(&C) Ctrl+C", IDM_COPY MENUITEM "粘贴(&P) Ctrl+V", IDM_PASTE } POPUP "选项(&O)" { MENUITEM "样式(&S)", IDM_STYLE } POPUP "帮助(&H)" { MENUITEM "关于(&A)", IDM_ABOUT } } // // Dialog resources主对话框窗口 // LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL DLG_MAIN DIALOGEX 6, 5, 265, 285 STYLE DS_3DLOOK | DS_CENTER | DS_SHELLFONT | WS_VISIBLE | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_GROUP | WS_MAXIMIZEBOX | WS_POPUP | WS_THICKFRAME | WS_SYSMENU | WS_TABSTOP EXSTYLE WS_EX_WINDOWEDGE CAPTION "Notepad" MENU IDR_MENU1 CLASS "DLG_MAIN" FONT 12, "Tahoma", 400, 0, 0 { //RICHEDIT_CLASS 2.0版本class name //L"RichEdit50W" CLASS 4.1版本class name CONTROL "", IDC_RICHEDIT1,RICHEDIT_CLASS, WS_VSCROLL | NOT WS_BORDER | NOT WS_TABSTOP | ES_MULTILINE | ES_NOHIDESEL | ES_WANTRETURN, 0, 33, 265, 230, WS_EX_CLIENTEDGE } //关于对话框 LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL IDD_DIALOG1 DIALOG 0, 0, 174, 105 STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_VISIBLE | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP | WS_SYSMENU CAPTION "关于" FONT 8, "Ms Shell Dlg 2" { DEFPUSHBUTTON "确 定", IDOK, 136, 84, 25, 14 LTEXT "Notepad v1.0 demo\n\n制作:suju\n\nEmail:[email protected]", IDC_STATIC, 73, 26, 90, 40, SS_LEFT CONTROL IDB_BITMAP1, IDC_STATIC, WC_STATIC, WS_GROUP | SS_BITMAP | SS_CENTERIMAGE | SS_NOTIFY | 0x00000840, 0, 19, 66, 56, WS_EX_TRANSPARENT } // // String Table resources工具栏提示字符串资源 // LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL STRINGTABLE { IDM_OPEN "打开" IDM_SAVE "保存" IDM_STYLE "样式" IDM_FIND "查找" IDM_REPLACE "替换" IDM_NEW "新建" IDM_REVO "撤销" IDM_SHEAR "剪切" IDM_COPY "复制" IDM_RECOVERY "恢复" IDM_PASTE "粘贴" IDM_BOLD "粗体" IDM_ITALIC "斜体" IDM_UNDERLINE "下划线" IDM_CENTER "居中显示" IDM_LEFT "靠左显示" IDM_RIGHT "靠右显示" } // // Accelerator resources加速键 // LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL ID_ACCE ACCELERATORS { "F", IDM_FIND, VIRTKEY, CONTROL "O", IDM_OPEN, VIRTKEY, CONTROL "H", IDM_REPLACE, VIRTKEY, CONTROL "S", IDM_SAVE, VIRTKEY, CONTROL VK_TAB, IDM_TAB, VIRTKEY } // // Icon resources图标资源 // LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL IDI_ICON1 ICON ".\\notepad.ico"
notepad.c文件
//#define WIN32_LEAN_AND_MEAN #include "notepad.h" #define TBSTYLE_FLAT 2048 //工具栏样式 /*主启动函数*/ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { hInst = hInstance; //保存实例句柄 LoadLibrary("RichEd20.dll"); //载入richedit动态库,这个控件是以单独dll形式保存的2.0版本 //LoadLibrary("msftedit.dll"); //载入richedit动态库,这个控件是4.1的 MSG msg; //队列消息变量 HWND hwnd; //窗口句柄 HICON icon; //图标 HACCEL haccel; //加速键 //自定义查找对话框消息 uFindReplaceMsg = RegisterWindowMessage(FINDMSGSTRING); //载入窗口图标 icon=LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1)); //--start声明,注册一个窗口类,类名和默认对话框模板类型一样。 WNDCLASSEX wndclass ; //窗口类结构 ZeroMemory(&wndclass,sizeof(wndclass)); //初始化结构 wndclass.cbSize = sizeof (WNDCLASSEX); //cbSize大小,window检测窗口类型的参数。 wndclass.style= CS_HREDRAW | CS_VREDRAW; //样式 wndclass.lpfnWndProc= WndProc; //指定窗口消息处理函数 wndclass.cbClsExtra= 0 ; //窗口类预留字节空间,这里为0字节 wndclass.cbWndExtra = DLGWINDOWEXTRA ; //窗口结构预留字节 wndclass.hInstance= hInstance ; //窗口类模块句柄 wndclass.hIcon =icon; //定义图标 wndclass.hCursor= LoadCursor (NULL, IDC_ARROW) ; //鼠标光标 wndclass.hbrBackground= (HBRUSH) (COLOR_BTNFACE + 1) ; //设置背景色 wndclass.lpszMenuName= NULL; //窗口应用程序菜单 NULL wndclass.lpszClassName= szAppName ; //窗口类别名称,对话框窗口和模板类名称相同 //注册窗口 if(!RegisterClassEx(&wndclass)) { //注册失败处理 MessageBox(NULL,TEXT("窗口注册失败!"),TEXT("Notepad"),MB_ICONERROR); return 0; } /*--end 注册窗口*/ //基于对话框模板方式创建一个非模态对话框窗口 //MAKEINTRESOURCE宏用于把数字资源ID转为字符串指针。 hwnd=CreateDialog(hInstance,MAKEINTRESOURCE(DLG_MAIN),NULL,0); /*初始化窗口标题栏,并显示窗口*/ SetWindowText(hwnd,strcat(defaultname,"-Notepad")); ShowWindow(hwnd,nShowCmd); UpdateWindow(hwnd); /*设置richedit控件响应消息*/ hwndrich=GetDlgItem(hwnd,IDC_RICHEDIT1); SendMessage(hwndrich,EM_SETEVENTMASK,0,ENM_SELCHANGE|ENM_MOUSEEVENTS|ENM_CHANGE|ENM_KEYEVENTS|ENM_SCROLL|ENM_DROPFILES); SendMessage(hwndrich,EM_EXLIMITTEXT,0,-1); //载入加速键资源表,保存加速键表句柄 haccel=LoadAccelerators(hInstance,MAKEINTRESOURCE(ID_ACCE)); //创建状态栏,并重置窗口位置 createStatus(hwnd); setWindowSize(hwnd); /*命令行和拖放文件打开判断*/ if (strcmp(lpCmdLine,TEXT(""))!=0){ clickfile(hwnd,lpCmdLine); } //*主消息循环*// while (GetMessage(&msg,NULL,0,0)) { //加速键捕获处理 if (!TranslateAccelerator(hwnd,haccel,&msg)) { //非模态对话框消息处理 if (hwnd==NULL || !IsDialogMessage (hwnd,&msg)) { //主消息循环体 TranslateMessage(&msg); DispatchMessage(&msg); } } } FreeLibrary(hInstance); //释放模块句柄资源 return msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam) { switch(message) { case WM_CREATE: initToolbar(hwnd); menuChange(hwnd); //初始化字符格式结构 ZeroMemory(&cformat,sizeof(CHARFORMAT)); cformat.cbSize=sizeof(CHARFORMAT); cformat.dwMask=CFM_SIZE|CFM_COLOR|CFM_FACE|CFM_ITALIC|CFM_BOLD|CFM_STRIKEOUT|CFM_UNDERLINE; //初始化段落格式结构 ZeroMemory(¶format,sizeof(paraformat)); paraformat.cbSize=sizeof(PARAFORMAT); return 0; case WM_SIZE: setWindowSize(hwnd); //重置窗口 return 0; case WM_CLOSE: close(hwnd); //响应close return 0; case WM_NOTIFY: notifyChange(hwnd,lParam); //工具栏和richedit组件特定消息,键盘,鼠标控制 return 0; case WM_COMMAND: switch(LOWORD(wParam)) { case IDM_TAB: //tab加速键 SendMessage(hwndrich,EM_REPLACESEL,0,(LPARAM)TEXT("\t")); textChange(F_CHANGE); break; case IDM_NEW: newfile(hwnd); break; case IDM_OPEN: openfile(hwnd); break; case IDM_STYLE: setFont(hwndrich); break; case IDM_SAVEAS: savefile(hwnd,SAVEAS); break; case IDM_EXIT: close(hwnd); break; case IDM_SAVE: savefile(hwnd,SAVE); break; case IDM_REVO: //撤销 SendMessage(hwndrich,EM_UNDO,0,0); textChange(F_CHANGE); break; case IDM_RECOVERY: //恢复 SendMessage(hwndrich,EM_REDO,0,0); textChange(F_CHANGE); break; case IDM_COPY: SendMessage(hwndrich,WM_COPY,0,0); break; case IDM_SHEAR: SendMessage(hwndrich,WM_CUT,0,0); textChange(F_CHANGE); break; case IDM_PASTE: SendMessage(hwndrich,WM_PASTE,0,0); textChange(F_CHANGE); break; case IDM_REPLACE: hwndfind=getFindDialog(hwnd,REPLACE); break; case IDM_FIND: hwndfind=getFindDialog(hwnd,FIND); break; case IDM_BOLD: quickSetFormat(BOLD); break; case IDM_ITALIC: quickSetFormat(ITALIC); break; case IDM_UNDERLINE: quickSetFormat(UNDERLINE); break; case IDM_CENTER: setAlignment(PFA_CENTER); break; case IDM_LEFT: setAlignment(PFA_LEFT); break; case IDM_RIGHT: setAlignment(PFA_RIGHT); break; case IDM_ABOUT: //about模态窗口 DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG1), hwnd,(DLGPROC)AboutDialogProc); } return 0; default: //查找替换对话框消息 if (message==uFindReplaceMsg){ findText(); return 0; } } return DefWindowProc(hwnd, message, wParam, lParam) ; } //about模态对话框 回调函数 BOOL CALLBACK AboutDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) { case WM_CLOSE: EndDialog(hwndDlg, 0); return TRUE; case WM_COMMAND: switch(LOWORD(wParam)) { case IDOK: EndDialog(hwndDlg, 0); break; } return TRUE; } return FALSE; } //组件响应事件处理 void notifyChange(HWND hwnd,LPARAM lParam) { LPTOOLTIPTEXT lpToolTipText; //TOOLTIPTEXT结构指针 MSGFILTER* msgfilter; //MSGFILTER结构指针 //MSGFILTER,TOOLTIPTEXT结构第一个字段都是NMHDR结构 LPNMHDR nmhdr=(LPNMHDR)lParam; //从nmhdr结构获取code消息代码 switch(nmhdr->code) { //richedit键盘鼠标事件响应 case EN_MSGFILTER: msgfilter=(MSGFILTER*)lParam; //MSGFILTER结构中msg消息字段 switch(msgfilter->msg) { case WM_MOUSEACTIVATE: //鼠标单击 setStatus(); break; case WM_KEYUP: //按键按起状态 textChange(F_CHANGE); } break; //工具栏提示文本响应 case TTN_NEEDTEXT: lpToolTipText = (LPTOOLTIPTEXT)lParam; // 如果系统需要文本,则从资源中进行装载字符串 LoadString (hInst, lpToolTipText->hdr.idFrom, // 字符串ID == 命令ID szBuf, sizeof(szBuf)); // 将结构lpszText字段指向字符串 lpToolTipText->lpszText = szBuf; break; //选择文本改变响应 case EN_SELCHANGE: menuChange(hwnd); } } //初始化工具栏 void initToolbar(HWND hwnd) { //按钮结构数组 TBBUTTON tbButtons[]={ {BNEW, IDM_NEW, TBSTATE_ENABLED, TBSTYLE_BUTTON}, {BOPEN, IDM_OPEN, TBSTATE_ENABLED, TBSTYLE_BUTTON}, {BSAVE, IDM_SAVE, TBSTATE_ENABLED, TBSTYLE_BUTTON}, {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP}, {BREVO, IDM_REVO, TBSTATE_ENABLED, TBSTYLE_BUTTON}, {BRECOVERY, IDM_RECOVERY, TBSTATE_ENABLED, TBSTYLE_BUTTON}, {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP}, {BSHEAR, IDM_SHEAR, TBSTATE_ENABLED, TBSTYLE_BUTTON}, {BCOPY, IDM_COPY, TBSTATE_ENABLED, TBSTYLE_BUTTON}, {BPASTE, IDM_PASTE, TBSTATE_ENABLED, TBSTYLE_BUTTON}, {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP}, {BFIND, IDM_FIND, TBSTATE_ENABLED, TBSTYLE_BUTTON}, {BREPLACE, IDM_REPLACE, TBSTATE_ENABLED, TBSTYLE_BUTTON}, {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP}, {BFONTSTYLE, IDM_STYLE, TBSTATE_ENABLED, TBSTYLE_BUTTON}, {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP}, {BLEFT, IDM_LEFT, TBSTATE_ENABLED, TBSTYLE_BUTTON}, {BCENTER, IDM_CENTER, TBSTATE_ENABLED, TBSTYLE_BUTTON}, {BRIGHT, IDM_RIGHT, TBSTATE_ENABLED, TBSTYLE_BUTTON}, {BBOLD, IDM_BOLD, TBSTATE_ENABLED, TBSTYLE_CHECK}, {BITALIC, IDM_ITALIC, TBSTATE_ENABLED, TBSTYLE_CHECK}, {BUNDERLINE, IDM_UNDERLINE, TBSTATE_ENABLED, TBSTYLE_CHECK}, }; //创建工具栏,返回工具栏句柄,IDR_TOOLBAR1工具栏图像id资源号 hWndToolBar=CreateToolbarEx(hwnd,WS_VISIBLE|WS_CHILD|TBSTYLE_FLAT|TBSTYLE_TOOLTIPS,1,22, hInst,IDR_TOOLBAR1,tbButtons,22,0,0,16,16,sizeof(TBBUTTON)); } // void createStatus(HWND hwnd) { //创建一个状态栏 hwndStatus=CreateWindow(STATUSCLASSNAME,"",SBS_SIZEGRIP|WS_CHILD | WS_VISIBLE, 0,0,0,0,hwnd,NULL,hInst,NULL); //移动初始化状态栏 moveStatus(hwnd); //设置状态栏分栏文本,WPARAM指定栏目 SendMessage(hwndStatus, SB_SETTEXT, (WPARAM)0, (LPARAM)TEXT("就绪")); //使用格式化字符串来设置状态栏文本 wsprintf(status_line,staformat,1,1); wsprintf(status_size,sizeformat,0); SendMessage(hwndStatus, SB_SETTEXT, (WPARAM)1, (LPARAM)status_line); SendMessage(hwndStatus, SB_SETTEXT, (WPARAM)2, (LPARAM)status_size); } void moveStatus(HWND hwnd) { RECT rcClient; int width[3]; //状态栏分割数组 GetClientRect(hwnd, &rcClient); //获取父窗口矩形 int length=rcClient.right/3; //根据父窗口宽度来分割指定大小 width[0]=length; //状态栏第一栏宽度,为分割长度length width[1]=length*2; //状态栏往后栏目宽度,为length*栏目标号 width[2]=length*3; //根据width数组来设置状态栏 SendMessage(hwndStatus, SB_SETPARTS, 3, (LPARAM)(LPINT)width); MoveWindow(hwndStatus,0,0,0,0,TRUE); } // void setStatus() { int ln,col,lindex; //获取当前光标索引 SendMessage(hwndrich,EM_GETSEL,(WPARAM)&lindex,0); //获取当前行 ln=SendMessage(hwndrich,EM_LINEFROMCHAR,lindex,0); //返回当前行首字符所以 col=SendMessage(hwndrich,EM_LINEINDEX,ln,0); //用lindex索引减col索引得到列号,更新消息 wsprintf(status_line,staformat,ln+1,lindex-col+1); wsprintf(status_size,sizeformat,size); SendMessage(hwndStatus, SB_SETTEXT, (WPARAM)1, (LPARAM)status_line); SendMessage(hwndStatus, SB_SETTEXT, (WPARAM)2, (LPARAM)status_size); } ///获取对话框 HWND getFindDialog(HWND hwnd,int model) { //初始化FINDREPLACE结构 ZeroMemory(&fr, sizeof(fr)); fr.lStructSize = sizeof(FINDREPLACE); //结构大小 fr.hwndOwner = hwnd; //父窗口 fr.lpstrFindWhat = szFindWhat; //查找字符串 fr.wFindWhatLen = sizeof(szFindWhat); //查找字符串长度 fr.Flags=FR_DOWN|FR_MATCHCASE|FR_HIDEWHOLEWORD; //查找标记 if (model){ //替换对话框 fr.lpstrReplaceWith=szReplaceWhat; //替换字符串 fr.wReplaceWithLen=sizeof(szReplaceWhat); //字符串长度 fr.Flags=FR_HIDEWHOLEWORD|FR_REPLACE|FR_REPLACEALL; //替换标记 return ReplaceText(&fr); } return FindText(&fr); } //查找,替换逻辑 void findText() { //FR_DIALOGTERM消息就返回 if (fr.Flags&FR_DIALOGTERM){return;} //定义查找结构,并获取当前光标位置 FINDTEXTEX findtext; findtext.lpstrText=fr.lpstrFindWhat; SendMessage(hwndrich,EM_EXGETSEL,0,(LPARAM)&findtext.chrg); if (fr.Flags&FR_FINDNEXT||fr.Flags&FR_REPLACE||fr.Flags&FR_REPLACEALL) { //FR_REPLACE或FR_REPLACEALL消息时执行 if (fr.Flags&FR_REPLACE||fr.Flags&FR_REPLACEALL){ CHAR buffer[MAX_PATH]; //声明临时数组存储当前选中文本内容 SendMessage(hwndrich,EM_GETSELTEXT,0,(LPARAM)buffer); if (strcmp(buffer,fr.lpstrFindWhat)==0){ //当前选中内容和替换文本一致,进行替换并更新状态栏 SendMessage(hwndrich,EM_REPLACESEL,0,(LPARAM)fr.lpstrReplaceWith); textChange(F_CHANGE); } } //FR_DOWN标志判断 if (fr.Flags&FR_DOWN){ //非FR_FINDNEXT消息,进行findtext结构查找范围更改 if (!(fr.Flags&FR_FINDNEXT)&&findtext.chrg.cpMin!=findtext.chrg.cpMax){ findtext.chrg.cpMin=findtext.chrg.cpMax+strlen(fr.lpstrReplaceWith); }else{findtext.chrg.cpMin=findtext.chrg.cpMax;} //findtext查找范围cpMax默认为当前文本内容长度 findtext.chrg.cpMax=GetWindowTextLength(hwndrich); }else{ findtext.chrg.cpMax=-1;} //非FR_DOWN标志,进行向上查找,改变查找范围 LRESULT pos; //声明pos变量记录当前查找结果索引 pos=SendMessage(hwndrich,EM_FINDTEXTEX,fr.Flags,(LPARAM)&findtext); if (pos==-1){ if (fr.Flags&FR_REPLACEALL){ //FR_REPLACEALL消息时提示信息 MessageBox(hwndfind,TEXT("全部替换完毕!"),"Notepad",MB_ICONINFORMATION); }else{ MessageBox(hwndfind,TEXT("没有找到匹配字符!"),"Notepad",MB_ICONINFORMATION);} return; //FR_REPLACEALL消息,递归替换,函数返回点 }else{ //选中当前查找文本,高亮显示 SendMessage(hwndrich,EM_EXSETSEL,0,(LPARAM)&(findtext.chrgText)); } //FR_REPLACEALL 递归查找 if (fr.Flags&FR_REPLACEALL){findText();}; } } //richedit流回调函数 DWORD CALLBACK StreamCallback(DWORD dwCookie,LPBYTE pbBuff,LONG cb,LONG *pcb) { FILE* ofile=(FILE*)dwCookie; //文件指针 int get; LONG i=0; while ((get=fgetc(ofile))!=EOF && (i++)<cb){ *(pbBuff++)=get; //数据写入pbBuff缓冲区。cb写入最大值 } *pcb=i; //实际写入大小 return 0; } //流回调写入函数 DWORD CALLBACK SaveStreamCallback(DWORD dwCookie,LPBYTE pbBuff,LONG cb,LONG *pcb) { FILE* sfile=(FILE*)dwCookie; //文件指针 LONG i=0; while ((i++)<cb){ putc(*(pbBuff++),sfile); //pbBuff缓存区写入文件 } *pcb=i; return 0; } //初始化OPENFILENAME结构 void initOpn(OPENFILENAME* opfn,char* filename,LPCSTR Title,DWORD filterIndex) { ZeroMemory(opfn,sizeof(OPENFILENAME)); opfn->lStructSize=sizeof(OPENFILENAME); //结构大小 opfn->lpstrFile=filename; //文件名保存字符数组 opfn->lpstrTitle=Title; //标题 opfn->lpstrFilter=filtername; //文件过滤器 opfn->nMaxFile=MAX_PATH; //lpstrFile数组大小 opfn->lpstrDefExt=""; //默认文件后缀 //定义打开模式标记 opfn->Flags=OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; opfn->nFilterIndex=filterIndex; //文件过滤器索引 } //初始化编辑流结构 void initEidtStream(EDITSTREAM* stream,LPCSTR type,EDITSTREAMCALLBACK callback) { ZeroMemory(stream,sizeof(EDITSTREAM)); file=fopen(filename,type); //根据模式打开文件 stream->dwCookie=(DWORD_PTR)file; //定义编辑流结构字段 stream->dwError=0; stream->pfnCallback=callback; //回调函数 if (strcmp(type,TEXT("rb"))==0){ TCHAR buff[3]; //字符缓存 //16进制格式化输入字符缓冲区,FFFE为unicode文件头,这里逆序存入字符数组,为FEFF sprintf(buff,"%X%X",fgetc(file),fgetc(file)); if (strcmp(buff,TEXT("FEFF"))==0){ txtcode=TXT_UNICODE; }else{ txtcode=TXT_ASCII; fseek(file,0,0); //从定位文件到开头 } }else{ IF_FALSE(txtcode,fprintf(file,TEXT("%c%c"),255,254),0);//255->0xFF,254->0xFE } } //保存文件 void savefile(HWND hwnd,int savemodel) { //判断保存模式 if(savemodel || strcmp(SaveFileName,TEXT(""))==0) { if (savefiledialog(hwndrich)){ //保存成功。更新标题名 strcpy(SaveFileName,filename); SetWindowText(hwnd,strcat(SaveFileName,TEXT("-Notepad"))); } }else{ savetofile(); } } //保存文件对话框 int savefiledialog(HWND hwndrich) { //初始化OPENFILENAME结构-保存 initOpn(&opfn,filename,"保存",filterIndex); if(GetSaveFileName(&opfn)){ savetofile(); return 1; } return 0; } //保存文件 void savetofile() { EDITSTREAM stream; //写入模式初始化编辑流 initEidtStream(&stream,"wb",SaveStreamCallback); //判断文件后缀,其实OPENFILENAME结构有保存选择后缀字段,使用字段会简化点 selText(filtername,opfn.nFilterIndex,defext); TCHAR* charpos=strstr(defext,"rtf"); if (charpos==NULL){ //非rtf后缀,都使用text格式保存 IF_FALSE(txtcode,SendMessage(hwndrich,EM_STREAMOUT,SF_TEXT|SF_UNICODE,(LPARAM)&stream), SendMessage(hwndrich,EM_STREAMOUT,SF_TEXT,(LPARAM)&stream)); }else{ SendMessage(hwndrich,EM_STREAMOUT,SF_RTF,(LPARAM)&stream);} //更新状态栏,并修改编辑状态。 SendMessage(hwndStatus, SB_SETTEXT, (WPARAM)0, (LPARAM)TEXT("已保存")); isSave=TRUE; fclose(file); //关闭文件句柄 } //字符格式结构 void getCHARFORMAT(HWND hwndrich,CHARFORMAT* cformat,CHOOSEFONT* cf) { LOGFONT* lf=cf->lpLogFont; //获取当前选择字符样式结构,CHARFORMAT SendMessage(hwndrich,EM_GETCHARFORMAT,SCF_SELECTION,(LPARAM)cformat); //与~CFE_AUTOCOLOR字段,总是使dwEffects的CFE_AUTOCOLOR位无效 cformat->dwEffects&=~CFE_AUTOCOLOR; cf->rgbColors=cformat->crTextColor; strcpy(lf->lfFaceName,cformat->szFaceName); //根据CHARFORMAT结构字段初始化LOGFONT lf->lfStrikeOut=cformat->dwEffects&CFM_STRIKEOUT; //删除线 lf->lfUnderline=cformat->dwEffects&CFM_UNDERLINE; //下划线 lf->lfItalic=cformat->dwEffects&CFE_ITALIC; //斜体 cformat->dwEffects&CFE_BOLD?lf->lfWeight=FW_BOLD:0; //粗体 lf->lfHeight=-cformat->yHeight/15; //字体大小 } //工具栏快速设置 void quickSetFormat(int STYLE) { //获取选中文本字符格式结构 SendMessage(hwndrich,EM_GETCHARFORMAT,SCF_SELECTION,(LPARAM)&cformat); switch(STYLE) { case BOLD: if (SendMessage(hWndToolBar,TB_ISBUTTONCHECKED,IDM_BOLD,0)){ cformat.dwEffects|=CFM_BOLD; //|=,添加CFM_BOLD属性。&=~CFM_BOLD清除属性 }else{cformat.dwEffects&=~CFM_BOLD;} break; case ITALIC: if (SendMessage(hWndToolBar,TB_ISBUTTONCHECKED,IDM_ITALIC,0)){ cformat.dwEffects|=CFM_ITALIC; //斜体 }else{cformat.dwEffects&=~CFM_ITALIC;} break; case UNDERLINE: if (SendMessage(hWndToolBar,TB_ISBUTTONCHECKED,IDM_UNDERLINE,0)){ cformat.dwEffects|=CFM_UNDERLINE; //下划线 }else{cformat.dwEffects&=~CFM_UNDERLINE;} } //设置格式,状态栏 SendMessage(hwndrich,EM_SETCHARFORMAT,SCF_SELECTION,(LPARAM)&cformat); SendMessage(hwndStatus, SB_SETTEXT, (WPARAM)0, (LPARAM)TEXT("已修改")); isSave=FALSE; } //选取文本动态改变工具栏图标状态 void checkFormat() { SendMessage(hwndrich,EM_GETCHARFORMAT,SCF_SELECTION,(LPARAM)&cformat); /*?三元运算符,根据选中文本格式,改变对应工具栏图标状态*/ //下划线 cformat.dwEffects&CFM_UNDERLINE?SendMessage(hWndToolBar,TB_CHECKBUTTON,IDM_UNDERLINE,TRUE): SendMessage(hWndToolBar,TB_CHECKBUTTON,IDM_UNDERLINE,FALSE); //斜体 cformat.dwEffects&CFE_ITALIC?SendMessage(hWndToolBar,TB_CHECKBUTTON,IDM_ITALIC,TRUE): SendMessage(hWndToolBar,TB_CHECKBUTTON,IDM_ITALIC,FALSE); //粗体 cformat.dwEffects&CFE_BOLD?SendMessage(hWndToolBar,TB_CHECKBUTTON,IDM_BOLD,TRUE): SendMessage(hWndToolBar,TB_CHECKBUTTON,IDM_BOLD,FALSE); } //设置样式 void setFont(HWND hwndrich) { CHOOSEFONT cf; //字体设置对话框结构 LOGFONT lf; //字体属性结构 ZeroMemory(&cf,sizeof(CHOOSEFONT)); cf.lStructSize=sizeof(CHOOSEFONT); cf.lpLogFont= &lf; cf.Flags= CF_SCREENFONTS|CF_EFFECTS|CF_INITTOLOGFONTSTRUCT; //对话框默认显示样式标记 getCHARFORMAT(hwndrich,&cformat,&cf); //获取当前样式来设置字体对话框 if(ChooseFont(&cf)){ //依据LOGFONT字段来设置CHARFORMAT结构字段量 lf.lfItalic?(cformat.dwEffects|=CFE_ITALIC):(cformat.dwEffects&=~CFE_ITALIC); lf.lfStrikeOut?(cformat.dwEffects|=CFM_STRIKEOUT):(cformat.dwEffects&=~CFM_STRIKEOUT); lf.lfUnderline?(cformat.dwEffects|=CFM_UNDERLINE):(cformat.dwEffects&=~CFM_UNDERLINE); lf.lfWeight>=FW_BOLD?(cformat.dwEffects|=CFM_BOLD):(cformat.dwEffects&=~CFM_BOLD); cformat.crTextColor=cf.rgbColors; //颜色 cformat.yHeight=-lf.lfHeight*15; //size大小 strcpy(cformat.szFaceName,lf.lfFaceName); //字体名称 SendMessage(hwndrich,EM_SETCHARFORMAT,SCF_SELECTION,(LPARAM)&cformat); SendMessage(hwndStatus, SB_SETTEXT, (WPARAM)0, (LPARAM)TEXT("已修改")); isSave=FALSE; } } //文件后缀判断,//可以直接使用OPENFILENAME结构字段保存选择的后缀 void selText(TCHAR* lpchar,int index,TCHAR* defext) { int i; //根据选择索引值获取索引对应后缀字符串 for(i=0;i<((index-1)*2+1);++i){ while(*(lpchar++)!='\0'){ } } strcpy(defext,lpchar); } //打开文件 void openfile(HWND hwnd) { if (isSave){ readfile(hwnd); }else{ int result=MessageBox(hwnd,TEXT("文件已经改动!需要保存吗?"),TEXT("提示"),MB_YESNOCANCEL|MB_ICONINFORMATION); switch(result) { case IDYES: //另存为 savefile(hwnd,SAVEAS); readfile(hwnd); break; case IDNO: readfile(hwnd); break; case IDCANCEL: break; } } } //拖放文件打开 void clickfile(HWND hwnd,LPSTR name) { //获取命令行字符串,截取两端的“ name=substring(name,1,strlen(name)-2); strcpy(filename,name); //初始化编辑流,并打开文件 EDITSTREAM stream; initEidtStream(&stream,"rb",StreamCallback); //从文件检查后缀 TCHAR* charpos=strstr(filename,".rtf"); if (charpos==NULL){ //非rtf文件打开模式 filterIndex=2; //改变后缀索引 //根据文本编码打开文件 if (txtcode){ SendMessage(hwndrich,EM_STREAMIN,SF_TEXT|SF_UNICODE,(LPARAM)&stream); txtcode=TXT_UNICODE; }else{ //ASCII码 SendMessage(hwndrich,EM_STREAMIN,SF_TEXT,(LPARAM)&stream); } }else{ filterIndex=1; SendMessage(hwndrich,EM_STREAMIN,SF_RTF,(LPARAM)&stream); } //初始化OPENFILENAME结构 initOpn(&opfn,filename,"打开",filterIndex); strcpy(SaveFileName,filename); //设置标题栏 SetWindowText(hwnd,strcat(SaveFileName,TEXT("-Notepad"))); //更改状态栏信息 textChange(F_OPEN); SendMessage(hwndStatus, SB_SETTEXT, (WPARAM)0, (LPARAM)TEXT("就绪")); isSave=TRUE; fclose(file); } //读取文件 void readfile(HWND hwnd) { //打开模式初始化结构 initOpn(&opfn,filename,TEXT("打开"),filterIndex); if(GetOpenFileName(&opfn)){ EDITSTREAM stream; //读取模式初始化编辑流 initEidtStream(&stream,"rb",StreamCallback); filterIndex=opfn.nFilterIndex; selText(filtername,opfn.nFilterIndex,defext); TCHAR* charpos=strstr(defext,"rtf"); //检索文件后缀 if (charpos==NULL){ SetWindowText(hwndrich,TEXT("")); //清空当前内容 //根据文本编码打开文件 IF_FALSE(txtcode,SendMessage(hwndrich,EM_STREAMIN,SF_TEXT|SF_UNICODE,(LPARAM)&stream), SendMessage(hwndrich,EM_STREAMIN,SF_TEXT,(LPARAM)&stream)); }else{ SendMessage(hwndrich,EM_STREAMIN,SF_RTF,(LPARAM)&stream);} //更改标题栏文件名 strcpy(SaveFileName,filename); SetWindowText(hwnd,strcat(SaveFileName,TEXT("-Notepad"))); textChange(F_OPEN); SendMessage(hwndStatus, SB_SETTEXT, (WPARAM)0, (LPARAM)TEXT("就绪")); isSave=TRUE; fclose(file); } } //获取内容长度 long getLength() { //GETTEXTLENGTHEX结构 用来保存当前内容长度字段 GETTEXTLENGTHEX lengthstrust={GTL_NUMCHARS,1200}; return SendMessage(hwndrich,EM_GETTEXTLENGTHEX,(WPARAM)&lengthstrust,(LPARAM)0); } //窗口布局改变 void setWindowSize(HWND hwnd) { RECT mainrect,recttemp; //width,richedit宽度,height,richedit高度 long width,height; //获取主窗口布局矩形 GetClientRect(hwnd,&mainrect); //获取width width=mainrect.right-mainrect.left; //移动状态栏 moveStatus(hwnd); //获取状态栏窗口矩形 GetWindowRect(hwndStatus,&recttemp); height=recttemp.top; //获取工具栏窗口矩形 GetWindowRect(hWndToolBar,&recttemp); //得到richedit窗口top long top=recttemp.bottom-recttemp.top; height-=recttemp.bottom; SendMessage(hWndToolBar,TB_AUTOSIZE,0,0); //改变richedit窗口位置大小 MoveWindow(hwndrich,mainrect.left,top, width,height,TRUE); } //设置状态栏 void textChange(int model) { //当前文本长度 long sizetemp=getLength(); //文本内容长度改变,model为open,或isSave为TRUE if (model && isSave && size!=sizetemp){ isSave=FALSE; SendMessage(hwndStatus, SB_SETTEXT, (WPARAM)0, (LPARAM)TEXT("已修改")); } //更新文本长度 size=sizetemp; setStatus(); } //菜单工具栏状态 void menuChange(HWND hwnd) { CHARRANGE chrg; //获取文本选择区域 SendMessage(hwndrich,EM_EXGETSEL,0,(LPARAM)&chrg); if (chrg.cpMin==chrg.cpMax){ EnableMenuItem(GetMenu(hwnd),IDM_COPY,MF_BYCOMMAND|MF_GRAYED); EnableMenuItem(GetMenu(hwnd),IDM_SHEAR,MF_BYCOMMAND|MF_GRAYED); EnableMenuItem(GetMenu(hwnd),IDM_STYLE,MF_BYCOMMAND|MF_GRAYED); SendMessage(hWndToolBar,TB_ENABLEBUTTON,IDM_COPY,FALSE); SendMessage(hWndToolBar,TB_ENABLEBUTTON,IDM_SHEAR,FALSE); SendMessage(hWndToolBar,TB_ENABLEBUTTON,IDM_STYLE,FALSE); SendMessage(hWndToolBar,TB_ENABLEBUTTON,IDM_BOLD,FALSE); SendMessage(hWndToolBar,TB_ENABLEBUTTON,IDM_ITALIC,FALSE); SendMessage(hWndToolBar,TB_ENABLEBUTTON,IDM_UNDERLINE,FALSE); }else{ EnableMenuItem(GetMenu(hwnd),IDM_COPY,MF_BYCOMMAND|MF_ENABLED); EnableMenuItem(GetMenu(hwnd),IDM_SHEAR,MF_BYCOMMAND|MF_ENABLED); EnableMenuItem(GetMenu(hwnd),IDM_STYLE,MF_BYCOMMAND|MF_ENABLED); SendMessage(hWndToolBar,TB_ENABLEBUTTON,IDM_COPY,TRUE); SendMessage(hWndToolBar,TB_ENABLEBUTTON,IDM_SHEAR,TRUE); SendMessage(hWndToolBar,TB_ENABLEBUTTON,IDM_STYLE,TRUE); SendMessage(hWndToolBar,TB_ENABLEBUTTON,IDM_BOLD,TRUE); SendMessage(hWndToolBar,TB_ENABLEBUTTON,IDM_ITALIC,TRUE); SendMessage(hWndToolBar,TB_ENABLEBUTTON,IDM_UNDERLINE,TRUE); //更新格式化工具栏状态 checkFormat(); } } //新建文件 void newfile(HWND hwnd) { if (isSave){ SetWindowText(hwndrich,TEXT("")); SetWindowText(hwnd,defaultname); }else{ int result=MessageBox(hwnd,TEXT("文件已经改动!需要保存吗?"),TEXT("提示"),MB_YESNOCANCEL|MB_ICONINFORMATION); switch(result) { case IDYES: savefile(hwnd,SAVEAS); break; case IDNO: //清空窗口内容,设置标题栏 SetWindowText(hwndrich,TEXT("")); SetWindowText(hwnd,defaultname); SendMessage(hwndStatus, SB_SETTEXT, (WPARAM)0, (LPARAM)TEXT("就绪")); isSave=TRUE; break; case IDCANCEL: break; } } txtcode=TXT_ASCII; //改变默认编码 } //退出 void close(HWND hwnd) { //检查文件保存状态 if (isSave){ PostQuitMessage(0); }else{ int result=MessageBox(hwnd,TEXT("文件已经改动!需要保存吗?"),TEXT("提示"), MB_YESNOCANCEL|MB_ICONINFORMATION); switch(result) { case IDYES: //保存文件再退出 savefile(hwnd,SAVE); PostQuitMessage(0); break; case IDNO: PostQuitMessage(0); break; case IDCANCEL: break; } } } //设置段落格式 void setAlignment(int style) { //获取当前段落格式 style格式参数 SendMessage(hwndrich,EM_GETPARAFORMAT,0,(LPARAM)¶format); //设置文本居中,靠左,靠右属性有效字段PFM_ALIGNMENT paraformat.dwMask|=PFM_ALIGNMENT; paraformat.wAlignment=style; SendMessage(hwndrich,EM_SETPARAFORMAT,0,(LPARAM)¶format); //更改保存状态 isSave=FALSE; SendMessage(hwndStatus, SB_SETTEXT, (WPARAM)0, (LPARAM)TEXT("已修改")); } //字符串截取 TCHAR* substring(TCHAR* ch,int pos,int length) { char* pch=ch; //定义一个字符指针,指向传递进来的ch地址。 TCHAR* subch=calloc(sizeof(TCHAR),length+1); //通过calloc来分配一个length长度的字符数组,返回的是字符指针。 int i; pch=pch+pos; //是pch指针指向pos位置。 for(i=0;i<length;i++) { subch[i]=*(pch++); } subch[length]='\0';//加上字符串结束符。 return subch; //返回分配的字符数组地址。 }