Click here to Skip to main content
15,886,724 members
Articles / Programming Languages / eVC

A Simple Windows Mobile 5.0 Task Enumerator

Rate me:
Please Sign up or sign in to vote.
4.38/5 (6 votes)
11 Dec 2005CPOL2 min read 63.7K   409   25  
A simple task enumerator for Windows Mobile SmartPhones.
// SmartPhoneTaskManager.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "SmartPhoneTaskManager.h"
#include "Tlhelp32.h"
#include <windows.h>
#include <commctrl.h>

#define SUCCESS 0
#define FAILURE -1


#define MAX_LOADSTRING 100
#define MENU_HEIGHT 26
// Global Variables:
HINSTANCE                        g_hInst;                        // current instance
HWND                             g_hWndMenuBar;                // menu bar handle
HWND g_hWndTaskManMenuBar;
HWND statusHandle;
HWND hMainWnd;
// Forward declarations of functions included in this code module:
ATOM                       MyRegisterClass(HINSTANCE, LPTSTR);
BOOL                        InitInstance(HINSTANCE, int);
LRESULT CALLBACK        WndProc(HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK TaskManagerDlgProc(const HWND hTaskManDlg, const UINT
								 uIMessage,
								 const WPARAM wParam, LPARAM lParam);

int StopProcess(char* processname);

int FindLastError();

int WINAPI WinMain(HINSTANCE hInstance,
				   HINSTANCE hPrevInstance,
				   LPTSTR    lpCmdLine,
				   int       nCmdShow)
{
	MSG msg;

	// Perform application initialization:
	if (!InitInstance(hInstance, nCmdShow))
	{
		return FALSE;
	}


	// Main message loop:
	while (GetMessage(&msg, NULL, 0, 0))
	{
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}

	return (int) msg.wParam;
}

//
//  FUNCTION: MyRegisterClass()
//
//  PURPOSE: Registers the window class.
//
//  COMMENTS:
//
ATOM MyRegisterClass(HINSTANCE hInstance, LPTSTR szWindowClass)
{
	WNDCLASS wc;

	wc.style         = CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc   = WndProc;
	wc.cbClsExtra    = 0;
	wc.cbWndExtra    = 0;
	wc.hInstance     = hInstance;
	wc.hIcon         = LoadIcon(hInstance,
		MAKEINTRESOURCE(IDI_SMARTPHONETASKMANAGER));
	wc.hCursor       = 0;
	wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
	wc.lpszMenuName  = 0;
	wc.lpszClassName = szWindowClass;

	return RegisterClass(&wc);
}

//
//   FUNCTION: InitInstance(HINSTANCE, int)
//
//   PURPOSE: Saves instance handle and creates main window
//
//   COMMENTS:
//
//        In this function, we save the instance handle in a global variable and
//        create and display the main program window.
//
HWND hTaskManagerDlg;
HWND hListWnd;
DWORD WINAPI ProcessViewThread(PVOID lParam);

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
	volatile BOOL status = FALSE;
	HWND hWnd;
	TCHAR szTitle[MAX_LOADSTRING];                // title bar text
	TCHAR szWindowClass[MAX_LOADSTRING];        // main window class name

	g_hInst = hInstance; // Store instance handle in our global variable


	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
	LoadString(hInstance, IDC_SMARTPHONETASKMANAGER, szWindowClass,MAX_LOADSTRING);

	//If it is already running, then focus on the window, and exit
	hWnd = FindWindow(szWindowClass, szTitle);
	if (hWnd)
	{
		status = TRUE;
		// set focus to foremost child window
		// The "| 0x00000001" is used to bring any owned windows to the	foreground and
		// activate them.
		status = SetForegroundWindow((HWND)((ULONG) hWnd | 0x00000001));
		return status;
	}
	status = TRUE;
	if(status == TRUE)
	{
		if(MyRegisterClass(hInstance, szWindowClass) != 0)
			status = TRUE;
	
	}

	if(status == TRUE)
	{

		hWnd = CreateWindow(szWindowClass, szTitle, WS_VISIBLE,
				CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL,
				NULL, hInstance, NULL);
		if (!hWnd)
		{
			status = FALSE;
		}

	}

	RECT rc;

	if( status == TRUE )
	{
		hMainWnd = hWnd;
		status = GetWindowRect(hWnd, &rc);
	}

	if(status == TRUE)
	{
		rc.bottom -= MENU_HEIGHT;
		MoveWindow(hWnd, rc.left, rc.top, rc.right, rc.bottom, FALSE);
	
	}

	if(status == TRUE)
	{
		status = ShowWindow(hWnd,nCmdShow);
	
	}

	if(hWnd)
		UpdateWindow(hWnd);
	if(status == TRUE)
	{
		hTaskManagerDlg =
			CreateDialog(hInstance,MAKEINTRESOURCE(IDD_DIALOG_TASKMAN),hWnd/*NULL*/,(DLGPROC)TaskManagerDlgProc);
		if(!hTaskManagerDlg)
		{
			MessageBox(NULL,TEXT("Could not start taskman"),TEXT("Taskman Failed"),MB_OK|MB_ICONERROR);
			status = FALSE;
		}
		else
			status = TRUE;
	}

	if(status == TRUE)
		status = ShowWindow(hTaskManagerDlg,nCmdShow);

	SetWindowText(hTaskManagerDlg,TEXT("Smartphone Task Manager"));
	if(hTaskManagerDlg)
		status = UpdateWindow(hTaskManagerDlg);
	
	hListWnd = ::GetDlgItem(hTaskManagerDlg,IDC_LIST_ENUM_TASKS);

	if(hListWnd == NULL)
	{
		status = FALSE;
	}
	else 
		status = TRUE;
	if(status == TRUE)
		::SetFocus(hListWnd);

	UpdateWindow(hListWnd);

	
	DWORD threadID;
	if(status == TRUE)
	{
		if(CreateThread(NULL,0,&ProcessViewThread,0,0,&threadID) == NULL)
		{
			status = FALSE;
		}
	}
	return status;

}

