Windows通用对话框—增强POPPAD

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值