Annotation of mstools/samples/sdktools/dlgedit/util.c, revision 1.1.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: util.c
                     14: *
                     15: * Contains miscellaneous utility functions for dlgedit.
                     16: *
                     17: * Functions:
                     18: *   MyAlloc()
                     19: *   MyRealloc()
                     20: *   MyFree()
                     21: *   IsValue()
                     22: *   HasBlanks()
                     23: *   valtoi()
                     24: *   axtoi()
                     25: *   Myitoa()
                     26: *   itoax()
                     27: *   IsUniqueID()
                     28: *   NextID()
                     29: *   Message()
                     30: *   ClientToScreenRect()
                     31: *   ScreenToClientRect()
                     32: *   DUToWinPoint()
                     33: *   WinToDUPoint()
                     34: *   DUToWinRect()
                     35: *   WinToDURect()
                     36: *   MapDlgClientPoint()
                     37: *   MapWindowPoint()
                     38: *   MyMapWindowRect()
                     39: *   GetChildRect()
                     40: *   CenterWindow()
                     41: *   FitRectToScreen()
                     42: *   ids()
                     43: *   PixelsToPointSize()
                     44: *   PointSizeToPixels()
                     45: *
                     46: * Comments:
                     47: *
                     48: ****************************************************************************/
                     49: 
                     50: #include "dlgedit.h"
                     51: #include "dlgfuncs.h"
                     52: #include "dlgextrn.h"
                     53: 
                     54: #include <stdarg.h>
                     55: #include <ctype.h>
                     56: 
                     57: 
                     58: #define CBOVERHEAD      (sizeof(INT)+sizeof(INT)+sizeof(INT))
                     59: #define MEMSIGHEAD      0x1234
                     60: #define MEMSIGTAIL      0x5678
                     61: 
                     62: 
                     63: STATICFN BOOL IDUsedByCtrl(INT id);
                     64: 
                     65: 
                     66: 
                     67: /****************************************************************************
                     68: * MyAlloc
                     69: *
                     70: * Does a local alloc.
                     71: * 
                     72: * Arguments:
                     73: *   INT cbAlloc - number of bytes to allocate.
                     74: *
                     75: * Returns:
                     76: *
                     77: * A pointer to the memory if succesful; otherwise, NULL.
                     78: *
                     79: ****************************************************************************/
                     80: 
                     81: VOID *MyAlloc(
                     82:     INT cbAlloc)
                     83: {
                     84:     register HANDLE hMem;
                     85: 
                     86:     if (hMem = LocalAlloc(LMEM_FIXED, cbAlloc)) {
                     87:         return (VOID *)hMem;
                     88:     }
                     89:     else {
                     90:         MessageBeep(0);
                     91:         Message(MSG_OUTOFMEMORY);
                     92: 
                     93:         return NULL;
                     94:     }
                     95: }
                     96: 
                     97: 
                     98: /****************************************************************************
                     99: * MyRealloc
                    100: *
                    101: * reallocates memory and returns a pointer to the memory block.
                    102: *
                    103: ****************************************************************************/
                    104: 
                    105: VOID *MyRealloc(
                    106:     VOID *npMem,
                    107:     INT cbNewAlloc)
                    108: {
                    109:     npMem = (VOID *)LocalReAlloc((HANDLE)npMem, cbNewAlloc, LMEM_MOVEABLE);
                    110: 
                    111:     if (!npMem) {
                    112:         MessageBeep(0);
                    113:         Message(MSG_OUTOFMEMORY);
                    114: 
                    115:         return NULL;
                    116:     }
                    117: 
                    118:     return npMem;
                    119: }
                    120: 
                    121: /****************************************************************************
                    122: * MyFree
                    123: *
                    124: * Frees the specified memory.
                    125: *
                    126: ****************************************************************************/
                    127: 
                    128: VOID *MyFree(
                    129:     VOID *npMem)
                    130: {
                    131:     if (LocalFree((HANDLE)npMem)) {
                    132:         MessageBeep(0);
                    133:         Message(MSG_MEMERROR);
                    134: 
                    135:         return npMem;
                    136:     }
                    137: 
                    138:     return NULL;
                    139: }
                    140: 
                    141: 
                    142: 
                    143: /************************************************************************
                    144: * IsValue
                    145: *
                    146: * This function tells you if the string you give it represents a
                    147: * valid value or not.  For this purpose, a valid value can only
                    148: * have the ascii characters from '0' to '9' with possibly the
                    149: * first character being '-'.  Or be a Hex Number, with 0x preceeding
                    150: * it.
                    151: *
                    152: * Arguments:
                    153: *     LPTSTR pszValue  = The string to test.
                    154: *
                    155: * Returns:
                    156: *     (0 == 0) if szValue represents a value.
                    157: *     (c == 0) if szValue does not represent a value where c is
                    158: *               non-zero.
                    159: *
                    160: *
                    161: ************************************************************************/
                    162: 
                    163: BOOL IsValue(
                    164:     LPTSTR pszValue)
                    165: {
                    166:     INT i;
                    167: 
                    168:     if (pszValue[0] == CHAR_0 &&
                    169:             (pszValue[1] == CHAR_X || pszValue[1] == CHAR_CAP_X)) {
                    170:         for (i = 2; iswxdigit(pszValue[i]); i++)
                    171:             ;
                    172:     }
                    173:     else {
                    174:         for (i = 0; iswdigit(pszValue[i]) ||
                    175:                 (i == 0 && pszValue[i] == CHAR_MINUS); i++)
                    176:             ;
                    177:     }
                    178: 
                    179:     return (pszValue[i] == 0);
                    180: }
                    181: 
                    182: 
                    183: 
                    184: /************************************************************************
                    185: * HasBlanks
                    186: *
                    187: * This function returns TRUE if the given string has imbedded
                    188: * blanks in it.
                    189: *
                    190: * Arguments:
                    191: *   LPTSTR psz - String to check.
                    192: *
                    193: *
                    194: ************************************************************************/
                    195: 
                    196: BOOL HasBlanks(
                    197:     LPTSTR psz)
                    198: {
                    199:     while (*psz)
                    200:         if (*psz++ == CHAR_SPACE)
                    201:             return TRUE;
                    202: 
                    203:     return FALSE;
                    204: }
                    205: 
                    206: 
                    207: 
                    208: /************************************************************************
                    209: * valtoi
                    210: *
                    211: * Takes a string and returns its integer representation.
                    212: * This function handles both hex ("0x1234") and decimal ("1234")
                    213: * strings transparently.
                    214: *
                    215: * Arguments:
                    216: *   LPTSTR pszValue = The string to convert.
                    217: *
                    218: *
                    219: ************************************************************************/
                    220: 
                    221: INT valtoi(
                    222:     LPTSTR pszValue)
                    223: {
                    224:     return (pszValue[0] == CHAR_0 &&
                    225:             (pszValue[1] == CHAR_CAP_X || pszValue[1] == CHAR_X)) ?
                    226:             axtoi(&pszValue[2]) : awtoi(pszValue);
                    227: }
                    228: 
                    229: 
                    230: 
                    231: /************************************************************************
                    232: * axtoi
                    233: *
                    234: * This function converts a null terminated ascii string for a
                    235: * hex number to its integer value.  Should just be the number
                    236: * with no preceeding "0x" or trailing "H".  Garbage will result
                    237: * if there are non-hex digits in the string.  Hex digits are:
                    238: * 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, a, b, c, d, e, f.
                    239: * Non-hex digits will be treated like '0'.
                    240: *
                    241: * Arguments:
                    242: *     LPTSTR pch  = The null terminated hex string.
                    243: *
                    244: * Returns:
                    245: *     The integer value represented by the given ascii string.
                    246: *
                    247: ************************************************************************/
                    248: 
                    249: INT axtoi(
                    250:     LPTSTR pch)
                    251: {
                    252:     register TCHAR ch;
                    253:     register INT n = 0;
                    254: 
                    255:     while((ch = *pch++) != 0) {
                    256:         if (iswdigit(ch))
                    257:             ch -= CHAR_0;
                    258:         else if (ch >= CHAR_CAP_A && ch <= CHAR_CAP_F)
                    259:             ch += (TCHAR)(10 - CHAR_CAP_A);
                    260:         else if (ch >= CHAR_A && ch <= CHAR_F)
                    261:             ch += (TCHAR)(10 - CHAR_A);
                    262:         else
                    263:             ch = (TCHAR)0;
                    264: 
                    265:         n = 16 * n + ch;
                    266:     }
                    267: 
                    268:     return n;
                    269: }
                    270: 
                    271: 
                    272: 
                    273: /************************************************************************
                    274: * Myitoa
                    275: *
                    276: * This function converts a word to an ascii string.  It builds either
                    277: * a decimal string or a hex string, based on whether Hex Mode is on
                    278: * when it is called.
                    279: *
                    280: * Arguments:
                    281: *   INT n      - The number to convert.
                    282: *   LPTSTR psz - The buffer to put the string in, should have at least
                    283: *                17 bytes to take the string.
                    284: *
                    285: ************************************************************************/
                    286: 
                    287: VOID Myitoa(
                    288:     INT n,
                    289:     LPTSTR psz)
                    290: {
                    291:     if (gfHexMode)
                    292:         itoax(n, psz);
                    293:     else
                    294:         itoaw(n, psz, 10);
                    295: }
                    296: 
                    297: 
                    298: 
                    299: /************************************************************************
                    300: * itoax
                    301: *
                    302: * This function converts an int, 'n', to an ascii string
                    303: * representing it as a 4 digit hex number with "0x" preceeding it.
                    304: *
                    305: * Arguments:
                    306: *   INT n          = The number to convert.
                    307: *   LPTSTR pszBuff = The buffer to put the string in, must
                    308: *                    be at least 7 characters long to take the string.
                    309: *
                    310: *
                    311: ************************************************************************/
                    312: 
                    313: VOID itoax(
                    314:     INT n,
                    315:     LPTSTR pszBuff)
                    316: {
                    317:     INT i;
                    318:     INT j;
                    319: 
                    320:     pszBuff[0] = CHAR_0;
                    321:     pszBuff[1] = CHAR_X;
                    322: 
                    323:     for (i = 5; i > 1; i--) {
                    324:         j = n & 15;
                    325: 
                    326:         if (j > 9)
                    327:             pszBuff[i] = (TCHAR)(j + (CHAR_A - 10));
                    328:         else
                    329:             pszBuff[i] = (TCHAR)(j + CHAR_0);
                    330: 
                    331:         n = n >> 4;
                    332:     }
                    333: 
                    334:     pszBuff[6] = CHAR_NULL;
                    335: }
                    336: 
                    337: 
                    338: 
                    339: /************************************************************************
                    340: * NextID
                    341: *
                    342: * This function returns the next available id.
                    343: *
                    344: * For dialogs, it starts at 100 and increments by 100.  It will not
                    345: * return a value until it finds one that begins a range that is
                    346: * not used by any control in any of the dialogs in the res list.
                    347: * In other words, it is guaranteed that the number returned and
                    348: * the range of the next 99 numbers are not used by any control in
                    349: * any dialog in the current res file.
                    350: *
                    351: * When returning a new id for a control, it usually starts at the
                    352: * dialog base, but if there are any controls, it starts at one higher
                    353: * than the id of the last control in the dialog that does not have
                    354: * one of the special-cased ids (the unused id, IDOK or IDCANCEL).
                    355: * It will find the first available id above this.
                    356: *
                    357: * When returning a default id for a new label, it starts at the dialog
                    358: * base (or 100 if there is not a dialog being edited) and starts
                    359: * searching for the first available one.  It guarantees that the
                    360: * id returned is not used by any control in the current dialog, or
                    361: * any other label, or any control in the entire resource list.
                    362: *
                    363: * Arguments:
                    364: *   INT idType      - The type of id desired:
                    365: *                     NEXTID_DIALOG  = ID for a new dialog.
                    366: *                     NEXTID_CONTROL = ID for a new control.
                    367: *                     NEXTID_LABEL   = ID for a new label.
                    368: *   NPLABEL plHead  - The current label list to check for conflicts with.
                    369: *   INT idExclude   - An id that you specifically want to skip over.
                    370: *                     Set to zero if you don't care.
                    371: *
                    372: * Returns:
                    373: *     The "next" unused id value.
                    374: *
                    375: *
                    376: ************************************************************************/
                    377: 
                    378: INT NextID(
                    379:     INT idType,
                    380:     NPLABEL plHead,
                    381:     INT idExclude)
                    382: {
                    383:     INT id;
                    384: 
                    385:     if (idType == NEXTID_CONTROL) {
                    386:         /*
                    387:          * Start at the base from the dialog plus one.  It is
                    388:          * assumed that this routine will not be called for an
                    389:          * id for a control if there is not a dialog being
                    390:          * edited first.
                    391:          */
                    392:         id = gcd.npc->id + 1;
                    393: 
                    394:         /*
                    395:          * Keep looping until an unused id is found.
                    396:          */
                    397:         while (!IsUniqueID(id) || FindID(id, plHead) || id == idExclude)
                    398:             id++;
                    399:     }
                    400:     else if (idType == NEXTID_DIALOG) {
                    401:         /*
                    402:          * Start at 100.
                    403:          */
                    404:         id = 100;
                    405: 
                    406:         /*
                    407:          * Keep looping by hundreds until an unused id is found.
                    408:          */
                    409:         while (!IsUniqueID(id) || FindID(id, plHead) || id == idExclude)
                    410:             id += 100;
                    411:     }
                    412:     else {
                    413:         /*
                    414:          * We are looking for a default id for a new label.  Start
                    415:          * at the dialog base, if there is a dialog being edited.
                    416:          */
                    417:         if (gfEditingDlg)
                    418:             id = gcd.npc->id + 1;
                    419:         else
                    420:             id = 100;
                    421: 
                    422:         /*
                    423:          * Keep looping until an unused id is found.  The id should
                    424:          * not be used by any control in the current dialog, any
                    425:          * other label already, or any control in the res file.
                    426:          */
                    427:         while (FindID(id, plHead) || FindIDInRes(id) || id == idExclude)
                    428:             id++;
                    429:     }
                    430: 
                    431:     /*
                    432:      * We found an unused one.  Return it.
                    433:      */
                    434:     return id;
                    435: }
                    436: 
                    437: 
                    438: 
                    439: /************************************************************************
                    440: * IDUsedByCtrl
                    441: *
                    442: * This function returns TRUE if the given ID is used by any control
                    443: * in the current dialog.  This also counts the text field of W_ICON
                    444: * controls, if they are ordinals.
                    445: *
                    446: * Arguments:
                    447: *   INT id = The ID to look for.
                    448: *
                    449: * Returns:
                    450: *   TRUE if the id is used, FALSE if not.
                    451: *
                    452: *
                    453: ************************************************************************/
                    454: 
                    455: STATICFN BOOL IDUsedByCtrl(
                    456:     INT id)
                    457: {
                    458:     register NPCTYPE npc;
                    459: 
                    460:     for (npc = npcHead; npc; npc = npc->npcNext) {
                    461:         if (npc->id == id ||
                    462:                 (npc->pwcd->iType == W_ICON &&
                    463:                 npc->text &&
                    464:                 IsOrd(npc->text) &&
                    465:                 id == (INT)OrdID(npc->text)))
                    466:             return TRUE;
                    467:     }
                    468: 
                    469:     return FALSE;
                    470: }
                    471: 
                    472: 
                    473: 
                    474: /************************************************************************
                    475: * IsUniqueID
                    476: *
                    477: * This function returns TRUE if the given id is unique.  A unique
                    478: * id is either the special "unused" id value, or it is an id that
                    479: * is not already assigned to any other control in the current dialog
                    480: * and it is not assigned to any other dialog in the current res list.
                    481: *
                    482: * Note that this routine does NOT look for duplicates in the include
                    483: * file of this id, only for ids that have been used by other controls
                    484: * or dialogs already.
                    485: *
                    486: * Arguments:
                    487: *   INT id = The id to verify is unique.
                    488: *
                    489: * Returns:
                    490: *   TRUE if the id is "unique", FALSE if it is not.
                    491: *
                    492: *
                    493: ************************************************************************/
                    494: 
                    495: BOOL IsUniqueID(
                    496:     INT id)
                    497: {
                    498:     ORDINAL ord;
                    499: 
                    500:     /*
                    501:      * If the id is the special unused id, it is considered unique.
                    502:      */
                    503:     if (id == IDUNUSED)
                    504:         return TRUE;
                    505: 
                    506:     /*
                    507:      * Not unique if another control in the dialog has the same id.
                    508:      */
                    509:     if (IDUsedByCtrl(id))
                    510:         return FALSE;
                    511: 
                    512:     /*
                    513:      * Not unique if another dialog has the same id.
                    514:      */
                    515:     WriteOrd(&ord, id);
                    516:     if (FindDialog((LPTSTR)&ord))
                    517:         return FALSE;
                    518: 
                    519:     return TRUE;
                    520: }
                    521: 
                    522: 
                    523: 
                    524: /************************************************************************
                    525: * Message
                    526: *
                    527: * This function puts up a message box with a string indexed by idMsg.
                    528: *
                    529: * Returns:
                    530: *     What MessageBox returns.
                    531: *
                    532: ************************************************************************/
                    533: 
                    534: INT Message(
                    535:     INT idMsg,
                    536:     ...)
                    537: {
                    538:     va_list marker;
                    539:     INT RetCode;
                    540:     TCHAR szT[CCHTEXTMAX];
                    541:     BOOL fDisabledSave;
                    542: 
                    543:     va_start(marker, idMsg);
                    544:     wvsprintf(szT, ids(gamdMessages[idMsg].ids), marker);
                    545: 
                    546:     fDisabledSave = gfDisabled;
                    547:     gfDisabled = TRUE;
                    548:     RetCode = MessageBox(NULL, szT, ids(IDS_DLGEDIT),
                    549:             (WORD)(gamdMessages[idMsg].fMessageBox | MB_TASKMODAL));
                    550:     gfDisabled = fDisabledSave;
                    551: 
                    552:     va_end(marker);
                    553: 
                    554:     return RetCode;
                    555: }
                    556: 
                    557: 
                    558: 
                    559: /************************************************************************
                    560: * ClientToScreenRect
                    561: *
                    562: * This function converts the coordinates in a rectangle from points
                    563: * relative to the client area into points that are relative to the
                    564: * screen.
                    565: *
                    566: * Arguments:
                    567: *   HWND hwnd - Window handle for the conversion.
                    568: *   PRECT prc - Pointer to the rectangle to convert.
                    569: *
                    570: *
                    571: ************************************************************************/
                    572: 
                    573: VOID ClientToScreenRect(
                    574:     HWND hwnd,
                    575:     PRECT prc)
                    576: {
                    577:     ClientToScreen(hwnd, (PPOINT)prc);
                    578:     ClientToScreen(hwnd, ((PPOINT)prc) + 1);
                    579: }
                    580: 
                    581: 
                    582: 
                    583: /************************************************************************
                    584: * ScreenToClientRect
                    585: *
                    586: * This function converts the coordinates in a rectangle from points
                    587: * relative to the screen into points that are relative to the given
                    588: * window's client area.
                    589: *
                    590: * Arguments:
                    591: *   HWND hwnd - Window handle for the conversion.
                    592: *   PRECT prc - Pointer to the rectangle to convert.
                    593: *
                    594: *
                    595: ************************************************************************/
                    596: 
                    597: VOID ScreenToClientRect(
                    598:     HWND hwnd,
                    599:     PRECT prc)
                    600: {
                    601:     ScreenToClient(hwnd, (PPOINT)prc);
                    602:     ScreenToClient(hwnd, ((PPOINT)prc) + 1);
                    603: }
                    604: 
                    605: 
                    606: 
                    607: /************************************************************************
                    608: * DUToWinPoint
                    609: *
                    610: * This function converts the coordinates in the given point from
                    611: * dialog units (DU's) to window units for the current dialog.
                    612: *
                    613: * Arguments:
                    614: *   PPOINT ppt - Pointer to the point to convert.
                    615: *
                    616: *
                    617: ************************************************************************/
                    618: 
                    619: VOID DUToWinPoint(
                    620:     PPOINT ppt)
                    621: {
                    622:     ppt->x = MulDiv(ppt->x, gcd.cxChar, 4);
                    623:     ppt->y = MulDiv(ppt->y, gcd.cyChar, 8);
                    624: }
                    625: 
                    626: 
                    627: 
                    628: /************************************************************************
                    629: * WinToDUPoint
                    630: *
                    631: * This function converts the coordinates in the given point from
                    632: * window points to dialog units (DU's) for the current dialog.
                    633: *
                    634: * Arguments:
                    635: *   PPOINT ppt - Pointer to the point to convert.
                    636: *
                    637: *
                    638: ************************************************************************/
                    639: 
                    640: VOID WinToDUPoint(
                    641:     PPOINT ppt)
                    642: {
                    643:     ppt->x = MulDiv(ppt->x, 4, gcd.cxChar);
                    644:     ppt->y = MulDiv(ppt->y, 8, gcd.cyChar);
                    645: }
                    646: 
                    647: 
                    648: 
                    649: /************************************************************************
                    650: * DUToWinRect
                    651: *
                    652: * This function converts the coordinates in a rectangle from
                    653: * dialog units for the current dialog to window units.
                    654: *
                    655: * Arguments:
                    656: *   PRECT prc - Pointer to the rectangle to convert.
                    657: *
                    658: *
                    659: ************************************************************************/
                    660: 
                    661: VOID DUToWinRect(
                    662:     PRECT prc)
                    663: {
                    664:     DUToWinPoint((PPOINT)prc);
                    665:     DUToWinPoint(((PPOINT)prc) + 1);
                    666: }
                    667: 
                    668: 
                    669: 
                    670: /************************************************************************
                    671: * WinToDURect
                    672: *
                    673: * This function converts the coordinates in a rectangle from
                    674: * window units to dialog units for the current dialog.
                    675: *
                    676: * Arguments:
                    677: *   PRECT prc - Pointer to the rectangle to convert.
                    678: *
                    679: *
                    680: ************************************************************************/
                    681: 
                    682: VOID WinToDURect(
                    683:     PRECT prc)
                    684: {
                    685:     WinToDUPoint((PPOINT)prc);
                    686:     WinToDUPoint(((PPOINT)prc) + 1);
                    687: }
                    688: 
                    689: 
                    690: 
                    691: /************************************************************************
                    692: * MapDlgClientPoint
                    693: *
                    694: * This function converts client points to be relative to the window
                    695: * origin instead, or the other way around.  If fFromClient is TRUE,
                    696: * the point is considered to be relative to the client origin in
                    697: * the dialog, and will be converted to a point relative to the
                    698: * window origin instead.
                    699: *
                    700: * If fFromClient is FALSE, the point is considered to be relative
                    701: * to the window origin, and will be mapped to a point that is
                    702: * relative to the client origin.
                    703: *
                    704: * This function assumes that the global grcDlgClient has been
                    705: * previously calculated.  It should only be called to map points
                    706: * for the current dialog being edited (for which grcDlgClient has
                    707: * been calculated).
                    708: *
                    709: * Arguments:
                    710: *   PPOINT ppt       - Pointer to the point to convert.
                    711: *   BOOL fFromClient - TRUE if the point is relative to the client origin.
                    712: *
                    713: *
                    714: ************************************************************************/
                    715: 
                    716: VOID MapDlgClientPoint(
                    717:     PPOINT ppt,
                    718:     BOOL fFromClient)
                    719: {
                    720:     if (fFromClient) {
                    721:         ppt->x += grcDlgClient.left;
                    722:         ppt->y += grcDlgClient.top;
                    723:     }
                    724:     else {
                    725:         ppt->x -= grcDlgClient.left;
                    726:         ppt->y -= grcDlgClient.top;
                    727:     }
                    728: }
                    729: 
                    730: 
                    731: 
                    732: /************************************************************************
                    733: * MapWindowPoint
                    734: *
                    735: * This function maps a point from one window to another.  The point
                    736: * given is in window coordinates (not client coordinates) and is
                    737: * mapped so that it is relative to the destination window.
                    738: *
                    739: * Arguments:
                    740: *   HWND hwndFrom   - Source window.
                    741: *   HWND hwndTo     - Destination window.
                    742: *   PPOINT ppt      - Pointer to the point to convert.
                    743: *
                    744: * Comments:
                    745: * In Win 3.1 (and NT) the MapWindowPoints call can be used and this one can be removed.
                    746: * It is only needed here for compatibility with Win 3.0.
                    747: *
                    748: ************************************************************************/
                    749: 
                    750: VOID MapWindowPoint(
                    751:     HWND hwndFrom,
                    752:     HWND hwndTo,
                    753:     PPOINT ppt)
                    754: {
                    755:     RECT rcFrom;
                    756:     RECT rcTo;
                    757: 
                    758:     GetWindowRect(hwndFrom, &rcFrom);
                    759:     GetWindowRect(hwndTo, &rcTo);
                    760: 
                    761:     ppt->x += rcFrom.left - rcTo.left;
                    762:     ppt->y += rcFrom.top - rcTo.top;
                    763: }
                    764: 
                    765: 
                    766: 
                    767: /************************************************************************
                    768: * MyMapWindowRect
                    769: *
                    770: * This function maps a rectangle from one window to another.  The rectangle
                    771: * given is in window coordinates (not client coordinates) and is
                    772: * mapped so that it is relative to the destination window.
                    773: *
                    774: * Arguments:
                    775: *   HWND hwndFrom   - Source window.
                    776: *   HWND hwndTo     - Destination window.
                    777: *   PRECT prc       - Pointer to the rectangle to convert.
                    778: *
                    779: * Comments:
                    780: * In Win 3.1 (and NT) the MapWindowRect call can be used and this one can be removed.
                    781: * It is only needed here for compatibility with Win 3.0.
                    782: ************************************************************************/
                    783: 
                    784: VOID MyMapWindowRect(
                    785:     HWND hwndFrom,
                    786:     HWND hwndTo,
                    787:     PRECT prc)
                    788: {
                    789:     RECT rcFrom;
                    790:     RECT rcTo;
                    791: 
                    792:     GetWindowRect(hwndFrom, &rcFrom);
                    793:     GetWindowRect(hwndTo, &rcTo);
                    794: 
                    795:     OffsetRect(prc, rcFrom.left - rcTo.left, rcFrom.top - rcTo.top);
                    796: }
                    797: 
                    798: 
                    799: 
                    800: /************************************************************************
                    801: * GetChildRect
                    802: *
                    803: * This function returns the client rectangle for a given child control,
                    804: * mapped to its parent window.
                    805: *
                    806: * Arguments:
                    807: *   HWND hwndChild - Child window.
                    808: *   PRECT prc      - Where to return the rectangle.
                    809: *
                    810: ************************************************************************/
                    811: 
                    812: VOID GetChildRect(
                    813:     HWND hwndChild,
                    814:     PRECT prc)
                    815: {
                    816:     HWND hwndParent;
                    817: 
                    818:     hwndParent = GetParent(hwndChild);
                    819:     GetClientRect(hwndChild, prc);
                    820:     ClientToScreenRect(hwndChild, prc);
                    821:     ScreenToClientRect(hwndParent, prc);
                    822: }
                    823: 
                    824: 
                    825: 
                    826: /************************************************************************
                    827: * CenterWindow
                    828: *
                    829: * This function centers the given window over its owner.  It ensures
                    830: * that the window is entirely within the visible screen, however.
                    831: * If the window does not have an owner, it is centered over the
                    832: * desktop.
                    833: *
                    834: * Arguments:
                    835: *   HWND hwnd - The window to center.
                    836: *
                    837: ************************************************************************/
                    838: 
                    839: VOID CenterWindow(
                    840:     HWND hwnd)
                    841: {
                    842:     RECT rc;
                    843:     RECT rcOwner;
                    844:     RECT rcCenter;
                    845:     HWND hwndOwner;
                    846: 
                    847:     GetWindowRect(hwnd, &rc);
                    848: 
                    849:     if (!(hwndOwner = GetWindow(hwnd, GW_OWNER)))
                    850:         hwndOwner = GetDesktopWindow();
                    851: 
                    852:     GetWindowRect(hwndOwner, &rcOwner);
                    853: 
                    854:     /*
                    855:      *  Calculate the starting x,y for the new
                    856:      *  window so that it would be centered.
                    857:      */
                    858:     rcCenter.left = rcOwner.left +
                    859:             (((rcOwner.right - rcOwner.left) -
                    860:             (rc.right - rc.left))
                    861:             / 2);
                    862: 
                    863:     rcCenter.top = rcOwner.top +
                    864:             (((rcOwner.bottom - rcOwner.top) -
                    865:             (rc.bottom - rc.top))
                    866:             / 2);
                    867: 
                    868:     rcCenter.right = rcCenter.left + (rc.right - rc.left);
                    869:     rcCenter.bottom = rcCenter.top + (rc.bottom - rc.top);
                    870: 
                    871:     FitRectToScreen(&rcCenter);
                    872: 
                    873:     SetWindowPos(hwnd, NULL, rcCenter.left, rcCenter.top, 0, 0,
                    874:             SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER);
                    875: }
                    876: 
                    877: 
                    878: 
                    879: /************************************************************************
                    880: * FitRectToScreen
                    881: *
                    882: * This function ensures that the given rectangle is entirely within
                    883: * the visible screen, adjusting it if necessary.
                    884: *
                    885: * Arguments:
                    886: *   PRECT prc - The rectangle.
                    887: *
                    888: ************************************************************************/
                    889: 
                    890: VOID FitRectToScreen(
                    891:     PRECT prc)
                    892: {
                    893:     INT cxScreen;
                    894:     INT cyScreen;
                    895:     INT delta;
                    896: 
                    897:     cxScreen = GetSystemMetrics(SM_CXSCREEN);
                    898:     cyScreen = GetSystemMetrics(SM_CYSCREEN);
                    899: 
                    900:     if (prc->right > cxScreen) {
                    901:         delta = prc->right - prc->left;
                    902:         prc->right = cxScreen;
                    903:         prc->left = prc->right - delta;
                    904:     }
                    905: 
                    906:     if (prc->left < 0) {
                    907:         delta = prc->right - prc->left;
                    908:         prc->left = 0;
                    909:         prc->right = prc->left + delta;
                    910:     }
                    911: 
                    912:     if (prc->bottom > cyScreen) {
                    913:         delta = prc->bottom - prc->top;
                    914:         prc->bottom = cyScreen;
                    915:         prc->top = prc->bottom - delta;
                    916:     }
                    917: 
                    918:     if (prc->top < 0) {
                    919:         delta = prc->bottom - prc->top;
                    920:         prc->top = 0;
                    921:         prc->bottom = prc->top + delta;
                    922:     }
                    923: }
                    924: 
                    925: 
                    926: 
                    927: /************************************************************************
                    928: * ids
                    929: *
                    930: * This function will return a string, given the string id.  If this is
                    931: * the first time that the string has been retrieved, memory will be
                    932: * allocated for it and it will be loaded.  After it is loaded once, it
                    933: * is then cached in a LPTSTR array and is available for later without
                    934: * having to load it again.
                    935: *
                    936: * Arguments:
                    937: *   UINT idString - String ID of the string to retrieve.
                    938: *
                    939: ************************************************************************/
                    940: 
                    941: LPTSTR ids(
                    942:     UINT idString)
                    943: {
                    944:     static LPTSTR apsz[CSTRINGS];       // String resource array cache.
                    945:     LPTSTR psz;
                    946:     INT cch;
                    947: 
                    948:     if (apsz[idString])
                    949:         return apsz[idString];
                    950: 
                    951:     if (!(psz = MyAlloc(CCHTEXTMAX * sizeof(TCHAR))))
                    952:         return szEmpty;
                    953: 
                    954:     if (!(cch = LoadString(ghInst, idString, psz, CCHTEXTMAX))) {
                    955:         MyFree(psz);
                    956:         return szEmpty;
                    957:     }
                    958: 
                    959:     apsz[idString] = psz = MyRealloc(psz, (cch + 1) * sizeof(TCHAR));
                    960: 
                    961:     return (psz ? psz : szEmpty);
                    962: }
                    963: 
                    964: 
                    965: 
                    966: /************************************************************************
                    967: * PixelsToPointSize
                    968: *
                    969: * This function takes a font height in pixels and converts it to
                    970: * the equivalent point size.  Note that the pixel height of a font
                    971: * is actually the tmHeight field of the TEXTMETRIC structure minus
                    972: * the tmInternalLeading value.
                    973: *
                    974: * This function relies on the global gcyPixelsPerInch having been
                    975: * set before it is called.
                    976: *
                    977: * Arguments:
                    978: *   INT nPixels - Pixel size to convert to point size.
                    979: *
                    980: ************************************************************************/
                    981: 
                    982: INT PixelsToPointSize(
                    983:     INT nPixels)
                    984: {
                    985:     return MulDiv(nPixels, 72, gcyPixelsPerInch);
                    986: }
                    987: 
                    988: 
                    989: 
                    990: /************************************************************************
                    991: * PointSizeToPixels
                    992: *
                    993: * This function takes a given point size and converts it to the
                    994: * equivalent pixel text height.  This value can be placed in
                    995: * the TEXTMETRIC structure's tmHeight field if it is made negative
                    996: * first.  This will cause a CreateFont call to automatically
                    997: * subtract the internal leading value before creating the font.
                    998: *
                    999: * This function relies on the global gcyPixelsPerInch having been
                   1000: * set before it is called.
                   1001: *
                   1002: * Arguments:
                   1003: *   INT nPointSize - Point size to convert to pixels.
                   1004: *
                   1005: ************************************************************************/
                   1006: 
                   1007: INT PointSizeToPixels(
                   1008:     INT nPointSize)
                   1009: {
                   1010:     return MulDiv(nPointSize, gcyPixelsPerInch, 72);
                   1011: }
                   1012: 
                   1013: 
                   1014: 

unix.superglobalmegacorp.com

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