首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

文本编辑器有关问题(新手)

2012-03-02 
文本编辑器问题(新手)C/C++ code/*--------------------------------------TYPER.C -- Typing Program(c)

文本编辑器问题(新手)

C/C++ code
/*--------------------------------------   TYPER.C -- Typing Program              (c) Charles Petzold, 1998  --------------------------------------*/ #include <windows.h>#define BUFFER(x,y) *(pBuffer + y * cxBuffer + x)LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,                    PSTR szCmdLine, int iCmdShow){     static TCHAR szAppName[] = TEXT ("Typer") ;     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, TEXT ("Typing Program"),                          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 DWORD   dwCharSet = DEFAULT_CHARSET ;     static int     cxChar, cyChar, cxClient, cyClient, cxBuffer, cyBuffer,                    xCaret, yCaret ;     static TCHAR * pBuffer = NULL ;     HDC            hdc ;     int            x, y, i ;     PAINTSTRUCT    ps ;     TEXTMETRIC     tm ;          switch (message)     {     case WM_INPUTLANGCHANGE:          dwCharSet = wParam ;                                        // fall through     case WM_CREATE:          hdc = GetDC (hwnd) ;         // SelectObject (hdc, CreateFont (0, 0, 0, 0, 0, 0, 0, 0,                    //               dwCharSet, 0, 0, 0, FIXED_PITCH, NULL)) ;                    GetTextMetrics (hdc, &tm) ;          cxChar = tm.tmAveCharWidth ;          cyChar = tm.tmHeight ;                    DeleteObject (SelectObject (hdc, GetStockObject (SYSTEM_FONT))) ;          ReleaseDC (hwnd, hdc) ;                                        // fall through                     case WM_SIZE:               // obtain window size in pixels          if (message == WM_SIZE)          {               cxClient = LOWORD (lParam) ;               cyClient = HIWORD (lParam) ;          }               // calculate window size in characters                    cxBuffer = max (1, cxClient / cxChar) ;          cyBuffer = max (1, cyClient / cyChar) ;                         // allocate memory for buffer and clear it                    if (pBuffer != NULL)               free (pBuffer) ;        [color=#FF0000]  pBuffer = (TCHAR *) malloc (cxBuffer * cyBuffer * sizeof (TCHAR)) ;                    for (y = 0 ; y < cyBuffer ; y++)               for (x = 0 ; x < cxBuffer ; x++)                    BUFFER(x,y) = ' ' ;[/color]                                   // set caret to upper left corner          xCaret = 0 ;          yCaret = 0 ;                              if (hwnd == GetFocus ())               SetCaretPos (xCaret * cxChar, yCaret * cyChar) ;          InvalidateRect (hwnd, NULL, TRUE) ;          return 0 ;                         case WM_SETFOCUS:               // create and show the caret                    CreateCaret (hwnd, NULL, cxChar, cyChar) ;          SetCaretPos (xCaret * cxChar, yCaret * cyChar) ;          ShowCaret (hwnd) ;          return 0 ;               case WM_KILLFOCUS:               // hide and destroy the caret          HideCaret (hwnd) ;          DestroyCaret () ;          return 0 ;               case WM_KEYDOWN:          switch (wParam)          {          case VK_HOME:               xCaret = 0 ;               break ;                         case VK_END:               xCaret = cxBuffer - 1 ;               break ;                         case VK_PRIOR:               yCaret = 0 ;               break ;                         case VK_NEXT:               yCaret = cyBuffer - 1 ;               break ;                         case VK_LEFT:               xCaret = max (xCaret - 1, 0) ;               break ;                         case VK_RIGHT:               xCaret = min (xCaret + 1, cxBuffer - 1) ;               break ;                         case VK_UP:               yCaret = max (yCaret - 1, 0) ;               break ;                         case VK_DOWN:               yCaret = min (yCaret + 1, cyBuffer - 1) ;               break ;                         case VK_DELETE:               for (x = xCaret ; x < cxBuffer - 1 ; x++)                    BUFFER (x, yCaret) = BUFFER (x + 1, yCaret) ;                              BUFFER (cxBuffer - 1, yCaret) = ' ' ;                              HideCaret (hwnd) ;               hdc = GetDC (hwnd) ;                         SelectObject (hdc, CreateFont (0, 0, 0, 0, 0, 0, 0, 0,                                   dwCharSet, 0, 0, 0, FIXED_PITCH, NULL)) ;                                   TextOut (hdc, xCaret * cxChar, yCaret * cyChar,                        & BUFFER (xCaret, yCaret),                        cxBuffer - xCaret) ;               DeleteObject (SelectObject (hdc, GetStockObject (SYSTEM_FONT))) ;               ReleaseDC (hwnd, hdc) ;               ShowCaret (hwnd) ;               break ;          }          SetCaretPos (xCaret * cxChar, yCaret * cyChar) ;          return 0 ;               case WM_CHAR:          for (i = 0 ; i < (int) LOWORD (lParam) ; i++)          {               switch (wParam)               {               case '\b':                    // backspace                    if (xCaret > 0)                    {                         xCaret-- ;                         SendMessage (hwnd, WM_KEYDOWN, VK_DELETE, 1) ;                    }                    break ;                                   case '\t':                    // tab                    do                    {                         SendMessage (hwnd, WM_CHAR, ' ', 1) ;                    }                    while (xCaret % 8 != 0) ;                    break ;                                   case '\n':                    // line feed                    if (++yCaret == cyBuffer)                         yCaret = 0 ;                    break ;                                   case '\r':                    // carriage return                    xCaret = 0 ;                                        if (++yCaret == cyBuffer)                         yCaret = 0 ;                    break ;                                   case '\x1B':                  // escape                    for (y = 0 ; y < cyBuffer ; y++)                         for (x = 0 ; x < cxBuffer ; x++)                              BUFFER (x, y) = ' ' ;                                             xCaret = 0 ;                    yCaret = 0 ;                                             InvalidateRect (hwnd, NULL, FALSE) ;                    break ;                                        default:                      // character codes                    BUFFER (xCaret, yCaret) = (TCHAR) wParam ;                                        HideCaret (hwnd) ;                    hdc = GetDC (hwnd) ;                             SelectObject (hdc, CreateFont (0, 0, 0, 0, 0, 0, 0, 0,                                   dwCharSet, 0, 0, 0, FIXED_PITCH, NULL)) ;                    TextOut (hdc, xCaret * cxChar, yCaret * cyChar,                             & BUFFER (xCaret, yCaret), 1) ;                    DeleteObject (                         SelectObject (hdc, GetStockObject (SYSTEM_FONT))) ;                    ReleaseDC (hwnd, hdc) ;                    ShowCaret (hwnd) ;                    if (++xCaret == cxBuffer)                    {                         xCaret = 0 ;                                                  if (++yCaret == cyBuffer)                              yCaret = 0 ;                    }                    break ;               }          }                    SetCaretPos (xCaret * cxChar, yCaret * cyChar) ;          return 0 ;               case WM_PAINT:                  hdc = BeginPaint (hwnd, &ps) ;                             SelectObject (hdc, CreateFont (0, 0, 0, 0, 0, 0, 0, 0,                                   dwCharSet, 0, 0, 0, FIXED_PITCH, NULL)) ;          HideCaret(hwnd);          MoveToEx(hdc,100,100,NULL);          LineTo(hdc,20,400);           ShowCaret(hwnd);          for (y = 0 ; y < cyBuffer ; y++)               TextOut (hdc, 0, y * cyChar, & BUFFER(0,y), cxBuffer) ;          DeleteObject (SelectObject (hdc, GetStockObject (SYSTEM_FONT))) ;          EndPaint (hwnd, &ps) ;          return 0 ;               case WM_DESTROY:          PostQuitMessage (0) ;          return 0 ;     }     return DefWindowProc (hwnd, message, wParam, lParam) ;} 



