1 /*
2 * Copyright (c) 1999-2000 Eric Williams.
3 *
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.
8 *
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.
13 *
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
17 */
18
19 /*
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.
25 */
26
27 /*
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. :-)
31 */
32
33 #define NONAMELESSUNION
34 #define NONAMELESSSTRUCT
35
36 #include <windows.h>
37 #include <commdlg.h>
38 #include <stdio.h>
39 #include <string.h>
40 #include "cmdlgtst.h"
41
42 #include <wine/debug.h>
43
44 WINE_DEFAULT_DEBUG_CHANNEL(cmdlgtst);
45
46 /*
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
52 * one bit.
53 */
54
55 /*
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}.
59 */
60
61 struct FlagTableEntry {
62 int ft_id;
63 unsigned long ft_bit;
64 };
65
66 #define EXPORT
67
68 static const char menuName[] = "CmdlgtstMenu";
69 static const char className[] = "CmdlgtstClass";
70 static const char windowName[] = "Cmdlgtst Window";
71
72 /*
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.)
76 */
77
78 static HINSTANCE g_hInstance;
79
80 /*
81 * global CommDlg data structures for modals. These are placed here
82 * so that the custom dialog boxes can get at them.
83 */
84
85 static PAGESETUPDLG psd;
86 static PRINTDLG pd;
87 static COLORREF cc_cr[16];
88 static CHOOSECOLOR cc;
89 static LOGFONT cf_lf;
90 static CHOOSEFONT cf;
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;
95
96 /* Stuff for find and replace. These are modeless, so I have to put them here. */
97
98 static HWND findDialogBox = 0;
99 static UINT findMessageId = 0;
100
101 static FINDREPLACE frS;
102 static char fromstring[1024], tostring[1024];
103
104 /* Stuff for the drawing of the window(s). I put them here for convenience. */
105
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 */
109
110 /* Utility routines. */
111
112 static void nyi(HWND hWnd)
113 {
114 /* "Hi there! I'm not yet implemented!" */
115 MessageBox(hWnd, "Not yet implemented!", "NYI", MB_ICONEXCLAMATION | MB_OK);
116 }
117
118 #if 0
119 static UINT CALLBACK dummyfnHook(HWND hWnd, UINT msg, UINT wParam, UINT lParam)
120 {
121 /*
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."
124 */
125
126 (void) hWnd;
127 (void) msg;
128 (void) wParam;
129 (void) lParam;
130
131 WINE_TRACE("dummyfnhook\n"); /* visible under Wine, but Windows probably won't see it! */
132
133 return 0;
134 }
135 #endif
136
137 /*
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.
142 */
143
144 static void mwi_Print(HWND hWnd)
145 {
146 pd.lStructSize = sizeof(PRINTDLG);
147 pd.hwndOwner = hWnd;
148 pd.hDevMode = 0;
149 pd.hDevNames = 0;
150 pd.hDC = 0;
151 pd.Flags = 0;
152 pd.nMinPage = 1;
153 pd.nMaxPage = 100;
154 pd.hInstance = g_hInstance;
155 pd.lCustData = 0;
156 pd.lpfnPrintHook = 0;
157 pd.lpfnSetupHook = 0;
158 pd.lpPrintTemplateName = 0;
159 pd.lpSetupTemplateName = 0;
160 pd.hPrintTemplate = 0;
161 pd.hSetupTemplate = 0;
162 }
163
164 static void mwi_PageSetup(HWND hWnd)
165 {
166 ZeroMemory(&psd, sizeof(PAGESETUPDLG));
167 psd.lStructSize = sizeof(PAGESETUPDLG);
168 psd.hwndOwner = hWnd;
169
170 }
171
172 static void mwi_Color(HWND hWnd)
173 {
174 int i;
175
176 /* there's probably an init call for this, somewhere. */
177
178 for(i=0;i<16;i++)
179 cc_cr[i] = RGB(0,0,0);
180
181 cc.lStructSize = sizeof(CHOOSECOLOR);
182 cc.hwndOwner = hWnd;
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;
186 cc.Flags = 0;
187 cc.lCustData = 0;
188 cc.lpfnHook = 0;
189 cc.lpTemplateName = 0;
190 }
191
192 static void mwi_Font(HWND hWnd)
193 {
194 cf.lStructSize = sizeof(CHOOSEFONT);
195 cf.hwndOwner = hWnd;
196 cf.hDC = 0;
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?? */
200 cf.lCustData = 0;
201 cf.lpfnHook = 0;
202 cf.lpTemplateName = 0;
203 cf.hInstance = g_hInstance;
204 cf.lpszStyle = 0;
205 cf.nFontType = 0;
206 cf.nSizeMin = 8;
207 cf.nSizeMax = 72;
208
209 cf_lf.lfHeight = -18; /* this can be positive or negative, but negative is usually used. */
210 }
211
212 static void mwi_File(HWND hWnd)
213 {
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";
227 ofn.Flags = 0;
228 ofn.nFileOffset = 0;
229 ofn.nFileExtension = 0;
230 ofn.lpstrDefExt = "*";
231 ofn.lCustData = 0;
232 ofn.lpfnHook = 0;
233 ofn.lpTemplateName = 0;
234
235 ofn_result[0] = '\0';
236 }
237
238 static void mwi_FindReplace(HWND hWnd)
239 {
240 frS.lStructSize = sizeof(FINDREPLACE);
241 frS.hwndOwner = hWnd;
242 frS.hInstance = g_hInstance;
243 frS.Flags = FR_DOWN;
244 frS.lpstrFindWhat = fromstring;
245 frS.lpstrReplaceWith = tostring;
246 frS.wFindWhatLen = sizeof(fromstring);
247 frS.wReplaceWithLen = sizeof(tostring);
248 frS.lCustData = 0;
249 frS.lpfnHook = 0;
250 frS.lpTemplateName = 0;
251
252 fromstring[0] = '\0';
253 tostring[0] = '\0';
254 findMessageId = RegisterWindowMessage(FINDMSGSTRING);
255 }
256
257 static void mwi_InitAll(HWND hWnd)
258 {
259 mwi_Print(hWnd);
260 mwi_Font(hWnd);
261 mwi_Color(hWnd);
262 mwi_File(hWnd);
263 mwi_FindReplace(hWnd);
264 mwi_PageSetup(hWnd);
265 }
266
267 /*
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.
274 */
275
276 static void paintMainWindow(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
277 {
278 PAINTSTRUCT ps;
279 RECT rect;
280 HPEN pen;
281 HFONT font;
282 HBRUSH brush;
283
284 (void) iMessage;
285 (void) wParam;
286 (void) lParam;
287
288 /* Commence painting! */
289
290 BeginPaint(hWnd, &ps);
291 GetClientRect(hWnd, &rect);
292
293 pen = SelectObject(ps.hdc, CreatePen(0, 0, fgColor));
294 brush = SelectObject(ps.hdc, CreateSolidBrush(bgColor));
295 font = SelectObject(ps.hdc, CreateFontIndirect(&cf_lf));
296
297 /*
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);
302 */
303 Rectangle(ps.hdc, rect.left, rect.top, rect.right, rect.bottom);
304
305 /* now draw a couple of lines, just for giggles. */
306
307 MoveToEx(ps.hdc, rect.left, rect.top, NULL);
308 LineTo(ps.hdc, rect.right, rect.bottom);
309 MoveToEx(ps.hdc, rect.left, rect.bottom, NULL);
310 LineTo(ps.hdc, rect.right, rect.top);
311
312 /* draw some text */
313
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);
317
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));
321
322 /*
323 * set the HDC back to the old pen and brush,
324 * and delete the newly created objects.
325 */
326
327 pen = SelectObject(ps.hdc, pen);
328 DeleteObject(pen);
329 brush = SelectObject(ps.hdc, brush);
330 DeleteObject(brush);
331 font = SelectObject(ps.hdc, font);
332 DeleteObject(font);
333
334 EndPaint(hWnd, &ps);
335 }
336
337 /*
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.
342 */
343
344 static void mw_checkError(HWND hWnd, BOOL explicitcancel)
345 {
346 DWORD errval = CommDlgExtendedError();
347 if(errval) {
348 char errbuf[80];
349
350 sprintf(errbuf, "CommDlgExtendedError(): error code %d (0x%x)", errval, errval);
351 MessageBox(hWnd, errbuf, "Error", MB_ICONEXCLAMATION | MB_OK);
352 }
353 else {
354 if(explicitcancel) MessageBox(hWnd, "Nope, user canceled it.", "No", MB_OK);
355 }
356 }
357
358 /*
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.
363 */
364
365 static void mw_ColorSetup(HWND hWnd)
366 {
367 if(ChooseColor(&cc)) {
368 RECT rect;
369
370 GetClientRect(hWnd, &rect);
371 InvalidateRect(hWnd, &rect, FALSE);
372 bgColor = cc.rgbResult;
373 }
374 else mw_checkError(hWnd, FALSE);
375 }
376
377 static void mw_FontSetup(HWND hWnd)
378 {
379 if(ChooseFont(&cf)) {
380 RECT rect;
381 GetClientRect(hWnd, &rect);
382 InvalidateRect(hWnd, &rect, FALSE);
383 txtColor = cf.rgbColors;
384 }
385 else mw_checkError(hWnd, FALSE);
386 }
387
388 static void mw_FindSetup(HWND hWnd)
389 {
390 if(findDialogBox == 0) {
391 findDialogBox = FindText(&frS);
392 if(findDialogBox==0) mw_checkError(hWnd,TRUE);
393 }
394 }
395
396 static void mw_ReplaceSetup(HWND hWnd)
397 {
398 if(findDialogBox == 0) {
399 findDialogBox = ReplaceText(&frS);
400 if(findDialogBox==0) mw_checkError(hWnd,TRUE);
401 }
402 }
403
404 static void mw_OpenSetup(HWND hWnd)
405 {
406 if(GetOpenFileName(&ofn)) {
407 RECT rect;
408 GetClientRect(hWnd, &rect);
409 InvalidateRect(hWnd, &rect, FALSE);
410 }
411 else mw_checkError(hWnd,FALSE);
412 }
413
414 static void mw_SaveSetup(HWND hWnd)
415 {
416 if(GetSaveFileName(&ofn)) {
417 RECT rect;
418 GetClientRect(hWnd, &rect);
419 InvalidateRect(hWnd, &rect, FALSE);
420 }
421 else mw_checkError(hWnd,FALSE);
422 }
423
424 /*
425 * Can't find documentation in Borland for this one. Does it
426 * exist at all, or is it merely a subdialog of Print?
427 */
428
429 static void mw_PSetupSetup(HWND hWnd)
430 {
431 nyi(hWnd);
432 }
433
434 static void mw_PrintSetup(HWND hWnd)
435 {
436 if(PrintDlg(&pd)) {
437 /*
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.
441 */
442
443 #if 0
444 Escape(tmp.hDC, STARTDOC, 8, "Test-Doc", NULL);
445 #endif
446
447 /* Print text and rectangle */
448
449 #if 0
450 TextOut(tmp.hDC, 50, 50, "Common Dialog Test Page", 23);
451
452 Rectangle(tmp.hDC, 50, 90, 625, 105);
453 Escape(tmp.hDC, NEWFRAME, 0, NULL, NULL);
454 Escape(tmp.hDC, ENDDOC, 0, NULL, NULL);
455 DeleteDC(tmp.hDC);
456 #endif
457 if (pd.hDevMode != 0)
458 GlobalFree(pd.hDevMode);
459 if (pd.hDevNames != 0)
460 GlobalFree(pd.hDevNames);
461
462 pd.hDevMode = 0;
463 pd.hDevNames = 0;
464
465 MessageBox(hWnd, "Success.", "Yes", MB_OK);
466 }
467 else mw_checkError(hWnd,TRUE);
468 }
469
470 #define OF(fn, fi, fl) \
471 if(dm->dmFields & fl){ \
472 WINE_TRACE(" %s =%hd\n", (fn), dm->fi); \
473 } else \
474 WINE_TRACE(" %s NOT SET!\n", fn);
475
476
477 static void mw_PageSetup(HWND hWnd)
478 {
479 DEVMODEA *dm;
480 DEVNAMES *dn;
481 CHAR tmplnm[30] = "PAGESETUPDLGORD_CSTM";
482
483 if(psd.Flags & PSD_ENABLEPAGESETUPTEMPLATE)
484 psd.lpPageSetupTemplateName = tmplnm;
485 psd.hInstance = g_hInstance;
486
487 if(PageSetupDlg(&psd)){
488 dm = GlobalLock(psd.hDevMode);
489 if(dm) {
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", u1.s1.dmScale, DM_SCALE);
502 OF("dmCopies", u1.s1.dmCopies, DM_COPIES);
503 OF("dmDefaultSource", u1.s1.dmDefaultSource,DM_DEFAULTSOURCE);
504 OF("dmPrintQuality", u1.s1.dmPrintQuality, DM_PRINTQUALITY);
505 if(dm->dmFields & DM_POSITION)
506 WINE_TRACE(" dmPosition(%d, %d)\n", dm->u1.s2.dmPosition.x, dm->u1.s2.dmPosition.y);
507 else
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);
516 else
517 WINE_TRACE(" dmFormName NOT SET!\n");
518 if(dm->dmFields & DM_ICMMETHOD)
519 WINE_TRACE(" dmICMMethod = %#x\n", dm->dmICMMethod);
520 else
521 WINE_TRACE(" dmICMMethod NOT SET!\n");
522
523 GlobalUnlock(psd.hDevMode);
524 }
525 else
526 WINE_TRACE("dm == NULL\n");
527
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);
532
533 WINE_TRACE("\nDEVNAMES struct\n");
534 dn = GlobalLock(psd.hDevNames);
535 if(dn){
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);
541 }else
542 WINE_TRACE(" dn == NULL!\n");
543 WINE_TRACE("End.\n");
544
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);
551
552 psd.hDevMode = NULL;
553 psd.hDevNames = NULL;
554 psd.hPageSetupTemplate = NULL;
555
556 MessageBox(hWnd, "Success.", "Yes", MB_OK);
557 } mw_checkError(hWnd, FALSE);
558 }
559
560 /********************************************************************************************************/
561 /*
562 * Some support functions for the custom dialog box handlers.
563 * In particular, we have to set things properly, and get the flags back.
564 */
565
566 static void mwcd_SetFlags(HWND hWnd, struct FlagTableEntry *table, DWORD flags)
567 {
568 int i;
569
570 for(i=0; table[i].ft_id != IDOK; i++)
571 {
572 CheckDlgButton(hWnd, table[i].ft_id,(table[i].ft_bit & flags) ? 1 : 0);
573 }
574 }
575
576 static DWORD mwcd_GetFlags(HWND hWnd, struct FlagTableEntry * table)
577 {
578 int i;
579 unsigned long l = 0;
580
581 for(i=0; table[i].ft_id != IDOK; i++)
582 {
583 if(IsDlgButtonChecked(hWnd, table[i].ft_id) == 1)
584 l |= table[i].ft_bit;
585 }
586
587 return l;
588 }
589
590 /*
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.
595 */
596
597 static INT_PTR mwcd_Setup(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
598 struct FlagTableEntry * table, DWORD* flags)
599 {
600 (void) lParam;
601
602 switch(uMsg)
603 {
604 case WM_INITDIALOG:
605 /* Set the controls properly. */
606
607 mwcd_SetFlags(hWnd, table, *flags);
608
609 return TRUE; /* I would return FALSE if I explicitly called SetFocus(). */
610 /* As usual, Windows is weird. */
611
612 case WM_COMMAND:
613 switch(wParam) {
614 case IDOK:
615 *flags = mwcd_GetFlags(hWnd, table);
616 EndDialog(hWnd,1);
617 break;
618
619 case IDCANCEL:
620 EndDialog(hWnd,0);
621 break;
622
623 case CM_R_HELP:
624 break; /* help? We don't need no steenkin help! */
625
626 default:
627 break; /* eat the message */
628 }
629 return TRUE;
630
631 default:
632 return FALSE; /* since I don't process this particular message */
633 }
634 }
635
636 static INT_PTR CALLBACK mwcd_ColorSetup(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
637 {
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},
646 {IDOK, 0},
647 };
648
649 return mwcd_Setup(hWnd, uMsg, wParam, lParam, flagTable, &cc.Flags);
650 }
651
652 static INT_PTR CALLBACK mwcd_FontSetup(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
653 {
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},
677 {IDOK, 0},
678 };
679
680 return mwcd_Setup(hWnd, uMsg, wParam, lParam, flagTable, &cf.Flags);
681 }
682
683 static INT_PTR CALLBACK mwcd_FindSetup(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
684 {
685
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},
704 {IDOK, 0},
705 };
706
707 return mwcd_Setup(hWnd, uMsg, wParam, lParam, flagTable, &frS.Flags);
708 }
709
710 static INT_PTR CALLBACK mwcd_PrintSetup(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
711 {
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},
735 {IDOK, 0},
736 };
737
738 return mwcd_Setup(hWnd, uMsg, wParam, lParam, flagTable, &pd.Flags);
739 }
740
741 static INT_PTR CALLBACK mwcd_PageSetup(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
742 {
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},
763 {IDOK, 0}
764 };
765
766 return mwcd_Setup(hWnd, uMsg, wParam, lParam, flagTable, &psd.Flags);
767 }
768
769 static INT_PTR CALLBACK mwcd_FileSetup(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
770 {
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},
789 {IDOK, 0},
790 };
791
792 return mwcd_Setup(hWnd, uMsg, wParam, lParam, flagTable, &ofn.Flags);
793 }
794
795 static INT_PTR CALLBACK mwcd_About(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
796 {
797 (void) wParam;
798 (void) lParam;
799
800 switch(uMsg) {
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 */
804 }
805 }
806
807 /*
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.
812 */
813
814 static void mwc_ColorSetup(HWND hWnd)
815 {
816 int r = DialogBox(g_hInstance, "Color_Flags_Dialog", hWnd, mwcd_ColorSetup);
817 if(r < 0) { MessageBox(hWnd, "Failure opening Color_Flags_Dialog box", "Error", MB_ICONASTERISK|MB_OK); }
818 }
819
820 static void mwc_FontSetup(HWND hWnd)
821 {
822 int r = DialogBox(g_hInstance, "Font_Flags_Dialog", hWnd, mwcd_FontSetup);
823 if(r < 0) { MessageBox(hWnd, "Failure opening Font_Flags_Dialog box", "Error", MB_ICONASTERISK|MB_OK); }
824 }
825
826 static void mwc_FindReplaceSetup(HWND hWnd)
827 {
828 int r = DialogBox(g_hInstance, "Find_Flags_Dialog", hWnd, mwcd_FindSetup);
829 if(r < 0) { MessageBox(hWnd, "Failure opening Find_Flags_Dialog box", "Error", MB_ICONASTERISK|MB_OK); }
830 }
831
832 static void mwc_PrintSetup(HWND hWnd)
833 {
834 int r = DialogBox(g_hInstance, "Print_Flags_Dialog", hWnd, mwcd_PrintSetup);
835 if(r < 0) { MessageBox(hWnd, "Failure opening Print_Flags_Dialog box", "Error", MB_ICONASTERISK|MB_OK); }
836 }
837
838 static void mwc_PageSetup(HWND hWnd)
839 {
840 int r = DialogBox(g_hInstance, "PageSetup_Flags_Dialog", hWnd, mwcd_PageSetup);
841 if(r < 0) { MessageBox(hWnd, "Failure opening PageSetup_Flags_Dialog box", "Error", MB_ICONASTERISK|MB_OK); }
842 }
843
844 static void mwc_FileSetup(HWND hWnd)
845 {
846 int r = DialogBox(g_hInstance, "File_Flags_Dialog", hWnd, mwcd_FileSetup);
847 if(r < 0) { MessageBox(hWnd, "Failure opening File_Flags_Dialog box", "Error", MB_ICONASTERISK|MB_OK); }
848 }
849
850 /*
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.
855 */
856
857 static LRESULT CALLBACK EXPORT mainWindowDispatcher(
858 HWND hWnd,
859 UINT uMsg,
860 WPARAM wParam,
861 LPARAM lParam
862 )
863 {
864
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);
869 findDialogBox = 0;
870 }
871 else if (lpfr->Flags & FR_FINDNEXT) {
872 MessageBox(hWnd, "Finding next occurrence.", "Findnext", MB_OK);
873 }
874 else if (lpfr->Flags & FR_REPLACE) {
875 MessageBox(hWnd, "Replacing next occurrence.", "Replace", MB_OK);
876 }
877 else if (lpfr->Flags & FR_REPLACEALL) {
878 MessageBox(hWnd, "Replacing all occurrences.", "Replace All", MB_OK);
879 }
880 else {
881 MessageBox(hWnd, "Eh?", "Eh?", MB_OK);
882 }
883 return 1;
884 }
885 else switch(uMsg) {
886 case WM_CREATE:
887 /*
888 * this is always the first message... at least as far
889 * as we are concerned.
890 */
891 mwi_InitAll(hWnd);
892 break;
893
894 case WM_PAINT:
895 /* Well, draw something! */
896 paintMainWindow(hWnd, uMsg, wParam, lParam);
897 break;
898
899 case WM_DESTROY:
900 /* Uh oh. Eject! Eject! Eject! */
901 PostQuitMessage(0);
902 break;
903
904 case WM_COMMAND:
905 /* menu or accelerator pressed; do something. */
906
907 switch(wParam) {
908 case CM_U_EXIT:
909 /* Uh oh. Eject! Eject! Eject! */
910 PostQuitMessage(0);
911 break;
912
913 /* these actually call the Common Dialogs. */
914
915 case CM_U_COLOR:
916 mw_ColorSetup(hWnd); return 1;
917
918 case CM_U_FONT:
919 mw_FontSetup(hWnd); return 1;
920
921 case CM_U_FIND:
922 mw_FindSetup(hWnd); return 1;
923
924 case CM_U_REPLACE:
925 mw_ReplaceSetup(hWnd); return 1;
926
927 case CM_U_OPEN:
928 mw_OpenSetup(hWnd); return 1;
929
930 case CM_U_SAVE:
931 mw_SaveSetup(hWnd); return 1;
932
933 case CM_U_PSETUP:
934 mw_PSetupSetup(hWnd); return 1;
935
936 case CM_U_PRINT:
937 mw_PrintSetup(hWnd); return 1;
938
939 case CM_U_PAGESETUP:
940 mw_PageSetup(hWnd); return 1;
941
942 /*
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.
946 */
947
948 case CM_F_FILE:
949 mwc_FileSetup(hWnd); return 1;
950
951 case CM_F_COLOR:
952 mwc_ColorSetup(hWnd); return 1;
953
954 case CM_F_FONT:
955 mwc_FontSetup(hWnd); return 1;
956
957 case CM_F_FINDREPLACE:
958 mwc_FindReplaceSetup(hWnd); return 1;
959
960 case CM_F_PRINT:
961 mwc_PrintSetup(hWnd); return 1;
962
963 case CM_F_PAGESETUP:
964 mwc_PageSetup(hWnd); return 1;
965
966 case CM_H_ABOUT:
967 DialogBox(g_hInstance, "AboutDialog", hWnd, mwcd_About);
968 return 1;
969 case CM_H_USAGE:
970 DialogBox(g_hInstance, "UsageDialog", hWnd, mwcd_About);
971 /* return value? *What* return value? */
972 return 1;
973
974 default:
975 nyi(hWnd); return 1;
976 }
977 break;
978
979 default:
980 return DefWindowProc(hWnd, uMsg, wParam, lParam);
981 }
982 return 0;
983 }
984
985 /* Class registration. One might call this a Windowsism. */
986
987 static int registerMainWindowClass(HINSTANCE hInstance)
988 {
989 WNDCLASS wndClass;
990
991 wndClass.style = CS_HREDRAW|CS_VREDRAW;
992 wndClass.lpfnWndProc = mainWindowDispatcher;
993 wndClass.cbClsExtra = 0;
994 wndClass.cbWndExtra = 0;
995 wndClass.hInstance = hInstance;
996 #if 0
997 wndClass.hIcon = LoadIcon(hInstance, "whello");
998 wndClass.hCursor = LoadCursor(hInstance, IDC_ARROW);
999 #endif
1000 wndClass.hIcon = 0;
1001 wndClass.hCursor = 0;
1002 wndClass.hbrBackground = GetStockObject(WHITE_BRUSH);
1003 wndClass.lpszMenuName = menuName;
1004 wndClass.lpszClassName = className;
1005
1006 return RegisterClass(&wndClass);
1007 }
1008
1009 /*
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).
1013 */
1014
1015 static HWND createMainWindow(HINSTANCE hInstance, int show)
1016 {
1017 HWND hWnd;
1018
1019 hWnd = CreateWindow(
1020 className, /* classname */
1021 windowName, /* windowname/title */
1022 WS_OVERLAPPEDWINDOW, /* dwStyle */
1023 0, /* x */
1024 0, /* y */
1025 CW_USEDEFAULT, /* width */
1026 CW_USEDEFAULT, /* height */
1027 0, /* parent window */
1028 0, /* menu */
1029 hInstance, /* instance */
1030 0 /* passthrough for MDI */
1031 );
1032
1033 if(hWnd==0) return 0;
1034
1035 ShowWindow(hWnd, show);
1036 UpdateWindow(hWnd);
1037
1038 return hWnd;
1039 }
1040
1041 static int messageLoop(HINSTANCE hInstance, HWND hWnd)
1042 {
1043 MSG msg;
1044
1045 (void) hInstance;
1046 (void) hWnd;
1047
1048 while(GetMessage(&msg, 0, 0, 0)) {
1049 TranslateMessage(&msg);
1050 DispatchMessage(&msg);
1051 }
1052
1053 return msg.wParam;
1054 }
1055
1056 /*
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.
1063 */
1064
1065 int PASCAL WinMain(
1066 HINSTANCE hInstance, HINSTANCE hPrevInstance,
1067 LPSTR lpszCmdLine, int nCmdShow
1068 )
1069 {
1070 HWND hWnd;
1071
1072 (void) lpszCmdLine;
1073
1074 strcpy(ofn_result, "--- not yet set ---");
1075
1076 if(hPrevInstance==0) {
1077 if(!registerMainWindowClass(hInstance))
1078 return -1;
1079 }
1080
1081 g_hInstance = hInstance;
1082
1083 hWnd = createMainWindow(hInstance,nCmdShow);
1084 if(hWnd == 0)
1085 return -1;
1086
1087 return messageLoop(hInstance, hWnd);
1088 }
1089
1090 /* And now the end of the program. Enjoy. */
1091
1092 /*
1093 * (c) 1999-2000 Eric Williams. Rights as specified under the WINE
1094 * License. Don't hoard code; share it!
1095 */
1096
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.