|
|
1.1 root 1: /***************************************************************************
2: * *
3: * MODULE : imagedit.c *
4: * *
5: * DESCRIPTION : Contains main entry-level routine for ImagEdit. *
6: * *
7: * FUNCTIONS : WinMain () - Program entry point. *
8: * *
9: * HISTORY : 3/14/89 - LR *
10: * *
11: ***************************************************************************/
12:
13: #include "imagedit.h"
14: #include "dialogs.h"
15: #include "ids.h"
16:
17: #include <string.h>
18: #include <stdlib.h>
19:
20: #include <commdlg.h>
21:
22:
23: /*
24: * External declarations for the Windows variables that contain
25: * command line information.
26: */
27: extern INT __argc;
28: extern CHAR **__argv;
29:
30:
31: STATICFN BOOL NEAR InitApplication(VOID);
32: STATICFN BOOL NEAR InitInstance(LPSTR lpCmdLine, INT cmdShow);
33: STATICFN VOID NEAR PenWinRegister(VOID);
34: STATICFN VOID NEAR ReadEnv(VOID);
35: STATICFN VOID NEAR WriteEnv(VOID);
36: STATICFN VOID NEAR SizeRibbons(HWND hwnd);
37: STATICFN VOID NEAR CleanUp(VOID);
38:
39: static RECT grcAppPos; // Saves the app's window pos.
40: static WORD gmsgHelp; // Registered help msg from commdlg.dll
41: static BOOL fStartAsIcon = FALSE; // TRUE if app is started minimized.
42:
43: /*
44: * Contains the address of the Pen Windows callback.
45: */
46: typedef VOID ( APIENTRY *LPFNPENWIN)(WORD, BOOL);
47: static LPFNPENWIN lpfnRegisterPenApp;
48:
49:
50:
51: /****************************************************************************
52: * *
53: * FUNCTION :int PASCAL WinMain(hInstance,hPrevInstance,lpCmdLine,cmdShow) *
54: * *
55: * PURPOSE :Serves as program entry point and contains message loop *
56: * *
57: ****************************************************************************/
58:
59: INT WINAPI
60: WinMain(
61: HINSTANCE hInstance,
62: HINSTANCE hPrevInstance,
63: LPSTR lpCmdLine,
64: INT nCmdShow)
65: {
66: MSG msg;
67:
68: DBGStackReport(TRUE);
69:
70: ghInst = hInstance;
71:
72: /* if this is the first instance then call initialization procedure */
73: if (!hPrevInstance) {
74: if (!InitApplication())
75: return FALSE;
76: }
77:
78: if (!InitInstance(lpCmdLine, nCmdShow))
79: return FALSE;
80:
81: while (GetMessage(&msg, NULL, 0, 0)) {
82: if (!ghwndColor || !IsDialogMessage(ghwndColor, &msg)) {
83: if (!ghwndPropBar || !IsDialogMessage(ghwndPropBar, &msg)) {
84: if (!TranslateAccelerator(ghwndMain, haccelTbl, &msg)) {
85: TranslateMessage(&msg);
86: DispatchMessage(&msg);
87: }
88: }
89: }
90: }
91:
92: DBGStackReport(FALSE);
93:
94: /*
95: * Return the value from PostQuitMessage.
96: */
97: return msg.wParam;
98: }
99:
100:
101:
102: /****************************************************************************
103: * *
104: * FUNCTION : InitApplication() *
105: * *
106: * PURPOSE : To create all ImagEdit's window classes, namely those of *
107: * the parent window, edit window, mode window and "palette" *
108: * window. *
109: * *
110: * RETURNS : TRUE if class registration was successful, FALSE otherwise *
111: * *
112: * SIDE EFFECTS: All class variables affected for all windows. *
113: * *
114: ****************************************************************************/
115:
116: STATICFN BOOL NEAR InitApplication(VOID)
117: {
118: WNDCLASS wc;
119:
120: /* assign values and register the parent window class */
121: wc.style = 0;
122: wc.lpfnWndProc = MainWndProc;
123: wc.cbClsExtra = 0;
124: wc.cbWndExtra = 0;
125: wc.hInstance = ghInst;
126: wc.hIcon = LoadIcon(ghInst, MAKEINTRESOURCE(IDICON_IMAGEDIT));
127: wc.hCursor = LoadCursor(NULL, IDC_ARROW);
128: wc.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE + 1);
129: wc.lpszMenuName = "imagedit";
130: wc.lpszClassName = szMainClass;
131: if (!RegisterClass(&wc))
132: return FALSE;
133:
134: wc.style = CS_DBLCLKS;
135: wc.lpfnWndProc = ColorBoxWndProc;
136: wc.cbClsExtra = 0;
137: wc.cbWndExtra = 0;
138: wc.hInstance = ghInst;
139: wc.hIcon = NULL;
140: wc.hCursor = LoadCursor(NULL, IDC_ARROW);
141: wc.hbrBackground = GetStockObject(LTGRAY_BRUSH);
142: wc.lpszMenuName = (LPSTR)NULL;
143: wc.lpszClassName = szColorBoxClass;
144: if (!RegisterClass(&wc))
145: return FALSE;
146:
147: wc.style = 0;
148: wc.lpfnWndProc = ColorLRWndProc;
149: wc.cbClsExtra = 0;
150: wc.cbWndExtra = 0;
151: wc.hInstance = ghInst;
152: wc.hIcon = NULL;
153: wc.hCursor = LoadCursor(NULL, IDC_ARROW);
154: wc.hbrBackground = GetStockObject(LTGRAY_BRUSH);
155: wc.lpszMenuName = (LPSTR)NULL;
156: wc.lpszClassName = szColorLRClass;
157: if (!RegisterClass(&wc))
158: return FALSE;
159:
160: wc.style = CS_DBLCLKS;
161: wc.lpfnWndProc = WorkWndProc;
162: wc.cbClsExtra = 0;
163: wc.cbWndExtra = 0;
164: wc.hInstance = ghInst;
165: wc.hIcon = NULL;
166: wc.hCursor = (HCURSOR)NULL;
167: wc.hbrBackground = (HBRUSH)NULL;
168: wc.lpszMenuName = (LPSTR)NULL;
169: wc.lpszClassName = szWorkClass;
170: if (!RegisterClass(&wc))
171: return FALSE;
172:
173: wc.style = 0;
174: wc.lpfnWndProc = ToolboxWndProc;
175: wc.cbClsExtra = 0;
176: wc.cbWndExtra = 0;
177: wc.hInstance = ghInst;
178: wc.hIcon = NULL;
179: wc.hCursor = LoadCursor(NULL, IDC_ARROW);
180: wc.hbrBackground = GetStockObject(LTGRAY_BRUSH);
181: wc.lpszMenuName = NULL;
182: wc.lpszClassName = szToolboxClass;
183: if (!RegisterClass(&wc))
184: return FALSE;
185:
186: wc.style = 0;
187: wc.lpfnWndProc = ToolBtnWndProc;
188: wc.cbClsExtra = 0;
189: wc.cbWndExtra = 0;
190: wc.hInstance = ghInst;
191: wc.hIcon = NULL;
192: wc.hCursor = LoadCursor(NULL, IDC_ARROW);
193: wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
194: wc.lpszMenuName = NULL;
195: wc.lpszClassName = szToolBtnClass;
196: if (!RegisterClass(&wc))
197: return FALSE;
198:
199: wc.style = 0;
200: wc.lpfnWndProc = ViewWndProc;
201: wc.cbClsExtra = 0;
202: wc.cbWndExtra = 0;
203: wc.hInstance = ghInst;
204: wc.hIcon = NULL;
205: wc.hCursor = LoadCursor(NULL, IDC_ARROW);
206: wc.hbrBackground = GetStockObject(LTGRAY_BRUSH);
207: wc.lpszMenuName = NULL;
208: wc.lpszClassName = szViewClass;
209: if (!RegisterClass(&wc))
210: return FALSE;
211:
212: return TRUE;
213: }
214:
215:
216:
217: /****************************************************************************
218: * *
219: * FUNCTION : InitInstance(lpCmdLine, cmdShow) *
220: * *
221: * PURPOSE : Load strings from resource file, make procedure instances *
222: * of all dialog functions, create ImagEdit's windows, color *
223: * "palettes", tool cursors and do a variety of other initial-*
224: * izations. Also prepare ImagEdit if started up from cmd line*
225: * with an argument. Some of these may be redundant, since a *
226: * lot of pBrush stuff has been retained here. *
227: * *
228: * SIDE EFFECTS: numerous *
229: * *
230: ****************************************************************************/
231:
232: STATICFN BOOL NEAR InitInstance(
233: LPSTR lpCmdLine,
234: INT cmdShow)
235: {
236: INT i;
237: INT iScrollBarWidth; /* width of vertical scrollbar */
238: INT iScrollBarHeight; /* height of horizontal scrollbar */
239: INT iScreenWid;
240: INT iScreenHgt; /* full screen width and height */
241: INT x;
242: INT y;
243: INT cx;
244: INT cy;
245: BOOL fMaximized;
246: RECT rcColor;
247: RECT rcClient;
248: RECT rc;
249: POINT pt;
250:
251: /*
252: * Load the "Out of memory." string now, since we may not be able to
253: * load it if/when it needs to be displayed.
254: */
255: ids(IDS_OUTOFMEMORY);
256:
257: /*
258: * Register for Pen Windows, if it is present.
259: */
260: PenWinRegister();
261:
262: /* register private ImagEdit clipboard format for icons and cursors */
263: if (!(ClipboardFormat = RegisterClipboardFormat("ImagEdit")))
264: return FALSE;
265:
266: if (!(haccelTbl = LoadAccelerators(ghInst, "imagedit")))
267: return FALSE;
268:
269: hcurWait = LoadCursor(NULL, IDC_WAIT);
270: gaTools[TOOL_PENCIL].hcur =
271: LoadCursor(ghInst, MAKEINTRESOURCE(IDCUR_PENCIL));
272: gaTools[TOOL_BRUSH].hcur =
273: LoadCursor(ghInst, MAKEINTRESOURCE(IDCUR_BRUSH));
274: gaTools[TOOL_SELECT].hcur =
275: gaTools[TOOL_LINE].hcur =
276: gaTools[TOOL_RECT].hcur =
277: gaTools[TOOL_SOLIDRECT].hcur =
278: gaTools[TOOL_CIRCLE].hcur =
279: gaTools[TOOL_SOLIDCIRCLE].hcur =
280: LoadCursor(ghInst, MAKEINTRESOURCE(IDCUR_CROSS));
281: gaTools[TOOL_FLOODFILL].hcur =
282: LoadCursor(ghInst, MAKEINTRESOURCE(IDCUR_FLOOD));
283: gaTools[TOOL_HOTSPOT].hcur =
284: LoadCursor(ghInst, MAKEINTRESOURCE(IDCUR_HOTSPOT));
285:
286: /*
287: * Select the default tool. Since the toolbox is not created yet,
288: * this just sets up some globals.
289: */
290: ToolboxSelectTool(TOOL_FIRST);
291:
292: /*
293: * Create a dark gray pen for use in borders later.
294: */
295: if (!(hpenDarkGray = CreatePen(PS_SOLID, 1, RGB_DARKGRAY)))
296: return FALSE;
297:
298: /*
299: * Initialize the two color palettes to the default colors.
300: */
301: for (i = 0; i < COLORSMAX; i++) {
302: gargbColor[i] = gargbDefaultColor[i];
303: gargbMono[i] = gargbDefaultMono[i];
304: }
305:
306: /* get some system parameters */
307: iScrollBarWidth = GetSystemMetrics(SM_CXVSCROLL);
308: iScrollBarHeight = GetSystemMetrics(SM_CYHSCROLL);
309: iScreenWid = GetSystemMetrics(SM_CXFULLSCREEN);
310: iScreenHgt = GetSystemMetrics(SM_CYFULLSCREEN);
311: gcyBorder = GetSystemMetrics(SM_CYBORDER);
312:
313: /*
314: * Build the help file name path. Assume the help file is in the
315: * same directory as the executable.
316: */
317: GetModuleFileName(ghInst, gszHelpFile, CCHMAXPATH);
318: *FileInPath(gszHelpFile) = '\0';
319: lstrcat(gszHelpFile, ids(IDS_HELPFILE));
320:
321: /*
322: * Register the message for help from the common dialogs.
323: */
324: gmsgHelp = RegisterWindowMessage(HELPMSGSTRING);
325:
326: /*
327: * Hook the message filter stream so that we can detect F1 keystrokes.
328: */
329: lpfnMsgFilterHookFunc =
330: MakeProcInstance((FARPROC)MsgFilterHookFunc, ghInst);
331: ghhkMsgFilter =
332: SetWindowsHook(WH_MSGFILTER, lpfnMsgFilterHookFunc);
333:
334: if (!ReadWindowPos(szAppPos, &x, &y, &cx, &cy, &fMaximized)) {
335: x = 2 * iScrollBarWidth;
336: y = iScrollBarHeight;
337: cx = min(iScreenWid - (4 * iScrollBarWidth), MAXDEFAULTAPPCX);
338: cy = min(iScreenHgt - (6 * iScrollBarHeight), MAXDEFAULTAPPCY);
339: fMaximized = FALSE;
340: }
341:
342: /* create parent window */
343: ghwndMain = CreateWindow(szMainClass, ids(IDS_PGMTITLE),
344: WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
345: x, y, cx, cy, NULL, NULL, ghInst, NULL);
346:
347: if (ghwndMain == NULL) {
348: Message(MSG_OUTOFMEMORY);
349: return FALSE;
350: }
351:
352: /*
353: * Read the preferences data saved in the ini file.
354: */
355: ReadEnv();
356:
357: /*
358: * Create the Toolbox and the View window (invisible).
359: */
360: ToolboxCreate();
361: ViewCreate();
362:
363: lpfnColorDlgProc = (WNDPROC)MakeProcInstance(
364: (FARPROC)ColorDlgProc, ghInst);
365: ghwndColor = CreateDialog(ghInst, MAKEINTRESOURCE(DID_COLOR),
366: ghwndMain, lpfnColorDlgProc);
367:
368: ghwndWork = CreateWindow(szWorkClass, NULL,
369: WS_CHILD | WS_BORDER,
370: 0, 0, 0, 0,
371: ghwndMain,
372: NULL, ghInst, NULL);
373:
374: /*
375: * Build the device table.
376: */
377: InitDeviceList();
378:
379: SetColorPalette(gnColors, giType, TRUE);
380: SetScreenColor(grgbScreenDefault);
381:
382: if (!ReadWindowPos(szColorPos, &x, &y, &cx, &cy, &fMaximized)) {
383: /*
384: * The previous position of the Color palette couldn't be found.
385: * Position the palette just below the bottom left corner of the
386: * client area of the editor, but make sure it is completely
387: * visible.
388: */
389: GetWindowRect(ghwndColor, &rcColor);
390: GetClientRect(ghwndMain, &rcClient);
391: cx = rcColor.right - rcColor.left;
392: cy = rcColor.bottom - rcColor.top;
393: pt.x = rcClient.left + (2 * PALETTEMARGIN);
394: pt.y = rcClient.bottom + (2 * PALETTEMARGIN);
395: ClientToScreen(ghwndMain, &pt);
396: SetRect(&rc, pt.x, pt.y, pt.x + cx, pt.y + cy);
397: FitRectToScreen(&rc);
398: x = rc.left;
399: y = rc.top;
400: }
401:
402: SetWindowPos(ghwndColor, NULL, x, y, 0, 0,
403: SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER);
404:
405: SetFileName(NULL);
406:
407: /*
408: * If the app was saved when maximized (and they didn't start it up
409: * with some kind of an option to have it minimized or in some
410: * other funny initial state from the shell), then cause it to
411: * be maximized when shown.
412: */
413: if (fMaximized && (cmdShow == SW_SHOWNORMAL || cmdShow == SW_SHOW))
414: cmdShow = SW_SHOWMAXIMIZED;
415:
416: ShowWindow(ghwndMain, cmdShow);
417: UpdateWindow(ghwndMain);
418:
419: /*
420: * Did the user start this app minimized from the program manager?
421: */
422: if (IsIconic(ghwndMain)) {
423: /*
424: * Set a flag. The showing of the palettes will be deferred
425: * until the app is restored.
426: */
427: fStartAsIcon = TRUE;
428: }
429: else {
430: /*
431: * If they had the Toolbox/Color Palette before, show them now.
432: */
433: ToolboxShow(gfShowToolbox);
434: ColorShow(gfShowColor);
435: }
436:
437: /*
438: * If there was a command line argument specified, try and open
439: * it as the initial file.
440: */
441: if (__argc > 1)
442: OpenCmdLineFile(__argv[1]);
443:
444: return TRUE;
445: }
446:
447:
448:
449: /************************************************************************
450: * PenWinRegister
451: *
452: * This function will register for Pen Windows, if it is present.
453: *
454: ************************************************************************/
455:
456: STATICFN VOID NEAR PenWinRegister(VOID)
457: {
458: HANDLE hmod;
459:
460: if (!(hmod = (HANDLE)GetSystemMetrics(SM_PENWINDOWS)))
461: return;
462:
463: if (lpfnRegisterPenApp =
464: (LPFNPENWIN)GetProcAddress(hmod, "RegisterPenApp"))
465: (*lpfnRegisterPenApp)(1, TRUE); // Be Pen-Enhanced!
466: }
467:
468:
469:
470: /************************************************************************
471: * MainWndProc
472: *
473: * Main window procedure for ImagEdit.
474: *
475: * History:
476: *
477: ************************************************************************/
478:
479: WINDOWPROC MainWndProc(
480: HWND hwnd,
481: UINT msg,
482: WPARAM wParam,
483: LPARAM lParam)
484: {
485: switch (msg) {
486: case WM_CREATE:
487: {
488: RECT rc;
489:
490: /*
491: * Create the PropBar window.
492: */
493: lpfnPropBarDlgProc = (WNDPROC)MakeProcInstance(
494: (FARPROC)PropBarDlgProc, ghInst);
495: CreateDialog(ghInst, MAKEINTRESOURCE(DID_PROPBAR), hwnd,
496: lpfnPropBarDlgProc);
497:
498: /*
499: * Save away its height for sizing later (like when
500: * the app is minimized then restored).
501: */
502: GetWindowRect(ghwndPropBar, &rc);
503: gcyPropBar = rc.bottom - rc.top;
504: }
505:
506: break;
507:
508: case WM_NCCALCSIZE:
509: /*
510: * Save away what is going to be the new window position.
511: */
512: if (!IsIconic(hwnd) && !IsZoomed(hwnd))
513: grcAppPos = *((LPRECT)lParam);
514:
515: /*
516: * Now let the DefWindowProc calculate the client area normally.
517: */
518: goto DoDefault;
519:
520: case WM_ACTIVATE:
521: /*
522: * If the main window is getting activated, there is no
523: * currently active dialog.
524: */
525: if (LOWORD(wParam))
526: gidCurrentDlg = 0;
527:
528: goto DoDefault;
529:
530: case WM_INITMENU:
531: if (GetMenu(ghwndMain) == (HMENU)wParam)
532: InitMenu((HMENU)wParam);
533:
534: break;
535:
536: case WM_COMMAND:
537: MenuCmd(LOWORD(wParam));
538: break;
539:
540: case WM_SIZE:
541: SizeRibbons(hwnd);
542:
543: if (wParam != SIZEICONIC)
544: WorkReset();
545:
546: /*
547: * Did the app start minimized and is it being restored
548: * for the first time? If so, show the palettes as
549: * the user has requested.
550: */
551: if (fStartAsIcon && !IsIconic(hwnd)) {
552: ToolboxShow(gfShowToolbox);
553: ColorShow(gfShowColor);
554: fStartAsIcon = FALSE;
555: }
556:
557: break;
558:
559: case WM_MENUSELECT:
560: if ((UINT)(int)(short)HIWORD(wParam) &
561: (MF_POPUP | MF_SYSMENU))
562: gMenuSelected = 0;
563: else
564: gMenuSelected = LOWORD(wParam);
565:
566: break;
567:
568: case WM_CLOSE:
569: if (VerifySaveFile()) {
570: DestroyWindow(hwnd);
571: CleanUp();
572: }
573:
574: break;
575:
576: case WM_DESTROY:
577: /*
578: * Save the position of the app's window.
579: */
580: WriteWindowPos(&grcAppPos, IsZoomed(hwnd), szAppPos);
581:
582: WinHelp(ghwndMain, gszHelpFile, HELP_QUIT, 0L);
583:
584: PostQuitMessage(0);
585:
586: break;
587:
588: case WM_QUERYENDSESSION:
589: return VerifySaveFile();
590:
591: default:
592: /*
593: * Is this the registered help message from one of the common
594: * dialogs? If so, show the help for it.
595: *
596: * The check to be sure gmsgHelp is non-zero is just in
597: * case the call to register the help message failed
598: * (it will return zero) and there happens to be a zero
599: * message that gets sent to this window somehow.
600: */
601: if (msg == gmsgHelp && gmsgHelp) {
602: ShowHelp(FALSE);
603: return 0;
604: }
605:
606: DoDefault:
607: return DefWindowProc(hwnd, msg, wParam, lParam);
608: }
609:
610: return 0;
611: }
612:
613:
614:
615: /************************************************************************
616: * ReadWindowPos
617: *
618: * This function retrieves the saved window position for a window and
619: * returns it in the specified variables. It is used between sessions
620: * to restore the application windows to the position they had when
621: * the editor was last exited.
622: *
623: * Returns TRUE if the position could be read, or FALSE otherwise.
624: * If FALSE is returned, the values in the specified variables are
625: * not valid! The caller must be able to handle a FALSE return and
626: * supply a default position for the window.
627: *
628: * Arguments:
629: * PSTR pstrKeyName - KeyName the position was saved under.
630: * PINT px - Saved x position.
631: * PINT py - Saved y position.
632: * PINT pcx - Saved width.
633: * PINT pcy - Saved height.
634: * BOOL *pfMaximized - Set to TRUE if window was maximized when saved.
635: *
636: * History:
637: *
638: ************************************************************************/
639:
640: BOOL ReadWindowPos(
641: PSTR pstrKeyName,
642: PINT px,
643: PINT py,
644: PINT pcx,
645: PINT pcy,
646: BOOL *pfMaximized)
647: {
648: static CHAR szSep[] = " ,";
649: CHAR szBuf[CCHTEXTMAX];
650: PSTR pstr;
651:
652: if (!GetPrivateProfileString(ids(IDS_APPNAME),
653: pstrKeyName, "", szBuf, CCHTEXTMAX, ids(IDS_IMAGEDITINI)))
654: return FALSE;
655:
656: if (!(pstr = strtok(szBuf, szSep)))
657: return FALSE;
658:
659: *px = atoi(pstr);
660:
661: if (!(pstr = strtok(NULL, szSep)))
662: return FALSE;
663:
664: *py = atoi(pstr);
665:
666: if (!(pstr = strtok(NULL, szSep)))
667: return FALSE;
668:
669: *pcx = atoi(pstr);
670:
671: if (!(pstr = strtok(NULL, szSep)))
672: return FALSE;
673:
674: *pcy = atoi(pstr);
675:
676: /*
677: * If there is a "1" following the coordinates, the window was
678: * maximized when it was saved.
679: */
680: *pfMaximized = FALSE;
681: if ((pstr = strtok(NULL, szSep)) && atoi(pstr) == 1)
682: *pfMaximized = TRUE;
683:
684: /*
685: * Don't allow a zero sized window.
686: */
687: if (*pcx == 0 || *pcy == 0)
688: return FALSE;
689:
690: /*
691: * Return success.
692: */
693: return TRUE;
694: }
695:
696:
697:
698: /************************************************************************
699: * WriteWindowPos
700: *
701: * This function writes the position of a window to the
702: * editor's profile file under the specified keyname.
703: * The ReadWindowPos function is the counterpart of this
704: * function.
705: *
706: * Arguments:
707: * PRECT prc - Rectangle for the "restored" window size.
708: * BOOL fMaximized - TRUE if the window is maximized.
709: * PSTR pstrKeyName - KeyName to save the position under.
710: *
711: * History:
712: *
713: ************************************************************************/
714:
715: VOID WriteWindowPos(
716: PRECT prc,
717: BOOL fMaximized,
718: PSTR pstrKeyName)
719: {
720: CHAR szBuf[CCHTEXTMAX];
721:
722: wsprintf(szBuf, "%d %d %d %d", prc->left, prc->top,
723: prc->right - prc->left, prc->bottom - prc->top);
724:
725: if (fMaximized)
726: strcat(szBuf, " 1");
727:
728: WritePrivateProfileString(ids(IDS_APPNAME),
729: pstrKeyName, szBuf, ids(IDS_IMAGEDITINI));
730: }
731:
732:
733:
734: /*************************************************************************
735: * ReadEnv
736: *
737: * This function initializes variables from their counterparts
738: * in the private profile file for ImagEdit. The application
739: * merely needs to construct an array of INIENTRY structures
740: * to describe the variables that must be initialized.*
741: * Note that the original value read from the profile is saved when
742: * it is read. This allows us to optimize what needs to be written
743: * out with WriteEnv.
744: *
745: * History:
746: *
747: *************************************************************************/
748:
749: STATICFN VOID NEAR ReadEnv(VOID)
750: {
751: register INT i;
752: HDC hdc;
753: CHAR szBuf[CCHTEXTMAX];
754: DWORD rgb;
755:
756: for (i = 0; gaie[i].pstrKeyName; i++) {
757: *gaie[i].pnVar = gaie[i].nSave =
758: GetPrivateProfileInt(ids(IDS_APPNAME),
759: gaie[i].pstrKeyName, gaie[i].nDefault,
760: ids(IDS_IMAGEDITINI));
761: }
762:
763: /*
764: * Look for the saved screen color.
765: */
766: if (GetPrivateProfileString(ids(IDS_APPNAME), szrgbScreen, "",
767: szBuf, CCHTEXTMAX, ids(IDS_IMAGEDITINI))) {
768: rgb = (DWORD)atol(szBuf);
769: }
770: else {
771: /*
772: * The last screen color was not found. The default will be
773: * the current system screen background color.
774: */
775: rgb = GetSysColor(COLOR_BACKGROUND);
776: }
777:
778: /*
779: * Make the ImagEdit default screen color a solid color.
780: */
781: hdc = GetDC(ghwndMain);
782: grgbScreenDefault = GetNearestColor(hdc, rgb);
783: ReleaseDC(ghwndMain, hdc);
784: }
785:
786:
787:
788: /*************************************************************************
789: * WriteEnv
790: *
791: * This function is the counterpart to ReadEnv. It saves values
792: * in the profile file.
793: *
794: * History:
795: *
796: *************************************************************************/
797:
798: STATICFN VOID NEAR WriteEnv(VOID)
799: {
800: register INT i;
801: CHAR szBuf[CCHTEXTMAX];
802:
803: for (i = 0; gaie[i].pstrKeyName; i++) {
804: /*
805: * Has the user changed the value since it was read?
806: */
807: if (gaie[i].nSave != *gaie[i].pnVar) {
808: /*
809: * If the new value is the same as the default value,
810: * erase the entry from the ini file. Otherwise,
811: * write the user-specified value out.
812: */
813: if (*gaie[i].pnVar == gaie[i].nDefault) {
814: WritePrivateProfileString(ids(IDS_APPNAME),
815: gaie[i].pstrKeyName, NULL, ids(IDS_IMAGEDITINI));
816: }
817: else {
818: itoa(*gaie[i].pnVar, szBuf, 10);
819: WritePrivateProfileString(ids(IDS_APPNAME),
820: gaie[i].pstrKeyName, szBuf, ids(IDS_IMAGEDITINI));
821: }
822: }
823: }
824:
825: /*
826: * Save the current screen color.
827: */
828: ltoa((LONG)grgbScreen, szBuf, 10);
829: WritePrivateProfileString(ids(IDS_APPNAME),
830: szrgbScreen, szBuf, ids(IDS_IMAGEDITINI));
831: }
832:
833:
834:
835: /************************************************************************
836: * SizeRibbons
837: *
838: * This function positions and sizes the child ribbons in the editor.
839: * It needs to be called any time the size of the main windows changes.
840: *
841: * Arguments:
842: * HWND hwnd - Parent window handle.
843: *
844: * History:
845: *
846: ************************************************************************/
847:
848: STATICFN VOID NEAR SizeRibbons(
849: HWND hwnd)
850: {
851: RECT rcClient;
852:
853: if (ghwndPropBar && !IsIconic(hwnd)) {
854: /*
855: * Get the client area.
856: */
857: GetClientRect(hwnd, &rcClient);
858:
859: /*
860: * Size/move the PropBar window to fit
861: * the new client area.
862: */
863: SetWindowPos(ghwndPropBar, NULL,
864: 0, 0,
865: rcClient.right - rcClient.left,
866: min(rcClient.bottom - rcClient.top, gcyPropBar),
867: SWP_NOACTIVATE | SWP_NOZORDER);
868: }
869: }
870:
871:
872:
873: /************************************************************************
874: * CleanUp
875: *
876: * Cleans up all the resources allocated by the editor.
877: *
878: * History:
879: *
880: ************************************************************************/
881:
882: STATICFN VOID NEAR CleanUp(VOID)
883: {
884: WriteEnv();
885:
886: if (ghdcANDMask) {
887: DeleteDC(ghdcANDMask);
888: DeleteObject(ghbmANDMask);
889: }
890: if (ghdcImage) {
891: DeleteDC(ghdcImage);
892: DeleteObject(ghbmImage);
893: }
894:
895: ImageFreeUndo();
896:
897: if (hpenDarkGray)
898: DeleteObject(hpenDarkGray);
899:
900: if (ghbrLeft)
901: DeleteObject(ghbrLeft);
902:
903: if (ghbrLeftSolid)
904: DeleteObject(ghbrLeftSolid);
905:
906: if (ghbrRight)
907: DeleteObject(ghbrRight);
908:
909: if (ghbrRightSolid)
910: DeleteObject(ghbrRightSolid);
911:
912: if (ghbrScreen)
913: DeleteObject(ghbrScreen);
914:
915: if (ghbrInverse)
916: DeleteObject(ghbrInverse);
917:
918: if (ghpenLeft)
919: DeleteObject(ghpenLeft);
920:
921: if (ghpenRight)
922: DeleteObject(ghpenRight);
923:
924: ImageLinkFreeList();
925:
926: if (lpfnMsgFilterHookFunc) {
927: UnhookWindowsHook(WH_MSGFILTER, lpfnMsgFilterHookFunc);
928: FreeProcInstance(lpfnMsgFilterHookFunc);
929: }
930:
931: if (lpfnPropBarDlgProc)
932: FreeProcInstance((FARPROC)lpfnPropBarDlgProc);
933:
934: if (lpfnColorDlgProc)
935: FreeProcInstance((FARPROC)lpfnColorDlgProc);
936: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.