/* 
CCIDE
Copyright 2001-2006 David Lindauer.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

You may contact the author at:
	mailto::camille@bluegrass.net
 */
#define STRICT
#include <windows.h>
#include <commdlg.h>
#include <commctrl.h>
#include <richedit.h>
#include <prsht.h>
#include <stdio.h>
#include "winconst.h"
#include "helpid.h"
#include "header.h"

extern HWND hwndFrame;
extern PROJLIST *projectList;
extern LOGFONT EditFont;
extern HINSTANCE hInstance;
extern char szHelpPath[];
extern COLORREF keywordColor;
extern COLORREF numberColor;
extern COLORREF commentColor;
extern COLORREF stringColor;
extern COLORREF escapeColor;
extern COLORREF backgroundColor;
extern COLORREF textColor;
extern COLORREF highlightColor;
extern int tabs, editFlags;
extern char szInstallPath[];
extern int changedProject;

extern int rightmargin;
extern int leftmargin;
extern int topmargin;
extern int bottommargin;
extern char printHeader[];
extern char printFooter[];
extern int completionEnabled;
extern int parenthesisCheck;

static WNDPROC oldproc;

int custColors[16];
int browseInfo;

static HWND definehWnd;
static int defineSelected;
static int custColorsTemp[16];
static int browseInfoTemp;
static int completionEnableTemp;
static int parenthesisCheckTemp;
static char szHelpPathTemp[1024];
static COLORREF keywordColorTemp;
static COLORREF numberColorTemp;
static COLORREF commentColorTemp;
static COLORREF stringColorTemp;
static COLORREF escapeColorTemp;
static COLORREF backgroundColorTemp;
static COLORREF textColorTemp;
static COLORREF highlightColorTemp;
static int tabsTemp, editFlagsTemp;

static int rightMarginTemp;
static int leftMarginTemp;
static int topMarginTemp;
static int bottomMarginTemp;
static char headerTemp[256];
static char footerTemp[256];
static HBITMAP menubuttonBM;

#ifdef XXXXX
LRESULT CALLBACK _export InchesHook(HWND hwnd, UINT iMessage, WPARAM wParam,
    LPARAM lParam)
{
	char buf[256];
	char *text;
	LRESULT rv ;
	int val;
	
	switch(iMessage)
	{
		case WM_SETTEXT:
    		CallWindowProc(oldproc, hwnd, EM_SETLIMITTEXT, 4, 0);
			text = (char *)lParam;
			val = atoi(text);
			buf[0] = val / 10 + '0';
			buf[1] = '.';
			buf[2] = val % 10 + '0';
			buf[3] = '\"';
			buf[4] = 0;
			lParam = (LPARAM)buf;
			break;
		case WM_GETTEXT:
    		rv = CallWindowProc(oldproc, hwnd, iMessage, 5, (LPARAM)buf);
			text = (char *)lParam;
			if (buf[0] != '0')
			{
				buf[0] = buf[0];
				buf[1] = buf[2];
				buf[2] = 0;
			}
			else
			{
				buf[0] = buf[2];
				buf[1] = 0;
			}
			val = strlen(buf) + 1;
			if (val > wParam)
				val = wParam;
			memcpy(text, buf, val);
			return val;
		case EM_SETSEL:
			lParam = wParam;
			break;
		case EM_EXSETSEL:
			{
				charinfo *a = (charinfo *)lParam;
				a->max = a->min;
			}
			break;
		case WM_LBUTTONDOWN:
		case WM_LBUTTONUP:
		
    		rv = CallWindowProc(oldproc, hwnd, iMessage, wParam, lParam);
			CallWindowProc(oldproc, hwnd, EM_GETSEL, (WPARAM)&val, 0);
			if (val & 1)
			{
				val--;
			}				
			CallWindowProc(oldproc, hwnd, EM_SETSEL, val, val);
			return rv;
		
		case WM_KEYDOWN:
			switch(wParam)
			{
				case VK_LEFT:
				case VK_RIGHT:
    				CallWindowProc(oldproc, hwnd, iMessage, wParam, lParam);
    				CallWindowProc(oldproc, hwnd, WM_KEYUP, wParam, lParam);
					break;
				case VK_RETURN:
					break;
				default:
					if (isdigit(wParam))
					{
						CallWindowProc(oldproc, hwnd, WM_KEYDOWN, VK_DELETE, 0);
						CallWindowProc(oldproc, hwnd, WM_KEYUP, VK_DELETE, 0);
				    	rv = CallWindowProc(oldproc, hwnd, iMessage, wParam, lParam);
						return rv;
					}
					return 0;
			}
			break ;
		case WM_KEYUP:
			switch(wParam)
			{
				case VK_LEFT:
				case VK_RIGHT:
				case VK_RETURN:
					break;
				default:
					if (isdigit(wParam))
					{
				    	rv = CallWindowProc(oldproc, hwnd, iMessage, wParam, lParam);
						CallWindowProc(oldproc, hwnd, WM_KEYDOWN, VK_RIGHT, 0);
						CallWindowProc(oldproc, hwnd, WM_KEYUP, VK_RIGHT, 0);
						return rv;
					}
					return 0;
			}
			break ;
		case WM_CHAR:
			if (isdigit(wParam))
			{
				break;
			}
			return 0;
	}
    return CallWindowProc(oldproc, hwnd, iMessage, wParam, lParam);
}
#endif
LRESULT CALLBACK _export colorProc(HWND hwnd, UINT iMessage, WPARAM wParam,
    LPARAM lParam)
{
    HDC dc;
    PAINTSTRUCT paint;
    RECT r;
    LOGBRUSH l;
    HBRUSH b;
    CHOOSECOLOR c;
    switch (iMessage)
    {
        case WM_SETCOLOR:
            SetWindowLong(hwnd, 0, lParam);
            InvalidateRect(hwnd, 0, 0);
            break;
        case WM_PAINT:
            dc = BeginPaint(hwnd, &paint);
            GetClientRect(hwnd, &r);
            l.lbStyle = BS_SOLID;
            l.lbColor = GetWindowLong(hwnd, 0);
            b = CreateBrushIndirect(&l);
            FillRect(dc, &r, b);
            DeleteObject(b);
            EndPaint(hwnd, &paint);
            break;
        case WM_LBUTTONDOWN:
            memset(&c, 0, sizeof(c));
            c.lStructSize = sizeof(CHOOSECOLOR);
            c.hwndOwner = hwnd;
            c.rgbResult = GetWindowLong(hwnd, 0);
            c.lpCustColors = custColorsTemp;
            c.Flags = CC_RGBINIT ;
            if (ChooseColor(&c))
            {
                SetWindowLong(hwnd, 0, c.rgbResult);
                InvalidateRect(hwnd, 0, 0);
            }
            else
                CommDlgExtendedError();
            return 0;
        case WM_RETRIEVECOLOR:
            return GetWindowLong(hwnd, 0);
        case WM_CREATE:
            SetWindowLong(hwnd, 0, 0);
            InvalidateRect(hwnd, 0, 0);
            break;
		case WM_COMMAND:
			if (wParam == IDHELP)
				ContextHelp(IDH_CHOOSE_COLOR_DIALOG);
			break ;
        case WM_DESTROY:
            break;
    }
    DefWindowProc(hwnd, iMessage, wParam, lParam);
}

