做网站首页图片素材,wordpress 增删改查 函数,门户网站建设方案模板,直播系统平台Windows最初发行时的主要目标之一就是提倡一种标准化的用户界面。对于公用菜单 项来说#xff0c;这一目标实现得很快。几乎所有的软件制造商都采用了Alt-File-Open组合来打开 文件。但是#xff0c;真正用来打开文件的对话框却经常很不一样。
从Windows 3.1开始#xff0c…Windows最初发行时的主要目标之一就是提倡一种标准化的用户界面。对于公用菜单 项来说这一目标实现得很快。几乎所有的软件制造商都采用了Alt-File-Open组合来打开 文件。但是真正用来打开文件的对话框却经常很不一样。
从Windows 3.1开始这一问题的解决方案开始出现。这一方案被称作“公用对话框库”common dialogue box library。这个库包括了一些函数可以用来激活打开和存储文件、 查找和替换、选择颜色、选择字体以及打印将在第十三章中演示的对话框。
在使用这些函数时基本上要初始化一个结构的一些字段并将该结构的指针传递给公用对话框库的某个函数。该函数会创建并显示相应对话框。当用户关闭对话框时函数将控制权返还给程序然后程序可以从此前传递给函数的结构中获取信息。
需要在所有用到公用对话框库的C源文件中包括COMMDLG.H头文件。
本节必须掌握的知识点 公用对话框 第68练完善的POPPAD 第69练颜色对话框模板
10.3.1 公用对话框
■打开文件公用对话框 要打开文件的公用对话框可以使用 Windows API 中的 GetOpenFileName 函数。该函数允许用户选择一个文件并返回所选文件的路径。
以下是 GetOpenFileName 函数的函数原型
BOOL GetOpenFileName( LPOPENFILENAME lpofn
);
参数说明
lpofn指向 OPENFILENAME 结构体的指针它包含了打开文件对话框的各种参数和选项。
返回值
如果用户选择了文件并点击了打开按钮函数返回非零值 (TRUE)。
如果用户取消了对话框或者发生了错误函数返回零值 (FALSE)。 OPENFILENAME 是一个结构体用于配置和传递给 GetOpenFileName 和 GetSaveFileName 函数的参数和选项。它定义了打开文件对话框和保存文件对话框的行为。
以下是 OPENFILENAME 结构体的定义
typedef struct tagOFN { DWORD lStructSize;// 结构体的大小必须设置为 sizeof(OPENFILENAME) HWND hwndOwner; // 父窗口的句柄 HINSTANCE hInstance; // 应用程序实例句柄 LPCTSTR lpstrFilter; // 文件过滤器 LPTSTR lpstrCustomFilter; // 自定义过滤器 DWORD nMaxCustFilter; // 自定义过滤器的最大长度 DWORD nFilterIndex; // 初始选择的过滤器索引 LPTSTR lpstrFile; // 接收选择的文件路径的缓冲区 DWORD nMaxFile; // lpstrFile 缓冲区的大小 LPTSTR lpstrFileTitle; // 接收选择的文件名的缓冲区 DWORD nMaxFileTitle; // lpstrFileTitle 缓冲区的大小 LPCTSTR lpstrInitialDir; // 初始目录 LPCTSTR lpstrTitle; // 对话框标题 DWORD Flags; // 选项标志 WORD nFileOffset; // 文件名在 lpstrFile 中的偏移量 WORD nFileExtension; // 文件扩展名在 lpstrFile 中的偏移量 LPCTSTR lpstrDefExt; // 默认文件扩展名 LPARAM lCustData; // 自定义数据 LPOFNHOOKPROC lpfnHook; // 钩子函数 LPCTSTR lpTemplateName; // 自定义模板的资源名称
#if (_WIN32_WINNT 0x0500) void * pvReserved; // 保留不要使用 DWORD dwReserved; // 保留不要使用 DWORD FlagsEx; // 扩展选项标志
#endif // (_WIN32_WINNT 0x0500)
} OPENFILENAME, *LPOPENFILENAME;
OPENFILENAME 结构体的注释详细说明了每个成员的作用和用法您可以根据需要设置相应的成员来配置打开文件对话框的行为和选项。 ●使用 GetOpenFileName 函数的一般步骤如下
1初始化 OPENFILENAME 结构体设置各种参数和选项。
2调用 GetOpenFileName 函数并传递指向初始化的 OPENFILENAME 结构体的指针。
3检查 GetOpenFileName 的返回值判断用户是否选择了文件并点击了打开按钮。
4如果返回值为非零通过 OPENFILENAME 结构体的 lpstrFile 成员获取所选文件的路径。
●以下是一个简单的示例代码演示如何使用 GetOpenFileName 函数
#include windows.h
#include commdlg.h int main()
{ OPENFILENAME ofn { 0 }; TCHAR szFile[MAX_PATH] { 0 }; ofn.lStructSize sizeof(OPENFILENAME); ofn.hwndOwner NULL; // 父窗口句柄可设置为 NULL ofn.lpstrFilter _T(Text Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0); // 文件过滤器 ofn.lpstrFile szFile; // 存储用户选择的文件路径 ofn.nMaxFile MAX_PATH; // szFile 缓冲区大小 ofn.Flags OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST; // 选项 if (GetOpenFileName(ofn)) { // 用户选择了文件并点击了打开按钮 MessageBox(NULL, ofn.lpstrFile, _T(Selected File), MB_OK); } return 0;
}
以上示例代码使用 GetOpenFileName 函数打开一个包含文件过滤器的打开文件对话框。用户可以选择一个文本文件 (.txt) 或任何文件 (所有文件选项)。如果用户选择了文件并点击了打开按钮则通过 MessageBox 函数显示所选文件的路径。
【注意】示例代码中使用了 _T 宏它根据编译选项确定是使用 ANSI 字符集还是 Unicode 字符集。在 Unicode 编译模式下TCHAR 被定义为 wchar_t在 ANSI 编译模式下TCHAR 被定义为 char。因此字符串参数和结构体成员使用 _T 宏进行宽字符/窄字符兼容处理。 ■存储文件公用对话框 要使用公共文件对话框来存储文件您可以使用 GetSaveFileName 函数和 OPENFILENAME 结构体。以下是一个简单的示例代码展示如何配置和使用公共文件对话框来存储文件
#include windows.h
#include commdlg.h int main()
{ // 初始化 OPENFILENAME 结构体 OPENFILENAME ofn {0}; TCHAR szFile[MAX_PATH] {0}; ofn.lStructSize sizeof(OPENFILENAME); ofn.hwndOwner NULL; // 父窗口的句柄这里设置为 NULL ofn.lpstrFilter TEXT(Text Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0); // 文件过滤器 ofn.lpstrFile szFile; // 用于接收文件路径的缓冲区 ofn.nMaxFile MAX_PATH; // 缓冲区大小 ofn.lpstrDefExt TEXT(txt); // 默认文件扩展名 ofn.Flags OFN_OVERWRITEPROMPT; // 显示覆盖提示对话框 // 显示存储文件对话框 if (GetSaveFileName(ofn)) { // 用户点击了保存按钮可以使用 ofn.lpstrFile 获取选择的文件路径 MessageBox(NULL, ofn.lpstrFile, TEXT(Selected File), MB_OK); } return 0;
}
以上代码首先初始化了 OPENFILENAME 结构体并设置了相关的成员如文件过滤器、文件路径缓冲区、默认文件扩展名等。然后使用 GetSaveFileName 函数来显示存储文件对话框。如果用户点击了保存按钮并选择了文件路径您可以通过 ofn.lpstrFile 获取选择的文件路径并进行相应的处理。 ■查找和替换公用对话框
要使用公共文件对话框来进行查找和替换操作您可以使用 FindText 和 ReplaceText 函数以及相应的结构体。以下是一个简单的示例代码演示如何配置和使用公共文件对话框来进行查找和替换
#include windows.h
#include commdlg.h int main()
{ // 初始化 FINDREPLACE 结构体 FINDREPLACE fr {0}; TCHAR szFind[MAX_PATH] {0}; TCHAR szReplace[MAX_PATH] {0}; fr.lStructSize sizeof(FINDREPLACE); fr.hwndOwner NULL; // 父窗口的句柄这里设置为 NULL fr.lpstrFindWhat szFind; // 用于接收查找文本的缓冲区 fr.wFindWhatLen MAX_PATH; // 缓冲区大小 fr.lpstrReplaceWith szReplace; // 用于接收替换文本的缓冲区 fr.wReplaceWithLen MAX_PATH; // 缓冲区大小 fr.Flags FR_DOWN; // 查找方向为向下 // 显示查找和替换对话框 if (FindText(fr)) { // 用户点击了查找或替换按钮可以使用 fr.lpstrFindWhat
//和 fr.lpstrReplaceWith 获取查找和替换文本 MessageBox(NULL, fr.lpstrFindWhat, TEXT(Find Text), MB_OK); MessageBox(NULL, fr.lpstrReplaceWith, TEXT(Replace Text), MB_OK); } return 0;
}
以上代码首先初始化了 FINDREPLACE 结构体并设置了相关的成员如查找文本缓冲区、替换文本缓冲区等。然后使用 FindText 函数来显示查找和替换对话框。如果用户点击了查找或替换按钮您可以通过 fr.lpstrFindWhat 和 fr.lpstrReplaceWith 获取查找和替换文本并进行相应的处理。
●以下是 FINDREPLACE 结构体的定义每个成员都有相应的注释说明其作用和用法
typedef struct tagFINDREPLACE { DWORD lStructSize; // 结构体的大小必须设置为 sizeof(FINDREPLACE) HWND hwndOwner; // 父窗口的句柄 HINSTANCE hInstance; // 应用程序实例句柄 DWORD Flags; // 选项标志 LPCTSTR lpstrFindWhat; // 查找文本的缓冲区 LPCTSTR lpstrReplaceWith; // 替换文本的缓冲区 WORD wFindWhatLen; // 查找文本的缓冲区大小 WORD wReplaceWithLen; // 替换文本的缓冲区大小 LPARAM lCustData; // 自定义数据 LPFRHOOKPROC lpfnHook; // 钩子函数 LPCTSTR lpTemplateName; // 自定义模板的资源名称
} FINDREPLACE, *LPFINDREPLACE; ■选择字体公用对话框
要使用公共字体对话框来选择字体您可以使用 ChooseFont 函数和 CHOOSEFONT 结构体。以下是一个简单的示例代码展示如何配置和使用公共字体对话框来选择字体
#include windows.h
#include commdlg.h int main()
{ // 初始化 CHOOSEFONT 结构体 CHOOSEFONT cf {0}; LOGFONT lf {0}; cf.lStructSize sizeof(CHOOSEFONT); cf.hwndOwner NULL; // 父窗口的句柄这里设置为 NULL cf.lpLogFont lf; // 用于接收选择的字体信息的 LOGFONT 结构体指针 cf.Flags CF_SCREENFONTS | CF_EFFECTS; // 显示屏幕字体和效果选项 // 显示选择字体对话框 if (ChooseFont(cf)) { // 用户点击了确定按钮可以使用 lf 字段获取选择的字体信息 MessageBox(NULL, lf.lfFaceName, TEXT(Selected Font), MB_OK); } return 0;
}
以下是 CHOOSEFONT 结构体的定义其中包含了选择字体对话框的相关配置信息
typedef struct tagCHOOSEFONT { DWORD lStructSize; // 结构体的大小必须设置为 sizeof(CHOOSEFONT) HWND hwndOwner; // 父窗口的句柄 HDC hDC; // 设备上下文句柄 LPLOGFONT lpLogFont; // 用于接收选择的字体信息的 LOGFONT 结构体指针 INT iPointSize; // 字体大小以 1/10 点为单位 DWORD Flags; // 选项标志 COLORREF rgbColors; // 初始文本颜色和背景颜色 LPARAM lCustData // 自定义数据 LPCFHOOKPROC lpfnHook; // 钩子函数 LPCTSTR lpTemplateName; // 自定义模板的资源名称 HINSTANCE hInstance; // 应用程序实例句柄 LPTSTR lpszStyle; // 预定义样式列表 WORD nFontType; // 字体类型标志 WORD ___MISSING_ALIGNMENT__; // 未使用 INT nSizeMin; // 最小可选择的字体大小 INT nSizeMax; // 最大可选择的字体大小
} CHOOSEFONT, *LPCHOOSEFONT; ■选择颜色公用对话框
要使用公共颜色对话框来选择颜色您可以使用 ChooseColor 函数和 CHOOSECOLOR 结构体。以下是一个简单的示例代码展示如何配置和使用公共颜色对话框来选择颜色
#include windows.h
#include commdlg.h int main()
{ // 初始化 CHOOSECOLOR 结构体 CHOOSECOLOR cc {0}; COLORREF acrCustColors[16] {0}; cc.lStructSize sizeof(CHOOSECOLOR); cc.hwndOwner NULL; // 父窗口的句柄这里设置为 NULL cc.lpCustColors acrCustColors; // 自定义颜色数组 cc.Flags CC_FULLOPEN | CC_RGBINIT; // 全部颜色打开和初始颜色设置 // 显示选择颜色对话框 if (ChooseColor(cc)) { // 用户点击了确定按钮可以使用 cc.rgbResult 获取选择的颜色 COLORREF selectedColor cc.rgbResult; MessageBox(NULL, TEXT(Selected Color), TEXT(Selected Color), MB_OK); } return 0;
}
以上代码首先初始化了 CHOOSECOLOR 结构体并设置了相关的成员如父窗口句柄、自定义颜色数组、显示选项等。然后使用 ChooseColor 函数来显示选择颜色对话框。如果用户点击了确定按钮并选择了颜色您可以通过 cc.rgbResult 获取选择的颜色并进行相应的处理。
以下是 CHOOSECOLOR 结构体的定义其中包含了选择颜色对话框的相关配置信息
typedef struct tagCHOOSECOLOR { DWORD lStructSize; // 结构体的大小必须设置为 sizeof(CHOOSECOLOR) HWND hwndOwner; // 父窗口的句柄 HWND hInstance; // 应用程序实例句柄 COLORREF rgbResult; // 选择的颜色 COLORREF* lpCustColors; // 自定义颜色数组 DWORD Flags; // 选项标志 LPARAM lCustData; // 自定义数据 LPCCHOOKPROC lpfnHook; // 钩子函数 LPCTSTR lpTemplateName; // 自定义模板的资源名称
} CHOOSECOLOR, *LPCHOOSECOLOR;
10.3.2 第68练完善的POPPAD
■POPPAD.C
/*------------------------------------------------------------------------ 068 WIN32 API 每日一练 第68个例子POPPAD.C公用对话框-文本编辑器 POPPAD.C //主程序 POPFILE.C //文件菜单处理 POPFIND.C //SEARCH菜单处理 POPFONT.C //FONT菜单处理 POPPRINTO.C //打印处理第十三章讲述 (c) www.bcdaren.com 编程达人
-----------------------------------------------------------------------*/
#include windows.h
#include commdlg.h //公用对话框库
#include resource.h
#define EDITID 1 //顶级菜单IDFILE 0 ,EDIT 1,SEARCH 2,FORMAT 3,HELP 4
#define UNTITLED TEXT ((untitled)) LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
BOOL CALLBACK AboutDlgProc (HWND, UINT, WPARAM, LPARAM) ; // Functions in POPFILE.C
void PopFileInitialize (HWND) ; //初始化File对话框
BOOL PopFileOpenDlg (HWND, PTSTR, PTSTR) ; //创建“打开”文件对话框
BOOL PopFileSaveDlg (HWND, PTSTR, PTSTR) ; //创建“保存”文件对话框
BOOL PopFileRead (HWND, PTSTR) ; //读文件
BOOL PopFileWrite (HWND, PTSTR) ; //写文件 // Functions in POPFIND.C
HWND PopFindFindDlg (HWND) ; //初始化Find对话框
HWND PopFindReplaceDlg (HWND) ; //初始化FindReplace对话框
BOOL PopFindFindText (HWND, int *, LPFINDREPLACE) ; //查找字符串
BOOL PopFindReplaceText (HWND, int *, LPFINDREPLACE) ; //替换字符串
BOOL PopFindNextText (HWND, int *) ; //查找下一处
BOOL PopFindValidFind (void) ; //无效查找 // Functions in POPFONT.C
void PopFontInitialize (HWND) ; //初始化对话框字体
BOOL PopFontChooseFont (HWND) ; //选择字体
void PopFontSetFont (HWND) ; //设置字体
void PopFontDeinitialize (void) ; //删除字体 // Functions in POPPRNT.C
BOOL PopPrntPrintFile (HINSTANCE, HWND, HWND, PTSTR) ; //打印文件 // Global 变量
static HWND hDlgModeless ; //通用对话框句柄
static TCHAR szAppName[] TEXT (PopPad) ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{ MSG msg; HWND hwnd; HACCEL hAccel; WNDCLASS wndclass; wndclass.style CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc WndProc; wndclass.cbClsExtra 0; wndclass.cbWndExtra 0; wndclass.hInstance hInstance; wndclass.hIcon LoadIcon(hInstance, szAppName); wndclass.hCursor LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName szAppName; wndclass.lpszClassName szAppName; if (!RegisterClass(wndclass)) { MessageBox(NULL, TEXT(This program requires Windows NT!), szAppName, MB_ICONERROR); return 0; } hwnd CreateWindow(szAppName, NULL, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, szCmdLine); ShowWindow(hwnd, iCmdShow); UpdateWindow(hwnd); hAccel LoadAccelerators(hInstance, szAppName); while (GetMessage(msg, NULL, 0, 0)) {//对话框为空或不是对话框消息时 if (hDlgModeless NULL || !IsDialogMessage(hDlgModeless, msg)) {//如果加速键消息未被翻译过TranslateAccelerator函数返回值为0 if (!TranslateAccelerator(hwnd, hAccel, msg)) { TranslateMessage(msg); DispatchMessage(msg); } } } return msg.wParam;
}
//设置标题
void DoCaption (HWND hwnd, TCHAR * szTitleName)
{ TCHAR szCaption[64 MAX_PATH]; wsprintf(szCaption, TEXT(%s - %s), szAppName, szTitleName[0] ? szTitleName : UNTITLED); SetWindowText(hwnd, szCaption);
}
//向用户显示消息框提示信息
void OkMessage (HWND hwnd, TCHAR * szMessage, TCHAR * szTitleName)
{ TCHAR szBuffer[64 MAX_PATH]; wsprintf(szBuffer, szMessage, szTitleName[0] ? szTitleName : UNTITLED); MessageBox(hwnd, szBuffer, szAppName, MB_OK | MB_ICONEXCLAMATION);
}
// 是否保存文件
short AskAboutSave (HWND hwnd, TCHAR * szTitleName)
{ TCHAR szBuffer[64 MAX_PATH]; int iReturn; wsprintf(szBuffer, TEXT(Save current changes in %s?), szTitleName[0] ? szTitleName : UNTITLED); iReturn MessageBox(hwnd, szBuffer, szAppName, MB_YESNOCANCEL | MB_ICONQUESTION); if (iReturn IDYES) if (!SendMessage(hwnd, WM_COMMAND, IDM_FILE_SAVE, 0))//IDM_FILE_SAVE返回0为失败1成功 iReturn IDCANCEL;//YES但保存失败 return iReturn;
}
//主窗口过程
LRESULT CALLBACK WndProc ( HWND hwnd, UINT message, WPARAM wParam,LPARAM
lParam)
{ static BOOL bNeedSave FALSE ; static HINSTANCE hInst ; static HWND hwndEdit ; static int iOffset ;
//完全路径文件名缓冲区和文件名缓冲区 static TCHAR szFileName[MAX_PATH], szTitleName[MAX_PATH] ; static UINT messageFindReplace ; int iSelBeg, iSelEnd, iEnable ; LPFINDREPLACE pfr ; switch (message) { case WM_CREATE: hInst ((LPCREATESTRUCT) lParam) - hInstance ; // 创建编辑控件子窗口 hwndEdit CreateWindow (TEXT (edit), NULL, WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL | WS_BORDER | ES_LEFT | ES_MULTILINE |
//ES_NOHIDESEL反转所选文本 ES_NOHIDESEL | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0, 0, 0, 0, hwnd, (HMENU) EDITID, hInst, NULL) ; //设置文本编辑控件的最大字符数0L为long类型常量0 SendMessage (hwndEdit, EM_LIMITTEXT, 32000, 0L) ; // 初始化公用对话框 PopFileInitialize (hwnd) ;//初始化文件公用对话框 PopFontInitialize (hwndEdit) ; //创建字体
/*定义一个新的窗口消息仅当多个应用程序必须处理同一条消息时才使用RegisterWindowMessage。“查找或替换”对话框会将 FINDMSGSTRING 注册的消息发送到其所有者窗口的窗口过程。*/ messageFindReplace RegisterWindowMessage (FINDMSGSTRING) ; DoCaption (hwnd, szTitleName) ; //窗口标题栏显示文件名 return 0 ; case WM_SETFOCUS: SetFocus(hwndEdit);//设置焦点 return 0; case WM_SIZE: MoveWindow(hwndEdit, 0, 0, LOWORD(lParam), HIWORD(lParam),TRUE); return 0; //当下拉菜单或子菜单即将变为活动状态时发送 case WM_INITMENUPOPUP: switch (lParam) { case 1: // Edit 菜单 // 如果有撤销操作启用“Undo”菜单 //启用禁用或显示指定的菜单项 EnableMenuItem ((HMENU) wParam, IDM_EDIT_UNDO, SendMessage (hwndEdit, EM_CANUNDO, 0, 0L) ? MF_ENABLED : MF_GRAYED) ; // 如果文本在剪贴板中则启用粘贴 EnableMenuItem ((HMENU) wParam, IDM_EDIT_PASTE, IsClipboardFormatAvailable (CF_TEXT) ? //剪贴板是否有内容 MF_ENABLED : MF_GRAYED) ; //如果有选中文本字符串启用剪切、复制和删除选中的文本
//获取选定文本的位置信息 SendMessage (hwndEdit, EM_GETSEL, (WPARAM) iSelBeg, (LPARAM) iSelEnd) ; //如果开始位置等于结束位置禁用菜单 iEnable iSelBeg ! iSelEnd ? MF_ENABLED : MF_GRAYED ; EnableMenuItem ((HMENU) wParam, IDM_EDIT_CUT,iEnable) ; EnableMenuItem ((HMENU) wParam, IDM_EDIT_COPY,iEnable) ; EnableMenuItem ((HMENU) wParam, IDM_EDIT_CLEAR,iEnable) ; break ; case 2: // Search 菜单 //如果非模态对话框NULL时激活菜单 iEnable hDlgModeless NULL ? MF_ENABLED : MF_GRAYED ; EnableMenuItem ((HMENU) wParam, IDM_SEARCH_FIND,iEnable) ; EnableMenuItem ((HMENU) wParam, IDM_SEARCH_NEXT, iEnable) ; EnableMenuItem ((HMENU) wParam, IDM_SEARCH_REPLACE, iEnable) ; break ; } return 0 ; case WM_COMMAND: // 处理EDIT控件消息 if (lParam LOWORD (wParam) EDITID) { switch (HIWORD (wParam)) //控件通知码 { //当编辑控件即将重绘时发送。
//在控件格式化文本之后但在显示文本之前发送此通知代码。 case EN_UPDATE : bNeedSave TRUE ; return 0 ; case EN_ERRSPACE : //空间不足 case EN_MAXTEXT : MessageBox(hwnd, TEXT(Edit control out of space.), szAppName, MB_OK | MB_ICONSTOP); return 0; } break ; } switch (LOWORD (wParam)) //加速键ID或菜单ID这里两个ID相等 { //处理FILE菜单消息 case IDM_FILE_NEW: //保存旧文件如果保存时失败则什么都不做直接返回。 if (bNeedSave IDCANCEL AskAboutSave (hwnd, szTitleName)) return 0; //清除编辑框内容 SetWindowText(hwndEdit, TEXT(\0));//设置标题栏缓冲区为空 szFileName[0] \0;//设置文件名缓冲区为空 szTitleName[0] \0;//设置标题缓冲区为空 DoCaption(hwnd, szTitleName);//显示标题栏 bNeedSave FALSE; return 0; case IDM_FILE_OPEN: //保存旧文件如果保存时失败则什么都不做直接返回。 if (bNeedSave IDCANCEL AskAboutSave(hwnd, szTitleName)) return 0; if (PopFileOpenDlg(hwnd, szFileName, szTitleName)) { if (!PopFileRead(hwndEdit, szFileName)) { OkMessage(hwnd, TEXT(Could not read file %s!), szTitleName); szFileName[0] \0; szTitleName[0] \0; } } DoCaption(hwnd, szTitleName); bNeedSave FALSE; return 0; case IDM_FILE_SAVE: if (szFileName[0]) { if (PopFileWrite(hwndEdit, szFileName)) { bNeedSave FALSE; return 1; } else { OkMessage(hwnd, TEXT(Could not write file %s), szTitleName); return 0; } } //继续往下执行 case IDM_FILE_SAVE_AS: if (PopFileSaveDlg(hwnd, szFileName, szTitleName)) { DoCaption(hwnd, szTitleName); if (PopFileWrite(hwndEdit, szFileName)) { bNeedSave FALSE; return 1; } else { OkMessage(hwnd, TEXT(Could not write file %s), szTitleName); return 0; } } return 0; case IDM_FILE_PRINT: if (!PopPrntPrintFile(hInst, hwnd, hwndEdit, szTitleName)) OkMessage(hwnd, TEXT(Could not print file %s), szTitleName); return 0; case IDM_APP_EXIT: SendMessage(hwnd, WM_CLOSE, 0, 0); return 0; // Edit 菜单消息 case IDM_EDIT_UNDO: SendMessage (hwndEdit, WM_UNDO, 0, 0) ; return 0 ; case IDM_EDIT_CUT: SendMessage (hwndEdit, WM_CUT, 0, 0) ; return 0 ; case IDM_EDIT_COPY: SendMessage(hwndEdit, WM_COPY, 0, 0); return 0; case IDM_EDIT_PASTE: SendMessage (hwndEdit, WM_PASTE, 0, 0) ; return 0 ; case IDM_EDIT_CLEAR: SendMessage(hwndEdit, WM_CLEAR, 0, 0); return 0; case IDM_EDIT_SELECT_ALL: SendMessage(hwndEdit, EM_SETSEL, 0, -1); return 0; // Search 菜单消息 case IDM_SEARCH_FIND: //查找将从iOffset位置开始首获取选中文本后面的位置iOffset) SendMessage(hwndEdit, EM_GETSEL, 0, (LPARAM)iOffset); hDlgModeless PopFindFindDlg(hwnd); return 0; case IDM_SEARCH_NEXT: SendMessage(hwndEdit, EM_GETSEL, 0, (LPARAM)iOffset); if (PopFindValidFind()) PopFindNextText(hwndEdit, iOffset); else hDlgModeless PopFindFindDlg(hwnd); return 0; case IDM_SEARCH_REPLACE: SendMessage (hwndEdit, EM_GETSEL, 0, (LPARAM) iOffset) ; hDlgModeless PopFindReplaceDlg (hwnd) ; return 0 ; case IDM_FORMAT_FONT: if (PopFontChooseFont(hwnd)) PopFontSetFont(hwndEdit); return 0 ; // Help菜单消息 case IDM_HELP: OkMessage(hwnd, TEXT(Help not yet implemented!), TEXT(\0)); return 0; case IDM_APP_ABOUT: DialogBox(hInst, TEXT(AboutBox), hwnd, AboutDlgProc); return 0 ; } break ; case WM_CLOSE: if (!bNeedSave || IDCANCEL ! AskAboutSave (hwnd, szTitleName)) DestroyWindow (hwnd) ; return 0 ; //结束会话或者系统关机发送的消息 case WM_QUERYENDSESSION : if (!bNeedSave || IDCANCEL ! AskAboutSave(hwnd, szTitleName)) return 1;//结束 return 0;//不结束 case WM_DESTROY: PopFontDeinitialize(); PostQuitMessage(0); return 0; default: //处理“查找”、“替换”发送的特殊消息 if (message messageFindReplace) { pfr (LPFINDREPLACE)lParam; //用户点击了“取消”按钮 if (pfr-Flags FR_DIALOGTERM) hDlgModeless NULL; //用户点击了“查找下一个”按钮 if (pfr-Flags FR_FINDNEXT) if (!PopFindFindText(hwndEdit, iOffset, pfr)) OkMessage(hwnd, TEXT(Text not found!), TEXT(\0)); //用户点击了“替换”或“替换全部” if (pfr-Flags FR_REPLACE || pfr-Flags FR_REPLACEALL) if (!PopFindReplaceText(hwndEdit, iOffset, pfr)) OkMessage(hwnd, TEXT(Text not found!), TEXT(\0)); if (pfr-Flags FR_REPLACEALL) while (PopFindReplaceText(hwndEdit, iOffset, pfr)); return 0; } break ; } return DefWindowProc (hwnd, message, wParam, lParam) ;
}
//About模态对话框窗口过程
BOOL CALLBACK AboutDlgProc (HWND hDlg, UINT message,WPARAM wParam, LPARAM lParam)
{ switch (message) { case WM_INITDIALOG: return TRUE; case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: EndDialog(hDlg, 0); return TRUE; } break; } return FALSE;
} ■POPFILE.C
/*-------------------------------------------------------------------------- POPFILE.C -- Popup Editor File Functions ------------------------------------------------------------------------*/
#include windows.h
#include commdlg.h
static OPENFILENAME ofn ; //初始化对话框
void PopFileInitialize (HWND hwnd)
{ static TCHAR szFilter[] TEXT (Text Files (*.TXT)\0*.txt\0) \ TEXT(ASCII Files (*.ASC)\0*.asc\0) \ TEXT(All Files (*.*)\0*.*\0\0); ofn.lStructSize sizeof (OPENFILENAME) ; //结构体的大小 ofn.hwndOwner hwnd ; //所属窗口可以为NULL ofn.hInstance NULL ; //对话框模板或模块句柄ofn.Flags字段相关 ofn.lpstrFilter szFilter ; //文件筛选字符串 ofn.lpstrCustomFilter NULL ; //缓冲区保留用户选择的过滤样式 ofn.nMaxCustFilter 0 ; //以TCHAR为单位的缓冲大小 ofn.nFilterIndex 0 ; //当前选择的过滤器的索引 ofn.lpstrFile NULL ; // 在打开和关闭函数中设置全路径文件名缓冲区 ofn.nMaxFile MAX_PATH ;
// 在打开和关闭函数中设置接收不含路径的文件名的缓冲区 ofn.lpstrFileTitle NULL ; ofn.nMaxFileTitle MAX_PATH ; ofn.lpstrInitialDir NULL ; //在这个字符串中指定初始目录 ofn.lpstrTitle NULL ; //对话框标题默认为“打开”或“保存” // 在打开和关闭函数中设置对话框不同行为的标志只读多选覆盖等
ofn.Flags 0; ofn.nFileOffset 0 ; //返回文件名字符串中文件名的起始位置 ofn.nFileExtension 0 ; //扩展名在字符串中的起始位置 ofn.lpstrDefExt TEXT (txt) ; //指定默认的扩展名
//系统传递给由lpfnHook成员标识的hook过程的应用程序定义的数据 ofn.lCustData 0L ; ofn.lpfnHook NULL ; //指向一个钩子程序 ofn.lpTemplateName NULL ; //是对话框模板资源
}
//创建一个“打开”文件对话框
BOOL PopFileOpenDlg (HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName)
{ ofn.hwndOwner hwnd; ofn.lpstrFile pstrFileName;//全路径文件名 ofn.lpstrFileTitle pstrTitleName;//文件名含扩展名
//隐藏只读复选框如果文件不存在则创建文件 ofn.Flags OFN_HIDEREADONLY | OFN_CREATEPROMPT;
//创建一个“打开”文件对话框该对话框允许用户指定驱动器
//目录以及要打开的文件或文件集的名称。 return GetOpenFileName(ofn);
}
//创建一个“保存”文件对话框
BOOL PopFileSaveDlg (HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName)
{ ofn.hwndOwner hwnd; ofn.lpstrFile pstrFileName; ofn.lpstrFileTitle pstrTitleName;
//如果所选文件已存在则使 “另存为”对话框生成一个消息框。
//用户必须确认是否覆盖文件。 ofn.Flags OFN_OVERWRITEPROMPT;
//创建一个“保存”对话框该对话框允许用户指定要保存的文件的驱动器目录和名称。 return GetSaveFileName(ofn);
}
//读取文件
BOOL PopFileRead (HWND hwndEdit, PTSTR pstrFileName)
{ BYTE bySwap ; DWORD dwBytesRead ; HANDLE hFile ; int i, iFileLength, iUniTest ; PBYTE pBuffer, pText, pConv ; // 打开文件 if (INVALID_HANDLE_VALUE (hFile CreateFile(pstrFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL))) return FALSE; // 获取文件大小以字节为单位并为读取分配内存。 iFileLength GetFileSize (hFile, NULL) ; pBuffer malloc (iFileLength 2) ; //多出两个字节存放两个\0 //读文件到缓冲区并在文件末尾放\0结束符 ReadFile (hFile, pBuffer, iFileLength, dwBytesRead, NULL) ; CloseHandle (hFile) ; pBuffer[iFileLength] \0 ; pBuffer[iFileLength 1] \0 ; //测试文本是否是Unicode编码前两个字节为0xFEFF或0xFFFE //IS_TEXT_UNICODE_SIGNATURE——0xFEFF小端高高低低 //IS_TEXT_UNICODE_REVERSE_SIGNATURE——0xFFFE大端 iUniTest IS_TEXT_UNICODE_SIGNATURE | IS_TEXT_UNICODE_REVERSE_SIGNATURE ; if (IsTextUnicode (pBuffer, iFileLength, iUniTest)) { pText pBuffer 2;//跳过前两个字节指向正文部分 iFileLength - 2;
//如果大端存储调换字节顺序 if (iUniTest IS_TEXT_UNICODE_REVERSE_SIGNATURE) { for (i 0; i iFileLength / 2; i) { bySwap ((BYTE *)pText)[2 * i]; ((BYTE *)pText)[2 * i] ((BYTE *)pText)[2 * i 1]; ((BYTE *)pText)[2 * i 1] bySwap; } } //为可能的字符串转换分配内存 pConv malloc (iFileLength 2) ; //Edit控件使用Unicode则显示之前将Unicode文本转化为多字节文本 #ifndef UNICODE WideCharToMultiByte (CP_ACP, 0, (PWSTR) pText, -1, pConv, iFileLength 2, NULL, NULL) ; //共iFileLength2字节含2个\0 //Edit控件是非Unicode则直接拷贝文本 #else lstrcpy ((PTSTR) pConv, (PTSTR) pText) ; #endif } else //非Unicode文件 { pText pBuffer ; //ASCII转Unicode需2倍的空间。额外加两个\0。 pConv malloc (2 * iFileLength 2) ; // 如果编辑控件是Unicode则转换ASCII文本。 #ifdef UNICODE MultiByteToWideChar (CP_ACP, 0, pText, -1, (PTSTR) pConv, iFileLength 1) ; // 如果不是则直接拷贝 #else lstrcpy ((PTSTR) pConv, (PTSTR) pText) ; #endif } SetWindowText (hwndEdit, (PTSTR) pConv) ; //将内容写入到编辑框 free (pBuffer) ; free (pConv) ; return TRUE ;
}
//写文件
BOOL PopFileWrite (HWND hwndEdit, PTSTR pstrFileName)
{ DWORD dwBytesWritten ; HANDLE hFile ; int iLength ; PTSTR pstrBuffer ;
//小端模式时前两个字节被写入FF FE。大端时被写入FE FF WORD wByteOrderMark 0xFEFF ; //打开文件必要时可创建文件 if (INVALID_HANDLE_VALUE (hFile CreateFile(pstrFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL))) return FALSE; //获取编辑框中的字符个数并分配内存 iLength GetWindowTextLength (hwndEdit) ; pstrBuffer (PTSTR) malloc ((iLength 1) * sizeof (TCHAR)) ; if (!pstrBuffer) { CloseHandle(hFile); return FALSE; } // 如果编辑框使用Unicode编码则写入Unicode字节序 #ifdef UNICODE WriteFile (hFile, wByteOrderMark, 2, dwBytesWritten, NULL) ; #endif //获取编辑框中的文本并输出到文件 GetWindowText (hwndEdit, pstrBuffer, iLength 1) ; WriteFile (hFile, pstrBuffer, iLength * sizeof (TCHAR), dwBytesWritten, NULL) ; if ((iLength * sizeof (TCHAR)) ! (int) dwBytesWritten) { CloseHandle(hFile); free(pstrBuffer); return FALSE; } CloseHandle (hFile) ; free (pstrBuffer) ; return TRUE ;
}
■POPFIND.C
/*-------------------------------------------------------------------------- POPFIND.C -- Popup Editor Search and Replace Functions ------------------------------------------------------------------------*/
#include windows.h
#include commdlg.h
#include tchar.h // for _tcsstr (strstr for Unicode non-Unicode)
#define MAX_STRING_LEN 256
static TCHAR szFindText [MAX_STRING_LEN] ;
static TCHAR szReplText [MAX_STRING_LEN] ; //初始化Find对话框
HWND PopFindFindDlg (HWND hwnd)
{ static FINDREPLACE fr ; // 非模态对话框必须是静态的!! fr.lStructSize sizeof (FINDREPLACE) ; //结构的长度以字节为单位。 fr.hwndOwner hwnd ; //拥有对话框的窗口的句柄。 fr.hInstance NULL ;
//隐藏搜索方向单选按钮隐藏“区分大小写”复选框 fr.Flags FR_HIDEUPDOWN | FR_HIDEMATCHCASE | FR_HIDEWHOLEWORD ; //隐藏“仅匹配整个单词”复选框 fr.lpstrFindWhat szFindText ; //键入的搜索字符串缓冲区的长度 fr.lpstrReplaceWith NULL; //键入的替换字符串缓冲区的长度 //如果FINDMSGSTRING消息指定FR_REPLACE或FR_REPLACEALL标志 //则lpstrReplaceWith包含替换字符串该FINDTEXT函数忽略这个成员。 //lpstrFindWhat成员指向的缓冲区的长度以字节为单位。
fr.wFindWhatLen MAX_STRING_LEN ; //lpstrReplaceWith成员指向的缓冲区的长度以字节为单位。 fr.wReplaceWithLen 0 ; fr.lCustData 0 ; //Hook过程的应用程序定义的数据
//指向FRHookProc Hook过程的指针该过程可以处理用于对话框的消息。 fr.lpfnHook NULL ; fr.lpTemplateName NULL;//hInstance成员标识的模块中对话框模板资源的名称。 return FindText (fr) ; //创建查找对话框并返回其句柄
}
//初始化FindReplace对话框
HWND PopFindReplaceDlg (HWND hwnd)
{ static FINDREPLACE fr ; // 非模态对话框必须是静态的!! fr.lStructSize sizeof (FINDREPLACE) ; fr.hwndOwner hwnd ; fr.hInstance NULL ; fr.Flags FR_HIDEUPDOWN | FR_HIDEMATCHCASE | FR_HIDEWHOLEWORD ; fr.lpstrFindWhat szFindText ; fr.lpstrReplaceWith szReplText ; fr.wFindWhatLen MAX_STRING_LEN ; fr.wReplaceWithLen MAX_STRING_LEN ; fr.lCustData 0 ; fr.lpfnHook NULL ; fr.lpTemplateName NULL ; return ReplaceText (fr) ;
}
//查找字符串
BOOL PopFindFindText (HWND hwndEdit, int * piSearchOffset, LPFINDREPLACE pfr)
{ int iLength, iPos ; PTSTR pstrDoc, pstrPos ; //文件指针和当前位置指针 //读取编辑框内容 iLength GetWindowTextLength (hwndEdit) ; if (NULL (pstrDoc (PTSTR) malloc ((iLength 1) * sizeof (TCHAR)))) return FALSE ; GetWindowText (hwndEdit, pstrDoc, iLength 1) ; // 在文档中搜索查找字符串 pstrPos _tcsstr (pstrDoc * piSearchOffset, pfr-lpstrFindWhat) ; free (pstrDoc) ; //如果找不到返回FALSE if (pstrPos NULL) return FALSE ; //找到字符串将偏移设置到新的位置 iPos pstrPos - pstrDoc ;
//偏移设到找到的字符串的后面。 * piSearchOffset iPos lstrlen (pfr-lpstrFindWhat) ; //选中找到的文本 SendMessage (hwndEdit, EM_SETSEL, iPos, * piSearchOffset) ;
//可视窗口滚动到插入符号的位置以便可见找到的文本。 SendMessage (hwndEdit, EM_SCROLLCARET, 0, 0) ; return TRUE ;
}
//查找下一处
BOOL PopFindNextText (HWND hwndEdit, int * piSearchOffset)
{ FINDREPLACE fr; fr.lpstrFindWhat szFindText; return PopFindFindText(hwndEdit, piSearchOffset, fr);
}
//替换文本字符串
BOOL PopFindReplaceText (HWND hwndEdit, int * piSearchOffset, LPFINDREPLACE pfr)
{ //查找文本 if (!PopFindFindText (hwndEdit, piSearchOffset, pfr)) return FALSE ; // 替换 SendMessage ( hwndEdit, EM_REPLACESEL, 0, (LPARAM) pfr- lpstrReplaceWith) ; return TRUE ;
}
//无效查找
BOOL PopFindValidFind (void)
{ return * szFindText ! \0 ; //没输入查找文本时是无效的查找。
}
■POPFONT.C
/*---------------------------------------------------- POPFONT.C -- Popup Editor Font Functions
------------------------------------------------------*/
#include windows.h
#include commdlg.h
static LOGFONT logfont ; //字体的属性结构变量
static HFONT hFont ; //选择字体
BOOL PopFontChooseFont (HWND hwnd)
{ CHOOSEFONT cf ; //包含ChooseFont函数用来初始化“字体”对话框的信息。用户
//关闭对话框后系统将在此结构中返回有关用户选择的信息。 cf.lStructSize sizeof (CHOOSEFONT) ; //结构的长度以字节为单位。 cf.hwndOwner hwnd ; //拥有对话框的窗口的句柄。 cf.hDC NULL ; //忽略 cf.lpLogFont logfont ; //指向LOGFONT结构的指针 。 cf.iPointSize 0 ; //选择的字体的大小单位是1/10磅
//用logfont初始化对话框屏幕字体、效果复选框 cf.Flags CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS | CF_EFFECTS ; cf.rgbColors 0 ; //文本颜色 cf.lCustData 0 ; cf.lpfnHook NULL ; cf.lpTemplateName NULL ; cf.hInstance NULL ; cf.lpszStyle NULL ; //字体样式 cf.nFontType 0 ; // 所选的字体 cf.nSizeMin 0 ; //用户可以选择的最小点数 cf.nSizeMax 0 ; //用户可以选择的最大点数 return ChooseFont (cf) ;
}
//初始化对话框字体
void PopFontInitialize (HWND hwndEdit)
{ GetObject(GetStockObject(SYSTEM_FONT), sizeof(LOGFONT), //获取系统字体 (PTSTR)logfont); hFont CreateFontIndirect(logfont); //创建字体 SendMessage(hwndEdit, WM_SETFONT, (WPARAM)hFont,0);//初始化对话框为系统字体
}
//设置字体
void PopFontSetFont (HWND hwndEdit)
{ HFONT hFontNew; RECT rect; hFontNew CreateFontIndirect(logfont); SendMessage(hwndEdit, WM_SETFONT, (WPARAM)hFontNew, 0);//改变对话框字体 DeleteObject(hFont); hFont hFontNew; GetClientRect(hwndEdit, rect); InvalidateRect(hwndEdit, rect, TRUE);
}
//删除字体
void PopFontDeinitialize (void)
{ DeleteObject (hFont) ;
}
■POPPRINTO.C
/*------------------------------------------------------------------------ POPPRNTO.C -- Popup Editor Printing Functions (dummy version)
--------------------------------------------------------------------------*/
#include windows.h
BOOL PopPrntPrintFile ( HINSTANCE hInst, HWND hwnd, HWND hwndEdit, PTSTR pstrTitleName)
{ return FALSE ;
} ■资源脚本文件068_POPPAD3.rc
包含一个快捷键资源、对话框资源、ICON图标资源和菜单资源。
/
//
// Icon
// // Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
PopPad ICON favicon.ico /
//
// Menu
// PopPad MENU
BEGIN POPUP FILE BEGIN MENUITEM NEW\tCtrlN, IDM_FILE_NEW MENUITEM OPEN...\tCtrlO, IDM_FILE_OPEN MENUITEM SAVE\tCtrlS, IDM_FILE_SAVE MENUITEM SAVE AS..., IDM_FILE_SAVE_AS MENUITEM SEPARATOR MENUITEM PRINT\tCtrlP, IDM_FILE_PRINT MENUITEM SEPARATOR MENUITEM EXIT, IDM_APP_EXIT END POPUP EDIT BEGIN MENUITEM UNDO\tCtrlZ, IDM_EDIT_UNDO MENUITEM SEPARATOR MENUITEM CUT\tCtrlX, IDM_EDIT_CUT MENUITEM COPY\tCtrlC, IDM_EDIT_COPY MENUITEM PASTE\tCtrlV, IDM_EDIT_PASTE MENUITEM DELETE\tDEL, IDM_EDIT_CLEAR MENUITEM SEPARATOR MENUITEM SELECT ALL, IDM_EDIT_SELECT_ALL END POPUP SEARCH BEGIN MENUITEM FIND...\tCtrlF, IDM_SEARCH_FIND MENUITEM FIND NEXT\tF3, IDM_SEARCH_NEXT MENUITEM REPLEACE...\tCtrlR, IDM_SEARCH_REPLACE END POPUP FORMAT BEGIN MENUITEM FONT..., IDM_FORMAT_FONT END POPUP HELP BEGIN MENUITEM HELP, IDM_HELP MENUITEM ABOUT POPPAD..., IDM_APP_ABOUT END
END /
//
// Dialog
// ABOUTBOX DIALOGEX 32, 32, 309, 177
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_SYSMENU
FONT 8, MS Shell Dlg, 400, 0, 0x1
BEGIN DEFPUSHBUTTON 确定,IDOK,122,156,50,14 ICON PopPad,IDC_STATIC,15,12,20,20 CTEXT POPPAD,IDC_STATIC,113,28,58,8 CTEXT PopPad Editor for Windows,IDC_STATIC,93,68,119,8 CTEXT (C) Charles Petzold,1998,IDC_STATIC,91,88,115,8
END PRINTDLGBOX DIALOGEX 0, 0, 309, 176
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION POPPAD
FONT 8, MS Shell Dlg, 400, 0, 0x1
BEGIN PUSHBUTTON 取消,IDCANCEL,127,155,50,14 CTEXT Sending,IDC_STATIC,113,24,72,8 LTEXT ,IDC_STATIC,30,48,246,72 CTEXT to print spooler.,IDC_STATIC,116,138,72,8
END /
//
// Accelerator
// IDR_ACCELERATOR1 ACCELERATORS
BEGIN VK_BACK, IDM_EDIT_UNDO, VIRTKEY, ALT, NOINVERT VK_DELETE, IDM_EDIT_CLEAR, VIRTKEY, NOINVERT VK_F1, IDM_HELP, VIRTKEY, NOINVERT VK_F3, IDM_SEARCH_NEXT, VIRTKEY, NOINVERT VK_INSERT, IDM_EDIT_COPY, VIRTKEY, CONTROL, NOINVERT C, IDM_EDIT_COPY, VIRTKEY, NOINVERT F, IDM_SEARCH_FIND, VIRTKEY, NOINVERT N, IDM_FILE_NEW, VIRTKEY, NOINVERT P, IDM_FILE_PRINT, VIRTKEY, NOINVERT R, IDM_SEARCH_REPLEACE, VIRTKEY, NOINVERT S, IDM_FILE_SAVE, VIRTKEY, NOINVERT V, IDM_EDIT_PASTE, VIRTKEY, NOINVERT X, IDM_EDIT_CUT, VIRTKEY, NOINVERT Z, IDM_EDIT_UNDO, VIRTKEY, NOINVERT
END ■运行结果 图10-13 公用对话框——文本编辑器 总结
实例POPPAD程序加入菜单时并没有实现几种标准菜单项。现在我们有了充分的准备可以实现POPPAD中打开文件、读取文件、存储文件的程序逻辑。在此过程中我们还将添加选择字体和査找并替换文本的程序逻辑。
为避免重复第十三章的源代码在POPPAD3.C的菜单定义中加上了打印选项以及其他一些相关代码。
POPPAD.C包含程序的所有基本源代码。
POPFILE.C中包含了激活打开文件和存储文件对话框的代码以及文件I/O例程。
POPFIND.C包含了査找和替换文本的程序逻辑。
POPFONT.C包含了选择字体的程序逻辑。
POPPRNTO.C没有实质功能它将在第十三章被POPPRNT.C所替换并完成最终的POPPAD程序。 【注意】实例POPPAD程序中关于公用对话框初始化的部分可以被简化直接将相应的公用对话框结构体初始化为零然后再初始化几个必要的字段就可以了参见上一节。
●Unicode文件的判断——IsTextUnicodelpBuffer,cb, lpi
1lpBuffer参数要测试的字符串其缓冲区地址。
2cb个参数lpBuffer指向的字节数注意是不是字符数
3lpi是个in/out类型的传入时指定哪些测试项目传出时为符合哪个测试项目。
4返回值TRUE或FALSE
●字符串的转化——这里的多字节是广义的即可指ANSI也可指UTF_8等。 1WideCharToMultiByte——将Unicode字符串转为多字节字符串 字段 功能 CodePage CodePage参数用于标识要为转换新的字符串的相关代码页如CP_ACP实现了Unicode与ANSI的转换CP_UTF8 实现了Unicode与UTF-8的转换 dwFlags 进行额外的控制会影响使用了读音符号比如重音的字符 lpWideCharStr 转换为宽字节字符串的缓冲区 cchWideChar lpWideCharStr指向的缓冲区的字符个数。如果-1字符串将被设定为以NULL为结束符的字符串并且自动计算长度含\0。 lpMultiByteStr 接收被转换字符串的缓冲区 cchMultiByte lpMultiByteStr指向的缓冲区最大值用字节来计量 lpDefaultChar 遇到一个不能转换的宽字符函数便会使用该参数指向的字符。 pfUsedDefaultChar 只要遇到任何一个不能被转换的字符就会被函数设为TRUE。 2MultiByteToWideChar——将多字节字符串转为Unicode字符串 字段 功能 CodePage 用来标记与一个多字节字符串相关的代码页 dwFlags 进行额外的控制会影响使用了读音符号比如重音的字符 lpWideCharStr 转换为宽字节字符串的缓冲区 cchWideChar lpWideCharStr指向的缓冲区的字符个数如果-1字符串将被设定为以NULL为结束符的字符串并且自动计算长度含\0。 lpMultiByteStr 接收被转换字符串的缓冲区 cchMultiByte lpMultiByteStr指向的缓冲区最大值用字节来计量 lpDefaultChar 遇到一个不能转换的宽字符函数便会使用该参数指向的字符。 pfUsedDefaultChar 只要遇到任何一个不能被转换的字符就会被函数设为TRUE。 ●查找和替换公用对话框
1对话框是非模态的所以消息循环应该调用IsDialogMessage。
2FINDREPLACE结构不能声明为窗口过程的局部变量必须是静态变量或全局变量。因为当调用FindText或ReplaceText调出对话框后PopFindFindDlgPopFindReplaceDlg这些函数会立即返回。但该结构会作为消息的lParam参数被发送到父窗口的消息过程。为防止该结构被释放要声明为静态变量。
3“查找”或“替换”对话框与父窗口会进行一种特殊的消息进行通信。
所以程序首先须通过FINDMSGSTR这个名字向系统申请获得该特殊消息的ID号即msgID RegisterWindowMessage (FINDMSGSTRING)后就可以利用msgID进行通信了。