Annotation of mstools/samples/sdktools/dlgedit/dlgedit.c, revision 1.1

1.1     ! root        1: 
        !             2: /******************************************************************************\
        !             3: *       This is a part of the Microsoft Source Code Samples. 
        !             4: *       Copyright (C) 1993 Microsoft Corporation.
        !             5: *       All rights reserved. 
        !             6: *       This source code is only intended as a supplement to 
        !             7: *       Microsoft Development Tools and/or WinHelp documentation.
        !             8: *       See these sources for detailed information regarding the 
        !             9: *       Microsoft samples programs.
        !            10: \******************************************************************************/
        !            11: 
        !            12: /****************************** Module Header *******************************
        !            13: * Module Name: dlgedit.c
        !            14: *
        !            15: * Main function and window procedure for the Dialog Box Editor.
        !            16: *
        !            17: * Functions:
        !            18: *
        !            19: *   MainWndProc()
        !            20: *   ReadWindowPos()
        !            21: *   WriteWindowPos()
        !            22: *   InitApplication()
        !            23: *   InitInstance()
        !            24: *   PenWinRegister()
        !            25: *   GetSystemValues()
        !            26: *   ReadEnv()
        !            27: *   WriteEnv()
        !            28: *   LoadSysColorBitmaps()
        !            29: *   LoadAlterBitmap()
        !            30: *   RGBInvertRGB()
        !            31: *   SizeRibbons()
        !            32: *   DialogTerminate()
        !            33: *
        !            34: * Comments:
        !            35: *
        !            36: * Because of the need for a dialog in both work and test mode to be
        !            37: * shown relative to the client area of its parent, and because the
        !            38: * editor has a ribbon control along the top of its client area, there
        !            39: * needed to be another window created that will be the actual parent
        !            40: * of the dialog being edited.  This window, called the ghwndSubClient
        !            41: * window, is sized to be the size of the editors client area minus
        !            42: * the height of the ribbon window at the top.  This makes it so that
        !            43: * a dialog that has an origin of 0,0 will have the top edge of its
        !            44: * client area just below the bottom of the ribbon window in the
        !            45: * editor.  This window does not need any special processing.  It simply
        !            46: * paints its background with the app workspace color, and is used as
        !            47: * the basis for coordinate conversion for the dialog.
        !            48: *
        !            49: ****************************************************************************/
        !            50: 
        !            51: #include "dlgedit.h"
        !            52: #include "dlgfuncs.h"
        !            53: #include "dlgextrn.h"
        !            54: #include "dialogs.h"
        !            55: 
        !            56: #include <commdlg.h>
        !            57: 
        !            58: #include <stdlib.h>
        !            59: #include <string.h>
        !            60: 
        !            61: STATICFN BOOL InitApplication(HANDLE hInstance);
        !            62: STATICFN BOOL InitInstance(HANDLE hInstance, INT nCmdShow);
        !            63: STATICFN VOID PenWinRegister(VOID);
        !            64: STATICFN VOID GetSystemValues(VOID);
        !            65: STATICFN VOID ReadEnv(VOID);
        !            66: STATICFN VOID WriteEnv(VOID);
        !            67: STATICFN VOID LoadSysColorBitmaps(VOID);
        !            68: STATICFN HBITMAP LoadAlterBitmap(INT idbm, DWORD rgbNew, DWORD rgbNew2);
        !            69: STATICFN DWORD RGBInvertRGB(DWORD rgb);
        !            70: STATICFN VOID SizeRibbons(HWND hwnd);
        !            71: STATICFN VOID DialogTerminate(VOID);
        !            72: 
        !            73: static RECT grcAppPos;              // Saves the app's window pos.
        !            74: static UINT gmsgHelp;               // Registered help message from commdlg.
        !            75: static BOOL fStartAsIcon = FALSE;   // TRUE if app is started minimized.
        !            76: 
        !            77: /*
        !            78:  * Contains the address of the Pen Windows callback.
        !            79:  */
        !            80: typedef VOID ( APIENTRY *LPFNPENWIN)(WORD, BOOL);
        !            81: static LPFNPENWIN lpfnRegisterPenApp;
        !            82: 
        !            83: 
        !            84: 
        !            85: /************************************************************************
        !            86: * WinMain
        !            87: *
        !            88: * This is the main function for the dialog editor.
        !            89: *
        !            90: ************************************************************************/
        !            91: 
        !            92: INT WINAPI WinMain(
        !            93:     HINSTANCE hInstance,
        !            94:     HINSTANCE hPrevInstance,
        !            95:     LPSTR lpCmdLine,
        !            96:     INT nCmdShow)
        !            97: {
        !            98:     MSG msg;
        !            99: 
        !           100:     if (!hPrevInstance) {
        !           101:         if (!InitApplication(hInstance)) {
        !           102:             Message(MSG_NOINIT);
        !           103:             return FALSE;
        !           104:         }
        !           105:     }
        !           106: 
        !           107:     if (!InitInstance(hInstance, nCmdShow)) {
        !           108:         Message(MSG_NOINIT);
        !           109:         return FALSE;
        !           110:     }
        !           111: 
        !           112:     while (GetMessage(&msg, NULL, 0, 0)) {
        !           113:         if (!ghwndTestDlg || !IsDialogMessage(ghwndTestDlg, &msg)) {
        !           114:             if (!hwndStatus || !IsDialogMessage(hwndStatus, &msg)) {
        !           115:                 if (!TranslateAccelerator(ghwndMain, ghAccTable, &msg)) {
        !           116:                     TranslateMessage(&msg);
        !           117:                     DispatchMessage(&msg);
        !           118:                 }
        !           119:             }
        !           120:         }
        !           121:     }
        !           122: 
        !           123:     DialogTerminate();
        !           124: 
        !           125:     /*
        !           126:      * Return the value from PostQuitMessage.
        !           127:      */
        !           128:     return msg.wParam;
        !           129: }
        !           130: 
        !           131: 
        !           132: 
        !           133: /************************************************************************
        !           134: * InitApplication
        !           135: *
        !           136: * Registers the window classes.
        !           137: *
        !           138: * Arguments:
        !           139: *   HANDLE hInstance - Instance handle from WinMain.
        !           140: *
        !           141: * Returns:
        !           142: *   TRUE if all of the window classes were created; otherwise, FALSE.
        !           143: *
        !           144: ************************************************************************/
        !           145: 
        !           146: STATICFN BOOL InitApplication(
        !           147:     HANDLE hInstance)
        !           148: {
        !           149:     WNDCLASS wc;
        !           150: 
        !           151:     wc.style = CS_DBLCLKS;
        !           152:     wc.lpfnWndProc = MainWndProc;
        !           153:     wc.cbClsExtra = 0;
        !           154:     wc.cbWndExtra = sizeof(DWORD);
        !           155:     wc.hInstance = hInstance;
        !           156:     wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDICON_DLGEDIT));
        !           157:     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
        !           158:     wc.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE + 1);
        !           159:     wc.lpszMenuName = MAKEINTRESOURCE(IDMENU_MAIN);
        !           160:     wc.lpszClassName = szMainClass;
        !           161:     if (!RegisterClass(&wc))
        !           162:         return FALSE;
        !           163: 
        !           164:     wc.style = 0;
        !           165:     wc.lpfnWndProc = DefWindowProc;
        !           166:     wc.cbClsExtra = 0;
        !           167:     wc.cbWndExtra = 0;
        !           168:     wc.hInstance = hInstance;
        !           169:     wc.hIcon = NULL;
        !           170:     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
        !           171:     wc.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE + 1);
        !           172:     wc.lpszMenuName = NULL;
        !           173:     wc.lpszClassName = szSubClientClass;
        !           174:     if (!RegisterClass(&wc))
        !           175:         return FALSE;
        !           176: 
        !           177:     wc.style = CS_DBLCLKS;
        !           178:     wc.lpfnWndProc = DragWndProc;
        !           179:     wc.cbClsExtra = 0;
        !           180:     wc.cbWndExtra = sizeof(DWORD);
        !           181:     wc.hInstance = hInstance;
        !           182:     wc.hIcon = NULL;
        !           183:     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
        !           184:     wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
        !           185:     wc.lpszMenuName = NULL;
        !           186:     wc.lpszClassName = szDragClass;
        !           187:     if (!RegisterClass(&wc))
        !           188:         return FALSE;
        !           189: 
        !           190:     wc.style = 0;
        !           191:     wc.lpfnWndProc = ToolboxWndProc;
        !           192:     wc.cbClsExtra = 0;
        !           193:     wc.cbWndExtra = 0;
        !           194:     wc.hInstance = hInstance;
        !           195:     wc.hIcon = NULL;
        !           196:     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
        !           197:     wc.hbrBackground = GetStockObject(LTGRAY_BRUSH);
        !           198:     wc.lpszMenuName = NULL;
        !           199:     wc.lpszClassName = szToolboxClass;
        !           200:     if (!RegisterClass(&wc))
        !           201:         return FALSE;
        !           202: 
        !           203:     wc.style = 0;
        !           204:     wc.lpfnWndProc = ToolBtnWndProc;
        !           205:     wc.cbClsExtra = 0;
        !           206:     wc.cbWndExtra = 0;
        !           207:     wc.hInstance = hInstance;
        !           208:     wc.hIcon = NULL;
        !           209:     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
        !           210:     wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
        !           211:     wc.lpszMenuName = NULL;
        !           212:     wc.lpszClassName = szToolBtnClass;
        !           213:     if (!RegisterClass(&wc))
        !           214:         return FALSE;
        !           215: 
        !           216:     wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
        !           217:     wc.lpfnWndProc = CustomWndProc;
        !           218:     wc.cbClsExtra = 0;
        !           219:     wc.cbWndExtra = 0;
        !           220:     wc.hInstance = hInstance;
        !           221:     wc.hIcon = NULL;
        !           222:     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
        !           223:     wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
        !           224:     wc.lpszMenuName = NULL;
        !           225:     wc.lpszClassName = szCustomClass;
        !           226:     if (!RegisterClass(&wc))
        !           227:         return FALSE;
        !           228: 
        !           229:     return TRUE;
        !           230: }
        !           231: 
        !           232: 
        !           233: 
        !           234: /************************************************************************
        !           235: * InitInstance
        !           236: *
        !           237: * Initializes the dialog editor by loading resources, etc.
        !           238: *
        !           239: * Arguments:
        !           240: *   HANDLE hInstance - Instance handle from WinMain.
        !           241: *   int nCmdShow     - Show command from WinMain.
        !           242: *
        !           243: * Returns:
        !           244: *   FALSE if any errors occurred during initialization
        !           245: *
        !           246: ************************************************************************/
        !           247: 
        !           248: STATICFN BOOL InitInstance(
        !           249:     HANDLE hInstance,
        !           250:     INT nCmdShow)
        !           251: {
        !           252:     HDC hDC;
        !           253:     TEXTMETRIC tm;
        !           254:     INT x;
        !           255:     INT y;
        !           256:     INT cx;
        !           257:     INT cy;
        !           258:     BOOL fMaximized;
        !           259:     INT i;
        !           260:     TCHAR szArg1[CCHTEXTMAX];
        !           261: 
        !           262:     ghInst = hInstance;
        !           263: 
        !           264:     /*
        !           265:      * We need a mouse - make sure we have one.
        !           266:      */
        !           267:     if (!GetSystemMetrics(SM_MOUSEPRESENT)) {
        !           268:         Message(MSG_NOMOUSE);
        !           269:         return FALSE;
        !           270:     }
        !           271: 
        !           272:     /*
        !           273:      * Register for Pen Windows, if it is present.
        !           274:      */
        !           275:     PenWinRegister();
        !           276: 
        !           277:     ghAccTable = LoadAccelerators(ghInst, MAKEINTRESOURCE(IDACCEL_MAIN));
        !           278: 
        !           279:     /*
        !           280:      * Create a dark gray pen for use in borders later.
        !           281:      */
        !           282:     if (!(hpenDarkGray = CreatePen(PS_SOLID, 1, DARKGRAY)))
        !           283:         return FALSE;
        !           284: 
        !           285:     /*
        !           286:      * Get some system constants.
        !           287:      */
        !           288:     GetSystemValues();
        !           289: 
        !           290:     /*
        !           291:      * Note that this must be done instead of using the text metrics,
        !           292:      * because Windows internally generates a better average value for
        !           293:      * proportional fonts, and we must match it or our dialogs will
        !           294:      * be out of proportion.
        !           295:      */
        !           296:     gcxSysChar = LOWORD(GetDialogBaseUnits());
        !           297:     gcySysChar = HIWORD(GetDialogBaseUnits());
        !           298: 
        !           299:     /*
        !           300:      * Because some useful worker routines like WinToDUPoint use
        !           301:      * the values in gcd.c*Char, set them to be the default font right
        !           302:      * away.  When a dialog is loaded with a different font, they
        !           303:      * will be modified.
        !           304:      */
        !           305:     gcd.cxChar = gcxSysChar;
        !           306:     gcd.cyChar = gcySysChar;
        !           307: 
        !           308:     /*
        !           309:      * Build the help file name path.  Assume the help file is in the
        !           310:      * same directory as the executable.
        !           311:      */
        !           312:     GetModuleFileName(ghInst, gszHelpFile, CCHMAXPATH);
        !           313:     *FileInPath(gszHelpFile) = CHAR_NULL;
        !           314:     lstrcat(gszHelpFile, ids(IDS_HELPFILE));
        !           315: 
        !           316:     /*
        !           317:      * Register the message for help from the common dialogs.
        !           318:      */
        !           319:     gmsgHelp = RegisterWindowMessage(HELPMSGSTRING);
        !           320: 
        !           321:     /*
        !           322:      * Hook the message filter stream so that we can detect F1 keystrokes.
        !           323:      */
        !           324:     ghhkMsgFilter = SetWindowsHook(WH_MSGFILTER, (HOOKPROC)MsgFilterHookFunc);
        !           325: 
        !           326:     /*
        !           327:      * Read the last position for the app.
        !           328:      */
        !           329:     if (!ReadWindowPos(szAppPos, &x, &y, &cx, &cy, &fMaximized)) {
        !           330:         x = CW_USEDEFAULT;
        !           331:         y = CW_USEDEFAULT;
        !           332:         cx = CW_USEDEFAULT;
        !           333:         cy = CW_USEDEFAULT;
        !           334:         fMaximized = FALSE;
        !           335:     }
        !           336: 
        !           337:     /*
        !           338:      * Create the main window.
        !           339:      */
        !           340:     if (!(ghwndMain = CreateWindow(szMainClass, NULL,
        !           341:             WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
        !           342:             x, y, cx, cy, NULL, NULL, hInstance, NULL)))
        !           343:         return FALSE;
        !           344: 
        !           345:     ShowFileStatus(TRUE);
        !           346: 
        !           347:     /*
        !           348:      * Read the Preferences data.
        !           349:      */
        !           350:     ReadEnv();
        !           351: 
        !           352:     /*
        !           353:      * If the app was saved when maximized (and they didn't start it up
        !           354:      * with some kind of an option to have it minimized or in some
        !           355:      * other funny initial state from the shell), then cause it to
        !           356:      * be maximized when shown.
        !           357:      */
        !           358:     if (fMaximized && (nCmdShow == SW_SHOWNORMAL || nCmdShow == SW_SHOW))
        !           359:         nCmdShow = SW_SHOWMAXIMIZED;
        !           360: 
        !           361:     ShowWindow(ghwndMain, nCmdShow);
        !           362:     UpdateWindow(ghwndMain);
        !           363: 
        !           364:     /*
        !           365:      * Did the user start this app minimized from the program manager?
        !           366:      */
        !           367:     if (IsIconic(ghwndMain)) {
        !           368:         /*
        !           369:          * Set a flag.  The showing of the toolbox will be deferred
        !           370:          * until the app is restored.
        !           371:          */
        !           372:         fStartAsIcon = TRUE;
        !           373:     }
        !           374:     else {
        !           375:         /*
        !           376:          * If they had the Toolbox before, show it now.
        !           377:          */
        !           378:         if (gfShowToolbox)
        !           379:             ToolboxShow(TRUE);
        !           380:     }
        !           381: 
        !           382:     hcurArrow = LoadCursor(NULL, IDC_ARROW);
        !           383:     hcurWait = LoadCursor(NULL, IDC_WAIT);
        !           384:     hcurOutSel = LoadCursor(ghInst, MAKEINTRESOURCE(IDCUR_OUTSEL));
        !           385:     hcurMove = LoadCursor(ghInst, MAKEINTRESOURCE(IDCUR_MOVE));
        !           386:     hcurInsert = LoadCursor(ghInst, MAKEINTRESOURCE(IDCUR_INSERT));
        !           387:     hcurDropTool = LoadCursor(ghInst, MAKEINTRESOURCE(IDCUR_DROPTOOL));
        !           388:     hcurSizeNESW = LoadCursor(NULL, IDC_SIZENESW);
        !           389:     hcurSizeNS = LoadCursor(NULL, IDC_SIZENS);
        !           390:     hcurSizeNWSE = LoadCursor(NULL, IDC_SIZENWSE);
        !           391:     hcurSizeWE = LoadCursor(NULL, IDC_SIZEWE);
        !           392: 
        !           393:     if (!hcurArrow ||
        !           394:             !hcurWait ||
        !           395:             !hcurOutSel ||
        !           396:             !hcurMove ||
        !           397:             !hcurDropTool ||
        !           398:             !hcurInsert)
        !           399:         return FALSE;
        !           400: 
        !           401:     if ((hDC = GetDC(ghwndMain)) == NULL)
        !           402:         return FALSE;
        !           403: 
        !           404:     GetTextMetrics(hDC, &tm);
        !           405: 
        !           406:     gcyPixelsPerInch = GetDeviceCaps(hDC, LOGPIXELSY);
        !           407: 
        !           408:     /*
        !           409:      * Create a memory DC for drawing bitmaps.
        !           410:      */
        !           411:     ghDCMem = CreateCompatibleDC(hDC);
        !           412: 
        !           413:     ReleaseDC(ghwndMain, hDC);
        !           414: 
        !           415:     /*
        !           416:      * Load the bitmaps that depend on system colors.
        !           417:      */
        !           418:     LoadSysColorBitmaps();
        !           419: 
        !           420:     fmtDlg = RegisterClipboardFormat(L"DIALOG");
        !           421: 
        !           422:     /*
        !           423:      * Initialize the icon control ordinal to the icon id from our exe
        !           424:      * that we will use to show these kind of controls.
        !           425:      */
        !           426:     WriteOrd(&gordIcon, IDICON_ICON);
        !           427: 
        !           428:     /*
        !           429:      * Initialize the default text fields in the awcd array.  Because
        !           430:      * CCONTROLS does not include the dialog type, it has to be done
        !           431:      * separately.
        !           432:      */
        !           433:     awcd[W_DIALOG].pszTextDefault = ids(awcd[W_DIALOG].idsTextDefault);
        !           434:     for (i = 0; i < CCONTROLS; i++)
        !           435:         awcd[i].pszTextDefault = ids(awcd[i].idsTextDefault);
        !           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:         MultiByteToWideChar(CP_ACP, 0, __argv[1], -1, szArg1, CCHTEXTMAX);
        !           443:         OpenCmdLineFile(szArg1);
        !           444:     }
        !           445: 
        !           446:     /*
        !           447:      * Be sure the focus is on the main window.  This corrects a
        !           448:      * problem where the accelerators don't initially work because
        !           449:      * the focus gets placed on the Properties Bar.
        !           450:      */
        !           451:     SetFocus(ghwndMain);
        !           452: 
        !           453:     return TRUE;
        !           454: }
        !           455: 
        !           456: 
        !           457: 
        !           458: /************************************************************************
        !           459: * PenWinRegister
        !           460: *
        !           461: * This function will register for Pen Windows, if it is present.
        !           462: *
        !           463: ************************************************************************/
        !           464: 
        !           465: STATICFN VOID PenWinRegister(VOID)
        !           466: {
        !           467:     HANDLE hmod;
        !           468: 
        !           469:     if (!(hmod = (HANDLE)GetSystemMetrics(SM_PENWINDOWS)))
        !           470:         return;
        !           471: 
        !           472:     if (lpfnRegisterPenApp =
        !           473:             (LPFNPENWIN)GetProcAddress(hmod, "RegisterPenApp"))
        !           474:         (*lpfnRegisterPenApp)(1, TRUE);     // Be Pen-Enhanced!
        !           475: }
        !           476: 
        !           477: 
        !           478: 
        !           479: /************************************************************************
        !           480: * GetSystemValues
        !           481: *
        !           482: * This function reads various system values.  It is called at init time,
        !           483: * as well as if we are informed by a WM_SYSVALUECHANGED message that
        !           484: * some of these values have been changed.
        !           485: *
        !           486: ************************************************************************/
        !           487: 
        !           488: STATICFN VOID GetSystemValues(VOID)
        !           489: {
        !           490:     gcyBorder = GetSystemMetrics(SM_CYBORDER);
        !           491: 
        !           492:     /*
        !           493:      * The distance that the mouse can move during a pre-drag operation
        !           494:      * before starting to drag the control anyways is based on the
        !           495:      * mouse double-click movement distances in the system.
        !           496:      */
        !           497:     gcxPreDragMax = GetSystemMetrics(SM_CXDOUBLECLK);
        !           498:     gcyPreDragMax = GetSystemMetrics(SM_CYDOUBLECLK);
        !           499: 
        !           500:     /*
        !           501:      * The number of milliseconds that the pre-drag debounce time lasts.
        !           502:      */
        !           503:     gmsecPreDrag = 250;
        !           504: }
        !           505: 
        !           506: 
        !           507: 
        !           508: /************************************************************************
        !           509: * ReadWindowPos
        !           510: *
        !           511: * This function retrieves the saved window position for a window and
        !           512: * returns it in the specified variables.  It is used between sessions
        !           513: * to restore the application windows to the position they had when
        !           514: * the editor was last exited.
        !           515: *
        !           516: * Arguments:
        !           517: *   LPTSTR pszKeyName  - KeyName the position was saved under.
        !           518: *   PINT px            - Saved x position.
        !           519: *   PINT py            - Saved y position.
        !           520: *   PINT pcx           - Saved width.
        !           521: *   PINT pcy           - Saved height.
        !           522: *   BOOL *pfMaximized  - Set to TRUE if window was maximized when saved.
        !           523: *
        !           524: * Returns: 
        !           525: *   TRUE if the position could be read, or FALSE otherwise.
        !           526: *   If FALSE is returned, the values in the specified variables are
        !           527: *   not valid!  The caller must be able to handle a FALSE return and
        !           528: *   supply a default position for the window.
        !           529: *
        !           530: ************************************************************************/
        !           531: 
        !           532: BOOL ReadWindowPos(
        !           533:     LPTSTR pszKeyName,
        !           534:     PINT px,
        !           535:     PINT py,
        !           536:     PINT pcx,
        !           537:     PINT pcy,
        !           538:     BOOL *pfMaximized)
        !           539: {
        !           540:     static CHAR szSep[] = " ,";
        !           541:     TCHAR szBuf[CCHTEXTMAX];
        !           542:     CHAR szBufAnsi[CCHTEXTMAX];
        !           543:     PSTR psz;
        !           544:     BOOL fDefCharUsed;
        !           545: 
        !           546:     if (!GetPrivateProfileString(ids(IDS_APPNAME),
        !           547:             pszKeyName, szEmpty, szBuf, CCHTEXTMAX, ids(IDS_DLGEDITINI)))
        !           548:         return FALSE;
        !           549: 
        !           550:     WideCharToMultiByte(CP_ACP, 0, szBuf, -1, szBufAnsi, CCHTEXTMAX,
        !           551:             NULL, &fDefCharUsed);
        !           552: 
        !           553:     if (!(psz = strtok(szBufAnsi, szSep)))
        !           554:         return FALSE;
        !           555: 
        !           556:     *px = atoi(psz);
        !           557: 
        !           558:     if (!(psz = strtok(NULL, szSep)))
        !           559:         return FALSE;
        !           560: 
        !           561:     *py = atoi(psz);
        !           562: 
        !           563:     if (!(psz = strtok(NULL, szSep)))
        !           564:         return FALSE;
        !           565: 
        !           566:     *pcx = atoi(psz);
        !           567: 
        !           568:     if (!(psz = strtok(NULL, szSep)))
        !           569:         return FALSE;
        !           570: 
        !           571:     *pcy = atoi(psz);
        !           572: 
        !           573:     /*
        !           574:      * If there is a "1" following the coordinates, the window was
        !           575:      * maximized when it was saved.
        !           576:      */
        !           577:     *pfMaximized = FALSE;
        !           578:     if ((psz = strtok(NULL, szSep)) && atoi(psz) == 1)
        !           579:         *pfMaximized = TRUE;
        !           580: 
        !           581:     /*
        !           582:      * Don't allow a zero sized window.
        !           583:      */
        !           584:     if (*pcx == 0 || *pcy == 0)
        !           585:         return FALSE;
        !           586: 
        !           587:     /*
        !           588:      * Return success.
        !           589:      */
        !           590:     return TRUE;
        !           591: 
        !           592: }
        !           593: 
        !           594: 
        !           595: 
        !           596: /************************************************************************
        !           597: * WriteWindowPos
        !           598: *
        !           599: * This function writes the position of a window to the
        !           600: * editor's profile file under the specified keyname.
        !           601: * The ReadWindowPos function is the counterpart of this
        !           602: * function.
        !           603: *
        !           604: * Arguments:
        !           605: *   PRECT prc          - Rectangle for the "restored" window size.
        !           606: *   BOOL fMaximized    - TRUE if the window is maximized.
        !           607: *   LPTSTR pszKeyName  - KeyName to save the position under.
        !           608: *
        !           609: ************************************************************************/
        !           610: 
        !           611: VOID WriteWindowPos(
        !           612:     PRECT prc,
        !           613:     BOOL fMaximized,
        !           614:     LPTSTR pszKeyName)
        !           615: {
        !           616:     TCHAR szBuf[CCHTEXTMAX];
        !           617: 
        !           618:     wsprintf(szBuf, L"%d %d %d %d", prc->left, prc->top,
        !           619:             prc->right - prc->left, prc->bottom - prc->top);
        !           620: 
        !           621:     if (fMaximized)
        !           622:         lstrcat(szBuf, L" 1");
        !           623: 
        !           624:     WritePrivateProfileString(ids(IDS_APPNAME),
        !           625:             pszKeyName, szBuf, ids(IDS_DLGEDITINI));
        !           626: }
        !           627: 
        !           628: 
        !           629: 
        !           630: /*************************************************************************
        !           631: * ReadEnv
        !           632: *
        !           633: * This function initializes variables from their counterparts
        !           634: * in the private profile file for DlgEdit.  The application
        !           635: * merely needs to construct an array of INIENTRY structures
        !           636: * to describe the variables that must be initialized.
        !           637: *
        !           638: * Note that the original value read from the profile is saved when
        !           639: * it is read.  This allows us to optimize what needs to be written
        !           640: * out with WriteEnv.
        !           641: *
        !           642: *************************************************************************/
        !           643: 
        !           644: STATICFN VOID ReadEnv(VOID)
        !           645: {
        !           646:     register INT i;
        !           647: 
        !           648:     for (i = 0; gaie[i].pszKeyName; i++) {
        !           649:         *gaie[i].pnVar = gaie[i].nSave =
        !           650:                 GetPrivateProfileInt(ids(IDS_APPNAME),
        !           651:                 gaie[i].pszKeyName, gaie[i].nDefault,
        !           652:                 ids(IDS_DLGEDITINI));
        !           653:     }
        !           654: 
        !           655:     ReadCustomProfile();
        !           656: }
        !           657: 
        !           658: 
        !           659: 
        !           660: /*************************************************************************
        !           661: * WriteEnv
        !           662: *
        !           663: * This function is the counterpart to ReadEnv.  It saves values
        !           664: * in the profile file.
        !           665: *
        !           666: *************************************************************************/
        !           667: 
        !           668: STATICFN VOID WriteEnv(VOID)
        !           669: {
        !           670:     register INT i;
        !           671:     TCHAR szBuf[17];
        !           672: 
        !           673:     for (i = 0; gaie[i].pszKeyName; i++) {
        !           674:         /*
        !           675:          * Has the user changed the value since it was read?
        !           676:          */
        !           677:         if (gaie[i].nSave != *gaie[i].pnVar) {
        !           678:             /*
        !           679:              * If the new value is the same as the default value,
        !           680:              * erase the entry from the ini file.  Otherwise,
        !           681:              * write the user-specified value out.
        !           682:              */
        !           683:             if (*gaie[i].pnVar == gaie[i].nDefault) {
        !           684:                 WritePrivateProfileString(ids(IDS_APPNAME),
        !           685:                         gaie[i].pszKeyName, NULL, ids(IDS_DLGEDITINI));
        !           686:             }
        !           687:             else {
        !           688:                 itoaw(*gaie[i].pnVar, szBuf, 10);
        !           689:                 WritePrivateProfileString(ids(IDS_APPNAME),
        !           690:                         gaie[i].pszKeyName, szBuf, ids(IDS_DLGEDITINI));
        !           691:             }
        !           692:         }
        !           693:     }
        !           694: 
        !           695:     WriteCustomProfile();
        !           696: }
        !           697: 
        !           698: 
        !           699: 
        !           700: /************************************************************************
        !           701: * MainWndProc
        !           702: *
        !           703: * This is the window procedure for the "dlgedit" class.  This is the
        !           704: * class of the main dialog editor "client" window.
        !           705: *
        !           706: ************************************************************************/
        !           707: 
        !           708: WINDOWPROC MainWndProc(
        !           709:     HWND hwnd,
        !           710:     UINT msg,
        !           711:     WPARAM wParam,
        !           712:     LPARAM lParam)
        !           713: {
        !           714:     switch (msg) {
        !           715:         case WM_CREATE:
        !           716:             {
        !           717:                 RECT rc;
        !           718: 
        !           719:                 /*
        !           720:                  * Create the status window.
        !           721:                  */
        !           722:                 CreateDialog(ghInst, MAKEINTRESOURCE(DID_STATUS),
        !           723:                         hwnd, StatusDlgProc);
        !           724: 
        !           725:                 /*
        !           726:                  * Save away its height for sizing later (like when
        !           727:                  * the app is minimized then restored).
        !           728:                  */
        !           729:                 GetWindowRect(hwndStatus, &rc);
        !           730:                 gcyStatus = rc.bottom - rc.top;
        !           731: 
        !           732:                 ghwndSubClient = CreateWindow(szSubClientClass, NULL,
        !           733:                         WS_CHILD | WS_VISIBLE, 0, 0, 0, 0,
        !           734:                         hwnd, NULL, ghInst, NULL);
        !           735: 
        !           736:                 ghMenuMain = GetMenu(hwnd);
        !           737:                 LoadMenuBitmaps(ghMenuMain);
        !           738:             }
        !           739: 
        !           740:             break;
        !           741: 
        !           742:         case WM_ACTIVATE:
        !           743:             /*
        !           744:              * If the main window is getting activated, there is no
        !           745:              * currently active dialog.
        !           746:              */
        !           747:             if (LOWORD(wParam))
        !           748:                 gidCurrentDlg = 0;
        !           749: 
        !           750:             goto DoDefault;
        !           751: 
        !           752:         case WM_INITMENU:
        !           753:             if (GetMenu(ghwndMain) == (HMENU)wParam)
        !           754:                 InitMenu((HMENU)wParam);
        !           755: 
        !           756:             break;
        !           757: 
        !           758:         case WM_MENUSELECT:
        !           759:             if (HIWORD(wParam) &
        !           760:                     (MF_POPUP | MF_SYSMENU))
        !           761:                 gMenuSelected = 0;
        !           762:             else
        !           763:                 gMenuSelected = LOWORD(wParam);
        !           764: 
        !           765:             break;
        !           766: 
        !           767:         case WM_COMMAND:
        !           768:             DialogMenu(LOWORD(wParam));
        !           769:             break;
        !           770: 
        !           771:         case WM_KEYDOWN:
        !           772:             switch (wParam) {
        !           773:                 case VK_UP:
        !           774:                 case VK_DOWN:
        !           775:                 case VK_LEFT:
        !           776:                 case VK_RIGHT:
        !           777:                     if ((GetKeyState(VK_SHIFT) & 0x8000) ||
        !           778:                             (GetKeyState(VK_CONTROL) & 0x8000))
        !           779:                         break;
        !           780: 
        !           781:                     /*
        !           782:                      * Ignore it if we are not in a normal state
        !           783:                      * (don't allow when dragging).
        !           784:                      */
        !           785:                     if (gState != STATE_NORMAL)
        !           786:                         break;
        !           787: 
        !           788:                     /*
        !           789:                      * Be sure any outstanding changes get applied
        !           790:                      * without errors.
        !           791:                      */
        !           792:                     if (!StatusApplyChanges())
        !           793:                         break;
        !           794: 
        !           795:                     /*
        !           796:                      * Move the control in the specified direction.
        !           797:                      */
        !           798:                     MoveControl(wParam);
        !           799:                     break;
        !           800: 
        !           801:                 case VK_TAB:
        !           802:                     if (GetKeyState(VK_CONTROL) & 0x8000)
        !           803:                         break;
        !           804: 
        !           805:                     /*
        !           806:                      * Ignore it if we are not in a normal state
        !           807:                      * (don't allow when dragging).
        !           808:                      */
        !           809:                     if (gState != STATE_NORMAL)
        !           810:                         break;
        !           811: 
        !           812:                     /*
        !           813:                      * Be sure any outstanding changes get applied
        !           814:                      * without errors.
        !           815:                      */
        !           816:                     if (!StatusApplyChanges())
        !           817:                         break;
        !           818: 
        !           819:                     /*
        !           820:                      * Is the shift key pressed also?
        !           821:                      */
        !           822:                     if (GetKeyState(VK_SHIFT) & 0x8000)
        !           823:                         SelectPrevious();
        !           824:                     else
        !           825:                         SelectNext();
        !           826: 
        !           827:                     break;
        !           828: 
        !           829:                 case VK_ESCAPE:
        !           830:                     if ((GetKeyState(VK_SHIFT) & 0x8000) ||
        !           831:                             (GetKeyState(VK_CONTROL) & 0x8000))
        !           832:                         break;
        !           833: 
        !           834:                     /*
        !           835:                      * Be sure any outstanding changes get applied
        !           836:                      * without errors.
        !           837:                      */
        !           838:                     if (!StatusApplyChanges())
        !           839:                         break;
        !           840: 
        !           841:                     if (gState == STATE_SELECTING)
        !           842:                         OutlineSelectCancel();
        !           843: 
        !           844:                     /*
        !           845:                      * Cancel any drag operation they might have been doing.
        !           846:                      */
        !           847:                     if (gState != STATE_NORMAL)
        !           848:                         DragCancel();
        !           849: 
        !           850:                     break;
        !           851: 
        !           852:                 case VK_RETURN:
        !           853:                     if ((GetKeyState(VK_SHIFT) & 0x8000) ||
        !           854:                             (GetKeyState(VK_CONTROL) & 0x8000))
        !           855:                         break;
        !           856: 
        !           857:                     /*
        !           858:                      * Be sure any outstanding changes get applied
        !           859:                      * without errors.
        !           860:                      */
        !           861:                     if (!StatusApplyChanges())
        !           862:                         break;
        !           863: 
        !           864:                     switch (gState) {
        !           865:                         POINTS mpt;
        !           866:                         POINT pt;
        !           867:                         DWORD dwPos;
        !           868: 
        !           869:                         case STATE_SELECTING:
        !           870:                             /*
        !           871:                              * In outline selection mode.  Map the
        !           872:                              * location of the mouse at the time that
        !           873:                              * the user pressed Enter into a point
        !           874:                              * relative to the dialog client and complete
        !           875:                              * the selection operation.
        !           876:                              */
        !           877:                             dwPos = GetMessagePos();
        !           878:                             mpt = (*((POINTS *)&(dwPos)));
        !           879:                             ((pt).x = (mpt).x, (pt).y = (mpt).y);
        !           880:                             ScreenToClient(gcd.npc->hwnd, &pt);
        !           881:                             OutlineSelectEnd(pt.x, pt.y);
        !           882: 
        !           883:                             break;
        !           884: 
        !           885:                         case STATE_DRAGGING:
        !           886:                         case STATE_DRAGGINGNEW:
        !           887:                             /*
        !           888:                              * We are dragging something.  Map the
        !           889:                              * location of the mouse at the time
        !           890:                              * that the user pressed Enter into a
        !           891:                              * point relative to the proper window
        !           892:                              * and complete the drag operation.
        !           893:                              */
        !           894:                             dwPos = GetMessagePos();
        !           895:                             mpt = (*((POINTS *)&(dwPos)));
        !           896:                             ((pt).x = (mpt).x, (pt).y = (mpt).y);
        !           897: 
        !           898:                             /*
        !           899:                              * The point must be changed to be relative to
        !           900:                              * the window that the ending mouse up message
        !           901:                              * would have come through, which will be the
        !           902:                              * capture window for the drag.  This will be
        !           903:                              * the dialog if we are adding a new control,
        !           904:                              * or it will be the selected control if we are
        !           905:                              * dragging an existing control.
        !           906:                              */
        !           907:                             ScreenToClient((gState == STATE_DRAGGING) ?
        !           908:                                     gnpcSel->hwnd : gcd.npc->hwnd, &pt);
        !           909: 
        !           910:                             /*
        !           911:                              * If the dialog is selected, map the points from
        !           912:                              * the client area to the window.
        !           913:                              */
        !           914:                             if (gfDlgSelected)
        !           915:                                 MapDlgClientPoint(&pt, TRUE);
        !           916: 
        !           917:                             DragEnd(pt.x, pt.y);
        !           918: 
        !           919:                             break;
        !           920:                     }
        !           921: 
        !           922:                     break;
        !           923:             }
        !           924: 
        !           925:             break;
        !           926: 
        !           927:         case WM_NCCALCSIZE:
        !           928:             /*
        !           929:              * Save away what is going to be the new window position.
        !           930:              */
        !           931:             if (!IsIconic(hwnd) && !IsZoomed(hwnd))
        !           932:                 grcAppPos = *((LPRECT)lParam);
        !           933: 
        !           934:             /*
        !           935:              * Now let the DefWindowProc calculate the client area normally.
        !           936:              */
        !           937:             goto DoDefault;
        !           938: 
        !           939:         case WM_MOVE:
        !           940:             if (gfEditingDlg)
        !           941:                 RepositionDialog();
        !           942: 
        !           943:             break;
        !           944: 
        !           945:         case WM_SIZE:
        !           946:             SizeRibbons(hwnd);
        !           947: 
        !           948:             /*
        !           949:              * Did the app start minimized and is it being restored
        !           950:              * for the first time?  If so, show the toolbox if
        !           951:              * the user has requested it.
        !           952:              */
        !           953:             if (fStartAsIcon && !IsIconic(hwnd)) {
        !           954:                 if (gfShowToolbox)
        !           955:                     ToolboxShow(TRUE);
        !           956: 
        !           957:                 fStartAsIcon = FALSE;
        !           958:             }
        !           959: 
        !           960:             break;
        !           961: 
        !           962:         case WM_SYSCOLORCHANGE:
        !           963:             LoadSysColorBitmaps();
        !           964:             break;
        !           965: 
        !           966:         case WM_CLOSE:
        !           967:             if (ghwndTestDlg)
        !           968:                 DestroyTestDialog();
        !           969: 
        !           970:             if (DoWeSave(FILE_INCLUDE) == IDCANCEL ||
        !           971:                     DoWeSave(FILE_RESOURCE) == IDCANCEL)
        !           972:                 break;
        !           973: 
        !           974:             /*
        !           975:              * First destroy the Properties Bar.
        !           976:              */
        !           977:             DestroyWindow(hwndStatus);
        !           978:             hwndStatus = NULL;
        !           979: 
        !           980:             DestroyWindow(hwnd);
        !           981:             break;
        !           982: 
        !           983:         case WM_QUERYENDSESSION:
        !           984:             if (ghwndTestDlg)
        !           985:                 DestroyTestDialog();
        !           986: 
        !           987:             if (DoWeSave(FILE_INCLUDE) == IDCANCEL ||
        !           988:                     DoWeSave(FILE_RESOURCE) == IDCANCEL)
        !           989:                 return FALSE;
        !           990:             else
        !           991:                 return TRUE;
        !           992: 
        !           993:         case WM_DESTROY:
        !           994:             /*
        !           995:              * Save the position of the app's window.
        !           996:              */
        !           997:             WriteWindowPos(&grcAppPos, IsZoomed(hwnd), szAppPos);
        !           998: 
        !           999:             WinHelp(hwnd, gszHelpFile, HELP_QUIT, 0L);
        !          1000:             FreeMenuBitmaps();
        !          1001:             PostQuitMessage(0);
        !          1002:             break;
        !          1003: 
        !          1004:         default:
        !          1005:             /*
        !          1006:              * Is this the registered help message from one of the common
        !          1007:              * dialogs?  If so, show the help for it.
        !          1008:              *
        !          1009:              * The check to be sure gmsgHelp is non-zero is just in
        !          1010:              * case the call to register the help message failed
        !          1011:              * (it will return zero) and there happens to be a zero
        !          1012:              * message that gets sent to this window somehow.
        !          1013:              */
        !          1014:             if (msg == gmsgHelp && gmsgHelp) {
        !          1015:                 ShowHelp(FALSE);
        !          1016:                 return 0;
        !          1017:             }
        !          1018: 
        !          1019:         DoDefault:
        !          1020:             return DefWindowProc(hwnd, msg, wParam, lParam);
        !          1021:     }
        !          1022: 
        !          1023:     return 0;
        !          1024: }
        !          1025: 
        !          1026: 
        !          1027: 
        !          1028: /************************************************************************
        !          1029: * LoadSysColorBitmaps
        !          1030: *
        !          1031: * This function loads bitmaps that depend on the system window and
        !          1032: * highlight colors.  As it loads them, it replaces two special colors
        !          1033: * in them with some system colors.
        !          1034: * This is used for the control type bitmaps that appear in lines
        !          1035: * in the listbox in the Order/Group dialog.
        !          1036: *
        !          1037: ************************************************************************/
        !          1038: 
        !          1039: STATICFN VOID LoadSysColorBitmaps(VOID)
        !          1040: {
        !          1041:     DWORD rgbWindow;
        !          1042:     DWORD rgbWindowText;
        !          1043:     DWORD rgbHighlight;
        !          1044:     DWORD rgbHighlightText;
        !          1045:     INT i;
        !          1046: 
        !          1047:     rgbWindow = GetSysColor(COLOR_WINDOW);
        !          1048:     rgbWindowText = GetSysColor(COLOR_WINDOWTEXT);
        !          1049:     rgbHighlight = GetSysColor(COLOR_HIGHLIGHT);
        !          1050:     rgbHighlightText = GetSysColor(COLOR_HIGHLIGHTTEXT);
        !          1051: 
        !          1052:     if (hbmTabStop)
        !          1053:         DeleteObject(hbmTabStop);
        !          1054: 
        !          1055:     hbmTabStop = LoadAlterBitmap(IDBM_TABSTOP, rgbWindow, rgbWindowText);
        !          1056: 
        !          1057:     if (hbmTabStopSel)
        !          1058:         DeleteObject(hbmTabStopSel);
        !          1059: 
        !          1060:     hbmTabStopSel = LoadAlterBitmap(IDBM_TABSTOP,
        !          1061:             rgbHighlight, rgbHighlightText);
        !          1062: 
        !          1063:     for (i = 0; i < CCONTROLS; i++) {
        !          1064:         if (awcd[i].hbmCtrlType)
        !          1065:             DeleteObject(awcd[i].hbmCtrlType);
        !          1066: 
        !          1067:         awcd[i].hbmCtrlType = LoadAlterBitmap(
        !          1068:                 awcd[i].idbmCtrlType, rgbWindow, rgbWindowText);
        !          1069: 
        !          1070:         if (awcd[i].hbmCtrlTypeSel)
        !          1071:             DeleteObject(awcd[i].hbmCtrlTypeSel);
        !          1072: 
        !          1073:         awcd[i].hbmCtrlTypeSel = LoadAlterBitmap(
        !          1074:                 awcd[i].idbmCtrlType, rgbHighlight, rgbHighlightText);
        !          1075:     }
        !          1076: 
        !          1077:     if (ghbmDragHandle)
        !          1078:         DeleteObject(ghbmDragHandle);
        !          1079: 
        !          1080:     ghbmDragHandle = LoadAlterBitmap(IDBM_DRAGHANDLE,
        !          1081:             rgbWindow, rgbHighlight);
        !          1082: 
        !          1083:     if (ghbmDragHandle2)
        !          1084:         DeleteObject(ghbmDragHandle2);
        !          1085: 
        !          1086:     ghbmDragHandle2 = LoadAlterBitmap(IDBM_DRAGHANDLE2,
        !          1087:             rgbWindow, rgbHighlight);
        !          1088: }
        !          1089: 
        !          1090: 
        !          1091: 
        !          1092: /************************************************************************
        !          1093: * LoadAlterBitmap
        !          1094: *
        !          1095: * This function loads a single bitmap.  As it does, it replaces a
        !          1096: * couple special RGB colors (REPLACECOLOR1 and REPLACECOLOR2) with
        !          1097: * the passed in RGB colors.
        !          1098: *
        !          1099: * Arguments:
        !          1100: *   INT idbm      - Integer ID of the bitmap to load.
        !          1101: *   DWORD rgbNew  - Color to replace the special color with.
        !          1102: *   DWORD rgbNew2 - A second color to replace the second special color with.
        !          1103: *
        !          1104: * Returns:
        !          1105: *   The handle to the bitmap, or NULL if an error occurs.
        !          1106: *
        !          1107: ************************************************************************/
        !          1108: 
        !          1109: STATICFN HBITMAP LoadAlterBitmap(
        !          1110:     INT idbm,
        !          1111:     DWORD rgbNew,
        !          1112:     DWORD rgbNew2)
        !          1113: {
        !          1114:     register INT i;
        !          1115:     LPBITMAPINFOHEADER lpbihInfo;
        !          1116:     HDC hdcScreen;
        !          1117:     HANDLE hresLoad;
        !          1118:     HANDLE hres;
        !          1119:     DWORD FAR *qlng;
        !          1120:     LPBYTE lpbBits;
        !          1121:     HANDLE hbmp;
        !          1122:     DWORD rgbReplace1;
        !          1123:     DWORD rgbReplace2;
        !          1124: 
        !          1125:     hresLoad = FindResource(ghInst, MAKEINTRESOURCE(idbm), RT_BITMAP);
        !          1126:     if (!hresLoad)
        !          1127:         return NULL;
        !          1128: 
        !          1129:     hres = LoadResource(ghInst, hresLoad);
        !          1130:     if (!hresLoad)
        !          1131:         return NULL;
        !          1132: 
        !          1133:     rgbNew = RGBInvertRGB(rgbNew);
        !          1134:     rgbNew2 = RGBInvertRGB(rgbNew2);
        !          1135:     rgbReplace1 = RGBInvertRGB(REPLACECOLOR1);
        !          1136:     rgbReplace2 = RGBInvertRGB(REPLACECOLOR2);
        !          1137:     lpbihInfo = (LPBITMAPINFOHEADER)LockResource(hres);
        !          1138:     qlng = (LPDWORD)((PBYTE)(lpbihInfo) + lpbihInfo->biSize);
        !          1139: 
        !          1140:     for (i = 0; i < (1 << lpbihInfo->biBitCount); i++, qlng++) {
        !          1141:         if (*qlng == rgbReplace1)
        !          1142:             *qlng = rgbNew;
        !          1143:         else if (*qlng == rgbReplace2)
        !          1144:             *qlng = rgbNew2;
        !          1145:     }
        !          1146: 
        !          1147:     /*
        !          1148:      * First skip over the header structure.
        !          1149:      */
        !          1150:     lpbBits = (LPBYTE)(lpbihInfo + 1);
        !          1151: 
        !          1152:     /*
        !          1153:      * Skip the color table entries, if any.
        !          1154:      */
        !          1155:     lpbBits += (1 << (lpbihInfo->biBitCount)) * sizeof(RGBQUAD);
        !          1156: 
        !          1157:     /*
        !          1158:      * Create a color bitmap compatible with the display device.
        !          1159:      */
        !          1160:     if (hdcScreen = GetDC(NULL)) {
        !          1161:         hbmp = CreateDIBitmap(hdcScreen, lpbihInfo, (LONG)CBM_INIT,
        !          1162:                 lpbBits, (LPBITMAPINFO)lpbihInfo, DIB_RGB_COLORS);
        !          1163:         ReleaseDC(NULL, hdcScreen);
        !          1164:     }
        !          1165: 
        !          1166:     UnlockResource(hres);
        !          1167:     FreeResource(hres);
        !          1168: 
        !          1169:     return hbmp;
        !          1170: }
        !          1171: 
        !          1172: 
        !          1173: 
        !          1174: /************************************************************************
        !          1175: * RGBInvertRGB
        !          1176: *
        !          1177: * Reverses the RGB order of a color.  This needs to be done to match
        !          1178: * the resource file format of the color table.
        !          1179: *
        !          1180: ************************************************************************/
        !          1181: 
        !          1182: STATICFN DWORD RGBInvertRGB(
        !          1183:     DWORD rgb)
        !          1184: {
        !          1185:     return (DWORD)RGB(GetBValue(rgb), GetGValue(rgb), GetRValue(rgb));
        !          1186: }
        !          1187: 
        !          1188: 
        !          1189: 
        !          1190: /************************************************************************
        !          1191: * SizeRibbons
        !          1192: *
        !          1193: * This function positions and sizes the child ribbon and subclient
        !          1194: * windows in the dialog editor.  It needs to be called any time the
        !          1195: * size of the main windows changes.
        !          1196: *
        !          1197: * Arguments:
        !          1198: *   HWND hwnd - Parent window handle.
        !          1199: *
        !          1200: ************************************************************************/
        !          1201: 
        !          1202: STATICFN VOID SizeRibbons(
        !          1203:     HWND hwnd)
        !          1204: {
        !          1205:     RECT rcClient;
        !          1206: 
        !          1207:     if (hwndStatus && !IsIconic(hwnd)) {
        !          1208:         /*
        !          1209:          * Get the client area.
        !          1210:          */
        !          1211:         GetClientRect(hwnd, &rcClient);
        !          1212: 
        !          1213:         /*
        !          1214:          * Size/move the status and subclient window to fit
        !          1215:          * the new client area.
        !          1216:          */
        !          1217:         SetWindowPos(hwndStatus, NULL,
        !          1218:                 0, 0,
        !          1219:                 rcClient.right - rcClient.left,
        !          1220:                 min(rcClient.bottom - rcClient.top, gcyStatus),
        !          1221:                 SWP_NOACTIVATE | SWP_NOZORDER);
        !          1222: 
        !          1223:         SetWindowPos(ghwndSubClient, NULL,
        !          1224:                 0, gcyStatus,
        !          1225:                 rcClient.right - rcClient.left,
        !          1226:                 max((rcClient.bottom - rcClient.top) - gcyStatus, 0),
        !          1227:                 SWP_NOACTIVATE | SWP_NOZORDER);
        !          1228:     }
        !          1229: }
        !          1230: 
        !          1231: 
        !          1232: 
        !          1233: /****************************************************************************
        !          1234: * DialogTerminate
        !          1235: *
        !          1236: * This undoes what DialogInit does.  It should be called before terminating
        !          1237: * and after a DialogInit.
        !          1238: *
        !          1239: ****************************************************************************/
        !          1240: 
        !          1241: STATICFN VOID DialogTerminate(VOID)
        !          1242: {
        !          1243:     register INT i;
        !          1244: 
        !          1245:     /*
        !          1246:      * Save the Preferences data.
        !          1247:      */
        !          1248:     WriteEnv();
        !          1249: 
        !          1250:     if (hbmTabStop)
        !          1251:         DeleteObject(hbmTabStop);
        !          1252: 
        !          1253:     if (hbmTabStopSel)
        !          1254:         DeleteObject(hbmTabStopSel);
        !          1255: 
        !          1256:     if (ghbmDragHandle)
        !          1257:         DeleteObject(ghbmDragHandle);
        !          1258: 
        !          1259:     if (ghbmDragHandle2)
        !          1260:         DeleteObject(ghbmDragHandle2);
        !          1261: 
        !          1262:     if (ghDCMem)
        !          1263:         DeleteDC(ghDCMem);
        !          1264: 
        !          1265:     /*
        !          1266:      * Free the control type bitmaps.
        !          1267:      */
        !          1268:     for (i = 0; i < CCONTROLS; i++) {
        !          1269:         if (awcd[i].hbmCtrlType)
        !          1270:             DeleteObject(awcd[i].hbmCtrlType);
        !          1271: 
        !          1272:         if (awcd[i].hbmCtrlTypeSel)
        !          1273:             DeleteObject(awcd[i].hbmCtrlTypeSel);
        !          1274:     }
        !          1275: 
        !          1276:     /*
        !          1277:      * Free all the custom control links.  This must be done before the
        !          1278:      * app exits so that any loaded DLL's get unloaded!
        !          1279:      */
        !          1280:     while (gpclHead)
        !          1281:         RemoveCustomLink(gpclHead);
        !          1282: 
        !          1283:     if (hpenDarkGray)
        !          1284:         DeleteObject(hpenDarkGray);
        !          1285: 
        !          1286:     if (ghhkMsgFilter)
        !          1287:         UnhookWindowsHookEx(ghhkMsgFilter);
        !          1288: 
        !          1289:     if (lpfnRegisterPenApp)
        !          1290:         (*lpfnRegisterPenApp)((WORD)1, FALSE);
        !          1291: }

unix.superglobalmegacorp.com

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