|
Its a good practise if we don't depend on IDE/third-party tools/software to detect memory leaks in our code. Its better if we can predict before hand the consequences of writing each line of code.
But there may be situations where we need to work on projects written by someone else. In such cases these third-party tools may help us in finding a QUICK solution.
The visual studio debugger along with C run-time (CRT) libraries provides us means for detecting memory leaks.But its capabilities are minimal.
Enabling memory leak detection in visual studio:
1. If our program can exit from multiple locations, instead of putting a call to _CrtDumpMemoryLeaks at each possible exit,include the following call at the beginning of program:
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
This statement automatically calls _CrtDumpMemoryLeaks when program exits.
2 . The macro _CRTDBG_MAP_ALLOC applies to c library functions malloc, realloc.With a little bit of extra code, we can get it to work with new/delete:
#define _CRTDBG_MAP_ALLOC
#include <iostream>
#include <crtdbg.h>
#ifdef _DEBUG
#define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
#define new DEBUG_NEW
#endif
These macros should be added after including all other header files.
3. By default, _CrtDumpMemoryLeaks dumps memory leak information to the Output window,we can reset this to a file using _CrtSetReportMode. For doing this add the following lines of code at the starting of your program.
HANDLE hLogFile;
hLogFile = CreateFileA("c:\\memoryLeaksDump.rtf", GENERIC_WRITE,FILE_SHARE_WRITE, NULL, CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL, NULL);
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
_CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_WARN, hLogFile);
_CrtSetReportFile(_CRT_ERROR, hLogFile);
_CrtSetReportFile(_CRT_ASSERT, hLogFile);
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
http://www.mindfiresolutions.com/Enabling-memory-leak-detection-in-VC-44.php[^]Cheers,
Eliza
|
|
|
|
|
Hi,
i am new to wince. I followed the steps from the following docs but i did not succeed.
http://linuxtogo.org/~koen/letux/bootloader/bsp/DOC/DotNET420Guide.html
http://linuxtogo.org/~koen/letux/doc/NET410Guide.htm
http://arm.co.kr/programs/read.php?board=qna&uid=409&cp=3&field=&keyWord=&PHPSESSID=c20fb1f1438ba974d7c2beca9a4c89c2
http://www.embedinfo.com/english/download/winces3ceb2410.pdf
if any one knows how to port wince to smdk2410 board please help me.
amiya kumar das
|
|
|
|
|
What about array allocations:
byte t = new byte[x];
delete []t;
Yossi
|
|
|
|
|
Code for malloc(), calloc(), realloc() and free() would be very useful.
Mark
|
|
|
|
|
Yes, it would be very appreciated.
|
|
|
|
|
Hello
What if we could use CMemoryDump wrappers, instead?
Regards
Sreekanth Muralidharan
Bangalore.
Sreekanth Muralidharan,
Corporate Systems Consultant [Embedded Systems],
INDIA
|
|
|
|
|
First of all thank you very much for this usefull code!!
This is a possible solution for the bug as mentioned in the first reply to the theme "Now its ready for WCE MFC" (see
http://www.codeproject.com/ce/ce_crtdbg.asp?df=100&forumid=2264&select=1109032#xx1109032xx[^]).
In the file WCECrtDBG.cpp I made the follwing changes (written in bold font)
#define WCErtDBG_FILE
#include "WCECrtDBG.h"
#undef WCErtDBG_FILE
In the header file I inserted the following lines:
class garbageCollector {
public:
garbageCollector() {}
~garbageCollector();
};
#ifndef WCErtDBG_FILE
#define delete ::delete
#endif
#define DEBUG_NEW ::new (THIS_FILE, __LINE__, true, true)
I think the problem is, that the delete-operator defined in WCECrtDBG.cpp is not called in other classes, but only in the class where the garbace collector has been added. In my case I put it in the Dialog-Class (MyProjectDlg.cpp). If I use some other classes, then the delete operator of WCECrtDBG.cpp isn't called in those classes.
Here an example to illustrate my thought:
void function1(void) { }
class BaseClass
{
void function1(void) { };
};
class SubClass : public BaseClass
{
void function1(void) { };
void function2(void)
{
function1();
BaseClass::function1();
::function1();
}
};
The "bug" with the delete-operator must be something like that.
But with the mentioned enhancements it seems to work correct.
Please tell me if I am right with my thought.
|
|
|
|
|
Hello
The bug is still there in the MFC architecture as well. You should point to a NULL even after you delete the allocations.
It should be something like:
<br />
if(alloc)<br />
{<br />
delete alloc;<br />
alloc = NULL;<br />
}
You may be lucky if you don't get a dump if the code is without alloc = NULL .
Sometimes the above sequence too fails. What to do, then?
Before deallocating the above region, reallocate the region ( you may use 'C' realloc for that)with a different quanta of memory and delete the allocation. It works !!
Regards
Sreekanth Muralidharan
Sreekanth Muralidharan,
Corporate Systems Consultant [Embedded Systems],
INDIA
|
|
|
|
|
in the file wcecrtdbg.h and wcecrtdbg.cpp
replaced code
void __cdecl operator delete(void *pvMem), char* name, int line);
with
void __cdecl operator delete(void *pvMem);
then the function delete is work well .
|
|
|
|
|
could anyone tell me the activation key. i am naive user.
|
|
|
|
|
I joined a bigger wince project, and I'd like to do some mem leak detection, so I tried using this crtdbg.h, but when I compile, these are the errors I'm getting:
mem.h(31) : error C2059: syntax error : 'string'
mem.h(31) : error C2091: function returns function
mem.h(31) : error C2809: 'operator new' has no formal parameters
mem.h(31) : error C2065: 'place' : undeclared identifier
mem.h defines a whole lot of memory operations, and here's the place where it's failing, most likely due to the redefinition.
#if !defined(AFX_STDAFX_H__A064B061_22CA_40B8_8A45_ACD1CCAD2FF6__INCLUDED_) && !defined(__AFXWIN_H__)
inline void *operator new(unsigned int, void *place) { return place; }
Does anyone know how I can resolve these errors??
Many thanks for any advice whatsoever!
Heath
|
|
|
|
|
Hey!!
Please let me know which compiler you are trying to compile your code against. If it was GCC then it would work fine. Else string is not a predefined data type.
Regards
Sreekanth Muralidharan,
Corporate Systems Consultant [Embedded Systems],
INDIA
|
|
|
|
|
hi!
Tried to use the header file. It detects memory leaks, but displays the following:
Detected memory leaks!
Dumping objects ->
F:\docs\opis\projects\ETMSSync\PDA\work\crtdbg.h(93) : normal block at 0x00090008, 12 bytes long
Data
F:\docs\opis\projects\ETMSSync\PDA\work\crtdbg.h(93) : normal block at 0x000900E8, 8 bytes long
Data <>
how come it points to crtdbg.h as the source of the leak?
thanks 
|
|
|
|
|
Hello
Normally, this happens even if you use other debugging or trace tools.
For instance, Visual Studio debugger generates lines indicating a leak in wincore.cpp quite often.
This may be because of the dependency your code has generated. Or this may be a problem in the trace tool code dependency itself.(May be a leak in leak detector itself !! ).
Regards
Sreekanth Muralidharan,
Corporate Systems Consultant [Embedded Systems],
INDIA
-- modified at 22:40 Thursday 1st December, 2005
|
|
|
|
|
I changed this code in 1 hour and now works with MFC on PocketPC 2002/2003 (not tested on previous versions).
For any file (*.cpp) i your project insert these lines:
#include "stdafx.h"
#include "WCECrtDBG.h"... your includes ...
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
And now in ONE file for all project (for example file with application object) insert folowing lines:
#ifdef _DEBUG
_CrtSetDbgFlag(ON);
#endif
Thats all.
Best regards
P.
Code:
------
WCECrtDBG.h
<code>#if !defined(_WCECRTDBG_H)
#define _WCECRTDBG_H
#if defined(_DEBUG) && defined(_WIN32_WCE)
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include <windows.h>
void* operator new(unsigned int s, char* name, int line, bool log, bool msg);
void __cdecl operator delete(void *pvMem);
class garbageCollector {
public:
garbageCollector() {}
~garbageCollector();
};
#define DEBUG_NEW ::new (THIS_FILE, __LINE__, true, true)
#define _CrtSetDbgFlag(ignore) garbageCollector _GB;
#else
#define _CrtSetDbgFlag(ignore)
#endif // _DEBUG && _WIN32_WCE
#endif // _WCECRTDBG_H</code>
WCECrtDBG.cpp
<code>#include "stdafx.h"
#include "atlconv.h"
#include "WCECrtDBG.h"
#if defined(_DEBUG) && defined(_WIN32_WCE)
extern "C" void WINAPIV NKDbgPrintfW(LPCWSTR lpszFmt, ...);
//extern void AquratWriteLog(const char* szFileName, bool bWithDate, bool bWithNewLine, const char* szFormat, ...);
struct _CrtFileName {
char* _CrtName;
_CrtFileName* _CrtNext;
};
struct _CrtMem {
_CrtFileName* _CrtFileName;
int _CrtLine;
unsigned int _CrtMemLen;
void* _CrtMemAddr;
_CrtMem* _CrtNext;
};
_CrtMem* _CrtMemRoot = 0;
_CrtFileName* _CrtFileNameRoot = 0;
void* operator new(unsigned int s, char* name, int line, bool log, bool msg) {
void* retPtr = malloc(s);
if (retPtr) {
_CrtMem* _crtMemCell = (struct _CrtMem*)malloc (sizeof(_CrtMem));
_crtMemCell->_CrtLine = line;
_crtMemCell->_CrtMemLen = s;
_crtMemCell->_CrtMemAddr= retPtr;
_crtMemCell->_CrtNext = 0;
_CrtFileName* _tmpCrtFileName;
for(_tmpCrtFileName = _CrtFileNameRoot; _tmpCrtFileName && strcmp(name, _tmpCrtFileName->_CrtName); _tmpCrtFileName = _tmpCrtFileName->_CrtNext)
; // empty body
if(!_tmpCrtFileName) {
char* _crtName = (char*)malloc((strlen(name) + 1) * sizeof(char));
strcpy(_crtName, name);
_CrtFileName* _crtFileName = (struct _CrtFileName*)malloc(sizeof (_CrtFileName));
_crtFileName->_CrtName = _crtName;
_crtFileName->_CrtNext = 0;
if(!_CrtFileNameRoot)
_CrtFileNameRoot = _crtFileName;
else {
for(_tmpCrtFileName = _CrtFileNameRoot; _tmpCrtFileName->_CrtNext; _tmpCrtFileName = _tmpCrtFileName->_CrtNext)
; // empty body
_tmpCrtFileName->_CrtNext = _crtFileName;
}
_tmpCrtFileName = _crtFileName;
}
_crtMemCell->_CrtFileName = _tmpCrtFileName;
if (!_CrtMemRoot) {
_CrtMemRoot = _crtMemCell;
}
else {
_CrtMem* _tmpMemPtr;
for(_tmpMemPtr = _CrtMemRoot; _tmpMemPtr->_CrtNext; _tmpMemPtr = _tmpMemPtr->_CrtNext)
; // empty body
_tmpMemPtr->_CrtNext = _crtMemCell;
}
}
return retPtr;
}
void __cdecl operator delete(void *pvMem) {
if(pvMem) {
_CrtMem* _tmpMem;
if(pvMem == _CrtMemRoot->_CrtMemAddr) {
_tmpMem = _CrtMemRoot;
_CrtMemRoot = _CrtMemRoot->_CrtNext;
free(_tmpMem);
}
else {
for(_tmpMem = _CrtMemRoot; _tmpMem->_CrtNext && (_tmpMem->_CrtNext->_CrtMemAddr != pvMem); _tmpMem = _tmpMem->_CrtNext)
; // empty body
if(_tmpMem->_CrtNext) {
_CrtMem* _tmpMem2;
_tmpMem2 = _tmpMem->_CrtNext;
_tmpMem->_CrtNext = _tmpMem2->_CrtNext;
free(_tmpMem2);
}
else
NKDbgPrintfW(_T("%s(%i) : Warning : deletes memory pointer not allocated with new!\n"), _T(__FILE__), __LINE__);
}
free (pvMem);
}
}
garbageCollector::~garbageCollector () {
USES_CONVERSION;
if(!_CrtMemRoot)
NKDbgPrintfW(_T("No memory leaks detected!\n"));
else {
_CrtMem* _tmpMem;
NKDbgPrintfW (_T("Detected memory leaks!\nDumping objects ->\n"));
//AquratWriteLog("memory.txt", true, true, "Detected memory leaks!");
for(_tmpMem = _CrtMemRoot; _tmpMem; _tmpMem = _tmpMem->_CrtNext) {
NKDbgPrintfW(_T("%s(%i) : normal block at 0x%08X, %i bytes long\n Data <"), A2W(_tmpMem->_CrtFileName->_CrtName), _tmpMem->_CrtLine, _tmpMem->_CrtMemAddr, _tmpMem->_CrtMemLen);
//AquratWriteLog("memory.txt", false, false, "%s(%i) : normal block at 0x%08X, %i bytes long\n Data <", _tmpMem->_CrtFileName->_CrtName, _tmpMem->_CrtLine, _tmpMem->_CrtMemAddr, _tmpMem->_CrtMemLen);
for(unsigned int i = 0; i < _tmpMem->_CrtMemLen; i++) {
NKDbgPrintfW(_T("%c"), *(((char*)_tmpMem->_CrtMemAddr)+i));
//AquratWriteLog("memory.txt", false, false, "%c", *(((char*)_tmpMem->_CrtMemAddr)+i));
}
NKDbgPrintfW(_T(">\n"));
//AquratWriteLog("memory.txt", false, true, ">");
}
}
_CrtFileName* _tmpName = _CrtFileNameRoot;
for(;_tmpName;) {
_CrtFileNameRoot = _tmpName->_CrtNext;
free(_tmpName->_CrtName);
free(_tmpName);
_tmpName = _CrtFileNameRoot;
}
}
#endif // _DEBUG && _WIN32_WCE</code>
|
|
|
|
|
Hello,
Thanks for your crtdbg first.But I found it does'nt work on my project.
The problem is ,when I call delete,It does'nt call the operate delete you define
in the WCECrtdbg.cpp. I have to write ::delete instead of delete.
How to resolve this problem?
Thank you again!
jason
|
|
|
|
|
|
 Thanks for Piotr, There is my code. Fix delete problem.
