Attempt at fixing MAX_PATH issues for mingw.
[wine/gsoc_dplay.git] / programs / cmdlgtst / cmdlgtst.c
blobe5d85b0f712b5455f42d5279d8462444f46c3116
1 /*
2 * Copyright (c) 1999-2000 Eric Williams.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * One might call this a Commdlg test jig. Its sole function in life
21 * is to call the Commdlg Common Dialogs. The results of a call to
22 * File Open or File Save are printed in the upper left corner;
23 * Font adjusts the font of the printout, and Color adjusts the color
24 * of the background.
28 * Ideally it would also do event logging and be a bit less stupid
29 * about displaying the results of the various requesters. But hey,
30 * it's only a first step. :-)
33 #include <windows.h>
34 #include <commdlg.h>
35 #include <stdio.h>
36 #include <string.h>
37 #include "cmdlgtst.h"
40 * This structure is to set up flag / control associations for the custom
41 * requesters. The ft_id is the id for the control (usually generated
42 * by the system) and the ft_bit is the flag bit which goes into the
43 * settings longword for the various Commdlg structures. It is assumed
44 * that all flags fit in an unsigned long and that all bits are in fact
45 * one bit.
49 * The array of entries is terminated by {IDOK, 0}; the assumption is that
50 * IDOK would never be associated with a dialogbox control (since it's
51 * usually the ID of the OK button}.
54 struct FlagTableEntry {
55 int ft_id;
56 unsigned long ft_bit;
59 #if 0
60 #define FAR
61 #endif
62 #define EXPORT
64 static char menuName[] = "CmdlgtstMenu";
65 static char className[] = "CmdlgtstClass";
66 static char windowName[] = "Cmdlgtst Window";
69 * global hInstance variable. This makes the code non-threadable,
70 * but wotthehell; this is Win32 anyway! (Though it does work
71 * under Win16, if one doesn't run more than one copy at a time.)
74 static HINSTANCE g_hInstance;
77 * global CommDlg data structures for modals. These are placed here
78 * so that the custom dialog boxes can get at them.
81 static PRINTDLG pd;
82 static COLORREF cc_cr[16];
83 static CHOOSECOLOR cc;
84 static LOGFONT cf_lf;
85 static CHOOSEFONT cf;
86 static char ofn_filepat[] = "All Files (*.*)\0*.*\0Only Text Files (*.txt)\0*.txt\0";
87 static char ofn_result[1024];
88 static char ofn_titleresult[128];
89 static OPENFILENAME ofn;
91 /* Stuff for find and replace. These are modeless, so I have to put them here. */
93 static HWND findDialogBox = 0;
94 static UINT findMessageId = 0;
96 static FINDREPLACE frS;
97 static char fromstring[1024], tostring[1024];
99 /* Stuff for the drawing of the window(s). I put them here for convenience. */
101 static COLORREF fgColor = RGB(0, 0, 0); /* not settable */
102 static COLORREF bgColor = RGB(255, 255, 255); /* COLOR dialog */
103 static COLORREF txtColor = RGB(0, 0, 0); /* settable if one enables CF_EFFECTS */
105 /* Utility routines. */
107 void nyi(HWND hWnd)
109 /* "Hi there! I'm not yet implemented!" */
110 MessageBox(hWnd, "Not yet implemented!", "NYI", MB_ICONEXCLAMATION | MB_OK);
113 UINT CALLBACK dummyfnHook(HWND hWnd, UINT msg, UINT wParam, UINT lParam)
116 * If the user specifies something that needs an awfully stupid hook function,
117 * this is the one to use. It's a no-op, and says "I didn't do anything."
120 (void) hWnd;
121 (void) msg;
122 (void) wParam;
123 (void) lParam;
125 printf("dummyfnhook\n"); /* visible under Wine, but Windows probably won't see it! */
127 return 0;
131 * Initialization code. This code simply shoves in predefined
132 * data into the COMMDLG data structures; in the future, I might use
133 * a series of loadable resources, or static initializers; of course,
134 * if Microsoft decides to change the field ordering, I'd be screwed.
137 void mwi_Print(HWND hWnd)
139 pd.lStructSize = sizeof(PRINTDLG);
140 pd.hwndOwner = hWnd;
141 pd.hDevMode = 0;
142 pd.hDevNames = 0;
143 pd.hDC = 0;
144 pd.Flags = 0;
145 pd.nMinPage = 1;
146 pd.nMaxPage = 100;
147 pd.hInstance = g_hInstance;
148 pd.lCustData = 0;
149 pd.lpfnPrintHook = 0;
150 pd.lpfnSetupHook = 0;
151 pd.lpPrintTemplateName = 0;
152 pd.lpSetupTemplateName = 0;
153 pd.hPrintTemplate = 0;
154 pd.hSetupTemplate = 0;
157 void mwi_Color(HWND hWnd)
159 int i;
161 /* there's probably an init call for this, somewhere. */
163 for(i=0;i<16;i++)
164 cc_cr[i] = RGB(0,0,0);
166 cc.lStructSize = sizeof(CHOOSECOLOR);
167 cc.hwndOwner = hWnd;
168 cc.hInstance = (HWND)g_hInstance; /* Should be an HINSTANCE but MS made a typo */
169 cc.rgbResult = RGB(0,0,0);
170 cc.lpCustColors = cc_cr;
171 cc.Flags = 0;
172 cc.lCustData = 0;
173 cc.lpfnHook = 0;
174 cc.lpTemplateName = 0;
177 void mwi_Font(HWND hWnd)
179 cf.lStructSize = sizeof(CHOOSEFONT);
180 cf.hwndOwner = hWnd;
181 cf.hDC = 0;
182 cf.lpLogFont = &cf_lf;
183 cf.Flags = CF_SCREENFONTS; /* something's needed for display; otherwise it craps out with an error */
184 cf.rgbColors = RGB(0,0,0); /* what is *this* doing here?? */
185 cf.lCustData = 0;
186 cf.lpfnHook = 0;
187 cf.lpTemplateName = 0;
188 cf.hInstance = g_hInstance;
189 cf.lpszStyle = 0;
190 cf.nFontType = 0;
191 cf.nSizeMin = 8;
192 cf.nSizeMax = 72;
194 cf_lf.lfHeight = -18; /* this can be positive or negative, but negative is usually used. */
197 void mwi_File(HWND hWnd)
199 ofn.lStructSize = sizeof(OPENFILENAME);
200 ofn.hwndOwner = hWnd;
201 ofn.hInstance = g_hInstance;
202 ofn.lpstrFilter = (LPSTR) ofn_filepat;
203 ofn.lpstrCustomFilter = 0;
204 ofn.nMaxCustFilter = 0;
205 ofn.nFilterIndex = 0;
206 ofn.lpstrFile = ofn_result;
207 ofn.nMaxFile = sizeof(ofn_result);
208 ofn.lpstrFileTitle = ofn_titleresult;
209 ofn.nMaxFileTitle = sizeof(ofn_titleresult);
210 ofn.lpstrInitialDir = 0;
211 ofn.lpstrTitle = "Open File";
212 ofn.Flags = 0;
213 ofn.nFileOffset = 0;
214 ofn.nFileExtension = 0;
215 ofn.lpstrDefExt = "*";
216 ofn.lCustData = 0;
217 ofn.lpfnHook = 0;
218 ofn.lpTemplateName = 0;
220 ofn_result[0] = '\0';
223 void mwi_FindReplace(HWND hWnd)
225 frS.lStructSize = sizeof(FINDREPLACE);
226 frS.hwndOwner = hWnd;
227 frS.hInstance = g_hInstance;
228 frS.Flags = FR_DOWN;
229 frS.lpstrFindWhat = fromstring;
230 frS.lpstrReplaceWith = tostring;
231 frS.wFindWhatLen = sizeof(fromstring);
232 frS.wReplaceWithLen = sizeof(tostring);
233 frS.lCustData = 0;
234 frS.lpfnHook = 0;
235 frS.lpTemplateName = 0;
237 fromstring[0] = '\0';
238 tostring[0] = '\0';
239 findMessageId = RegisterWindowMessage(FINDMSGSTRING);
242 void mwi_InitAll(HWND hWnd)
244 mwi_Print(hWnd);
245 mwi_Font(hWnd);
246 mwi_Color(hWnd);
247 mwi_File(hWnd);
248 mwi_FindReplace(hWnd);
252 * Various configurations for the window. Ideally, this
253 * would be stored with the window itself, but then, this
254 * isn't the brightest of apps. Wouldn't be hard to set up,
255 * though -- one of the neater functions of Windows, but if
256 * someone decides to load the windows themselves from resources,
257 * there might be a problem.
260 void paintMainWindow(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
262 PAINTSTRUCT ps;
263 RECT rect;
264 HPEN pen;
265 HFONT font;
266 HBRUSH brush;
268 (void) iMessage;
269 (void) wParam;
270 (void) lParam;
272 /* Commence painting! */
274 BeginPaint(hWnd, &ps);
275 GetClientRect(hWnd, (LPRECT) &rect);
277 pen = (HPEN) SelectObject(ps.hdc, CreatePen(0, 0, fgColor));
278 brush = (HBRUSH) SelectObject(ps.hdc, CreateSolidBrush(bgColor));
279 font = (HFONT) SelectObject(ps.hdc, CreateFontIndirect(&cf_lf));
282 * Ideally, we'd only need to draw the exposed bit.
283 * But something in BeginPaint is screwing up the rectangle.
284 * Either that, or Windows is drawing it wrong. AARGH!
285 * Rectangle(ps.hdc, ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right, ps.rcPaint.bottom);
287 Rectangle(ps.hdc, rect.left, rect.top, rect.right, rect.bottom);
289 /* now draw a couple of lines, just for giggles. */
291 MoveToEx(ps.hdc, rect.left, rect.top, (POINT FAR *) 0);
292 LineTo(ps.hdc, rect.right, rect.bottom);
293 MoveToEx(ps.hdc, rect.left, rect.bottom, (POINT FAR *) 0);
294 LineTo(ps.hdc, rect.right, rect.top);
296 /* draw some text */
298 SetTextAlign(ps.hdc, TA_CENTER|TA_BASELINE);
299 SetTextColor(ps.hdc, txtColor);
300 TextOut(ps.hdc, (rect.left+rect.right)/2, (rect.top+rect.bottom)/2, "Common Dialog Test Page", 23);
302 SetTextAlign(ps.hdc, TA_LEFT|TA_TOP);
303 TextOut(ps.hdc, rect.left+10, rect.top+10, ofn_result, strlen(ofn_result));
304 TextOut(ps.hdc, rect.left+10, rect.top-cf_lf.lfHeight+10, ofn_titleresult, strlen(ofn_titleresult));
307 * set the HDC back to the old pen and brush,
308 * and delete the newly created objects.
311 pen = (HPEN) SelectObject(ps.hdc, pen);
312 DeleteObject(pen);
313 brush = (HBRUSH) SelectObject(ps.hdc, brush);
314 DeleteObject(brush);
315 font = (HFONT) SelectObject(ps.hdc, font);
316 DeleteObject(font);
318 EndPaint(hWnd, &ps);
322 * This function simply returns an error indication. Naturally,
323 * I do not (yet) see an elegant method by which one can convert
324 * the CDERR_xxx return values into something resembling usable text;
325 * consult cderr.h to see what was returned.
328 void mw_checkError(HWND hWnd, BOOL explicitcancel)
330 DWORD errval = CommDlgExtendedError();
331 if(errval) {
332 char errbuf[80];
334 sprintf(errbuf, "CommDlgExtendedError(): error code %ld (0x%lx)", errval, errval);
335 MessageBox(hWnd, errbuf, "Error", MB_ICONEXCLAMATION | MB_OK);
337 else {
338 if(explicitcancel) MessageBox(hWnd, "Nope, user canceled it.", "No", MB_OK);
343 * The actual dialog function calls. These merely wrap the Commdlg
344 * calls, and do something (not so) intelligent with the result.
345 * Ideally, the main window would refresh and take into account the
346 * various values specified in the dialog.
349 void mw_ColorSetup(HWND hWnd)
351 if(ChooseColor(&cc)) {
352 RECT rect;
354 GetClientRect(hWnd, (LPRECT) &rect);
355 InvalidateRect(hWnd, (LPRECT) &rect, FALSE);
356 bgColor = cc.rgbResult;
358 else mw_checkError(hWnd, FALSE);
361 void mw_FontSetup(HWND hWnd)
363 if(ChooseFont(&cf)) {
364 RECT rect;
365 GetClientRect(hWnd, (LPRECT) &rect);
366 InvalidateRect(hWnd, (LPRECT) &rect, FALSE);
367 txtColor = cf.rgbColors;
369 else mw_checkError(hWnd, FALSE);
372 void mw_FindSetup(HWND hWnd)
374 if(findDialogBox == 0) {
375 findDialogBox = FindText(&frS);
376 if(findDialogBox==0) mw_checkError(hWnd,TRUE);
380 void mw_ReplaceSetup(HWND hWnd)
382 if(findDialogBox == 0) {
383 findDialogBox = ReplaceText(&frS);
384 if(findDialogBox==0) mw_checkError(hWnd,TRUE);
388 void mw_OpenSetup(HWND hWnd)
390 if(GetOpenFileName(&ofn)) {
391 RECT rect;
392 GetClientRect(hWnd, (LPRECT) &rect);
393 InvalidateRect(hWnd, (LPRECT) &rect, FALSE);
395 else mw_checkError(hWnd,FALSE);
398 void mw_SaveSetup(HWND hWnd)
400 if(GetSaveFileName(&ofn)) {
401 RECT rect;
402 GetClientRect(hWnd, (LPRECT) &rect);
403 InvalidateRect(hWnd, (LPRECT) &rect, FALSE);
405 else mw_checkError(hWnd,FALSE);
409 * Can't find documentation in Borland for this one. Does it
410 * exist at all, or is it merely a subdialog of Print?
413 void mw_PSetupSetup(HWND hWnd)
415 nyi(hWnd);
418 void mw_PrintSetup(HWND hWnd)
420 if(PrintDlg(&pd)) {
422 * the following are suggested in the Borland documentation,
423 * but aren't that useful until WinE starts to actually
424 * function with respect to printing.
427 #if 0
428 Escape(tmp.hDC, STARTDOC, 8, "Test-Doc", NULL);
429 #endif
431 /* Print text and rectangle */
433 #if 0
434 TextOut(tmp.hDC, 50, 50, "Common Dialog Test Page", 23);
436 Rectangle(tmp.hDC, 50, 90, 625, 105);
437 Escape(tmp.hDC, NEWFRAME, 0, NULL, NULL);
438 Escape(tmp.hDC, ENDDOC, 0, NULL, NULL);
439 DeleteDC(tmp.hDC);
440 #endif
441 if (pd.hDevMode != 0)
442 GlobalFree(pd.hDevMode);
443 if (pd.hDevNames != 0)
444 GlobalFree(pd.hDevNames);
446 pd.hDevMode = 0;
447 pd.hDevNames = 0;
449 MessageBox(hWnd, "Success.", "Yes", MB_OK);
451 else mw_checkError(hWnd,TRUE);
455 * Some support functions for the custom dialog box handlers.
456 * In particular, we have to set things properly, and get the flags back.
459 void mwcd_SetFlags(HWND hWnd, struct FlagTableEntry *table, unsigned long flags)
461 int i;
463 for(i=0; table[i].ft_id != IDOK; i++)
465 CheckDlgButton(hWnd, table[i].ft_id,(table[i].ft_bit & flags) ? 1 : 0);
469 unsigned long mwcd_GetFlags(HWND hWnd, struct FlagTableEntry * table)
471 int i;
472 unsigned long l = 0;
474 for(i=0; table[i].ft_id != IDOK; i++)
476 if(IsDlgButtonChecked(hWnd, table[i].ft_id) == 1)
477 l |= table[i].ft_bit;
480 return l;
484 * These functions are the custom dialog box handlers.
485 * The division of labor may be a tad peculiar; in particular,
486 * the flag tables should probably be in the main functions,
487 * not the handlers. I'll fix that later; this works as of right now.
490 BOOL mwcd_Setup(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
491 struct FlagTableEntry * table, unsigned long * flags)
493 (void) lParam;
495 switch(uMsg)
497 case WM_INITDIALOG:
498 /* Set the controls properly. */
500 mwcd_SetFlags(hWnd, table, *flags);
502 return TRUE; /* I would return FALSE if I explicitly called SetFocus(). */
503 /* As usual, Windows is weird. */
505 case WM_COMMAND:
506 switch(wParam) {
507 case IDOK:
508 *flags = mwcd_GetFlags(hWnd, table);
509 EndDialog(hWnd,1);
510 break;
512 case IDCANCEL:
513 EndDialog(hWnd,0);
514 break;
516 case CM_R_HELP:
517 break; /* help? We don't need no steenkin help! */
519 default:
520 break; /* eat the message */
522 return TRUE;
524 default:
525 return FALSE; /* since I don't process this particular message */
529 BOOL CALLBACK mwcd_ColorSetup(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
531 static struct FlagTableEntry flagTable[] = {
532 {I_CC_RGBINIT, CC_RGBINIT},
533 {I_CC_SHOWHELP, CC_SHOWHELP},
534 {I_CC_PREVENTFULLOPEN, CC_PREVENTFULLOPEN},
535 {I_CC_FULLOPEN, CC_FULLOPEN},
536 {I_CC_ENABLETEMPLATEHANDLE, CC_ENABLETEMPLATEHANDLE},
537 {I_CC_ENABLETEMPLATE, CC_ENABLETEMPLATE},
538 {I_CC_ENABLEHOOK, CC_ENABLEHOOK},
539 {IDOK, 0},
542 return mwcd_Setup(hWnd, uMsg, wParam, lParam, flagTable, &cc.Flags);
545 BOOL CALLBACK mwcd_FontSetup(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
547 static struct FlagTableEntry flagTable[] = {
548 {I_CF_APPLY, CF_APPLY},
549 {I_CF_ANSIONLY, CF_ANSIONLY},
550 {I_CF_BOTH, CF_BOTH},
551 {I_CF_TTONLY, CF_TTONLY},
552 {I_CF_EFFECTS, CF_EFFECTS},
553 {I_CF_ENABLEHOOK, CF_ENABLEHOOK},
554 {I_CF_ENABLETEMPLATE, CF_ENABLETEMPLATE},
555 {I_CF_ENABLETEMPLATEHANDLE, CF_ENABLETEMPLATEHANDLE},
556 {I_CF_FIXEDPITCHONLY, CF_FIXEDPITCHONLY},
557 {I_CF_INITTOLOGFONTSTRUCT, CF_INITTOLOGFONTSTRUCT},
558 {I_CF_LIMITSIZE, CF_LIMITSIZE},
559 {I_CF_NOFACESEL, CF_NOFACESEL},
560 {I_CF_USESTYLE, CF_USESTYLE},
561 {I_CF_WYSIWYG, CF_WYSIWYG},
562 {I_CF_SHOWHELP, CF_SHOWHELP},
563 {I_CF_SCREENFONTS, CF_SCREENFONTS},
564 {I_CF_SCALABLEONLY, CF_SCALABLEONLY},
565 {I_CF_PRINTERFONTS, CF_PRINTERFONTS},
566 {I_CF_NOVECTORFONTS, CF_NOVECTORFONTS},
567 {I_CF_NOSTYLESEL, CF_NOSTYLESEL},
568 {I_CF_NOSIZESEL, CF_NOSIZESEL},
569 {I_CF_NOOEMFONTS, CF_NOOEMFONTS},
570 {IDOK, 0},
573 return mwcd_Setup(hWnd, uMsg, wParam, lParam, flagTable, &cf.Flags);
576 BOOL CALLBACK mwcd_FindSetup(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
579 static struct FlagTableEntry flagTable[] = {
580 {I_FR_DIALOGTERM, FR_DIALOGTERM},
581 {I_FR_DOWN, FR_DOWN},
582 {I_FR_ENABLEHOOK, FR_ENABLEHOOK},
583 {I_FR_ENABLETEMPLATE, FR_ENABLETEMPLATE},
584 {I_FR_ENABLETEMPLATEHANDLE, FR_ENABLETEMPLATEHANDLE},
585 {I_FR_FINDNEXT, FR_FINDNEXT},
586 {I_FR_HIDEMATCHCASE, FR_HIDEMATCHCASE},
587 {I_FR_HIDEWHOLEWORD, FR_HIDEWHOLEWORD},
588 {I_FR_HIDEUPDOWN, FR_HIDEUPDOWN},
589 {I_FR_MATCHCASE, FR_MATCHCASE},
590 {I_FR_NOMATCHCASE, FR_NOMATCHCASE},
591 {I_FR_NOUPDOWN, FR_NOUPDOWN},
592 {I_FR_NOWHOLEWORD, FR_NOWHOLEWORD},
593 {I_FR_REPLACE, FR_REPLACE},
594 {I_FR_REPLACEALL, FR_REPLACEALL},
595 {I_FR_SHOWHELP, FR_SHOWHELP},
596 {I_FR_WHOLEWORD, FR_WHOLEWORD},
597 {IDOK, 0},
600 return mwcd_Setup(hWnd, uMsg, wParam, lParam, flagTable, &frS.Flags);
603 BOOL CALLBACK mwcd_PrintSetup(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
605 static struct FlagTableEntry flagTable[] = {
606 {I_PD_ALLPAGES, PD_ALLPAGES},
607 {I_PD_COLLATE, PD_COLLATE},
608 {I_PD_DISABLEPRINTTOFILE, PD_DISABLEPRINTTOFILE},
609 {I_PD_ENABLEPRINTHOOK, PD_ENABLEPRINTHOOK},
610 {I_PD_ENABLEPRINTTEMPLATE, PD_ENABLEPRINTTEMPLATE},
611 {I_PD_ENABLEPRINTTEMPLATEHANDLE, PD_ENABLEPRINTTEMPLATEHANDLE},
612 {I_PD_ENABLESETUPHOOK, PD_ENABLESETUPHOOK},
613 {I_PD_ENABLESETUPTEMPLATE, PD_ENABLESETUPTEMPLATE},
614 {I_PD_ENABLESETUPTEMPLATEHANDLE, PD_ENABLESETUPTEMPLATEHANDLE},
615 {I_PD_HIDEPRINTTOFILE, PD_HIDEPRINTTOFILE},
616 {I_PD_NOPAGENUMS, PD_NOPAGENUMS},
617 {I_PD_NOSELECTION, PD_NOSELECTION},
618 {I_PD_NOWARNING, PD_NOWARNING},
619 {I_PD_PAGENUMS, PD_PAGENUMS},
620 {I_PD_PRINTSETUP, PD_PRINTSETUP},
621 {I_PD_PRINTTOFILE, PD_PRINTTOFILE},
622 {I_PD_RETURNDC, PD_RETURNDC},
623 {I_PD_RETURNDEFAULT, PD_RETURNDEFAULT},
624 {I_PD_RETURNIC, PD_RETURNIC},
625 {I_PD_SELECTION, PD_SELECTION},
626 {I_PD_SHOWHELP, PD_SHOWHELP},
627 {I_PD_USEDEVMODECOPIES, PD_USEDEVMODECOPIES},
628 {IDOK, 0},
631 return mwcd_Setup(hWnd, uMsg, wParam, lParam, flagTable, &pd.Flags);
634 BOOL CALLBACK mwcd_FileSetup(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
636 static struct FlagTableEntry flagTable[] = {
637 {I_OFN_ALLOWMULTISELECT, OFN_ALLOWMULTISELECT},
638 {I_OFN_CREATEPROMPT, OFN_CREATEPROMPT},
639 {I_OFN_ENABLEHOOK, OFN_ENABLEHOOK},
640 {I_OFN_ENABLETEMPLATE, OFN_ENABLETEMPLATE},
641 {I_OFN_ENABLETEMPLATEHANDLE, OFN_ENABLETEMPLATEHANDLE},
642 {I_OFN_EXTENSIONDIFFERENT, OFN_EXTENSIONDIFFERENT},
643 {I_OFN_FILEMUSTEXIST, OFN_FILEMUSTEXIST},
644 {I_OFN_HIDEREADONLY, OFN_HIDEREADONLY},
645 {I_OFN_NOCHANGEDIR, OFN_NOCHANGEDIR},
646 {I_OFN_NOREADONLYRETURN, OFN_NOREADONLYRETURN},
647 {I_OFN_NOTESTFILECREATE, OFN_NOTESTFILECREATE},
648 {I_OFN_NOVALIDATE, OFN_NOVALIDATE},
649 {I_OFN_OVERWRITEPROMPT, OFN_OVERWRITEPROMPT},
650 {I_OFN_PATHMUSTEXIST, OFN_PATHMUSTEXIST},
651 {I_OFN_READONLY, OFN_READONLY},
652 {I_OFN_SHAREAWARE, OFN_SHAREAWARE},
653 {I_OFN_SHOWHELP, OFN_SHOWHELP},
654 {IDOK, 0},
657 return mwcd_Setup(hWnd, uMsg, wParam, lParam, flagTable, &pd.Flags);
660 BOOL CALLBACK mwcd_About(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
662 (void) wParam;
663 (void) lParam;
665 switch(uMsg) {
666 case WM_INITDIALOG: return TRUE; /* let WINDOWS set the focus. */
667 case WM_COMMAND: EndDialog(hWnd, 0); return TRUE; /* it's our OK button. */
668 default: return FALSE; /* it's something else, let Windows worry about it */
673 * These functions call custom dialog boxes (resource-loaded, if I do this right).
674 * Right now they don't do a heck of a lot, but at some future time
675 * they will muck about with the flags (and be loaded from the flags) of
676 * the CommDlg structures initialized by the mwi_xxx() routines.
679 void mwc_ColorSetup(HWND hWnd)
681 int r = DialogBox(g_hInstance, "Color_Flags_Dialog", hWnd, (DLGPROC) mwcd_ColorSetup);
682 if(r < 0) { MessageBox(hWnd, "Failure opening Color_Flags_Dialog box", "Error", MB_ICONASTERISK|MB_OK); }
685 void mwc_FontSetup(HWND hWnd)
687 int r = DialogBox(g_hInstance, "Font_Flags_Dialog", hWnd, (DLGPROC) mwcd_FontSetup);
688 if(r < 0) { MessageBox(hWnd, "Failure opening Font_Flags_Dialog box", "Error", MB_ICONASTERISK|MB_OK); }
691 void mwc_FindReplaceSetup(HWND hWnd)
693 int r = DialogBox(g_hInstance, "Find_Flags_Dialog", hWnd, (DLGPROC) mwcd_FindSetup);
694 if(r < 0) { MessageBox(hWnd, "Failure opening Find_Flags_Dialog box", "Error", MB_ICONASTERISK|MB_OK); }
697 void mwc_PrintSetup(HWND hWnd)
699 int r = DialogBox(g_hInstance, "Print_Flags_Dialog", hWnd, (DLGPROC) mwcd_PrintSetup);
700 if(r < 0) { MessageBox(hWnd, "Failure opening Print_Flags_Dialog box", "Error", MB_ICONASTERISK|MB_OK); }
703 void mwc_FileSetup(HWND hWnd)
705 int r = DialogBox(g_hInstance, "File_Flags_Dialog", hWnd, (DLGPROC) mwcd_PrintSetup);
706 if(r < 0) { MessageBox(hWnd, "Failure opening File_Flags_Dialog box", "Error", MB_ICONASTERISK|MB_OK); }
710 * Main window message dispatcher. Here the messages get chewed up
711 * and spit out. Note the ugly hack for the modeless Find/Replace box;
712 * this looks like it was bolted on with hexhead screws and is now
713 * dangling from Windows like a loose muffler. Sigh.
716 LRESULT CALLBACK EXPORT mainWindowDispatcher(
717 HWND hWnd,
718 UINT uMsg,
719 WPARAM wParam,
720 LPARAM lParam
724 if(uMsg == findMessageId) {
725 FINDREPLACE FAR* lpfr = (FINDREPLACE FAR*) lParam;
726 if(lpfr->Flags & FR_DIALOGTERM) {
727 MessageBox(hWnd, "User closing us down.", "Down", MB_OK);
728 findDialogBox = 0;
730 else if (lpfr->Flags & FR_FINDNEXT) {
731 MessageBox(hWnd, "Finding next occurrence.", "Findnext", MB_OK);
733 else if (lpfr->Flags & FR_REPLACE) {
734 MessageBox(hWnd, "Replacing next occurence.", "Replace", MB_OK);
736 else if (lpfr->Flags & FR_REPLACEALL) {
737 MessageBox(hWnd, "Replacing all occurrences.", "Replace All", MB_OK);
739 else {
740 MessageBox(hWnd, "Eh?", "Eh?", MB_OK);
742 return 1;
744 else switch(uMsg) {
745 case WM_CREATE:
747 * this is always the first message...at least as far as
748 * we are concerned.
750 mwi_InitAll(hWnd);
751 break;
753 case WM_PAINT:
754 /* Well, draw something! */
755 paintMainWindow(hWnd, uMsg, wParam, lParam);
756 break;
758 case WM_DESTROY:
759 /* Uh oh. Eject! Eject! Eject! */
760 PostQuitMessage(0);
761 break;
763 case WM_COMMAND:
764 /* menu or accelerator pressed; do something. */
766 switch(wParam) {
767 case CM_U_EXIT:
768 /* Uh oh. Eject! Eject! Eject! */
769 PostQuitMessage(0);
770 break;
772 /* these actually call the Common Dialogs. */
774 case CM_U_COLOR:
775 mw_ColorSetup(hWnd); return 1;
777 case CM_U_FONT:
778 mw_FontSetup(hWnd); return 1;
780 case CM_U_FIND:
781 mw_FindSetup(hWnd); return 1;
783 case CM_U_REPLACE:
784 mw_ReplaceSetup(hWnd); return 1;
786 case CM_U_OPEN:
787 mw_OpenSetup(hWnd); return 1;
789 case CM_U_SAVE:
790 mw_SaveSetup(hWnd); return 1;
792 case CM_U_PSETUP:
793 mw_PSetupSetup(hWnd); return 1;
795 case CM_U_PRINT:
796 mw_PrintSetup(hWnd); return 1;
799 * these set up various flags and values in the Common Dialog
800 * data structures, which are currently stored in static memory.
801 * The control dialogs themselves are resources as well.
804 case CM_F_FILE:
805 mwc_FileSetup(hWnd); return 1;
807 case CM_F_COLOR:
808 mwc_ColorSetup(hWnd); return 1;
810 case CM_F_FONT:
811 mwc_FontSetup(hWnd); return 1;
813 case CM_F_FINDREPLACE:
814 mwc_FindReplaceSetup(hWnd); return 1;
816 case CM_F_PRINT:
817 mwc_PrintSetup(hWnd); return 1;
819 case CM_H_ABOUT:
820 DialogBox(g_hInstance, "AboutDialog", hWnd, (DLGPROC) mwcd_About);
821 return 1;
822 case CM_H_USAGE:
823 DialogBox(g_hInstance, "UsageDialog", hWnd, (DLGPROC) mwcd_About);
824 /* return value? *What* return value? */
825 return 1;
827 default:
828 nyi(hWnd); return 1;
830 break;
832 default:
833 return DefWindowProc(hWnd, uMsg, wParam, lParam);
835 return 0;
838 /* Class registration. One might call this a Windowsism. */
840 int registerMainWindowClass(HINSTANCE hInstance)
842 WNDCLASS wndClass;
844 wndClass.style = CS_HREDRAW|CS_VREDRAW;
845 wndClass.lpfnWndProc = mainWindowDispatcher;
846 wndClass.cbClsExtra = 0;
847 wndClass.cbWndExtra = 0;
848 wndClass.hInstance = hInstance;
849 #if 0
850 wndClass.hIcon = LoadIcon(hInstance, "whello");
851 wndClass.hCursor = LoadCursor(hInstance, IDC_ARROW);
852 #endif
853 wndClass.hIcon = 0;
854 wndClass.hCursor = 0;
855 wndClass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
856 wndClass.lpszMenuName = menuName;
857 wndClass.lpszClassName = className;
859 return RegisterClass(&wndClass);
863 * Another Windowsism; this one's not too bad, as it compares
864 * favorably with CreateWindow() in X (mucking about with X Visuals
865 * can get messy; at least here we don't have to worry about that).
868 HWND createMainWindow(HINSTANCE hInstance, int show)
870 HWND hWnd;
872 hWnd = CreateWindow(
873 className, /* classname */
874 windowName, /* windowname/title */
875 WS_OVERLAPPEDWINDOW, /* dwStyle */
876 0, /* x */
877 0, /* y */
878 CW_USEDEFAULT, /* width */
879 CW_USEDEFAULT, /* height */
880 0, /* parent window */
881 0, /* menu */
882 hInstance, /* instance */
883 0 /* passthrough for MDI */
886 if(hWnd==0) return 0;
888 ShowWindow(hWnd, show);
889 UpdateWindow(hWnd);
891 return hWnd;
894 int messageLoop(HINSTANCE hInstance, HWND hWnd)
896 MSG msg;
898 (void) hInstance;
899 (void) hWnd;
901 while(GetMessage(&msg, 0, 0, 0)) {
902 TranslateMessage(&msg);
903 DispatchMessage(&msg);
906 return msg.wParam;
910 * Oh, did we tell you that main() isn't the name of the
911 * thing called in a Win16/Win32 app? And then there are
912 * the lack of argument lists, the necessity (at least in Win16)
913 * of having to deal with class registration exactly once (as the
914 * app may be run again), and some other bizarre holdovers from
915 * Windows 3.x days. But hey, Solitaire still works.
918 int PASCAL WinMain(
919 HINSTANCE hInstance, HINSTANCE hPrevInstance,
920 LPSTR lpszCmdLine, int nCmdShow
923 HWND hWnd;
925 (void) lpszCmdLine;
927 strcpy(ofn_result, "--- not yet set ---");
929 if(hPrevInstance==0) {
930 if(!registerMainWindowClass(hInstance))
931 return -1;
934 g_hInstance = hInstance;
936 hWnd = createMainWindow(hInstance,nCmdShow);
937 if(hWnd == 0)
938 return -1;
940 return messageLoop(hInstance, hWnd);
943 /* And now the end of the program. Enjoy. */
946 * (c) 1999-2000 Eric Williams. Rights as specified under the WINE
947 * License. Don't hoard code; share it!