  | 
      
        
          1樓
          巨大八爪鱼
          2016-4-26 21:10
          
          
           
         
        ScrollWindow(hWnd, 水平滚动量, 垂直滚动量, NULL, NULL); UpdateWindow(hWnd);
  当水平滚动量为负时向左滚动,为正时向右滚动。 垂直滚动量为负时向上滚动,为正时向下滚动。 滚动后最好调用UpdateWindow函数立即执行WM_PAINT。虽然不调用这个函数最终WM_PAINT也会执行,但是系统会拖到所有其他消息都处理完毕了才执行,有时会影响用户体验。 第三、四个参数一般为NULL,即滚动整个窗口。
  滚动后,系统会自动将暴露出来的空白部分交给WM_PAINT绘制。
  如果使用Ex版本的话,一般使用: ScrollWindowEx(hWnd, -40, 0, NULL, NULL, NULL, NULL, SW_INVALIDATE);
  
       | 
    
    
        | 
      
        
          2樓
          巨大八爪鱼
          2016-4-26 21:10
          
          
           
         
        【示例程序】 #include <tchar.h> #include <Windows.h>
  BITMAP bmp; HBITMAP hbmp;
  int nScrolled = 0;
  LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {     HDC hdc, hdcMem;     PAINTSTRUCT ps;
      switch (uMsg)     {     case WM_CHAR:         if (wParam == '+')         {             nScrolled = 1;             //ScrollWindowEx(hWnd, -40, 0, NULL, NULL, NULL, NULL, SW_INVALIDATE);             ScrollWindow(hWnd, -40, 0, NULL, NULL);             UpdateWindow(hWnd);         }         else if (wParam == '-')         {             nScrolled = 2;             ScrollWindow(hWnd, +40, 0, NULL, NULL);             UpdateWindow(hWnd);         }         break;     case WM_CREATE:         hbmp = (HBITMAP)LoadImage(NULL, TEXT("img21.bmp"), IMAGE_BITMAP, NULL, NULL, LR_LOADFROMFILE);         GetObject(hbmp, sizeof(bmp), &bmp);         break;     case WM_DESTROY:         DeleteObject(hbmp);         PostQuitMessage(0);         break;     case WM_PAINT:         hdc = BeginPaint(hWnd, &ps);         if (nScrolled > 0)         {             HBRUSH hbr;             RECT rcClient;             GetClientRect(hWnd, &rcClient);             if (nScrolled == 1)                 hbr = CreateSolidBrush(RGB(0, 0, 255));             else                 hbr = CreateSolidBrush(RGB(0, 255, 0));             FillRect(hdc, &rcClient, hbr);             DeleteObject(hbr);         }         else         {             hdcMem = CreateCompatibleDC(hdc);             SelectObject(hdcMem, hbmp);             BitBlt(hdc, 0, 0, bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY);             DeleteDC(hdcMem);         }         EndPaint(hWnd, &ps);         break;     default:         return DefWindowProc(hWnd, uMsg, wParam, lParam);     }     return FALSE; }
  int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) {     WNDCLASSEX wcex;     wcex.cbSize = sizeof(WNDCLASSEX);     wcex.cbClsExtra = wcex.cbWndExtra = 0;     wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);     wcex.hCursor = LoadCursor(NULL, IDC_ARROW);     wcex.hIcon = wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);     wcex.hInstance = hInstance;     wcex.lpfnWndProc = WndProc;     wcex.lpszClassName = TEXT("Scrolling Demo Window");     wcex.lpszMenuName = NULL;     wcex.style = NULL;     RegisterClassEx(&wcex);
      HWND hWnd = CreateWindow(wcex.lpszClassName, TEXT("Scrolling Demo"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);     ShowWindow(hWnd, nCmdShow);     UpdateWindow(hWnd);
      MSG msg;     while (GetMessage(&msg, NULL, 0, 0))     {         TranslateMessage(&msg);         DispatchMessage(&msg);     }     return 0; }
  
       | 
    
    
        | 
      
        
          3樓
          巨大八爪鱼
          2016-4-26 21:13
          
          
           
         
        在上面的程序中,按下+键窗口向左滚动,并将nScrolled设为1。如果按下-键则向右滚动,并将nScrolled设为2。程序刚启动时nScrolled值为0。 WM_PAINT的执行内容是:当nScrolled为0时绘制一张BMP图片,为1时将整个屏幕刷成蓝色,为2时刷成绿色。(这是为了方便观察ScrollWindow将窗口哪些区域设为了无效区域) 
       | 
    
    
        | 
      
        
          6樓
          巨大八爪鱼
          2016-4-26 21:17
          
          
           
         
        按下-后:  绿色部分为ScrollWindow创建的无效区域。 注意:如果在WM_PAINT中绘制时将图像画在了无效区域以外,那么这部分图像将不会显示出来。因为Windows为了提高性能,更新窗口时只将无效区域中的像素传送给显示器显示。  
       | 
    
    
        | 
      
        
          8樓
          巨大八爪鱼
          2016-4-26 22:00
          
          
           
         
         图中红色矩形为滚动区域。 A的坐标为(50, 50) B的坐标为(200, 150) C区域的宽度为40  
       | 
    
    
        | 
      
        
          9樓
          巨大八爪鱼
          2016-4-26 22:05
          
          
           
         
         当第三个参数不为NULL时,该函数直接把这块矩形区域剪下来往指定方向移动,并重绘暴露出来的区域。 例如这里把rect矩形剪下来直接往左平移到(10, 50)处,然后把暴露出来的区域交给WM_PAINT重绘。  
       |