// (c) 1999 Eric Williams.  Rights as specified under the WINE
// License.  Don't hoard code; share it!

//
// One might call this a Commdlg test jig.  Its sole function in life
// is to call the Commdlg Common Dialogs; at present it doesn't even
// do anything horribly interesting with the results.

// Ideally it would also do event logging and be a bit less stupid
// about displaying the results of the various requesters.  But hey,
// it's only a first step. :-)

#include <windows.h>
#include <commdlg.h>
#include <stdio.h>
#include "cmdlgtst.h"

// This structure is to set up flag / control associations for the custom
// requesters.  The ft_id is the id for the control (usually generated
// by the system) and the ft_bit is the flag bit which goes into the
// settings longword for the various Commdlg structures.  It is assumed
// that all flags fit in an unsigned long and that all bits are in fact
// one bit.

// The array of entries is terminated by {IDOK, 0}; the assumption is that
// IDOK would never be associated with a dialogbox control (since it's
// usually the ID of the OK button}.

struct FlagTableEntry {
	int ft_id;
	unsigned long ft_bit;
};

// #ifdef __WINE_WINDOWS_H
// #define EXPORT
// #define HWND HWND32
// int ctx_debug = 0;
// #else
// #define EXPORT _export
// #endif

//#define FAR
#define EXPORT

static char menuName[] = "TestCommdlgMenu";
static char className[] = "TestCommdlg";
static char windowName[] = "TestCommdlg Window";

// global hInstance variable.  This makes the code non-threadable,
// but wotthehell; this is Win32 anyway!  (Though it does work
// under Win16, if one doesn't run more than one copy at a time.)

static HINSTANCE g_hInstance;

// global CommDlg data structures for modals.  These are placed here
// so that the custom dialog boxes can get at them.

static PRINTDLG pd;
static COLORREF cc_cr[16];
static CHOOSECOLOR cc;
static LOGFONT cf_lf;
static CHOOSEFONT cf;
static char ofn_filepat[] = "All Files (*.*)\0*.*\0Only Text Files (*.txt)\0*.txt\0";
static char ofn_result[1024];
static OPENFILENAME ofn;

// Stuff for find and replace.  These are modeless, so I have to put them here.

static HWND findDialogBox = 0;
static UINT findMessageId = 0;

static int findDialogBoxInit = 0;
static int findDialogStructInit = 0;
static FINDREPLACE frS;
static char fromstring[1024], tostring[1024];

// Stuff for the drawing of the window(s).  I put them here for convenience.

static COLORREF fgColor = RGB(0, 0, 0); // not settable
static COLORREF bgColor = RGB(255, 255, 255);
static COLORREF txtColor = RGB(0, 0, 0); 

// Utility routines.  Currently there is only one, and it's a nasty
// reminder that I'm not done yet.

void nyi(HWND hWnd)
{
	MessageBox(hWnd, "Not yet implemented!", "NYI", MB_ICONEXCLAMATION | MB_OK);
}


// Initial initialization code.  This code simply shoves in predefined
// data into the COMMDLG data structures; in the future, I might use
// a series of loadable resources, or static initializers; of course,
// if Microsoft decides to change the field ordering, I'd be screwed.

void mwi_Print(HWND hWnd)
{
	pd.lStructSize = sizeof(PRINTDLG);
	pd.hwndOwner = hWnd;
	pd.hDevMode = 0;
	pd.hDevNames = 0;
	pd.hDC = 0;
	pd.Flags = 0;
	pd.nMinPage = 1;
	pd.nMaxPage = 100;
	pd.hInstance = 0;
	pd.lCustData = 0;
	pd.lpfnPrintHook = 0;
	pd.lpfnSetupHook = 0;
	pd.lpPrintTemplateName = 0;
	pd.lpSetupTemplateName = 0;
	pd.hPrintTemplate = 0;
	pd.hSetupTemplate = 0;

}

