2011-11-07 116 views
0

在我的应用程序中,我使用GetDC获取DC,并且我还使用ReleaseDC释放该DC。如何处理GDI资源泄漏

但是,当我使用VTune分析我的应用程序时,它在GetDC上显示一个GDIResource泄漏。

m_hdc = ::GetDC(hWndDisplay[frameIndex]); 
::SetStretchBltMode(m_hdc,STRETCH_DELETESCANS); 
::StretchDIBits(m_hdc,0,0,IMAGE_WIDTH,IMAGE_HEIGHT,0,0,imageWidth,imageHeight,rgbavpg,pTempBmpInfo,DIB_RGB_COLORS,SRCCOPY); 
::ReleaseDC(hWndDisplay[frameIndex],m_hdc); 

以下是相关的代码:全局定义为HDC m_hdc m_hdc ID;

void Display(unsigned char *rgbavpg,unsigned long imageSize, unsigned int imageWidth, unsigned int imageHeight, unsigned int frameIndex) 
{ 

PBITMAPINFO pTempBmpInfo = NULL; 
DWORD timespan; 
int temp; 

if ((IMAGE_WIDTH==imageWidth)&&(IMAGE_HEIGHT==imageHeight)) 
{ 
    frameNum++ ; 
} 
timespan = 1000/15; 
DWORD diff = GetTickCount() - tickes[frameIndex];//lvm4; 
tickes[frameIndex]=GetTickCount(); 
if (g_threadMarkedForStop[frameIndex] == TRUE) 
{   
    return; 
} 
if(diff < timespan) 
    { 
      Sleep(diff); 
    } 
if (FALSE == ::IsWindow(hWndDisplay[frameIndex])) 
{ 
    g_threadMarkedForStop[frameIndex] = TRUE 
    return; 
} 

pTempBmpInfo = &m_bmpinfo[frameIndex]; 
if(pTempBmpInfo != NULL) 
{ 
    pTempBmpInfo->bmiHeader.biWidth= imageWidth ; 
    pTempBmpInfo->bmiHeader.biHeight= imageHeight; 
} 
else 
{ 
    g_threadMarkedForStop[frameIndex] = TRUE; 

    return; 
} 
m_hdc = ::GetDC(hWndDisplay[frameIndex]); 
    ::SetStretchBltMode(m_hdc,STRETCH_DELETESCANS); 

if (true == fullscreen)    ::StretchDIBits(m_hdc,0,0,510,320,0,0,imageWidth,imageHeight,rgbavpg,pTempBmpInfo,DIB_RGB_COLORS,SRCCOPY); 
else 
{  ::StretchDIBits(m_hdc,0,0,IMAGE_WIDTH,IMAGE_HEIGHT,0,0,imageWidth,imageHeight,rgbavpg,pTempBmpInfo,DIB_RGB_COLORS,SRCCOPY); 
    //::SetDIBitsToDevice(m_hdc,0,0,IMAGE_WIDTH,IMAGE_HEIGHT,0,0,0,imageHeight,rgbavpg,pTempBmpInfo,DIB_RGB_COLORS); 
} 
::ReleaseDC(hWndDisplay[frameIndex],m_hdc); 
} 

请帮我解决这个问题。

+0

这段代码没有明显的泄漏。为什么m_hdc是你班级的成员?这是不对的。 –

+0

感谢您的回复。 m_hdc是全局定义的HDC类型的句柄。你能否详细说明为什么你认为这是不对的? –

+0

我假设汉斯的观点是,只要你不再需要他们,就应该使用和处置直流电。它们是内存/资源消耗的,被选入它们的bmp不能被删除,所以通常错误的做法是让它们躺在地上。 –

回答

0

尽管使用了一个成员变量m_hdc并且没有使用局部变量,但这个代码本身看起来不错。

您是否看到每次或仅有时会泄漏的VTune标记?

当我看到您对IsWindow()的调用和变量名g_threadMarkedForStop时,我想知道您是否在执行多线程。难道你有时会在GetDC和ReleaseDC之间破坏窗口?

+0

感谢您的回复... 实际上,我的应用程序通过逐帧解码通过编解码器显示一个或多个视频缩略图.VTune显示没有泄漏来显示一个视频缩略图,但对于多个视频缩略图,它显示的是GDIResource泄漏m_hdc = ::的GetDC(hWndDisplay [FRAMEINDEX]);即使我正在释放它,因为你可以看到我使用过ReleaseDC。是的,我已经完成多线程显示一个或多个缩略图。我并没有破坏GetDC和ReleaseDC之间的窗口。有没有其他可能的方式来释放DC?请尽快回复。 感谢和问候 Mayank –

+0

在这种情况下,我会1)将m_hdc更改为本地变量,以确保您不会从任何地方更改m_hdc并2)检查ReleaseDC的返回值以确保Windows真正释放了DC。如果VTune在这两次更改后仍然抱怨,则可能会忽略VTune错误消息。 –

+0

谢谢Werner, 我的问题现在已经解决了。现在我已经在本地声明了m_hdc并且它正在工作。但是我仍然想问你,当我声明为全局时,GDIResource泄漏的原因是什么? 非常感谢你.... –