我想把自己客户区显示的图形保存为位图
直接把客户区域显示的数据保存为位图时只能保存当前可见的
从网上搜到的关于保存.打开位图资料的都没提到在sdk中滚动视图保存的问题
怎样才能把整个客户区的全部保存(包括不可见的部分)
谢谢大家了!

解决方案 »

  1.   

    既然是自己画的就好办了,使用双缓冲就可以
    数据先画到缓冲区上(位图),然后再bitblt拷贝到显示设备上。
    这样就能保存一个完整的图形了
      

  2.   

    谢谢回答阿。不过我还是不太明白。现在我把我写的代码贴出来吧,请大家帮着指点一下。这个代码只能保存可见部分的。
    BOOL DibSaveImage (PTSTR pstrFileName, HWND hwnd, int cxClient,int cyClient,int cxtotalSize)
    {
         BOOL   bSuccess ;
     BITMAPFILEHEADER bfh;
     BITMAPINFOHEADER bih;
         DWORD  dwBytesWritten1,dwBytesWritten2,dwBytesWritten3 ;     HANDLE hFile ;
         HDC              hdc,  hdcMemBack;
     BITMAP             btm;
     DWORD             size;
         LPSTR            lpData;
         HBITMAP hBitmapBack,hOld;
         HGDIOBJ hBrushFill=NULL;  hdc=GetDC(hwnd);
     hdcMemBack=CreateCompatibleDC(hdc); 
     hBitmapBack=CreateCompatibleBitmap(hdc,cxClient*cxtotalSize,cyClient);
         hOld=SelectObject (hdcMemBack, hBitmapBack) ;
     Rectangle(hdcMemBack,0,0,cxClient*cxtotalSize,cyClient);
     BitBlt(hdcMemBack,0, 0,cxClient*cxtotalSize, cyClient, hdc, 0, 0, SRCCOPY);
         SelectObject(hdcMemBack,hOld);
     //GetBitmap(&btm);
     GetObject (hBitmapBack, sizeof (BITMAP), &btm) ;
     size = btm.bmWidthBytes * btm.bmHeight;
         lpData = (LPSTR)GlobalAlloc(GPTR, size);
     bih.biBitCount = btm.bmBitsPixel;
         bih.biClrImportant = 0;
         bih.biCompression = 0;
         bih.biHeight = btm.bmHeight;
         bih.biPlanes = 1;
         bih.biSize = sizeof(BITMAPINFOHEADER);
         bih.biSizeImage = size;
         bih.biWidth = btm.bmWidth;
         bih.biXPelsPerMeter = 0;
         bih.biYPelsPerMeter = 0;
         GetDIBits(hdcMemBack,hBitmapBack,0,bih.biHeight,lpData,(BITMAPINFO*)&bih,DIB_RGB_COLORS);
         bfh.bfReserved1 = bfh.bfReserved2 = 0;
         bfh.bfType = ((WORD)('M'<< 8)|'B');
         bfh.bfSize = 54 + size;
         bfh.bfOffBits = 54;
     ReleaseDC (hwnd, hdc) ;
           
     hFile = CreateFile (pstrFileName, GENERIC_WRITE, 0, NULL,
                             CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL) ;     if (hFile == INVALID_HANDLE_VALUE)
              return FALSE ;     bSuccess = WriteFile (hFile, &bfh, 14, &dwBytesWritten1, NULL) ;
                WriteFile (hFile, &bih, bih.biSize, &dwBytesWritten2, NULL) ;
    WriteFile (hFile, lpData, size, &dwBytesWritten3, NULL) ;
         CloseHandle (hFile) ;
     GlobalFree(lpData);
         DeleteObject(hBitmapBack);
         if (!bSuccess &&(dwBytesWritten2 != bih.biSize)&&(dwBytesWritten3 != size))
         {
              DeleteFile (pstrFileName) ;
              return FALSE ;
         }
         return TRUE ;
    }
      

  3.   

    这部分代码看不出什么问题,关键看你是怎么绘制到窗口DC上的。
    因为你拷贝位图是从窗口DC上拷贝的。如果你窗口DC本身就是只绘制了全部位图的一部分,那么你拷贝回来的也只是一部分了。你能把你WM_PAINT的处理部分贴出来么?
      

  4.   

    好的我现在把我的WM_PAINT消息部分和实现画图的函数贴出来。不过我的函数写得较乱,各位高人见笑了。谢谢大家。
    case WM_PAINT:            // Clear the window
              
              //InvalidateRect (hwnd, NULL, TRUE) ;
      
              hdc = BeginPaint (hwnd, &ps) ;
         si.cbSize = sizeof (si) ;
              si.fMask  = SIF_POS ;
      GetScrollInfo (hwnd, SB_HORZ, &si) ;
      iHorzPos=si.nPos;
      Draw(hwnd,lParam,cxClient, cyClient,iShape,iHorzPos,ifHorzPos,cxChar,noLine,cyChar);
      ifHorzPos=iHorzPos;
              EndPaint (hwnd, &ps) ;
              return 0 ;
    下面是Draw()函数的具体内容
    void Draw(HWND hwnd,LPARAM lParam,int  cxClient, int cyClient,int iShape,int iHs,int ifHs,int cw,int noLine,int ch)
    {   HDC hdc;
    //HPEN hPen;
        hdc=GetDC(hwnd);
    SetIsotropic (hdc, cxClient, cyClient) ;
    switch(iShape)
    {
    case 0: //如果是电压
    LineGraphYay( hdc,lParam );
        LineGraphx(hdc,lParam,apt2,iHs,ifHs,cw,noLine);
    SelectObject (hdc, CreatePen (PS_SOLID, 0, RGB (255, 0, 0))) ;
    LinePointYa(hdc);
    DeleteObject (SelectObject (hdc, GetStockObject (BLACK_PEN))) ;
    break; case 1: //如果是电流
    LineGraphLiuy( hdc,lParam,ch );
        LineGraphx(hdc,lParam,bpt2,iHs,ifHs,cw,noLine);
    SelectObject (hdc, CreatePen (PS_SOLID, 0, RGB (255, 0, 0))) ;
    LinePointLiu(hdc);
    DeleteObject (SelectObject (hdc, GetStockObject (BLACK_PEN))) ;
    break; case 2: //如果是电阻
    LineGraphZuy( hdc,lParam );
        LineGraphx(hdc,lParam,dpt2,iHs,ifHs,cw,noLine);
    SelectObject (hdc, CreatePen (PS_SOLID, 0, RGB (255, 0, 0))) ;
    LinePointZu(hdc);
    DeleteObject (SelectObject (hdc, GetStockObject (BLACK_PEN))) ;
    break; case 3: //如果是功率
    LineGraphGongy( hdc,lParam );
        LineGraphx(hdc,lParam,cpt2,iHs,ifHs,cw,noLine);
    SelectObject (hdc, CreatePen (PS_SOLID, 0, RGB (255, 0, 0))) ;
    LinePointGong(hdc);
    DeleteObject (SelectObject (hdc, GetStockObject (BLACK_PEN))) ;
    break;
    }

    ReleaseDC(hwnd,hdc);
    }
      

  5.   

    果然,好像你的paint只是画了可视区域部分。
      

  6.   

    既然是这样,那没有理由不用双缓冲了。既能提高绘图效率又不用抓图。
    双缓冲这里有介绍,http://www.vckbase.com/document/viewdoc/?id=1612
      

  7.   

    同意booklove(纳海行云) 
    用双缓冲,既能提高效率,又能根据位图大小方便控制滚动条。