// SDK_CmnControl.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include <commctrl.h>
// And remember to add comctl32.lib to project settings
#include "resource.h"
#include <stdio.h>	// for sprintf
#include <stdlib.h> // for atof

// For our support functions
#include "PNCmnControls.h"


LRESULT CALLBACK DialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam  )
{
	int wID;
	int wNotification;
	HWND hChild;
	RECT Rect, TabRect;

	switch( uMsg )
	{
		case WM_INITDIALOG:
			// Drynamically create an UpDown control
			hChild = CreateWindowEx( WS_EX_CLIENTEDGE, "STATIC", "0", WS_VISIBLE|WS_CHILD, 
				164, 46, 25, 22, hwndDlg, (HMENU)4000, 0, 0 );
			SendMessage( hChild, WM_SETFONT, (SendMessage(hwndDlg,WM_GETFONT,0,0)), 0);
			CreateUpDownControl( WS_CHILD|WS_VISIBLE|UDS_AUTOBUDDY|UDS_SETBUDDYINT,
				189,46,14,22, hwndDlg, 4001, 0, hChild, 100, 0, 0 );

			// Set Minimum and maximum positions for spin control
			hChild = GetDlgItem( hwndDlg, IDC_SPIN1 );
			SendMessage( hChild, UDM_SETRANGE32, 0, 100 );
			SendDlgItemMessage( hwndDlg, IDC_SPININCH, UDM_SETRANGE32, 0, 1000 );

			// Set default for the Inch spin control demo
			SetDlgItemText( hwndDlg, IDC_EDITINCH, "1.00\"" );

			// Initialize the Progress bar with it's range values (defaults to 0 to 100 anyway)
			SendDlgItemMessage( hwndDlg, IDC_PROGRESS1, PBM_SETRANGE32, 0, 100);

			// Initialize the slider control with it's range values (defaults to 0 to 100 anyway)
			SendDlgItemMessage( hwndDlg, IDC_SLIDERH, TBM_SETRANGE, TRUE, MAKELONG( 0, 100 ) );

			// Alternative method, using Programmers Notebook function PNSetSliderRange
			PNSetSliderRange( GetDlgItem( hwndDlg, IDC_SLIDERH ), 0, 100, TRUE );

			// Set selection range for slider control.
			SendDlgItemMessage( hwndDlg, IDC_SLIDERV, TBM_SETSEL, TRUE, MAKELONG(0,50) );

			// ListView and Image List demonstration
			{
			HIMAGELIST hImageList = ImageList_LoadImage( GetModuleHandle(NULL), 
				MAKEINTRESOURCE( IDB_FACEIMGLIST ), 16, 1, RGB(255,255,255), 
				IMAGE_BITMAP, LR_DEFAULTCOLOR );
			hChild = GetDlgItem( hwndDlg, IDC_FACELIST );
			ListView_SetImageList( hChild, hImageList, LVSIL_SMALL );
			PNListViewInsertColumn( hChild, 0, "Faces", 100 );
			PNListViewInsertItem( hChild, 0, "Smiley", 0 );
			PNListViewInsertItem( hChild, 1, "Average", 1 );
			PNListViewInsertItem( hChild, 2, "Frowny", 2 );
			PNListViewInsertItem( hChild, 3, "Surprise", 3 );
			
			PNListViewInitDrives( GetDlgItem(hwndDlg,IDC_DRVLIST) );
			PNListViewInitDrives( GetDlgItem(hwndDlg,IDC_DRVLIST2) );
			
			// Set on Row Row select and Grid Lines style for list view
			ListView_SetExtendedListViewStyle( hChild, LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES); 

			// Tree controls - Setup Drv list with list of drives
			hChild = GetDlgItem( hwndDlg, IDC_GENTREE );
			TreeView_SetImageList( hChild, hImageList, TVSIL_NORMAL );
			PNTreeViewInsertItem( hChild, "Root", TVI_ROOT,TVI_SORT, 0, 3 );

			hChild = GetDlgItem( hwndDlg, IDC_DRVTREE );
			PNTreeViewInitDrives( hChild );
			
			}

			// Tab Control
			hChild = GetDlgItem( hwndDlg, IDC_TABDEMO );
			PNTabControlInsertItem( hChild, 0, "Animation" );
			PNTabControlInsertItem( hChild, 1, "RichEdit" );
			PNTabControlInsertItem( hChild, 2, "DateTime" );
			PNTabControlInsertItem( hChild, 3, "IP Address" );
			SetWindowPos( hChild, 0, 0, 0, 250, 220, SWP_NOZORDER|SWP_NOMOVE );

			// Determine the client display area for the Tab control
			GetClientRect( hChild, &Rect );
			TabCtrl_GetItemRect( hChild, 0, &TabRect) ;
			Rect.top = 8;
			Rect.left = 8;
			Rect.bottom -= (8+TabRect.bottom);
			Rect.right -=8;

			// Animation Control
			hChild = GetDlgItem( hwndDlg, IDC_ANIMATE );
			if( Animate_Open( hChild, MAKEINTRESOURCE(IDR_AVI1) ) != FALSE )
				Animate_Play( hChild, 0, -1, -1 );
			
			// Place Animation control in the Tab parent, and resize it
			SetParent( hChild, GetDlgItem( hwndDlg, IDC_TABDEMO ) );
			SetWindowPos( hChild, 0, 8, TabRect.bottom+8, Rect.right-8, Rect.bottom-8, SWP_NOZORDER );

			// Richedit control: Make it a child to the tab control,
			// reposition and resize it, and then hide it.
			hChild = GetDlgItem( hwndDlg, IDC_RICHEDIT );
			SetParent( hChild, GetDlgItem( hwndDlg, IDC_TABDEMO ) );
			SetWindowPos( hChild, 0, 8, TabRect.bottom+8, Rect.right-8, Rect.bottom-8, SWP_NOZORDER );
			ShowWindow( hChild, SW_HIDE );
			CHARFORMAT CharFormat;
			CharFormat.cbSize = sizeof( CharFormat );
			CharFormat.dwMask = CFM_FACE|CFM_ITALIC;
			CharFormat.dwEffects = CFE_ITALIC;
			strcpy( CharFormat.szFaceName, "Times New Roman" );
			SendMessage( hChild, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&CharFormat );


			// Date Time picker control: Make it a child to the tab control,
			// reposition and resize it, and then hide it.
			hChild = GetDlgItem( hwndDlg, IDC_DATETIMEPICKER );
			SetParent( hChild, GetDlgItem( hwndDlg, IDC_TABDEMO ) );
			SetWindowPos( hChild, 0, 8, TabRect.bottom+8, Rect.right-8, Rect.bottom-8, SWP_NOZORDER|SWP_NOSIZE );
			ShowWindow( hChild, SW_HIDE );

			// Month control: Make it child of the tab control
			hChild = GetDlgItem( hwndDlg, IDC_MONTHCALENDAR );
			SetParent( hChild, GetDlgItem( hwndDlg, IDC_TABDEMO ) );
			SetWindowPos( hChild, 0, 8, TabRect.bottom+36, Rect.right-8, Rect.bottom-36, SWP_NOZORDER );
			ShowWindow( hChild, SW_HIDE );

			// IP: Make it child of the tab control
			hChild = GetDlgItem( hwndDlg, IDC_IPADDRESS );
			SetParent( hChild, GetDlgItem( hwndDlg, IDC_TABDEMO ) );
			SetWindowPos( hChild, 0, 8, TabRect.bottom+36, Rect.right-8, Rect.bottom-36, SWP_NOZORDER|SWP_NOSIZE );
			ShowWindow( hChild, SW_HIDE );

			
			return( TRUE );
			
		case WM_DESTROY:
			break;

		case WM_CLOSE:
			EndDialog( hwndDlg, 0 ); // Close the dialog
			break;

		case WM_HSCROLL: // Demonstration of Slider control
			// Verify the message came from the desired control
			if( GetDlgCtrlID( (HWND)lParam ) == IDC_SLIDERH )
			{
				// Send message to the control to determine it's new position
				int i= SendDlgItemMessage( hwndDlg, IDC_SLIDERH, TBM_GETPOS, 0, 0 );
				
				// Format position as a string, and place it in the STATIC text control
				char Text[4];
				sprintf( Text, "%d", i );
				SetDlgItemText( hwndDlg, IDC_SLIDERVAL, Text );

				// Update the vertical slider, to be at the same position
				SendDlgItemMessage( hwndDlg, IDC_SLIDERV, TBM_SETPOS, TRUE, i );
			}
			break;

		case WM_NOTIFY:
			// Parse out data from a WM_NOTIFY message
			wID = (int) wParam;
			wNotification = ((NMHDR*)lParam)->code;
			hChild = ((NMHDR*)lParam)->hwndFrom;

			/// Tab Control handler
			if( wID == IDC_TABDEMO && wNotification == TCN_SELCHANGE )
			{
				// Determine current tab selection
				int Index = TabCtrl_GetCurSel( hChild );

				ShowWindow( GetDlgItem( hChild, IDC_ANIMATE ), Index==0?SW_SHOW:SW_HIDE );
				ShowWindow( GetDlgItem( hChild, IDC_RICHEDIT ), Index==1?SW_SHOW:SW_HIDE );
				ShowWindow( GetDlgItem( hChild, IDC_DATETIMEPICKER ), Index==2?SW_SHOW:SW_HIDE );
				ShowWindow( GetDlgItem( hChild, IDC_MONTHCALENDAR ), Index==2?SW_SHOW:SW_HIDE );
				ShowWindow( GetDlgItem( hChild, IDC_IPADDRESS ), Index==3?SW_SHOW:SW_HIDE );
			}
			// Tree Control handlers
			else if( wID==IDC_GENTREE && wNotification == TVN_ENDLABELEDIT )
			{
				NMTVDISPINFO* pTreeItem = (NMTVDISPINFO*)lParam;
				if( pTreeItem->item.pszText )
					TreeView_SetItem( hChild, &pTreeItem->item );
			}
			else if( wID==IDC_DRVTREE && wNotification == TVN_ITEMEXPANDING )
			{
				PNTreeViewExpandPath( hChild, lParam );
			}
			else if (wID == IDC_DRVTREE && wNotification == TVN_SELCHANGED )
			{
				char Text[MAX_PATH];
				NMTREEVIEW* pNMTreeView = (NMTREEVIEW*)lParam;
				PNTreeViewGetDrivePath( hChild, Text, pNMTreeView->itemNew.hItem );
				SetDlgItemText( hwndDlg, IDC_DRVSELECTEDTREE, Text );
			}
			// Determine if notification came from specific control,
			// and if it was a double-click notification
			else if( wID == IDC_DRVLIST && wNotification == NM_DBLCLK )
			{
				// See LBITEMCHANGED below for alternate method of determining selected item
				int Index = ListView_GetNextItem( hChild, -1, LVNI_SELECTED ); 
    
				if( Index != -1 )
				{
					char Text[128];
					ListView_GetItemText( hChild, Index, 0, Text, sizeof(Text) );
					MessageBox( hwndDlg, Text, "You selected", MB_OK );
				}
			}
			else if( wID == IDC_FACELIST && wNotification == LVN_ENDLABELEDIT )
			{
				NMLVDISPINFO* pTreeItem = (NMLVDISPINFO*)lParam;
				if( pTreeItem->item.pszText )
					ListView_SetItem( hChild, &pTreeItem->item );
			}
			else if( wID == IDC_DRVLIST && wNotification == LVN_ITEMCHANGED )
			{
				NMLISTVIEW* pNMList = (NMLISTVIEW*)lParam;
				if( pNMList->iItem == -1 )
					SetDlgItemText( hwndDlg, IDC_DRVSELECTED, "No drive selected" );
				else
				{
					char Text[128];
					ListView_GetItemText( hChild, pNMList->iItem, 0, Text, sizeof(Text) );
					SetDlgItemText( hwndDlg, IDC_DRVSELECTED, Text );
				}

			}
			else if( wID == IDC_SPININCH && wNotification == UDN_DELTAPOS )
			{
				char Text[16];
				NMUPDOWN* UpDown = (NMUPDOWN*)lParam;
				// Base new value on Value from Edit box
				GetDlgItemText( hwndDlg, IDC_EDITINCH, Text, sizeof(Text) );
				int NewPos = int(atof( Text ) * 100) + UpDown->iDelta;
				// Insure minimum and maximum values are enforced
				int Upper, Lower;
				SendMessage( hChild, UDM_GETRANGE32, (WPARAM)&Lower, (LPARAM)&Upper );
				if( NewPos<Lower )
					NewPos=Lower;
				else if (NewPos > Upper )
					NewPos = Upper;
				// Put value into the Edit box
				hChild = GetDlgItem( hwndDlg, IDC_EDITINCH);//(HWND) SendMessage( hChild, UDM_GETBUDDY, 0, 0 );
				sprintf( Text, "%-2.2f\"", NewPos/100.0 );
				SetWindowText( hChild, Text );
				return( FALSE );
			}
			break;
		case WM_COMMAND: // A message from a control or menu item
			// Parse out WM_COMMAND parameters to be more readable
			wID = LOWORD(wParam);
			wNotification = HIWORD(wParam);
			hChild = (HWND) lParam;

			// Tree control demonstrations
			if( wID == IDC_ADDTREE && wNotification == BN_CLICKED )
			{
				hChild = GetDlgItem( hwndDlg, IDC_GENTREE );
				HTREEITEM hSelected;
				hSelected = TreeView_GetSelection( hChild );
				if( hSelected == 0 )
					hSelected = TVI_ROOT;
				char Text[16];
				if( PNTextBox( hwndDlg, Text, sizeof(Text), "Enter new tree item:", "Input" ) )
					PNTreeViewInsertItem( hChild, Text, hSelected, TVI_SORT, 0, 3 );
			}
			else if( wID == IDC_EDITTREE && wNotification == BN_CLICKED )
			{
				hChild = GetDlgItem( hwndDlg, IDC_GENTREE );
				HTREEITEM hSelected;
				hSelected = TreeView_GetSelection( hChild );
				if( hSelected == 0 )
					MessageBox( hwndDlg, "You must select an item in the tree to edit first", "Information", MB_ICONINFORMATION|MB_OK );
				else
				{
					char Text[16];
					if( PNTreeViewGetItemText( hChild, Text, sizeof(Text) ) )
					{
						if( PNTextBox( hwndDlg, Text, sizeof(Text), "Edit tree item:", "Input", FALSE ) )
							PNTreeViewSetItemText( hChild, Text, hSelected );
					}
				}
			}
			else if( wID == IDC_DELTREE && wNotification == BN_CLICKED )
			{
				hChild = GetDlgItem( hwndDlg, IDC_GENTREE );
				HTREEITEM hSelected;
				hSelected = TreeView_GetSelection( hChild );
				if( hSelected == 0 )
					MessageBox( hwndDlg, "You must select an item in the tree to delete first", "Information", MB_ICONINFORMATION|MB_OK );
				else
				{
					if( MessageBox( hwndDlg, "Are you sure you want to delete the selected item?", "Confirmation", MB_ICONINFORMATION|MB_YESNO ) == IDYES )
					{
						TreeView_DeleteItem( hChild, hSelected );
					}
				}
			}
			// The 'Go' button for progress bar demo
			else if( wID == IDC_PROGRESSGO && wNotification==BN_CLICKED )
			{
				// Turn cursor to an hour glass
				SetCursor( LoadCursor(0, MAKEINTRESOURCE(IDC_WAIT)) );
				// Enter our loop (simulated processing)
				for( int i=0; i < 100; i++ )
				{
					// Simulate a delay:
					Sleep( 10 );
					// Update progress bar with new position:
					SendDlgItemMessage( hwndDlg, IDC_PROGRESS1, PBM_SETPOS, i, 0 );
				}
			}
			else if (wID == IDC_DLGPROGDEMO && wNotification == BN_CLICKED )
			{
				char Text[16];
				HWND hDlg=PNProgressDlgPopup(hwndDlg, 0, 100);
				for( int i=0; i < 100; i++ )
				{
					// Simulate a delay:
					Sleep( 100 );
					// Update progress bar with new position:
					sprintf( Text, "On %d of %d", i+1, 100 );
					if( PNProgressDlgSetPos( hDlg, i, Text ) == FALSE )
						break; // Indicates user hit cancel option
					// Do actual processing here.
				}
				if( PNProgressDlgCanceled(hDlg) )
					MessageBox( hwndDlg, "You canceled that operation", "Information", MB_ICONINFORMATION|MB_OK  );
				PNProgressDlgClose( hDlg );
			}
			break;
	}
	return( FALSE );
}



int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
	// InitCommonControls should be called when you are going to use the 
	// common controls
	InitCommonControls();

    INITCOMMONCONTROLSEX icex;
    icex.dwSize = sizeof(icex);
    icex.dwICC = ICC_WIN95_CLASSES|ICC_DATE_CLASSES|ICC_INTERNET_CLASSES;
	BOOL Ret = InitCommonControlsEx(&icex);
	
	LoadLibrary("RICHED32.DLL");

	DialogBox( hInstance, MAKEINTRESOURCE(IDD_DIALOG1), 0, (DLGPROC)DialogProc );

	return 0;
}







