Windows通用对话框—增强POPPAD

来源:互联网 发布:js dialog onok 编辑:程序博客网 时间:2024/05/21 22:41

Windows通用对话框—增强POPPAD


当我们往第十章的POPPAD中增加菜单时,还有几个标准菜单项没有实作。现在我们已经准备好在POPPAD中加入打开文件、读入文件以及在磁盘上储存编辑过文件的功能。在处理中,我们还将在POPPAD中加入字体选择和搜索替换功能。

实作POPPAD3程序的文件如程序11-6所示。

程序11-6 POPPAD3
        POPPAD.C        /*------------------------------------------------------------------------          POPPAD.C -- Popup Editor                                                         (c) Charles Petzold, 1998        -------------------------------------------------------------------------*/        #include <windows.h>        #include <commdlg.h>        #include "resource.h"        #define     EDITID   1        #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) ;        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) ;        HWND        PopFindReplaceDlg                    (HWND) ;        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 variables        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))                          {                                          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))                                                 iReturn = IDCANCEL ;                                   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 ;                                                 // Create the edit control child window                          hwndEdit = CreateWindow (TEXT ("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) ;                                          // Initialize common dialog box stuff                          PopFileInitialize (hwnd) ;                          PopFontInitialize (hwndEdit) ;                                          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 menu                                                                              // Enable Undo if edit control can do it                                                                      EnableMenuItem ((HMENU) wParam, IDM_EDIT_UNDO,                                  SendMessage (hwndEdit, EM_CANUNDO, 0, 0L) ?                                               MF_ENABLED : MF_GRAYED) ;                                                                              // Enable Paste if text is in the clipboard                                                                     EnableMenuItem ((HMENU) wParam, IDM_EDIT_PASTE,                                       IsClipboardFormatAvailable (CF_TEXT) ?                                                    MF_ENABLED : MF_GRAYED) ;                                                                      // Enable Cut, Copy, and Del if text is selected                                                       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 menu                                                                      // Enable Find, Next, and Replace if modeless                                                 //   dialogs are not already active                                                                      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:                                                                 // Messages from edit control                                         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))                         {                                          // Messages from File menu                          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 ;                                         }                                  }                           //fall through                   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 ;                                                                                             // Messages from Edit menu                                        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 ;                                                                                     // Messages from Search menu            case   IDM_SEARCH_FIND:                                  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 ;                                                                                      // Messages from Help menu                                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:                                                 // Process "Find-Replace" messages                          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) ;        }        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 ;                   ofn.hInstance                        = NULL ;                   ofn.lpstrFilter                      = szFilter ;                   ofn.lpstrCustomFilter = NULL ;                   ofn.nMaxCustFilter    = 0 ;                   ofn.nFilterIndex      = 0 ;                   ofn.lpstrFile         = NULL ;              // Set in Open and Close functions                   ofn.nMaxFile                = MAX_PATH ;                   ofn.lpstrFileTitle            = NULL ;              // Set in Open and Close functions                   ofn.nMaxFileTitle             = MAX_PATH ;                   ofn.lpstrInitialDir           = NULL ;                   ofn.lpstrTitle                = NULL ;                   ofn.Flags                    = 0 ;                         // Set in Open and Close functions                   ofn.nFileOffset               = 0 ;                   ofn.nFileExtension            = 0 ;                   ofn.lpstrDefExt               = TEXT ("txt") ;                   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 ;                                          // Open the file.                   if (INVALID_HANDLE_VALUE ==                                  (hFile = CreateFile (pstrFileName, GENERIC_READ, FILE_SHARE_READ,                                NULL, OPEN_EXISTING, 0, NULL)))                    return FALSE ;                          // Get file size in bytes and allocate memory for read.                          // Add an extra two bytes for zero termination.                                             iFileLength = GetFileSize (hFile, NULL) ;                   pBuffer = malloc (iFileLength + 2) ;                         // Read file and put terminating zeros at end.                   ReadFile (hFile, pBuffer, iFileLength, &dwBytesRead, NULL) ;                   CloseHandle (hFile) ;                   pBuffer[iFileLength] = '\0' ;                   pBuffer[iFileLength + 1] = '\0' ;                          // Test to see if the text is Unicode            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 ;                                  }            }                                          // Allocate memory for possibly converted string                          pConv = malloc (iFileLength + 2) ;                                          // If the edit control is not Unicode, convert Unicode text to                                         // non-Unicode (i.e., in general, wide character).        #ifndef UNICODE                          WideCharToMultiByte (CP_ACP, 0, (PWSTR) pText, -1, pConv,                              iFileLength + 2, NULL, NULL) ;                                          // If the edit control is Unicode, just copy the string        #else                   lstrcpy ((PTSTR) pConv, (PTSTR) pText) ;        #endif            }                   else                  // the file is not Unicode             {                    pText = pBuffer ;                                          // Allocate memory for possibly converted string.                          pConv = malloc (2 * iFileLength + 2) ;                                          // If the edit control is Unicode, convert ASCII text.        #ifdef UNICODE                   MultiByteToWideChar (CP_ACP, 0, pText, -1, (PTSTR) pConv,                                                 iFileLength + 1) ;                                                         // If not, just copy buffer        #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 ;                   WORD          wByteOrderMark = 0xFEFF ;                                  // Open the file, creating it if necessary                              if (INVALID_HANDLE_VALUE ==                                  (hFile = CreateFile (pstrFileName, GENERIC_WRITE, 0,                       NULL, CREATE_ALWAYS, 0, NULL)))                          return FALSE ;                          // Get the number of characters in the edit control and allocate                          // memory for them.                              iLength = GetWindowTextLength (hwndEdit) ;                   pstrBuffer = (PTSTR) malloc ((iLength + 1) * sizeof (TCHAR)) ;                              if (!pstrBuffer)                   {                          CloseHandle (hFile) ;                          return FALSE ;                   }                          // If the edit control will return Unicode text, write the                          // byte order mark to the file.        #ifdef UNICODE                   WriteFile (hFile, &wByteOrderMark, 2, &dwBytesWritten, NULL) ;        #endif                          // Get the edit buffer and write that out to the file.                   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] ;        HWND PopFindFindDlg (HWND hwnd)        {                   static FINDREPLACE fr ;       // must be static for modeless dialog!!!                              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               = MAX_STRING_LEN ;                  fr.wReplaceWithLen            = 0 ;                   fr.lCustData                  = 0 ;                   fr.lpfnHook                   = NULL ;                   fr.lpTemplateName             = NULL ;                              return FindText (&fr) ;        }        HWND PopFindReplaceDlg (HWND hwnd)        {                   static FINDREPLACE fr ;       // must be static for modeless dialog!!!                              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 ;                                             // Read in the edit document                              iLength = GetWindowTextLength (hwndEdit) ;                              if (NULL == (pstrDoc = (PTSTR) malloc ((iLength + 1) * sizeof (TCHAR))))                         return FALSE ;                              GetWindowText (hwndEdit, pstrDoc, iLength + 1) ;                                             // Search the document for the find string                              pstrPos = _tcsstr (pstrDoc + * piSearchOffset, pfr->lpstrFindWhat) ;            free (pstrDoc) ;                                             // Return an error code if the string cannot be found                              if (pstrPos == NULL)                          return FALSE ;                                             // Find the position in the document and the new start offset                              iPos = pstrPos - pstrDoc ;                   * piSearchOffset = iPos + lstrlen (pfr->lpstrFindWhat) ;                                             // Select the found text                   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, LPFIND,REPLACE pfr)        {                 // Find the text            if (!PopFindFindText (hwndEdit, piSearchOffset, pfr))                 return FALSE ;                            // Replace it            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 ;                   cf.lStructSize                = sizeof (CHOOSEFONT) ;                   cf.hwndOwner                  = hwnd ;                   cf.hDC                        = NULL ;                   cf.lpLogFont                  = &logfont ;                   cf.iPointSize                 = 0 ;                   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 ;                         // Returned from ChooseFont                   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) ;        }        
