如题,在VC中,通过右键菜单截取当前窗口的图像到剪切板上?另问:如果当前窗口在windows窗口显示不全,会截取到么?怎么截?

解决方案 »

  1.   

    只说说思路:)方法一:1、创建一个内存DC和一个位图句柄(位图大小与窗口大小等大),并将二者建立关联;
    2、使用BitBlt方法将窗口DC的内容拷贝到内存DC;
    3、将位图内容拷贝至剪贴板,或直接存储为位图文件。如果当前窗口显示不全,比如超出屏幕边缘,或者被其它窗口覆盖,则无法抓到全图。
      

  2.   

    方法二:1、创建一个内存DC和一个位图句柄(位图大小与窗口大小等大),并将二者建立关联;
    2、使用CWnd::PrintWindow方法将窗口绘制到内存DC;
    3、将位图内容拷贝至剪贴板,或直接存储为位图文件。
      

  3.   

    用PrintWindow打印窗口
    至于操作剪切板你可以参考以下代码
    if(!OpenClipboard())
    return; //获取谱图图像
    GetWaveGraphy(); EmptyClipboard();
    SetClipboardData(CF_BITMAP, (HBITMAP)m_bitmapGraphy); 
    CloseClipboard();
      

  4.   

        CRect   rect;   
        GetClientRect(&rect);  
        CDC *hdc = GetDC();
        HDC memDC = CreateCompatibleDC(*hdc); // 绘图内存DC
        HBITMAP mybitmap = CreateCompatibleBitmap(*hdc, rect.Width(), rect.Height());
        SelectObject(memDC,mybitmap);    BitBlt(memDC,0,0, rect.right-rect.left+1, rect.bottom-rect.top+1, *hdc,0,0,SRCCOPY);       if(OpenClipboard())
        {
            EmptyClipboard();
            SetClipboardData(CF_BITMAP, (HBITMAP)mybitmap); 
            CloseClipboard();
        }我是这样截取的  已经可以获得了 、但我是用右键菜单截取的,菜单也会显示出来,如何去掉菜单呢?
      

  5.   

        HDC hDCMem = CreateCompatibleDC(NULL);
        RECT rect;
        HBITMAP hBmp = NULL;
        HDC hDC=::GetDC(m_hWnd);   
        ::GetClientRect(m_hWnd, &rect);    hBmp = CreateCompatibleBitmap(hDC, rect.right - rect.left, rect.bottom - rect.top);
        ::ReleaseDC(m_hWnd, hDC );    HGDIOBJ hOld = SelectObject(hDCMem, hBmp);    ::PrintWindow(m_hWnd, hDCMem, 0 );  
        SelectObject(hDCMem, hOld);
        DeleteObject(hDCMem);    if (OpenClipboard())
        {
            EmptyClipboard();  
            SetClipboardData(CF_BITMAP, hBmp);
            CloseClipboard();
        }可以去掉菜单了 但被windows挡住的是黑色的  如何解决呢?
      

  6.   

    右键菜单应用时用TrackPopupMenu弹出的,菜单关闭后会返回(类似于模态对话框阻塞在这儿的),如果菜单里选择的是“截屏”,那么TrackPopupMenu返回后你再运行你的截屏函数就可以了
      

  7.   


    6楼 7楼的方法都不能截取被windows挡住的部分?  还有别的方法么?
      

  8.   


    这代码应该可以的
    下面代码是我以前用的,窗口不在最前面也可以截图,你可以试试:
    菜单遮挡的问题按我8楼的方法试试看,等TrackPopupMenu返回了再截图
    RECT drt;
    HWND dWnd = m_hWnd;
    ::GetWindowRect(dWnd,&drt);
    HDC dhdc = ::GetDC(dWnd);
    HDC memhdc = CreateCompatibleDC(dhdc);
    HBITMAP membmp = (HBITMAP)CreateCompatibleBitmap(dhdc,drt.right-drt.left,drt.bottom-drt.top);
    (HBITMAP)SelectObject(memhdc,membmp);
    BitBlt(memhdc,0,0,drt.right,drt.bottom,dhdc,0,0,SRCCOPY);
      

  9.   

    To 10楼  and 11楼你们的代码都是一样的问题 就是当窗口不在Windows显示区域,有部分不在显示器内,截取的那部分就都是黑色的 
      

  10.   

    是什么系统
    我项目里就是这么用的
    只是没有把全部代码贴出来
    但是原理就是这样
    不过我的操作系统是xp
    另外这篇博客里我也是用类似的方法获取窗口内容生成打印预览的
    http://blog.csdn.net/xianglitian/archive/2010/10/23/5960970.aspx
      

  11.   

    我的也是XP你截取的窗口如果在PC显示器下面,就是没有全部显示也能截取全部?我没显示的部分是黑色的
      

  12.   

    To xianglitian7楼是我写的代码,您看看哪的问题?哪里错了?
      

  13.   

    To xianglitian7楼是我写的代码,您看看哪的问题?哪里错了?
      

  14.   


    我是MDI程序,被主窗口的一些窗体遮挡也是不行的,只能全部显示才可以
      

  15.   

    我试你的代码了,如下图,在1,2是不能截取全的,只有3可以。图是我直接print显示器窗口的。代码是:
    CRect rectWnd;
        CBitmap *pOldBitmap;
        CDC* pDC = GetDC();
        CDC* pMemDC = new CDC;    //获取窗口位图
        GetWindowRect(rectWnd);
        CBitmap bitmapPrint;
        bitmapPrint.DeleteObject();
        bitmapPrint.CreateCompatibleBitmap(pDC, rectWnd.Width(), rectWnd.Height());
        pMemDC->CreateCompatibleDC(pDC);
        pOldBitmap = pMemDC->SelectObject(&bitmapPrint);
        PrintWindow(pMemDC, 0);    pMemDC->SelectObject(pOldBitmap);    //释放内存
        ReleaseDC(pMemDC);
        delete pMemDC;    if (OpenClipboard())
        {
            EmptyClipboard();
            SetClipboardData(CF_BITMAP, bitmapPrint);
            CloseClipboard();
        }
      

  16.   

    下载我的“ScrollBitmap.rar”参考,可以满足你的要求
      

  17.   

    HDC hDCMem = CreateCompatibleDC(NULL);
      RECT rect;
      HBITMAP hBmp = NULL;
      HDC hDC=::GetDC(m_hWnd);   
      ::GetClientRect(m_hWnd, &rect);  hBmp = CreateCompatibleBitmap(hDC, rect.right - rect.left, rect.bottom - rect.top);
      ::ReleaseDC(m_hWnd, hDC );  HGDIOBJ hOld = SelectObject(hDCMem, hBmp);  ::PrintWindow(m_hWnd, hDCMem, 0 );   
      SelectObject(hDCMem, hOld);
      DeleteObject(hDCMem);  if (OpenClipboard())
      {
      EmptyClipboard();   
      SetClipboardData(CF_BITMAP, hBmp);
      CloseClipboard();
      }
      

  18.   


    我这不是一个dialog,而是在视图上画的,你的代码我出来的只是一个什么都没有的窗口,难道我编错了  
    能把你的主要代码贴一下么?
        UINT ID=::GetDlgCtrlID(m_hWnd);
        // afxDump << ID << " ID\n";
        // size
        CRect rc;
        if(m_hWnd == 0)
        {
            ID=0;
            GetWindowRect(&rc);// the dialog
        }
        else
        {
            ::GetWindowRect(m_hWnd, &rc);
        }
        // create dc
        CClientDC dc(this);
        CDC dcMem;
        dcMem.CreateCompatibleDC(&dc);
        // create empty bmp
        HBITMAP bmp=CreateCompatibleBitmap(dc /* not dcMem */, rc.Width(),rc.Height());
        dcMem.SelectObject(bmp);
        this->SendMessage(WM_PRINT,(WPARAM)dcMem.m_hDC,
            (LPARAM)(PRF_NONCLIENT | PRF_CHILDREN | PRF_CLIENT | PRF_ERASEBKGND | PRF_OWNED));
        // move bmp to clipboard
        CBitmap *pbmp=dcMem.GetCurrentBitmap();
        OpenClipboard();
        EmptyClipboard();
        SetClipboardData(CF_BITMAP,pbmp->GetSafeHandle());
        CloseClipboard();
        //
        DeleteObject(bmp);
      

  19.   

    http://www.xuyibo.org/kb/282.htm
    看下这个,希望对你有帮助
      

  20.   


    也是通过BitBlt画在实例上的
      

  21.   


    不是OnDraw  借用一个前辈的代码,直接画在视图类上   学习完会总结的   
      

  22.   

    你的代码我出来的只是一个什么都没有的窗口,不是有2个按钮吗,“open”可以打开一个bmp,在项目下有一个“金山词霸”
      

  23.   


    呵呵,难不成是“当前窗口的图像”这个说法造成的误会,LZ实际想做的应该是将视图客户区中的显示内容变成位图数据、放到剪贴板上,是这样么?如此的话就更简单了,DC操作而已。
      

  24.   

    前提是绘制流程是独立的,而DC作为参数传递(设计模式中的策略模式),
    这样的话只要传入内存DC指针或句柄,执行一遍绘制流程就可以了。