在如下程序中,我如果把变量定义为static,则程序能正常运行,如果我不定义为static就会出现很多莫名其妙的错误,请问这是为什么??
问题1:static在本程序中的作用,为什么没有定义为static变量进行初始化?
问题2:在该例程中,如果将fState定义为WndProc的静态变量,它也应该能正常运行,请问能不能改,如何改,二者的区别是什么??
问题3:lParam中的值一般为什么,有时其值为客户区的大小,有时却为鼠标的坐标或者滚动轴的坐标,这应该怎么区分??
问题4: LRESULT 的意思是什么?WndProc 有没有返回值,其值为什么??LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     static BOOL fState[DIVISIONS][DIVISIONS] ; //DIVISIONS为宏定义,其值为5
     //如下面注释的程序,如果我不定义成static,然后自己初始化就会一堆错误,请问是为什么?
     BOOL fState[DIVISIONS][DIVISIONS];
     memset(fState,0,sizeof(BOOL)*25);

     static int  cxBlock=0, cyBlock=0; //每个矩形框的宽度和高度
     HDC         hdc ;
     int         x, y ;
     PAINTSTRUCT ps ;
     RECT        rect ;
    
     switch (message)
     {
     case WM_SIZE :
          cxBlock = LOWORD (lParam) / DIVISIONS ;
          cyBlock = HIWORD (lParam) / DIVISIONS ;
          return 0 ;
          
     case WM_LBUTTONDOWN :
          x = LOWORD (lParam) / cxBlock ;
          y = HIWORD (lParam) / cyBlock ;
          
          if (x < DIVISIONS && y < DIVISIONS)
          {
               fState [x][y] ^= 1 ; //每次fState[x][y]与1进行异或运算后将结果赋给fState[x][y]
               
               rect.left   = x * cxBlock ;
               rect.top    = y * cyBlock ;
               rect.right  = (x + 1) * cxBlock ;
               rect.bottom = (y + 1) * cyBlock ;
   
               //使整个客户区都无效
               InvalidateRect (hwnd, &rect, FALSE) ;
          }
          else
               MessageBeep (0) ;
          return 0 ;
          
     case WM_PAINT :   //每次都将整个客户区根据fState矩阵的值进行重绘
      hdc = BeginPaint (hwnd, &ps) ;
          
          for (x = 0 ; x < DIVISIONS ; x++)
          for (y = 0 ; y < DIVISIONS ; y++)
          {
               Rectangle (hdc, x * cxBlock, y * cyBlock,
                         (x + 1) * cxBlock, (y + 1) * cyBlock) ;
                    
               if (fState [x][y])
               {
                    MoveToEx (hdc,  x    * cxBlock,  y    * cyBlock, NULL) ;
                    LineTo   (hdc, (x+1) * cxBlock, (y+1) * cyBlock) ;
                    MoveToEx (hdc,  x    * cxBlock, (y+1) * cyBlock, NULL) ;
                    LineTo   (hdc, (x+1) * cxBlock,  y    * cyBlock) ;
               }
          }
          EndPaint (hwnd, &ps) ;
          return 0 ;
               
     case WM_DESTROY :
          PostQuitMessage (0) ;
          return 0 ;
     }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
}