void mwi_Color(HWND hWnd)
{
	int i;

	// there's probably an init call for this, somewhere.

	for(i=0;i<16;i++)
		cc_cr[i] = RGB(0,0,0);

	cc.lStructSize = sizeof(CHOOSECOLOR);
	cc.hwndOwner = hWnd;
	cc.hInstance = 0;
	cc.rgbResult = RGB(0,0,0);
	cc.lpCustColors = cc_cr;
	cc.Flags = 0;
	cc.lCustData = 0;
	cc.lpfnHook = 0;
	cc.lpTemplateName = 0;
}

void mwi_Font(HWND hWnd)
{
	cf.lStructSize = sizeof(CHOOSEFONT);
	cf.hwndOwner = hWnd;
	cf.hDC = 0;
	cf.lpLogFont = &cf_lf;
	cf.Flags = 0;
	cf.rgbColors = RGB(0,0,0);  // what is *this* doing here??
	cf.lCustData = 0;
	cf.lpfnHook = 0;
	cf.lpTemplateName = 0;
	cf.hInstance = 0;
	cf.lpszStyle = 0;
	cf.nFontType = 0;
	cf.nSizeMin = 8;
	cf.nSizeMax = 72;
}

void mwi_File(HWND hWnd)
{
	ofn.lStructSize = sizeof(OPENFILENAME);
	ofn.hwndOwner = hWnd;
	ofn.hInstance = 0;
	ofn.lpstrFilter = (LPSTR) ofn_filepat;
	ofn.lpstrCustomFilter = 0;
	ofn.nMaxCustFilter = 0;
	ofn.nFilterIndex = 0;
	ofn.lpstrFile = ofn_result;
	ofn.nMaxFile = sizeof(ofn_result);
	ofn.lpstrFileTitle = 0;
	ofn.nMaxFileTitle = 0;
	ofn.lpstrInitialDir = 0;
	ofn.lpstrTitle = "Open File";
	ofn.Flags = 0;
	ofn.nFileOffset = 0;
	ofn.nFileExtension = 0;
	ofn.lpstrDefExt = "*";
	ofn.lCustData = 0;
	ofn.lpfnHook = 0;
	ofn.lpTemplateName = 0;

	ofn_result[0] = '\0';
}

void mwi_FindReplace(HWND hWnd)
{
	frS.lStructSize = sizeof(FINDREPLACE);
	frS.hwndOwner = hWnd;
	frS.hInstance = 0;
	frS.Flags = FR_DOWN;
	frS.lpstrFindWhat = fromstring;
	frS.lpstrReplaceWith = tostring;
	frS.wFindWhatLen = sizeof(fromstring);
	frS.wReplaceWithLen = sizeof(tostring);
	frS.lCustData = 0;
	frS.lpfnHook = 0;
	frS.lpTemplateName = 0;

	fromstring[0] = '\0';
	tostring[0] = '\0';
	findMessageId = RegisterWindowMessage(FINDMSGSTRING);
}

void mwi_InitAll(HWND hWnd)
{
	mwi_Print(hWnd);
	mwi_Font(hWnd);
	mwi_Color(hWnd);
	mwi_File(hWnd);
	mwi_FindReplace(hWnd);
}

// Various configurations for the window.  Ideally, this
// would be stored with the window itself, but then, this
// isn't the brightest of apps.  Wouldn't be hard to set up,
// though -- one of the neater functions of Windows, but if
// someone decides to load the windows themselves from resources,
// there might be a problem.