POPPRNT0.C
        /*------------------------------------------------------------------------          POPPRNT0.C -- Popup Editor Printing Functions (dummy version)        --------------------------------------------------------------------------*/        #include <windows.h>        BOOL PopPrntPrintFile (    HINSTANCE hInst, HWND hwnd, HWND hwndEdit,                                                                               PTSTR pstrTitleName)        {                   return FALSE ;        }        
POPPAD.RC (摘录)
        //Microsoft Developer Studio generated resource script.        #include "resource.h"        #include "afxres.h"        /////////////////////////////////////////////////////////////////////////////        // Dialog        ABOUTBOX DIALOG DISCARDABLE  32, 32, 180, 100        STYLE DS_MODALFRAME | WS_POPUP        FONT 8, "MS Sans Serif"        BEGIN           DEFPUSHBUTTON "OK",IDOK,66,80,50,14           ICON                                                     "POPPAD",IDC_STATIC,7,7,20,20           CTEXT                                                    "PopPad",IDC_STATIC,40,12,100,8           CTEXT         "Popup Editor for Windows",IDC_STATIC,7,40,166,8           CTEXT         "(c) Charles Petzold, 1998",IDC_STATIC,7,52,166,8        END        PRINTDLGBOX DIALOG DISCARDABLE  32, 32, 186, 95        STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU        CAPTION "PopPad"        FONT 8, "MS Sans Serif"        BEGIN           PUSHBUTTON    "Cancel",IDCANCEL,67,74,50,14           CTEXT                                                "Sending",IDC_STATIC,8,8,172,8           CTEXT         "",IDC_FILENAME,8,28,172,8           CTEXT         "to print spooler.",IDC_STATIC,8,48,172,8        END        /////////////////////////////////////////////////////////////////////////////        // Menu        POPPAD MENU DISCARDABLE        BEGIN            POPUP           "&File"            BEGIN            MENUITEM      "&New\tCtrl+N",   IDM_FILE_NEW          MENUITEM       "&Open...\tCtrl+O",IDM_FILE_OPEN          MENUITEM      "&Save\tCtrl+S",   IDM_FILE_SAVE          MENUITEM      "Save &As...",     IDM_FILE_SAVE_AS          MENUITEM      SEPARATOR          MENUITEM      "&Print\tCtrl+P",  IDM_FILE_PRINT          MENUITEM      SEPARATOR        MENUITEM      "E&xit",          IDM_APP_EXIT        END          POPUP "&Edit"        BEGIN          MENUITEM      "&Undo\tCtrl+Z",   IDM_EDIT_UNDO          MENUITEM      SEPARATOR          MENUITEM      "Cu&t\tCtrl+X",    IDM_EDIT_CUT          MENUITEM      "&Copy\tCtrl+C",   IDM_EDIT_COPY          MENUITEM      "&Paste\tCtrl+V",  IDM_EDIT_PASTE          MENUITEM      "De&lete\tDel",    IDM_EDIT_CLEAR          MENUITEM      SEPARATOR          MENUITEM      "&Select All",     IDM_EDIT_SELECT_ALL        END            POPUP     "&Search"        BEGIN                MENUITEM      "&Find...\tCtrl+F",IDM_SEARCH_FIND          MENUITEM      "Find &Next\tF3",  IDM_SEARCH_NEXT          MENUITEM      "&Replace...\tCtrl+R", IDM_SEARCH_REPLACE        END            POPUP    "F&ormat"        BEGIN          MENUITEM      "&Font...",                   END            POPUP "&Help"           BEGIN           MENUITEM      "&Help",                IDM_HELP          MENUITEM      "&About PopPad...",  IDM_APP_ABOUT            END        END        /////////////////////////////////////////////////////////////////////////////        // Accelerator        POPPAD ACCELERATORS DISCARDABLE        BEGIN          VK_BACK,      IDM_EDIT_UNDO,   VIRTKEY,     ALT,     NOINVERT          VK_DELETE,  IDM_EDIT_CLEAR,  VIRTKEY,        NOINVERT          VK_DELETE,  IDM_EDIT_CUT,    VIRTKEY,        SHIFT,   NOINVERT          VK_F1,      IDM_HELP,        VIRTKEY,        NOINVERT          VK_F3,      IDM_SEARCH_NEXT, VIRTKEY,        NOINVERT          VK_INSERT,  IDM_EDIT_COPY,   VIRTKEY,        CONTROL,  NOINVERT          VK_INSERT,                    IDM_EDIT_PASTE,        VIRTKEY,      SHIFT, NOINVERT          "^C",         IDM_EDIT_COPY,         ASCII,  NOINVERT          "^F",        IDM_SEARCH_FIND,       ASCII,        NOINVERT           "^N",        IDM_FILE_NEW,          ASCII,        NOINVERT            "^O",        IDM_FILE_OPEN,         ASCII,        NOINVERT            "^P",         IDM_FILE_PRINT,        ASCII,  NOINVERT            "^R",         IDM_SEARCH_REPLACE,    ASCII,  NOINVERT            "^S",         IDM_FILE_SAVE,         ASCII,  NOINVERT            "^V",         IDM_EDIT_PASTE,        ASCII,  NOINVERT            "^X",         IDM_EDIT_CUT,          ASCII,  NOINVERT            "^Z",         IDM_EDIT_UNDO,        ASCII,  NOINVERT        END        /////////////////////////////////////////////////////////////////////////////        // Icon        POPPAD                                                    ICON    DISCARDABLE    "poppad.ico"        
