Click here to Skip to main content
15,886,518 members
Articles / Programming Languages / C++

Simple Reminder Application

Rate me:
Please Sign up or sign in to vote.
3.88/5 (19 votes)
22 Sep 2006CPOL6 min read 143.4K   13.2K   33  
The article presents a simple Reminder application, using registry to store the reminders.
#include "Status_List_Reg.h"
#include "Dialog_Date.h"
#include "Reminder_APP.h"
#include "resource.h"


//Global Data
TCHAR ApplicationRegKey[]=L"Software\\Kavitesh Singh - Reminder Application";
extern HWND hListViewControl;
extern int	ApplicationStartUpStatus;
extern int RightClickMenuStatus;


//create Menu for the application without using resource
HMENU MenuDisplay(const HWND hwnd)
{
	HMENU hMenu;
	HMENU hMenuPopup;
	//main menu bar
	hMenu=CreateMenu();
	if(hMenu==NULL)
	{
		MessageBox(NULL,TEXT("Menu Build Error"),TEXT("Error"),0);
		return FALSE;
	}
	//first drop down menu
	hMenuPopup = CreatePopupMenu () ;
	AppendMenu (hMenuPopup, MF_STRING,    IDM_SYS_ADD_REMINDER, TEXT("Add New Reminder")) ;
	AppendMenu (hMenuPopup, MF_STRING,    IDM_SYS_APP_HIDE,		TEXT("H&ide Application")) ;
	AppendMenu (hMenuPopup, MF_STRING,    IDM_APP_EXIT,			TEXT("E&xit Application")) ;
	AppendMenu (hMenuPopup, MF_SEPARATOR, 0, NULL) ;
	AppendMenu (hMenuPopup, MF_STRING,    IDM_APP_ABOUT,		TEXT("A&bout Application")) ;
	AppendMenu (hMenu, MF_POPUP, (UINT_PTR)hMenuPopup,			TEXT("&File")) ;
	//second drop down menu
	hMenuPopup=CreatePopupMenu();
	AppendMenu (hMenuPopup, MF_STRING,    IDM_SYS_DELETE_ALL_REMINDER,	TEXT("Delete All Reminders")) ;
	AppendMenu (hMenuPopup, MF_STRING,    IDM_APP_STARTUP,	TEXT("Start at Logon")) ;
	AppendMenu (hMenu, MF_POPUP, (UINT_PTR)hMenuPopup,		TEXT("&Options")) ;
	if(!SetMenu(hwnd,hMenu))
		return (HMENU)-1;
	else 
		return hMenu;
	
}

//create pop-up menu when clicked on tray icon
HMENU SystemTrayMenu(const HWND hwnd)
{
	HMENU hMenuPopup;
	POINT pt;

	//directly create a pop up which will be displayed on right click. 
	//no main menu is required
	hMenuPopup=CreatePopupMenu();
	AppendMenu (hMenuPopup, MF_STRING,    IDM_SYS_ADD_REMINDER, TEXT("&Add New Reminder")) ;
	AppendMenu (hMenuPopup, MF_STRING,    IDM_SYS_APP_SHOW,		TEXT("S&how Application")) ;
	AppendMenu (hMenuPopup, MF_STRING,    IDM_SYS_APP_HIDE,		TEXT("H&ide Application")) ;
	AppendMenu (hMenuPopup, MF_STRING,    IDM_APP_STARTUP,		TEXT("Start at Logon")) ;
	AppendMenu (hMenuPopup, MF_STRING,    IDM_APP_EXIT,			TEXT("E&xit Application")) ;
	AppendMenu (hMenuPopup, MF_SEPARATOR, 0, NULL) ;
	AppendMenu (hMenuPopup, MF_STRING,    IDM_APP_ABOUT,		TEXT("A&bout Application")) ;
	//for check to be displayed on system tray menu also
		if(ApplicationStartUpStatus)
			CheckMenuItem(hMenuPopup,3,MF_BYPOSITION|MF_CHECKED);
		else
			CheckMenuItem(hMenuPopup,3,MF_BYPOSITION|MF_UNCHECKED);

	//capture the point where mouse click has happened and display menu there.
	GetCursorPos(&pt);
	SetForegroundWindow(hwnd);
	TrackPopupMenu(hMenuPopup, TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, 0, hwnd, NULL);
	//on right click on icon the system menu of windows use to pop up
	//so had send a null msg to maintain control after showing menu.
	PostMessage(hwnd, WM_NULL, 0, 0);
	return hMenuPopup;
}

