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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 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
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
42 #include <wine/debug.h>
44 WINE_DEFAULT_DEBUG_CHANNEL(cmdlgtst
);
47 * This structure is to set up flag / control associations for the custom
48 * requesters. The ft_id is the id for the control (usually generated
49 * by the system) and the ft_bit is the flag bit which goes into the
50 * settings longword for the various Commdlg structures. It is assumed
51 * that all flags fit in an unsigned long and that all bits are in fact
56 * The array of entries is terminated by {IDOK, 0}; the assumption is that
57 * IDOK would never be associated with a dialogbox control (since it's
58 * usually the ID of the OK button}.
61 struct FlagTableEntry
{
68 static const char menuName
[] = "CmdlgtstMenu";
69 static const char className
[] = "CmdlgtstClass";
70 static const char windowName
[] = "Cmdlgtst Window";
73 * global hInstance variable. This makes the code non-threadable,
74 * but wotthehell; this is Win32 anyway! (Though it does work
75 * under Win16, if one doesn't run more than one copy at a time.)
78 static HINSTANCE g_hInstance
;
81 * global CommDlg data structures for modals. These are placed here
82 * so that the custom dialog boxes can get at them.
85 static PAGESETUPDLG psd
;
87 static COLORREF cc_cr
[16];
88 static CHOOSECOLOR cc
;
91 static const char ofn_filepat
[] = "All Files (*.*)\0*.*\0Only Text Files (*.txt)\0*.txt\0";
92 static char ofn_result
[1024];
93 static char ofn_titleresult
[128];
94 static OPENFILENAME ofn
;
96 /* Stuff for find and replace. These are modeless, so I have to put them here. */
98 static HWND findDialogBox
= 0;
99 static UINT findMessageId
= 0;
101 static FINDREPLACE frS
;
102 static char fromstring
[1024], tostring
[1024];
104 /* Stuff for the drawing of the window(s). I put them here for convenience. */
106 static COLORREF fgColor
= RGB(0, 0, 0); /* not settable */
107 static COLORREF bgColor
= RGB(255, 255, 255); /* COLOR dialog */
108 static COLORREF txtColor
= RGB(0, 0, 0); /* settable if one enables CF_EFFECTS */
110 /* Utility routines. */
112 static void nyi(HWND hWnd
)
114 /* "Hi there! I'm not yet implemented!" */
115 MessageBox(hWnd
, "Not yet implemented!", "NYI", MB_ICONEXCLAMATION
| MB_OK
);
119 static UINT CALLBACK
dummyfnHook(HWND hWnd
, UINT msg
, UINT wParam
, UINT lParam
)
122 * If the user specifies something that needs an awfully stupid hook function,
123 * this is the one to use. It's a no-op, and says "I didn't do anything."
131 WINE_TRACE("dummyfnhook\n"); /* visible under Wine, but Windows probably won't see it! */
138 * Initialization code. This code simply shoves in predefined
139 * data into the COMMDLG data structures; in the future, I might use
140 * a series of loadable resources, or static initializers; of course,
141 * if Microsoft decides to change the field ordering, I'd be screwed.
144 static void mwi_Print(HWND hWnd
)
146 pd
.lStructSize
= sizeof(PRINTDLG
);
154 pd
.hInstance
= g_hInstance
;
156 pd
.lpfnPrintHook
= 0;
157 pd
.lpfnSetupHook
= 0;
158 pd
.lpPrintTemplateName
= 0;
159 pd
.lpSetupTemplateName
= 0;
160 pd
.hPrintTemplate
= 0;
161 pd
.hSetupTemplate
= 0;
164 static void mwi_PageSetup(HWND hWnd
)
166 ZeroMemory(&psd
, sizeof(PAGESETUPDLG
));
167 psd
.lStructSize
= sizeof(PAGESETUPDLG
);
168 psd
.hwndOwner
= hWnd
;
172 static void mwi_Color(HWND hWnd
)
176 /* there's probably an init call for this, somewhere. */
179 cc_cr
[i
] = RGB(0,0,0);
181 cc
.lStructSize
= sizeof(CHOOSECOLOR
);
183 cc
.hInstance
= (HWND
)g_hInstance
; /* Should be an HINSTANCE but MS made a typo */
184 cc
.rgbResult
= RGB(0,0,0);
185 cc
.lpCustColors
= cc_cr
;
189 cc
.lpTemplateName
= 0;
192 static void mwi_Font(HWND hWnd
)
194 cf
.lStructSize
= sizeof(CHOOSEFONT
);
197 cf
.lpLogFont
= &cf_lf
;
198 cf
.Flags
= CF_SCREENFONTS
; /* something's needed for display; otherwise it craps out with an error */
199 cf
.rgbColors
= RGB(0,0,0); /* what is *this* doing here?? */
202 cf
.lpTemplateName
= 0;
203 cf
.hInstance
= g_hInstance
;
209 cf_lf
.lfHeight
= -18; /* this can be positive or negative, but negative is usually used. */
212 static void mwi_File(HWND hWnd
)
214 ofn
.lStructSize
= sizeof(OPENFILENAME
);
215 ofn
.hwndOwner
= hWnd
;
216 ofn
.hInstance
= g_hInstance
;
217 ofn
.lpstrFilter
= ofn_filepat
;
218 ofn
.lpstrCustomFilter
= 0;
219 ofn
.nMaxCustFilter
= 0;
220 ofn
.nFilterIndex
= 0;
221 ofn
.lpstrFile
= ofn_result
;
222 ofn
.nMaxFile
= sizeof(ofn_result
);
223 ofn
.lpstrFileTitle
= ofn_titleresult
;
224 ofn
.nMaxFileTitle
= sizeof(ofn_titleresult
);
225 ofn
.lpstrInitialDir
= 0;
226 ofn
.lpstrTitle
= "Open File";
229 ofn
.nFileExtension
= 0;
230 ofn
.lpstrDefExt
= "*";
233 ofn
.lpTemplateName
= 0;
235 ofn_result
[0] = '\0';
238 static void mwi_FindReplace(HWND hWnd
)
240 frS
.lStructSize
= sizeof(FINDREPLACE
);
241 frS
.hwndOwner
= hWnd
;
242 frS
.hInstance
= g_hInstance
;
244 frS
.lpstrFindWhat
= fromstring
;
245 frS
.lpstrReplaceWith
= tostring
;
246 frS
.wFindWhatLen
= sizeof(fromstring
);
247 frS
.wReplaceWithLen
= sizeof(tostring
);
250 frS
.lpTemplateName
= 0;
252 fromstring
[0] = '\0';
254 findMessageId
= RegisterWindowMessage(FINDMSGSTRING
);
257 static void mwi_InitAll(HWND hWnd
)
263 mwi_FindReplace(hWnd
);
268 * Various configurations for the window. Ideally, this
269 * would be stored with the window itself, but then, this
270 * isn't the brightest of apps. Wouldn't be hard to set up,
271 * though -- one of the neater functions of Windows, but if
272 * someone decides to load the windows themselves from resources,
273 * there might be a problem.
276 static void paintMainWindow(HWND hWnd
, UINT iMessage
, WPARAM wParam
, LPARAM lParam
)
288 /* Commence painting! */
290 BeginPaint(hWnd
, &ps
);
291 GetClientRect(hWnd
, (LPRECT
) &rect
);
293 pen
= (HPEN
) SelectObject(ps
.hdc
, CreatePen(0, 0, fgColor
));
294 brush
= (HBRUSH
) SelectObject(ps
.hdc
, CreateSolidBrush(bgColor
));
295 font
= (HFONT
) SelectObject(ps
.hdc
, CreateFontIndirect(&cf_lf
));
298 * Ideally, we'd only need to draw the exposed bit.
299 * But something in BeginPaint is screwing up the rectangle.
300 * Either that, or Windows is drawing it wrong. AARGH!
301 * Rectangle(ps.hdc, ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right, ps.rcPaint.bottom);
303 Rectangle(ps
.hdc
, rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
305 /* now draw a couple of lines, just for giggles. */
307 MoveToEx(ps
.hdc
, rect
.left
, rect
.top
, (POINT
*) 0);
308 LineTo(ps
.hdc
, rect
.right
, rect
.bottom
);
309 MoveToEx(ps
.hdc
, rect
.left
, rect
.bottom
, (POINT
*) 0);
310 LineTo(ps
.hdc
, rect
.right
, rect
.top
);
314 SetTextAlign(ps
.hdc
, TA_CENTER
|TA_BASELINE
);
315 SetTextColor(ps
.hdc
, txtColor
);
316 TextOut(ps
.hdc
, (rect
.left
+rect
.right
)/2, (rect
.top
+rect
.bottom
)/2, "Common Dialog Test Page", 23);
318 SetTextAlign(ps
.hdc
, TA_LEFT
|TA_TOP
);
319 TextOut(ps
.hdc
, rect
.left
+10, rect
.top
+10, ofn_result
, strlen(ofn_result
));
320 TextOut(ps
.hdc
, rect
.left
+10, rect
.top
-cf_lf
.lfHeight
+10, ofn_titleresult
, strlen(ofn_titleresult
));
323 * set the HDC back to the old pen and brush,
324 * and delete the newly created objects.
327 pen
= (HPEN
) SelectObject(ps
.hdc
, pen
);
329 brush
= (HBRUSH
) SelectObject(ps
.hdc
, brush
);
331 font
= (HFONT
) SelectObject(ps
.hdc
, font
);
338 * This function simply returns an error indication. Naturally,
339 * I do not (yet) see an elegant method by which one can convert
340 * the CDERR_xxx return values into something resembling usable text;
341 * consult cderr.h to see what was returned.
344 static void mw_checkError(HWND hWnd
, BOOL explicitcancel
)
346 DWORD errval
= CommDlgExtendedError();
350 sprintf(errbuf
, "CommDlgExtendedError(): error code %d (0x%x)", errval
, errval
);
351 MessageBox(hWnd
, errbuf
, "Error", MB_ICONEXCLAMATION
| MB_OK
);
354 if(explicitcancel
) MessageBox(hWnd
, "Nope, user canceled it.", "No", MB_OK
);
359 * The actual dialog function calls. These merely wrap the Commdlg
360 * calls, and do something (not so) intelligent with the result.
361 * Ideally, the main window would refresh and take into account the
362 * various values specified in the dialog.
365 static void mw_ColorSetup(HWND hWnd
)
367 if(ChooseColor(&cc
)) {
370 GetClientRect(hWnd
, (LPRECT
) &rect
);
371 InvalidateRect(hWnd
, (LPRECT
) &rect
, FALSE
);
372 bgColor
= cc
.rgbResult
;
374 else mw_checkError(hWnd
, FALSE
);
377 static void mw_FontSetup(HWND hWnd
)
379 if(ChooseFont(&cf
)) {
381 GetClientRect(hWnd
, (LPRECT
) &rect
);
382 InvalidateRect(hWnd
, (LPRECT
) &rect
, FALSE
);
383 txtColor
= cf
.rgbColors
;
385 else mw_checkError(hWnd
, FALSE
);
388 static void mw_FindSetup(HWND hWnd
)
390 if(findDialogBox
== 0) {
391 findDialogBox
= FindText(&frS
);
392 if(findDialogBox
==0) mw_checkError(hWnd
,TRUE
);
396 static void mw_ReplaceSetup(HWND hWnd
)
398 if(findDialogBox
== 0) {
399 findDialogBox
= ReplaceText(&frS
);
400 if(findDialogBox
==0) mw_checkError(hWnd
,TRUE
);
404 static void mw_OpenSetup(HWND hWnd
)
406 if(GetOpenFileName(&ofn
)) {
408 GetClientRect(hWnd
, (LPRECT
) &rect
);
409 InvalidateRect(hWnd
, (LPRECT
) &rect
, FALSE
);
411 else mw_checkError(hWnd
,FALSE
);
414 static void mw_SaveSetup(HWND hWnd
)
416 if(GetSaveFileName(&ofn
)) {
418 GetClientRect(hWnd
, (LPRECT
) &rect
);
419 InvalidateRect(hWnd
, (LPRECT
) &rect
, FALSE
);
421 else mw_checkError(hWnd
,FALSE
);
425 * Can't find documentation in Borland for this one. Does it
426 * exist at all, or is it merely a subdialog of Print?
429 static void mw_PSetupSetup(HWND hWnd
)
434 static void mw_PrintSetup(HWND hWnd
)
438 * the following are suggested in the Borland documentation,
439 * but aren't that useful until WinE starts to actually
440 * function with respect to printing.
444 Escape(tmp
.hDC
, STARTDOC
, 8, "Test-Doc", NULL
);
447 /* Print text and rectangle */
450 TextOut(tmp
.hDC
, 50, 50, "Common Dialog Test Page", 23);
452 Rectangle(tmp
.hDC
, 50, 90, 625, 105);
453 Escape(tmp
.hDC
, NEWFRAME
, 0, NULL
, NULL
);
454 Escape(tmp
.hDC
, ENDDOC
, 0, NULL
, NULL
);
457 if (pd
.hDevMode
!= 0)
458 GlobalFree(pd
.hDevMode
);
459 if (pd
.hDevNames
!= 0)
460 GlobalFree(pd
.hDevNames
);
465 MessageBox(hWnd
, "Success.", "Yes", MB_OK
);
467 else mw_checkError(hWnd
,TRUE
);
470 #define OF(fn, fi, fl) \
471 if(dm->dmFields & fl){ \
472 WINE_TRACE(" %s =%hd\n", (fn), dm->fi); \
474 WINE_TRACE(" %s NOT SET!\n", fn);
477 static void mw_PageSetup(HWND hWnd
)
481 CHAR tmplnm
[30] = "PAGESETUPDLGORD_CSTM";
483 if(psd
.Flags
& PSD_ENABLEPAGESETUPTEMPLATE
)
484 psd
.lpPageSetupTemplateName
= tmplnm
;
485 psd
.hInstance
= g_hInstance
;
487 if(PageSetupDlg(&psd
)){
488 dm
= GlobalLock(psd
.hDevMode
);
490 WINE_TRACE("dm != NULL\nDEVMODEA struct:\n");
491 WINE_TRACE(" dmDeviceName ='%s'\n", dm
->dmDeviceName
);
492 WINE_TRACE(" dmSpecVersion =%#x\n", dm
->dmSpecVersion
);
493 WINE_TRACE(" dmDriverVersion =%#x\n", dm
->dmDriverVersion
);
494 WINE_TRACE(" dmSize =%#x\n", dm
->dmSize
);
495 WINE_TRACE(" dmDriverExtra =%#x\n", dm
->dmDriverExtra
);
496 WINE_TRACE(" dmFields =%#x\n", dm
->dmFields
);
497 OF("dmOrientation", u1
.s1
.dmOrientation
, DM_ORIENTATION
)
498 OF("dmPaperSize", u1
.s1
.dmPaperSize
, DM_PAPERSIZE
);
499 OF("dmPaperLength", u1
.s1
.dmPaperLength
, DM_PAPERLENGTH
);
500 OF("dmPaperWidth", u1
.s1
.dmPaperWidth
, DM_PAPERWIDTH
);
501 OF("dmScale", dmScale
, DM_SCALE
);
502 OF("dmCopies", dmCopies
, DM_COPIES
);
503 OF("dmDefaultSource", dmDefaultSource
,DM_DEFAULTSOURCE
);
504 OF("dmPrintQuality", dmPrintQuality
, DM_PRINTQUALITY
);
505 if(dm
->dmFields
& DM_POSITION
)
506 WINE_TRACE(" dmPosition(%d, %d)\n", dm
->u1
.dmPosition
.x
, dm
->u1
.dmPosition
.y
);
508 WINE_TRACE(" dmPosition NOT SET!\n");
509 OF("dmColor", dmColor
, DM_COLOR
);
510 OF("dmDuplex", dmDuplex
, DM_DUPLEX
);
511 OF("dmYResolution", dmYResolution
, DM_YRESOLUTION
);
512 OF("dmTTOption", dmTTOption
, DM_TTOPTION
);
513 OF("dmCollate", dmCollate
, DM_COLLATE
);
514 if(dm
->dmFields
& DM_FORMNAME
)
515 WINE_TRACE(" dmFormName = '%s'\n", dm
->dmFormName
);
517 WINE_TRACE(" dmFormName NOT SET!\n");
518 if(dm
->dmFields
& DM_ICMMETHOD
)
519 WINE_TRACE(" dmICMMethod = %#x\n", dm
->dmICMMethod
);
521 WINE_TRACE(" dmICMMethod NOT SET!\n");
523 GlobalUnlock(psd
.hDevMode
);
526 WINE_TRACE("dm == NULL\n");
528 WINE_TRACE("\nPAGESETUPDLG struct\n");
529 WINE_TRACE(" ptPaperSize(%d, %d)\n", psd
.ptPaperSize
.x
, psd
.ptPaperSize
.y
);
530 WINE_TRACE(" rtMargin(%d, %d, %d, %d)\n",
531 psd
.rtMargin
.left
, psd
.rtMargin
.top
, psd
.rtMargin
.right
, psd
.rtMargin
.bottom
);
533 WINE_TRACE("\nDEVNAMES struct\n");
534 dn
= GlobalLock(psd
.hDevNames
);
536 WINE_TRACE(" wDriverOffset='%s'\n", ((char*)dn
+dn
->wDriverOffset
));
537 WINE_TRACE(" wDeviceOffset='%s'\n", ((char*)dn
+dn
->wDeviceOffset
));
538 WINE_TRACE(" wOutputOffset='%s'\n", ((char*)dn
+dn
->wOutputOffset
));
539 WINE_TRACE(" wDefault ='%s'\n", ((char*)dn
+dn
->wDefault
));
540 GlobalUnlock(psd
.hDevNames
);
542 WINE_TRACE(" dn == NULL!\n");
543 WINE_TRACE("End.\n");
545 if (psd
.hDevMode
!= NULL
)
546 GlobalFree(psd
.hDevMode
);
547 if (psd
.hDevNames
!= NULL
)
548 GlobalFree(psd
.hDevNames
);
549 if (psd
.hPageSetupTemplate
!= NULL
)
550 GlobalFree(psd
.hPageSetupTemplate
);
553 psd
.hDevNames
= NULL
;
554 psd
.hPageSetupTemplate
= NULL
;
556 MessageBox(hWnd
, "Success.", "Yes", MB_OK
);
557 } mw_checkError(hWnd
, FALSE
);
560 /********************************************************************************************************/
562 * Some support functions for the custom dialog box handlers.
563 * In particular, we have to set things properly, and get the flags back.
566 static void mwcd_SetFlags(HWND hWnd
, struct FlagTableEntry
*table
, DWORD flags
)
570 for(i
=0; table
[i
].ft_id
!= IDOK
; i
++)
572 CheckDlgButton(hWnd
, table
[i
].ft_id
,(table
[i
].ft_bit
& flags
) ? 1 : 0);
576 static DWORD
mwcd_GetFlags(HWND hWnd
, struct FlagTableEntry
* table
)
581 for(i
=0; table
[i
].ft_id
!= IDOK
; i
++)
583 if(IsDlgButtonChecked(hWnd
, table
[i
].ft_id
) == 1)
584 l
|= table
[i
].ft_bit
;
591 * These functions are the custom dialog box handlers.
592 * The division of labor may be a tad peculiar; in particular,
593 * the flag tables should probably be in the main functions,
594 * not the handlers. I'll fix that later; this works as of right now.
597 static INT_PTR
mwcd_Setup(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
,
598 struct FlagTableEntry
* table
, DWORD
* flags
)
605 /* Set the controls properly. */
607 mwcd_SetFlags(hWnd
, table
, *flags
);
609 return TRUE
; /* I would return FALSE if I explicitly called SetFocus(). */
610 /* As usual, Windows is weird. */
615 *flags
= mwcd_GetFlags(hWnd
, table
);
624 break; /* help? We don't need no steenkin help! */
627 break; /* eat the message */
632 return FALSE
; /* since I don't process this particular message */
636 static INT_PTR CALLBACK
mwcd_ColorSetup(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
638 static struct FlagTableEntry flagTable
[] = {
639 {I_CC_RGBINIT
, CC_RGBINIT
},
640 {I_CC_SHOWHELP
, CC_SHOWHELP
},
641 {I_CC_PREVENTFULLOPEN
, CC_PREVENTFULLOPEN
},
642 {I_CC_FULLOPEN
, CC_FULLOPEN
},
643 {I_CC_ENABLETEMPLATEHANDLE
, CC_ENABLETEMPLATEHANDLE
},
644 {I_CC_ENABLETEMPLATE
, CC_ENABLETEMPLATE
},
645 {I_CC_ENABLEHOOK
, CC_ENABLEHOOK
},
649 return mwcd_Setup(hWnd
, uMsg
, wParam
, lParam
, flagTable
, &cc
.Flags
);
652 static INT_PTR CALLBACK
mwcd_FontSetup(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
654 static struct FlagTableEntry flagTable
[] = {
655 {I_CF_APPLY
, CF_APPLY
},
656 {I_CF_ANSIONLY
, CF_ANSIONLY
},
657 {I_CF_BOTH
, CF_BOTH
},
658 {I_CF_TTONLY
, CF_TTONLY
},
659 {I_CF_EFFECTS
, CF_EFFECTS
},
660 {I_CF_ENABLEHOOK
, CF_ENABLEHOOK
},
661 {I_CF_ENABLETEMPLATE
, CF_ENABLETEMPLATE
},
662 {I_CF_ENABLETEMPLATEHANDLE
, CF_ENABLETEMPLATEHANDLE
},
663 {I_CF_FIXEDPITCHONLY
, CF_FIXEDPITCHONLY
},
664 {I_CF_INITTOLOGFONTSTRUCT
, CF_INITTOLOGFONTSTRUCT
},
665 {I_CF_LIMITSIZE
, CF_LIMITSIZE
},
666 {I_CF_NOFACESEL
, CF_NOFACESEL
},
667 {I_CF_USESTYLE
, CF_USESTYLE
},
668 {I_CF_WYSIWYG
, CF_WYSIWYG
},
669 {I_CF_SHOWHELP
, CF_SHOWHELP
},
670 {I_CF_SCREENFONTS
, CF_SCREENFONTS
},
671 {I_CF_SCALABLEONLY
, CF_SCALABLEONLY
},
672 {I_CF_PRINTERFONTS
, CF_PRINTERFONTS
},
673 {I_CF_NOVECTORFONTS
, CF_NOVECTORFONTS
},
674 {I_CF_NOSTYLESEL
, CF_NOSTYLESEL
},
675 {I_CF_NOSIZESEL
, CF_NOSIZESEL
},
676 {I_CF_NOOEMFONTS
, CF_NOOEMFONTS
},
680 return mwcd_Setup(hWnd
, uMsg
, wParam
, lParam
, flagTable
, &cf
.Flags
);
683 static INT_PTR CALLBACK
mwcd_FindSetup(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
686 static struct FlagTableEntry flagTable
[] = {
687 {I_FR_DIALOGTERM
, FR_DIALOGTERM
},
688 {I_FR_DOWN
, FR_DOWN
},
689 {I_FR_ENABLEHOOK
, FR_ENABLEHOOK
},
690 {I_FR_ENABLETEMPLATE
, FR_ENABLETEMPLATE
},
691 {I_FR_ENABLETEMPLATEHANDLE
, FR_ENABLETEMPLATEHANDLE
},
692 {I_FR_FINDNEXT
, FR_FINDNEXT
},
693 {I_FR_HIDEMATCHCASE
, FR_HIDEMATCHCASE
},
694 {I_FR_HIDEWHOLEWORD
, FR_HIDEWHOLEWORD
},
695 {I_FR_HIDEUPDOWN
, FR_HIDEUPDOWN
},
696 {I_FR_MATCHCASE
, FR_MATCHCASE
},
697 {I_FR_NOMATCHCASE
, FR_NOMATCHCASE
},
698 {I_FR_NOUPDOWN
, FR_NOUPDOWN
},
699 {I_FR_NOWHOLEWORD
, FR_NOWHOLEWORD
},
700 {I_FR_REPLACE
, FR_REPLACE
},
701 {I_FR_REPLACEALL
, FR_REPLACEALL
},
702 {I_FR_SHOWHELP
, FR_SHOWHELP
},
703 {I_FR_WHOLEWORD
, FR_WHOLEWORD
},
707 return mwcd_Setup(hWnd
, uMsg
, wParam
, lParam
, flagTable
, &frS
.Flags
);
710 static INT_PTR CALLBACK
mwcd_PrintSetup(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
712 static struct FlagTableEntry flagTable
[] = {
713 {I_PD_ALLPAGES
, PD_ALLPAGES
},
714 {I_PD_COLLATE
, PD_COLLATE
},
715 {I_PD_DISABLEPRINTTOFILE
, PD_DISABLEPRINTTOFILE
},
716 {I_PD_ENABLEPRINTHOOK
, PD_ENABLEPRINTHOOK
},
717 {I_PD_ENABLEPRINTTEMPLATE
, PD_ENABLEPRINTTEMPLATE
},
718 {I_PD_ENABLEPRINTTEMPLATEHANDLE
, PD_ENABLEPRINTTEMPLATEHANDLE
},
719 {I_PD_ENABLESETUPHOOK
, PD_ENABLESETUPHOOK
},
720 {I_PD_ENABLESETUPTEMPLATE
, PD_ENABLESETUPTEMPLATE
},
721 {I_PD_ENABLESETUPTEMPLATEHANDLE
, PD_ENABLESETUPTEMPLATEHANDLE
},
722 {I_PD_HIDEPRINTTOFILE
, PD_HIDEPRINTTOFILE
},
723 {I_PD_NOPAGENUMS
, PD_NOPAGENUMS
},
724 {I_PD_NOSELECTION
, PD_NOSELECTION
},
725 {I_PD_NOWARNING
, PD_NOWARNING
},
726 {I_PD_PAGENUMS
, PD_PAGENUMS
},
727 {I_PD_PRINTSETUP
, PD_PRINTSETUP
},
728 {I_PD_PRINTTOFILE
, PD_PRINTTOFILE
},
729 {I_PD_RETURNDC
, PD_RETURNDC
},
730 {I_PD_RETURNDEFAULT
, PD_RETURNDEFAULT
},
731 {I_PD_RETURNIC
, PD_RETURNIC
},
732 {I_PD_SELECTION
, PD_SELECTION
},
733 {I_PD_SHOWHELP
, PD_SHOWHELP
},
734 {I_PD_USEDEVMODECOPIES
, PD_USEDEVMODECOPIES
},
738 return mwcd_Setup(hWnd
, uMsg
, wParam
, lParam
, flagTable
, &pd
.Flags
);
741 static INT_PTR CALLBACK
mwcd_PageSetup(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
743 static struct FlagTableEntry flagTable
[] = {
744 {I_PSD_DEFAULTMINMARGINS
, PSD_DEFAULTMINMARGINS
},
745 {I_PSD_DISABLEMARGINS
, PSD_DISABLEMARGINS
},
746 {I_PSD_DISABLEORIENTATION
, PSD_DISABLEORIENTATION
},
747 {I_PSD_DISABLEPAGEPAINTING
, PSD_DISABLEPAGEPAINTING
},
748 {I_PSD_DISABLEPAPER
, PSD_DISABLEPAPER
},
749 {I_PSD_DISABLEPRINTER
, PSD_DISABLEPRINTER
},
750 {I_PSD_ENABLEPAGEPAINTHOOK
, PSD_ENABLEPAGEPAINTHOOK
},
751 {I_PSD_ENABLEPAGESETUPHOOK
, PSD_ENABLEPAGESETUPHOOK
},
752 {I_PSD_ENABLEPAGESETUPTEMPLATE
, PSD_ENABLEPAGESETUPTEMPLATE
},
753 {I_PSD_ENABLEPAGESETUPTEMPLATEHANDLE
, PSD_ENABLEPAGESETUPTEMPLATEHANDLE
},
754 {I_PSD_INHUNDREDTHSOFMILLIMETERS
, PSD_INHUNDREDTHSOFMILLIMETERS
},
755 {I_PSD_INTHOUSANDTHSOFINCHES
, PSD_INTHOUSANDTHSOFINCHES
},
756 {I_PSD_INWININIINTLMEASURE
, PSD_INWININIINTLMEASURE
},
757 {I_PSD_MARGINS
, PSD_MARGINS
},
758 {I_PSD_MINMARGINS
, PSD_MINMARGINS
},
759 {I_PSD_NONETWORKBUTTON
, PSD_NONETWORKBUTTON
},
760 {I_PSD_NOWARNING
, PSD_NOWARNING
},
761 {I_PSD_RETURNDEFAULT
, PSD_RETURNDEFAULT
},
762 {I_PSD_SHOWHELP
, PSD_SHOWHELP
},
766 return mwcd_Setup(hWnd
, uMsg
, wParam
, lParam
, flagTable
, &psd
.Flags
);
769 static INT_PTR CALLBACK
mwcd_FileSetup(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
771 static struct FlagTableEntry flagTable
[] = {
772 {I_OFN_ALLOWMULTISELECT
, OFN_ALLOWMULTISELECT
},
773 {I_OFN_CREATEPROMPT
, OFN_CREATEPROMPT
},
774 {I_OFN_ENABLEHOOK
, OFN_ENABLEHOOK
},
775 {I_OFN_ENABLETEMPLATE
, OFN_ENABLETEMPLATE
},
776 {I_OFN_ENABLETEMPLATEHANDLE
, OFN_ENABLETEMPLATEHANDLE
},
777 {I_OFN_EXTENSIONDIFFERENT
, OFN_EXTENSIONDIFFERENT
},
778 {I_OFN_FILEMUSTEXIST
, OFN_FILEMUSTEXIST
},
779 {I_OFN_HIDEREADONLY
, OFN_HIDEREADONLY
},
780 {I_OFN_NOCHANGEDIR
, OFN_NOCHANGEDIR
},
781 {I_OFN_NOREADONLYRETURN
, OFN_NOREADONLYRETURN
},
782 {I_OFN_NOTESTFILECREATE
, OFN_NOTESTFILECREATE
},
783 {I_OFN_NOVALIDATE
, OFN_NOVALIDATE
},
784 {I_OFN_OVERWRITEPROMPT
, OFN_OVERWRITEPROMPT
},
785 {I_OFN_PATHMUSTEXIST
, OFN_PATHMUSTEXIST
},
786 {I_OFN_READONLY
, OFN_READONLY
},
787 {I_OFN_SHAREAWARE
, OFN_SHAREAWARE
},
788 {I_OFN_SHOWHELP
, OFN_SHOWHELP
},
792 return mwcd_Setup(hWnd
, uMsg
, wParam
, lParam
, flagTable
, &ofn
.Flags
);
795 static INT_PTR CALLBACK
mwcd_About(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
801 case WM_INITDIALOG
: return TRUE
; /* let WINDOWS set the focus. */
802 case WM_COMMAND
: EndDialog(hWnd
, 0); return TRUE
; /* it's our OK button. */
803 default: return FALSE
; /* it's something else, let Windows worry about it */
808 * These functions call custom dialog boxes (resource-loaded, if I do this right).
809 * Right now they don't do a heck of a lot, but at some future time
810 * they will muck about with the flags (and be loaded from the flags) of
811 * the CommDlg structures initialized by the mwi_xxx() routines.
814 static void mwc_ColorSetup(HWND hWnd
)
816 int r
= DialogBox(g_hInstance
, "Color_Flags_Dialog", hWnd
, (DLGPROC
) mwcd_ColorSetup
);
817 if(r
< 0) { MessageBox(hWnd
, "Failure opening Color_Flags_Dialog box", "Error", MB_ICONASTERISK
|MB_OK
); }
820 static void mwc_FontSetup(HWND hWnd
)
822 int r
= DialogBox(g_hInstance
, "Font_Flags_Dialog", hWnd
, (DLGPROC
) mwcd_FontSetup
);
823 if(r
< 0) { MessageBox(hWnd
, "Failure opening Font_Flags_Dialog box", "Error", MB_ICONASTERISK
|MB_OK
); }
826 static void mwc_FindReplaceSetup(HWND hWnd
)
828 int r
= DialogBox(g_hInstance
, "Find_Flags_Dialog", hWnd
, (DLGPROC
) mwcd_FindSetup
);
829 if(r
< 0) { MessageBox(hWnd
, "Failure opening Find_Flags_Dialog box", "Error", MB_ICONASTERISK
|MB_OK
); }
832 static void mwc_PrintSetup(HWND hWnd
)
834 int r
= DialogBox(g_hInstance
, "Print_Flags_Dialog", hWnd
, (DLGPROC
) mwcd_PrintSetup
);
835 if(r
< 0) { MessageBox(hWnd
, "Failure opening Print_Flags_Dialog box", "Error", MB_ICONASTERISK
|MB_OK
); }
838 static void mwc_PageSetup(HWND hWnd
)
840 int r
= DialogBox(g_hInstance
, "PageSetup_Flags_Dialog", hWnd
, (DLGPROC
) mwcd_PageSetup
);
841 if(r
< 0) { MessageBox(hWnd
, "Failure opening PageSetup_Flags_Dialog box", "Error", MB_ICONASTERISK
|MB_OK
); }
844 static void mwc_FileSetup(HWND hWnd
)
846 int r
= DialogBox(g_hInstance
, "File_Flags_Dialog", hWnd
, (DLGPROC
) mwcd_FileSetup
);
847 if(r
< 0) { MessageBox(hWnd
, "Failure opening File_Flags_Dialog box", "Error", MB_ICONASTERISK
|MB_OK
); }
851 * Main window message dispatcher. Here the messages get chewed up
852 * and spit out. Note the ugly hack for the modeless Find/Replace box;
853 * this looks like it was bolted on with hexhead screws and is now
854 * dangling from Windows like a loose muffler. Sigh.
857 static LRESULT CALLBACK EXPORT
mainWindowDispatcher(
865 if(uMsg
== findMessageId
) {
866 FINDREPLACE
* lpfr
= (FINDREPLACE
*) lParam
;
867 if(lpfr
->Flags
& FR_DIALOGTERM
) {
868 MessageBox(hWnd
, "User closing us down.", "Down", MB_OK
);
871 else if (lpfr
->Flags
& FR_FINDNEXT
) {
872 MessageBox(hWnd
, "Finding next occurrence.", "Findnext", MB_OK
);
874 else if (lpfr
->Flags
& FR_REPLACE
) {
875 MessageBox(hWnd
, "Replacing next occurrence.", "Replace", MB_OK
);
877 else if (lpfr
->Flags
& FR_REPLACEALL
) {
878 MessageBox(hWnd
, "Replacing all occurrences.", "Replace All", MB_OK
);
881 MessageBox(hWnd
, "Eh?", "Eh?", MB_OK
);
888 * this is always the first message...at least as far as
895 /* Well, draw something! */
896 paintMainWindow(hWnd
, uMsg
, wParam
, lParam
);
900 /* Uh oh. Eject! Eject! Eject! */
905 /* menu or accelerator pressed; do something. */
909 /* Uh oh. Eject! Eject! Eject! */
913 /* these actually call the Common Dialogs. */
916 mw_ColorSetup(hWnd
); return 1;
919 mw_FontSetup(hWnd
); return 1;
922 mw_FindSetup(hWnd
); return 1;
925 mw_ReplaceSetup(hWnd
); return 1;
928 mw_OpenSetup(hWnd
); return 1;
931 mw_SaveSetup(hWnd
); return 1;
934 mw_PSetupSetup(hWnd
); return 1;
937 mw_PrintSetup(hWnd
); return 1;
940 mw_PageSetup(hWnd
); return 1;
943 * these set up various flags and values in the Common Dialog
944 * data structures, which are currently stored in static memory.
945 * The control dialogs themselves are resources as well.
949 mwc_FileSetup(hWnd
); return 1;
952 mwc_ColorSetup(hWnd
); return 1;
955 mwc_FontSetup(hWnd
); return 1;
957 case CM_F_FINDREPLACE
:
958 mwc_FindReplaceSetup(hWnd
); return 1;
961 mwc_PrintSetup(hWnd
); return 1;
964 mwc_PageSetup(hWnd
); return 1;
967 DialogBox(g_hInstance
, "AboutDialog", hWnd
, (DLGPROC
) mwcd_About
);
970 DialogBox(g_hInstance
, "UsageDialog", hWnd
, (DLGPROC
) mwcd_About
);
971 /* return value? *What* return value? */
980 return DefWindowProc(hWnd
, uMsg
, wParam
, lParam
);
985 /* Class registration. One might call this a Windowsism. */
987 static int registerMainWindowClass(HINSTANCE hInstance
)
991 wndClass
.style
= CS_HREDRAW
|CS_VREDRAW
;
992 wndClass
.lpfnWndProc
= mainWindowDispatcher
;
993 wndClass
.cbClsExtra
= 0;
994 wndClass
.cbWndExtra
= 0;
995 wndClass
.hInstance
= hInstance
;
997 wndClass
.hIcon
= LoadIcon(hInstance
, "whello");
998 wndClass
.hCursor
= LoadCursor(hInstance
, IDC_ARROW
);
1001 wndClass
.hCursor
= 0;
1002 wndClass
.hbrBackground
= (HBRUSH
) GetStockObject(WHITE_BRUSH
);
1003 wndClass
.lpszMenuName
= menuName
;
1004 wndClass
.lpszClassName
= className
;
1006 return RegisterClass(&wndClass
);
1010 * Another Windowsism; this one's not too bad, as it compares
1011 * favorably with CreateWindow() in X (mucking about with X Visuals
1012 * can get messy; at least here we don't have to worry about that).
1015 static HWND
createMainWindow(HINSTANCE hInstance
, int show
)
1019 hWnd
= CreateWindow(
1020 className
, /* classname */
1021 windowName
, /* windowname/title */
1022 WS_OVERLAPPEDWINDOW
, /* dwStyle */
1025 CW_USEDEFAULT
, /* width */
1026 CW_USEDEFAULT
, /* height */
1027 0, /* parent window */
1029 hInstance
, /* instance */
1030 0 /* passthrough for MDI */
1033 if(hWnd
==0) return 0;
1035 ShowWindow(hWnd
, show
);
1041 static int messageLoop(HINSTANCE hInstance
, HWND hWnd
)
1048 while(GetMessage(&msg
, 0, 0, 0)) {
1049 TranslateMessage(&msg
);
1050 DispatchMessage(&msg
);
1057 * Oh, did we tell you that main() isn't the name of the
1058 * thing called in a Win16/Win32 app? And then there are
1059 * the lack of argument lists, the necessity (at least in Win16)
1060 * of having to deal with class registration exactly once (as the
1061 * app may be run again), and some other bizarre holdovers from
1062 * Windows 3.x days. But hey, Solitaire still works.
1066 HINSTANCE hInstance
, HINSTANCE hPrevInstance
,
1067 LPSTR lpszCmdLine
, int nCmdShow
1074 strcpy(ofn_result
, "--- not yet set ---");
1076 if(hPrevInstance
==0) {
1077 if(!registerMainWindowClass(hInstance
))
1081 g_hInstance
= hInstance
;
1083 hWnd
= createMainWindow(hInstance
,nCmdShow
);
1087 return messageLoop(hInstance
, hWnd
);
1090 /* And now the end of the program. Enjoy. */
1093 * (c) 1999-2000 Eric Williams. Rights as specified under the WINE
1094 * License. Don't hoard code; share it!