Annotation of mstools/samples/sdktools/imagedit/imagedit.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.