|
First, I appologize if the answer is here somewhere but I couldn't find it. I am trying to find out where in my program I have a GDI object leak. As I run my program, the task manager reports that my GDI object count is rising. I have been programming VC++ since 4.0 and I am very verse in deleting my objects when I am done with them. However, I have run into a case where I believe it is in a Win32 call that may make a copy. I just don't know which one.
For example, I just learned that CStatic::SetIcon makes a copy. I have an array of HICONs that are loaded in App::InitInstance and destroyed in App:ExitInstance. Everytime I call a CStatic::SetIcon with one of these icon handles, the GDI object count increases. The fix was to do a GetIcon first, and DeleteObject on the icon handle it returns. Program is happy now in that regard.
But I still am missing some and I was wondering where. The program is graphic intensive and would be tough to start selectively commenting out the graphic calls.
Any thoughts?
|
|
|
|
|
Are you running the debug kernel of windows?
In the old days (I mean 1994/1995) if you did so, when your process exited, if you had not freed all the GDI objects, you would get a dump when running your process under debug mode of all the GDI object you failed to 'free'.
You might also find this utility helpful:
http://msdn.microsoft.com/msdnmag/issues/03/01/GDILeaks/default.aspx[^]
|
|
|
|
|
I am using WindowsXP with latest patches, etc. The task manager GDI Object count increases when I open a particular dialog box, for example. This dialog box has many CStatic-based elements which I use for some icon displays (that change based on some user WM_ events). It also has CButton-based elements for some metal-looking buttons with regions and icons. I started commenting out different pieces, trying to isolate the issue. The icons change while the dialog is open and the GDI Object count increases. It stays at that level when the dialog is closed but goes up yet again when the dialog is re-opened. To complicate matters more, I use a CMemDC to draw on before BitBlt-ing onto the CDC provided in the OnDraw.
I wouldn't necessarily have an issue with this but if the program runs for hours, I get low system resource errors, the program fails to paint windows, and eventually locks up. It seems to happen more frequently when I am in front of customers. Task manager is the only way to kill it.
I will look into the article you mentioned. I also looked at different tools (Rational Purify, Numega, etc.) but they are expensive.... I may have no alternative.
Thanks!
|
|
|
|
|
MFC uses a lot of object caching.
As a result, you can't use the values in the Task Mgr as an accurate account of what 'you' have freed as MFC may still have the object cached. It makes it rather hard to find any real leaks.
...cmk
Save the whales - collect the whole set
|
|
|
|
|
I was wondering about that. I did see some cases where the count would linger before going down. However, I have some cases where it jumps up by 30 to 40 and then stays put (see response to Blake above). It gets bigger and bigger as the program stays running and eventually I get system resource errors and the program hangs.
|
|
|
|
|
prcarp wrote:
appologize
No need! If you feel the need, it implies you know what you're doing, but have not figured out the answer yet!
It would help if you posted the leak error message.
If it is happening in debug mode, the odds are that the leak reported is invalid. Since the task manager reports that the count is rising, then it probably is real. Before assuming the task manager is telling you the entire truth: give it a few minutes or try closing the IDE, to see if the task manager stops reporting the same count. If the task manager does report the same count, then try running a release version of your application and see if the same thing is still happening.
Assuming (ass-u-me) that the problem is in the code you wrote, then I would put a TRACE(...) statement wherever you create a GDI object as well as where you release/free the GDI object (to see if they match).
There is also the possibility that you selected a pen, brush, ect... and did not restore the original (unlikely).
Oh Well! I dought if any of this helped (you already knew it).
INTP
"The more help VB provides VB programmers, the more miserable your life as a C++ programmer becomes."
Andrew W. Troelsen
|
|
|
|
|
hello
I am making a program in MFC
I have a class for a window
I want to achieve this: when a key is pressed something happens.
To achieve this I did this
I went to class view I right clicked on my class and clicked on propreties
I clciked on messages
I selected WM_KEYDOWN and from the right column I selected
Add OnKeyDown
this created a new function:
void CViewListaLocatari::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
MessageBox("toader","toader",MB_OK);
if (nChar==VK_DELETE)
OnBnSterge();
else
CFormView::OnKeyUp(nChar, nRepCnt, nFlags);
CFormView::OnKeyDown(nChar, nRepCnt, nFlags);
}
and this line appeared in the message map
ON_WM_KEYDOWN()
I changed it to this
ON_WM_KEYDOWN(WM_KEYDOWN,OnKeyDown)
because it made more sense for it to be like that although I don't know if I did right
anyway it doesn't work
and no messagebox appears even
how do I make it work?
or do you know another way to do this?
|
|
|
|
|
First -- don't screw around with the code that ClassWizard writes unles you know what you are doing. Change it back the way it was.
WM_KEYDOWN events are not handled by CDialog-derived classes. You have to use PreTranslateMessage() to capture the key events. Key events always go to the window that has focus.
|
|
|
|
|
Thank you. It works fine.
|
|
|
|
|
can you please elaborate on this
PreTranslateMessage()
where exactly should I put this ?
It is not a method that I can use
can you please explain more please
|
|
|
|
|
Have you tried catching WM_CHAR ?
|
|
|
|
|
Rick York wrote:
Have you tried catching WM_CHAR ?
doesn't work
|
|
|
|
|
Hello,
I want to draw some text into a bitmap image. The image is stored in the memory. I just want to place some text in there. Afterwards it should be processed by a DirectShow pipeline but this doesn't matter here....
I tried a lot with GDI, but it doesn't work so far. Here is my code:
unsigned __int8 pBuffer;
int m_ImageWidth = 1024;
int m_ImageHeight = 1024;<br />
<br />
BITMAP bmp = {0,m_ImageWidth,m_ImageHeight,m_ImageWidth,1,8,pBuffer};<br />
HBITMAP hBMP = CreateBitmapIndirect(&bmp);<br />
HDC hDC_bmp = CreateCompatibleDC(0);<br />
HBITMAP hBMPc = CreateCompatibleBitmap(hDC_bmp,m_ImageWidth,m_ImageHeight);<br />
HGDIOBJ x = SelectObject(hDC_bmp, hBMPc);<br />
<br />
<br />
<br />
HDC hDC_txt = CreateCompatibleDC(0);<br />
int b = BitBlt(hDC_bmp,0,0,200,200,hDC_txt,0,0,BLACKNESS);<br />
<br />
char text_tag[16];<br />
sprintf(text_tag,"0123456789");<br />
RECT rect = {0,0,200,200};<br />
<br />
int a = DrawText(hDC_txt,TEXT(text_tag),1,&rect,DT_LEFT);<br />
<br />
BITMAPINFO bmInfo;<br />
memset(&bmInfo.bmiHeader,0,sizeof(BITMAPINFOHEADER));<br />
bmInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);<br />
bmInfo.bmiHeader.biWidth=m_ImageWidth;<br />
bmInfo.bmiHeader.biHeight=m_ImageHeight;<br />
bmInfo.bmiHeader.biPlanes=1;<br />
bmInfo.bmiHeader.biBitCount=24;<br />
<br />
HBITMAP g = CreateDIBitmap(hDC_txt,&bmInfo.bmiHeader,0,0,0,DIB_RGB_COLORS);<br />
<br />
int c = GetObject(g,1024*1024,(void*)pBuffer);
After processing these lines i think I should have the image with the text in the Buffer "pBuffer". But I don't have. Can anyone tell me why and how it works??? I am also open to a different method which just puts text into my bitmap.
Thanks for help
chris
|
|
|
|
|
wookie182 wrote:
HDC hDC_txt = CreateCompatibleDC(0);
int b = BitBlt(hDC_bmp,0,0,200,200,hDC_txt,0,0,BLACKNESS);
this is a problem.
before you Blt to a DC, that DC needs to have a bitmap selected into it.
but, i'm not sure why you need hDC_txt in the first place. you should be able to do a DrawText onto hDC_bmp (after selecting your bitmap into hDC_bmp, of course).
Cleek | Image Toolkits | Thumbnail maker
|
|
|
|
|
Well if I do without the hDC_txt it produces the same result. Only 24byte (nonsens) are writen in the Buffer. My new code looked like this
<br />
...<br />
BITMAP bmp = {0,m_ImageWidth,m_ImageHeight,m_ImageWidth,1,8,pBuffer};<br />
HBITMAP hBMP = CreateBitmapIndirect(&bmp);<br />
HDC hDC_bmp = CreateCompatibleDC(0);<br />
HBITMAP hBMPc = CreateCompatibleBitmap(hDC_bmp,m_ImageWidth,m_ImageHeight);<br />
HGDIOBJ x = SelectObject(hDC_bmp, hBMPc);<br />
<br />
char text_tag[16];<br />
sprintf(text_tag,"0123456789");<br />
RECT rect = {0,0,200,200};<br />
<br />
int a = DrawText(hDC_bmp,TEXT(text_tag),1,&rect,DT_LEFT);<br />
<br />
BITMAPINFO bmInfo;<br />
memset(&bmInfo.bmiHeader,0,sizeof(BITMAPINFOHEADER));<br />
bmInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);<br />
bmInfo.bmiHeader.biWidth=m_ImageWidth;<br />
bmInfo.bmiHeader.biHeight=m_ImageHeight;<br />
bmInfo.bmiHeader.biPlanes=1;<br />
bmInfo.bmiHeader.biBitCount=8;<br />
<br />
HBITMAP g = CreateDIBitmap(hDC_bmp,&bmInfo.bmiHeader,0,0,0,DIB_RGB_COLORS);<br />
<br />
int c = GetObject(g,1024*1024,(void*)pBuffer__);<br />
I'm very new to this GDI stuff. And I don't exactly know what I'm actually doing. I just want to have text in my bitmap.... so please tolerate some stupid misstakes and questions...
Thanks
Chris
|
|
|
|
|
Ahhh, you almost lost me entirely here "__int8 pBuffer" (that makes no since). Then I glanced at the rest of the code, which almost(!) looks reasonable(?).
wookie182 wrote:
I tried a lot with GDI, but it doesn't work so far.
Sorry, but that is because you do not know what your are doing!
INTP
"The more help VB provides VB programmers, the more miserable your life as a C++ programmer becomes."
Andrew W. Troelsen
|
|
|
|
|
Of course I am NOT using an uninitialized Pointer!!! There is some code before, which allocates memory and puts data to this buffer. I am just new to this GDI stuff and I believe there must be something wrong in these lines....
|
|
|
|
|
Simpilest way:
1) Create a display compatible dc.
2) Create a display compatible bitmap.
3) Select the bitmap into the dc.
4) Draw on the bitmap via the dc.
5) Select the old bitmap into the dc.
6) Release the dc you created.
7) You now have a bitmap with text on it.
Your code is a bit to complicated and you are drawing on 2 different DCs, drawing text is the same as drawing a line or a rectangle. All your drawing must be done on the SAME DC, after all that is where your drawing area is (the bitmap).
INTP
"The more help VB provides VB programmers, the more miserable your life as a C++ programmer becomes."
Andrew W. Troelsen
|
|
|
|
|
hi,
can anyone tell me how to show a bitmap or an icon on a button to be used in a dialog window( my application is a SDI app with view class derived from CFormView). i have added a bitmap as a resource.
thanks
aditya
|
|
|
|
|
See this article.
"One must learn from the bite of the fire to leave it alone." - Native American Proverb
|
|
|
|
|
|
Aditya Rao wrote:
how to show a bitmap or an icon on a button to be used in a dialog window
Yeap,Here it is :-
This![^]
"Opinions are neither right nor wrong. I cannot change your opinion. I can, however, change what influences your opinion." - David Crow
cheers,
Alok Gupta
VC Forum Q&A :- I/ IV
|
|
|
|
|
If WM_PAINT shows up with an hDC of 0 -- does that mean anything?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br />
Peter Weyzen<br />
Staff Engineer<br />
<A HREF="http://www.santacruznetworks.com">Santa Cruz Networks</A>
|
|
|
|
|
Peter Weyzen wrote:
If WM_PAINT shows up with an hDC of 0 -- does that mean anything?
It means it's working as expected. As far as I know, WM_PAINT doesn't send an hDC; both wParam an lParam in that message are unused.
Maybe you mean some other message?
--
jlr
http://jlamas.blogspot.com/[^]
|
|
|
|
|
Thanks for the help -- I don't know all the details anymore. My boss came in wondering why this was happening...
I didn't have an answer for him...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br />
Peter Weyzen<br />
Staff Engineer<br />
<A HREF="http://www.santacruznetworks.com">Santa Cruz Networks</A>
|
|
|
|
|