为什么GetDC(hwnd),获取在hdc,用BitBlt传送后是空的?

screen12 2017-12-14 01:56:38
有一个应用程序,叫sabaki,在win10下,运行它以后,它有一个棋盘窗口,我用

HDC hdc = GetDC(hwnd); 获取它的窗口dc

再用BitBlt传送到另一个图像中,再把这个图像显示出来,结果发现,图像全黑。是空的。

但是,奇怪的是,在win7下不是这样的,win7下正常,它的hdc的图像可以用BitBlt显示出来,而win10下就不行。

请问有可能是什么原因?

(如需要我上传这个应用程序,我可以上传)
...全文
733 3 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
worldy 2017-12-15
  • 打赏
  • 举报
回复
GetDC在非WM_PAINT消息时使用,在WM_PAINT消息时,使用BenginPaint获取DC
zgl7903 2017-12-15
  • 打赏
  • 举报
回复
试试拷贝屏幕,然后截取其中的部分

BOOL CopyWnd(HWND hSrcWnd, HWND hDstWnd, BOOL bClientOnly)
{
  BOOL bRet = FALSE;

  HWND hDeskTop = NULL;
  HDC hSrcDC = NULL;
  HDC hMemDC = NULL;
  HBITMAP hMemBmp = NULL;
  HGDIOBJ hOldBmp = NULL;
  HDC hDstDC = NULL;
  
  do
  {
    hDeskTop = GetDesktopWindow(); //获取桌面句柄 

    //检测句柄有效性
    if(!(hDeskTop 
      && (hSrcWnd == NULL || IsWindow(hSrcWnd))
      && IsWindow(hDstWnd)
      && 1))
    {
      bRet = -1;
      break;
    }
    
    //桌面DC
    hSrcDC = GetDC(hDeskTop);
    //Get Widht & Height
    int nWidth = GetDeviceCaps(hSrcDC, HORZRES);
    int nHeight = GetDeviceCaps(hSrcDC, VERTRES);
  
    //创建内存DC
    hMemDC = CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
    if(hMemDC == NULL)
    {
      bRet = -2;
      break;
    }
    
    //创建内存位图
    hMemBmp = CreateBitmap(nWidth, nHeight, 1, 32, NULL);
    if(hMemBmp == NULL)
    {
      bRet = -3;
      break;
    }
    //选入内存位图
    hOldBmp = SelectObject(hMemDC, hMemBmp);
    
    /*    
    if(! PrintWindow(hSrcWnd, hMemDC, 0))
    {
      bRet = -4;
      break;
    }
    */
    //拷贝桌面DC
    if(!BitBlt(hSrcDC, 0, 0, nWidth, nHeight, hMemDC, 0, 0, SRCCOPY))
    {
      bRet = -4;
      break;
    }    

    //获取贴图区域坐标
    RECT rcSrc, rcDst;
    if(hSrcWnd == NULL) //空时默认为整个屏幕
    {
      rcSrc.left = rcSrc.top = 0;
      rcSrc.right = nWidth, rcSrc.bottom = nHeight;
    }
    else if(bClientOnly)
    {
      GetClientRect(hSrcWnd, &rcSrc);
      POINT lt = { rcSrc.left, rcSrc.top};
      POINT rb = { rcSrc.right, rcSrc.bottom};
      ClientToScreen(hSrcWnd, <);
      ClientToScreen(hSrcWnd, &rb);
      rcSrc.left = lt.x, rcSrc.top = lt.y;
      rcSrc.right = rb.x, rcSrc.bottom = rb.y;
    }
    else
    {
      GetWindowRect(hSrcWnd, &rcSrc);
    }
    GetClientRect(hDstWnd, &rcDst);

    hDstDC = GetDC(hDstWnd);
    if(hDstDC == NULL)
    {
      bRet = -5;
      break;
    }

    //设置缩放半色调
    int nOldMode = SetStretchBltMode(hDstDC, HALFTONE);
    //缩放贴图
    StretchBlt(hDstDC, 
      0, 0, rcDst.right-rcDst.left, rcDst.bottom-rcDst.top,
      hMemDC, 
      rcSrc.left, rcSrc.top, rcSrc.right-rcSrc.left, rcSrc.bottom-rcSrc.top,
      SRCCOPY);
    //恢复缩放模式
    SetStretchBltMode(hDstDC, nOldMode);

    bRet = TRUE;

  }while(0);

  //结束清理
  if(hDstWnd && hDstDC)
  {
    ReleaseDC(hDstWnd, hDstDC);
    hDstDC = NULL;
  }
  if(hMemDC && hOldBmp)
  {
    SelectObject(hMemDC, hOldBmp);
  }
  if(hMemBmp)
  {
    DeleteObject(hMemBmp);
    hMemBmp = NULL;
  }
  if(hMemDC)
  {
    DeleteDC(hMemDC);
    hMemDC = NULL;
  }
  if(hDeskTop && hSrcDC)
  {
    ReleaseDC(hDeskTop, hSrcDC);
    hSrcDC = NULL;
  }

  return bRet;
}

void CDlg1Dlg::OnButton1()
{
  CString szHwnd;
  GetDlgItemText(IDC_EDIT1, szHwnd);
  HWND hSrcWnd = (HWND)_ttoi64(szHwnd); //窗口句柄
  CopyWnd(hSrcWnd, GetDlgItem(IDC_STATIC1)->m_hWnd, 0);
}

schlafenhamster 2017-12-15
  • 打赏
  • 举报
回复
据说 DC 是 不能 跨 线程的 !

16,548

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • AIGC Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