|
|
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.