//-------------------------------------------------------------------------

void RegisterColorWindow(void)
{
    WNDCLASS wc;
    memset(&wc, 0, sizeof(wc));
    wc.style = 0;
    wc.lpfnWndProc = &colorProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = sizeof(void*);
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(0, IDI_APPLICATION);
    wc.hCursor = LoadCursor(0, IDC_ARROW);
    wc.hbrBackground = 0;
    wc.lpszMenuName = 0;
    wc.lpszClassName = "xccColorClass";
    RegisterClass(&wc);
}

// ==============================================================
//
// property sheet constant names
//

static PROPSHEETPAGE editPages[EDIT_PROPERTY_SHEET_COUNT]; 
    // the page structures
static PROPSHEETHEADER editHeader; // the header structure

// ==============================================================
//
// routine to set the result from the killactive notify message

static void SetResult(HWND hwnd, int value)
{
    SetWindowLong(hwnd, DWL_MSGRESULT, value);
}

//-------------------------------------------------------------------------

void SetColor(HWND hwnd, int control, int color)
{
    SendMessage(GetDlgItem(hwnd, control), WM_SETCOLOR, 0, color);
}

//-------------------------------------------------------------------------

int GetColor(HWND hwnd, int control)
{
    SendMessage(GetDlgItem(hwnd, control), WM_RETRIEVECOLOR, 0, 0);
}

// ==============================================================
//
static int FAR PASCAL EditProc(HWND hwnd, UINT wmsg, WPARAM wparam, LPARAM
    lparam)

{
    NMHDR *nmhead;
    static CHOOSEFONT ch;
    static LOGFONT lf;
    switch (wmsg)
    {
        case WM_INITDIALOG:
            return TRUE;
        case WM_COMMAND:
            switch (wparam)
            {
            case IDC_SELECTFONT:
                memset(&ch, 0, sizeof(ch));
                memcpy(&lf, &EditFont, sizeof(lf));
                ch.lStructSize = sizeof(ch);
                ch.hwndOwner = 0;
                ch.lpLogFont = &lf;
                ch.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
                    CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS ;
                if (ChooseFont(&ch))
                    ApplyFontSettings(ch.lpLogFont);
                break;
            }
            break;
        case WM_NOTIFY:
            nmhead = (NMHDR*)lparam;
            switch (nmhead->code)
            {
            case PSN_SETACTIVE:
                /* page startup */
                NewFocus(hwnd, IDC_TABSTOPS);
                SetEditFieldValue(hwnd, IDC_TABSTOPS, tabsTemp);
                SetColor(hwnd, IDC_KEYWORDCOLOR, keywordColorTemp);
                SetColor(hwnd, IDC_COMMENTCOLOR, commentColorTemp);
                SetColor(hwnd, IDC_NUMBERCOLOR, numberColorTemp);
                SetColor(hwnd, IDC_STRINGCOLOR, stringColorTemp);
                SetColor(hwnd, IDC_ESCAPECOLOR, escapeColorTemp);
                SetColor(hwnd, IDC_BACKGROUNDCOLOR, backgroundColorTemp);
                SetColor(hwnd, IDC_TEXTCOLOR, textColorTemp);
                SetColor(hwnd, IDC_HIGHLIGHTCOLOR, highlightColorTemp);
                SetCBField(hwnd, IDC_BACKUPFILE, !!(editFlagsTemp &BACKUP_FILES)
                    );
                SetCBField(hwnd, IDC_BACKUPPROJ, !!(editFlagsTemp
                    &BACKUP_PROJECTS));
                SetCBField(hwnd, IDC_TABSASSPACES, !!(editFlagsTemp
                    &TABS_AS_SPACES));
                SetCBField(hwnd, IDC_AUTOINDENT, !(editFlagsTemp &AUTO_INDENT));
                SetCBField(hwnd, IDC_AUTOFORMAT, !(editFlagsTemp &AUTO_FORMAT));
                break;
            case PSN_KILLACTIVE:
                /* verify ok always */
                tabsTemp = GetEditFieldValue(hwnd, IDC_TABSTOPS);
                keywordColorTemp = GetColor(hwnd, IDC_KEYWORDCOLOR);
                commentColorTemp = GetColor(hwnd, IDC_COMMENTCOLOR);
                numberColorTemp = GetColor(hwnd, IDC_NUMBERCOLOR);
                stringColorTemp = GetColor(hwnd, IDC_STRINGCOLOR);
                escapeColorTemp = GetColor(hwnd, IDC_ESCAPECOLOR);
                backgroundColorTemp = GetColor(hwnd, IDC_BACKGROUNDCOLOR);
                textColorTemp = GetColor(hwnd, IDC_TEXTCOLOR);
                highlightColorTemp = GetColor(hwnd, IDC_HIGHLIGHTCOLOR);
                editFlagsTemp &= !(BACKUP_FILES | BACKUP_PROJECTS |
                    TABS_AS_SPACES | AUTO_FORMAT | AUTO_INDENT);
                editFlagsTemp |= GetCBField(hwnd, IDC_BACKUPFILE) ?
                    BACKUP_FILES : 0;
                editFlagsTemp |= GetCBField(hwnd, IDC_BACKUPPROJ) ?
                    BACKUP_PROJECTS : 0;
                editFlagsTemp |= GetCBField(hwnd, IDC_TABSASSPACES) ?
                    TABS_AS_SPACES : 0;
                editFlagsTemp |= GetCBField(hwnd, IDC_AUTOINDENT) ? 0 :
                    AUTO_INDENT;
                editFlagsTemp |= GetCBField(hwnd, IDC_AUTOFORMAT) ? 0 :
                    AUTO_FORMAT;
                SetResult(hwnd, FALSE);
                break;
            case PSN_APPLY:
                /* Page application */
                tabs = tabsTemp;
                keywordColor = keywordColorTemp;
                commentColor = commentColorTemp;
                numberColor = numberColorTemp;
                stringColor = stringColorTemp;
                escapeColor = escapeColorTemp;
                backgroundColor = backgroundColorTemp;
                textColor = textColorTemp;
                highlightColor = highlightColorTemp;
                editFlags = editFlagsTemp;
                memcpy(custColors, custColorsTemp, sizeof(custColors));
                ApplyEditSettings();
//                IntToProfile("EditFlags",editFlags) ;
                break;
            case PSN_HELP:
                ContextHelp(IDH_EDITOR_CONFIGURATION);
                break;
            }
            break;
    }
    return FALSE;
}