<br />
WCECrtDBG.h<br />
#if !defined(_WCECRTDBG_H)<br />
#define _WCECRTDBG_H<br />
<br />
#pragma once<br />
<br />
#if defined(_DEBUG) && defined(_WIN32_WCE)<br />
<br />
#include <stdlib.h><br />
#include <malloc.h><br />
#include <string.h><br />
#include <windows.h><br />
<br />
void* operator new(unsigned int s, char* name, int line);<br />
void __cdecl operator delete(void *pvMem, char* name, int line);<br />
<br />
class garbageCollector<br />
{<br />
public:<br />
garbageCollector();<br />
~garbageCollector();<br />
};<br />
<br />
#ifndef WCErtDBG_FILE<br />
#define delete ::delete<br />
#endif<br />
<br />
#undef DEBUG_NEW<br />
#define DEBUG_NEW ::new (THIS_FILE, __LINE__)<br />
#define _CrtSetDbgFlag(ignore) extern garbageCollector _GB;<br />
#else<br />
#define _CrtSetDbgFlag(ignore)<br />
#endif // _DEBUG && _WIN32_WCE<br />
<br />
#endif // _WCECRTDBG_H<br />
<br />
WCECrtDBG.cpp<br />
#include "stdafx.h"<br />
#include "atlconv.h"<br />
<br />
#define WCErtDBG_FILE<br />
#include "WCECrtDBG.h"<br />
#undef WCErtDBG_FILE<br />
<br />
#if defined(_DEBUG) && defined(_WIN32_WCE)<br />
<br />
extern "C" void WINAPIV NKDbgPrintfW(LPCWSTR lpszFmt, ...);<br />
<br />
garbageCollector _GB;<br />
<br />
struct _CrtFileName<br />
{<br />
char* _CrtName;<br />
_CrtFileName* _CrtNext;<br />
};<br />
<br />
struct _CrtMem<br />
{<br />
_CrtFileName* _CrtFileName;<br />
int _CrtLine;<br />
unsigned int _CrtMemLen;<br />
void* _CrtMemAddr;<br />
_CrtMem* _CrtNext;<br />
};<br />
<br />
_CrtMem* _CrtMemRoot = 0;<br />
_CrtFileName* _CrtFileNameRoot = 0;<br />
<br />
void* operator new(unsigned int s, char* name, int line)<br />
{<br />
void* retPtr = malloc(s);<br />
if (retPtr)<br />
{<br />
_CrtMem* _crtMemCell = (struct _CrtMem*)malloc (sizeof(_CrtMem));<br />
_crtMemCell->_CrtLine = line;<br />
_crtMemCell->_CrtMemLen = s;<br />
_crtMemCell->_CrtMemAddr = retPtr;<br />
_crtMemCell->_CrtNext = 0;<br />
<br />
_CrtFileName* _tmpCrtFileName = NULL;<br />
for (_tmpCrtFileName = _CrtFileNameRoot;<br />
_tmpCrtFileName && strcmp(name, _tmpCrtFileName->_CrtName);<br />
_tmpCrtFileName = _tmpCrtFileName->_CrtNext);
if (!_tmpCrtFileName)<br />
{<br />
char* _crtName = (char*)malloc((strlen(name) + 1) * sizeof(char));<br />
strcpy(_crtName, name);<br />
_CrtFileName* _crtFileName = (struct _CrtFileName*)malloc(sizeof (_CrtFileName));<br />
_crtFileName->_CrtName = _crtName;<br />
_crtFileName->_CrtNext = 0;<br />
if (!_CrtFileNameRoot)<br />
{<br />
_CrtFileNameRoot = _crtFileName;<br />
}<br />
else<br />
{<br />
for (_tmpCrtFileName = _CrtFileNameRoot;<br />
_tmpCrtFileName->_CrtNext;<br />
_tmpCrtFileName = _tmpCrtFileName->_CrtNext);
_tmpCrtFileName->_CrtNext = _crtFileName;<br />
}<br />
_tmpCrtFileName = _crtFileName;<br />
}<br />
_crtMemCell->_CrtFileName = _tmpCrtFileName;<br />
<br />
if (!_CrtMemRoot)<br />
{<br />
_CrtMemRoot = _crtMemCell;<br />
}<br />
else<br />
{<br />
_CrtMem* _tmpMemPtr = NULL;<br />
for (_tmpMemPtr = _CrtMemRoot;<br />
_tmpMemPtr->_CrtNext;<br />
_tmpMemPtr = _tmpMemPtr->_CrtNext);
_tmpMemPtr->_CrtNext = _crtMemCell;<br />
}<br />
}<br />
return retPtr;<br />
}<br />
<br />
void __cdecl operator delete(void *pvMem, char* , int )<br />
{<br />
if (pvMem)<br />
{<br />
_CrtMem* _tmpMem = NULL;<br />
if (pvMem == _CrtMemRoot->_CrtMemAddr)<br />
{<br />
_tmpMem = _CrtMemRoot;<br />
_CrtMemRoot = _CrtMemRoot->_CrtNext;<br />
free(_tmpMem);<br />
}<br />
else<br />
{<br />
for (_tmpMem = _CrtMemRoot;<br />
_tmpMem->_CrtNext && (_tmpMem->_CrtNext->_CrtMemAddr != pvMem);<br />
_tmpMem = _tmpMem->_CrtNext);
if (_tmpMem->_CrtNext)<br />
{<br />
_CrtMem* _tmpMem2;<br />
_tmpMem2 = _tmpMem->_CrtNext;<br />
_tmpMem->_CrtNext = _tmpMem2->_CrtNext;<br />
free(_tmpMem2);<br />
}<br />
else<br />
{<br />
NKDbgPrintfW(_T("%s(%i) : Warning : deletes memory pointer not allocated with new!\n"),<br />
_T(__FILE__),<br />
__LINE__);<br />
}<br />
}<br />
free (pvMem);<br />
}<br />
}<br />
<br />
garbageCollector::garbageCollector()<br />
{<br />
<br />
}<br />
<br />
garbageCollector::~garbageCollector ()<br />
{<br />
USES_CONVERSION;<br />
if (!_CrtMemRoot)<br />
{<br />
NKDbgPrintfW(_T("No memory leaks detected!\n"));<br />
}<br />
else<br />
{<br />
_CrtMem* _tmpMem = NULL;<br />
NKDbgPrintfW (_T("Detected memory leaks!\nDumping objects ->\n"));<br />
<br />
for (_tmpMem = _CrtMemRoot; _tmpMem; _tmpMem = _tmpMem->_CrtNext)<br />
{<br />
NKDbgPrintfW(_T("%s(%i) : normal block at 0x%08X, %i bytes long\n"),<br />
A2W(_tmpMem->_CrtFileName->_CrtName),<br />
_tmpMem->_CrtLine,<br />
_tmpMem->_CrtMemAddr,<br />
_tmpMem->_CrtMemLen);<br />
}<br />
}<br />
<br />
_CrtFileName* _tmpName = _CrtFileNameRoot;<br />
<br />
for (; _tmpName; )<br />
{<br />
_CrtFileNameRoot = _tmpName->_CrtNext;<br />
free(_tmpName->_CrtName);<br />
free(_tmpName);<br />
_tmpName = _CrtFileNameRoot;<br />
}<br />
}<br />
<br />
#endif // _DEBUG && _WIN32_WCE<br />
Hello, I am Poney
-- modified at 5:01 Thursday 23rd March, 2006
|
|
|
|
|
Well, I still having problem with the delete.
the new is going fine but the delete goes to the original delete and not the new one.
i am working with VS 2005 with WM2005 SDK cpp project for wm2005 devices
Regards
Yossi
|
|
|
|
|
and I want to know where to call "_CrtSetDbgFlag (ON);" is
the best? I put it in a class method's first line.
I have define new as ::new(_T(__FILE__), __LINE__)
jason
|
|
|
|
|
in Tip 2,you said :
Tip 2), the utility display the address in hexa, and you can add a small
code to the operator new function, just after the first malloc:
if (retPtr == (void*)0x76DA0)
dumb instruction; <- place a breakpoint on this one
so you can detect easily which line of your code called the operator new
to allocate memory at the specified address and wasn't freed.
but every time the program use different memory address,how can this
method work?
jason
|
|
|
|
|
I want to know where the the memory leak happened,I put #define new new(_T(__FILE__), __LINE__) in *.cpp file,but it doesn't work,Why?Can you help me?
Thanks a lot!
|
|
|
|
|
If any person out there who has a heart please help me. I am writing a task manager that does the same fuctions as the on in win98 in c++. I am have troubles because I am not good in programming and to make matters worse it must be finished by Tuesday morning. If any one who has got code for it or can write the code that can display the active programs that are running in the background, I will be very thank full. I have looked the entire web for code but found nothing, the one or two that I do find has got header files missing and does not work. Please any one help me and contact me at phienix3@hotmail.com.
T hanks
|
|
|
|
|
Hi
Try calling EnumProcesses() to enumerate the running processes. EnumProcesses() will get you an array of process ids. If you need the file name of the file that has spawned each process, try using GetModuleFileNameEx() . Before calling this make sure you enumerate all the modules associated with the process by calling EnumerateProcessModules() .
That complete's half of your work.
After you get the handles to all the processes, from the user interface you have designed take the user input(user clicked on xxx process). Try getting the handle to that process. Manage the process from there.
If you want to terminate the process user selected, use TerminateProcess() function.
The above process WILL NOT work for smart devices.
If your project is for smart devices, use the following technique:
<br />
#include "stdafx.h"<br />
#include "SmartPhoneTaskManager.h"<br />
#include "Tlhelp32.h"<br />
#include <windows.h><br />
#include <commctrl.h><br />
<br />
#define MAX_LOADSTRING 100<br />
<br />
HINSTANCE g_hInst;
HWND g_hWndMenuBar;
<br />
ATOM MyRegisterClass(HINSTANCE, LPTSTR);<br />
BOOL InitInstance(HINSTANCE, int);<br />
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);<br />
<br />
BOOL CALLBACK TaskManagerDlgProc(const HWND hTaskManDlg, const UINT uIMessage, <br />
const WPARAM wParam, LPARAM lParam);<br />
<br />
int WINAPI WinMain(HINSTANCE hInstance,<br />
HINSTANCE hPrevInstance,<br />
LPTSTR lpCmdLine,<br />
int nCmdShow)<br />
{<br />
MSG msg;<br />
<br />
if (!InitInstance(hInstance, nCmdShow)) <br />
{<br />
return FALSE;<br />
}<br />
<br />
<br />
while (GetMessage(&msg, NULL, 0, 0)) <br />
{<br />
{<br />
TranslateMessage(&msg);<br />
DispatchMessage(&msg);<br />
}<br />
}<br />
<br />
return (int) msg.wParam;<br />
}<br />
<br />
ATOM MyRegisterClass(HINSTANCE hInstance, LPTSTR szWindowClass)<br />
{<br />
WNDCLASS wc;<br />
<br />
wc.style = CS_HREDRAW | CS_VREDRAW;<br />
wc.lpfnWndProc = WndProc;<br />
wc.cbClsExtra = 0;<br />
wc.cbWndExtra = 0;<br />
wc.hInstance = hInstance;<br />
wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SMARTPHONETASKMANAGER));<br />
wc.hCursor = 0;<br />
wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);<br />
wc.lpszMenuName = 0;<br />
wc.lpszClassName = szWindowClass;<br />
<br />
return RegisterClass(&wc);<br />
}<br />
<br />
HWND hTaskManagerDlg;<br />
HWND hListWnd;<br />
DWORD WINAPI ProcessViewThread(PVOID lParam);<br />
<br />
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)<br />
{<br />
HWND hWnd;<br />
TCHAR szTitle[MAX_LOADSTRING];
TCHAR szWindowClass[MAX_LOADSTRING];
<br />
g_hInst = hInstance;
<br />
<br />
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); <br />
LoadString(hInstance, IDC_SMARTPHONETASKMANAGER, szWindowClass, MAX_LOADSTRING);<br />
<br />
hWnd = FindWindow(szWindowClass, szTitle); <br />
if (hWnd) <br />
{<br />
SetForegroundWindow((HWND)((ULONG) hWnd | 0x00000001));<br />
return 0;<br />
} <br />
<br />
if (!MyRegisterClass(hInstance, szWindowClass))<br />
{<br />
return FALSE;<br />
}<br />
<br />
hWnd = CreateWindow(szWindowClass, szTitle, WS_VISIBLE,<br />
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);<br />
<br />
if (!hWnd)<br />
{<br />
return FALSE;<br />
}<br />
<br />
ShowWindow(hWnd, nCmdShow);<br />
UpdateWindow(hWnd);<br />
<br />
hTaskManagerDlg = CreateDialog(hInstance,MAKEINTRESOURCE(IDD_DIALOG_TASKMAN),NULL,(DLGPROC)TaskManagerDlgProc);<br />
if(!hTaskManagerDlg)<br />
{<br />
MessageBox(NULL,TEXT("Could not start taskman"),TEXT("Taskman Failed"),MB_OK|MB_ICONERROR);<br />
return FALSE;<br />
<br />
}<br />
<br />
ShowWindow(hTaskManagerDlg,SW_SHOWMAXIMIZED);<br />
UpdateWindow(hTaskManagerDlg);<br />
hListWnd = ::GetDlgItem(hTaskManagerDlg,IDC_LIST_ENUM_TASKS);<br />
::SetFocus(hListWnd);<br />
DWORD threadID;<br />
CreateThread(NULL,0,&ProcessViewThread,0,0,&threadID);<br />
<br />
return TRUE;<br />
}<br />
<br />
<br />
<br />
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)<br />
{<br />
int wmId, wmEvent;<br />
PAINTSTRUCT ps;<br />
HDC hdc;<br />
<br />
<br />
switch (message) <br />
{<br />
case WM_COMMAND:<br />
wmId = LOWORD(wParam); <br />
wmEvent = HIWORD(wParam); <br />
switch (wmId)<br />
{<br />
case IDM_OK:<br />
break;<br />
case IDM_CANCEL:<br />
DestroyWindow(hWnd);<br />
default:<br />
return DefWindowProc(hWnd, message, wParam, lParam);<br />
<br />
}<br />
break;<br />
case WM_CREATE:<br />
SHMENUBARINFO mbi;<br />
<br />
memset(&mbi, 0, sizeof(SHMENUBARINFO));<br />
mbi.cbSize = sizeof(SHMENUBARINFO);<br />
mbi.hwndParent = hWnd;<br />
mbi.nToolBarId = IDR_MENU;<br />
mbi.hInstRes = g_hInst;<br />
<br />
if (!SHCreateMenuBar(&mbi)) <br />
{<br />
g_hWndMenuBar = NULL;<br />
}<br />
else<br />
{<br />
g_hWndMenuBar = mbi.hwndMB;<br />
}<br />
<br />
break;<br />
case WM_PAINT:<br />
hdc = BeginPaint(hWnd, &ps);<br />
<br />
EndPaint(hWnd, &ps);<br />
break;<br />
case WM_DESTROY:<br />
CommandBar_Destroy(g_hWndMenuBar);<br />
PostQuitMessage(0);<br />
break;<br />
<br />
<br />
default:<br />
return DefWindowProc(hWnd, message, wParam, lParam);<br />
}<br />
return 0;<br />
}<br />
<br />
<br />
<br />
BOOL CALLBACK TaskManagerDlgProc(const HWND hTaskManDlg, const UINT uIMessage, <br />
const WPARAM wParam, LPARAM lParam)<br />
{<br />
<br />
HWND statusHandle = GetDlgItem(hTaskManagerDlg,IDC_STATIC_STATUS);<br />
<br />
BOOL hIsHandled = TRUE;<br />
switch(uIMessage)<br />
{<br />
case WM_COMMAND:<br />
{ <br />
switch(LOWORD(wParam))<br />
{<br />
case IDCANCEL:<br />
hIsHandled = TRUE;<br />
DestroyWindow(hTaskManagerDlg);<br />
PostQuitMessage(0);<br />
break;<br />
case IDC_BUTTON_STOPPROCESS:<br />
<br />
hIsHandled = TRUE;<br />
default:<br />
hIsHandled = FALSE;<br />
}<br />
}<br />
case WM_PAINT:<br />
SetWindowText(statusHandle,TEXT("Running..."));<br />
break;<br />
<br />
}<br />
<br />
return hIsHandled;<br />
<br />
}<br />
<br />
<br />
<br />
DWORD WINAPI ProcessViewThread(PVOID lParam)<br />
{<br />
<br />
<br />
<br />
static int index = 0;<br />
HANDLE snapHand;<br />
PROCESSENTRY32 procEntry;<br />
procEntry.dwSize = sizeof(PROCESSENTRY32);<br />
snapHand = CreateToolhelp32Snapshot(TH32CS_SNAPALL|TH32CS_SNAPPROCESS,0);<br />
if(INVALID_HANDLE_VALUE == snapHand)<br />
return -1;<br />
if(!Process32First(snapHand,&procEntry))<br />
{<br />
if(GetLastError() == ERROR_NO_MORE_FILES)<br />
{<br />
SendMessage(hListWnd,LB_ADDSTRING,0,LPARAM(TEXT("EndOfListing")));<br />
}<br />
return -1;<br />
}<br />
procEntry.dwSize = sizeof(procEntry);<br />
do<br />
{<br />
SendMessage(hListWnd,LB_ADDSTRING,index,LPARAM(procEntry.szExeFile));<br />
SendMessage(hListWnd,LB_SETCURSEL,index,0);<br />
index++;<br />
}while(Process32Next(snapHand,&procEntry));<br />
<br />
HWND stopHandle = GetDlgItem(hTaskManagerDlg,IDC_BUTTON_STOPPROCESS);<br />
::SetFocus(stopHandle);<br />
<br />
<br />
CloseToolhelp32Snapshot(snapHand);<br />
<br />
<br />
<br />
return 0;<br />
<br />
<br />
}<br />
|
|
|
|
|
During debug I am getting following error on Desktop:
"The Connection to the target device has been broken.
Debugging will now stop.
You must now exit and restart eVC"
And the program is exiting with following message in debug window.
The program '...\...' has exited with code -1159943394 (0xBADCAB1E).
|
|
|
|
|