//create right click menu on list view control
HMENU RightClickMenuonListView(const HWND hwnd)
{	
	HMENU hMenuPopup;
	POINT pt;

	//directly create a pop up which will be displayed on right click. 
	//no main menu is required
	hMenuPopup=CreatePopupMenu();
	AppendMenu (hMenuPopup, MF_STRING,    IDM_SYS_EDIT_REMINDER,TEXT("Edit Reminder")) ;
	AppendMenu (hMenuPopup, MF_STRING,    IDM_SYS_DEL_REMINDER,TEXT("Delete Reminder")) ;
	AppendMenu (hMenuPopup, MF_SEPARATOR, 0, NULL) ;
	AppendMenu (hMenuPopup, MF_STRING,    IDM_SYS_ADD_REMINDER, TEXT("Add New Reminder")) ;
	
	//no data in listview or clicked on empty space
	if(RightClickMenuStatus==0)
	{
		EnableMenuItem(hMenuPopup,0,MF_BYPOSITION|MF_GRAYED);
		EnableMenuItem(hMenuPopup,1,MF_BYPOSITION|MF_GRAYED);
	}
	else
	{
		EnableMenuItem(hMenuPopup,0,MF_BYPOSITION|MF_ENABLED);
		EnableMenuItem(hMenuPopup,1,MF_BYPOSITION|MF_ENABLED);
	}
	//capture the point where mouse click has happened and display menu there.
	GetCursorPos(&pt);
	//SetForegroundWindow(hwnd);
	TrackPopupMenu(hMenuPopup, TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, 0, hwnd, NULL);
	return hMenuPopup;

}





//create Status bar
HWND CreateStatusBar(const HWND hwnd)
{
	static int cyVScroll;
	LRESULT lResult;
	int i=3;
	int a[3]={100,200,-1};
	HWND hStatusBar=CreateStatusWindow(WS_CHILD|WS_VISIBLE ,L"",hwnd,ID_STATUS_BAR);
	lResult = SendMessage( hStatusBar, (UINT) SB_SIMPLE,(WPARAM) FALSE,0 );
	//create status bar with 3 parts and initialize it with blank text
	lResult = SendMessage(hStatusBar,(UINT) SB_SETPARTS,(WPARAM) i,(LPARAM) a);
	lResult = SendMessage(hStatusBar,(UINT) SB_SETTEXT,(WPARAM) 0,(LPARAM) L"");
	lResult = SendMessage(hStatusBar,(UINT) SB_SETTEXT,(WPARAM) 1,(LPARAM) L"");
	lResult = SendMessage(hStatusBar,(UINT) SB_SETTEXT,(WPARAM) 2,(LPARAM) L"");
	return hStatusBar;
}

//Display time in the parts of status bar
void DisplayClockDateStatusBar(const HWND hStatusBar)
{
	LVITEM lvItem = {sizeof(LVITEM)};
	TCHAR szBuffer[260]=L"";
	TCHAR szSystemDate[20]=L"";
	TCHAR szSystemTime[20]=L"";
	GetTimeFormat(LOCALE_USER_DEFAULT,NULL,NULL,NULL,szSystemTime,sizeof(szSystemTime));
	GetDateFormat(LOCALE_USER_DEFAULT,NULL,NULL,NULL,szSystemDate,sizeof(szSystemDate));
	SendMessage(hStatusBar,(UINT) SB_SETTEXT,(WPARAM) 0,(LPARAM) szSystemDate);
	SendMessage(hStatusBar,(UINT) SB_SETTEXT,(WPARAM) 1,(LPARAM) szSystemTime);

	//to get first reminder in the list view control
	lvItem.mask=LVIF_TEXT;
	lvItem.iItem=0;
	lvItem.iSubItem=2;
	lvItem.cchTextMax=255;
	lvItem.pszText=szBuffer;

	if(SendMessage(hListViewControl,LVM_GETITEM,0,(LPARAM)&lvItem))
	{
				SendMessage(hStatusBar,(UINT) SB_SETTEXT,(WPARAM) 2,(LPARAM) szBuffer);
	}
	else
		SendMessage(hStatusBar,(UINT) SB_SETTEXT,(WPARAM) 2,(LPARAM) L" Reminder Application by Kavitesh Singh");

}