其实我问的就是带颜色的那一段代码!我明白他们的字面意思,但不明白为啥要如此做!我试图去掉他们,但去掉后,客户区全都变成一个一个的小方块了,为什么啊?



[解决办法]
//BUFFER(x,y) ='' ;首先这句话注释会乱码 是因为如果注视 值为不确定(未初始化),
case WM_PAINT:里面这句
for (y = 0 ; y < cyBuffer ; y++)
TextOut (hdc, 0, y * cyChar, & BUFFER(0,y), cxBuffer);//会把BUFFER(0,y)值输出。你注释后,值
没有正确初始。所以乱码。
[解决办法]
不会。。等待高手解答
[解决办法]
这个程序就只做了个简单处理.
输入的信息存在pBuffer中, 但当窗口大小改变时, pBuffer直接清除(重新申请,并填入空格),客户区将变为空白.所以程序只是作为演示用.
pBuffer在程序开始时(第一个WM_SIZE消息)就申请空间, 并填入空格.
如果注释掉它, 那么在WM_PAINT时, 调用pBuffer指针将会不确定. 不确定的位置的内容很少有可能是可见字符,所以就会显示乱码.(可能textout会把乱码统一变成方块吧)
for (y = 0 ; y < cyBuffer ; y++)
TextOut (hdc, 0, y * cyChar, & BUFFER(0,y), cxBuffer) ;
BUFFER(0,y)是一个宏
#define BUFFER(x,y) *(pBuffer + y * cxBuffer + x)
[解决办法]
CreateCaret放在WINMAIN 的createwindow之后就可以,

在WM_SETFOCUS事件里就是隐藏或显示,或根据鼠标为止重定位光标,光标不需要反复创建。

热点排行