//
//  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  PURPOSE:  Processes messages for the main window.
//
//  WM_COMMAND        - process the application menu
//  WM_PAINT        - Paint the main window
//  WM_DESTROY        - post a quit message and return
//
//


LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
						 lParam)
{
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	HDC hdc;


	switch (message)
	{
	case WM_COMMAND:
		wmId    = LOWORD(wParam);
		wmEvent = HIWORD(wParam);
		// Parse the menu selections:
		switch (wmId)
		{
		case IDM_OK:
			// DestroyWindow(hWnd);
			break;
		case IDM_CANCEL:
			if(!DestroyWindow(hWnd))
				return FALSE;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);

		}
		break;
	case WM_CREATE:
		SHMENUBARINFO mbi;

		memset(&mbi, 0, sizeof(SHMENUBARINFO));
		mbi.cbSize     = sizeof(SHMENUBARINFO);
		mbi.dwFlags = SHCMBF_HMENU;
		mbi.hwndParent = hWnd;
		mbi.nToolBarId = IDR_MENU;
		mbi.hInstRes   = g_hInst;

		if (!SHCreateMenuBar(&mbi))
		{
			g_hWndMenuBar = NULL;
		}
		else
		{
			g_hWndMenuBar = mbi.hwndMB;
		}

		break;
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);
		// TODO: Add any drawing code here...

		EndPaint(hWnd, &ps);
		break;
	case WM_DESTROY:
		CommandBar_Destroy(g_hWndMenuBar);
		PostQuitMessage(0);
		break;


	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}




