By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,836 Members | 2,023 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,836 IT Pros & Developers. It's quick & easy.

Memory Leak (40K per mouse over)

P: 11
I'm currently writing a replacement shell and am suffering from quite dire memory leaks, when running, every time I roll my mouse over the taskbar icon a new window scrolls out revealing the window's caption and then on WM_MOUSELEAVE the window closes again. somehow this process also increases my program's private working set by 40K (using SysInternals' Process Explorer) Any help would be appreciated.

Extract from TaskbarItem.cpp:

Expand|Select|Wrap|Line Numbers
  1. LRESULT CALLBACK            TaskbarItem::LocalProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam){
  2.     switch(msg){
  3.         case WM_MOUSEMOVE:{
  4.             if(this->caption==(TaskExpander*)NULL)
  5.                 this->caption=new TaskExpander(&(*this));
  6.             else
  7.                 this->caption->Reopen();
  8.         }break;
  9.         case WM_MOVED:
  10.             if(caption!=(TaskExpander*)NULL){
  11.                 SendMessage(caption->GetDispHWnd(),WM_MOVED,0,0);
  12.             }
  13.             break;
  14.         default:return DefWindowProc(hWnd,msg,wParam,lParam);
  15.     }
  16.     return 0L;
  17. }
Extract from TaskExpander.cpp:
Expand|Select|Wrap|Line Numbers
  1. void                                TaskExpander::Reopen        (){
  2.     if((state & _O)==0){
  3.         KillTimer(dWnd,IDT_TIMER_CLOSE);
  4.         KillTimer(dWnd,IDT_TIMER_TIMEOUT);
  5.         state=OPENING;
  6.         SetTimer(dWnd,IDT_TIMER_OPEN,ANI_TIME,0);
  7.         ShowWindow(dWnd,SW_SHOW);
  8.     }
  9. }
  10. LRESULT CALLBACK                    TaskExpander::LocalProc        (HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam){
  11.     LPPAINTSTRUCT ps=new PAINTSTRUCT;
  12.     HDC hdc;
  13.     HFONT hFont;
  14.     hFont=global::font::basic;
  15.     switch(msg){        
  16.         case WM_MOVED:{
  17.             LPRECT r=new RECT;
  18.             LPRECT s=new RECT;
  19.             GetWindowRect(pTbi->GetDispHWnd(),r);
  20.             GetWindowRect(hWnd,s);
  21.             position.x=r->right;
  22.             position.y=r->top-1;
  23.             MoveWindow(hWnd,position.x-(s->right-s->left),position.y,(r->right-r->left),r->bottom-r->top,true);
  24.             InvalidateRgn(hWnd,NULL,TRUE);
  25.         }break;
  26.         case WM_PAINT:{
  27.             hdc=BeginPaint(hWnd,ps);
  28.             SetBkColor(hdc,0x00000000);
  29.             SelectObject(hdc,hFont);
  30.             SetTextColor(hdc,0x00FFFFFF);
  31.             size_t psz;
  32.             LPRECT r=new RECT;
  33.             GetWindowRect(hWnd,r);
  34.             HICON icon=pTbi->GetIcon();
  35.             StringCchLength(pTbi->GetTitle(),MAX_LOADSTRING,&psz);
  36.             TextOut(hdc,2*ICON_GAP+ICON_SIZE,ICON_GAP/2,pTbi->GetTitle(),psz);
  37.             DrawIconEx(hdc,ICON_GAP,0,icon,ICON_SIZE,ICON_SIZE,0,NULL,DI_NORMAL);
  38.             EndPaint(hWnd,ps);
  39.             delete r;
  40.             }break;
  41.         case WM_TIMER:
  42.             switch(wParam){
  43.                 case IDT_TIMER_OPEN:{
  44.                     state=OPENING;
  45.                     hdc=GetDC(hWnd);
  46.                     LPRECT r=new RECT;
  47.                     size_t psz;
  48.                     SIZE size;
  49.                     SelectObject(hdc,hFont);
  50.                     StringCchLength(pTbi->GetTitle(),MAX_LOADSTRING,&psz);
  51.                     GetTextExtentPoint32(hdc,pTbi->GetTitle(),*&psz,&size);
  52.                     GetWindowRect(hWnd,r);
  53.                     if((size.cx+(2*ICON_GAP)+ICON_SIZE)-(r->right-r->left)>ANI_STEP)
  54.                         MoveWindow(hWnd,position.x-(r->right-r->left)-ANI_STEP,position.y,(r->right-r->left)+ANI_STEP,r->bottom-r->top,true);
  55.                     else{
  56.                         MoveWindow(hWnd,position.x-(size.cx+(2*ICON_GAP)+ICON_SIZE),position.y,(size.cx+(2*ICON_GAP)+ICON_SIZE),r->bottom-r->top,true);
  57.                         KillTimer(hWnd,IDT_TIMER_OPEN);
  58.                         SetTimer(hWnd,IDT_TIMER_TIMEOUT,10000,(TIMERPROC)NULL);
  59.                         state=OPEN;
  60.                     }
  61.                     delete r;
  62.                 }break;
  63.                 case IDT_TIMER_CLOSE:{
  64.                     state=CLOSING;
  65.                     KillTimer(hWnd,IDT_TIMER_TIMEOUT);
  66.                     LPRECT r=new RECT;
  67.                     GetWindowRect(hWnd,r);
  68.                     MoveWindow(hWnd,position.x-(r->right-r->left)+ANI_STEP,position.y,(r->right-r->left)-ANI_STEP,r->bottom-r->top,true);
  69.                     if(r->right-r->left <= ICON_SIZE+ANI_STEP){
  70.                         KillTimer(hWnd,IDT_TIMER_CLOSE);
  71.                         state=READY;
  72.                         ShowWindow(hWnd,SW_HIDE);
  73.                     }
  74.                     delete r;
  75.                 }break;
  76.                 case IDT_TIMER_TIMEOUT:{
  77.                     KillTimer(hWnd,IDT_TIMER_OPEN);
  78.                     this->state=CLOSING;
  79.                     SetTimer(hWnd,IDT_TIMER_CLOSE,ANI_TIME,(TIMERPROC)NULL);
  80.                 }break;
  81.             }break;
  82.         case WM_INIT:
  83.             ShowWindow(dWnd,SW_SHOW);
  84.             SetTimer(hWnd,IDT_TIMER_OPEN,ANI_TIME,(TIMERPROC)NULL);break;
  85.             state=OPENING;
  86.             break;
  87.         case WM_MOUSEMOVE:
  88.             if(state==CLOSING){
  89.                 KillTimer(hWnd,IDT_TIMER_CLOSE);
  90.                 SetTimer(hWnd,IDT_TIMER_OPEN,ANI_TIME,(TIMERPROC)NULL);
  91.             }
  92.             if(!tracking){
  93.                 TRACKMOUSEEVENT tme;
  94.                 tme.cbSize=sizeof(tme);
  95.                 tme.dwFlags=TME_LEAVE;
  96.                 tme.hwndTrack=hWnd;
  97.                 TrackMouseEvent(&tme);
  98.                 tracking=true;
  99.             }
  100.             break;
  101.         case WM_MOUSELEAVE:
  102.             KillTimer(hWnd,IDT_TIMER_OPEN);
  103.             KillTimer(hWnd,IDT_TIMER_TIMEOUT);
  104.             SetTimer(hWnd,IDT_TIMER_CLOSE,ANI_TIME,0);
  105.             state=CLOSING;
  106.             tracking=false;
  107.             break;
  108.         case WM_LBUTTONDOWN:
  109.             SetForegroundWindow(pTbi->GetHWnd());
  110.             SetActiveWindow(pTbi->GetHWnd());
  111.             break;
  112.         default:delete ps,hdc,hFont;return DefWindowProc(hWnd,msg,wParam,lParam);
  113.     }
  114.     return 0L;
  115. }
