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