2 u011198059 u011198059 于 2014.02.26 10:19 提问

关于windows程序设计第六章的最后一个范例……

在第六章(讲键盘)的里面最后有一个typer程序的代码,我能看懂它们但有些不理解为什么作者要这么做………………在此贴上消息处理部分的代码恳请了解API的人帮忙解答一下……这里刚入门现在已经完全昏了

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) ;

case WM_SIZE:
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) ;

      pBuffer = (TCHAR *) malloc (cxBuffer * cyBuffer * sizeof (TCHAR)) ;

      for (y = 0 ; y < cyBuffer ; y++)
           for (x = 0 ; x < cxBuffer ; x++)
                BUFFER(x,y) = ' ' ;

           // 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)) ;

      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) ;

}

问题:
①vk_DELETE里我理解作者是想把输入的char给删除……但我搞不懂他那样写的原因是什么,特别
for (x = xCaret ; x < cxBuffer - 1 ; x++)
BUFFER (x, yCaret) = BUFFER (x + 1, yCaret) ;

       BUFFER (cxBuffer - 1, yCaret) = ' ' ;

这里我就完全看得云里雾里搞不懂意义……尤其BUFFER这个玩意儿是干啥的我在MSDN也没找到;w;难道是最先开始漏看了哪一章吗

②default那里的 TextOut (hdc, xCaret * cxChar, yCaret * cyChar,
& BUFFER (xCaret, yCaret), 1) ;
部分,为什么buffer前会有个"&"?如果我没记错的话这个不是指输出地址的意思吗……这个BUFFER到底是什么呢?

;w;谢谢大家了

2个回答

qq_33001647
qq_33001647   2016.07.25 08:54

BUFFER就是为了取到坐标为(x,y)处的位置,因为windows程序默认坐标是以左上角为原点,坐标为(x,y)时,水平方向上有y+1行,所以该处的位置用数组表示为(pBuffer+(y+1-1)*cxBuffer+x),大致是这个意思吧,楼主好好体会下就明白了,实在不行,画表格比如(1,3)等这样用具体的数字试试

qq_33001647
qq_33001647   2016.07.25 08:54

BUFFER就是为了取到坐标为(x,y)处的位置,因为windows程序默认坐标是以左上角为原点,坐标为(x,y)时,水平方向上有y+1行,所以该处的位置用数组表示为(pBuffer+(y+1-1)*cxBuffer+x),大致是这个意思吧,楼主好好体会下就明白了,实在不行,画表格比如(1,3)等这样用具体的数字试试

Csdn user default icon
上传中...
上传图片
插入图片