Dec 1 '08 #1
Share this Question
Share on Google+
5 Replies


Banfa
Expert Mod 5K+
P: 8,916
I see the code allocating TaskExpanders

this->caption=new TaskExpander(&(*this));

but never deleting them and I see the code deleting pointers

default:delete ps,hdc,hFont;return DefWindowProc(hWnd,msg,wParam,lParam);

that have not had memory allocated to them while most of the time it doesn't delete

LPPAINTSTRUCT ps=new PAINTSTRUCT;

allocated PAINTSTRUCTs
Dec 1 '08 #2

P: 11
Thank you for your response.

@Banfa
They would be deleted in the destructor for the TaakbarItem, however this should only cause the memory to go up on the first call surely? memory goes up every time the expander reopens.

adding the "delete ps;" in the relevant places has roughly halved the memory leaking. I managed to find the main cause to be the GetDC() on line 45, adding a corresponding releaseDC has solved the problem.
Thank you for your help.
Dec 1 '08 #3

weaknessforcats
Expert Mod 5K+
P: 9,197
You are creating new RECT variables in several places. How are those cleaned up?
Dec 1 '08 #4

P: 11
@weaknessforcats
Those are now all being deleted after use.

Thank you for your help.
This aspect of the program no longer leaks, the rest of the program has the memory management of a sieve but i should be able to sort that out. Thank you.
Dec 1 '08 #5

Banfa
Expert Mod 5K+
P: 8,916
I don't know if this is code you inherited or wrote but personally whenever I allocate memory from the heap using new I always put in the corresponding delete immediately before filling in any other code.

You may also want to consider using the handle template
Dec 1 '08 #6

Post your reply

Sign in to post your reply or Sign up for a free account.