五、Windows子窗口控件的编辑类别
在某些方面,编辑类别是最简单的预先定义窗口类别;在另一方面,它又是最复杂的窗口类别。当您使用类别名称「edit」建立子窗口时,您根据CreateWindow呼叫中的x位置、y位置、宽度和高度这些参数定义了一个矩形。此矩形含有可编辑文字。当子窗口控件拥有输入焦点时,您可以输入文字,移动光标,使用鼠标或者Shift键与一个光标键来选取部分文字,按Ctrl-X来删除所选文字或按Ctrl-C来复制所选文字、并送到剪贴簿上,按Ctrl-V键插入剪贴簿上的文字。
编辑控件的最简单的应用之一是作为单行输入区域。但是编辑控件并不仅限于单行,这一点我将在程序9-4 POPPAD1中说明。和我们在这本书中所遇到的各种其它问题一样,POPPAD程序将逐步增强以使用菜单、对话框(加载与储存文件)和打印。最后的版本将是一个简单而完整的文字编辑器,且其程序代码将非常简洁。
	程序9-4 POPPAD1
	
        
POPPAD1.C
        
/*---------------------------------------------------------------------------
        
  POPPAD1.C -- Popup Editor using child window edit box
        
                                   (c) Charles Petzold, 1998
        
---------------------------------------------------------------------------*/
        
#include <windows.h>
        
#define ID_EDIT     1
        
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
        
TCHAR szAppName[] = TEXT ("PopPad1") ;
        
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
        
                   PSTR szCmdLine, int iCmdShow)
        
{
        
           HWND                  hwnd ;
        
           MSG                      msg ;
        
           WNDCLASS              wndclass ;
        
   
        
           wndclass.style                                       = CS_HREDRAW | CS_VREDRAW ;
        
           wndclass.lpfnWndProc                                 = WndProc ;
        
           wndclass.cbClsExtra                                  = 0 ;
        
         wndclass.cbWndExtra                                  = 0 ;
        
           wndclass.hInstance                                   = hInstance ;
        
           wndclass.hIcon                                       = LoadIcon (NULL, IDI_APPLICATION) ;
        
           wndclass.hCursor                                     = LoadCursor (NULL, IDC_ARROW) ;
        
           wndclass.hbrBackground                       = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
        
           wndclass.lpszMenuName                        = NULL ;
        
           wndclass.lpszClassName                       = szAppName ;
        
   
        
           if (!RegisterClass (&wndclass))
        
           {
        
                  MessageBox (  NULL, TEXT ("This program requires Windows NT!"),
        
                                                                       szAppName, MB_ICONERROR) ;
        
                  return 0 ;
        
           }
        
    hwnd = CreateWindow (szAppName, szAppName,
        
                       WS_OVERLAPPEDWINDOW,
        
                       CW_USEDEFAULT, CW_USEDEFAULT,
        
                       CW_USEDEFAULT, CW_USEDEFAULT,
        
                       NULL, NULL, hInstance, NULL) ;
        
  ShowWindow (hwnd, iCmdShow) ;
        
  UpdateWindow (hwnd) ;
        
   
        
           while (GetMessage (&msg, NULL, 0, 0))
        
           {
        
                  TranslateMessage (&msg) ;
        
                  DispatchMessage (&msg) ;
        
           }
        
           return msg.wParam ;
        
}
        
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam)
        
{
        
           static HWND hwndEdit ;
        
           switch (message)
        
           {
        
           case   WM_CREATE :
        
                  hwndEdit = CreateWindow (TEXT ("edit"), NULL,
        
               WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL |
        
               WS_BORDER | ES_LEFT | ES_MULTILINE |
        
               ES_AUTOHSCROLL | ES_AUTOVSCROLL,
        
               0, 0, 0, 0, hwnd, (HMENU) ID_EDIT,
        
              ((LPCREATESTRUCT) lParam) -> hInstance, NULL) ;
        
                  return 0 ;
        
        
        
           case   WM_SETFOCUS :
        
                  SetFocus (hwndEdit) ;
        
                  return 0 ;
        
        
        
           case   WM_SIZE :
        
           MoveWindow (hwndEdit, 0, 0, LOWORD (lParam), HIWORD (lParam), TRUE) ;
        
                  return 0 ;
        
        
        
           case   WM_COMMAND :
        
                  if (LOWORD (wParam) == ID_EDIT)
        
               if (HIWORD (wParam) == EN_ERRSPACE ||
        
                   HIWORD (wParam) == EN_MAXTEXT)
        
            MessageBox (hwnd, TEXT ("Edit control out of space."),
        
                   szAppName, MB_OK | MB_ICONSTOP) ;
        
                  return 0 ;
        
             
        
           case   WM_DESTROY :
        
                  PostQuitMessage (0) ;
        
                  return 0 ;
        
          }
        
           return DefWindowProc (hwnd, message, wParam, lParam) ;
        
}
        
POPPAD1是一个多行编辑器(只是没有文件I/O),其C语言原始码不到100行(不过,有一个缺陷,即预先定义的多行编辑控件只限于30,000字符的文字)。您可以看到,POPPAD1本身并没有做多少工作,预先定义的编辑控件完成了许多工作,这样,您可以知道,无需额外的程序时编辑控件能做些什么。
