Fixes for -Wmissing-declarations and -Wwrite-strings warnings.
[wine/wine64.git] / programs / cmdlgtst / cmdlgtst.c
blobe37ac03a789b2ef12afe28ccdf7900086a1ef7f0
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 #define EXPORT
61 static const char menuName[] = "CmdlgtstMenu";
62 static const char className[] = "CmdlgtstClass";
63 static const char windowName[] = "Cmdlgtst Window";
66 * global hInstance variable. This makes the code non-threadable,
67 * but wotthehell; this is Win32 anyway! (Though it does work
68 * under Win16, if one doesn't run more than one copy at a time.)
71 static HINSTANCE g_hInstance;
74 * global CommDlg data structures for modals. These are placed here
75 * so that the custom dialog boxes can get at them.
78 static PRINTDLG pd;
79 static COLORREF cc_cr[16];
80 static CHOOSECOLOR cc;
81 static LOGFONT cf_lf;
82 static CHOOSEFONT cf;
83 static const char ofn_filepat[] = "All Files (*.*)\0*.*\0Only Text Files (*.txt)\0*.txt\0";
84 static char ofn_result[1024];
85 static char ofn_titleresult[128];
86 static OPENFILENAME ofn;
88 /* Stuff for find and replace. These are modeless, so I have to put them here. */
90 static HWND findDialogBox = 0;
91 static UINT findMessageId = 0;
93 static FINDREPLACE frS;
94 static char fromstring[1024], tostring[1024];
96 /* Stuff for the drawing of the window(s). I put them here for convenience. */
98 static COLORREF fgColor = RGB(0, 0, 0); /* not settable */
99 static COLORREF bgColor = RGB(255, 255, 255); /* COLOR dialog */
100 static COLORREF txtColor = RGB(0, 0, 0); /* settable if one enables CF_EFFECTS */
102 /* Utility routines. */
104 static void nyi(HWND hWnd)
106 /* "Hi there! I'm not yet implemented!" */
107 MessageBox(hWnd, "Not yet implemented!", "NYI", MB_ICONEXCLAMATION | MB_OK);
110 #if 0
111 static UINT CALLBACK dummyfnHook(HWND hWnd, UINT msg, UINT wParam, UINT lParam)
114 * If the user specifies something that needs an awfully stupid hook function,
115 * this is the one to use. It's a no-op, and says "I didn't do anything."
118 (void) hWnd;
119 (void) msg;
120 (void) wParam;
121 (void) lParam;
123 printf("dummyfnhook\n"); /* visible under Wine, but Windows probably won't see it! */
125 return 0;
127 #endif
130 * Initialization code. This code simply shoves in predefined
131 * data into the COMMDLG data structures; in the future, I might use
132 * a series of loadable resources, or static initializers; of course,
133 * if Microsoft decides to change the field ordering, I'd be screwed.
136 static void mwi_Print(HWND hWnd)
138 pd.lStructSize = sizeof(PRINTDLG);
139 pd.hwndOwner = hWnd;
140 pd.hDevMode = 0;
141 pd.hDevNames = 0;
142 pd.hDC = 0;
143 pd.Flags = 0;
144 pd.nMinPage = 1;
145 pd.nMaxPage = 100;
146 pd.hInstance = g_hInstance;
147 pd.lCustData = 0;
148 pd.lpfnPrintHook = 0;
149 pd.lpfnSetupHook = 0;
150 pd.lpPrintTemplateName = 0;
151 pd.lpSetupTemplateName = 0;
152 pd.hPrintTemplate = 0;
153 pd.hSetupTemplate = 0;
156 static void mwi_Color(HWND hWnd)
158 int i;
160 /* there's probably an init call for this, somewhere. */
162 for(i=0;i<16;i++)
163 cc_cr[i] = RGB(0,0,0);
165 cc.lStructSize = sizeof(CHOOSECOLOR);
166 cc.hwndOwner = hWnd;
167 cc.hInstance = (HWND)g_hInstance; /* Should be an HINSTANCE but MS made a typo */
168 cc.rgbResult = RGB(0,0,0);
169 cc.lpCustColors = cc_cr;
170 cc.Flags = 0;
171 cc.lCustData = 0;
172 cc.lpfnHook = 0;
173 cc.lpTemplateName = 0;
176 static void mwi_Font(HWND hWnd)
178 cf.lStructSize = sizeof(CHOOSEFONT);
179 cf.hwndOwner = hWnd;
180 cf.hDC = 0;
181 cf.lpLogFont = &cf_lf;
182 cf.Flags = CF_SCREENFONTS; /* something's needed for display; otherwise it craps out with an error */
183 cf.rgbColors = RGB(0,0,0); /* what is *this* doing here?? */
184 cf.lCustData = 0;
185 cf.lpfnHook = 0;
186 cf.lpTemplateName = 0;
187 cf.hInstance = g_hInstance;
188 cf.lpszStyle = 0;
189 cf.nFontType = 0;
190 cf.nSizeMin = 8;
191 cf.nSizeMax = 72;
193 cf_lf.lfHeight = -18; /* this can be positive or negative, but negative is usually used. */
196 static void mwi_File(HWND hWnd)
198 ofn.lStructSize = sizeof(OPENFILENAME);
199 ofn.hwndOwner = hWnd;
200 ofn.hInstance = g_hInstance;
201 ofn.lpstrFilter = ofn_filepat;
202 ofn.lpstrCustomFilter = 0;
203 ofn.nMaxCustFilter = 0;
204 ofn.nFilterIndex = 0;
205 ofn.lpstrFile = ofn_result;
206 ofn.nMaxFile = sizeof(ofn_result);
207 ofn.lpstrFileTitle = ofn_titleresult;
208 ofn.nMaxFileTitle = sizeof(ofn_titleresult);
209 ofn.lpstrInitialDir = 0;
210 ofn.lpstrTitle = "Open File";
211 ofn.Flags = 0;
212 ofn.nFileOffset = 0;
213 ofn.nFileExtension = 0;
214 ofn.lpstrDefExt = "*";
215 ofn.lCustData = 0;
216 ofn.lpfnHook = 0;
217 ofn.lpTemplateName = 0;
219 ofn_result[0] = '\0';
222 static void mwi_FindReplace(HWND hWnd)
224 frS.lStructSize = sizeof(FINDREPLACE);
225 frS.hwndOwner = hWnd;
226 frS.hInstance = g_hInstance;
227 frS.Flags = FR_DOWN;
228 frS.lpstrFindWhat = fromstring;
229 frS.lpstrReplaceWith = tostring;
230 frS.wFindWhatLen = sizeof(fromstring);
231 frS.wReplaceWithLen = sizeof(tostring);
232 frS.lCustData = 0;
233 frS.lpfnHook = 0;
234 frS.lpTemplateName = 0;
236 fromstring[0] = '\0';
237 tostring[0] = '\0';
238 findMessageId = RegisterWindowMessage(FINDMSGSTRING);
241 static void mwi_InitAll(HWND hWnd)
243 mwi_Print(hWnd);
244 mwi_Font(hWnd);
245 mwi_Color(hWnd);
246 mwi_File(hWnd);
247 mwi_FindReplace(hWnd);
251 * Various configurations for the window. Ideally, this
252 * would be stored with the window itself, but then, this
253 * isn't the brightest of apps. Wouldn't be hard to set up,
254 * though -- one of the neater functions of Windows, but if
255 * someone decides to load the windows themselves from resources,
256 * there might be a problem.
259 static void paintMainWindow(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
261 PAINTSTRUCT ps;
262 RECT rect;
263 HPEN pen;
264 HFONT font;
265 HBRUSH brush;
267 (void) iMessage;
268 (void) wParam;
269 (void) lParam;
271 /* Commence painting! */
273 BeginPaint(hWnd, &ps);
274 GetClientRect(hWnd, (LPRECT) &rect);
276 pen = (HPEN) SelectObject(ps.hdc, CreatePen(0, 0, fgColor));
277 brush = (HBRUSH) SelectObject(ps.hdc, CreateSolidBrush(bgColor));
278 font = (HFONT) SelectObject(ps.hdc, CreateFontIndirect(&cf_lf));
281 * Ideally, we'd only need to draw the exposed bit.
282 * But something in BeginPaint is screwing up the rectangle.
283 * Either that, or Windows is drawing it wrong. AARGH!
284 * Rectangle(ps.hdc, ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right, ps.rcPaint.bottom);
286 Rectangle(ps.hdc, rect.left, rect.top, rect.right, rect.bottom);
288 /* now draw a couple of lines, just for giggles. */
290 MoveToEx(ps.hdc, rect.left, rect.top, (POINT *) 0);
291 LineTo(ps.hdc, rect.right, rect.bottom);
292 MoveToEx(ps.hdc, rect.left, rect.bottom, (POINT *) 0);
293 LineTo(ps.hdc, rect.right, rect.top);
295 /* draw some text */
297 SetTextAlign(ps.hdc, TA_CENTER|TA_BASELINE);
298 SetTextColor(ps.hdc, txtColor);
299 TextOut(ps.hdc, (rect.left+rect.right)/2, (rect.top+rect.bottom)/2, "Common Dialog Test Page", 23);
301 SetTextAlign(ps.hdc, TA_LEFT|TA_TOP);
302 TextOut(ps.hdc, rect.left+10, rect.top+10, ofn_result, strlen(ofn_result));
303 TextOut(ps.hdc, rect.left+10, rect.top-cf_lf.lfHeight+10, ofn_titleresult, strlen(ofn_titleresult));
306 * set the HDC back to the old pen and brush,
307 * and delete the newly created objects.
310 pen = (HPEN) SelectObject(ps.hdc, pen);
311 DeleteObject(pen);
312 brush = (HBRUSH) SelectObject(ps.hdc, brush);
313 DeleteObject(brush);
314 font = (HFONT) SelectObject(ps.hdc, font);
315 DeleteObject(font);
317 EndPaint(hWnd, &ps);
321 * This function simply returns an error indication. Naturally,
322 * I do not (yet) see an elegant method by which one can convert
323 * the CDERR_xxx return values into something resembling usable text;
324 * consult cderr.h to see what was returned.
327 static void mw_checkError(HWND hWnd, BOOL explicitcancel)
329 DWORD errval = CommDlgExtendedError();
330 if(errval) {
331 char errbuf[80];
333 sprintf(errbuf, "CommDlgExtendedError(): error code %ld (0x%lx)", errval, errval);
334 MessageBox(hWnd, errbuf, "Error", MB_ICONEXCLAMATION | MB_OK);
336 else {
337 if(explicitcancel) MessageBox(hWnd, "Nope, user canceled it.", "No", MB_OK);
342 * The actual dialog function calls. These merely wrap the Commdlg
343 * calls, and do something (not so) intelligent with the result.
344 * Ideally, the main window would refresh and take into account the
345 * various values specified in the dialog.
348 static void mw_ColorSetup(HWND hWnd)
350 if(ChooseColor(&cc)) {
351 RECT rect;
353 GetClientRect(hWnd, (LPRECT) &rect);
354 InvalidateRect(hWnd, (LPRECT) &rect, FALSE);
355 bgColor = cc.rgbResult;
357 else mw_checkError(hWnd, FALSE);
360 static void mw_FontSetup(HWND hWnd)
362 if(ChooseFont(&cf)) {
363 RECT rect;
364 GetClientRect(hWnd, (LPRECT) &rect);
365 InvalidateRect(hWnd, (LPRECT) &rect, FALSE);
366 txtColor = cf.rgbColors;
368 else mw_checkError(hWnd, FALSE);
371 static void mw_FindSetup(HWND hWnd)
373 if(findDialogBox == 0) {
374 findDialogBox = FindText(&frS);
375 if(findDialogBox==0) mw_checkError(hWnd,TRUE);
379 static void mw_ReplaceSetup(HWND hWnd)
381 if(findDialogBox == 0) {
382 findDialogBox = ReplaceText(&frS);
383 if(findDialogBox==0) mw_checkError(hWnd,TRUE);
387 static void mw_OpenSetup(HWND hWnd)
389 if(GetOpenFileName(&ofn)) {
390 RECT rect;
391 GetClientRect(hWnd, (LPRECT) &rect);
392 InvalidateRect(hWnd, (LPRECT) &rect, FALSE);
394 else mw_checkError(hWnd,FALSE);
397 static void mw_SaveSetup(HWND hWnd)
399 if(GetSaveFileName(&ofn)) {
400 RECT rect;
401 GetClientRect(hWnd, (LPRECT) &rect);
402 InvalidateRect(hWnd, (LPRECT) &rect, FALSE);
404 else mw_checkError(hWnd,FALSE);
408 * Can't find documentation in Borland for this one. Does it
409 * exist at all, or is it merely a subdialog of Print?
412 static void mw_PSetupSetup(HWND hWnd)
414 nyi(hWnd);
417 static void mw_PrintSetup(HWND hWnd)
419 if(PrintDlg(&pd)) {
421 * the following are suggested in the Borland documentation,
422 * but aren't that useful until WinE starts to actually
423 * function with respect to printing.
426 #if 0
427 Escape(tmp.hDC, STARTDOC, 8, "Test-Doc", NULL);
428 #endif
430 /* Print text and rectangle */
432 #if 0
433 TextOut(tmp.hDC, 50, 50, "Common Dialog Test Page", 23);
435 Rectangle(tmp.hDC, 50, 90, 625, 105);
436 Escape(tmp.hDC, NEWFRAME, 0, NULL, NULL);
437 Escape(tmp.hDC, ENDDOC, 0, NULL, NULL);
438 DeleteDC(tmp.hDC);
439 #endif
440 if (pd.hDevMode != 0)
441 GlobalFree(pd.hDevMode);
442 if (pd.hDevNames != 0)
443 GlobalFree(pd.hDevNames);
445 pd.hDevMode = 0;
446 pd.hDevNames = 0;
448 MessageBox(hWnd, "Success.", "Yes", MB_OK);
450 else mw_checkError(hWnd,TRUE);
454 * Some support functions for the custom dialog box handlers.
455 * In particular, we have to set things properly, and get the flags back.
458 static void mwcd_SetFlags(HWND hWnd, struct FlagTableEntry *table, unsigned long flags)
460 int i;
462 for(i=0; table[i].ft_id != IDOK; i++)
464 CheckDlgButton(hWnd, table[i].ft_id,(table[i].ft_bit & flags) ? 1 : 0);
468 static unsigned long mwcd_GetFlags(HWND hWnd, struct FlagTableEntry * table)
470 int i;
471 unsigned long l = 0;
473 for(i=0; table[i].ft_id != IDOK; i++)
475 if(IsDlgButtonChecked(hWnd, table[i].ft_id) == 1)
476 l |= table[i].ft_bit;
479 return l;
483 * These functions are the custom dialog box handlers.
484 * The division of labor may be a tad peculiar; in particular,
485 * the flag tables should probably be in the main functions,
486 * not the handlers. I'll fix that later; this works as of right now.
489 static BOOL mwcd_Setup(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
490 struct FlagTableEntry * table, unsigned long * flags)
492 (void) lParam;
494 switch(uMsg)
496 case WM_INITDIALOG:
497 /* Set the controls properly. */
499 mwcd_SetFlags(hWnd, table, *flags);
501 return TRUE; /* I would return FALSE if I explicitly called SetFocus(). */
502 /* As usual, Windows is weird. */
504 case WM_COMMAND:
505 switch(wParam) {
506 case IDOK:
507 *flags = mwcd_GetFlags(hWnd, table);
508 EndDialog(hWnd,1);
509 break;
511 case IDCANCEL:
512 EndDialog(hWnd,0);
513 break;
515 case CM_R_HELP:
516 break; /* help? We don't need no steenkin help! */
518 default:
519 break; /* eat the message */
521 return TRUE;
523 default:
524 return FALSE; /* since I don't process this particular message */
528 static BOOL CALLBACK mwcd_ColorSetup(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
530 static struct FlagTableEntry flagTable[] = {
531 {I_CC_RGBINIT, CC_RGBINIT},
532 {I_CC_SHOWHELP, CC_SHOWHELP},
533 {I_CC_PREVENTFULLOPEN, CC_PREVENTFULLOPEN},
534 {I_CC_FULLOPEN, CC_FULLOPEN},
535 {I_CC_ENABLETEMPLATEHANDLE, CC_ENABLETEMPLATEHANDLE},
536 {I_CC_ENABLETEMPLATE, CC_ENABLETEMPLATE},
537 {I_CC_ENABLEHOOK, CC_ENABLEHOOK},
538 {IDOK, 0},
541 return mwcd_Setup(hWnd, uMsg, wParam, lParam, flagTable, &cc.Flags);
544 static BOOL CALLBACK mwcd_FontSetup(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
546 static struct FlagTableEntry flagTable[] = {
547 {I_CF_APPLY, CF_APPLY},
548 {I_CF_ANSIONLY, CF_ANSIONLY},
549 {I_CF_BOTH, CF_BOTH},
550 {I_CF_TTONLY, CF_TTONLY},
551 {I_CF_EFFECTS, CF_EFFECTS},
552 {I_CF_ENABLEHOOK, CF_ENABLEHOOK},
553 {I_CF_ENABLETEMPLATE, CF_ENABLETEMPLATE},
554 {I_CF_ENABLETEMPLATEHANDLE, CF_ENABLETEMPLATEHANDLE},
555 {I_CF_FIXEDPITCHONLY, CF_FIXEDPITCHONLY},
556 {I_CF_INITTOLOGFONTSTRUCT, CF_INITTOLOGFONTSTRUCT},
557 {I_CF_LIMITSIZE, CF_LIMITSIZE},
558 {I_CF_NOFACESEL, CF_NOFACESEL},
559 {I_CF_USESTYLE, CF_USESTYLE},
560 {I_CF_WYSIWYG, CF_WYSIWYG},
561 {I_CF_SHOWHELP, CF_SHOWHELP},
562 {I_CF_SCREENFONTS, CF_SCREENFONTS},
563 {I_CF_SCALABLEONLY, CF_SCALABLEONLY},
564 {I_CF_PRINTERFONTS, CF_PRINTERFONTS},
565 {I_CF_NOVECTORFONTS, CF_NOVECTORFONTS},
566 {I_CF_NOSTYLESEL, CF_NOSTYLESEL},
567 {I_CF_NOSIZESEL, CF_NOSIZESEL},
568 {I_CF_NOOEMFONTS, CF_NOOEMFONTS},
569 {IDOK, 0},
572 return mwcd_Setup(hWnd, uMsg, wParam, lParam, flagTable, &cf.Flags);
575 static BOOL CALLBACK mwcd_FindSetup(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
578 static struct FlagTableEntry flagTable[] = {
579 {I_FR_DIALOGTERM, FR_DIALOGTERM},
580 {I_FR_DOWN, FR_DOWN},
581 {I_FR_ENABLEHOOK, FR_ENABLEHOOK},
582 {I_FR_ENABLETEMPLATE, FR_ENABLETEMPLATE},
583 {I_FR_ENABLETEMPLATEHANDLE, FR_ENABLETEMPLATEHANDLE},
584 {I_FR_FINDNEXT, FR_FINDNEXT},
585 {I_FR_HIDEMATCHCASE, FR_HIDEMATCHCASE},
586 {I_FR_HIDEWHOLEWORD, FR_HIDEWHOLEWORD},
587 {I_FR_HIDEUPDOWN, FR_HIDEUPDOWN},
588 {I_FR_MATCHCASE, FR_MATCHCASE},
589 {I_FR_NOMATCHCASE, FR_NOMATCHCASE},
590 {I_FR_NOUPDOWN, FR_NOUPDOWN},
591 {I_FR_NOWHOLEWORD, FR_NOWHOLEWORD},
592 {I_FR_REPLACE, FR_REPLACE},
593 {I_FR_REPLACEALL, FR_REPLACEALL},
594 {I_FR_SHOWHELP, FR_SHOWHELP},
595 {I_FR_WHOLEWORD, FR_WHOLEWORD},
596 {IDOK, 0},
599 return mwcd_Setup(hWnd, uMsg, wParam, lParam, flagTable, &frS.Flags);
602 static BOOL CALLBACK mwcd_PrintSetup(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
604 static struct FlagTableEntry flagTable[] = {
605 {I_PD_ALLPAGES, PD_ALLPAGES},
606 {I_PD_COLLATE, PD_COLLATE},
607 {I_PD_DISABLEPRINTTOFILE, PD_DISABLEPRINTTOFILE},
608 {I_PD_ENABLEPRINTHOOK, PD_ENABLEPRINTHOOK},
609 {I_PD_ENABLEPRINTTEMPLATE, PD_ENABLEPRINTTEMPLATE},
610 {I_PD_ENABLEPRINTTEMPLATEHANDLE, PD_ENABLEPRINTTEMPLATEHANDLE},
611 {I_PD_ENABLESETUPHOOK, PD_ENABLESETUPHOOK},
612 {I_PD_ENABLESETUPTEMPLATE, PD_ENABLESETUPTEMPLATE},
613 {I_PD_ENABLESETUPTEMPLATEHANDLE, PD_ENABLESETUPTEMPLATEHANDLE},
614 {I_PD_HIDEPRINTTOFILE, PD_HIDEPRINTTOFILE},
615 {I_PD_NOPAGENUMS, PD_NOPAGENUMS},
616 {I_PD_NOSELECTION, PD_NOSELECTION},
617 {I_PD_NOWARNING, PD_NOWARNING},
618 {I_PD_PAGENUMS, PD_PAGENUMS},
619 {I_PD_PRINTSETUP, PD_PRINTSETUP},
620 {I_PD_PRINTTOFILE, PD_PRINTTOFILE},
621 {I_PD_RETURNDC, PD_RETURNDC},
622 {I_PD_RETURNDEFAULT, PD_RETURNDEFAULT},
623 {I_PD_RETURNIC, PD_RETURNIC},
624 {I_PD_SELECTION, PD_SELECTION},
625 {I_PD_SHOWHELP, PD_SHOWHELP},
626 {I_PD_USEDEVMODECOPIES, PD_USEDEVMODECOPIES},
627 {IDOK, 0},
630 return mwcd_Setup(hWnd, uMsg, wParam, lParam, flagTable, &pd.Flags);
633 static BOOL CALLBACK mwcd_FileSetup(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
635 static struct FlagTableEntry flagTable[] = {
636 {I_OFN_ALLOWMULTISELECT, OFN_ALLOWMULTISELECT},
637 {I_OFN_CREATEPROMPT, OFN_CREATEPROMPT},
638 {I_OFN_ENABLEHOOK, OFN_ENABLEHOOK},
639 {I_OFN_ENABLETEMPLATE, OFN_ENABLETEMPLATE},
640 {I_OFN_ENABLETEMPLATEHANDLE, OFN_ENABLETEMPLATEHANDLE},
641 {I_OFN_EXTENSIONDIFFERENT, OFN_EXTENSIONDIFFERENT},
642 {I_OFN_FILEMUSTEXIST, OFN_FILEMUSTEXIST},
643 {I_OFN_HIDEREADONLY, OFN_HIDEREADONLY},
644 {I_OFN_NOCHANGEDIR, OFN_NOCHANGEDIR},
645 {I_OFN_NOREADONLYRETURN, OFN_NOREADONLYRETURN},
646 {I_OFN_NOTESTFILECREATE, OFN_NOTESTFILECREATE},
647 {I_OFN_NOVALIDATE, OFN_NOVALIDATE},
648 {I_OFN_OVERWRITEPROMPT, OFN_OVERWRITEPROMPT},
649 {I_OFN_PATHMUSTEXIST, OFN_PATHMUSTEXIST},
650 {I_OFN_READONLY, OFN_READONLY},
651 {I_OFN_SHAREAWARE, OFN_SHAREAWARE},
652 {I_OFN_SHOWHELP, OFN_SHOWHELP},
653 {IDOK, 0},
656 return mwcd_Setup(hWnd, uMsg, wParam, lParam, flagTable, &ofn.Flags);
659 static BOOL CALLBACK mwcd_About(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
661 (void) wParam;
662 (void) lParam;
664 switch(uMsg) {
665 case WM_INITDIALOG: return TRUE; /* let WINDOWS set the focus. */
666 case WM_COMMAND: EndDialog(hWnd, 0); return TRUE; /* it's our OK button. */
667 default: return FALSE; /* it's something else, let Windows worry about it */
672 * These functions call custom dialog boxes (resource-loaded, if I do this right).
673 * Right now they don't do a heck of a lot, but at some future time
674 * they will muck about with the flags (and be loaded from the flags) of
675 * the CommDlg structures initialized by the mwi_xxx() routines.
678 static void mwc_ColorSetup(HWND hWnd)
680 int r = DialogBox(g_hInstance, "Color_Flags_Dialog", hWnd, (DLGPROC) mwcd_ColorSetup);
681 if(r < 0) { MessageBox(hWnd, "Failure opening Color_Flags_Dialog box", "Error", MB_ICONASTERISK|MB_OK); }
684 static void mwc_FontSetup(HWND hWnd)
686 int r = DialogBox(g_hInstance, "Font_Flags_Dialog", hWnd, (DLGPROC) mwcd_FontSetup);
687 if(r < 0) { MessageBox(hWnd, "Failure opening Font_Flags_Dialog box", "Error", MB_ICONASTERISK|MB_OK); }
690 static void mwc_FindReplaceSetup(HWND hWnd)
692 int r = DialogBox(g_hInstance, "Find_Flags_Dialog", hWnd, (DLGPROC) mwcd_FindSetup);
693 if(r < 0) { MessageBox(hWnd, "Failure opening Find_Flags_Dialog box", "Error", MB_ICONASTERISK|MB_OK); }
696 static void mwc_PrintSetup(HWND hWnd)
698 int r = DialogBox(g_hInstance, "Print_Flags_Dialog", hWnd, (DLGPROC) mwcd_PrintSetup);
699 if(r < 0) { MessageBox(hWnd, "Failure opening Print_Flags_Dialog box", "Error", MB_ICONASTERISK|MB_OK); }
702 static void mwc_FileSetup(HWND hWnd)
704 int r = DialogBox(g_hInstance, "File_Flags_Dialog", hWnd, (DLGPROC) mwcd_FileSetup);
705 if(r < 0) { MessageBox(hWnd, "Failure opening File_Flags_Dialog box", "Error", MB_ICONASTERISK|MB_OK); }
709 * Main window message dispatcher. Here the messages get chewed up
710 * and spit out. Note the ugly hack for the modeless Find/Replace box;
711 * this looks like it was bolted on with hexhead screws and is now
712 * dangling from Windows like a loose muffler. Sigh.
715 static LRESULT CALLBACK EXPORT mainWindowDispatcher(
716 HWND hWnd,
717 UINT uMsg,
718 WPARAM wParam,
719 LPARAM lParam
723 if(uMsg == findMessageId) {
724 FINDREPLACE * lpfr = (FINDREPLACE *) lParam;
725 if(lpfr->Flags & FR_DIALOGTERM) {
726 MessageBox(hWnd, "User closing us down.", "Down", MB_OK);
727 findDialogBox = 0;
729 else if (lpfr->Flags & FR_FINDNEXT) {
730 MessageBox(hWnd, "Finding next occurrence.", "Findnext", MB_OK);
732 else if (lpfr->Flags & FR_REPLACE) {
733 MessageBox(hWnd, "Replacing next occurrence.", "Replace", MB_OK);
735 else if (lpfr->Flags & FR_REPLACEALL) {
736 MessageBox(hWnd, "Replacing all occurrences.", "Replace All", MB_OK);
738 else {
739 MessageBox(hWnd, "Eh?", "Eh?", MB_OK);
741 return 1;
743 else switch(uMsg) {
744 case WM_CREATE:
746 * this is always the first message...at least as far as
747 * we are concerned.
749 mwi_InitAll(hWnd);
750 break;
752 case WM_PAINT:
753 /* Well, draw something! */
754 paintMainWindow(hWnd, uMsg, wParam, lParam);
755 break;
757 case WM_DESTROY:
758 /* Uh oh. Eject! Eject! Eject! */
759 PostQuitMessage(0);
760 break;
762 case WM_COMMAND:
763 /* menu or accelerator pressed; do something. */
765 switch(wParam) {
766 case CM_U_EXIT:
767 /* Uh oh. Eject! Eject! Eject! */
768 PostQuitMessage(0);
769 break;
771 /* these actually call the Common Dialogs. */
773 case CM_U_COLOR:
774 mw_ColorSetup(hWnd); return 1;
776 case CM_U_FONT:
777 mw_FontSetup(hWnd); return 1;
779 case CM_U_FIND:
780 mw_FindSetup(hWnd); return 1;
782 case CM_U_REPLACE:
783 mw_ReplaceSetup(hWnd); return 1;
785 case CM_U_OPEN:
786 mw_OpenSetup(hWnd); return 1;
788 case CM_U_SAVE:
789 mw_SaveSetup(hWnd); return 1;
791 case CM_U_PSETUP:
792 mw_PSetupSetup(hWnd); return 1;
794 case CM_U_PRINT:
795 mw_PrintSetup(hWnd); return 1;
798 * these set up various flags and values in the Common Dialog
799 * data structures, which are currently stored in static memory.
800 * The control dialogs themselves are resources as well.
803 case CM_F_FILE:
804 mwc_FileSetup(hWnd); return 1;
806 case CM_F_COLOR:
807 mwc_ColorSetup(hWnd); return 1;
809 case CM_F_FONT:
810 mwc_FontSetup(hWnd); return 1;
812 case CM_F_FINDREPLACE:
813 mwc_FindReplaceSetup(hWnd); return 1;
815 case CM_F_PRINT:
816 mwc_PrintSetup(hWnd); return 1;
818 case CM_H_ABOUT:
819 DialogBox(g_hInstance, "AboutDialog", hWnd, (DLGPROC) mwcd_About);
820 return 1;
821 case CM_H_USAGE:
822 DialogBox(g_hInstance, "UsageDialog", hWnd, (DLGPROC) mwcd_About);
823 /* return value? *What* return value? */
824 return 1;
826 default:
827 nyi(hWnd); return 1;
829 break;
831 default:
832 return DefWindowProc(hWnd, uMsg, wParam, lParam);
834 return 0;
837 /* Class registration. One might call this a Windowsism. */
839 static int registerMainWindowClass(HINSTANCE hInstance)
841 WNDCLASS wndClass;
843 wndClass.style = CS_HREDRAW|CS_VREDRAW;
844 wndClass.lpfnWndProc = mainWindowDispatcher;
845 wndClass.cbClsExtra = 0;
846 wndClass.cbWndExtra = 0;
847 wndClass.hInstance = hInstance;
848 #if 0
849 wndClass.hIcon = LoadIcon(hInstance, "whello");
850 wndClass.hCursor = LoadCursor(hInstance, IDC_ARROW);
851 #endif
852 wndClass.hIcon = 0;
853 wndClass.hCursor = 0;
854 wndClass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
855 wndClass.lpszMenuName = menuName;
856 wndClass.lpszClassName = className;
858 return RegisterClass(&wndClass);
862 * Another Windowsism; this one's not too bad, as it compares
863 * favorably with CreateWindow() in X (mucking about with X Visuals
864 * can get messy; at least here we don't have to worry about that).
867 static HWND createMainWindow(HINSTANCE hInstance, int show)
869 HWND hWnd;
871 hWnd = CreateWindow(
872 className, /* classname */
873 windowName, /* windowname/title */
874 WS_OVERLAPPEDWINDOW, /* dwStyle */
875 0, /* x */
876 0, /* y */
877 CW_USEDEFAULT, /* width */
878 CW_USEDEFAULT, /* height */
879 0, /* parent window */
880 0, /* menu */
881 hInstance, /* instance */
882 0 /* passthrough for MDI */
885 if(hWnd==0) return 0;
887 ShowWindow(hWnd, show);
888 UpdateWindow(hWnd);
890 return hWnd;
893 static int messageLoop(HINSTANCE hInstance, HWND hWnd)
895 MSG msg;
897 (void) hInstance;
898 (void) hWnd;
900 while(GetMessage(&msg, 0, 0, 0)) {
901 TranslateMessage(&msg);
902 DispatchMessage(&msg);
905 return msg.wParam;
909 * Oh, did we tell you that main() isn't the name of the
910 * thing called in a Win16/Win32 app? And then there are
911 * the lack of argument lists, the necessity (at least in Win16)
912 * of having to deal with class registration exactly once (as the
913 * app may be run again), and some other bizarre holdovers from
914 * Windows 3.x days. But hey, Solitaire still works.
917 int PASCAL WinMain(
918 HINSTANCE hInstance, HINSTANCE hPrevInstance,
919 LPSTR lpszCmdLine, int nCmdShow
922 HWND hWnd;
924 (void) lpszCmdLine;
926 strcpy(ofn_result, "--- not yet set ---");
928 if(hPrevInstance==0) {
929 if(!registerMainWindowClass(hInstance))
930 return -1;
933 g_hInstance = hInstance;
935 hWnd = createMainWindow(hInstance,nCmdShow);
936 if(hWnd == 0)
937 return -1;
939 return messageLoop(hInstance, hWnd);
942 /* And now the end of the program. Enjoy. */
945 * (c) 1999-2000 Eric Williams. Rights as specified under the WINE
946 * License. Don't hoard code; share it!