截取菜单,即将当前所选择的菜单截取下来,截图的大小为菜单的大小。不被菜单所覆盖的地方为白色。
例如:____________
      |New       |
      |Open Open1|
      |Save Open2|
      |     Open3|
      |__________|
注:框线之中为所截图的菜单,也是当前所选择的菜单
本人不解之处:
1.有的窗口单不是标准菜单,不能获取其句柄。
2.一般在弹出菜单前,会有一WM_ENTERMENULOOP消息,但有的窗口似乎没有,例如firefox
感谢各位不吝赐教。谢谢。

解决方案 »

  1.   

    截取WM_INITMENUPOPUP消息时自然就拿到了菜单句柄,然后就可以截图将DC选进来
      

  2.   

    您好,关键是有的非标准菜单它不会产生WM_INITMENUPOPUP(例如firefox),没有办法获取句柄。另如何将DC选进来?请详细讲述一下。谢谢。
      

  3.   

    你只需要一个RECT即可
    CRect rect(0, 0,m_xScreen,m_yScreen);
    m_pBitmap=CBitmap::FromHandle(CopyScreenToBitmap(&rect));
    CopyScreenToBitmap是一个在网上广为流传的函数
    HBITMAP CTestDlg ::CopyScreenToBitmap(LPRECT lpRect,BOOL bSave)
    //lpRect 代表选定区域
    {
    HDC       hScrDC, hMemDC;      
    // 屏幕和内存设备描述表
    HBITMAP    hBitmap, hOldBitmap;   
    // 位图句柄
    int       nX, nY, nX2, nY2;      
    // 选定区域坐标
    int       nWidth, nHeight;

    // 确保选定区域不为空矩形
    if (IsRectEmpty(lpRect))
    return NULL;
    //为屏幕创建设备描述表
    hScrDC = CreateDC(_T("DISPLAY"), NULL, NULL, NULL);

    //为屏幕设备描述表创建兼容的内存设备描述表
    hMemDC = CreateCompatibleDC(hScrDC);
    // 获得选定区域坐标
    nX = lpRect->left;
    nY = lpRect->top;
    nX2 = lpRect->right;
    nY2 = lpRect->bottom;

    //确保选定区域是可见的
    if (nX < 0)
    nX = 0;
    if (nY < 0)
    nY = 0;
    if (nX2 > m_xScreen)
    nX2 = m_xScreen;
    if (nY2 > m_yScreen)
    nY2 = m_yScreen;
    nWidth = nX2 - nX;
    nHeight = nY2 - nY;
    // 创建一个与屏幕设备描述表兼容的位图
    hBitmap = CreateCompatibleBitmap
    (hScrDC, nWidth, nHeight);
    // 把新位图选到内存设备描述表中
    hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);
    // 把屏幕设备描述表拷贝到内存设备描述表中
    if(bSave)
    {
    //创建军兼容DC,当bSave为中时把开始保存的全屏位图,按截取矩形大小保存
    CDC dcCompatible;
    dcCompatible.CreateCompatibleDC(CDC::FromHandle(hMemDC));
    dcCompatible.SelectObject(m_pBitmap);
            
    BitBlt(hMemDC, 0, 0, nWidth, nHeight,
    dcCompatible, nX, nY, SRCCOPY);

    }
    else
    {
    BitBlt(hMemDC, 0, 0, nWidth, nHeight,
    hScrDC, nX, nY, SRCCOPY);
    }

    hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap);
    //得到屏幕位图的句柄
    //清除 
    DeleteDC(hScrDC);
    DeleteDC(hMemDC);

    if(bSave)
    {

    if (OpenClipboard()) 
    {
    //清空剪贴板
    EmptyClipboard();
    //把屏幕内容粘贴到剪贴板上,
    //hBitmap 为刚才的屏幕位图句柄
    SetClipboardData(CF_BITMAP, hBitmap);
    //关闭剪贴板
    CloseClipboard();
    }
    }
    // 返回位图句柄

    return hBitmap;
    }
    通过一个RECT得到一个Bitmap
    在DC中通过SelectObject把这个Bitmap选进去
      

  4.   

    --------------------------------------------------
    很感谢你的答复。但拷贝位图不是这个问题的中心,这个问题的关键是如何获取菜单的面积大小和坐标。
    你就是你所提的CopyScreenToBitmap的参数。
    对于标准菜单可以获取菜单句柄,然后计算出菜单面积,但有的菜单不是标准菜单,也就是说不能获取句柄。不知你有没有关于如何取得菜单面积的好建议?谢谢。