// ==============================================================
//
static int FAR PASCAL PrintFormatProc(HWND hwnd, UINT wmsg, WPARAM wparam, LPARAM
    lparam)

{
    NMHDR *nmhead;
    static CHOOSEFONT ch;
    static LOGFONT lf;
	static int buttonid;
	HWND hwnde;
    switch (wmsg)
    {
        case WM_INITDIALOG:
			if (menubuttonBM == NULL)
			{
				menubuttonBM= LoadImage(hInstance, "ID_MENUBM", 
					IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS);
			}
			SendDlgItemMessage(hwnd, IDC_PRINTFOOTERBUTTON, BM_SETIMAGE, 0, (LPARAM)menubuttonBM);	
			SendDlgItemMessage(hwnd, IDC_PRINTHEADERBUTTON, BM_SETIMAGE, 0, (LPARAM)menubuttonBM);
			hwnde = GetDlgItem(hwnd, IDC_LEFTMARGIN);
#ifdef XXXXX
            oldproc = (WNDPROC)SetWindowLong(hwnde, GWL_WNDPROC, (int)
                InchesHook);
			hwnde = GetDlgItem(hwnd, IDC_RIGHTMARGIN);
            oldproc = (WNDPROC)SetWindowLong(hwnde, GWL_WNDPROC, (int)
                InchesHook);
			hwnde = GetDlgItem(hwnd, IDC_TOPMARGIN);
            oldproc = (WNDPROC)SetWindowLong(hwnde, GWL_WNDPROC, (int)
                InchesHook);
			hwnde = GetDlgItem(hwnd, IDC_BOTTOMMARGIN);
            oldproc = (WNDPROC)SetWindowLong(hwnde, GWL_WNDPROC, (int)
                InchesHook);
#endif
            return TRUE;
		case WM_COMMAND: 
		    {
				char *insert = NULL;
				int type = LOWORD(wparam);
				switch(LOWORD(wparam))
				{
					case IDC_PRINTFOOTERBUTTON:
					case IDC_PRINTHEADERBUTTON:
						buttonid = LOWORD(wparam);
						{
	                		HMENU menu = LoadMenu(hInstance, "PRINTFORMATMENU"), popup;
							HWND wnd = GetDlgItem(hwnd, buttonid);
							RECT r;
							GetWindowRect(wnd, &r);
			                popup = GetSubMenu(menu, 0);
	        			    TrackPopupMenuEx(popup, TPM_TOPALIGN | TPM_LEFTALIGN | TPM_LEFTBUTTON, r.right,
	                		    r.top, hwnd, NULL);
	                		DestroyMenu(menu);
						}
						break;
					case IDM_PF12HR:
						insert = "%T";
						break;
					case IDM_PF24HR:
						insert = "%t";
						break;
					case IDM_PFUSADATE:
						insert = "%D";
						break;
					case IDM_PFEURODATE:
						insert = "%d";
						break;
					case IDM_PFCURPAGE:
						insert = "%P";
						break;
					case IDM_PFNUMPAGE:
						insert = "%#";
						break;
					case IDM_PFFILENAME:
						insert = "%F";
						break;
					case IDM_PFCENTER:
						insert = "%C";
						break;
					case IDM_PFLEFT:
						insert = "%L";
						break;
					case IDM_PFRIGHT:
						insert = "%R";
						break;
				}
				if (insert)
				{
	                SendDlgItemMessage(hwnd, 
						buttonid == IDC_PRINTHEADERBUTTON ? IDC_PRINTHEADER : IDC_PRINTFOOTER,
						EM_REPLACESEL, 1, (LPARAM)insert);
					
				}
		    }
			break;
        case WM_NOTIFY:
            nmhead = (NMHDR*)lparam;
            switch (nmhead->code)
            {
            case PSN_SETACTIVE:
                /* page startup */
                NewFocus(hwnd, IDC_PRINTHEADER);
                SetEditField(hwnd, IDC_PRINTHEADER, headerTemp);
                SetEditField(hwnd, IDC_PRINTFOOTER, footerTemp);
                SetEditFieldValue(hwnd, IDC_LEFTMARGIN, leftMarginTemp);
	    		SendDlgItemMessage(hwnd, IDC_LEFTMARGIN, EM_SETLIMITTEXT, 4, 0);
                SetEditFieldValue(hwnd, IDC_RIGHTMARGIN, rightMarginTemp);
	    		SendDlgItemMessage(hwnd, IDC_RIGHTMARGIN, EM_SETLIMITTEXT, 4, 0);
                SetEditFieldValue(hwnd, IDC_TOPMARGIN, topMarginTemp);
	    		SendDlgItemMessage(hwnd, IDC_TOPMARGIN, EM_SETLIMITTEXT, 4, 0);
                SetEditFieldValue(hwnd, IDC_BOTTOMMARGIN, bottomMarginTemp);
	    		SendDlgItemMessage(hwnd, IDC_BOTTOMMARGIN, EM_SETLIMITTEXT, 4, 0);
                break;
            case PSN_KILLACTIVE:
                /* verify ok always */
                GetEditField(hwnd, IDC_PRINTHEADER, headerTemp);
                GetEditField(hwnd, IDC_PRINTFOOTER, footerTemp);
                leftMarginTemp = GetEditFieldValue(hwnd, IDC_LEFTMARGIN);
                rightMarginTemp = GetEditFieldValue(hwnd, IDC_RIGHTMARGIN);
                topMarginTemp = GetEditFieldValue(hwnd, IDC_TOPMARGIN);
                bottomMarginTemp = GetEditFieldValue(hwnd, IDC_BOTTOMMARGIN);
                SetResult(hwnd, FALSE);
                break;
            case PSN_APPLY:
                /* Page application */
				rightmargin = rightMarginTemp;
				leftmargin = leftMarginTemp;
				topmargin = topMarginTemp;
				bottommargin = bottomMarginTemp;
				strcpy(printHeader, headerTemp);
				strcpy(printFooter, footerTemp);
                break;
            case PSN_HELP:
                ContextHelp(IDH_PRINTER_CONFIGURATION);
                break;
            }
            break;
    }
    return FALSE;
}
//-------------------------------------------------------------------------

static int FAR PASCAL GeneralProc(HWND hwnd, UINT wmsg, WPARAM wparam, LPARAM
    lparam)

