void  CMainFrame::DrawTitleBar(CDC *pDC)
{

CRect rectWnd;
CDC* pMemDC=new CDC;
CBitmap bitmapTemp, *pOldBitmap;
int nWidth, nHeight; GetWindowRect(&rectWnd);

nWidth = rectWnd.Width();
nHeight = GetSystemMetrics(SM_CYSIZE) + GetSystemMetrics(SM_CYFRAME)+1; //创建位图内存
bitmapTemp.CreateCompatibleBitmap(pDC, nWidth, nHeight);
pMemDC->CreateCompatibleDC(pDC);
pOldBitmap=pMemDC->SelectObject(&bitmapTemp); //绘制底色
pMemDC->FillSolidRect(0, 0, nWidth, nHeight, m_clrMain);    // GDI+贴图片
ScreenToClient(rectWnd);       //屏幕坐标转换客户区坐标
HDC tc=GetDC()->m_hDC;
Graphics graphics(tc);         //创建需要的DC,取得DC句柄
Image image(_T("titlebar.png"),false);    // 图片的路径
graphics.DrawImage(&image,rectWnd.left,rectWnd.top,rectWnd.Width(),rectWnd.Height());  //画按钮
m_tlbtnClose.DrawButton(pMemDC, 8);
m_tlbtnMin.DrawButton(pMemDC,56);
if(flag==0)
{
   m_tlbtnRes.DrawButton(pMemDC,32);
}
else
{
    m_tlbtnMax.DrawButton(pMemDC,32);
}
  
  //绘制标题
  DrawCaption(pMemDC); 
  pDC->BitBlt(0, 0, nWidth, nHeight, pMemDC, 0, 0, SRCCOPY);
  pMemDC->SelectObject(pOldBitmap);
  ReleaseDC(pMemDC);
  delete pMemDC;
}

