几个API:
BeginPaint
GetClientRect(GetWindowRect)
CreateCompatibleBitmap -> 获得HBITMAP
位图写文件
EndPaint

解决方案 »

  1.   

    我创建的是htmlwiew 绘制显示都不是由我管理,我想把整个网页做成位图,但是无论我如何操作得到的总是视口的位图,我怎样才能得到整个视的位图呢,请大家踊跃发表意见,在线等候
      

  2.   

    GetWindowRect得到整个视的大小,创建屏幕DC,按视的东西抓。
      

  3.   

    可能是我说的不清楚,说白了 我就是想让程序自动拍照,照下整幅网页 存为.bmp图像,
    可现在无论我怎么照,都只能照到窗口中正在显示的一部分,各位,我怎样才能照下整个网页呢?帮我出出主意。
      

  4.   

    写窗口图像到BMP位图文件
     
     
            WINDOWS的窗口图像从本质上来说,是WINDOWS在内存DC上绘制的一幅图像,
    我们要将此图像存储起来,首先要获得WINDOWS窗口的区域大小,然后将区域中的图像
    存在一内存DC中,由于内存DC是与设备相关的位图,所以将它存储起来还要用DDBTODIB
    函数转换成DIB位图,最后再用WriteDIB函数转储成BMP文件。  BOOL WriteWindowToDIB( LPTSTR szFile, CWnd *pWnd )
    {
    CBitmap  bitmap;
    CWindowDC dc(pWnd);
    CDC  memDC;
    CRect rect; memDC.CreateCompatibleDC(&dc); pWnd->GetWindowRect(rect);
           //用窗口区域大小定义一个内存DC ,并将窗口图像暂存其中
    bitmap.CreateCompatibleBitmap(&dc, rect.Width(),rect.Height() ); CBitmap* pOldBitmap = memDC.SelectObject(&bitmap);
    memDC.BitBlt(0, 0, rect.Width(),rect.Height(), &dc, 0, 0, SRCCOPY); // 如果设备支持调色板,创建调色板
    CPalette pal;
    if( dc.GetDeviceCaps(RASTERCAPS) & RC_PALETTE )
    {
    UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256);
    LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];
    pLP->palVersion = 0x300; pLP->palNumEntries =
    GetSystemPaletteEntries( dc, 0, 255, pLP->palPalEntry ); // Create the palette
    pal.CreatePalette( pLP ); delete[] pLP;
    } memDC.SelectObject(pOldBitmap); // 转换 bitmap 到 a DIB
    HANDLE hDIB = DDBToDIB( bitmap, BI_RGB, &pal ); if( hDIB == NULL )
    return FALSE; // Write it to file
    WriteDIB( szFile, hDIB ); // Free the memory allocated by DDBToDIB for the DIB
    GlobalFree( hDIB );
    return TRUE;
      

  5.   

    怎么不理解我呢? 以上各位说的还是将窗口存为位图文件,而我想知道的是怎样将整个视存在一幅位图中,例如,我在chtmlview 中到用了 news.sina.com.cn 这一页 我想将全部的新闻标题都存为 位图,而不是窗口中可以看到的部分。
      

  6.   

    这个问题我现在回答第五遍了,
    LPTSTR CRemoteC::CopyScreenToBitmap(LPRECT lpRect)
    {HDC      hScrDC, hMemDC;      // 屏幕和内存设备描述表
    HBITMAP    hBitmap,hOldBitmap;    // 位图句柄
    int      nX, nY, nX2, nY2;      // 选定区域坐标
    int      nWidth, nHeight;      // 位图宽度和高度
    int      xScrn, yScrn;        // 屏幕分辨率
    // 确保选定区域不为空矩形
    if (IsRectEmpty(lpRect))  return NULL;//为屏幕创建设备描述表
    hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);//为屏幕设备描述表创建兼容的内存设备描述表
    hMemDC = CreateCompatibleDC(hScrDC);// 获得选定区域坐标
    nX = lpRect->left;
    nY = lpRect->top;
    nX2 = lpRect->right;
    nY2 = lpRect->bottom;// 获得屏幕分辨率
    xScrn = GetDeviceCaps(hScrDC, HORZRES);
    yScrn = GetDeviceCaps(hScrDC, VERTRES);//确保选定区域是可见的if (nX < 0) nX = 0;
    if (nY < 0) nY = 0;
    if (nX2 > xScrn) nX2 = xScrn;
    if (nY2 > yScrn) nY2 = yScrn;
    nWidth = nX2 - nX;
    nHeight = nY2 - nY;// 创建一个与屏幕设备描述表兼容的位图
    int *temp=new int(m_szResolution.Find("*"));
    char *pWidth=new char[10];
    char *pHeight=new char[10];
    strcpy(pWidth,m_szResolution.Mid(0,*temp));
    strcpy(pHeight,m_szResolution.Mid(*temp+1));
    delete temp;
    int nDestResWidth=atoi(pWidth);
    int nDestResHeight=atoi(pHeight);
    delete pWidth;
    delete pHeight;
    hBitmap = CreateCompatibleBitmap(hScrDC, nDestResWidth, nDestResHeight);// 把新位图选到内存设备描述表中
    hOldBitmap=(HBITMAP)::SelectObject(hMemDC, hBitmap);// 把屏幕设备描述表拷贝到内存设备描述表中
    StretchBlt(hMemDC, 0, 0, nDestResWidth, nDestResHeight,hScrDC, nX, nY,nWidth,nHeight,SRCCOPY);
    //得到屏幕位图的句柄
    hBitmap =(HBITMAP) ::SelectObject(hMemDC, hOldBitmap);
    //清除 
    DeleteDC(hScrDC);
    DeleteDC(hMemDC);
    char tmppath[MAX_PATH];
    char *tmpname=new char[MAX_PATH];
    GetTempPath(MAX_PATH,tmppath);
    GetTempFileName(tmppath,"AnyServer",0,tmpname);//获得一个唯一的临时文件名
      SaveBitmapToFile(hBitmap,tmpname);
    return tmpname;
    }
    int CRemoteC::SaveBitmapToFile(HBITMAP hBitmap, LPSTR lpFileName)
    {
    //我们也可以把屏幕内容以位图格式存到磁盘文件上.
        //lpFileName 为位图文件名
    HDC        hDC;          //设备描述表
      int        iBits;      //当前显示分辨率下每个像素所占字节数
    WORD      wBitCount;  //位图中每个像素所占字节数
        //定义调色板大小, 位图中像素字节大小,位图文件大小,写入文件字节数
    DWORD      dwPaletteSize=0,
          dwBmBitsSize,
      dwDIBSize, dwWritten;
    BITMAP    Bitmap;    //位图属性结构
    BITMAPFILEHEADER  bmfHdr;    //位图文件头结构
    BITMAPINFOHEADER  bi;        //位图信息头结构 
    LPBITMAPINFOHEADER lpbi;      //指向位图信息头结构
    HANDLE          fh, hDib, hPal,hOldPal=NULL;
                    //定义文件,分配内存句柄,调色板句柄
                        //计算位图文件每个像素所占字节数
        hDC = CreateDC("DISPLAY",NULL,NULL,NULL);
        iBits = GetDeviceCaps(hDC, BITSPIXEL)*GetDeviceCaps(hDC, PLANES);
        DeleteDC(hDC);
        if (iBits <= 1)
      wBitCount = 1;
    else if (iBits <= 4)
      wBitCount = 4;
    else if (iBits <= 8)
      wBitCount = 8;
    else if (iBits <= 32)
      wBitCount = 24;
        //计算调色板大小
    if (wBitCount <= 8)
          dwPaletteSize = (1 <<  wBitCount) *
          sizeof(RGBQUAD);
        //设置位图信息头结构
        GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
        bi.biSize            = sizeof(BITMAPINFOHEADER);
        bi.biWidth          = Bitmap.bmWidth;
        bi.biHeight          = Bitmap.bmHeight;
        bi.biPlanes          = 1;
        bi.biBitCount        = wBitCount;
        bi.biCompression      = BI_RGB;
        bi.biSizeImage        = 0;
        bi.biXPelsPerMeter    = 0;
        bi.biYPelsPerMeter    = 0;
        bi.biClrUsed        = 0;
        bi.biClrImportant      = 0;    dwBmBitsSize = ((Bitmap.bmWidth*wBitCount+31)/32)* 4*Bitmap.bmHeight ;
        hDib  = GlobalAlloc(GHND,dwBmBitsSize+dwPaletteSize+sizeof(BITMAPINFOHEADER));//为位图内容分配内存
        lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
        *lpbi = bi;
        hPal=(HPALETTE)::GetStockObject(DEFAULT_PALETTE);// 处理调色板  
        if (hPal)
        {
          hDC  = GetDC(NULL);
          hOldPal = SelectPalette(hDC,(HPALETTE)hPal, FALSE);
          RealizePalette(hDC);
        }
        // 获取该调色板下新的像素值
        GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight,
    (LPSTR)lpbi + sizeof(BITMAPINFOHEADER)
        +dwPaletteSize,
    (BITMAPINFO *)
        lpbi, DIB_RGB_COLORS);
        //恢复调色板  
        if (hOldPal)
        {
          SelectPalette(hDC,(HPALETTE) hOldPal, TRUE);
          RealizePalette(hDC);
          ReleaseDC(NULL, hDC);
        }
        //创建位图文件    
        fh = CreateFile(lpFileName, GENERIC_WRITE,0, NULL, CREATE_ALWAYS,
      FILE_ATTRIBUTE_NORMAL&brvbar;FILE_FLAG_SEQUENTIAL_SCAN, NULL);
        if (fh == INVALID_HANDLE_VALUE)
          return FALSE;
        // 设置位图文件头
        bmfHdr.bfType = 0x4D42;  // "BM"
        dwDIBSize    = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)
                  + dwPaletteSize + dwBmBitsSize;  
        bmfHdr.bfSize = dwDIBSize;
        bmfHdr.bfReserved1 = 0;
        bmfHdr.bfReserved2 = 0;
        bmfHdr.bfOffBits = (DWORD)sizeof
        (BITMAPFILEHEADER) 
          + (DWORD)sizeof(BITMAPINFOHEADER)
          + dwPaletteSize;
        // 写入位图文件头
        WriteFile(fh, (LPSTR)&bmfHdr, sizeof
                (BITMAPFILEHEADER), &dwWritten, NULL);
        // 写入位图文件其余内容
        WriteFile(fh, (LPSTR)lpbi, dwDIBSize, 
        &dwWritten, NULL);
        //清除  
        GlobalUnlock(hDib);
        GlobalFree(hDib);
        CloseHandle(fh);
    return TRUE;  
    }
    取rect的话只要GetWindowRect就行了
      

  7.   

    kingzai() 谢谢你不辞劳苦的为大家回答问题,而我想知道的是怎样将整个视存在一幅位图中,例如,我在CHtmlView 中到用了 http://news.sina.com.cn 这一页 我想将全部的新闻标题都存为 位图,而不是窗口中可以看到的部分。 
      

  8.   

    hbs_biscuit:
        偶也是来学习的,也是菜鸟,这样说我可无地自容.要想将全部的新闻标题都存为位图 ,如果按我这种方法的话。CopyScreenToBitmap(LPRECT lpRect)的输入参数是要取得矩形区域的大小,而要想将全部的新闻标题都存为 位图,这个可能比较困难,首先要计算各个标题的矩形区域,而且标题的位置大部分都是不固定的,如果取某个特定位置好办,查看当前页面的html文件即可。我的想法是写一个遍历,将位置比较固定的标题存成位图。
      

  9.   

    kingzai() 唉,就怪我的表达不好,我的意思并不是将特定的html页做成位图(sina.com.cn只是据个例子),由于某些原因我要做一个服务器,他将定期的访问数据库钟的web连接,将得到网页存为位图,我起初想到的是把网页显示出来然后拷屏,但这样做只能拷下显示器上可见的部分。如果我们手动的作这些工作,我们只要先拷一屏,然后拓东滚动条,在继续拷,然后将得到的n 幅图用图像处理软件处理,拼成一幅图即可,但是如果写一个程序模拟这些操作,就显得菜了点,我想找一个跟好的方法。
    我目前有一个想法-----直接调用 IWebBrowser2接口,这从技术上和代码工作量上都很困难
    正在考虑别的办法..........如果大家友好的想法,请不吝赐教!!!!
    也可以在另一张帖子上发表高见
    http://www.csdn.net/expert/topic/450/450843.shtm
      

  10.   

    可以这样做:
    1、先取得ie窗口的IID_IHTMLDOCUMENT2接口 。见http://support.microsoft.com/default.aspx?scid=kb;EN-US;q249232
    2。取得页面所有元素集合的接口 IHTMLElementCollection
    IHTMLElementCollection* pColl; 
    hr = pHTMLDocument2->get_all ( &pColl ); 
    3。将页面元素存成位图:
    采取我上面这种方法,不过先要的到页面元素的矩形区域
      

  11.   

    要是能替换html view的那个OnPaint就好,它应该是根据当前的ClientRect和它自己的DC来画的,我们自己计算画整个页面需要的Rect大小,再创建一个MemDC传进去,让它以为页面上所有的元素都可见,就都画到MemDC上了。
      

  12.   

    to DoItFreely(Freely):我也是这个想法,可是刚才听高人说Onpaint替了也没用,CHtmlView继承了CFormView 而IWebBrowser只是CFormView上的一个控件被封装了