Dialog已经正常显示,然后通过timer,在这个Dialog类中的某个成员函数中,想要获得dialog的DC进行处理。
void CRunDlg::Start()
{
CPaintDC * pdc = (CPaintDC *) GetDC();
...
}
Debug版中没有问题,release版中却过不去了。
而且关键是我在GetDC前插入一个AfxMessageBox,能弹出来,在GetDC之后插入AfxMessageBox,就弹不出来了。就算是GetDC失败也应该是返回NULL啊。
然后尝试了:
CDC * pdc = GetDC();
CPaintDC dc(this);
无一例外……

解决方案 »

  1.   

    直接用API试试看PS:这么多分。拿代码我帮你调好了
      

  2.   

    前几天我写的一个程序和你的一个样子,Debug没有问题,release问题莫名其妙
    后来发现是内存泄露搞得鬼,你看看你的程序是不是这方面的原因
      

  3.   

    我想是指不是这句代码出现的问题,肯定是其他的代码的原故。
    但是我建议:
    你所有的定时器里面的代码都在WM_PAINT消息函数中写,然后用定时器更新不同的RECT是否可以?
      

  4.   

    而且关键是我在GetDC前插入一个AfxMessageBox,能弹出来,在GetDC之后插入AfxMessageBox,就弹不出来了。奇怪的是,这个函数是没有继续执行下去了,但是程序并没有抱错退出,也没有失去响应,还能操作……内存泄露我还是很小心的,查过两次了,应该不是。
      

  5.   

    timer是在OnPaint中调用的。“然后用定时器更新不同的RECT是否可以”什么意思?
      

  6.   

    直接用 ::GetDC() 或 ::BeginPaint() 有没有试过?
      

  7.   

    void CRunDlg::Start()
    {
    CPaintDC * pdc;
    try{
    pdc = (CPaintDC *) GetDC();
    }
    catch (CException e) {
    char errrr[1024]; e.GetErrorMessage(errrr,1024);
    writeLog(errrr);
    }
    }居然写不出来。faint用过API了,
    pdc = (CPaintDC *) ::GetDC(this->GetSafeHwnd());
    过是能过,可是bitblt不到dialog的DC上。
      

  8.   

    鹦鹉啊,我以前也是这么用的,没出过问题。我想的是跟小兔子、哈雷想的差不多,应该是在前面的代码导致的冲突。不过还没有想到什么东西会跟GetDC冲突。
      

  9.   

    用DebugView看看是哪边退出的。
      

  10.   

    在release状态下,选择菜单项的"project"->"setting",切换到link选项页,选中"Generate debug info"项。可以在release下调试应用程序,调一下程序看看。至于debug与release的区别,可能是由于在进入这个函数的时候debug对一些变量及环境信息进行了初始化,而release没有初始化,所以会导致出错。解决办法就是不要在debug下编写调试程序,而采用release状态编写调试程序,方法就是我最开始说的那个样子,你可以先试试。
      

  11.   

    DebugView怎么用?而且这个并没有引起程序的退出,只是CRunDialog的一些继承的成员函数,比如GetDC、GetClientRect等不能用了。
      

  12.   

    刚刚忘了还有C++选项页的“debug info”里面选择“program database”,不要让他选中NONE。
      

  13.   

    用完GetDC后记得用ReleaseDC,估计是这个引起的。
      

  14.   

    真的没有内存泄露。需要用到new的地方都在OnInitDialog中,然后一直存在,直到析构的时候才销毁。单步调试的方法试过了,出来的汇编码和程序段对不上号,还没有到启动计时器就over了。
      

  15.   

    Anikan(皮皮鱼),我还没有能够GetDC呢~~而且除了GetDC,GetClientRect之类的都不能用。
      

  16.   

    Since only five common device contexts are available at any given time, failure to release a device context can prevent other applications from accessing a device context
      

  17.   

    看看debug的汇编和release的汇编代码有什么区别。包括栈或者其他的什么库。这种东西都是很奇怪的,说不准是哪里的问题。实在不行,换个环境试一下吧。如果不涉及商业密码和很复杂的环境配置,我可以替你试一下
      

  18.   

    估计是CPaintDC * pdc = (CPaintDC *) GetDC();异常了,没有handle,然后就抛出到函数退出点了。你GetDC记得每次用完都要Release,不然会出问题的。还有CDC就OK了,不用再转换为CPaintDC吧。
      

  19.   

    不是商业秘密的问题,而是环境太复杂。GetDC似乎是死循环了,用mfc的源码替换,在CDC::FromHandle(hdc);处出的问题。在CDC::FromHandle(hdc);前写日志能写,在CDC::FromHandle(hdc);之后就不能把日志写进去了。
      

  20.   

    这样使用 CPaintDC 肯定是错了MSDN 的原话 ---A CPaintDC object can only be used when responding to a WM_PAINT message, usually in your OnPaint message-handler member function建议把 Windows 和 MFC 中有关绘制的过程理清楚
      

  21.   

    To ross33123():其实我是想说GetDC的问题,我一开始是用的CDC *,不过拷贝这段代码的时候正好换了CPaintDC *,发现也不好用。用CPaintDC *也好,用CClientDC *也好,用CDC *也好,都是要先从GetDC获得一个CDC *再转换的。而现在GetDC不能返回一个CDC *啊,另外,在Debug版中是可以的。目前是用HDC,从::GetDC()返回,这样画是没有问题了,但是问题依然是存在的。奇怪就在于可以获得dialog的DC的句柄,但是在调用CDC::FromHandle()从句柄获得CDC对象的时候就停住了,想死循环一样,没有报异常,程序也没有终止。
      

  22.   

    完全没必要在OnTimer中对DC进行操作
    只要修改FLAG然后在OnPaint中进行相应
    然后InvalidateRect就可以了May you succeed!
      

  23.   

    试试这样能不能BitBlt()..
    HDC hDC = ::GetDC(this->GetSafeHwnd());
    if(! hDC){
        AfxMessageBox("Can not get a dc, T_T);
        return;
    }
    ..........//
    .......   //
    ::BitBlt(hDC,0,0,nWidth,nHeight,MemDC.GetSafeHdc(),0,0,SRCCOPY);如果还不行的话..无语 ^o^
    窗口句柄Get不到dc..不知何故.(排除ReleaseDC()的问题)
      

  24.   

    "GetClientRect之类的都不能用"
    窗口有问题?全都是CWnd的成员函数..
      

  25.   

    "GetClientRect之类的都不能用"
    应该是窗口句柄无效导致的,OnInitDialog里把句柄记下来,到GetDC()的时候两个比较一下看是否相等。
      

  26.   

    To lambochan(打杂) :句柄能获得的,也能bitblt,但是无法FromHandle。To nonocast(如果没有如果):不是在OnTimer中做的。只是SetTimer之后就KillTimer了。本来就是想写在OnPaint里边的,但是为了代码的可读性才单独拿出来的。To ringphone(临风) :不行的,因为API方式::GetDC能够获得正常的Dialog的DC的句柄。
      

  27.   

    在OnInitDialog中获取CDC:
    CPaintDC * pdc = (CPaintDC *) GetDC();
    在OnDestory中释放CDC;
    ReleaseDC(pDC);
    不要在OnTimer中获取CDC,因为获取DCD相当于是分配一定的内存并将CDC的参数存入此内存,如果在OnTimer中获取,就等于不断的分配内存而不释放已分配的内存会造成内存泄露.
    如果以上的方法还不能解决问题,就可能是数组超界的问题,我以前也出过类似的问题,程序在Debug下正常,但在release下出错,检查了一下,也没发现内存泄露的问题,最后发现是数组超界.
    因为VC在DEbug方式下会对数组超界采取一定的保护措施,所以有时候在Debug下数组超界没问题而在release下会出问题.
      

  28.   

    ross33123() 的说法有道理。
     ckp(surge) 在OnInitDialog中获取CDC
    我觉得不行。
    Identifies the device context for the CWnd client area if successful; otherwise, the return value is NULL. The pointer may be temporary and should not be stored for later use.
    MSDN上是这样解释的,这样得到的指针会无效,更加导致程序出错。
      

  29.   

    问题查到了,在OnInitDialog中为一个CDC *指针new了一个CDC对象,导致跟需要调用的一个DLL冲突。放到其它函数中结果正常……可惜看不到那个DLL的源码,还是不知道怎么回事。