五、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本身并没有做多少工作,预先定义的编辑控件完成了许多工作,这样,您可以知道,无需额外的程序时编辑控件能做些什么。