#include <windows.h>       
#include <ole2.h>
#include <shellapi.h>
#include <initguid.h>

#include "resource.h"
#include "typbrows.h" 

TYPEINFOBLOCK tib [1000] ;

extern HINSTANCE hInst ;

BOOL CALLBACK  MainDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{   
	switch (msg)
	{         
		case WM_INITDIALOG:
		{                    
			HKEY lTypeLibKey, lNameKey ;
			DWORD SubKey = 0, index = 0 ;
			LONG lResult ;    
			OLECHAR ClassIdString [128] ;
			long AppNameLength ;
			HRESULT hr ;			
			
/*
Open a key to the type library section of the registry
*/
			lResult = RegOpenKey (HKEY_CLASSES_ROOT, TEXT("TypeLib"), &lTypeLibKey) ;
			             
/*
For each key, get the first value (the typelib class ID as a string)
*/
			             
			while (RegEnumKey(lTypeLibKey, SubKey, ClassIdString, sizeof(ClassIdString)) == ERROR_SUCCESS)
			{ 	
				lResult = RegOpenKey (lTypeLibKey, ClassIdString, &lNameKey) ;         // open key to the clsid

				DWORD VersionNum = 0 ;
				OLECHAR VerString [128], *pDec ;

				while (RegEnumKey (lNameKey, VersionNum, VerString, sizeof(VerString)) == ERROR_SUCCESS)
				{
					AppNameLength = 128 ;  
					lResult = RegQueryValue (lNameKey, VerString, tib[index].name,  &AppNameLength) ;				
					lstrcat (tib[index].name, VerString) ;
					tib[index].wVerMajor = _wtoi (VerString) ;

					pDec = wcschr (VerString,'.') ;
					if (pDec == NULL)
					{
						tib[index].wVerMinor = 0 ;
						MessageBox (NULL, VerString, L"Bad Minor Version", 0) ;
					}
					else
					{
						tib[index].wVerMinor = _wtoi (pDec+1) ;
					}

					SendDlgItemMessage (hDlg, IDC_LIST1, LB_ADDSTRING, 0, (LPARAM)((LPSTR) (tib[index].name))) ;  
					hr = CLSIDFromString (ClassIdString, &(tib[index].clsid)) ;

					VersionNum ++ ;
					index ++ ;
				}


			    RegCloseKey (lNameKey) ;
			
				SubKey ++ ; 	// 0-based
			}
			
			RegCloseKey (lTypeLibKey) ;
		
			return FALSE ;
		}
		
		case WM_COMMAND:
		{
			switch (LOWORD(wParam))
			{
				case IDOK:
				{   
					if (HIWORD(wParam) == BN_CLICKED)
					{
						SendMessage (hDlg, WM_CLOSE, 0, 0) ;
					}
					return TRUE ;
				}
				
				case IDC_LIST1:
				{   
					if(HIWORD(wParam) == LBN_DBLCLK)
					{ 
						SendMessage (hDlg, WM_COMMAND, IDC_BUTTON2, 0) ;                        
					}
					return TRUE ;				
				}

				case IDC_BUTTON1:
				{
					OPENFILENAME of ;
					TCHAR File [128] ;
					HRESULT hr ;
					LPTYPELIB pTypeLib ;

					File [0] = 0x00 ;
				

					ZeroMemory (&of, sizeof (of)) ;

					of.lStructSize = sizeof (of) ;
					of.hwndOwner = NULL ;
					of.lpstrFile = File ;
					of.nMaxFile = sizeof (File) ;
					of.lpstrFilter = TEXT("Type Libraries (*.TLB)\0*.TLB\0") ;

					if (GetOpenFileName (&of))
					{
	   					hr = LoadTypeLib (File, &pTypeLib) ;

						if (SUCCEEDED(hr))
						{
							CreateDialogParam (hInst, MAKEINTRESOURCE(IDD_BROWSE), NULL, 
								(FARPROC)TypeBrowseProc, (LPARAM)pTypeLib) ;
							pTypeLib->Release( ) ;
						}
						else
						{
							MessageBox (hDlg, TEXT("Couldn't open type lib file"), TEXT("Error"), MB_ICONSTOP) ;
						}
					}
					return TRUE ;

				}

				case IDC_BUTTON2:
				{
					LPTYPELIB pTypeLib ;

		  			LRESULT lr = SendDlgItemMessage (hDlg, IDC_LIST1, LB_GETCURSEL, 0, 0L) ;					
					HRESULT hr = LoadRegTypeLib (((tib[lr].clsid)), tib[lr].wVerMajor, tib[lr].wVerMinor, 0, &pTypeLib) ;

   				 	if (!SUCCEEDED(hr))
    				{
    					MessageBox (NULL, TEXT("Couldn't load type lib"), TEXT("Error"), 0) ;
    				}
    				else
					{
						CreateDialogParam (hInst, MAKEINTRESOURCE(IDD_BROWSE), hDlg ,
							(DLGPROC)TypeBrowseProc , (LPARAM)pTypeLib) ;
						pTypeLib->Release( ) ;
					}

					return TRUE ;
				}
			}
			return FALSE ;
		}

		case WM_CLOSE:
		{
			DestroyWindow (hDlg) ;
			return TRUE ;
		}

		case WM_DESTROY:
		{
			PostQuitMessage (0) ;
			return TRUE ;
		}
	}
	return FALSE ;
}
