none
关于CDC::GetCurrentBitmap 返回黑色bitmap RRS feed

  • 问题

  • 最近在用mfc画背景时遇到一个问题

    本来准备在dialog首次调用onpaint时通过获取CDC::GetCurrentBitmap获取到当前的背景

    后面再erase时就用这张图片刷新背景

    现在遇到的问题是大部分测试机台没有问题,但其中两台win7 64位和win server 2008均遇到GetCurrentBitmap获取到的是一张全黑的图片

    目前完全没有方向,请教各位大大有没有遇到过类似问题

    2014年7月30日 3:30

全部回复

  • 你的程序使用什么机子和什么版本的VS做的,测试机都是什么版本的VS?

    2014年7月31日 11:46
  • VS2010(带的mfc库是100版本的) 和VS2012(带的mfc库是110的)都试过

    测试机台没有安装vs

    现在win7那台没问题了

    2008还是不行


    2014年8月1日 3:26
  • 你好:

            很高兴你的问题在win7上解决了,你能提供一下你的解决方案给可能有同样问题的人吗,同时可能会给我们思路来解决你在win server 2008

    上的问题。

            首先对于你说显示的图片是全黑的,我认为应该是位图对象没有选上,默认的位图对象的像素都是0,导致颜色全黑。我认识的win server

    2008 系统一般用作于服务器,对程序的运行需求比较严格。所以就是看看Win2008server的一些安全性设置是否对程序有影响

    有个DEP(数据执行保护)的设置,请对比下Win7Win2008是否一样DEP的设置在系统属性-》高级-》性能-》设置-》数据执行保护

           如果上述方法无效但测试机的话条件允许,也许你能在win server 2008上装个VS来调试你的代码,通过设置断点查看一些关键的变量的值或

    错误的代码来排除error。或者你能提供你的一些详细的信息像什么时候或什么事件产生重绘背景或共享你的代码在Onedrive上让我重现你的问题

    从而帮你调试。

    Shu Hu


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2014年8月1日 7:07
  • win7的测试机台复制不到现象,不知道是何原因

    win server 2008 DEP设定为Turn on DEP for essential Windows Programs and services only仍然会有问题

    另外我手上还有机台win server 2012的,都可以正常work 

    代码大概是这样的

    void CMyTabCtrl::OnPaint() { PAINTSTRUCT ps; HDC hDC=::BeginPaint(this->GetSafeHwnd(),&ps); CDC *pDc=CDC::FromHandle(hDC); InitBackground(pDc); ... ... ::EndPaint(this->GetSafeHwnd(),&ps); } void CMyTabCtrl::InitBackground(CDC* pDc) {

    //init CMyTabCtrl::cbitmap if(cbitmap.m_hObject == NULL) { CRect crect; this->GetWindowRect(&crect); ::AfxGetMainWnd()->ScreenToClient(crect); HBITMAP hbm = CImageRes::CopyBitmap((HBITMAP)(pDc->GetCurrentBitmap())->m_hObject , crect); cbitmap.Attach(hbm); } } void CMyTabCtrl::MyDrawBackGround(CDC* pDc, CRect wRect) { if(cbitmap.m_hObject != NULL) {//drawbackground CDC dcMemoryback; dcMemoryback.CreateCompatibleDC(pDc); SelectObject(dcMemoryback,cbitmap); pDc->BitBlt(0, 0, wRect.Width(), wRect.Height(), &dcMemoryback, 0, 0, SRCCOPY); dcMemoryback.DeleteDC(); } }

    BOOL CMyTabCtrl::OnEraseBkgnd(CDC* pDC)
    {
    CRect wRect;
    this->GetWindowRect(&wRect);
    this->ScreenToClient(wRect);

    MyDrawBackGround(pDC,wRect);
    return 1;
    //return CTabCtrl::OnEraseBkgnd(pDC);
    }



    • 已编辑 leanliu 2014年8月1日 9:49 DEP
    2014年8月1日 9:38
  • 你好,不好意思我这无法重现你的问题,但我想提一些意见供你参考:

    首先确认下你所用的API在不同系统下的行为是否一致,如果一致,那么我认为你的代码是没问题的,如果你的程序只有在win server里出现,而win server 2008是过去微软vista系统的服务器版本,所以我认为可能是Desktop Window Manager的问题,是微软vista遗留下来的应用程序兼容性选项的问题。我建议你用WM_NCPAINT消息来取代WM_PAINT,你可以试一试。有什么问题我很高兴能为你解答,希望这能够帮助到你。


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.


    • 已编辑 Shu 2017 2014年8月1日 12:01
    • 已标记为答案 leanliu 2014年8月4日 8:11
    • 取消答案标记 leanliu 2014年8月4日 8:12
    2014年8月1日 12:00
  • 无法重现是说在win server上也复制不到么

    使用WM_NCPAINT替换WM_PAINT也不行

    另外有深入debug下CDC::GetCurrentBitmap

    其主要是通过::GetCurrentObject(HDC hdc,UINT uObjectType)获取HDIOBJ

    发现出问题时返回的句柄地址都是一个固定的值(0x0105004C)

    后面再用::GetObject时返回0,获取不到相应的信息(GetLastError也是返回0)


    • 已编辑 leanliu 2014年8月4日 8:21
    2014年8月4日 8:20