void paintMainWindow(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
	PAINTSTRUCT ps;
	RECT rect;
	HPEN pen;
	HFONT font;
	HBRUSH brush;

	// Commence painting!

	BeginPaint(hWnd, &ps);
	GetClientRect(hWnd, (LPRECT) &rect);

	pen = (HPEN) SelectObject(ps.hdc, CreatePen(0, 0, fgColor));
	brush = (HBRUSH) SelectObject(ps.hdc, CreateSolidBrush(bgColor));
	font = (HFONT) SelectObject(ps.hdc, CreateFontIndirect(&cf_lf));

	// only need to draw the exposed bit.
	Rectangle(ps.hdc, ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right, ps.rcPaint.bottom);

	// now draw a couple of lines, just for giggles.

	MoveToEx(ps.hdc, rect.left, rect.top, (POINT FAR *) 0);
	LineTo(ps.hdc, rect.right, rect.bottom);
	MoveToEx(ps.hdc, rect.left, rect.bottom, (POINT FAR *) 0);
	LineTo(ps.hdc, rect.right, rect.top);

	// draw some text

	SetTextAlign(ps.hdc, TA_CENTER|TA_BASELINE);
	SetTextColor(ps.hdc, txtColor);
	TextOut(ps.hdc, (rect.left+rect.right)/2, (rect.top+rect.bottom)/2, "Common Dialog Test Page", 23);

	SetTextAlign(ps.hdc, TA_LEFT|TA_TOP);
	TextOut(ps.hdc, rect.left, rect.top, ofn_result, strlen(ofn_result));

	// set the HDC back to the old pen and brush,
	// and delete the newly created objects.

	pen = (HPEN) SelectObject(ps.hdc, pen);
	DeleteObject(pen);
	brush = (HBRUSH) SelectObject(ps.hdc, brush);
	DeleteObject(brush);
	font = (HFONT) SelectObject(ps.hdc, font);
	DeleteObject(font);

	EndPaint(hWnd, &ps);
}

// This function simply returns an error indication.  Naturally,
// I do not (yet) see an elegant method by which one can convert
// the CDERR_xxx return values into something resembling usable text;
// consult cderr.h to see what was returned.

void mw_checkError(HWND hWnd, BOOL explicitcancel)
{
	DWORD errval = CommDlgExtendedError();
	if(errval) {
		char errbuf[80];

		sprintf(errbuf, "CommDlgExtendedError(): error code %ld (0x%lx)", errval, errval);
		MessageBox(hWnd, errbuf, "Error", MB_ICONEXCLAMATION | MB_OK);
	}
	else {
		if(explicitcancel) MessageBox(hWnd, "Nope, user canceled it.", "No", MB_OK);
	}
}

// The actual dialog function calls.  These merely wrap the Commdlg
// calls, and do something (not so) intelligent with the result.
// Ideally, the main window would refresh and take into account the
// various values specified in the dialog.

void mw_ColorSetup(HWND hWnd)
{
	if(ChooseColor(&cc)) {
		RECT rect;

		GetClientRect(hWnd, (LPRECT) &rect);
		InvalidateRect(hWnd, (LPRECT) &rect, FALSE);
		bgColor = cc.rgbResult;
	}
	else mw_checkError(hWnd, FALSE);
}

void mw_FontSetup(HWND hWnd)
{
	if(ChooseFont(&cf)) {
		RECT rect;
		GetClientRect(hWnd, (LPRECT) &rect);
		InvalidateRect(hWnd, (LPRECT) &rect, FALSE);
		txtColor = cf.rgbColors;
	}
	else mw_checkError(hWnd, FALSE);
}

void mw_FindSetup(HWND hWnd)
{
	if(findDialogBox == 0) {
		findDialogBox = FindText(&frS);
		if(findDialogBox==0) mw_checkError(hWnd,TRUE);
	}
}

void mw_ReplaceSetup(HWND hWnd)
{
	if(findDialogBox == 0) {
		findDialogBox = ReplaceText(&frS);
		if(findDialogBox==0) mw_checkError(hWnd,TRUE);
	}
}

void mw_OpenSetup(HWND hWnd)
{
	if(GetOpenFileName(&ofn)) {
		RECT rect;
		GetClientRect(hWnd, (LPRECT) &rect);
		InvalidateRect(hWnd, (LPRECT) &rect, FALSE);
	}
	else mw_checkError(hWnd,FALSE);
}

void mw_SaveSetup(HWND hWnd)
{
	if(GetSaveFileName(&ofn)) {
		RECT rect;
		GetClientRect(hWnd, (LPRECT) &rect);
		InvalidateRect(hWnd, (LPRECT) &rect, FALSE);
	}
	else mw_checkError(hWnd,FALSE);
}

// Can't find documentation in Borland for this one.  Does it
// exist at all, or is it merely a subdialog of Print?

