riched20: EM_STREAMIN should send a EN_UPDATE notification.
[wine/wine-kai.git] / programs / cmdlgtst / cmdlgtst.c
blob644fa2c10bda6cbd8bd0aac4f7d82c30382f448a
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 #define NONAMELESSUNION
34 #define NONAMELESSSTRUCT
36 #include <windows.h>
37 #include <commdlg.h>
38 #include <stdio.h>
39 #include <string.h>
40 #include "cmdlgtst.h"
43 * This structure is to set up flag / control associations for the custom
44 * requesters. The ft_id is the id for the control (usually generated
45 * by the system) and the ft_bit is the flag bit which goes into the
46 * settings longword for the various Commdlg structures. It is assumed
47 * that all flags fit in an unsigned long and that all bits are in fact
48 * one bit.
52 * The array of entries is terminated by {IDOK, 0}; the assumption is that
53 * IDOK would never be associated with a dialogbox control (since it's
54 * usually the ID of the OK button}.
57 struct FlagTableEntry {
58 int ft_id;
59 unsigned long ft_bit;
62 #define EXPORT
64 static const char menuName[] = "CmdlgtstMenu";
65 static const char className[] = "CmdlgtstClass";
66 static const 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 PAGESETUPDLG psd;
82 static PRINTDLG pd;
83 static COLORREF cc_cr[16];
84 static CHOOSECOLOR cc;
85 static LOGFONT cf_lf;
86 static CHOOSEFONT cf;
87 static const char ofn_filepat[] = "All Files (*.*)\0*.*\0Only Text Files (*.txt)\0*.txt\0";
88 static char ofn_result[1024];
89 static char ofn_titleresult[128];
90 static OPENFILENAME ofn;
92 /* Stuff for find and replace. These are modeless, so I have to put them here. */
94 static HWND findDialogBox = 0;
95 static UINT findMessageId = 0;
97 static FINDREPLACE frS;
98 static char fromstring[1024], tostring[1024];
100 /* Stuff for the drawing of the window(s). I put them here for convenience. */
102 static COLORREF fgColor = RGB(0, 0, 0); /* not settable */
103 static COLORREF bgColor = RGB(255, 255, 255); /* COLOR dialog */
104 static COLORREF txtColor = RGB(0, 0, 0); /* settable if one enables CF_EFFECTS */
106 /* Utility routines. */
108 static void nyi(HWND hWnd)
110 /* "Hi there! I'm not yet implemented!" */
111 MessageBox(hWnd, "Not yet implemented!", "NYI", MB_ICONEXCLAMATION | MB_OK);
114 #if 0
115 static UINT CALLBACK dummyfnHook(HWND hWnd, UINT msg, UINT wParam, UINT lParam)
118 * If the user specifies something that needs an awfully stupid hook function,
119 * this is the one to use. It's a no-op, and says "I didn't do anything."
122 (void) hWnd;
123 (void) msg;
124 (void) wParam;
125 (void) lParam;
127 printf("dummyfnhook\n"); /* visible under Wine, but Windows probably won't see it! */
129 return 0;
131 #endif
134 * Initialization code. This code simply shoves in predefined
135 * data into the COMMDLG data structures; in the future, I might use
136 * a series of loadable resources, or static initializers; of course,
137 * if Microsoft decides to change the field ordering, I'd be screwed.
140 static void mwi_Print(HWND hWnd)
142 pd.lStructSize = sizeof(PRINTDLG);
143 pd.hwndOwner = hWnd;
144 pd.hDevMode = 0;
145 pd.hDevNames = 0;
146 pd.hDC = 0;
147 pd.Flags = 0;
148 pd.nMinPage = 1;
149 pd.nMaxPage = 100;
150 pd.hInstance = g_hInstance;
151 pd.lCustData = 0;
152 pd.lpfnPrintHook = 0;
153 pd.lpfnSetupHook = 0;
154 pd.lpPrintTemplateName = 0;
155 pd.lpSetupTemplateName = 0;
156 pd.hPrintTemplate = 0;
157 pd.hSetupTemplate = 0;
160 static void mwi_PageSetup(HWND hWnd)
162 ZeroMemory(&psd, sizeof(PAGESETUPDLG));
163 psd.lStructSize = sizeof(PAGESETUPDLG);
164 psd.hwndOwner = hWnd;
168 static void mwi_Color(HWND hWnd)
170 int i;
172 /* there's probably an init call for this, somewhere. */
174 for(i=0;i<16;i++)
175 cc_cr[i] = RGB(0,0,0);
177 cc.lStructSize = sizeof(CHOOSECOLOR);
178 cc.hwndOwner = hWnd;
179 cc.hInstance = (HWND)g_hInstance; /* Should be an HINSTANCE but MS made a typo */
180 cc.rgbResult = RGB(0,0,0);
181 cc.lpCustColors = cc_cr;
182 cc.Flags = 0;
183 cc.lCustData = 0;
184 cc.lpfnHook = 0;
185 cc.lpTemplateName = 0;
188 static void mwi_Font(HWND hWnd)
190 cf.lStructSize = sizeof(CHOOSEFONT);
191 cf.hwndOwner = hWnd;
192 cf.hDC = 0;
193 cf.lpLogFont = &cf_lf;
194 cf.Flags = CF_SCREENFONTS; /* something's needed for display; otherwise it craps out with an error */
195 cf.rgbColors = RGB(0,0,0); /* what is *this* doing here?? */
196 cf.lCustData = 0;
197 cf.lpfnHook = 0;
198 cf.lpTemplateName = 0;
199 cf.hInstance = g_hInstance;
200 cf.lpszStyle = 0;
201 cf.nFontType = 0;
202 cf.nSizeMin = 8;
203 cf.nSizeMax = 72;
205 cf_lf.lfHeight = -18; /* this can be positive or negative, but negative is usually used. */
208 static void mwi_File(HWND hWnd)
210 ofn.lStructSize = sizeof(OPENFILENAME);
211 ofn.hwndOwner = hWnd;
212 ofn.hInstance = g_hInstance;
213 ofn.lpstrFilter = ofn_filepat;
214 ofn.lpstrCustomFilter = 0;
215 ofn.nMaxCustFilter = 0;
216 ofn.nFilterIndex = 0;
217 ofn.lpstrFile = ofn_result;
218 ofn.nMaxFile = sizeof(ofn_result);
219 ofn.lpstrFileTitle = ofn_titleresult;
220 ofn.nMaxFileTitle = sizeof(ofn_titleresult);
221 ofn.lpstrInitialDir = 0;
222 ofn.lpstrTitle = "Open File";
223 ofn.Flags = 0;
224 ofn.nFileOffset = 0;
225 ofn.nFileExtension = 0;
226 ofn.lpstrDefExt = "*";
227 ofn.lCustData = 0;
228 ofn.lpfnHook = 0;
229 ofn.lpTemplateName = 0;
231 ofn_result[0] = '\0';
234 static void mwi_FindReplace(HWND hWnd)
236 frS.lStructSize = sizeof(FINDREPLACE);
237 frS.hwndOwner = hWnd;
238 frS.hInstance = g_hInstance;
239 frS.Flags = FR_DOWN;
240 frS.lpstrFindWhat = fromstring;
241 frS.lpstrReplaceWith = tostring;
242 frS.wFindWhatLen = sizeof(fromstring);
243 frS.wReplaceWithLen = sizeof(tostring);
244 frS.lCustData = 0;
245 frS.lpfnHook = 0;
246 frS.lpTemplateName = 0;
248 fromstring[0] = '\0';
249 tostring[0] = '\0';
250 findMessageId = RegisterWindowMessage(FINDMSGSTRING);
253 static void mwi_InitAll(HWND hWnd)
255 mwi_Print(hWnd);
256 mwi_Font(hWnd);
257 mwi_Color(hWnd);
258 mwi_File(hWnd);
259 mwi_FindReplace(hWnd);
260 mwi_PageSetup(hWnd);
264 * Various configurations for the window. Ideally, this
265 * would be stored with the window itself, but then, this
266 * isn't the brightest of apps. Wouldn't be hard to set up,
267 * though -- one of the neater functions of Windows, but if
268 * someone decides to load the windows themselves from resources,
269 * there might be a problem.
272 static void paintMainWindow(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
274 PAINTSTRUCT ps;
275 RECT rect;
276 HPEN pen;
277 HFONT font;
278 HBRUSH brush;
280 (void) iMessage;
281 (void) wParam;
282 (void) lParam;
284 /* Commence painting! */
286 BeginPaint(hWnd, &ps);
287 GetClientRect(hWnd, (LPRECT) &rect);
289 pen = (HPEN) SelectObject(ps.hdc, CreatePen(0, 0, fgColor));
290 brush = (HBRUSH) SelectObject(ps.hdc, CreateSolidBrush(bgColor));
291 font = (HFONT) SelectObject(ps.hdc, CreateFontIndirect(&cf_lf));
294 * Ideally, we'd only need to draw the exposed bit.
295 * But something in BeginPaint is screwing up the rectangle.
296 * Either that, or Windows is drawing it wrong. AARGH!
297 * Rectangle(ps.hdc, ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right, ps.rcPaint.bottom);
299 Rectangle(ps.hdc, rect.left, rect.top, rect.right, rect.bottom);
301 /* now draw a couple of lines, just for giggles. */
303 MoveToEx(ps.hdc, rect.left, rect.top, (POINT *) 0);
304 LineTo(ps.hdc, rect.right, rect.bottom);
305 MoveToEx(ps.hdc, rect.left, rect.bottom, (POINT *) 0);
306 LineTo(ps.hdc, rect.right, rect.top);
308 /* draw some text */
310 SetTextAlign(ps.hdc, TA_CENTER|TA_BASELINE);
311 SetTextColor(ps.hdc, txtColor);
312 TextOut(ps.hdc, (rect.left+rect.right)/2, (rect.top+rect.bottom)/2, "Common Dialog Test Page", 23);
314 SetTextAlign(ps.hdc, TA_LEFT|TA_TOP);
315 TextOut(ps.hdc, rect.left+10, rect.top+10, ofn_result, strlen(ofn_result));
316 TextOut(ps.hdc, rect.left+10, rect.top-cf_lf.lfHeight+10, ofn_titleresult, strlen(ofn_titleresult));
319 * set the HDC back to the old pen and brush,
320 * and delete the newly created objects.
323 pen = (HPEN) SelectObject(ps.hdc, pen);
324 DeleteObject(pen);
325 brush = (HBRUSH) SelectObject(ps.hdc, brush);
326 DeleteObject(brush);
327 font = (HFONT) SelectObject(ps.hdc, font);
328 DeleteObject(font);
330 EndPaint(hWnd, &ps);
334 * This function simply returns an error indication. Naturally,
335 * I do not (yet) see an elegant method by which one can convert
336 * the CDERR_xxx return values into something resembling usable text;
337 * consult cderr.h to see what was returned.
340 static void mw_checkError(HWND hWnd, BOOL explicitcancel)
342 DWORD errval = CommDlgExtendedError();
343 if(errval) {
344 char errbuf[80];
346 sprintf(errbuf, "CommDlgExtendedError(): error code %ld (0x%lx)", errval, errval);
347 MessageBox(hWnd, errbuf, "Error", MB_ICONEXCLAMATION | MB_OK);
349 else {
350 if(explicitcancel) MessageBox(hWnd, "Nope, user canceled it.", "No", MB_OK);
355 * The actual dialog function calls. These merely wrap the Commdlg
356 * calls, and do something (not so) intelligent with the result.
357 * Ideally, the main window would refresh and take into account the
358 * various values specified in the dialog.
361 static void mw_ColorSetup(HWND hWnd)
363 if(ChooseColor(&cc)) {
364 RECT rect;
366 GetClientRect(hWnd, (LPRECT) &rect);
367 InvalidateRect(hWnd, (LPRECT) &rect, FALSE);
368 bgColor = cc.rgbResult;
370 else mw_checkError(hWnd, FALSE);
373 static void mw_FontSetup(HWND hWnd)
375 if(ChooseFont(&cf)) {
376 RECT rect;
377 GetClientRect(hWnd, (LPRECT) &rect);
378 InvalidateRect(hWnd, (LPRECT) &rect, FALSE);
379 txtColor = cf.rgbColors;
381 else mw_checkError(hWnd, FALSE);
384 static void mw_FindSetup(HWND hWnd)
386 if(findDialogBox == 0) {
387 findDialogBox = FindText(&frS);
388 if(findDialogBox==0) mw_checkError(hWnd,TRUE);
392 static void mw_ReplaceSetup(HWND hWnd)
394 if(findDialogBox == 0) {
395 findDialogBox = ReplaceText(&frS);
396 if(findDialogBox==0) mw_checkError(hWnd,TRUE);
400 static void mw_OpenSetup(HWND hWnd)
402 if(GetOpenFileName(&ofn)) {
403 RECT rect;
404 GetClientRect(hWnd, (LPRECT) &rect);
405 InvalidateRect(hWnd, (LPRECT) &rect, FALSE);
407 else mw_checkError(hWnd,FALSE);
410 static void mw_SaveSetup(HWND hWnd)
412 if(GetSaveFileName(&ofn)) {
413 RECT rect;
414 GetClientRect(hWnd, (LPRECT) &rect);
415 InvalidateRect(hWnd, (LPRECT) &rect, FALSE);
417 else mw_checkError(hWnd,FALSE);
421 * Can't find documentation in Borland for this one. Does it
422 * exist at all, or is it merely a subdialog of Print?
425 static void mw_PSetupSetup(HWND hWnd)
427 nyi(hWnd);
430 static void mw_PrintSetup(HWND hWnd)
432 if(PrintDlg(&pd)) {
434 * the following are suggested in the Borland documentation,
435 * but aren't that useful until WinE starts to actually
436 * function with respect to printing.
439 #if 0
440 Escape(tmp.hDC, STARTDOC, 8, "Test-Doc", NULL);
441 #endif
443 /* Print text and rectangle */
445 #if 0
446 TextOut(tmp.hDC, 50, 50, "Common Dialog Test Page", 23);
448 Rectangle(tmp.hDC, 50, 90, 625, 105);
449 Escape(tmp.hDC, NEWFRAME, 0, NULL, NULL);
450 Escape(tmp.hDC, ENDDOC, 0, NULL, NULL);
451 DeleteDC(tmp.hDC);
452 #endif
453 if (pd.hDevMode != 0)
454 GlobalFree(pd.hDevMode);
455 if (pd.hDevNames != 0)
456 GlobalFree(pd.hDevNames);
458 pd.hDevMode = 0;
459 pd.hDevNames = 0;
461 MessageBox(hWnd, "Success.", "Yes", MB_OK);
463 else mw_checkError(hWnd,TRUE);
466 #define OF(fn, fi, fl) \
467 if(dm->dmFields & fl){ \
468 printf(" %s =%hd \n", (fn), dm->fi); \
469 } else \
470 printf(" %s NOT SET!\n", fn);
473 static void mw_PageSetup(HWND hWnd)
475 DEVMODEA *dm;
476 DEVNAMES *dn;
477 CHAR tmplnm[30] = "PAGESETUPDLGORD_CSTM";
479 if(psd.Flags & PSD_ENABLEPAGESETUPTEMPLATE)
480 psd.lpPageSetupTemplateName = tmplnm;
481 psd.hInstance = g_hInstance;
483 if(PageSetupDlg(&psd)){
484 dm = GlobalLock(psd.hDevMode);
485 if(dm) {
486 printf("dm != NULL\nDEVMODEA struct:\n");
487 printf(" dmDeviceName ='%s' \n", dm->dmDeviceName);
488 printf(" dmSpecVersion =%#x \n", dm->dmSpecVersion);
489 printf(" dmDriverVersion =%#x \n", dm->dmDriverVersion);
490 printf(" dmSize =%#x \n", dm->dmSize);
491 printf(" dmDriverExtra =%#x \n", dm->dmDriverExtra);
492 printf(" dmFields =%#lx\n", dm->dmFields);
493 OF("dmOrientation", u1.s1.dmOrientation, DM_ORIENTATION)
494 OF("dmPaperSize", u1.s1.dmPaperSize, DM_PAPERSIZE);
495 OF("dmPaperLength", u1.s1.dmPaperLength, DM_PAPERLENGTH);
496 OF("dmPaperWidth", u1.s1.dmPaperWidth, DM_PAPERWIDTH);
497 OF("dmScale", dmScale, DM_SCALE);
498 OF("dmCopies", dmCopies, DM_COPIES);
499 OF("dmDefaultSource", dmDefaultSource,DM_DEFAULTSOURCE);
500 OF("dmPrintQuality", dmPrintQuality, DM_PRINTQUALITY);
501 if(dm->dmFields & DM_POSITION)
502 printf(" dmPosition(%ld, %ld)\n", dm->u1.dmPosition.x, dm->u1.dmPosition.y);
503 else
504 printf(" dmPosition NOT SET!\n");
505 OF("dmColor", dmColor, DM_COLOR);
506 OF("dmDuplex", dmDuplex, DM_DUPLEX);
507 OF("dmYResolution", dmYResolution, DM_YRESOLUTION);
508 OF("dmTTOption", dmTTOption, DM_TTOPTION);
509 OF("dmCollate", dmCollate, DM_COLLATE);
510 if(dm->dmFields & DM_FORMNAME)
511 printf(" dmFormName = '%s'\n", dm->dmFormName);
512 else
513 printf(" dmFormName NOT SET!\n");
514 if(dm->dmFields & DM_ICMMETHOD)
515 printf(" dmICMMethod = %#lx\n", dm->dmICMMethod);
516 else
517 printf(" dmICMMethod NOT SET!");
519 GlobalUnlock(psd.hDevMode);
521 else
522 printf("dm == NULL\n");
524 printf("\nPAGESETUPDLG struct\n");
525 printf(" ptPaperSize(%ld, %ld)\n", psd.ptPaperSize.x, psd.ptPaperSize.y);
526 printf(" rtMargin(%ld, %ld, %ld, %ld)\n",
527 psd.rtMargin.left, psd.rtMargin.top, psd.rtMargin.right, psd.rtMargin.bottom);
529 printf("\nDEVNAMES struct\n");
530 dn = GlobalLock(psd.hDevNames);
531 if(dn){
532 printf(" wDriverOffset='%s'\n", ((char*)dn+dn->wDriverOffset));
533 printf(" wDeviceOffset='%s'\n", ((char*)dn+dn->wDeviceOffset));
534 printf(" wOutputOffset='%s'\n", ((char*)dn+dn->wOutputOffset));
535 printf(" wDefault ='%s'\n", ((char*)dn+dn->wDefault));
536 GlobalUnlock(psd.hDevNames);
537 }else
538 printf(" dn == NULL!\n");
539 printf("End.\n");
541 if (psd.hDevMode != NULL)
542 GlobalFree(psd.hDevMode);
543 if (psd.hDevNames != NULL)
544 GlobalFree(psd.hDevNames);
545 if (psd.hPageSetupTemplate != NULL)
546 GlobalFree(psd.hPageSetupTemplate);
548 psd.hDevMode = NULL;
549 psd.hDevNames = NULL;
550 psd.hPageSetupTemplate = NULL;
552 MessageBox(hWnd, "Success.", "Yes", MB_OK);
553 } mw_checkError(hWnd, FALSE);
556 /********************************************************************************************************/
558 * Some support functions for the custom dialog box handlers.
559 * In particular, we have to set things properly, and get the flags back.
562 static void mwcd_SetFlags(HWND hWnd, struct FlagTableEntry *table, unsigned long flags)
564 int i;
566 for(i=0; table[i].ft_id != IDOK; i++)
568 CheckDlgButton(hWnd, table[i].ft_id,(table[i].ft_bit & flags) ? 1 : 0);
572 static unsigned long mwcd_GetFlags(HWND hWnd, struct FlagTableEntry * table)
574 int i;
575 unsigned long l = 0;
577 for(i=0; table[i].ft_id != IDOK; i++)
579 if(IsDlgButtonChecked(hWnd, table[i].ft_id) == 1)
580 l |= table[i].ft_bit;
583 return l;
587 * These functions are the custom dialog box handlers.
588 * The division of labor may be a tad peculiar; in particular,
589 * the flag tables should probably be in the main functions,
590 * not the handlers. I'll fix that later; this works as of right now.
593 static BOOL mwcd_Setup(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
594 struct FlagTableEntry * table, unsigned long * flags)
596 (void) lParam;
598 switch(uMsg)
600 case WM_INITDIALOG:
601 /* Set the controls properly. */
603 mwcd_SetFlags(hWnd, table, *flags);
605 return TRUE; /* I would return FALSE if I explicitly called SetFocus(). */
606 /* As usual, Windows is weird. */
608 case WM_COMMAND:
609 switch(wParam) {
610 case IDOK:
611 *flags = mwcd_GetFlags(hWnd, table);
612 EndDialog(hWnd,1);
613 break;
615 case IDCANCEL:
616 EndDialog(hWnd,0);
617 break;
619 case CM_R_HELP:
620 break; /* help? We don't need no steenkin help! */
622 default:
623 break; /* eat the message */
625 return TRUE;
627 default:
628 return FALSE; /* since I don't process this particular message */
632 static BOOL CALLBACK mwcd_ColorSetup(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
634 static struct FlagTableEntry flagTable[] = {
635 {I_CC_RGBINIT, CC_RGBINIT},
636 {I_CC_SHOWHELP, CC_SHOWHELP},
637 {I_CC_PREVENTFULLOPEN, CC_PREVENTFULLOPEN},
638 {I_CC_FULLOPEN, CC_FULLOPEN},
639 {I_CC_ENABLETEMPLATEHANDLE, CC_ENABLETEMPLATEHANDLE},
640 {I_CC_ENABLETEMPLATE, CC_ENABLETEMPLATE},
641 {I_CC_ENABLEHOOK, CC_ENABLEHOOK},
642 {IDOK, 0},
645 return mwcd_Setup(hWnd, uMsg, wParam, lParam, flagTable, &cc.Flags);
648 static BOOL CALLBACK mwcd_FontSetup(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
650 static struct FlagTableEntry flagTable[] = {
651 {I_CF_APPLY, CF_APPLY},
652 {I_CF_ANSIONLY, CF_ANSIONLY},
653 {I_CF_BOTH, CF_BOTH},
654 {I_CF_TTONLY, CF_TTONLY},
655 {I_CF_EFFECTS, CF_EFFECTS},
656 {I_CF_ENABLEHOOK, CF_ENABLEHOOK},
657 {I_CF_ENABLETEMPLATE, CF_ENABLETEMPLATE},
658 {I_CF_ENABLETEMPLATEHANDLE, CF_ENABLETEMPLATEHANDLE},
659 {I_CF_FIXEDPITCHONLY, CF_FIXEDPITCHONLY},
660 {I_CF_INITTOLOGFONTSTRUCT, CF_INITTOLOGFONTSTRUCT},
661 {I_CF_LIMITSIZE, CF_LIMITSIZE},
662 {I_CF_NOFACESEL, CF_NOFACESEL},
663 {I_CF_USESTYLE, CF_USESTYLE},
664 {I_CF_WYSIWYG, CF_WYSIWYG},
665 {I_CF_SHOWHELP, CF_SHOWHELP},
666 {I_CF_SCREENFONTS, CF_SCREENFONTS},
667 {I_CF_SCALABLEONLY, CF_SCALABLEONLY},
668 {I_CF_PRINTERFONTS, CF_PRINTERFONTS},
669 {I_CF_NOVECTORFONTS, CF_NOVECTORFONTS},
670 {I_CF_NOSTYLESEL, CF_NOSTYLESEL},
671 {I_CF_NOSIZESEL, CF_NOSIZESEL},
672 {I_CF_NOOEMFONTS, CF_NOOEMFONTS},
673 {IDOK, 0},
676 return mwcd_Setup(hWnd, uMsg, wParam, lParam, flagTable, &cf.Flags);
679 static BOOL CALLBACK mwcd_FindSetup(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
682 static struct FlagTableEntry flagTable[] = {
683 {I_FR_DIALOGTERM, FR_DIALOGTERM},
684 {I_FR_DOWN, FR_DOWN},
685 {I_FR_ENABLEHOOK, FR_ENABLEHOOK},
686 {I_FR_ENABLETEMPLATE, FR_ENABLETEMPLATE},
687 {I_FR_ENABLETEMPLATEHANDLE, FR_ENABLETEMPLATEHANDLE},
688 {I_FR_FINDNEXT, FR_FINDNEXT},
689 {I_FR_HIDEMATCHCASE, FR_HIDEMATCHCASE},
690 {I_FR_HIDEWHOLEWORD, FR_HIDEWHOLEWORD},
691 {I_FR_HIDEUPDOWN, FR_HIDEUPDOWN},
692 {I_FR_MATCHCASE, FR_MATCHCASE},
693 {I_FR_NOMATCHCASE, FR_NOMATCHCASE},
694 {I_FR_NOUPDOWN, FR_NOUPDOWN},
695 {I_FR_NOWHOLEWORD, FR_NOWHOLEWORD},
696 {I_FR_REPLACE, FR_REPLACE},
697 {I_FR_REPLACEALL, FR_REPLACEALL},
698 {I_FR_SHOWHELP, FR_SHOWHELP},
699 {I_FR_WHOLEWORD, FR_WHOLEWORD},
700 {IDOK, 0},
703 return mwcd_Setup(hWnd, uMsg, wParam, lParam, flagTable, &frS.Flags);
706 static BOOL CALLBACK mwcd_PrintSetup(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
708 static struct FlagTableEntry flagTable[] = {
709 {I_PD_ALLPAGES, PD_ALLPAGES},
710 {I_PD_COLLATE, PD_COLLATE},
711 {I_PD_DISABLEPRINTTOFILE, PD_DISABLEPRINTTOFILE},
712 {I_PD_ENABLEPRINTHOOK, PD_ENABLEPRINTHOOK},
713 {I_PD_ENABLEPRINTTEMPLATE, PD_ENABLEPRINTTEMPLATE},
714 {I_PD_ENABLEPRINTTEMPLATEHANDLE, PD_ENABLEPRINTTEMPLATEHANDLE},
715 {I_PD_ENABLESETUPHOOK, PD_ENABLESETUPHOOK},
716 {I_PD_ENABLESETUPTEMPLATE, PD_ENABLESETUPTEMPLATE},
717 {I_PD_ENABLESETUPTEMPLATEHANDLE, PD_ENABLESETUPTEMPLATEHANDLE},
718 {I_PD_HIDEPRINTTOFILE, PD_HIDEPRINTTOFILE},
719 {I_PD_NOPAGENUMS, PD_NOPAGENUMS},
720 {I_PD_NOSELECTION, PD_NOSELECTION},
721 {I_PD_NOWARNING, PD_NOWARNING},
722 {I_PD_PAGENUMS, PD_PAGENUMS},
723 {I_PD_PRINTSETUP, PD_PRINTSETUP},
724 {I_PD_PRINTTOFILE, PD_PRINTTOFILE},
725 {I_PD_RETURNDC, PD_RETURNDC},
726 {I_PD_RETURNDEFAULT, PD_RETURNDEFAULT},
727 {I_PD_RETURNIC, PD_RETURNIC},
728 {I_PD_SELECTION, PD_SELECTION},
729 {I_PD_SHOWHELP, PD_SHOWHELP},
730 {I_PD_USEDEVMODECOPIES, PD_USEDEVMODECOPIES},
731 {IDOK, 0},
734 return mwcd_Setup(hWnd, uMsg, wParam, lParam, flagTable, &pd.Flags);
737 static BOOL CALLBACK mwcd_PageSetup(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
739 static struct FlagTableEntry flagTable[] = {
740 {I_PSD_DEFAULTMINMARGINS, PSD_DEFAULTMINMARGINS},
741 {I_PSD_DISABLEMARGINS, PSD_DISABLEMARGINS},
742 {I_PSD_DISABLEORIENTATION, PSD_DISABLEORIENTATION},
743 {I_PSD_DISABLEPAGEPAINTING, PSD_DISABLEPAGEPAINTING},
744 {I_PSD_DISABLEPAPER, PSD_DISABLEPAPER},
745 {I_PSD_DISABLEPRINTER, PSD_DISABLEPRINTER},
746 {I_PSD_ENABLEPAGEPAINTHOOK, PSD_ENABLEPAGEPAINTHOOK},
747 {I_PSD_ENABLEPAGESETUPHOOK, PSD_ENABLEPAGESETUPHOOK},
748 {I_PSD_ENABLEPAGESETUPTEMPLATE, PSD_ENABLEPAGESETUPTEMPLATE},
749 {I_PSD_ENABLEPAGESETUPTEMPLATEHANDLE, PSD_ENABLEPAGESETUPTEMPLATEHANDLE},
750 {I_PSD_INHUNDREDTHSOFMILLIMETERS, PSD_INHUNDREDTHSOFMILLIMETERS},
751 {I_PSD_INTHOUSANDTHSOFINCHES, PSD_INTHOUSANDTHSOFINCHES},
752 {I_PSD_INWININIINTLMEASURE, PSD_INWININIINTLMEASURE},
753 {I_PSD_MARGINS, PSD_MARGINS},
754 {I_PSD_MINMARGINS, PSD_MINMARGINS},
755 {I_PSD_NONETWORKBUTTON, PSD_NONETWORKBUTTON},
756 {I_PSD_NOWARNING, PSD_NOWARNING},
757 {I_PSD_RETURNDEFAULT, PSD_RETURNDEFAULT},
758 {I_PSD_SHOWHELP, PSD_SHOWHELP},
759 {IDOK, 0}
762 return mwcd_Setup(hWnd, uMsg, wParam, lParam, flagTable, &psd.Flags);
765 static BOOL CALLBACK mwcd_FileSetup(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
767 static struct FlagTableEntry flagTable[] = {
768 {I_OFN_ALLOWMULTISELECT, OFN_ALLOWMULTISELECT},
769 {I_OFN_CREATEPROMPT, OFN_CREATEPROMPT},
770 {I_OFN_ENABLEHOOK, OFN_ENABLEHOOK},
771 {I_OFN_ENABLETEMPLATE, OFN_ENABLETEMPLATE},
772 {I_OFN_ENABLETEMPLATEHANDLE, OFN_ENABLETEMPLATEHANDLE},
773 {I_OFN_EXTENSIONDIFFERENT, OFN_EXTENSIONDIFFERENT},
774 {I_OFN_FILEMUSTEXIST, OFN_FILEMUSTEXIST},
775 {I_OFN_HIDEREADONLY, OFN_HIDEREADONLY},
776 {I_OFN_NOCHANGEDIR, OFN_NOCHANGEDIR},
777 {I_OFN_NOREADONLYRETURN, OFN_NOREADONLYRETURN},
778 {I_OFN_NOTESTFILECREATE, OFN_NOTESTFILECREATE},
779 {I_OFN_NOVALIDATE, OFN_NOVALIDATE},
780 {I_OFN_OVERWRITEPROMPT, OFN_OVERWRITEPROMPT},
781 {I_OFN_PATHMUSTEXIST, OFN_PATHMUSTEXIST},
782 {I_OFN_READONLY, OFN_READONLY},
783 {I_OFN_SHAREAWARE, OFN_SHAREAWARE},
784 {I_OFN_SHOWHELP, OFN_SHOWHELP},
785 {IDOK, 0},
788 return mwcd_Setup(hWnd, uMsg, wParam, lParam, flagTable, &ofn.Flags);
791 static BOOL CALLBACK mwcd_About(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
793 (void) wParam;
794 (void) lParam;
796 switch(uMsg) {
797 case WM_INITDIALOG: return TRUE; /* let WINDOWS set the focus. */
798 case WM_COMMAND: EndDialog(hWnd, 0); return TRUE; /* it's our OK button. */
799 default: return FALSE; /* it's something else, let Windows worry about it */
804 * These functions call custom dialog boxes (resource-loaded, if I do this right).
805 * Right now they don't do a heck of a lot, but at some future time
806 * they will muck about with the flags (and be loaded from the flags) of
807 * the CommDlg structures initialized by the mwi_xxx() routines.
810 static void mwc_ColorSetup(HWND hWnd)
812 int r = DialogBox(g_hInstance, "Color_Flags_Dialog", hWnd, (DLGPROC) mwcd_ColorSetup);
813 if(r < 0) { MessageBox(hWnd, "Failure opening Color_Flags_Dialog box", "Error", MB_ICONASTERISK|MB_OK); }
816 static void mwc_FontSetup(HWND hWnd)
818 int r = DialogBox(g_hInstance, "Font_Flags_Dialog", hWnd, (DLGPROC) mwcd_FontSetup);
819 if(r < 0) { MessageBox(hWnd, "Failure opening Font_Flags_Dialog box", "Error", MB_ICONASTERISK|MB_OK); }
822 static void mwc_FindReplaceSetup(HWND hWnd)
824 int r = DialogBox(g_hInstance, "Find_Flags_Dialog", hWnd, (DLGPROC) mwcd_FindSetup);
825 if(r < 0) { MessageBox(hWnd, "Failure opening Find_Flags_Dialog box", "Error", MB_ICONASTERISK|MB_OK); }
828 static void mwc_PrintSetup(HWND hWnd)
830 int r = DialogBox(g_hInstance, "Print_Flags_Dialog", hWnd, (DLGPROC) mwcd_PrintSetup);
831 if(r < 0) { MessageBox(hWnd, "Failure opening Print_Flags_Dialog box", "Error", MB_ICONASTERISK|MB_OK); }
834 static void mwc_PageSetup(HWND hWnd)
836 int r = DialogBox(g_hInstance, "PageSetup_Flags_Dialog", hWnd, (DLGPROC) mwcd_PageSetup);
837 if(r < 0) { MessageBox(hWnd, "Failure opening PageSetup_Flags_Dialog box", "Error", MB_ICONASTERISK|MB_OK); }
840 static void mwc_FileSetup(HWND hWnd)
842 int r = DialogBox(g_hInstance, "File_Flags_Dialog", hWnd, (DLGPROC) mwcd_FileSetup);
843 if(r < 0) { MessageBox(hWnd, "Failure opening File_Flags_Dialog box", "Error", MB_ICONASTERISK|MB_OK); }
847 * Main window message dispatcher. Here the messages get chewed up
848 * and spit out. Note the ugly hack for the modeless Find/Replace box;
849 * this looks like it was bolted on with hexhead screws and is now
850 * dangling from Windows like a loose muffler. Sigh.
853 static LRESULT CALLBACK EXPORT mainWindowDispatcher(
854 HWND hWnd,
855 UINT uMsg,
856 WPARAM wParam,
857 LPARAM lParam
861 if(uMsg == findMessageId) {
862 FINDREPLACE * lpfr = (FINDREPLACE *) lParam;
863 if(lpfr->Flags & FR_DIALOGTERM) {
864 MessageBox(hWnd, "User closing us down.", "Down", MB_OK);
865 findDialogBox = 0;
867 else if (lpfr->Flags & FR_FINDNEXT) {
868 MessageBox(hWnd, "Finding next occurrence.", "Findnext", MB_OK);
870 else if (lpfr->Flags & FR_REPLACE) {
871 MessageBox(hWnd, "Replacing next occurrence.", "Replace", MB_OK);
873 else if (lpfr->Flags & FR_REPLACEALL) {
874 MessageBox(hWnd, "Replacing all occurrences.", "Replace All", MB_OK);
876 else {
877 MessageBox(hWnd, "Eh?", "Eh?", MB_OK);
879 return 1;
881 else switch(uMsg) {
882 case WM_CREATE:
884 * this is always the first message...at least as far as
885 * we are concerned.
887 mwi_InitAll(hWnd);
888 break;
890 case WM_PAINT:
891 /* Well, draw something! */
892 paintMainWindow(hWnd, uMsg, wParam, lParam);
893 break;
895 case WM_DESTROY:
896 /* Uh oh. Eject! Eject! Eject! */
897 PostQuitMessage(0);
898 break;
900 case WM_COMMAND:
901 /* menu or accelerator pressed; do something. */
903 switch(wParam) {
904 case CM_U_EXIT:
905 /* Uh oh. Eject! Eject! Eject! */
906 PostQuitMessage(0);
907 break;
909 /* these actually call the Common Dialogs. */
911 case CM_U_COLOR:
912 mw_ColorSetup(hWnd); return 1;
914 case CM_U_FONT:
915 mw_FontSetup(hWnd); return 1;
917 case CM_U_FIND:
918 mw_FindSetup(hWnd); return 1;
920 case CM_U_REPLACE:
921 mw_ReplaceSetup(hWnd); return 1;
923 case CM_U_OPEN:
924 mw_OpenSetup(hWnd); return 1;
926 case CM_U_SAVE:
927 mw_SaveSetup(hWnd); return 1;
929 case CM_U_PSETUP:
930 mw_PSetupSetup(hWnd); return 1;
932 case CM_U_PRINT:
933 mw_PrintSetup(hWnd); return 1;
935 case CM_U_PAGESETUP:
936 mw_PageSetup(hWnd); return 1;
939 * these set up various flags and values in the Common Dialog
940 * data structures, which are currently stored in static memory.
941 * The control dialogs themselves are resources as well.
944 case CM_F_FILE:
945 mwc_FileSetup(hWnd); return 1;
947 case CM_F_COLOR:
948 mwc_ColorSetup(hWnd); return 1;
950 case CM_F_FONT:
951 mwc_FontSetup(hWnd); return 1;
953 case CM_F_FINDREPLACE:
954 mwc_FindReplaceSetup(hWnd); return 1;
956 case CM_F_PRINT:
957 mwc_PrintSetup(hWnd); return 1;
959 case CM_F_PAGESETUP:
960 mwc_PageSetup(hWnd); return 1;
962 case CM_H_ABOUT:
963 DialogBox(g_hInstance, "AboutDialog", hWnd, (DLGPROC) mwcd_About);
964 return 1;
965 case CM_H_USAGE:
966 DialogBox(g_hInstance, "UsageDialog", hWnd, (DLGPROC) mwcd_About);
967 /* return value? *What* return value? */
968 return 1;
970 default:
971 nyi(hWnd); return 1;
973 break;
975 default:
976 return DefWindowProc(hWnd, uMsg, wParam, lParam);
978 return 0;
981 /* Class registration. One might call this a Windowsism. */
983 static int registerMainWindowClass(HINSTANCE hInstance)
985 WNDCLASS wndClass;
987 wndClass.style = CS_HREDRAW|CS_VREDRAW;
988 wndClass.lpfnWndProc = mainWindowDispatcher;
989 wndClass.cbClsExtra = 0;
990 wndClass.cbWndExtra = 0;
991 wndClass.hInstance = hInstance;
992 #if 0
993 wndClass.hIcon = LoadIcon(hInstance, "whello");
994 wndClass.hCursor = LoadCursor(hInstance, IDC_ARROW);
995 #endif
996 wndClass.hIcon = 0;
997 wndClass.hCursor = 0;
998 wndClass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
999 wndClass.lpszMenuName = menuName;
1000 wndClass.lpszClassName = className;
1002 return RegisterClass(&wndClass);
1006 * Another Windowsism; this one's not too bad, as it compares
1007 * favorably with CreateWindow() in X (mucking about with X Visuals
1008 * can get messy; at least here we don't have to worry about that).
1011 static HWND createMainWindow(HINSTANCE hInstance, int show)
1013 HWND hWnd;
1015 hWnd = CreateWindow(
1016 className, /* classname */
1017 windowName, /* windowname/title */
1018 WS_OVERLAPPEDWINDOW, /* dwStyle */
1019 0, /* x */
1020 0, /* y */
1021 CW_USEDEFAULT, /* width */
1022 CW_USEDEFAULT, /* height */
1023 0, /* parent window */
1024 0, /* menu */
1025 hInstance, /* instance */
1026 0 /* passthrough for MDI */
1029 if(hWnd==0) return 0;
1031 ShowWindow(hWnd, show);
1032 UpdateWindow(hWnd);
1034 return hWnd;
1037 static int messageLoop(HINSTANCE hInstance, HWND hWnd)
1039 MSG msg;
1041 (void) hInstance;
1042 (void) hWnd;
1044 while(GetMessage(&msg, 0, 0, 0)) {
1045 TranslateMessage(&msg);
1046 DispatchMessage(&msg);
1049 return msg.wParam;
1053 * Oh, did we tell you that main() isn't the name of the
1054 * thing called in a Win16/Win32 app? And then there are
1055 * the lack of argument lists, the necessity (at least in Win16)
1056 * of having to deal with class registration exactly once (as the
1057 * app may be run again), and some other bizarre holdovers from
1058 * Windows 3.x days. But hey, Solitaire still works.
1061 int PASCAL WinMain(
1062 HINSTANCE hInstance, HINSTANCE hPrevInstance,
1063 LPSTR lpszCmdLine, int nCmdShow
1066 HWND hWnd;
1068 (void) lpszCmdLine;
1070 strcpy(ofn_result, "--- not yet set ---");
1072 if(hPrevInstance==0) {
1073 if(!registerMainWindowClass(hInstance))
1074 return -1;
1077 g_hInstance = hInstance;
1079 hWnd = createMainWindow(hInstance,nCmdShow);
1080 if(hWnd == 0)
1081 return -1;
1083 return messageLoop(hInstance, hWnd);
1086 /* And now the end of the program. Enjoy. */
1089 * (c) 1999-2000 Eric Williams. Rights as specified under the WINE
1090 * License. Don't hoard code; share it!