RESOURCE.H (摘录)
        // Microsoft Developer Studio generated include file.        // Used by poppad.rc        #define IDC_FILENAME          1000        #define IDM_FILE_NEW          40001        #define IDM_FILE_OPEN         40002        #define IDM_FILE_SAVE         40003        #define IDM_FILE_SAVE_AS      40004        #define IDM_FILE_PRINT        40005        #define IDM_APP_EXIT          40006        #define IDM_EDIT_UNDO         40007        #define IDM_EDIT_CUT          40008        #define IDM_EDIT_COPY         40009        #define IDM_EDIT_PASTE        40010        #define IDM_EDIT_CLEAR        40011        #define IDM_EDIT_SELECT_ALL   40012        #define IDM_SEARCH_FIND       40013        #define IDM_SEARCH_NEXT       40014        #define IDM_SEARCH_REPLACE    40015        #define IDM_FORMAT_FONT       40016        #define IDM_HELP              40017        #define IDM_APP_ABOUT         40018        

POPPAD.ICO

为了避免在第十三章中重复原始码,我在POPPAD.RC的菜单中加入了打印项目和一些其它的支持。

POPPAD.C包含了程序中所有的基本原始码。POPFILE.C具有启动File Open和File Save对话框的程序代码,它还包含文件I/O例程。POPFIND.C中包含了搜寻和替换文字功能。POPFONT.C包含了字体选择功能。POPPRNT0.C不完成什么工作:在第十三章中将使用POPPRNT.C替换POPPRNT0.C以建立最终的POPPAD程序。