void mw_PSetupSetup(HWND hWnd)
{
	nyi(hWnd);
}

void mw_PrintSetup(HWND hWnd)
{
	if(PrintDlg(&pd)) {
		// the following are suggested in the Borland documentation,
		// but aren't that useful until WinE starts to actually
		// function with respect to printing.

		// Escape(tmp.hDC, STARTDOC, 8, "Test-Doc", NULL);

	 /* Print text and rectangle */

		// TextOut(tmp.hDC, 50, 50, "Common Dialog Test Page", 23);

		// Rectangle(tmp.hDC, 50, 90, 625, 105);
		// Escape(tmp.hDC, NEWFRAME, 0, NULL, NULL);
		// Escape(tmp.hDC, ENDDOC, 0, NULL, NULL);
	 //	DeleteDC(tmp.hDC);
		 if (pd.hDevMode != NULL)
			 GlobalFree(pd.hDevMode);
		 if (pd.hDevNames != NULL)
			 GlobalFree(pd.hDevNames);

		 pd.hDevMode = 0;
		 pd.hDevNames = 0;

		 MessageBox(hWnd, "Success.", "Yes", MB_OK);
	}
	else mw_checkError(hWnd,TRUE);
}

// Some support functions for the custom dialog box handlers.
// In particular, we have to set things properly, and get the flags back.

void mwcd_SetFlags(HWND hWnd, struct FlagTableEntry *table, unsigned long flags)
{
	int i;

	for(i=0; table[i].ft_id != IDOK; i++)
	{
		CheckDlgButton(hWnd, table[i].ft_id,(table[i].ft_bit & flags) ? 1 : 0);
	}
}

unsigned long mwcd_GetFlags(HWND hWnd, struct FlagTableEntry * table)
{
	int i;
	unsigned long l = 0;

	for(i=0; table[i].ft_id != IDOK; i++)
	{
		if(IsDlgButtonChecked(hWnd, table[i].ft_id) == 1)
			l |= table[i].ft_bit;
	}

	return l;
}

// These functions are the custom dialog box handlers.
// The division of labor may be a tad peculiar; in particular,
// the flag tables should probably be in the main functions,
// not the handlers.  I'll fix that later; this works as of right now.

BOOL mwcd_Setup(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
					 struct FlagTableEntry * table, unsigned long * flags)
{
	switch(uMsg)
	{
		case WM_INITDIALOG:
			// Set the controls properly.

			mwcd_SetFlags(hWnd, table, *flags);

			return TRUE; // I would return FALSE if I explicitly called SetFocus().
							 // As usual, Windows is weird.

		case WM_COMMAND:
			switch(wParam) {
				case IDOK:
					*flags = mwcd_GetFlags(hWnd, table);
					EndDialog(hWnd,1);
					break;

				case IDCANCEL:
					EndDialog(hWnd,0);
					break;

				case CM_R_HELP:
					break; // help?  We don't need no steenkin help!

				default:
					break; // eat the message
			}
			return TRUE;

		default:
			return FALSE; // since I don't process this particular message
	}
}

BOOL CALLBACK mwcd_ColorSetup(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	static struct FlagTableEntry flagTable[] = {
		{I_CC_RGBINIT, CC_RGBINIT},
		{I_CC_SHOWHELP, CC_SHOWHELP},
		{I_CC_PREVENTFULLOPEN, CC_PREVENTFULLOPEN},
		{I_CC_FULLOPEN, CC_FULLOPEN},
		{I_CC_ENABLETEMPLATEHANDLE, CC_ENABLETEMPLATEHANDLE},
		{I_CC_ENABLETEMPLATE, CC_ENABLETEMPLATE},
		{I_CC_ENABLEHOOK, CC_ENABLEHOOK},
		{IDOK, 0},
	};

	return mwcd_Setup(hWnd, uMsg, wParam, lParam, flagTable, &cc.Flags);
}