{
    NMHDR *nmhead;
    int len;
	HWND dlg;
    switch (wmsg)
    {
        case WM_INITDIALOG:
            return TRUE;
        case WM_NOTIFY:
            nmhead = (NMHDR*)lparam;
            switch (nmhead->code)
            {
            case PSN_SETACTIVE:
                /* page startup */
                NewFocus(hwnd, IDC_BROWSEINFO);
                SetCBField(hwnd, IDC_BROWSEINFO, browseInfoTemp);
                SetCBField(hwnd, IDC_CODECOMP, completionEnableTemp);
				SetCBField(hwnd, IDC_PARENCHECK, parenthesisCheckTemp);
                break;
            case PSN_KILLACTIVE:
                /* verify ok always */
                browseInfoTemp = GetCBField(hwnd, IDC_BROWSEINFO);
                completionEnableTemp = GetCBField(hwnd, IDC_CODECOMP);
                parenthesisCheckTemp = GetCBField(hwnd, IDC_PARENCHECK);
                SetResult(hwnd, FALSE);
                break;
            case PSN_APPLY:
                /* Page application */
                browseInfo = browseInfoTemp;
				completionEnabled = completionEnableTemp;
				parenthesisCheck = parenthesisCheckTemp;
                break;
            case PSN_HELP:
                ContextHelp(IDH_GENERAL_CONFIGURATION);
                break;
            }
            break;
    }
    return FALSE;
}

//-------------------------------------------------------------------------

static int FAR PASCAL InstallProc(HWND hwnd, UINT wmsg, WPARAM wparam, LPARAM
    lparam)

{
    NMHDR *nmhead;
    int len;
    switch (wmsg)
    {
        case WM_INITDIALOG:
            return TRUE;
        case WM_NOTIFY:
            nmhead = (NMHDR*)lparam;
            switch (nmhead->code)
            {
            case PSN_SETACTIVE:
                /* page startup */
                NewFocus(hwnd, IDC_HELPPATH);
//                SetEditField(hwnd, IDC_INSTALLPATH, szInstallPathTemp);
                SetEditField(hwnd, IDC_HELPPATH, szHelpPathTemp);
                break;
            case PSN_KILLACTIVE:
                /* verify ok always */
//                GetEditField(hwnd, IDC_INSTALLPATH, szInstallPathTemp);
                GetEditField(hwnd, IDC_HELPPATH, szHelpPathTemp);
                SetResult(hwnd, FALSE);
                break;
            case PSN_APPLY:
                /* Page application */
//                strcpy(szInstallPath, szInstallPathTemp);
//                len = strlen(szInstallPath);
//                if (len && szInstallPath[len - 1] == '\\')
//                    szInstallPath[len - 1] = 0;
//                StringToProfile("InstallPath", szInstallPath);
                strcpy(szHelpPath, szHelpPathTemp);
				RundownHelp();
				InitHelp();
                break;
            case PSN_HELP:
                ContextHelp(IDH_INSTALL_CONFIGURATION);
                break;
            }
            break;
    }
    return FALSE;
}

// ==============================================================
//
// display the property sheet and return to caller
//
void DisplayProperties(HINSTANCE hInst, HWND hwnd, int startPage)
{
    tabsTemp = tabs;
    keywordColorTemp = keywordColor;
    commentColorTemp = commentColor;
    numberColorTemp = numberColor;
    stringColorTemp = stringColor;
    escapeColorTemp = escapeColor;
    backgroundColorTemp = backgroundColor;
    textColorTemp = textColor;
	highlightColorTemp = highlightColor;
    editFlagsTemp = editFlags;
    browseInfoTemp = browseInfo;
	completionEnableTemp = completionEnabled;
	parenthesisCheckTemp = parenthesisCheck;
    memcpy(custColorsTemp, custColors, sizeof(custColors));
//    strcpy(szInstallPathTemp, szInstallPath);
    strcpy(szHelpPathTemp, szHelpPath);

	strcpy(headerTemp, printHeader);
	strcpy(footerTemp, printFooter);
	rightMarginTemp = rightmargin;
	leftMarginTemp = leftmargin;
	topMarginTemp = topmargin;
	bottomMarginTemp = bottommargin;
	
    // struct for server page
    editPages[EDITPROP].dwSize = sizeof(PROPSHEETPAGE);
    editPages[EDITPROP].dwFlags = PSP_HASHELP;
    editPages[EDITPROP].hInstance = hInst;
    editPages[EDITPROP].u.pszTemplate = "EDITPROPDLG";
    editPages[EDITPROP].pfnDlgProc = EditProc;
    editPages[EDITPROP].pszTitle = "Edit";

    editPages[PRINTFORMATPROP].dwSize = sizeof(PROPSHEETPAGE);
    editPages[PRINTFORMATPROP].dwFlags = PSP_HASHELP;
    editPages[PRINTFORMATPROP].hInstance = hInst;
    editPages[PRINTFORMATPROP].u.pszTemplate = "PRINTFORMATPROPDLG";
    editPages[PRINTFORMATPROP].pfnDlgProc = PrintFormatProc;
    editPages[PRINTFORMATPROP].pszTitle = "Print Format";

    editPages[GENERALPROP].dwSize = sizeof(PROPSHEETPAGE);
    editPages[GENERALPROP].dwFlags = PSP_HASHELP;
    editPages[GENERALPROP].hInstance = hInst;
    editPages[GENERALPROP].u.pszTemplate = "GENERALPROPDLG";
    editPages[GENERALPROP].pfnDlgProc = GeneralProc;
    editPages[GENERALPROP].pszTitle = "General";

    editPages[INSTALLPROP].dwSize = sizeof(PROPSHEETPAGE);
    editPages[INSTALLPROP].dwFlags = PSP_HASHELP;
    editPages[INSTALLPROP].hInstance = hInst;
    editPages[INSTALLPROP].u.pszTemplate = "INSTALLPROPDLG";
    editPages[INSTALLPROP].pfnDlgProc = InstallProc;
    editPages[INSTALLPROP].pszTitle = "Install";

    // struct for property sheet header
    editHeader.dwSize = sizeof(PROPSHEETHEADER);
    editHeader.dwFlags = PSH_PROPSHEETPAGE | PSH_PROPTITLE | PSH_NOAPPLYNOW /* 
        | PSH_HASHELP*/;
    editHeader.hwndParent = hwnd;
    editHeader.hInstance = hInstance;
    editHeader.pszCaption = "General";
    editHeader.nPages = EDIT_PROPERTY_SHEET_COUNT;
    editHeader.u2.nStartPage = startPage;
    editHeader.u3.ppsp = &editPages[0];

    // make the property sheet and exit
    PropertySheet(&editHeader);
}

// ==============================================================
//
// property sheet constant names
//
#define TARGET_PROPERTY_SHEET_COUNT 6
#define TARGETPROP 0
#define DEBUGPROP 1
#define DEFINEPROP 2
#define TOOLOPTSPROP 3
#define PREBUILDPROP 4
#define POSTBUILDPROP 5

static PROPSHEETPAGE pages[TARGET_PROPERTY_SHEET_COUNT]; // the page structures
static PROPSHEETHEADER header; // the header structure
static PROJLIST *proj;
static PROJLIST workProj;

DEFINES *duplicateDefines(DEFINES *p)
{
    DEFINES *rv = 0,  **l = &rv;
    while (p)
    {
        *l = calloc(1,sizeof(DEFINES));
        if (! *l)
            return rv;
        **l =  *p;
        (*l)->next = 0;
        p = p->next;
        l = &(*l)->next;
    }
    return rv;
}

// ==============================================================
//
static int FAR PASCAL TargetProc(HWND hwnd, UINT wmsg, WPARAM wparam, LPARAM
    lparam)

{
    NMHDR *nmhead;
    int l;
    switch (wmsg)
    {
        case WM_INITDIALOG:
            return TRUE;
        case WM_NOTIFY:
            nmhead = (NMHDR*)lparam;
            switch (nmhead->code)
            {
            case PSN_SETACTIVE:
                /* page startup */
                SendDlgItemMessage(hwnd, IDC_BUILDTYPE, CB_RESETCONTENT, 0, 0);
                SendDlgItemMessage(hwnd, IDC_LIBTYPE, CB_RESETCONTENT, 0, 0);
                NewFocus(hwnd, IDC_BUILDTYPE);
                SetEditField(hwnd, IDC_INCLUDEPATH, relincludepath
                    (workProj.includePath, workProj.projectName));
                SetEditField(hwnd, IDC_OUTPUTPATH, relpath(workProj.outputPath, workProj.projectName))
                    ;
                SetCBField(hwnd, IDC_DEBUGINFO, workProj.buildFlags
                    &BF_DEBUGINFO ? 1 : 0);
                SetCBField(hwnd, IDC_MAPFILE, workProj.buildFlags &BF_MAPFILE ?
                    1 : 0);
                SetCBField(hwnd, IDC_COMPILEVIAASM, workProj.buildFlags
                    &BF_COMPILEVIAASM ? 1 : 0);
                SetCBField(hwnd, IDC_SHOWWARNINGS, workProj.buildFlags
                    &BF_SHOWWARNINGS ? 1 : 0);
                SetCBField(hwnd, IDC_C99, workProj.buildFlags &BF_C99 ? 1 : 0);
                SetCBField(hwnd, IDC_ANSI, workProj.buildFlags &BF_ANSI ? 1 : 0);
                SetCBField(hwnd, IDC_ALIGNSTACK, workProj.buildFlags 
						   &BF_ALIGNSTACK ? 1 : 0);
                AddComboString(hwnd, IDC_BUILDTYPE, "Windows Console");
                AddComboString(hwnd, IDC_BUILDTYPE, "Windows GUI");
                AddComboString(hwnd, IDC_BUILDTYPE, "Windows DLL");
                AddComboString(hwnd, IDC_BUILDTYPE, "Library");
                AddComboString(hwnd, IDC_BUILDTYPE, "MSDOS");
                AddComboString(hwnd, IDC_BUILDTYPE, "RAW");
                SetComboSel(hwnd, IDC_BUILDTYPE, workProj.buildType);
                AddComboString(hwnd, IDC_LIBTYPE, "Static RTL");
                AddComboString(hwnd, IDC_LIBTYPE, "Dynamic RTL");
                AddComboString(hwnd, IDC_LIBTYPE, "No Library");
                AddComboString(hwnd, IDC_LIBTYPE, "CRTDLL.DLL");
                SetComboSel(hwnd, IDC_LIBTYPE, workProj.libType);
                break;
            case PSN_KILLACTIVE:
                workProj.buildType = GetComboSel(hwnd, IDC_BUILDTYPE);
                workProj.libType = GetComboSel(hwnd, IDC_LIBTYPE);
				if (workProj.buildType < 0)
					workProj.buildType = proj->buildType;
				if (workProj.libType < 0)
					workProj.libType = proj->libType;
                GetEditField(hwnd, IDC_INCLUDEPATH, workProj.includePath);
                GetEditField(hwnd, IDC_OUTPUTPATH, workProj.outputPath);
                if (workProj.includePath[0] && workProj.includePath[strlen
                    (workProj.includePath) - 1] == '\\')
                    workProj.includePath[strlen(workProj.includePath) - 1] = 0;
                if (workProj.outputPath[0] && workProj.outputPath[strlen
                    (workProj.outputPath) - 1] == '\\')
                    workProj.outputPath[strlen(workProj.outputPath) - 1] = 0;
                absincludepath(workProj.includePath, workProj.projectName);
                abspath(workProj.outputPath, workProj.projectName);
                workProj.buildFlags &= ~(BF_DEBUGINFO | BF_MAPFILE | BF_ANSI |
                    BF_COMPILEVIAASM | BF_CRTDLL | BF_C99 | BF_ALIGNSTACK);
                if (GetCBField(hwnd, IDC_DEBUGINFO))
                    workProj.buildFlags |= BF_DEBUGINFO;
                if (GetCBField(hwnd, IDC_MAPFILE))
                    workProj.buildFlags |= BF_MAPFILE;
                if (GetCBField(hwnd, IDC_COMPILEVIAASM))
                    workProj.buildFlags |= BF_COMPILEVIAASM;
                if (GetCBField(hwnd, IDC_SHOWWARNINGS))
                    workProj.buildFlags |= BF_SHOWWARNINGS;
                if (GetCBField(hwnd, IDC_C99))
                    workProj.buildFlags |= BF_C99;
                if (GetCBField(hwnd, IDC_ANSI))
                    workProj.buildFlags |= BF_ANSI;
                if (GetCBField(hwnd, IDC_ALIGNSTACK))
                    workProj.buildFlags |= BF_ALIGNSTACK;
                /* verify ok always */
                SetResult(hwnd, FALSE);
                break;
            case PSN_APPLY:
                /* Page application */
				if (proj->buildType != workProj.buildType ||
					proj->libType != workProj.libType ||
					proj->buildFlags != workProj.buildFlags ||
					proj->defineFlags != workProj.defineFlags ||
					strcmp(proj->compileopts, workProj.compileopts) ||
					strcmp(proj->assembleopts, workProj.assembleopts) ||
					strcmp(proj->linkopts, workProj.linkopts) ||
					strcmp(proj->libopts, workProj.libopts) ||
					strcmp(proj->prebuildsteps, workProj.prebuildsteps) ||
					strcmp(proj->postbuildsteps, workProj.postbuildsteps))
 	               workProj.buildFlags |= BF_CHANGEDTARGET;
				else
				{
					DEFINES *l = proj->defines, *l1 = workProj.defines;
					while (l && l1)
					{
						if (strcmp(l->name, l1->name) || strcmp(l->value, l1->value))
						{
		 	                workProj.buildFlags |= BF_CHANGEDTARGET;
							break;							
						}
						l = l->next ;
						l1 = l1->next ;
					}
					if (l || l1)
 	                    workProj.buildFlags |= BF_CHANGEDTARGET;
				}
                workProj.changed = TRUE ; 
                while ((l = strlen(workProj.prebuildsteps)) &&
                    workProj.prebuildsteps[l - 1] == '\n')
                    workProj.prebuildsteps[l - 1] = 0;
                while ((l = strlen(workProj.postbuildsteps)) &&
                    workProj.postbuildsteps[l - 1] == '\n')
                    workProj.postbuildsteps[l - 1] = 0;
                ProjectDeleteDefines(proj->defines);
                *proj = workProj;
                workProj.defines = duplicateDefines(proj->defines);
                changedProject = TRUE;
                break;
            case PSN_RESET:
                ProjectDeleteDefines(workProj.defines);
                break;
            case PSN_HELP:

                ContextHelp(IDH_COMPILER_CONFIGURATION);
                break;
            }
            break;
    }
    return FALSE;
}

// ==============================================================
//
static int FAR PASCAL DebugProc(HWND hwnd, UINT wmsg, WPARAM wparam, LPARAM
    lparam)

{
    NMHDR *nmhead;
    int disable_state;
    switch (wmsg)
    {
        case WM_INITDIALOG:
            return TRUE;
        case WM_NOTIFY:
            nmhead = (NMHDR*)lparam;
            switch (nmhead->code)
            {
            case PSN_SETACTIVE:
                /* page startup */
                disable_state = workProj.buildType != BT_CONSOLE &&
                    workProj.buildType != BT_WINDOWS;
                DisableControl(hwnd, IDC_BREAKWINMAIN, disable_state);
                DisableControl(hwnd, IDC_BREAKDLL, disable_state);
                DisableControl(hwnd, IDC_DEBUGEXCEPTION, disable_state);
                DisableControl(hwnd, IDC_DEBUGTOOLTIPS, disable_state);
                DisableControl(hwnd, IDC_EDITCMDLINE, disable_state);
                NewFocus(hwnd, IDC_BREAKWINMAIN);
                SetCBField(hwnd, IDC_BREAKWINMAIN, workProj.buildFlags
                    &BF_BREAKWINMAIN ? 1 : 0);
                SetCBField(hwnd, IDC_BREAKDLL, workProj.buildFlags &BF_BREAKDLL
                    ? 1 : 0);
                SetCBField(hwnd, IDC_DEBUGEXCEPTION, workProj.buildFlags
                    &BF_DEBUGEXCEPTION ? 1 : 0);
                SetCBField(hwnd, IDC_DEBUGTOOLTIPS, workProj.buildFlags
                    &BF_DEBUGTOOLTIPS ? 1 : 0);
                SetEditField(hwnd, IDC_EDITCMDLINE, workProj.cmdline);
                break;
            case PSN_KILLACTIVE:
                /* verify ok always */
                workProj.buildFlags &= ~(BF_BREAKWINMAIN | BF_BREAKDLL |
                    BF_DEBUGEXCEPTION | BF_DEBUGTOOLTIPS);
                if (GetCBField(hwnd, IDC_BREAKWINMAIN))
                    workProj.buildFlags |= BF_BREAKWINMAIN;
                if (GetCBField(hwnd, IDC_BREAKDLL))
                    workProj.buildFlags |= BF_BREAKDLL;
                if (GetCBField(hwnd, IDC_DEBUGEXCEPTION))
                    workProj.buildFlags |= BF_DEBUGEXCEPTION;
                if (GetCBField(hwnd, IDC_DEBUGTOOLTIPS))
                    workProj.buildFlags |= BF_DEBUGTOOLTIPS;
                GetEditField(hwnd, IDC_EDITCMDLINE, workProj.cmdline);
                SetResult(hwnd, FALSE);
                break;
            case PSN_APPLY:
                /* Page application */
                break;
            case PSN_HELP:
                ContextHelp(IDH_DEBUG_CONFIGURATION);
                break;
            }
            break;
    }
    return FALSE;
}

//-------------------------------------------------------------------------

void SetDefineLBEditFields(HWND hwnd, int selected)
{
    DEFINES *d = workProj.defines;
    if (!d)
    {
        SendDlgItemMessage(hwnd, IDC_DEFINENAME, WM_SETTEXT, 0, (LPARAM)"");
        SendDlgItemMessage(hwnd, IDC_DEFINEVALUE, WM_SETTEXT, 0, (LPARAM)"");
    }
    else
    {
        char *buf = (char*)SendDlgItemMessage(hwnd, IDC_DEFINELIST,
            LB_GETITEMDATA, selected, (LPARAM)buf);
        SendDlgItemMessage(hwnd, IDC_DEFINENAME, WM_SETTEXT, 0, (LPARAM)buf);
        while (d)
        {
            if (d->name == buf)
            {
                SendDlgItemMessage(hwnd, IDC_DEFINEVALUE, WM_SETTEXT, 0, 
                    (LPARAM)d->value);
                break;
            }
            d = d->next;
        }
    }

}

//-------------------------------------------------------------------------

void GetDefineText(HWND hwnd, int selected)
{
    DEFINES *d = workProj.defines;
    char *data;
    if (!d)
        return ;
    data = (char*)SendDlgItemMessage(hwnd, IDC_DEFINELIST, LB_GETITEMDATA,
        selected, 0);
    while (d)
    {
        if (d->name == data)
        {
            SendDlgItemMessage(hwnd, IDC_DEFINEVALUE, WM_GETTEXT, 256, (LPARAM)
                d->value);
            break;
        }
        d = d->next;
    }
}

//-------------------------------------------------------------------------

static BOOL CALLBACK daDlgProc(HWND hwnd, UINT wmsg, WPARAM wparam, LPARAM
    lparam)
{
    char buf[256],  *p;
    DEFINES **d1;
    switch (wmsg)
    {
        case WM_INITDIALOG:
            CenterWindow(hwnd);
            return 1;
        case WM_COMMAND:
            switch (LOWORD(wparam))
            {
            case IDOK:
                SendDlgItemMessage(hwnd, IDC_DFADD, WM_GETTEXT, 256, (LPARAM)
                    buf);
                if (buf[0] == 0)
                    break;
                p = buf;
                if (!isalpha(*p) &&  *p != '_')
                {
                    ExtendedMessageBox("Error", 0, "Invalid Define Name");
                    break;
                }
                while (*p)
                {
                    if (!isalnum(*p) &&  *p != '_')
                    {
                        ExtendedMessageBox("Error", 0, "Invalid Define Name");
                        break;
                    }
                    p++;
                }
                GetDefineText(definehWnd, defineSelected);
                d1 = &workProj.defines;
                while (*d1)
                {
                    if (!strcmp((*d1)->name, buf))
                        break;
                    d1 = &(*d1)->next;
                }
                if (*d1)
                {
                    defineSelected = SendDlgItemMessage(definehWnd,
                        IDC_DEFINELIST, LB_FINDSTRINGEXACT,  - 1, (LPARAM)buf);
                    SetDefineLBEditFields(definehWnd, defineSelected);
                    ExtendedMessageBox("Error", 0, 
                        "Define already exists, selecting");
                }
                else
                {
                    *d1 = calloc(sizeof(DEFINES), 1);
                    if (! *d1)
                        ExtendedMessageBox("out of memory", 0, "out of memory");
                    else
                    {
                        defineSelected = SendDlgItemMessage(definehWnd,
                            IDC_DEFINELIST, LB_ADDSTRING, 0, (LPARAM)buf);
                        strcpy((*d1)->name, buf);
                        SendDlgItemMessage(definehWnd, IDC_DEFINELIST,
                            LB_SETITEMDATA, defineSelected, (LPARAM)(*d1)->name)
                            ;
                        SendDlgItemMessage(definehWnd, IDC_DEFINELIST,
                            LB_SETCURSEL, defineSelected, 0);
                        SetDefineLBEditFields(definehWnd, defineSelected);
                    }
                }
                EndDialog(hwnd, 1);
                break;
            case IDCANCEL:
                EndDialog(hwnd, 0);
                break;
            }
            break;
        case WM_CLOSE:
            EndDialog(hwnd, 0);
            break;
    }
    return 0;
}

// ==============================================================
// ==============================================================
//
static int FAR PASCAL DefineProc(HWND hwnd, UINT wmsg, WPARAM wparam, LPARAM
    lparam)

{
    NMHDR *nmhead;
    DEFINES *d,  **d1;
    int disable_state;
    char buf[256];
    char *data;
    switch (wmsg)
    {
        case WM_INITDIALOG:
            return TRUE;
        case WM_COMMAND:
            switch (HIWORD(wparam))
            {
            case LBN_SELCHANGE:
                GetDefineText(hwnd, defineSelected);
                defineSelected = SendDlgItemMessage(hwnd, IDC_DEFINELIST,
                    LB_GETCURSEL, 0, 0);
                SetDefineLBEditFields(hwnd, defineSelected);
                break;
            }
            switch (LOWORD(wparam))
            {
            case IDC_DEFINEADD:
                definehWnd = hwnd;
                DialogBox(hInstance, "DEFINEADDDLG", GetParent(hwnd), (DLGPROC)
                    daDlgProc);
                break;
            case IDC_DEFINEREMOVE:
                d1 = &workProj.defines;
                data = (char*)SendDlgItemMessage(hwnd, IDC_DEFINELIST,
                    LB_GETITEMDATA, defineSelected, 0);
                SendDlgItemMessage(hwnd, IDC_DEFINELIST, LB_DELETESTRING,
                    defineSelected, 0);
                while (*d1)
                {
                    if ((*d1)->name == data)
                    {
                        DEFINES *d2 =  *d1;
                        (*d1) = (*d1)->next;
                        free(d2);
                        break;
                    }
                    d1 = &(*d1)->next;
                }
                if (defineSelected && defineSelected >= SendDlgItemMessage(hwnd,
                    IDC_DEFINELIST, LB_GETCOUNT, 0, 0))
                    defineSelected--;
                SetDefineLBEditFields(hwnd, defineSelected);
                break;
            }
            break;
        case WM_NOTIFY:
            nmhead = (NMHDR*)lparam;
            switch (nmhead->code)
            {
            case PSN_SETACTIVE:
                /* page startup */
                d = workProj.defines;
                SendDlgItemMessage(hwnd, IDC_DEFINELIST, LB_RESETCONTENT, 0, 0);
                while (d)
                {
                    int i = SendDlgItemMessage(hwnd, IDC_DEFINELIST,
                        LB_ADDSTRING, 0, (LPARAM)d->name);
                    SendDlgItemMessage(hwnd, IDC_DEFINELIST, LB_SETITEMDATA, i,
                        (LPARAM)d->name);
                    d = d->next;
                }
                SetDefineLBEditFields(hwnd, defineSelected);
                SetCBField(hwnd, IDC_DEFINEPASSTONASM, workProj.defineFlags
                    &DEFINE_TONASM ? 1 : 0);
                SetResult(hwnd, FALSE);
                break;
            case PSN_KILLACTIVE:
                GetDefineText(hwnd, defineSelected);
                workProj.defineFlags = GetCBField(hwnd, IDC_DEFINEPASSTONASM) ?
                    1 : 0;
                SetResult(hwnd, FALSE);
                break;
            case PSN_APPLY:
                /* Page application */
                break;
            case PSN_RESET:
                break;
            case PSN_HELP:
                ContextHelp(IDH_DEFINE_CONFIGURATION);
                break;
            }
            break;
    }
    return FALSE;
}

// ==============================================================
//
static int FAR PASCAL TooloptProc(HWND hwnd, UINT wmsg, WPARAM wparam, LPARAM
    lparam)

{
    NMHDR *nmhead;
    switch (wmsg)
    {
        case WM_INITDIALOG:
            return TRUE;
        case WM_NOTIFY:
            nmhead = (NMHDR*)lparam;
            switch (nmhead->code)
            {
            case PSN_SETACTIVE:
                /* page startup */
                SetEditField(hwnd, IDC_TOCOMPILER, workProj.compileopts);
                SetEditField(hwnd, IDC_TOASSEMBLER, workProj.assembleopts);
                SetEditField(hwnd, IDC_TOLINKER, workProj.linkopts);
                SetEditField(hwnd, IDC_TOLIBRARIAN, workProj.libopts);
                break;
            case PSN_KILLACTIVE:
                /* verify ok always */
                GetEditField(hwnd, IDC_TOCOMPILER, workProj.compileopts);
                GetEditField(hwnd, IDC_TOASSEMBLER, workProj.assembleopts);
                GetEditField(hwnd, IDC_TOLINKER, workProj.linkopts);
                GetEditField(hwnd, IDC_TOLIBRARIAN, workProj.libopts);
                SetResult(hwnd, FALSE);
                break;
            case PSN_APPLY:
                /* Page application */
                break;
            case PSN_HELP:
                ContextHelp(IDH_TOOL_CONFIGURATION);
                break;
            }
            break;
    }
    return FALSE;
}

