5.49k likes | 5.61k Views
第三十讲 ). 吉林大学远程教育课件. Windows A P I 编 程. 学 时: 48. 主讲人 : 翟慧杰. // 函数: WndProc // 作用:主窗口消息循环 LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { static BOOL bNeedSave = FALSE; // 是否保存文件的标志 static char szFileName[_MAX_PATH];// 文件名
E N D
第三十讲) 吉林大学远程教育课件 Windows A P I编 程 学 时:48 主讲人 : 翟慧杰
//函数:WndProc //作用:主窗口消息循环 LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { static BOOL bNeedSave = FALSE; //是否保存文件的标志 static char szFileName[_MAX_PATH];//文件名 static char szTitleName[_MAX_FNAME + _MAX_EXT]; static HINSTANCE hInst;//应用程序句柄 static HWND hwndEdit;//编辑框句柄 static int iOffset; static UINT iMsgFindReplace; LPFINDREPLACE pfr;
switch (iMsg) { case WM_CREATE: //创建窗口 hInst = ((LPCREATESTRUCT) lParam) -> hInstance ; //创建编辑框 hwndEdit = CreateWindow ("edit", NULL, WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL |WS_BORDER | ES_LEFT | ES_MULTILINE |ES_NOHIDESEL | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0, 0, 0, 0, hwnd, (HMENU) EDITID, hInst, NULL) ;
SendMessage (hwndEdit, EM_LIMITTEXT, 32000, 0L); PopFileInitialize (hwnd); //初始化ofn /注册消息FINDMSGSTRING iMsgFindReplace = RegisterWindowMessage (FINDMSGSTRING) ; lstrcpy (szFileName, (PSTR) (((LPCREATESTRUCT) lParam)->lpCreateParams)) ; if (strlen (szFileName) > 0) { GetFileTitle (szFileName, szTitleName, sizeof (szTitleName)); //获取文件名 if (!PopFileRead (hwndEdit, szFileName))//读文件 OkMessage (hwnd, "文件 %s 不能读取!", szTitleName); } 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_COMMAND:// 菜单命令 if (lParam && LOWORD (wParam) == EDITID) { switch (HIWORD (wParam)) { case EN_UPDATE: bNeedSave = TRUE; return 0; case EN_ERRSPACE: case EN_MAXTEXT: MessageBox (hwnd, "编辑框超出边界!.", szAppName, MB_OK | MB_ICONSTOP); return 0; }
break; } switch (LOWORD (wParam)) { // 来自文件菜单的消息 case IDM_NEW://新建 if (bNeedSave && IDCANCEL ==AskAboutSave (hwnd, szTitleName)) return 0; SetWindowText (hwndEdit, "\0"); szFileName[0] = '\0'; szTitleName[0] = '\0'; DoCaption (hwnd, szTitleName); bNeedSave = FALSE; return 0; case IDM_OPEN://打开文件 if (bNeedSave && IDCANCEL ==AskAboutSave (hwnd, szTitleName)) return 0 ;
//弹出Open对话框 if (PopFileOpenDlg (hwnd, szFileName, szTitleName)) { //读文件 if (!PopFileRead (hwndEdit, szFileName)) { OkMessage (hwnd, "不能读取文件%s!",szTitleName); szFileName[0] = '\0'; szTitleName[0] = '\0'; } } DoCaption (hwnd, szTitleName); bNeedSave = FALSE; return 0; case IDM_SAVE://保存 if (szFileName[0]) {
//写文件 if (PopFileWrite (hwndEdit, szFileName)) { bNeedSave = FALSE; return 1; } else OkMessage (hwnd, "不能写文件 %s",szTitleName) ; return 0; }
case IDM_SAVEAS://另存为 //弹出Save AS对话框 if (PopFileSaveDlg (hwnd, szFileName, szTitleName)) { DoCaption (hwnd, szTitleName) ; if (PopFileWrite (hwndEdit, szFileName)) { bNeedSave = FALSE; return 1; } else OkMessage (hwnd, "不能写文件%s",szTitleName) ; } return 0; case IDM_EXIT://结束 SendMessage (hwnd, WM_CLOSE, 0, 0); return 0;
case IDM_UNDO ://撤消 SendMessage (hwndEdit, WM_UNDO, 0, 0); return 0; case IDM_CUT: //剪切 SendMessage (hwndEdit, WM_CUT, 0, 0); return 0; case IDM_COPY://复制 SendMessage (hwndEdit, WM_COPY, 0, 0); return 0; case IDM_PASTE://粘贴 SendMessage (hwndEdit, WM_PASTE, 0, 0); return 0; case IDM_CLEAR://清空 SendMessage (hwndEdit, WM_CLEAR, 0, 0); return 0; case IDM_SELALL://全选 SendMessage (hwndEdit, EM_SETSEL, 0, -1); return 0;
case IDM_FIND://查找 SendMessage (hwndEdit, EM_GETSEL, NULL,(LPARAM) &iOffset); hDlgModeless = PopFindFindDlg (hwnd); return 0; case IDM_NEXT://查找下一处 SendMessage (hwndEdit, EM_GETSEL, NULL,(LPARAM) &iOffset); if (PopFindValidFind ()) PopFindNextText (hwndEdit, &iOffset); else hDlgModeless = PopFindFindDlg (hwnd); return 0; case IDM_REPLACE://替换 SendMessage (hwndEdit, EM_GETSEL, NULL,(LPARAM) &iOffset); hDlgModeless = PopFindReplaceDlg (hwnd); 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: PostQuitMessage (0); return 0; default: //处理"Find-Replace" 消息 if (iMsg == iMsgFindReplace) {
pfr = (LPFINDREPLACE) lParam ; if (pfr->Flags & FR_DIALOGTERM) hDlgModeless = NULL; if (pfr->Flags & FR_FINDNEXT) if (!PopFindFindText (hwndEdit, &iOffset, pfr)) OkMessage (hwnd, "文本没找到!", "\0") ; if (pfr->Flags & FR_REPLACE ||pfr->Flags & FR_REPLACEALL) if (!PopFindReplaceText (hwndEdit, &iOffset, pfr)) OkMessage (hwnd, "文本没找到!", "\0") ; if (pfr->Flags & FR_REPLACEALL) while (PopFindReplaceText (hwndEdit, &iOffset, pfr)); return 0 ;}
break ; } return DefWindowProc (hwnd, iMsg, wParam, lParam) ; } //函数:PopFileInitialize //作用:初始化全局变量ofn void PopFileInitialize (HWND hwnd) { static char szFilter[] = "文本文件(*.TXT)\0*.txt\0" \ "ASCII文件(*.ASC)\0*.asc\0" \ "所有文件 (*.*)\0*.*\0\0" ; ofn.lStructSize= sizeof (OPENFILENAME) ; ofn.hwndOwner= hwnd ; ofn.hInstance= NULL ; ofn.lpstrFilter= szFilter ;
ofn.lpstrCustomFilter = NULL ; ofn.nMaxCustFilter= 0 ; ofn.nFilterIndex= 0 ; ofn.lpstrFile= NULL ; ofn.nMaxFile= _MAX_PATH ; ofn.lpstrFileTitle= NULL ; ofn.nMaxFileTitle= _MAX_FNAME + _MAX_EXT ; ofn.lpstrInitialDir= NULL ; ofn.lpstrTitle= NULL ; ofn.Flags= 0 ; ofn.nFileOffset= 0 ; ofn.nFileExtension= 0 ;
ofn.lpstrDefExt= "txt" ; ofn.lCustData= 0L ; ofn.lpfnHook= NULL ; ofn.lpTemplateName= NULL ; } //函数:PopFileOpenDlg //作用:弹出Open对话框 BOOL PopFileOpenDlg (HWND hwnd, PSTR pstrFileName, PSTR pstrTitleName) { ofn.hwndOwner= hwnd ; ofn.lpstrFile= pstrFileName ; ofn.lpstrFileTitle= pstrTitleName ; ofn.Flags= OFN_HIDEREADONLY; return GetOpenFileName (&ofn) ;//弹出Open对话框 }
//函数:PopFileSaveDlg //作用:弹出Save As对话框 BOOL PopFileSaveDlg (HWND hwnd, PSTR pstrFileName, PSTR pstrTitleName) { ofn.hwndOwner= hwnd ; ofn.lpstrFile= pstrFileName ; ofn.lpstrFileTitle= pstrTitleName ; ofn.Flags= OFN_OVERWRITEPROMPT ; return GetSaveFileName (&ofn) ; } //函数:PopFileLength //作用:计算文件长度 static long PopFileLength (FILE *file) { int iCurrentPos, iFileLength ; iCurrentPos = ftell (file) ;
(第三十一讲) 吉林大学远程教育课件 Windows A P I编 程 学 时:48 主讲人 : 翟慧杰
fseek (file, 0, SEEK_END) ; iFileLength = ftell (file) ; fseek (file, iCurrentPos, SEEK_SET) ; return iFileLength ; } //函数:PopFileRead //作用:读取文件 BOOL PopFileRead (HWND hwndEdit, PSTR pstrFileName) { FILE *file; int iLength; PSTR pstrBuffer;
//打开文件 if (NULL == (file = fopen (pstrFileName, "rb"))) return FALSE; iLength = PopFileLength (file);//获取文件长度 if (NULL == (pstrBuffer = (PSTR) malloc (iLength))) { fclose (file); //关闭文件 return FALSE; } fread (pstrBuffer, sizeof(char), iLength, file); //读取文件 fclose (file); pstrBuffer[iLength] = '\0';
SetWindowText (hwndEdit, pstrBuffer); //设置编辑框中的文本内容 return TRUE; } //函数:PopFileWrite //作用:写文件 BOOL PopFileWrite (HWND hwndEdit, PSTR pstrFileName) { FILE *file ; int iLength ; PSTR pstrBuffer ; if (NULL == (file = fopen (pstrFileName, "wb")))//打开文件 return FALSE ; iLength = GetWindowTextLength (hwndEdit) ; //获取编辑框中的文本内容长度
if (NULL == (pstrBuffer = (PSTR) malloc (iLength + 1))) { fclose (file) ;//关闭文件 return FALSE ; } //获取编辑框中的文本内容 GetWindowText (hwndEdit, pstrBuffer, iLength + 1) ; //写文件 if (iLength != (int) fwrite (pstrBuffer, 1, iLength, file)) { fclose (file); //关闭文件 free (pstrBuffer); return FALSE; }
fclose (file); free (pstrBuffer); return TRUE; } //函数:PopFindFindDlg //作用:弹出Find对话框 HWND PopFindFindDlg (HWND hwnd) { static FINDREPLACE fr; //初始化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;
fr.wFindWhatLen= sizeof (szFindText); fr.wReplaceWithLen= 0; fr.lCustData = 0; fr.lpfnHook= NULL; fr.lpTemplateName= NULL; return FindText (&fr);// 弹出Find对话框 } //函数:PopFindReplaceDlg //作用:弹出Replace对话框 HWND PopFindReplaceDlg (HWND hwnd) { static FINDREPLACE fr; //初始化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= sizeof (szFindText); fr.wReplaceWithLen= sizeof (szReplText); fr.lCustData= 0; fr.lpfnHook= NULL; fr.lpTemplateName= NULL; return ReplaceText (&fr); //弹出Replace对话框 }
//函数:PopFindFindText //作用:查找字符串 BOOL PopFindFindText (HWND hwndEdit, int *piSearchOffset, LPFINDREPLACE pfr) { int iLength, iPos; PSTR pstrDoc, pstrPos; //获取编辑框中的文本内容长度 iLength = GetWindowTextLength (hwndEdit); if (NULL == (pstrDoc = (PSTR) malloc (iLength + 1))) return FALSE; //获取编辑框中的文本内容 GetWindowText (hwndEdit, pstrDoc, iLength + 1); pstrPos = strstr (pstrDoc + *piSearchOffset, pfr->lpstrFindWhat); free (pstrDoc);
if (pstrPos == NULL) return FALSE; iPos = pstrPos - pstrDoc; *piSearchOffset = iPos + strlen (pfr->lpstrFindWhat); SendMessage (hwndEdit, EM_SETSEL, iPos, *piSearchOffset); SendMessage (hwndEdit, EM_SCROLLCARET, 0, 0); return TRUE; }
//函数:PopFindNextText //作用:查找下一处字符串 BOOL PopFindNextText (HWND hwndEdit, int *piSearchOffset) { FINDREPLACE fr; fr.lpstrFindWhat = szFindText; return PopFindFindText (hwndEdit, piSearchOffset, &fr); } //函数:PopFindReplaceText //作用:替换文本 BOOL PopFindReplaceText (HWND hwndEdit, int *piSearchOffset, LPFINDREPLACE pfr) { if (!PopFindFindText (hwndEdit, piSearchOffset, pfr)) //弹出Replace对话框 return FALSE;
SendMessage (hwndEdit, EM_REPLACESEL, 0, (LPARAM) pfr->lpstrReplaceWith); return TRUE; } BOOL PopFindValidFind (void) { return *szFindText != '\0'; } 首先声明了一个OPENFILENAME结构体的全局静态变量ofn,这个变量用于记录打开一个文件时系统需要的各种信息。
在调用打开文件对话框打开一个文件之前,必须先对OFN变量的各个域进行初始化。在调用打开文件对话框打开一个文件之前,必须先对OFN变量的各个域进行初始化。 在处理消息WM_CREATE时,程序调用自定义的函数PopFilelnitialize对OFN进行初始化操作。
然后,程序调用函数 RegisterWindowMessage对消息 FINDMSGSTRING进行注册。 Windows允许用户使用系统预定义的消息, 也允许用户使用自定义的消息,但是在使用 自定义的消息之前,必须对消息进行注册。函数RegisterWindowMessage的原型定义如下: 程序通过如下语句取得在命令行中指定的文件名:
其中,lParatn是消息处理函数的参数 lParam是指向CREATESTRUCT结构体 的指针,CREATESTRUCT结构体的成员 变量 lpCreateParams中记录在创建窗口时, 程序传递给CreateWindow函数的 lpParam参数的值 szCmdLine,而 szCmdLine又是 WinMain函数用于接收用户命令行的参数。 所以,上述语句的目的就是取得用户的命令行参数。lstrcpy用于把字符串复制到另一个字符串中,函数原型定义如下:
如果命令行中指定了打开的文件名, 即szFileName不为空,则程序调用如 下语句来加以处理:
(第三十二讲) 吉林大学远程教育课件 Windows A P I编 程 学 时:48 主讲人 : 翟慧杰
其中,函数GetFileTitle用于获取文件名, 函数原型定义如下所示。 在取得文件名后,程序调用函数PopFileRead把文件中的数据读人到编辑框中。函数PopFileRead的具体定义如下:
在PopFileRead函数中,首先定义了文件指 针file,然后通过函数fopen打开由 pstrFileName指定的文件,fopen函数的 原型定义如下: 然后,程序调用 PopFileLength采取得文件的长度,PopFileLength也是自定义的函数,其具体定义如下:
函数PopFileLength中首先通过ftell取得文件指针的当前位置,并把结果保存在iCurrentPos中,ftell函数的原型定义如下: PopFileLength然后调用 fseek函数移动文件指针到文件末尾处, fseek函数的原型定义如下:
程序中指定 offset参数的值为 0,指定 origin参数的值为 SEEK_END,表示把文件指针移动到距离文件末尾为0的位置,即文件的末尾处。 在把文件指针移动到文件末尾后,再一次调用函数ftell取得当前的文件指针的位置,并把结果保存在iFileLength变量中。 在取得文件的长度后,还必须把文件指针复位,以便后续的文件操作。 函数fread实现读取文件中的数据,这个函数的原型定义如下;
函数SetWindowsText用于把读取到的数据 显示在编辑框中,函数原型定义如下: OkMessage是自定义的一个通用函数,其主要作用是当程序顺利完成某一项操作后向用户通报操作成功的消息。 DoCaption也是自定义的一个通用函数,其主要作用是处理某个窗口的标题。 如果用户选择了文件菜单下的“打开”菜单项,则程序通过图形代码来进行相应的处理。
用户选择文件菜单下的“打开”菜单项的目的 就是希望打开一个新文件,但是在打开新文 件之前必须检查编辑框中的内容是否已经保 存,如果没有保存,则bNeedSave变量将被置 成TRUE,通过检查bNeedSave变量的值可以 决定是否需要对编辑框中的内容进行保存操作。函数AskAboutSave是自定义的函数,其作用是提示用户对没有保存的内容进行保存。函数AskAboutSave的具体定义如下:
在上述程序中,函数MessageBox用于弹出 一个消息框,函数原型定义如下: 如果用户认为需要保存文件,则必然会单击消息框中的Yes按钮,这时MessageBox函数的返回值为IDYES,程序于是接着调用SendMessage函数向应用程序发送一条WM_COMMAND消息,对这条消息的附加信息指定为IDM_SAVE。应用程序在接收到这条消息后,程序流程将转到对保存菜单项进行相应处理的代码处。
真正实现弹出 Open对话框的是 PopFileOpenDlg函数,函数的定义如下: 上述程序段中通过对 Windows API函数 GetOpenFileName的调用来实现弹出 Open对话框,GetOpenFileName函数的原型定义如下:
如果成功地打开某一个文件后,PopFileOpeDlg函数将返回TRUE,于是程序接着调用函数DoCaption改变窗口标题,同时把变量bNeedSave的值设置为FALSE。其他对话框的使用大致也遵循和Open对话框类似的过程。 例题的头文件Edit.h如下: