#pragma option w32

#define _COMMDLG_ TRUE
#define _WINBASE_ TRUE
#define _WINGDI_ TRUE

#include "windows.h--"
#include "griddemo.h--"
#include "RAGrid.h--"
#include "griddemo.rc"

dword main()
{
dword hRAGridDLL;
	IF(hRAGridDLL=LoadLibrary("RaGrid.dll")){
	  InitCommonControls();
		DialogBoxParam(hThisInst,IDD_DIALOG1,NULL,#DlgProc,NULL);
		FreeLibrary(hRAGridDLL);
	}
}

dword IPAddressProc(HWND hWin,UINT uMsg,WPARAM wParam,LPARAM lParam)
HDC hDC;
RECT rect;
{
	switch(uMsg){
		case WM_NCPAINT:
			GetWindowRect(hWin,#rect);
			rect.right-=rect.left;
			rect.left=0;
			rect.bottom-=rect.top;
			rect.top=0;
			hDC=GetWindowDC(hWin);
			FrameRect(hDC,#rect,GetStockObject(BLACK_BRUSH));
			rect.left++;
			rect.top++;
			rect.right--;
			rect.bottom--;
			CreateSolidBrush(GetSysColor(COLOR_WINDOW));
			$push	eax
			FrameRect(hDC,#rect,EAX);
			$pop		eax
			DeleteObject(EAX);
			ReleaseDC(hWin,hDC);
			RETURN 0;
		case WM_SHOWWINDOW:
			IF((!wParam) && (!fFlag)){
			//The flag is needed since the GM_ENDEDIT also hides the control
				fFlag=TRUE;
				GetWindowLong(hWin,GWL_ID);
				SendMessage(hGrd,GM_ENDEDIT,EAX,FALSE);
			}
			ELSE IF(wParam)fFlag=FALSE;
	}
	CallWindowProc(OldIPAddressProc,hWin,uMsg,wParam,lParam);
}

dword DlgProc(HWND hWin,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
byte buffer[MAX_PATH];
OPENFILENAME ofn;
COLUMN col;
COLORMAP cm;
RECT rect;
dword val;

	switch(uMsg){
		case WM_INITDIALOG:
			hWnd=hWin;
			hGrd=GetDlgItem(hWin,IDC_GRD1);
			SendMessage(hWin,WM_GETFONT,0,0);
	 		SendMessage(hGrd,WM_SETFONT,EAX,FALSE);
			SendMessage(hGrd,GM_SETBACKCOLOR,0C0FFFFh,0);
			SendMessage(hGrd,GM_SETGRIDCOLOR,808080h,0);
			SendMessage(hGrd,GM_SETTEXTCOLOR,800000h,0);
		//Image column
			hIml=ImageList_Create(15,15,ILC_COLOR24,8,8);
			cm.from=0xFFFFFF;
			cm.to=0C0FFFFh;
			CreateMappedBitmap(hThisInst,IDB_BITMAP,NULL,#cm,1);
			$push	eax
			ImageList_Add(hIml,EAX,0);
			$pop		eax
			DeleteObject(EAX);
			col.colwt=19;
			col.lpszhdrtext=NULL;
			col.halign=ALIGN_LEFT;
			col.calign=ALIGN_CENTER;
			col.ctype=TYPE_IMAGE;
			col.ctextmax=0;
			col.lpszformat=0;
			col.himl=hIml;
			col.hdrflag=0;
			SendMessage(hGrd,GM_ADDCOL,0,#col);
		//Text column
			col.colwt=130;
			col.lpszhdrtext=#szName;
			col.halign=ALIGN_LEFT;
			col.calign=ALIGN_LEFT;
			col.ctype=TYPE_EDITTEXT;
			col.ctextmax=31;
			col.lpszformat=0;
			col.himl=0;
			SendMessage(hGrd,GM_ADDCOL,0,#col);
		//Number column
			col.colwt=42;
			col.lpszhdrtext=#szID;
			col.halign=ALIGN_RIGHT;
			col.calign=ALIGN_RIGHT;
			col.ctype=TYPE_EDITLONG;
			col.ctextmax=11;
			col.lpszformat=#szFormat;
			col.himl=0;
			SendMessage(hGrd,GM_ADDCOL,0,#col);
		//Hotkey column
			col.colwt=118;
			col.lpszhdrtext=#szAccel;
			col.halign=ALIGN_LEFT;
			col.calign=ALIGN_LEFT;
			col.ctype=TYPE_HOTKEY;
			col.ctextmax=0;
			col.lpszformat=0;
			col.himl=0;
			SendMessage(hGrd,GM_ADDCOL,0,#col);
		//Checkbox column
			col.colwt=40;
			col.lpszhdrtext=#szCheck;
			col.halign=ALIGN_CENTER;
			col.calign=ALIGN_CENTER;
			col.ctype=TYPE_CHECKBOX;
			col.ctextmax=0;
			col.lpszformat=0;
			col.himl=0;
			SendMessage(hGrd,GM_ADDCOL,0,#col);
		//Combobox column
			col.colwt=130;
			col.lpszhdrtext=#szImageCombo;
			col.halign=ALIGN_LEFT;
			col.calign=ALIGN_LEFT;
			col.ctype=TYPE_COMBOBOX;
			col.ctextmax=0;
			col.lpszformat=0;
		//To create image combo, just add an image list
			col.himl=hIml;
			SendMessage(hGrd,GM_ADDCOL,0,#col);
		//Fill in some data in the combo
			$push	esi
			ESI=#szComboBoxText;
			FOR(;;){
				IF(lstrlen(ESI)){
					$push	eax
					SendMessage(hGrd,GM_COMBOADDSTRING,5,ESI);
					$pop		eax
					ESI=ESI+EAX+1;
				}
				ELSE BREAK;
			}
			$pop		esi
		//Button column
			col.colwt=130;
			col.lpszhdrtext=#szButton;
			col.halign=ALIGN_LEFT;
			col.calign=ALIGN_LEFT;
			col.ctype=TYPE_BUTTON;
			col.ctextmax=MAX_PATH;
			col.lpszformat=0;
			col.himl=0;
			SendMessage(hGrd,GM_ADDCOL,0,#col);
		//Date column
			col.colwt=80;
			col.lpszhdrtext=#szDate;
			col.halign=ALIGN_LEFT;
			col.calign=ALIGN_LEFT;
			col.ctype=TYPE_DATE;
			col.ctextmax=0;
			col.lpszformat=0;//offset szDateFormat
			col.himl=0;
			SendMessage(hGrd,GM_ADDCOL,0,#col);
		//Time column
			col.colwt=80;
			col.lpszhdrtext=#szTime;
			col.halign=ALIGN_LEFT;
			col.calign=ALIGN_LEFT;
			col.ctype=TYPE_TIME;
			col.ctextmax=0;
			col.lpszformat=0;//offset szTimeFormat
			col.himl=0;
			SendMessage(hGrd,GM_ADDCOL,0,#col);
		//IPAddress column (TYPE_USER)
			col.edthwnd=CreateWindowEx(NULL,#szIPAddressClass,NULL,WS_CHILD,0,0,90,19,hGrd,0,hThisInst,0);
			OldIPAddressProc=SetWindowLong(EAX,GWL_WNDPROC,#IPAddressProc);
			col.colwt=90;
			col.lpszhdrtext=#szIPAddress;
			col.halign=ALIGN_LEFT;
			col.calign=ALIGN_LEFT;
			col.ctype=TYPE_USER;
			col.ctextmax=4;
			col.lpszformat=0;
			col.himl=0;
			SendMessage(hGrd,GM_ADDCOL,0,#col);
		//Add some rows
			$push	esi
			ESI=#rdta;
			ECX=16;
			loop(ECX){
				$push	ecx
				SendMessage(hGrd,GM_ADDROW,0,ESI);
				$pop		ecx
				ESI+=sizeof(ROWDATA);
			}
			$pop		esi
			SendMessage(hGrd,GM_SETCURSEL,0,0);
			SetFocus(hGrd);
			return 0;
		case WM_SIZE:
			GetClientRect(hWin,#rect);
			rect.left+=3;
			rect.top+=3;
			rect.right-=6;
			rect.bottom-=3+21+3;
			MoveWindow(hGrd,rect.left,rect.top,rect.right,rect.bottom,TRUE);
			GetDlgItem(hWin,2);
			ECX=rect.bottom+6;
			EDX=rect.right-64;
			MoveWindow(EAX,EDX,ECX,64,21,TRUE);
			GetDlgItem(hWin,IDC_BTNTEST);
			ECX=rect.bottom+6;
			EDX=rect.right-64-3-64;
			MoveWindow(EAX,EDX,ECX,64,21,TRUE);
			GetDlgItem(hWin,IDC_BTNMOVEDOWN);
			ECX=rect.bottom+6;
			EDX=rect.right-64-3-64-3-64;
			MoveWindow(EAX,EDX,ECX,64,21,TRUE);
			GetDlgItem(hWin,IDC_BTNMOVEUP);
			ECX=rect.bottom+6;
			EDX=rect.right-64-3-64-3-64-3-64;
			MoveWindow(EAX,EDX,ECX,64,21,TRUE);
			GetDlgItem(hWin,IDC_BTNINSERT);
			ECX=rect.bottom+6;
			EDX=rect.right-64-3-64-3-64-3-64-3-64;
			MoveWindow(EAX,EDX,ECX,64,21,TRUE);
			GetDlgItem(hWin,IDC_BTNADD);
			ECX=rect.bottom+6;
			EDX=rect.right-64-3-64-3-64-3-64-3-64-3-64;
			MoveWindow(EAX,EDX,ECX,64,21,TRUE);
			GetDlgItem(hWin,IDC_BTNDEL);
			ECX=rect.bottom+6;
			EDX=rect.right-64-3-64-3-64-3-64-3-64-3-64-3-64;
			MoveWindow(EAX,EDX,ECX,64,21,TRUE);
			break;
		case WM_COMMAND:
			EDX=wParam;
			EAX=DX;
			EDX>>=16;
			if(EDX==BN_CLICKED){
				switch(EAX){
					CASE IDCANCEL:
						SendMessage(hWin,WM_CLOSE,NULL,NULL);
						break;
					CASE IDC_BTNTEST:
//					SendMessage(hGrd,GM_SETHDRHEIGHT,0,32);
//					SendMessage(hGrd,GM_SETROWHEIGHT,0,22);
//					SendMessage(hGrd,GM_SETCOLWIDTH,1,220);
//					SendMessage(hGrd,GM_RESETCONTENT,0,0);
//					SendMessage(hGrd,GM_ENTEREDIT,1,1);
//					SendMessage(hGrd,GM_SETHDRTEXT,1,offset szRAGridDLL);
						return 0;
					CASE IDC_BTNMOVEDOWN:
						SendMessage(hGrd,GM_GETCURROW,0,0);
						EDX=EAX+1;
						SendMessage(hGrd,GM_MOVEROW,EAX,EDX);
						SetFocus(hGrd);
						return 0;
					CASE IDC_BTNMOVEUP:
						SendMessage(hGrd,GM_GETCURROW,0,0);
						EDX=EAX-1;
						SendMessage(hGrd,GM_MOVEROW,EAX,EDX);
						SetFocus(hGrd);
						return 0;
					case IDC_BTNINSERT:
						SendMessage(hGrd,GM_GETCURROW,0,0);
						$push	eax
						SendMessage(hGrd,GM_INSROW,EAX,NULL);
						$pop eax
						SendMessage(hGrd,GM_SETCURSEL,0,EAX);
						SetFocus(hGrd);
						return 0;
					case IDC_BTNADD:
						SendMessage(hGrd,GM_ADDROW,0,NULL);
						SendMessage(hGrd,GM_SETCURSEL,0,EAX);
						SetFocus(hGrd);
						return 0;
					case IDC_BTNDEL:
						SendMessage(hGrd,GM_GETCURROW,0,0);
						$push	eax
						SendMessage(hGrd,GM_DELROW,EAX,0);
						$pop eax
						SendMessage(hGrd,GM_SETCURSEL,0,EAX);
						SetFocus(hGrd);
						return 0;
				}
			}
			break;
		case WM_NOTIFY:
			$push	esi
			ESI=lParam;
			EAX=ESI.NMHDR.hwndFrom;
			if(EAX==hGrd){
				switch(ESI.NMHDR.code){
					case GN_HEADERCLICK:
				//Sort the grid by column, invert sorting order
						SendMessage(hGrd,GM_COLUMNSORT,ESI.GRIDNOTIFY.col,SORT_INVERT);
						break;
					CASE GN_BUTTONCLICK:
				//Cell button clicked
						lstrcpy(#buffer,ESI.GRIDNOTIFY.lpdata);
				//Zero out the ofn struct
						RtlZeroMemory(#ofn,sizeof(ofn));
				//Setup the ofn struct
						ofn.lStructSize=sizeof(ofn);
						ofn.hwndOwner=hWin;
						ofn.hInstance=hThisInst;
						ofn.lpstrFilter=NULL;
//						$lea		eax,buffer
						ofn.lpstrFile=#buffer;
						ofn.nMaxFile=sizeof(buffer);
						ofn.lpstrDefExt=NULL;
						ofn.Flags=OFN_FILEMUSTEXIST|OFN_HIDEREADONLY|OFN_PATHMUSTEXIST;
				//Show the Open dialog
						IF(GetOpenFileName(#ofn)){
							EDX=ESI.GRIDNOTIFY.lpdata;
							lstrcpy(EDX,#buffer);
							ESI.GRIDNOTIFY.fcancel=FALSE;
						}
						ELSE ESI.GRIDNOTIFY.fcancel=TRUE;
						BREAK;
//					case GN_CHECKCLICK:
				//CheckBox value
//				mov		eax,[esi].GRIDNOTIFY.lpdata
//				mov		eax,[eax]
//				PrintHex eax
				//Cancel changing
//				mov		[esi].GRIDNOTIFY.fcancel,TRUE
//						BREAK;
//					case GN_IMAGECLICK:
				//ImageList handle
//				mov		eax,[esi].GRIDNOTIFY.hwnd
//				PrintHex eax
				//ImageList index
//				mov		eax,[esi].GRIDNOTIFY.lpdata
//				mov		eax,[eax]
//			PrintHex eax
//						BREAK;
//					case GN_BEFORESELCHANGE:
				//Setting fcancel to TRUE prevents selection changing
//				mov		[esi].GRIDNOTIFY.fcancel,TRUE
				//Changing row or col prevents rows or cols from getting focus
//				.if [esi].GRIDNOTIFY.col==0
//				mov		[esi].GRIDNOTIFY.col,1
//				.endif
//				PrintHex eax
//						BREAK;
//					case GN_AFTERSELCHANGE:
//				PrintHex eax
//						BREAK;
					case GN_BEFOREEDIT:
				//Setting fcancel to TRUE prevents cell edit control from showing
//				mov		[esi].GRIDNOTIFY.fcancel,TRUE
						IF(ESI.GRIDNOTIFY.col==9){
					//IPAddress column
							EAX=ESI.GRIDNOTIFY.lpdata;
							EAX=DSDWORD[EAX];
							SendMessage(ESI.GRIDNOTIFY.hwnd,IPM_SETADDRESS,0,EAX);
						}
						BREAK;
					case GN_AFTEREDIT:
				//Setting fcancel to TRUE prevents cell edit control from closing
//				mov		[esi].GRIDNOTIFY.fcancel,TRUE
						IF(ESI.GRIDNOTIFY.col==9){
					//IPAddress column
							SendMessage(ESI.GRIDNOTIFY.hwnd,IPM_GETADDRESS,0,#val);
							EDX=ESI.GRIDNOTIFY.lpdata;
							DSDWORD[EDX]=val;
						}
						BREAK;
//					case GN_BEFOREUPDATE:
				//Setting fcancel to TRUE prevents updating grid data
//				mov		[esi].GRIDNOTIFY.fcancel,TRUE
//						BREAK;
//					case GN_AFTERUPDATE:
//				PrintHex eax
//					 ˙BREAK;
					case GN_USERCONVERT:
						IF(ESI.GRIDNOTIFY.col==9){
					//IPAddress column
							$push	ebx,edi
							EDI=ESI.GRIDNOTIFY.lpdata;
							EBX=DSDWORD[EDI];
							ConvByteToDec();
							DSBYTE[EDI]='.';
							EDI++;
							ConvByteToDec();
							DSBYTE[EDI]='.';
							EDI++;
							ConvByteToDec();
							DSBYTE[EDI]='.';
							EDI++;
							ConvByteToDec();
							DSBYTE[EDI]=0;
							$pop		edi,ebx
						}
						BREAK;
				}
			}
			$pop		esi
			BREAK;
		case WM_CLOSE:
			ImageList_Destroy(hIml);
			EndDialog(hWin,0);
			BREAK;
		default:
			RETURN FALSE;
	}
	EAX=TRUE;
}

void ConvByteToDec()
{
		$rol		ebx,8
		EAX=BL;
		ECX=10;
		EAX=EAX/ECX;
		DL|=30h;
		DSBYTE[EDI+2]=DL;
		EAX=EAX/ECX;
		DL|=30h;
		DSBYTE[EDI+1]=DL;
		EAX=EAX/ECX;
		DL|=30h;
		DSBYTE[EDI]=DL;
		EDI+=3;
}