// ==============================================================
//
static int FAR PASCAL PrebuildProc(HWND hwnd, UINT wmsg, WPARAM wparam, LPARAM
    lparam)

{
    NMHDR *nmhead;
    switch (wmsg)
    {
        case WM_INITDIALOG:
            return TRUE;
        case WM_NOTIFY:
            nmhead = (NMHDR*)lparam;
            switch (nmhead->code)
            {
            case PSN_SETACTIVE:
                SetEditField(hwnd, IDC_PREBUILDLABEL, workProj.prebuildlabel);
                SendMessage(GetDlgItem(hwnd, IDC_PREBUILDLABEL), EM_LIMITTEXT,
                    80, 0);
                SetEditField(hwnd, IDC_PREBUILDSTEPS, workProj.prebuildsteps);
                /* page startup */
                break;
            case PSN_KILLACTIVE:
                /* verify ok always */
                GetEditField(hwnd, IDC_PREBUILDLABEL, workProj.prebuildlabel);
                GetEditField(hwnd, IDC_PREBUILDSTEPS, workProj.prebuildsteps);
                SetResult(hwnd, FALSE);
                break;
            case PSN_APPLY:
                /* Page application */
                break;
            case PSN_HELP:
                ContextHelp(IDH_PREBUILD_CONFIGURATION);
                break;
            }
            break;
    }
    return FALSE;
}

// ==============================================================
//
static int FAR PASCAL PostbuildProc(HWND hwnd, UINT wmsg, WPARAM wparam, LPARAM
    lparam)

{
    NMHDR *nmhead;
    switch (wmsg)
    {
        case WM_INITDIALOG:
            return TRUE;
        case WM_NOTIFY:
            nmhead = (NMHDR*)lparam;
            switch (nmhead->code)
            {
            case PSN_SETACTIVE:
                SetEditField(hwnd, IDC_POSTBUILDLABEL, workProj.postbuildlabel);
                SendMessage(GetDlgItem(hwnd, IDC_POSTBUILDLABEL), EM_LIMITTEXT,
                    80, 0);
                SetEditField(hwnd, IDC_POSTBUILDSTEPS, workProj.postbuildsteps);
                /* page startup */
                break;
            case PSN_KILLACTIVE:
                /* verify ok always */
                GetEditField(hwnd, IDC_POSTBUILDLABEL, workProj.postbuildlabel);
                GetEditField(hwnd, IDC_POSTBUILDSTEPS, workProj.postbuildsteps);
                SetResult(hwnd, FALSE);
                break;
            case PSN_APPLY:
                /* Page application */
                break;
            case PSN_HELP:
                ContextHelp(IDH_POSTBUILD_CONFIGURATION);
                break;
            }
            break;
    }
    return FALSE;
}

// ==============================================================
//
// display the property sheet and return to caller
//
void TargetProperties(HINSTANCE hInst, HWND hwnd, PROJLIST *p)
{
    proj = p;
    workProj =  *p;
    defineSelected = 0;
    workProj.defines = duplicateDefines(workProj.defines);
    // struct for server page
    pages[TARGETPROP].dwSize = sizeof(PROPSHEETPAGE);
    pages[TARGETPROP].dwFlags = PSP_HASHELP;
    pages[TARGETPROP].hInstance = hInst;
    pages[TARGETPROP].u.pszTemplate = "TARGETPROPDLG";
    pages[TARGETPROP].pfnDlgProc = TargetProc;
    pages[TARGETPROP].pszTitle = "General";

    pages[DEBUGPROP].dwSize = sizeof(PROPSHEETPAGE);
    pages[DEBUGPROP].dwFlags = PSP_HASHELP;
    pages[DEBUGPROP].hInstance = hInst;
    pages[DEBUGPROP].u.pszTemplate = "DEBUGPROPDLG";
    pages[DEBUGPROP].pfnDlgProc = DebugProc;
    pages[DEBUGPROP].pszTitle = "Debug";

    pages[DEFINEPROP].dwSize = sizeof(PROPSHEETPAGE);
    pages[DEFINEPROP].dwFlags = PSP_HASHELP;
    pages[DEFINEPROP].hInstance = hInst;
    pages[DEFINEPROP].u.pszTemplate = "DEFINEPROPDLG";
    pages[DEFINEPROP].pfnDlgProc = DefineProc;
    pages[DEFINEPROP].pszTitle = "Defines";

    pages[TOOLOPTSPROP].dwSize = sizeof(PROPSHEETPAGE);
    pages[TOOLOPTSPROP].dwFlags = PSP_HASHELP;
    pages[TOOLOPTSPROP].hInstance = hInst;
    pages[TOOLOPTSPROP].u.pszTemplate = "TOOLOPTPROPDLG";
    pages[TOOLOPTSPROP].pfnDlgProc = TooloptProc;
    pages[TOOLOPTSPROP].pszTitle = "Tool Options";

    pages[PREBUILDPROP].dwSize = sizeof(PROPSHEETPAGE);
    pages[PREBUILDPROP].dwFlags = PSP_HASHELP;
    pages[PREBUILDPROP].hInstance = hInst;
    pages[PREBUILDPROP].u.pszTemplate = "PREBUILDPROPDLG";
    pages[PREBUILDPROP].pfnDlgProc = PrebuildProc;
    pages[PREBUILDPROP].pszTitle = "Pre Build Step";

    pages[POSTBUILDPROP].dwSize = sizeof(PROPSHEETPAGE);
    pages[POSTBUILDPROP].dwFlags = PSP_HASHELP;
    pages[POSTBUILDPROP].hInstance = hInst;
    pages[POSTBUILDPROP].u.pszTemplate = "POSTBUILDPROPDLG";
    pages[POSTBUILDPROP].pfnDlgProc = PostbuildProc;
    pages[POSTBUILDPROP].pszTitle = "Post Build Step";

    // struct for property sheet header
    header.dwSize = sizeof(PROPSHEETHEADER);
    header.dwFlags = PSH_PROPSHEETPAGE | PSH_PROPTITLE | PSH_NOAPPLYNOW /* |
        PSH_HASHELP*/;
    header.hwndParent = hwnd;
    header.hInstance = hInstance;
    header.pszCaption = "Target";
    header.nPages = TARGET_PROPERTY_SHEET_COUNT;
    header.u2.nStartPage = 0;
    header.u3.ppsp = &pages[0];

    // make the property sheet and exit
    PropertySheet(&header);
}