HWND CreateListViewBox(const HINSTANCE hInstance,const HWND hwnd)
{
	LVCOLUMN LvCol; // Make Coluom struct for ListView
	LVITEM LvItem;  // ListView Item struct
	HWND hListControl=CreateWindowW(L"SysListView32",NULL,
		LVS_REPORT|WS_BORDER|WS_TABSTOP |WS_CHILD|LVS_SINGLESEL|LVS_NOSORTHEADER ,
		10,10,600,400,hwnd,NULL,hInstance,NULL);
	ListView_SetExtendedListViewStyle( hListControl,LVS_EX_FULLROWSELECT|LVS_EX_ONECLICKACTIVATE );
	ShowWindow(hListControl,SW_SHOW);
	memset(&LvCol,0,sizeof(LvCol)); // Reset Coluom
	LvCol.mask=LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM; // Type of mask
	LvItem.iSubItem=0; 
	// Inserting Couloms as much as we want
	//column 1
	LvCol.cx=100;          // width between each coloum  
	LvCol.pszText=L"Date";                     // First Header
	SendMessage(hListControl,LVM_INSERTCOLUMN,0,(LPARAM)&LvCol); // Insert/Show the coloum
	//column 2
	LvCol.cx=100;
	LvCol.pszText=L"Time";                          // Next coloum
	SendMessage(hListControl,LVM_INSERTCOLUMN,1,(LPARAM)&LvCol); 
	//column 3
	LvCol.cx=400;
	LvCol.pszText=L"Reminder";                          // Next coloum
	SendMessage(hListControl,LVM_INSERTCOLUMN,2,(LPARAM)&LvCol); 
	return hListControl;
}


//a general function to fill the list view with all three parameters.
int AddListViewRow(const HWND hControl, TCHAR *szItemText, TCHAR *szSubItemText1,TCHAR *szSubItemText2)
{
	LVITEM LvItem;  // ListView Item struct
	DWORD  lResult=0;
	LvItem.mask=LVIF_TEXT;   // Text Style
	LvItem.cchTextMax = 256; // Max size of text
    LvItem.iItem= (int)SendMessage(hControl,LVM_GETITEMCOUNT,0,0); //add after last value  
	LvItem.iSubItem=0;       // Put in first coluom
	LvItem.pszText=szItemText; // Text to display (can be from a char variable) (Items)
    lResult=(int)SendMessage(hControl,LVM_INSERTITEM,0,(LPARAM)&LvItem); // Send to the Listview
	//to add data to subitem
	LvItem.iSubItem=1;       // Put in first coluom
	LvItem.pszText=szSubItemText1; // Text to display (can be from a char variable) (Items)
    lResult=(DWORD)SendMessage(hControl,LVM_SETITEM,0,(LPARAM)&LvItem); // Send to the Listview
	//to add data to subitem
	LvItem.iSubItem=2;       // Put in first coluom
	LvItem.pszText=szSubItemText2; // Text to display (can be from a char variable) (Items)
    lResult=(DWORD)SendMessage(hControl,LVM_SETITEM,0,(LPARAM)&LvItem); // Send to the Listview
	return TRUE;
}



//Create main registry key of application name
HKEY CreateApplicationKey()
{
	HKEY hKey;
	LONG lRet;
	lRet=RegCreateKeyEx(HKEY_CURRENT_USER,ApplicationRegKey,0,NULL,REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL,&hKey,NULL);
	if( lRet != ERROR_SUCCESS )
	{
		MessageBox(NULL,L"Error in Creating Registry Key for Application",L"Registry Error",0);
		PostQuitMessage(0);
		return FALSE;
	}
	else
		return hKey;
}

//general function to add registry data with a Key(szDate),KeyValue(szTime) and KeyValueData(szReminder)
int AddDatatoRegistry(const HKEY hKey, TCHAR *szDate,TCHAR *szTime,TCHAR *szReminder)
{
	HKEY hSubKey;
	int lRet;
	lRet=RegCreateKeyEx(hKey,szDate,0,NULL,REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL,&hSubKey,NULL);
	if( lRet != ERROR_SUCCESS )
	{
		RegCloseKey(hSubKey);
		MessageBox(NULL,L"Error in Creating Registry Key for Reminder",L"Registry Error",0);
		return FALSE;
	}
	lRet=RegSetValueEx(hSubKey,szTime,0,REG_SZ,(BYTE*)szReminder,(lstrlen(szReminder)+1)*sizeof(TCHAR));
	if( lRet != ERROR_SUCCESS )
	{
		RegCloseKey(hSubKey);
		MessageBox(NULL,L"Error in Creating Registry Key for Reminder",L"Registry Error",0);
		return FALSE;
	}
	RegCloseKey(hSubKey);
	return TRUE;
}