BOOL CALLBACK TaskManagerDlgProc(const HWND hTaskManDlg, const UINT
								 uIMessage,
								 const WPARAM wParam, LPARAM lParam)
{

	WPARAM curSel = 0;
	SHMENUBARINFO taskManMenuBarInfo;
/*	statusHandle =  GetDlgItem(hTaskManDlg,IDC_STATIC_STATUS);
	if(statusHandle == NULL)
		return FALSE;*/
	BOOL hIsHandled = TRUE;
	char* message;
	message = new char[50];
	if(!message)
		return FALSE;
	memset(message,0,50);

	switch(uIMessage)
	{
		
	//case WM_CREATE:
	case WM_INITDIALOG:
		/* Create our custom menu bar here...*/
		memset(&taskManMenuBarInfo,0,sizeof(SHMENUBARINFO));
		taskManMenuBarInfo.cbSize = sizeof(SHMENUBARINFO);
		taskManMenuBarInfo.dwFlags = SHCMBF_HMENU;
		taskManMenuBarInfo.hwndParent = hTaskManDlg;
		taskManMenuBarInfo.nToolBarId = IDR_MENU_BAR;
		taskManMenuBarInfo.hInstRes = g_hInst;
		if(!SHCreateMenuBar(&taskManMenuBarInfo))
		{
		//	MessageBox(NULL,TEXT("Menu failed"),TEXT("Menu failed"),MB_OK|MB_ICONERROR);
				g_hWndTaskManMenuBar = NULL;
			
		}
		else
		{
			g_hWndTaskManMenuBar = taskManMenuBarInfo.hwndMB;
				
		}
		ShowWindow(g_hWndTaskManMenuBar,SW_SHOW);
		// break;
		//return TRUE;
		return FALSE;


	case WM_COMMAND:
	{
			// Task manager UI event notifications here ...
			switch(LOWORD(wParam))
			{
			case IDCANCEL:
				hIsHandled = TRUE;
				if(!DestroyWindow(hTaskManagerDlg))
					return FALSE;
				PostQuitMessage(0);
				break;
			case ID_EXIT:
				if(!DestroyWindow(hTaskManagerDlg))
					return FALSE;
				SendMessage(hMainWnd,WM_DESTROY,0,0);
				PostQuitMessage(0);
				break;
				
		
			case IDC_BUTTON_STOPPROCESS:
			case ID_COMMAND_SUSPENDSELECTED:
				// Get the handle of the process user selected.
				// End that process here...
				memset(message,0,50);
				curSel = SendMessage(hListWnd,LB_GETCURSEL,0,0);
				if(curSel == LB_ERR)
					return FALSE;
				
				if(SendMessage(hListWnd,LB_GETTEXT,curSel,(LPARAM)message) == LB_ERR)
					return FALSE;
				if(StopProcess(message)==FAILURE)
				{
					FindLastError();
				}
				else
				{
					if(SendMessage(hListWnd,LB_DELETESTRING,curSel,0) == LB_ERR)
						return FALSE;
					if(SendMessage(hListWnd,LB_SETCURSEL,curSel,0) == LB_ERR)
						return FALSE;
				}
				hIsHandled = TRUE;
				break;
			case IDSUSPEND:
			case ID_COMMAND_SUSPENDALL:
				keybd_event(VK_OFF,0,KEYEVENTF_SILENT,0);
				keybd_event(VK_OFF,0,KEYEVENTF_SILENT | KEYEVENTF_KEYUP,0);
				Sleep(5);
				break;

			case IDC_LIST_ENUM_TASKS:
			switch(HIWORD(wParam))
			{
				case LBN_DBLCLK:
					memset(message,0,50);
					curSel = SendMessage(hListWnd,LB_GETCURSEL,0,0);

					SendMessage(hListWnd,LB_GETTEXT,curSel,(LPARAM)message);
					if(StopProcess(message)==FAILURE)
						FindLastError();
					else
					{
						if(SendMessage(hListWnd,LB_DELETESTRING,curSel,0) == LB_ERR)
							return FALSE;
						if(SendMessage(hListWnd,LB_SETCURSEL,curSel,0)== LB_ERR)
							return FALSE;
					}
					hIsHandled = TRUE;
					break;
			}
			break;
				
			default:
				hIsHandled = FALSE;
			}

	}

	case WM_PAINT:
		UpdateWindow(statusHandle);
		break;
	}


	if(message)
	{
		delete [] message;
		message = NULL;
	}

	

	return hIsHandled;

}


