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

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

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

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

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

请问有可能是什么原因?

(如需要我上传这个应用程序,我可以上传)
...全文
382 3 打赏 收藏 转发到动态 举报
写回复
用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 是 不能 跨 线程的 !
原tab控件,仿360开关控件版权归原作者! VB控件背景透明代码来自:新浪 “玄雨清风”的博客 感谢以上两位源代码作者 链接:http://pan.baidu.com/s/1hrAEXqG 密码:nfhc '-----------------------以下是转自博客的控件透明源代码(可透明至父窗体或桌面)------------- '添加一个用户控件UserControl,代如下: Option Explicit '实现用户控件UserControl的"伪透明" Private Type POINTAPI X As Long Y As Long End Type Private Type RECT Left As Long Top As Long Right As Long Bottom As Long End Type Private Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long Private Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Long, ByVal hDC As Long) As Long Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long Private Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long Private Declare Function ScreenToClient Lib "user32" (ByVal hwnd As Long, lpPoint As POINTAPI) As Long Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long Private Declare Function GetClientRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long Private Declare Function CreateCompatibleBitmap Lib "gdi32" (ByVal hDC As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hDC As Long) As Long Private Declare Function SelectObject Lib "gdi32" (ByVal hDC As Long, ByVal hObject As Long) As Long Private Declare Function DeleteDC Lib "gdi32" (ByVal hDC As Long) As Long Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long Private Const WM_ERASEBKGND = &H14 Private Const WM_PAINT = &HF Private Const SRCCOPY = &HCC0020 ' (DWORD) dest = source Public Event MouseDown(Button As Integer, Shift As Integer, X A

16,472

社区成员

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

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

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