BOOL CALLBACK mwcd_FontSetup(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	static struct FlagTableEntry flagTable[] = {
		{I_CF_APPLY, CF_APPLY},
		{I_CF_ANSIONLY, CF_ANSIONLY},
		{I_CF_BOTH, CF_BOTH},
		{I_CF_TTONLY, CF_TTONLY},
		{I_CF_EFFECTS, CF_EFFECTS},
		{I_CF_ENABLEHOOK, CF_ENABLEHOOK},
		{I_CF_ENABLETEMPLATE, CF_ENABLETEMPLATE},
		{I_CF_ENABLETEMPLATEHANDLE, CF_ENABLETEMPLATEHANDLE},
		{I_CF_FIXEDPITCHONLY, CF_FIXEDPITCHONLY},
		{I_CF_INITTOLOGFONTSTRUCT, CF_INITTOLOGFONTSTRUCT},
		{I_CF_LIMITSIZE, CF_LIMITSIZE},
		{I_CF_NOFACESEL, CF_NOFACESEL},
		{I_CF_USESTYLE, CF_USESTYLE},
		{I_CF_WYSIWYG, CF_WYSIWYG},
		{I_CF_SHOWHELP, CF_SHOWHELP},
		{I_CF_SCREENFONTS, CF_SCREENFONTS},
		{I_CF_SCALABLEONLY, CF_SCALABLEONLY},
		{I_CF_PRINTERFONTS, CF_PRINTERFONTS},
		{I_CF_NOVECTORFONTS, CF_NOVECTORFONTS},
		{I_CF_NOSTYLESEL, CF_NOSTYLESEL},
		{I_CF_NOSIZESEL, CF_NOSIZESEL},
		{I_CF_NOOEMFONTS, CF_NOOEMFONTS},
		{IDOK, 0},
	};

	return mwcd_Setup(hWnd, uMsg, wParam, lParam, flagTable, &cf.Flags);
}