解决方案 »

  1.   

    删除ReleaseDC(pMemDC);
    因为delete pMemDC;会释放DC的另外CreateCompatibleDC对应的是DeleteDC
      

  2.   

    之前只是改变标题栏颜色,没出现异常。现在想给他贴png图片就加了下面的代码    // GDI+贴图片
    ScreenToClient(rectWnd); //屏幕坐标转换客户区坐标
    HDC tc=GetDC()->m_hDC;
    Graphics graphics(tc); //创建需要的DC,取得DC句柄
    Image image(_T("titlebar.png"),false); // 图片的路径
    graphics.DrawImage(&image,rectWnd.left,rectWnd.top,rectWnd.Width(),rectWnd.Height());  
    然后 就出现一个对话框提示 0x7c93300e8处未处理的异常:0xC0000005:读取位置0x00000010时发生访问冲突。
      

  3.   


    使用GDI+前要初始化,GdiplusStartup
      

  4.   

    to:stjay
    GDI+初始化在头文件里面有,在里面加了以后还是上面的错误。
    追踪到
    Image::Image(
        IN const WCHAR* filename,
        IN BOOL useEmbeddedColorManagement
        )
    {
        nativeImage = NULL;
        if(useEmbeddedColorManagement)
        {
            lastResult = DllExports::GdipLoadImageFromFileICM(
                filename, 
                &nativeImage
            );
        }
        else
        {      
            lastResult = DllExports::GdipLoadImageFromFile(
                filename, 
                &nativeImage
            );
        }
    }
    是不是文件路径写错了?还是我的逻辑写错了?
      

  5.   

    Image image(_T("titlebar.png"),false); // 图片的路径路径不正确,导致image对象是NULL,无法画图
    用绝对路径试试
      

  6.   

    我看你绘制按钮用的是 CMainFrame 的CDC, 我估计这里会有问题。
      

  7.   

    ...
    pMemDC->CreateCompatibleDC(pDC); //你用CMainFrame的CDC创建了一个兼容DC
    ...
    m_tlbtnClose.DrawButton(pMemDC, 8);//然后你将这个DC用到按钮的绘制中。
    ...
    Delete pMemDC ;//不知道你的DrawButton 是如何实现的。
    //绘图的消息通常 是Post出去的。
    //在不知道按钮是否完成绘制的情况下,你又删除了该DC我估计问题出在这里。
      

  8.   

    对,但是按钮没问题,就是想用GDI+画图,前面都是GDI画的需要设备描述表什么的,而GDI+不用,是不是之间有什么冲突?
      

  9.   

    刚才用断点追踪  
    Graphics graphics(tc); //创建需要的DC,取得DC句柄  tc出问题了。怎么回事?gdi和gdi+不太了解,求高人指点!
      

  10.   

    我的建议是这样:HWND     hWndBtnClose = m_tlbtnClose;
    WNDPROC  btnProc      = SetWindowLong (hWndBtnClose, GWL_WNDPROC, (LONG)MyCloseBtnProc);
    SetWindowLong (hWndBtnClose, GWL_USERDATA, (LONG)btnProc);
    //============================================
    // MyCloseBtnProc 函数
    LRESULT CALLBACK MyCloseBtnProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        switch (msg)
        {
        case WM_PAINT:
            {
                PAINTSTRUCT ps;
                HDC hDC = BeginPaint (hWnd, &ps);            //在这里绘制安钮
                  绘制的代码
                  //=============            EndPaint (hDC, &ps);
             }
           }     
            return CallWindowProc ( (WNDPROC)GetWindowLong (hWnd, GWL_USERDATA),
                                   hWnd, msg, wParam, lParam);
    }
          
                     
      

  11.   


    HDC tc = GetDC ()->m_hDC; //这句取的是窗口客户区坐标。你应该取窗口坐标。
      

  12.   

    to (hb19820102)
    我这样做按钮显示没问题,你的那种方法我会学习的。现在项目经理催进度,按钮改没时间,我想应该不会影响贴图的吧?
      

  13.   

    要么你把代码发给我:[email protected]
      

  14.   

    HDC tc=GetDC()->m_hDC; 这句不对
    应是HDC tc=pDC->m_hDC;
      

  15.   

    改了以后还是不行,断点追踪每次到Graphics graphics(tc); 就出问题了、
      

  16.   

    Image image(_T("E:\\title.png"),false);    // 图片的路径
    断点现在这一步出错了。是不是添加的路径不对?
    Image::Image(
        IN const WCHAR* filename,
        IN BOOL useEmbeddedColorManagement
        )
    {
        nativeImage = NULL;
        if(useEmbeddedColorManagement)
        {
            lastResult = DllExports::GdipLoadImageFromFileICM(
                filename, 
                &nativeImage
            );
        }
        else
        {      
            lastResult = DllExports::GdipLoadImageFromFile(
                filename, 
                &nativeImage
            );
        }
    }
    构造函数没有执行,直接跳过去了。
      

  17.   

    if (message == WM_MOVE || message == WM_NCACTIVATE || message == WM_NOTIFY)
     {
      CDC* pWinDC = GetWindowDC();
      if (pWinDC)
       DrawNCFrame(pWinDC);
       ReleaseDC(pWinDC); // 你先把这行去掉,试下。可能是绘制前,句柄被提前释放了。
     }
      

  18.   

    我改了以后还是出错啊?是不是后面还有什么不对?
    Image image(_T("E:\\title.png"),false); 断点到这后再往下执行就报错了,image的构造函数直接跳过去了。
      

  19.   

    项目挺大的,跟踪断点到Graphics graphics(tc); 过去后,graphics成了000000000,错误出在这里。
      

  20.   


    跟踪到断点 Graphics graphics(tc)时,tc有效吗?
      

  21.   

    恩,tc是有效的,graphics无效。qq多少,我加你qq联系你吧。
      

  22.   

    HDC tc=GetDC()->m_hDC;
    改为:HDC tc = pMemDC->m_hDC 试试