让我们先来看一看POPPAD.C。POPPAD.C含有两个文件名字符串:第一个,储存在WndProc,名称为szFileName,含有详细的驱动器名称、路径名称和文件名称;第二个,储存为szTitleName,是程序本身的文件名称。它用在POPPAD3的DoCaption函数中,以便将文件名称显示在窗口的标题列上;也用在OKMessage函数和AskAboutSave函数中,以便向使用者显示消息框。

POPFILE.C包含了几个显示「File Open」和「File Save」对话框以及实际执行文件I/O的函数。对话框是使用函数GetOpenFileName和GetSaveFileName来显示的。这两个函数都使用一个型态为OPENFILENAME的结构,这个结构在COMMDLG.H中定义。在POPFILE.C中,使用了一个该结构型态的整体变量,取名为ofn。ofn的大多数字段在PopFileInitialize函数中被初始化,POPPAD.C在WndProc中处理WM_CREATE消息时呼叫该函数。

将ofn作为静态整体结构变量会比较方便,因为GetOpenFileName和GetSaveFileName给该结构传回的一些信息,并将在以后呼叫这些函数时用到。

尽管通用对话框具有许多选项-包括设定自己的对话框模板,以及为对话框程序增加「挂勾(hook)」-POPFILE.C中使用的「File Open」和「File Save」对话框是最基本的。OPENFILENAME结构中被设定的字段只有lStructSize(结构的长度)、hwndOwner(对话框拥有者)、lpstrFilter(下面将简要讨论)、lpstrFile和nMaxFile(指向接收完整文件名称的缓冲区指标和该缓冲区的大小)、lpstrFileTitle和nMaxFileTitle(文件名称缓冲区及其大小)、Flags(设定对话框的选项)和lpstrDefExt(如果使用者在对话框中输入文件名时不指定文件扩展名,那么它就是内定的文件扩展名)。

当使用者在「File」菜单中选择「Open」时,POPPAD3呼叫POPFILE的PopFileOpenDlg函数,将窗口句柄、一个指向文件名称缓冲区的指标和一个指向文件标题缓冲区的指标传给它。PopFileOpenDlg恰当地设定OPENFILENAME结构的hwndOwner、lpstrFile和lpstrFileTitle字段,将Flags设定为OFN_ CREATEPROMPT,然后呼叫GetOpenFileName,显示如图11-6所示的普通对话框。

 

当使用者结束这个对话框时,GetOpenFileName函数传回。OFN_CREATEPROMPT旗标指示GetOpenFileName显示一个消息框,询问使用者如果所选文件不存在,是否要建立该文件。

左下角的下拉式清单方块列出了将要显示在文件列表中的文件型态,此清单方块被称为「筛选清单」。使用者可以通过从下拉式清单方块列表中选择另一种文件型态,来改变筛选条件。在POPFILE.C的PopFileInitialize函数中,我在变量szFilter(一个字符串数组)中为三种型态的文件定义了一个筛检清单:带有.TXT扩展名的文本文件、带有.ASC扩展名的ASCII文件和所有文件。OPENFILENAME结构的lpstrFilter字段储存指向此数组第一个字符串的指针。

如果使用者在对话框处于活动状态时改变了筛选条件,那么OPENFILENAME的nFilterIndex字段反映出使用者的选择。由于该结构是静态变量,下次启动对话框时,筛选条件将被设定为选中的文件型态。

POPFILE.C中的PopFileSaveDlg函数与此类似,它将Flags参数设定为OFN_OVERWRITEPROMPT,并呼叫GetSaveFileName启动「File Save」对话框。OFN_OVERWRITEPROMPT旗标导致显示一个消息框,如果被选文件已经存在,那么将询问使用者是否覆盖该文件。


0 0