//general function to delete registry data with a Key(szDate),KeyValue(szTime).
//The KeyValue(szTime) gets deleted along with the data inside.
int DeleteDatafromRegistry(const HKEY hKey, TCHAR *szDate,TCHAR *szTime)
{
	HKEY hSubKey;
	int lRet;
	lRet=RegOpenKeyEx(hKey,szDate,0,KEY_ALL_ACCESS,&hSubKey);
	if( lRet != ERROR_SUCCESS )
	{
		RegCloseKey(hSubKey);
		//MessageBox(NULL,L"Error in Deleting Registry Key for Reminder",L"Registry Error",0);
		return FALSE;
	}
	lRet=RegDeleteValue(hSubKey,szTime);
	if( lRet != ERROR_SUCCESS )
	{
		RegCloseKey(hSubKey);
		//MessageBox(NULL,L"Error in Deleting Registry Key for Reminder",L"Registry Error",0);
		return FALSE;
	}
	RegCloseKey(hSubKey);
	return TRUE;

}


//search subkey,and value name in registry, if found return the value data.
int SearchRegistryString(const HKEY hKey,TCHAR *szSearchDate,TCHAR *szSearchTime,TCHAR *szReminderData)
{
	HKEY hSubKey;
	LONG lRet;
	DWORD nSubkeys=0;
	DWORD MaxSubKeyLen=0;
	DWORD nValues=0;
	DWORD MaxValueNameLen=0;
	DWORD nIndex=0;
	DWORD nValueName=0;
	TCHAR szValueName[MAX_VALUE_NAME]=L"";
	TCHAR szValueData[MAX_VALUE_NAME]=L"";
	DWORD nValueData=0;
	lRet=RegOpenKey(hKey,szSearchDate,&hSubKey);
	if( lRet != ERROR_SUCCESS )
		return FALSE;
	//Get the no of keys
	lRet= RegQueryInfoKey(hSubKey,NULL,NULL,NULL,&nSubkeys,&MaxSubKeyLen,NULL,&nValues,&MaxValueNameLen,
		NULL,NULL,NULL);
	if( lRet != ERROR_SUCCESS )
	{
		RegCloseKey(hSubKey);
		MessageBox(NULL,L"Error in Searching Registry Key for Reminder",L"Registry Error",0);
		return FALSE;
	}
	//to list all the value names in a subkey.
	if(nValues)
	{
		for(nIndex=0;nIndex<nValues;nIndex++)
		{
			//if ommited then only first key gets printed
			nValueName=MAX_VALUE_NAME;
			nValueData=MAX_VALUE_NAME;
			ZeroMemory(szValueName,sizeof(szValueName));
			lRet=RegEnumValue(hSubKey,nIndex,szValueName,&nValueName,NULL,NULL,(BYTE*)szValueData,&nValueData);
			if (lRet == ERROR_SUCCESS) 
			{
				lRet=lstrcmpi(szValueName,szSearchTime);
				if(0==lRet)
				{
					lstrcpy(szReminderData,szValueData);
					RegCloseKey(hSubKey);
					return TRUE;
				}
				else 
					ZeroMemory(szReminderData,lstrlen(szReminderData));//to reset garbage data if any data
			}
		}
	}
	RegCloseKey(hSubKey);
	return FALSE;
}