/**
Return type: DWORD
Type: WINAPI
Function Name: ProcessViewThread
Arguments: PVOID lParam
Description: Thread for enumerating all the processes running in the system.
Dependencies: Tlhelp32.lib library
*/
DWORD WINAPI ProcessViewThread(PVOID lParam)
{
 	static int index = 0;
	HANDLE snapHand;
	PROCESSENTRY32 procEntry;
	procEntry.dwSize = sizeof(PROCESSENTRY32);
	snapHand = CreateToolhelp32Snapshot(TH32CS_SNAPALL|TH32CS_SNAPPROCESS,0);
	if(INVALID_HANDLE_VALUE == snapHand)
		return -1;
	if(!Process32First(snapHand,&procEntry))
	{
		if(GetLastError() ==  ERROR_NO_MORE_FILES)
		{
			SendMessage(hListWnd,LB_ADDSTRING,0,LPARAM(TEXT("EndOfListing")));
		}
		return -1;
	}
	procEntry.dwSize = sizeof(procEntry);
	do
	{
		SendMessage(hListWnd,LB_ADDSTRING,index,LPARAM(procEntry.szExeFile));
		SendMessage(hListWnd,LB_SETCURSEL,index,0);
		index++;
	}while(Process32Next(snapHand,&procEntry));

	HWND stopHandle = GetDlgItem(hTaskManagerDlg,IDC_BUTTON_STOPPROCESS);
	::SetFocus(stopHandle);

	CloseToolhelp32Snapshot(snapHand);
	return 0;


}

/**
	Function Name: StopProcess
	Behavior: Debugging/Process Management
	Description: Terminates a running process, given its name.
	Return Type: int (SUCCESS or FAILURE)
	Argument: char*(Name of the process to be terminated)

*/
int StopProcess(char* processname)
{

	volatile int status = FAILURE;
	HANDLE procHand;
	PROCESS_INFORMATION procInfo;
	if(processname == NULL)
		status = FAILURE;
	else
		status = SUCCESS;
	if(status != FAILURE)
	{
		status = CreateProcess((LPCWSTR)processname,NULL,NULL,NULL,FALSE,INHERIT_CALLER_PRIORITY|DEBUG_PROCESS,NULL,NULL,NULL,&procInfo);
		if(status == TRUE)
		{

			procHand = OpenProcess(PROCESS_TERMINATE,FALSE,procInfo.dwProcessId);
			if(procHand == NULL)
			{
				status = FAILURE;
			}
			if(status != FAILURE)
			{
					status = TerminateProcess(procHand,0);
					if(status)
						status = SUCCESS;
					else
						status = FAILURE;

			}

		}
		else
			status = FAILURE;
		
	}
		

	return status;


}
/***
	Function Name: FindLastError
	Behavior: Error Reporting
	Return Type: int
	Arguments: None 
	Description: Shows the last error in a readable format.
*/
int FindLastError()
{
	LPVOID lpMsgBuf;
	int error = GetLastError();
	FormatMessage( 
		FORMAT_MESSAGE_ALLOCATE_BUFFER | 
		FORMAT_MESSAGE_FROM_SYSTEM | 
		FORMAT_MESSAGE_IGNORE_INSERTS,
		NULL,
		error,
		0, // Default language
		(LPTSTR) &lpMsgBuf,
		0,
		NULL 
		);
	// Process any inserts in lpMsgBuf.
	// ...
	// Display the string.
	if(error != 14)
	{
		SetWindowText(statusHandle,(LPCTSTR)lpMsgBuf);
	}
	else
	{
//		SetWindowText(statusHandle,(LPCTSTR)"Not enough memory for this operation.");
	}

#ifdef DEBUG
	if(lpMsgBuf)
	{
		LocalFree( lpMsgBuf );
		lpMsgBuf = NULL;
	}
#endif



	return error;

}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Technical Lead
India India
I am a personality from Trivandrum , a green peaceful place in Kerala, South India.
I have been an enthusiast of Windows programming when I started creating simple windows when I learnt VC++ in LCC in Trivandrum. From then on its all about Windows in my flesh and blood.
My career graph moves like this:
1. I started working as a C/C++ programmer in a company in Trivandrum where I learnt the ABCs of Software Industry. I worked with them for about 1 year. I could not contine since I was in contract for 1 year.
2. Then I joined another organization in Trivandrum who gave me challenges to love. They made me mad about VC++ and Windows.
I was mad about Embedded Systems which made me, Myself = Embedded Systems + VC++.
3. Software Engineer in a telecom company in Hyderabad, Andhra Pradesh, S.India.
4. Currently working with a telecom company in Bangalore.
I totally, so, have experience of about 4.5 years.

Comments and Discussions