解决方案 »

  1.   

    1和2:请lz参考http://www.vckbase.com/document/viewdoc/?id=1720,好好体会一下什么是静态变量,以及怎么使用静态变量。
    3、lParam表示什么,由用户自己定义
    4、LRESULT是什么?在VC中选中LRESULT,然后右键菜单中选择goto definition,就可以看到LRESULT的定义了。
    5、WndProc的返回值就是LRESULT
      

  2.   

    该程序的功能是,把客户区分为5×5的单元格,然后当鼠标之余某一个单元格内时则在此单元格内画两条对角线,当用户在同一单元格内再点击一次,则两条对角线消失。下面为整个源程序,请楼上的给我看看为啥会有这么多错误该怎么改。
    红色的为我自己该的语句。#include <windows.h>#define DIVISIONS 5LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                        PSTR  szCmdLine, int iCmdShow)
    {
         static TCHAR szAppName[] = TEXT ("Checker1") ;
         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 ("Program requires Windows NT!"), 
                          szAppName, MB_ICONERROR) ;
              return 0 ;
         }
         
         hwnd = CreateWindow (szAppName, TEXT ("Checker1 Mouse Hit-Test Demo"),
                              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 BOOL fState[DIVISIONS][DIVISIONS] ;把这句替换为下面的就会错为什么??
     BOOL fState[DIVISIONS][DIVISIONS];
    [color=#FF0000]  memset(fState,0,sizeof(BOOL)*25);
    [/color]     static int  cxBlock=0, cyBlock=0; //每个矩形框的宽度和高度
         HDC         hdc ;
         int         x, y ;
         PAINTSTRUCT ps ;
         RECT        rect ;
        
         switch (message)
         {
         case WM_SIZE :
              cxBlock = LOWORD (lParam) / DIVISIONS ;
              cyBlock = HIWORD (lParam) / DIVISIONS ;
              return 0 ;
              
         case WM_LBUTTONDOWN :
              x = LOWORD (lParam) / cxBlock ;
              y = HIWORD (lParam) / cyBlock ;
              
              if (x < DIVISIONS && y < DIVISIONS)
              {
                   fState [x][y] ^= 1 ; //每次fState[x][y]与1进行异或运算后将结果赋给fState[x][y]
                   
                   rect.left   = x * cxBlock ;
                   rect.top    = y * cyBlock ;
                   rect.right  = (x + 1) * cxBlock ;
                   rect.bottom = (y + 1) * cyBlock ;
       
                   //使整个客户区都无效
                   InvalidateRect (hwnd, &rect, FALSE) ;
              }
              else
                   MessageBeep (0) ;
              return 0 ;
              
         case WM_PAINT :   //每次都将整个客户区根据fState矩阵的值进行重绘
          hdc = BeginPaint (hwnd, &ps) ;
              
              for (x = 0 ; x < DIVISIONS ; x++)
              for (y = 0 ; y < DIVISIONS ; y++)
              {
                   Rectangle (hdc, x * cxBlock, y * cyBlock,
                             (x + 1) * cxBlock, (y + 1) * cyBlock) ;
                        
                   if (fState [x][y])
                   {
                        MoveToEx (hdc,  x    * cxBlock,  y    * cyBlock, NULL) ;
                        LineTo   (hdc, (x+1) * cxBlock, (y+1) * cyBlock) ;
                        MoveToEx (hdc,  x    * cxBlock, (y+1) * cyBlock, NULL) ;
                        LineTo   (hdc, (x+1) * cxBlock,  y    * cyBlock) ;
                   }
              }
              EndPaint (hwnd, &ps) ;
              return 0 ;
                   
         case WM_DESTROY :
              PostQuitMessage (0) ;
              return 0 ;
         }
         return DefWindowProc (hwnd, message, wParam, lParam) ;
    }
      

  3.   

    fState指向的是存储了5个指针的数组,分别指向fState[0],fState[1],fState[2],fState[3],fState[4]
    要这样memset(fState[0],0,sizeof(BOOL)*25);2、静态变量存储在全局数据区,而且如果静态变量在函数中,那么无论当这个函数执行多少次,这个静态变量只初始化一次
      

  4.   

    问题1:static在本程序中的作用,为什么没有定义为static变量进行初始化?
    局部变量前面加static表示该变量为静态变量,在程序模块的静态区分配空间,函数返回后变量仍然存在,下次使用时仍保持上次用后的值,类似于全局变量,只是作用域不同。问题2:在该例程中,如果将fState定义为WndProc的静态变量,它也应该能正常运行,请问能不能改,如何改,二者的区别是什么??
    如果需要保持变量的值,可以将变量定义为静态变量(前面加static),如果不需要保持变量的值,通常用动态变量。问题3:lParam中的值一般为什么,有时其值为客户区的大小,有时却为鼠标的坐标或者滚动轴的坐标,这应该怎么区分??
    lParam的含义与具体的消息值有关,不同消息含义不同。问题4: LRESULT 的意思是什么?WndProc 有没有返回值,其值为什么??
    LRESULT是窗口函数的返回值类型,通常返回0表示函数处理了该消息,不同的消息,返回值的含义也不同,参考MSDN中各个消息的说明。如果不定义为static,会有什么样的错误?