//enumerate all the data stored in registry and then add it to listview
int UpdateListViewfromRegistry(const HWND hListView,const HKEY hKey)
{
	HKEY hSubKey;
	LRESULT lRet;
	DWORD nSubKeys=0;
	DWORD nIndexMain=0;
	DWORD nIndexSub=0;
	TCHAR szDate[15]=L"";
	TCHAR szTime[15]=L"";
	TCHAR szReminder[MAX_VALUE_NAME]=L"";
	DWORD nszDate=0;
	DWORD nSubValues=0;
	
	lRet=SendMessage(hListView,LVM_DELETEALLITEMS,0,0);  
	//delete empty keys from registry
	DeleteEmptyKeysfromRegistry(hKey);
	//Get the no of keys
	lRet= RegQueryInfoKey(hKey,NULL,NULL,NULL,&nSubKeys,0,NULL,0,0,NULL,NULL,NULL);
	if( lRet != ERROR_SUCCESS )
	{
		MessageBox(NULL,L"Error in Updating Registry Data in List View Box",L"Registry Error",0);
		return FALSE;
	}
	if(nSubKeys)
	{
		for(nIndexMain=0;nIndexMain<nSubKeys;nIndexMain++)
		{
		//if ommited then only first key gets printed
			nszDate=MAX_KEY_LENGTH;
			lRet=RegEnumKeyEx(hKey,nIndexMain,szDate,&nszDate,NULL,NULL,NULL,NULL);
			if (lRet == ERROR_SUCCESS) 
			{
				lRet=RegOpenKey(hKey,szDate,&hSubKey);
				lRet= RegQueryInfoKey(hSubKey,NULL,NULL,NULL,NULL,NULL,NULL,&nSubValues,NULL,NULL,NULL,NULL);
				if(nSubValues)
				{
					for(nIndexSub=0;nIndexSub<nSubValues;nIndexSub++)
					{
						{
							//require these initilization else wont print subsequent data
							DWORD nszReminder=MAX_VALUE_NAME;
							DWORD nszTime=MAX_VALUE_NAME;

							lRet=RegEnumValue(hSubKey,nIndexSub,szTime,&nszTime,NULL,NULL,(BYTE*)szReminder,&nszReminder);
							if (lRet == ERROR_SUCCESS) 
								AddListViewRow(hListView, szDate, szTime, szReminder);
							ZeroMemory(szTime,sizeof(szTime));
							ZeroMemory(szReminder,sizeof(szReminder));
						}
					}
				}
				RegCloseKey(hSubKey);
			}
		ZeroMemory(szDate,sizeof(szDate));
		}
	}
	//for sorting the list-view box
	SendMessage( hListViewControl,(UINT) LVM_SORTITEMSEX,0,(LPARAM)SortingCodeListViewControl);  
	return TRUE;
}

//sorting list view using callback funtion
int CALLBACK SortingCodeListViewControl(LPARAM lParam1, LPARAM lParam2,LPARAM lParamSort)  
{
	LVITEM lvItem={sizeof(LVITEM)};
	TCHAR szTemp[15]=L"";
	short nDay1=0,nDay2=0;
	short nMonth1=0,nMonth2=0;
	short nYear1=0,nYear2=0;
	short nHour1=0,nHour2=0;
	short nMin1=0,nMin2=0;
	short nAMP1=0,nAMP2=0;
	lvItem.mask = LVIF_TEXT;
	lvItem.iItem = (int) lParam1;
	lvItem.pszText = szTemp;
	lvItem.cchTextMax = 14;
	//for item itself
	lvItem.iSubItem = 0;
	SendMessage(hListViewControl,(UINT) LVM_GETITEM,0,(LPARAM)&lvItem );  
	//get date for first item, lParam has the index of two items being compared
	DateStringtoDateComponents(szTemp,&nDay1, &nMonth1, &nYear1);
	ZeroMemory(szTemp,sizeof(szTemp));
	//for subitem
	lvItem.iSubItem = 1;
	SendMessage(hListViewControl,(UINT) LVM_GETITEM,0,(LPARAM)&lvItem );  
	//get time for first item, lParam has the index of two items being compared
	TimeStringtoTimeComponents(szTemp,&nHour1, &nMin1, &nAMP1);
	ZeroMemory(szTemp,sizeof(szTemp));
	//for second item now
	lvItem.iItem = (int) lParam2;
	//for item itself
	lvItem.iSubItem = 0;
	SendMessage(hListViewControl,(UINT) LVM_GETITEM,0,(LPARAM)&lvItem );  
	//get date for first item, lParam has the index of two items being compared
	DateStringtoDateComponents(szTemp,&nDay2, &nMonth2, &nYear2);
	ZeroMemory(szTemp,sizeof(szTemp));
	//for subitem
	lvItem.iSubItem = 1;
	SendMessage(hListViewControl,(UINT) LVM_GETITEM,0,(LPARAM)&lvItem );  
	//get time for first item, lParam has the index of two items being compared
	TimeStringtoTimeComponents(szTemp,&nHour2, &nMin2, &nAMP2);
	if((nDay1 == nDay2)&&(nMonth1 == nMonth2)&&(nYear1 == nYear2)&&(nHour1 == nHour2)&&(nMin1 == nMin2)&&(nAMP1 == nAMP2))
		return 0;  //no swap
	if(nYear1>nYear2)
		return 1;	//swap
	//date comparison
	if((nMonth2 < nMonth1)||((nDay2 < nDay1)&&(nMonth2 <= nMonth1)))
		return 1;
	//check for same date if same then see if time is different 
	if((nDay2==nDay1)&&(nMonth2==nMonth1)&&(nYear2==nYear1))
	{
		//see past time, should be done after date check
		if(nAMP1>nAMP2)
			return 1;	//swap for am and pm
		//time comparison
		if((nAMP1==nAMP2)&&(((nHour2<nHour1)||((nHour2==nHour1) && nMin2<=nMin1))))
			return 1;		
	}
	return 0; //no swap
}