BOOL CALLBACK mwcd_FindSetup(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{

	static struct FlagTableEntry flagTable[] = {
		{I_FR_DIALOGTERM, FR_DIALOGTERM},
		{I_FR_DOWN, FR_DOWN},
		{I_FR_ENABLEHOOK, FR_ENABLEHOOK},
		{I_FR_ENABLETEMPLATE, FR_ENABLETEMPLATE},
		{I_FR_ENABLETEMPLATEHANDLE, FR_ENABLETEMPLATEHANDLE},
		{I_FR_FINDNEXT, FR_FINDNEXT},
		{I_FR_HIDEMATCHCASE, FR_HIDEMATCHCASE},
		{I_FR_HIDEWHOLEWORD, FR_HIDEWHOLEWORD},
		{I_FR_HIDEUPDOWN, FR_HIDEUPDOWN},
		{I_FR_MATCHCASE, FR_MATCHCASE},
		{I_FR_NOMATCHCASE, FR_NOMATCHCASE},
		{I_FR_NOUPDOWN, FR_NOUPDOWN},
		{I_FR_NOWHOLEWORD, FR_NOWHOLEWORD},
		{I_FR_REPLACE, FR_REPLACE},
		{I_FR_REPLACEALL, FR_REPLACEALL},
		{I_FR_SHOWHELP, FR_SHOWHELP},
		{I_FR_WHOLEWORD, FR_WHOLEWORD},
		{IDOK, 0},
	};

	return mwcd_Setup(hWnd, uMsg, wParam, lParam, flagTable, &frS.Flags);
}

BOOL CALLBACK mwcd_PrintSetup(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	static struct FlagTableEntry flagTable[] = {
		{I_PD_ALLPAGES, PD_ALLPAGES},
		{I_PD_COLLATE, PD_COLLATE},
		{I_PD_DISABLEPRINTTOFILE, PD_DISABLEPRINTTOFILE},
		{I_PD_ENABLEPRINTHOOK, PD_ENABLEPRINTHOOK},
		{I_PD_ENABLEPRINTTEMPLATE, PD_ENABLEPRINTTEMPLATE},
		{I_PD_ENABLEPRINTTEMPLATEHANDLE, PD_ENABLEPRINTTEMPLATEHANDLE},
		{I_PD_ENABLESETUPHOOK, PD_ENABLESETUPHOOK},
		{I_PD_ENABLESETUPTEMPLATE, PD_ENABLESETUPTEMPLATE},
		{I_PD_ENABLESETUPTEMPLATEHANDLE, PD_ENABLESETUPTEMPLATEHANDLE},
		{I_PD_HIDEPRINTTOFILE, PD_HIDEPRINTTOFILE},
		{I_PD_NOPAGENUMS, PD_NOPAGENUMS},
		{I_PD_NOSELECTION, PD_NOSELECTION},
		{I_PD_NOWARNING, PD_NOWARNING},
		{I_PD_PAGENUMS, PD_PAGENUMS},
		{I_PD_PRINTSETUP, PD_PRINTSETUP},
		{I_PD_PRINTTOFILE, PD_PRINTTOFILE},
		{I_PD_RETURNDC, PD_RETURNDC},
		{I_PD_RETURNDEFAULT, PD_RETURNDEFAULT},
		{I_PD_RETURNIC, PD_RETURNIC},
		{I_PD_SELECTION, PD_SELECTION},
		{I_PD_SHOWHELP, PD_SHOWHELP},
		{I_PD_USEDEVMODECOPIES, PD_USEDEVMODECOPIES},
		{IDOK, 0},
	};

	return mwcd_Setup(hWnd, uMsg, wParam, lParam, flagTable, &pd.Flags);
}

BOOL CALLBACK mwcd_FileSetup(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	static struct FlagTableEntry flagTable[] = {
		{I_OFN_ALLOWMULTISELECT, OFN_ALLOWMULTISELECT},
		{I_OFN_CREATEPROMPT, OFN_CREATEPROMPT},
		{I_OFN_ENABLEHOOK, OFN_ENABLEHOOK},
		{I_OFN_ENABLETEMPLATE, OFN_ENABLETEMPLATE},
		{I_OFN_ENABLETEMPLATEHANDLE, OFN_ENABLETEMPLATEHANDLE},
		{I_OFN_EXTENSIONDIFFERENT, OFN_EXTENSIONDIFFERENT},
		{I_OFN_FILEMUSTEXIST, OFN_FILEMUSTEXIST},
		{I_OFN_HIDEREADONLY, OFN_HIDEREADONLY},
		{I_OFN_NOCHANGEDIR, OFN_NOCHANGEDIR},
		{I_OFN_NOREADONLYRETURN, OFN_NOREADONLYRETURN},
		{I_OFN_NOTESTFILECREATE, OFN_NOTESTFILECREATE},
		{I_OFN_NOVALIDATE, OFN_NOVALIDATE},
		{I_OFN_OVERWRITEPROMPT, OFN_OVERWRITEPROMPT},
		{I_OFN_PATHMUSTEXIST, OFN_PATHMUSTEXIST},
		{I_OFN_READONLY, OFN_READONLY},
		{I_OFN_SHAREAWARE, OFN_SHAREAWARE},
      {I_OFN_SHOWHELP, OFN_SHOWHELP},
		{IDOK, 0},
	};

	return mwcd_Setup(hWnd, uMsg, wParam, lParam, flagTable, &pd.Flags);
}

BOOL CALLBACK mwcd_About(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch(uMsg) {
		case WM_INITDIALOG: return TRUE; // let WINDOWS set the focus.
		case WM_COMMAND: EndDialog(hWnd, 0); return TRUE; // it's our OK button.
		default: return FALSE; // it's something else, let Windows worry about it
	}
}


// These functions call custom dialog boxes (resource-loaded, if I do this right).
// Right now they don't do a heck of a lot, but at some future time
// they will muck about with the flags (and be loaded from the flags) of
// the CommDlg structures initialized by the mwi_xxx() routines.

void mwc_ColorSetup(HWND hWnd)
{
	int r = DialogBox(g_hInstance, "Color_Flags_Dialog", hWnd, (DLGPROC) mwcd_ColorSetup);
	if(r < 0) { MessageBox(hWnd, "Failure opening Color_Flags_Dialog box", "Error", MB_ICONASTERISK|MB_OK); }
}

void mwc_FontSetup(HWND hWnd)
{
	int r = DialogBox(g_hInstance, "Font_Flags_Dialog", hWnd, (DLGPROC) mwcd_FontSetup);
	if(r < 0) { MessageBox(hWnd, "Failure opening Font_Flags_Dialog box", "Error", MB_ICONASTERISK|MB_OK); }
}

void mwc_FindReplaceSetup(HWND hWnd)
{
	int r = DialogBox(g_hInstance, "Find_Flags_Dialog", hWnd, (DLGPROC) mwcd_FindSetup);
	if(r < 0) { MessageBox(hWnd, "Failure opening Find_Flags_Dialog box", "Error", MB_ICONASTERISK|MB_OK); }
}

void mwc_PrintSetup(HWND hWnd)
{
	int r = DialogBox(g_hInstance, "Print_Flags_Dialog", hWnd, (DLGPROC) mwcd_PrintSetup);
	if(r < 0) { MessageBox(hWnd, "Failure opening Print_Flags_Dialog box", "Error", MB_ICONASTERISK|MB_OK); }
}

void mwc_FileSetup(HWND hWnd)
{
	int r = DialogBox(g_hInstance, "File_Flags_Dialog", hWnd, (DLGPROC) mwcd_PrintSetup);
	if(r < 0) { MessageBox(hWnd, "Failure opening File_Flags_Dialog box", "Error", MB_ICONASTERISK|MB_OK); }
}

// Main window message dispatcher.  Here the messages get chewed up
// and spit out.  Note the ugly hack for the modeless Find/Replace box;
// this looks like it was bolted on with hexhead screws and is now
// dangling from Windows like a loose muffler.  Sigh.

LRESULT CALLBACK EXPORT mainWindowDispatcher(
	HWND hWnd,
	UINT uMsg,
	WPARAM wParam,
	LPARAM lParam
)
{

	if(uMsg == findMessageId) {
		FINDREPLACE FAR* lpfr = (FINDREPLACE FAR*) lParam;
		if(lpfr->Flags & FR_DIALOGTERM) {
			MessageBox(hWnd, "User closing us down.", "Down", MB_OK);
			findDialogBox = 0;
		}
		else if (lpfr->Flags & FR_FINDNEXT) {
			MessageBox(hWnd, "Finding next occurrence.", "Findnext", MB_OK);
		}
		else if (lpfr->Flags & FR_REPLACE) {
			MessageBox(hWnd, "Replacing next occurence.", "Replace", MB_OK);
		}
		else if (lpfr->Flags & FR_REPLACEALL) {
			MessageBox(hWnd, "Replacing all occurrences.", "Replace All", MB_OK);
		}
		else {
			MessageBox(hWnd, "Eh?", "Eh?", MB_OK);
		}
		return 1;
	}
	else switch(uMsg) {
	case WM_CREATE:
			// this is always the first message...at least as far as
			// we are concerned.
		mwi_InitAll(hWnd);
		break;

	case WM_PAINT:
			// Well, draw something!
		paintMainWindow(hWnd, uMsg, wParam, lParam);
		break;

	case WM_DESTROY:
			// Uh oh.  Eject!  Eject!  Eject!
		PostQuitMessage(0);
		break;

	case WM_COMMAND:
			// menu or accelerator pressed; do something.

		switch(wParam) {
		case CM_U_EXIT:
				// Uh oh.  Eject!  Eject!  Eject!
			PostQuitMessage(0);
			break;

		// these actually call the Common Dialogs.

		case CM_U_COLOR:
			mw_ColorSetup(hWnd); return 1;

		case CM_U_FONT:
			mw_FontSetup(hWnd); return 1;

		case CM_U_FIND:
			mw_FindSetup(hWnd); return 1;

		case CM_U_REPLACE:
			mw_ReplaceSetup(hWnd); return 1;

		case CM_U_OPEN:
			mw_OpenSetup(hWnd); return 1;

		case CM_U_SAVE:
			mw_SaveSetup(hWnd); return 1;

		case CM_U_PSETUP:
			mw_PSetupSetup(hWnd); return 1;

		case CM_U_PRINT:
			mw_PrintSetup(hWnd); return 1;

		// these set up various flags and values in the Common Dialog
		// data structures, which are currently stored in static memory.
		// The control dialogs themselves are resources as well.

		case CM_F_FILE:
			mwc_FileSetup(hWnd); return 1;

		case CM_F_COLOR:
			mwc_ColorSetup(hWnd); return 1;

		case CM_F_FONT:
			mwc_FontSetup(hWnd); return 1;

		case CM_F_FINDREPLACE:
			mwc_FindReplaceSetup(hWnd); return 1;

		case CM_F_PRINT:
			mwc_PrintSetup(hWnd); return 1;

		case CM_H_ABOUT:
			DialogBox(g_hInstance, "AboutDialog", hWnd, (DLGPROC) mwcd_About);
		case CM_H_USAGE:
			DialogBox(g_hInstance, "UsageDialog", hWnd, (DLGPROC) mwcd_About);
         	// return value?  *What* return value?
			return 1;

		default:
			nyi(hWnd); return 1;
		}
		break;

	default:
		return DefWindowProc(hWnd, uMsg, wParam, lParam);
	}
	return 0;
}

// Class registration.  One might call this a Windowsism.

int registerMainWindowClass(HINSTANCE hInstance)
{
	WNDCLASS wndClass;

	wndClass.style         = CS_HREDRAW|CS_VREDRAW;
	wndClass.lpfnWndProc   = mainWindowDispatcher;
	wndClass.cbClsExtra    = 0;
	wndClass.cbWndExtra    = 0;
	wndClass.hInstance     = hInstance;
	//wndClass.hIcon         = LoadIcon(hInstance, "whello");
	//wndClass.hCursor       = LoadCursor(hInstance, IDC_ARROW);
	wndClass.hIcon         = 0;
	wndClass.hCursor       = 0;
	wndClass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
	wndClass.lpszMenuName  = menuName;
	wndClass.lpszClassName = className;

	return RegisterClass(&wndClass);
}

// Another Windowsism; this one's not too bad, as it compares
// favorably with CreateWindow() in X (mucking about with X Visuals
// can get messy; at least here we don't have to worry about that).

HWND createMainWindow(HINSTANCE hInstance, int show)
{
	HWND hWnd;

	hWnd = CreateWindow(
		className,  // classname
		windowName,  // windowname/title
		WS_OVERLAPPEDWINDOW, // dwStyle
		0, //x
		0, //y
		CW_USEDEFAULT, //width
		CW_USEDEFAULT, //height
		0, // parent window
		0, // menu
		hInstance, // instance
		0          // passthrough for MDI
	);

	if(hWnd==0) return 0;

	ShowWindow(hWnd, show);
	UpdateWindow(hWnd);

	return hWnd;
}

int messageLoop(HINSTANCE hInstance, HWND hWnd)
{

	MSG msg;

	while(GetMessage(&msg, 0, 0, 0)) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return msg.wParam;
}

// Oh, did we tell you that main() isn't the name of the
// thing called in a Win16/Win32 app?  And then there are
// the lack of argument lists, the necessity (at least in Win16)
// of having to deal with class registration exactly once (as the
// app may be run again), and some other bizarre holdovers from
// Windows 3.x days.  But hey, Solitaire still works.

int PASCAL WinMain(
	HINSTANCE hInstance, HINSTANCE hPrevInstance,
	LPSTR lpszCmdLine, int nCmdShow
)
{
	HWND hWnd;

	strcpy(ofn_result, "--- not yet set ---");

	if(hPrevInstance==0) {
		if(!registerMainWindowClass(hInstance))
			return -1;
	}

	g_hInstance = hInstance;

	hWnd = createMainWindow(hInstance,nCmdShow);
	if(hWnd == 0)
		return -1;


	return messageLoop(hInstance, hWnd);
}

// And now the end of the program.  Enjoy.

// (c) 1999 Eric Williams.  Rights as specified under the WINE
// License.  Don't hoard code; share it!