int CompareCurrentTimewithRegistryDataTimer(const HKEY hKey)
{
	SYSTEMTIME SystemTime;
	TCHAR szSystemDate[20]=L"";
	TCHAR szSystemTime[20]=L"";
	TCHAR szReminder[260]=L"";
	short temp1=0,temp2=0,temp3=0;
	GetLocalTime(&SystemTime);
	//setting time in 12-hr format
	if(SystemTime.wHour<12)
	{
		if(SystemTime.wHour==0)
			temp1=12;
		else
			temp1=SystemTime.wHour;
		temp3=0;
	}
	else
	{
		if(SystemTime.wHour==12)
			temp1=12;
		else
			temp1=SystemTime.wHour-12;
		temp3=1;
	}
	temp2=SystemTime.wMinute;
	TimeComponentstoTimeString(temp1,temp2,temp3,szSystemTime);
	temp1=temp2=temp3=0;
	temp1=SystemTime.wDay;
	temp2=SystemTime.wMonth;
	temp3=SystemTime.wYear;
	DateComponentstoDateString(temp1,temp2,temp3,szSystemDate);
	//once systemtime/date is converted into registry stored format
	//it is searched in registry, if found the reminder is displayed
	if(SearchRegistryString(hKey,szSystemDate,szSystemTime,szReminder))
	{
		for(int i=100;i<150;i++)
			Beep(i+10,25);
		MessageBox(NULL,szReminder,L"Reminder",0);
		//reminder that is triggered is deleted and listview is 
		//updated with new values
		DeleteDatafromRegistry(hKey,szSystemDate,szSystemTime);
		UpdateListViewfromRegistry(hListViewControl,hKey);
		return TRUE;
	}
	return FALSE;
}


//this searches for any empty keys stored and deletes so that
//registry doesnt exceed nnecessarily 
int DeleteEmptyKeysfromRegistry(const HKEY hKey)
{
	HKEY hSubKey;
	LRESULT lRet;
	DWORD nSubKeys=0;
	DWORD nIndexMain=0;
	TCHAR szDate[15]=L"";
	DWORD nszDate=0;
	DWORD nSubValues=0;
	//Get the no of keys
	lRet= RegQueryInfoKey(hKey,NULL,NULL,NULL,&nSubKeys,0,NULL,0,0,NULL,NULL,NULL);
	if( lRet != ERROR_SUCCESS )
	{
		MessageBox(NULL,L"Error in Updating Registry Data in List View Box",L"Registry Error",0);
		return FALSE;
	}
	if(nSubKeys)
	{
		for(nIndexMain=0;nIndexMain<nSubKeys;nIndexMain++)
		{
		//if ommited then only first key gets printed
			nszDate=MAX_KEY_LENGTH;
			lRet=RegEnumKeyEx(hKey,nIndexMain,szDate,&nszDate,NULL,NULL,NULL,NULL);
			if (lRet == ERROR_SUCCESS) 
			{
				lRet=RegOpenKey(hKey,szDate,&hSubKey);
				lRet= RegQueryInfoKey(hSubKey,NULL,NULL,NULL,NULL,NULL,NULL,&nSubValues,NULL,NULL,NULL,NULL);
				if(!nSubValues)
				{
					RegCloseKey(hSubKey);
					lRet=RegDeleteKey(hKey,szDate);					
				}
				else
					RegCloseKey(hSubKey);
			}
		ZeroMemory(szDate,sizeof(szDate));
		}
	}
	return TRUE;
}

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
Software Developer (Senior)
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions