Annotation of mstools/samples/ddeml/clock/clock.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *  CLOCK.C - Windows Clock
                      3:  *
                      4:  */
                      5: 
                      6: #include <time.h>
                      7: #include <stdlib.h>
                      8: #include <stdio.h>
                      9: #include <string.h>
                     10: #include "windows.h"
                     11: #include "windowsx.h"
                     12: #include <ddeml.h>
                     13: #include "clock.h"
                     14: // #include "shellapi.h"
                     15: 
                     16: 
                     17: DWORD idInst = 0;
                     18: BOOL    bIconic    = FALSE;
                     19: BOOL    bColor     = TRUE;
                     20: BOOL    bNewFont   = TRUE;
                     21: 
                     22: CLOCKDISPSTRUCT ClockDisp;
                     23: 
                     24: TRIG CirTab[] = {              // circle sin, cos, table
                     25:     { 0,     -7999  },
                     26:     { 836,   -7956  },
                     27:     { 1663,  -7825  },
                     28:     { 2472,  -7608  },
                     29:     { 3253,  -7308  },
                     30:     { 3999,  -6928  },
                     31:     { 4702,  -6472  },
                     32:     { 5353,  -5945  },
                     33:     { 5945,  -5353  },
                     34:     { 6472,  -4702  },
                     35:     { 6928,  -4000  },
                     36:     { 7308,  -3253  },
                     37:     { 7608,  -2472  },
                     38:     { 7825,  -1663  },
                     39:     { 7956,  -836   },
                     40: 
                     41:     { 8000,  0      },
                     42:     { 7956,  836    },
                     43:     { 7825,  1663   },
                     44:     { 7608,  2472   },
                     45:     { 7308,  3253   },
                     46:     { 6928,  4000   },
                     47:     { 6472,  4702   },
                     48:     { 5945,  5353   },
                     49:     { 5353,  5945   },
                     50:     { 4702,  6472   },
                     51:     { 3999,  6928   },
                     52:     { 3253,  7308   },
                     53:     { 2472,  7608   },
                     54:     { 1663,  7825   },
                     55:     { 836,   7956   },
                     56: 
                     57:     { 0,     7999   },
                     58:     { -836,  7956   },
                     59:     { -1663, 7825   },
                     60:     { -2472, 7608   },
                     61:     { -3253, 7308   },
                     62:     { -4000, 6928   },
                     63:     { -4702, 6472   },
                     64:     { -5353, 5945   },
                     65:     { -5945, 5353   },
                     66:     { -6472, 4702   },
                     67:     { -6928, 3999   },
                     68:     { -7308, 3253   },
                     69:     { -7608, 2472   },
                     70:     { -7825, 1663   },
                     71:     { -7956, 836    },
                     72: 
                     73:     { -7999, -0     },
                     74:     { -7956, -836   },
                     75:     { -7825, -1663  },
                     76:     { -7608, -2472  },
                     77:     { -7308, -3253  },
                     78:     { -6928, -4000  },
                     79:     { -6472, -4702  },
                     80:     { -5945, -5353  },
                     81:     { -5353, -5945  },
                     82:     { -4702, -6472  },
                     83:     { -3999, -6928  },
                     84:     { -3253, -7308  },
                     85:     { -2472, -7608  },
                     86:     { -1663, -7825  },
                     87:     { -836 , -7956  }
                     88: };
                     89: 
                     90: HANDLE  hInst;
                     91: HWND    hWindow;
                     92: 
                     93: HBRUSH  hbrBackground;
                     94: HBRUSH  hbrColorWindow;
                     95: HBRUSH  hbrColorBlack;
                     96: HBRUSH  hbrForeground;
                     97: HFONT   hFont;
                     98: HPEN    hpenForeground;
                     99: HPEN    hpenBackground;
                    100: 
                    101: INT     nLeadZero   = 0;
                    102: INT     TimerID     = 1;    /* number used for timer-id */
                    103: INT     clockRadius;
                    104: INT     HorzRes;
                    105: INT     VertRes;
                    106: 
                    107: LONG    aspectD;
                    108: LONG    aspectN;
                    109: 
                    110: CHAR    szBuffer[BUFLEN];    /* buffer for stringtable stuff */
                    111: CHAR    szFontFile[20];
                    112: CHAR    szIniFile[20];
                    113: CHAR    szSection[30];
                    114: 
                    115: POINT   clockCenter;
                    116: 
                    117: TIME    oTime;
                    118: 
                    119: RECT    clockRect;
                    120: RECT    rCoordRect;
                    121: 
                    122: HDDEDATA EXPENTRY DdeCallback(WORD usType, WORD usFmt, HCONV hConv, HSZ hsz1,
                    123:         HSZ hsz2, HDDEDATA hData, DWORD lData1, DWORD lData2);
                    124: HSZ hszTime, hszNow, hszClock;    /* Hszs for DDEML use */
                    125: 
                    126: /*
                    127:  *  Function Prototypes
                    128:  */
                    129: 
                    130: LONG APIENTRY ClockWndProc(register HWND hWnd, UINT message, WPARAM wParam, LONG lParam);
                    131: 
                    132: void NEAR PASCAL ClockCreate(HWND hWnd);
                    133: BOOL NEAR PASCAL ClockInit(HANDLE hInstance);
                    134: void NEAR PASCAL ClockPaint(HWND hWnd, register HDC hDC, INT hint);
                    135: void NEAR PASCAL ClockSize(register HWND hWnd,INT newWidth,INT newHeight, WORD SizeWord);
                    136: void NEAR PASCAL ClockTimer(HWND hWnd, UINT msg);
                    137: void NEAR PASCAL CompClockDim(void);
                    138: void NEAR PASCAL CreateTools(void);
                    139: void NEAR PASCAL DeleteTools(void);
                    140: void NEAR PASCAL DrawBorder(HWND hWnd, register HDC hDC);
                    141: void NEAR PASCAL DrawFace(HDC hDC);
                    142: void NEAR PASCAL DrawHand(register HDC hDC, INT pos, HPEN hPen, INT scale, INT patMode);
                    143: void NEAR PASCAL DrawFatHand(register HDC hDC, INT pos, HPEN hPen, BOOL hHand);
                    144: void NEAR PASCAL FormatInit(register HANDLE hInstance, BOOL fModeChange);
                    145: void NEAR PASCAL SizeFont(HWND hWnd, INT newHeight, INT newWidth, INT wlen);
                    146: 
                    147: 
                    148: 
                    149: /*
                    150:  *  CreateTools()
                    151:  */
                    152: 
                    153: void NEAR PASCAL CreateTools(void)
                    154: 
                    155: {
                    156:   hbrForeground  = CreateSolidBrush(GetSysColor(COLOR_WINDOWTEXT));
                    157:   hbrColorWindow = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
                    158:   hbrColorBlack  = CreateSolidBrush(0L);
                    159:   hbrBackground  = hbrColorWindow;
                    160:   hpenForeground = CreatePen(0, 1, GetSysColor(COLOR_WINDOWTEXT));
                    161:   hpenBackground = CreatePen(0, 1, GetSysColor(COLOR_WINDOW));
                    162: }
                    163: 
                    164: 
                    165: /*
                    166:  *  DeleteTools()
                    167:  */
                    168: 
                    169: void NEAR PASCAL DeleteTools(void)
                    170: 
                    171: {
                    172:   DeleteObject(hbrForeground);
                    173:   DeleteObject(hbrColorWindow);
                    174:   DeleteObject(hbrColorBlack);
                    175:   DeleteObject(hpenForeground);
                    176:   DeleteObject(hpenBackground);
                    177: }
                    178: 
                    179: 
                    180: /*
                    181:  * SizeFont() - size font according to window size
                    182:  */
                    183: 
                    184: void NEAR PASCAL SizeFont(HWND hWnd, INT newHeight, INT newWidth, INT wlen)
                    185: {
                    186: register HDC    hDC;
                    187: TEXTMETRIC    tm;
                    188: LOGFONT    FontStruct;
                    189: 
                    190:     hDC = GetDC(hWnd);
                    191:     GetTextMetrics(hDC, &tm);
                    192: 
                    193:     if (ClockDisp.wFormat == IDM_DIGITAL)
                    194:         {
                    195:         if (hFont != NULL)
                    196:             DeleteObject(hFont);
                    197: 
                    198:         FontStruct.lfUnderline = FALSE;
                    199:         FontStruct.lfStrikeOut = FALSE;
                    200:         FontStruct.lfItalic    = FALSE;
                    201:         FontStruct.lfEscapement = FALSE;
                    202:         FontStruct.lfOrientation = FALSE;
                    203:         FontStruct.lfOutPrecision = OUT_DEFAULT_PRECIS;
                    204:         FontStruct.lfClipPrecision = CLIP_DEFAULT_PRECIS;
                    205: 
                    206:         /* Note that the numbers used in this formula depend on the
                    207:          * size of the numbers in the fonts which are 12 vert, 7 horz.
                    208:         */
                    209:         if (!bIconic)
                    210:             {
                    211:             FontStruct.lfHeight = (SHORT)min(newHeight/2, 45);
                    212: 
                    213:             /* The formula at the end is somewhat empirical. */
                    214:             FontStruct.lfWidth = (SHORT)min(25, newWidth/(wlen*3/2));
                    215: 
                    216:             /* This if is here because of a problem where:  if a clock
                    217:              * existed with a maximum size font, any new clock with a
                    218:              * smaller client area would get the same font that would not
                    219:              * fit in the Window.  So here, if the width does not match
                    220:              * maximum font dimensions, don't use the maximum height.
                    221:              */
                    222:             if (FontStruct.lfWidth != 25 && FontStruct.lfHeight == 45)
                    223:                 FontStruct.lfHeight = 40;
                    224:             }
                    225:         else
                    226:             {
                    227:             FontStruct.lfHeight = (SHORT)(newHeight/3);
                    228:             FontStruct.lfWidth  = (SHORT)(newWidth/5);
                    229:             }
                    230: 
                    231:         FontStruct.lfCharSet      = ANSI_CHARSET;
                    232:         FontStruct.lfQuality      = DRAFT_QUALITY;
                    233:         FontStruct.lfWeight      = FW_NORMAL;
                    234:         FontStruct.lfPitchAndFamily = VARIABLE_PITCH | FF_SWISS;
                    235: 
                    236:         lstrcpy(FontStruct.lfFaceName, "DIGITAL");
                    237: 
                    238:         hFont = CreateFontIndirect(&FontStruct);
                    239: 
                    240:         SelectObject(hDC, hFont);
                    241:         GetTextMetrics(hDC, &tm);
                    242:         SelectObject(hDC, GetStockObject(SYSTEM_FONT));
                    243:     }
                    244: 
                    245:     ReleaseDC(hWnd, hDC);
                    246: 
                    247:     /* Compute placement for digital text. */
                    248:     ClockDisp.line1.x = (newWidth) / 2;
                    249:     ClockDisp.line1.y = (newHeight - (tm.tmHeight)) / 2;
                    250:     ClockDisp.yline2  = ClockDisp.line1.y + tm.tmHeight;
                    251: }
                    252: 
                    253: 
                    254: /*
                    255:  *  CompClockDim() - Recompute the clock's dimensions.
                    256:  */
                    257: 
                    258: void NEAR PASCAL CompClockDim(void)
                    259: 
                    260: {
                    261: INT        i;
                    262: register INT    tWidth;
                    263: register INT    tHeight;
                    264: 
                    265:     tWidth = clockRect.right - clockRect.left;
                    266:     tHeight = clockRect.bottom - clockRect.top;
                    267: 
                    268:     if (tWidth > (INT)((tHeight * aspectD) / aspectN))
                    269:         {
                    270:         i = (INT)((tHeight * aspectD) / aspectN);
                    271:         clockRect.left += (tWidth - i) >> 1;
                    272:         clockRect.right = clockRect.left + i;
                    273:         }
                    274:     else
                    275:         {
                    276:         i = (INT)((tWidth * aspectN) / aspectD);
                    277:         clockRect.top += (tHeight - i) >> 1;
                    278:         clockRect.bottom = clockRect.top + i;
                    279:         }
                    280: }
                    281: 
                    282: 
                    283: /*
                    284:  *  ClockSize()
                    285:  */
                    286: 
                    287: void NEAR PASCAL ClockSize(register HWND hWnd,
                    288:                INT       newWidth,
                    289:                INT       newHeight,
                    290:                WORD      SizeWord)
                    291: {
                    292:     SetRect((LPRECT)&(clockRect), 0, 0, newWidth, newHeight);
                    293:     CompClockDim();
                    294: 
                    295:     if (SizeWord == SIZEICONIC)
                    296:         {
                    297:         /* Update once every 1/2 minute in the iconic state */
                    298:         KillTimer(hWnd, TimerID);
                    299:     SetTimer(hWnd, TimerID, (WORD)ICON_TLEN, 0L);
                    300:         bIconic = TRUE;
                    301:         }
                    302:     else if (bIconic)
                    303:         {
                    304:         /* Update every 1/2 second in the opened state. */
                    305:         KillTimer(hWnd, TimerID);
                    306:         SetTimer(hWnd, TimerID, OPEN_TLEN, 0L);
                    307:         bIconic = FALSE;
                    308:         }
                    309: 
                    310:     /* Compute where the digital readout should go. */
                    311:     SizeFont(hWnd, newHeight, newWidth, ClockDisp.wDigTimeLen);
                    312: }
                    313: 
                    314: 
                    315: /*
                    316:  *  DrawBorder() - Draws a Red Border around either clock.
                    317:  */
                    318: 
                    319: void NEAR PASCAL DrawBorder(HWND hWnd, register HDC hDC)
                    320: {
                    321: RECT Rect;
                    322: HPEN hPen;
                    323: 
                    324:     GetClientRect(hWnd, (LPRECT) &Rect);
                    325: 
                    326:     hPen = CreatePen(PS_SOLID, (bIconic) ? 1 : 2,
                    327:                (bColor)  ? RGB(255,0,0) : RGB(255,255,255));
                    328: 
                    329:     SelectObject(hDC, hPen);
                    330:     Rectangle(hDC, Rect.left+1, Rect.top+1, Rect.right, Rect.bottom);
                    331:     SelectObject(hDC, GetStockObject(BLACK_PEN));
                    332: 
                    333:     DeleteObject(hPen);
                    334: 
                    335:     /* Draw an external black border on an icon without killing the client area. */
                    336:     if (bIconic)
                    337:         {
                    338:        MoveToEx(hDC, Rect.left, Rect.top, NULL);
                    339:         LineTo(hDC, Rect.left,  Rect.bottom);
                    340:         LineTo(hDC, Rect.right, Rect.bottom);
                    341:         LineTo(hDC, Rect.right, Rect.top);
                    342:         LineTo(hDC, Rect.left,  Rect.top);
                    343:         }
                    344: }
                    345: 
                    346: 
                    347: /*
                    348:  *  DrawFace()
                    349:  */
                    350: 
                    351: void NEAR PASCAL DrawFace(HDC hDC)
                    352: {
                    353: INT        i;
                    354: RECT       tRect;
                    355: INT        blobHeight, blobWidth;
                    356: 
                    357:     blobWidth = (INT)((MAXBLOBWIDTH * (LONG)(clockRect.right - clockRect.left)) / HorzRes);
                    358:     blobHeight = (INT)((blobWidth * aspectN) / aspectD);
                    359: 
                    360:     if (blobHeight < 2)
                    361:         blobHeight = 1;
                    362: 
                    363:     if (blobWidth < 2)
                    364:         blobWidth = 2;
                    365: 
                    366:     InflateRect((LPRECT)&clockRect, -(blobHeight >> 1), -(blobWidth >> 1));
                    367: 
                    368:     clockRadius = (clockRect.right - clockRect.left-6) >> 1;
                    369:     clockCenter.y = clockRect.top + ((clockRect.bottom - clockRect.top) >> 1);
                    370:     clockCenter.x = clockRect.left + clockRadius+3;
                    371: 
                    372:     for (i=0; i < 60; i++)
                    373:         {
                    374:         tRect.top  = (INT)(((LONG)(CirTab[i].cos) * clockRadius) / CLKSCALE + clockCenter.y);
                    375:         tRect.left = (INT)(((LONG)(CirTab[i].sin) * clockRadius) / CLKSCALE + clockCenter.x);
                    376: 
                    377:         if (i % 5)
                    378:             {
                    379:             /* Draw a dot. */
                    380:             if (blobWidth > 2 && blobHeight >= 2)
                    381:                 {
                    382:                 tRect.right = tRect.left + 1;
                    383:                 tRect.bottom = tRect.top + 1;
                    384:                 FillRect(hDC, (LPRECT)&tRect, hbrForeground);
                    385:                 }
                    386:             }
                    387:         else
                    388:             {
                    389:             tRect.right = tRect.left + blobWidth;
                    390:             tRect.bottom = tRect.top + blobHeight;
                    391:             OffsetRect((LPRECT)&tRect, -(blobWidth >> 1) , -(blobHeight >> 1));
                    392:             FillRect(hDC, (LPRECT)&tRect, hbrForeground);
                    393:             }
                    394:         }
                    395:     InflateRect((LPRECT)&clockRect, (blobHeight >> 1), (blobWidth >> 1));
                    396: }
                    397: 
                    398: 
                    399: /*
                    400:  *  DrawHand() - Draw the second hand using XOR mode.
                    401:  */
                    402: 
                    403: void NEAR PASCAL DrawHand(register HDC hDC,
                    404:               INT          pos,
                    405:               HPEN         hPen,
                    406:               INT          scale,
                    407:               INT          patMode)
                    408: {
                    409: INT       radius;
                    410: 
                    411:     MoveToEx(hDC, clockCenter.x, clockCenter.y, NULL);
                    412:     radius = (INT)(((LONG)clockRadius * scale) / 100);
                    413:     SetROP2(hDC, patMode);
                    414:     SelectObject(hDC, hPen);
                    415: 
                    416:     LineTo(hDC, clockCenter.x + (INT)(((LONG)(CirTab[pos].sin) * (radius)) / CLKSCALE),
                    417:         clockCenter.y + (INT)(((LONG)(CirTab[pos].cos) * (radius)) / CLKSCALE));
                    418: }
                    419: 
                    420: 
                    421: /*
                    422:  *  DrawFatHand() - Draws either hour or minute hand.
                    423:  */
                    424: 
                    425: void NEAR PASCAL DrawFatHand(register HDC hDC, INT pos, HPEN hPen, BOOL hHand)
                    426: {
                    427: register INT    m;
                    428: INT        n;
                    429: INT        scale;
                    430: POINT      tip;
                    431: POINT      stip;
                    432: 
                    433:     SetROP2(hDC, R2_COPYPEN);
                    434: 
                    435:     SelectObject(hDC, hPen);
                    436: 
                    437:     scale = hHand ? 7 : 5;
                    438: 
                    439:     n = (pos+15)%60;
                    440:     m = (INT)((((LONG)clockRadius*scale) / 100));
                    441:     stip.y = (INT)((LONG)(CirTab[n].cos) * m / CLKSCALE);
                    442:     stip.x = (INT)((LONG)(CirTab[n].sin) * m / CLKSCALE);
                    443: 
                    444:     scale = hHand ? 65 : 80;
                    445:     tip.y = (INT)((LONG)(CirTab[pos].cos) * (((LONG)clockRadius * scale) / 100) / CLKSCALE);
                    446:     tip.x = (INT)((LONG)(CirTab[pos].sin) * (((LONG)clockRadius * scale) / 100) / CLKSCALE);
                    447: 
                    448:     MoveToEx(hDC, clockCenter.x+stip.x, clockCenter.y+stip.y, NULL);
                    449:     LineTo(hDC, clockCenter.x+tip.x,  clockCenter.y+tip.y);
                    450:     MoveToEx(hDC, clockCenter.x-stip.x, clockCenter.y-stip.y, NULL);
                    451:     LineTo(hDC, clockCenter.x+tip.x,  clockCenter.y+tip.y);
                    452: 
                    453:     scale = hHand ? 15 : 20;
                    454: 
                    455:     n = (pos + 30) % 60;
                    456:     m = (INT)(((LONG)clockRadius * scale) / 100);
                    457:     tip.y = (INT)((LONG)(CirTab[n].cos) * m / CLKSCALE);
                    458:     tip.x = (INT)((LONG)(CirTab[n].sin) * m / CLKSCALE);
                    459:     MoveToEx(hDC, clockCenter.x+stip.x, clockCenter.y+stip.y, NULL);
                    460:     LineTo(hDC, clockCenter.x+tip.x,  clockCenter.y+tip.y);
                    461:     MoveToEx(hDC, clockCenter.x-stip.x, clockCenter.y-stip.y, NULL);
                    462:     LineTo(hDC, clockCenter.x+tip.x,  clockCenter.y+tip.y);
                    463: }
                    464: 
                    465: 
                    466: /*
                    467:  *  ClockPaint()
                    468:  */
                    469: 
                    470: void NEAR PASCAL ClockPaint(HWND hWnd, register HDC hDC, INT hint)
                    471: {
                    472: INT     hour;
                    473: CHAR    *pszTime;
                    474: RECT    Rect;
                    475: TIME    nTime;
                    476: DWORD   rgbCol;
                    477: HBRUSH  hBr;
                    478: 
                    479:     GetClientRect(hWnd, (LPRECT) &Rect);
                    480: 
                    481:     GetTime(&nTime);
                    482: 
                    483:     if (ClockDisp.wFormat == IDM_DIGITAL)   /* Digital Display */
                    484:         {
                    485:         if (hint == REPAINT || bIconic)
                    486:             {
                    487:             SelectObject(hDC, GetStockObject(BLACK_BRUSH));
                    488:             DrawBorder(hWnd, hDC);
                    489: 
                    490:             /* Set old values as undefined, so entire clock updated. */
                    491:             oTime.hour24 = 25;
                    492:             oTime.minute = 60;
                    493:             oTime.ampm   = 2;
                    494:             }
                    495: 
                    496:         if (oTime.hour24 != nTime.hour24)
                    497:             {
                    498:             if (ClockDisp.wTimeFormat)
                    499:                 hour = nTime.hour24;
                    500:             else
                    501:                 hour = nTime.hour12;
                    502: 
                    503:             ClockDisp.szDigTime[0] = (CHAR)('0' + hour / 10);
                    504:             ClockDisp.szDigTime[1] = (CHAR)('0' + hour % 10);
                    505:             }
                    506: 
                    507:         if (oTime.minute != nTime.minute)
                    508:             {
                    509:             ClockDisp.szDigTime[3]  = (CHAR)('0' + nTime.minute / 10);
                    510:             ClockDisp.szDigTime[4]  = (CHAR)('0' + nTime.minute % 10);
                    511:             }
                    512: 
                    513:         /* Kill Leading zero if needed. */
                    514:         if (nLeadZero == 0 && ClockDisp.szDigTime[0] == '0')
                    515:             pszTime = ClockDisp.szDigTime + 1;
                    516:         else
                    517:             pszTime = ClockDisp.szDigTime;
                    518: 
                    519:         SetTextColor(hDC, (bColor) ? RGB(0,255,0) : RGB(255,255,255));
                    520:         SetBkColor(hDC, 0L);
                    521:         SetTextAlign(hDC, TA_CENTER);
                    522: 
                    523:         ClockDisp.wDigTimeLen = (WORD)((bIconic ? 5 : 8) + ClockDisp.szDigTime - pszTime);
                    524: 
                    525:         /* Is the font ready yet? */
                    526:         if (hFont == 0 || bNewFont)
                    527:             {
                    528:             /* Create a suitable font */
                    529:             SizeFont(hWnd, Rect.bottom - Rect.top, Rect.right - Rect.left, ClockDisp.wDigTimeLen);
                    530:             bNewFont = FALSE;
                    531:             }
                    532: 
                    533:         SelectObject(hDC, hFont);
                    534:         ClockDisp.szDigTime[6] = (CHAR)('0' + nTime.second / 10);
                    535:         ClockDisp.szDigTime[7] = (CHAR)('0' + nTime.second % 10);
                    536: 
                    537:         Rect.left += 4;
                    538:         Rect.right -= 4;
                    539:         Rect.top = ClockDisp.line1.y;
                    540:         Rect.bottom = ClockDisp.yline2;
                    541:         ExtTextOut(hDC, ClockDisp.line1.x, ClockDisp.line1.y, ETO_OPAQUE | ETO_CLIPPED,
                    542:          (LPRECT) &Rect, pszTime, (DWORD)ClockDisp.wDigTimeLen, NULL);
                    543:         SelectObject(hDC, GetStockObject(SYSTEM_FONT));
                    544:     }
                    545:     else
                    546:         {
                    547:         /* Analog display */
                    548:         SetBkMode(hDC, TRANSPARENT);
                    549:         if (hint == REPAINT)
                    550:             {
                    551:             SetBkMode(hDC, OPAQUE);
                    552:             /* When switching from Digital to analog, the brush selected
                    553:              *  continued to be black; So, the current background is to be
                    554:              * selected;
                    555:              * Fix for Bug #6385 -- SANKAR -- 11-26-89 */
                    556:             SelectObject(hDC, hbrBackground);
                    557: 
                    558:             /* Make a temp brush to color the background.  This is to
                    559:              * force use of a solid color so the hand motion is painted
                    560:              * correctly.
                    561:              */
                    562:             rgbCol = GetNearestColor(hDC, GetSysColor(COLOR_WINDOW));
                    563:             hBr = CreateSolidBrush(rgbCol);
                    564: 
                    565:             FillRect(hDC, &Rect, hBr);
                    566: 
                    567:             DeleteObject(hBr);
                    568: 
                    569:             SetBkMode(hDC, TRANSPARENT);
                    570: 
                    571:             DrawBorder(hWnd, hDC);
                    572:             DrawFace(hDC);
                    573:             DrawFatHand(hDC, oTime.hour * 5 + (oTime.minute / 12), hpenForeground, HHAND);
                    574:             DrawFatHand(hDC, oTime.minute, hpenForeground, MHAND);
                    575: 
                    576:             if (!bIconic)       /* Draw the second hand. */
                    577:                 DrawHand(hDC, oTime.second, hpenBackground, SECONDSCALE, R2_NOT);
                    578: 
                    579:             /* NOTE: Don't update oTime in this case! */
                    580: 
                    581:             return;
                    582:             }
                    583:     else if (hint == HANDPAINT)
                    584:         {
                    585:         if ((!bIconic) && nTime.second != oTime.second) /* Erase the old second hand. */
                    586:             DrawHand(hDC, oTime.second, hpenBackground, SECONDSCALE, R2_NOT);
                    587: 
                    588:         if (nTime.minute != oTime.minute || nTime.hour != oTime.hour)
                    589:             {
                    590:             if (bIconic)
                    591:                 {
                    592:                 DrawHand(hDC, oTime.minute, hpenBackground, MINUTESCALE, R2_COPYPEN);
                    593:                 DrawHand(hDC, oTime.hour * 5 + (oTime.minute / 12), hpenBackground, HOURSCALE, R2_COPYPEN);
                    594:                 DrawHand(hDC, nTime.minute, hpenForeground, MINUTESCALE, R2_COPYPEN);
                    595:                 DrawHand(hDC, nTime.hour * 5 + (nTime.minute / 12), hpenForeground, HOURSCALE, R2_COPYPEN);
                    596:                 }
                    597:             else
                    598:                 {
                    599:                 DrawFatHand(hDC, oTime.minute, hpenBackground, MHAND);
                    600:                 DrawFatHand(hDC, oTime.hour*5+(oTime.minute/12), hpenBackground, HHAND);
                    601:                 DrawFatHand(hDC, nTime.minute, hpenForeground, MHAND);
                    602:                 DrawFatHand(hDC, (nTime.hour) * 5 + (nTime.minute / 12), hpenForeground, HHAND );
                    603:                 }
                    604:             }
                    605: 
                    606:         if (!bIconic && nTime.second != oTime.second) /* Draw new second hand */
                    607:             DrawHand(hDC, nTime.second, hpenBackground, SECONDSCALE, R2_NOT);
                    608:         }
                    609:     }
                    610:     oTime = nTime;
                    611: }
                    612: 
                    613: 
                    614: /*
                    615:  *  ClockTimer()
                    616:  *
                    617:  *  msg - timer ID
                    618:  *
                    619:  * Called by windows to tell CLOCK there has been a time change.
                    620:  *
                    621:  */
                    622: 
                    623: void NEAR PASCAL ClockTimer(HWND hWnd, UINT msg)
                    624: {
                    625: HDC    hDC;
                    626: TIME    nTime;
                    627: 
                    628:     GetTime(&nTime);
                    629: 
                    630:     /* It's possible to change any part of the system at any time
                    631:      * through the Control Panel.  So we check everything.
                    632:      */
                    633:     if (((nTime.second == oTime.second) || bIconic) &&
                    634:         (nTime.minute == oTime.minute)          &&
                    635:         (nTime.hour24 == oTime.hour24))
                    636:         return;
                    637: 
                    638:     hDC = GetDC(hWnd);
                    639:     ClockPaint(hWnd, hDC, HANDPAINT);
                    640:     ReleaseDC(hWnd, hDC);
                    641:     DdePostAdvise(idInst, hszTime, hszNow);
                    642:        UNREFERENCED_PARAMETER(msg);
                    643: }
                    644: 
                    645: 
                    646: /*
                    647:  *  ClockCreate()
                    648:  */
                    649: 
                    650: void NEAR PASCAL ClockCreate(HWND hWnd)
                    651: {
                    652: INT        i;
                    653: register HDC    hDC;
                    654: INT        HorzSize;
                    655: INT        VertSize;
                    656: 
                    657:     hDC = GetDC(hWnd);
                    658:     VertRes = GetDeviceCaps(hDC, VERTRES);
                    659:     HorzRes = GetDeviceCaps(hDC, HORZRES);
                    660:     VertSize= GetDeviceCaps(hDC, VERTSIZE);
                    661:     HorzSize= GetDeviceCaps(hDC, HORZSIZE);
                    662:     ReleaseDC(hWnd, hDC);
                    663: 
                    664:     aspectN = ((LONG)VertRes * 100) / (LONG)VertSize;
                    665:     aspectD = ((LONG)HorzRes * 100) / (LONG)HorzSize;
                    666: 
                    667:     CreateTools();
                    668: 
                    669:     /* Scale sines for aspect ratio if this is the first instance */
                    670:     for (i=0; i < 60; i++) {
                    671:         CirTab[i].sin = (SHORT)((CirTab[i].sin * aspectN) / aspectD);
                    672:     }
                    673: }
                    674: 
                    675: 
                    676: 
                    677: /*
                    678:  *  FormatInit() -  International initialization.
                    679:  */
                    680: 
                    681: void NEAR PASCAL FormatInit(register HANDLE hInstance, BOOL fModeChange)
                    682: {
                    683: WORD i, ii;
                    684: CHAR szWinHeader[21], szKeyName[21], szRetVal[21];
                    685: 
                    686:     for (i=0; i < 11; i++)
                    687:         ClockDisp.szDigTime[i] = ' ';
                    688: 
                    689:     LoadString(hInstance, IDS_INTL, (LPSTR)szWinHeader, 20);
                    690: 
                    691:     LoadString(hInstance, IDS_ITIME, (LPSTR)szKeyName, 20);
                    692:     ClockDisp.wTimeFormat = (WORD)GetProfileInt((LPSTR)szWinHeader, (LPSTR)szKeyName, 0);
                    693: 
                    694:     LoadString(hInstance, IDS_S1159, (LPSTR)szKeyName, 20);
                    695:     LoadString(hInstance, IDS_1159, (LPSTR)szRetVal, 20);
                    696:     i = (WORD)GetProfileString((LPSTR)szWinHeader, (LPSTR)szKeyName, (LPSTR)szRetVal, (LPSTR)&ClockDisp.szAMPM[0][0], 7);
                    697: 
                    698:     LoadString(hInstance, IDS_S2359, (LPSTR)szKeyName, 20);
                    699:     LoadString(hInstance, IDS_2359, (LPSTR)szRetVal, 20);
                    700:     ii = (WORD)GetProfileString((LPSTR)szWinHeader, (LPSTR)szKeyName, (LPSTR)szRetVal, (LPSTR)&ClockDisp.szAMPM[1][0], 7);
                    701: 
                    702:     nLeadZero = GetProfileInt((LPSTR)szWinHeader, "iTLzero", 0);
                    703: 
                    704:     LoadString(hInstance, IDS_STIME, (LPSTR)szKeyName, 20);
                    705:     LoadString(hInstance, IDS_TIMESEP, (LPSTR)szRetVal, 20);
                    706: 
                    707:     GetProfileString((LPSTR)szWinHeader, (LPSTR)szKeyName, (LPSTR)szRetVal, (LPSTR)szRetVal, 20);
                    708:     ClockDisp.cTimeSep = szRetVal[0];
                    709: 
                    710:     ClockDisp.szDigTime[2] = ClockDisp.cTimeSep;
                    711:     ClockDisp.szDigTime[5] = ClockDisp.cTimeSep;
                    712: 
                    713:     LoadString(hInstance, IDS_USNAME, (LPSTR)szWinHeader, 20);
                    714:     LoadString(hInstance, IDS_CLKFORMAT, (LPSTR)szKeyName, 20);
                    715: 
                    716:     /* We will read the new mode (DIGITAL/ANALOG) only during init time. */
                    717:     if (fModeChange)
                    718:     {
                    719:         if (GetPrivateProfileInt((LPSTR)szWinHeader, (LPSTR)szKeyName, 1, (LPSTR)szIniFile))
                    720:             ClockDisp.wFormat = IDM_ANALOG;
                    721:         else
                    722:             ClockDisp.wFormat = IDM_DIGITAL;
                    723:     }
                    724: 
                    725:     if (ClockDisp.wFormat == IDM_ANALOG)
                    726:         hbrBackground = hbrColorWindow;
                    727:     else
                    728:         hbrBackground = hbrColorBlack;
                    729: 
                    730:     ClockDisp.wDigTimeLen = 2+1+2+1+2+1;
                    731: 
                    732:     if (!ClockDisp.wTimeFormat)
                    733:         ClockDisp.wDigTimeLen += ((i > ii) ? (i) : (ii));
                    734:     }
                    735: 
                    736: 
                    737: /*
                    738:  *  ClockInit()
                    739:  */
                    740: 
                    741: BOOL NEAR PASCAL ClockInit(HANDLE hInstance)
                    742: {
                    743: HDC       hDC;
                    744: static WNDCLASS        ClockClass;
                    745: 
                    746:     FormatInit(hInstance, TRUE);
                    747: 
                    748:     ClockClass.lpszClassName = (LPSTR)szBuffer;
                    749:     ClockClass.lpszMenuName  = (LPSTR)szBuffer;
                    750:     ClockClass.hbrBackground = (HBRUSH)NULL;
                    751:     ClockClass.style         = CS_VREDRAW | CS_HREDRAW;
                    752:     ClockClass.hInstance     = hInstance;
                    753:     ClockClass.lpfnWndProc   = ClockWndProc;
                    754:     ClockClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
                    755:     ClockClass.hIcon         = NULL;
                    756: 
                    757:     if (!RegisterClass((LPWNDCLASS)&ClockClass))
                    758:         return(FALSE);
                    759: 
                    760:     LoadString(hInstance, IDS_FONTFILE, (LPSTR)szFontFile, 20);
                    761:     AddFontResource(szFontFile);
                    762: 
                    763:     /* Check the number of colors that the display is capable of. */
                    764:     hDC = CreateDC("DISPLAY", NULL, NULL, NULL);
                    765:     bColor = (GetDeviceCaps(hDC, NUMCOLORS) > 2);
                    766:     bColor = FALSE;
                    767:     DeleteDC(hDC);
                    768: 
                    769:     return(TRUE);
                    770: }
                    771: 
                    772: 
                    773: /*
                    774:  *  ClockWndProc()
                    775:  */
                    776: 
                    777: LONG APIENTRY ClockWndProc(register HWND hWnd, UINT message, WPARAM wParam, LONG lParam)
                    778: {
                    779: HMENU   hMenu;
                    780: CHAR      szInt[2];      /* space for int to str conversion */
                    781: static CHAR      szAppName[12];  /* application name buffer */
                    782: PAINTSTRUCT ps;
                    783: 
                    784:     switch (message)
                    785:     {
                    786:         case WM_COMMAND:
                    787:         switch (wParam)
                    788:         {
                    789:             case IDM_ANALOG:
                    790:             case IDM_DIGITAL:
                    791:                 if (wParam != ClockDisp.wFormat)
                    792:                 {
                    793:                     /* Switch flag to other choice */
                    794:                     hMenu = GetMenu(hWnd);
                    795:                     CheckMenuItem(hMenu, ClockDisp.wFormat, MF_BYCOMMAND | MF_UNCHECKED);
                    796:                     CheckMenuItem(hMenu, ClockDisp.wFormat = (WORD)wParam, MF_BYCOMMAND | MF_CHECKED);
                    797:                     InvalidateRect(hWnd, (LPRECT)NULL, TRUE);
                    798: 
                    799:                     /* Write new configuration to CLOCK.INI */
                    800:                     LoadString(hInst, IDS_USNAME, (LPSTR)szAppName, 8);
                    801:                     LoadString(hInst, IDS_CLKFORMAT, (LPSTR)szBuffer, BUFLEN-1);
                    802:                     szInt[0] = (CHAR)('0' + (ClockDisp.wFormat == IDM_ANALOG));
                    803:                     szInt[1] = 0;
                    804:                     WritePrivateProfileString((LPSTR)szAppName,
                    805:                                               (LPSTR)szBuffer,
                    806:                                               (LPSTR)szInt,
                    807:                                               (LPSTR)szIniFile);
                    808:                 }
                    809:             break;
                    810: 
                    811:             case IDM_ABOUT:
                    812:                 {
                    813:                 LoadString(hInst, IDS_USNAME, (LPSTR)szAppName, 8);
                    814:                 // Add this when 3.1 stuff comes in. ShellAbout(hWnd, szAppName, (LPSTR)"", LoadIcon(hInst, (LPSTR)"cckk"));
                    815:                 break;
                    816:                 }
                    817: 
                    818:             default:
                    819:                 goto defproc;
                    820:             }
                    821:         break;
                    822: 
                    823:         case WM_SIZE:
                    824:             bNewFont = TRUE;
                    825:             ClockSize(hWnd, LOWORD(lParam), HIWORD(lParam), (WORD)wParam);
                    826:             UpdateWindow(hWnd);
                    827:             break;
                    828: 
                    829:         case WM_QUERYDRAGICON:
                    830:             return (LONG)LoadIcon(hInst, "cckk");
                    831: 
                    832:         case WM_DESTROY:
                    833:         {
                    834:             CHAR           szInt[10];
                    835:             HCURSOR        hTempCursor;
                    836: 
                    837:             KillTimer(hWnd, TimerID);
                    838:             DeleteTools();
                    839:             if (hFont)
                    840:                 DeleteObject(hFont);
                    841:             RemoveFontResource(szFontFile);
                    842: 
                    843:             SetCapture(hWnd);
                    844:             hTempCursor=SetCursor(LoadCursor(NULL, IDC_WAIT));
                    845: 
                    846:             if (!(IsIconic(hWnd) || IsZoomed(hWnd)))
                    847:                 GetWindowRect(hWnd, &rCoordRect);
                    848: 
                    849:             wsprintf((LPSTR)szInt, (LPSTR)"%i", (INT)IsIconic(hWnd));
                    850:             WritePrivateProfileString((LPSTR)szSection,
                    851:                                    (LPSTR)"Minimized",
                    852:                                    (LPSTR)szInt,
                    853:                                    (LPSTR)szIniFile);
                    854:             wsprintf((LPSTR)szInt, (LPSTR)"%i", (INT)IsZoomed(hWnd));
                    855:             WritePrivateProfileString((LPSTR)szSection,
                    856:                                    (LPSTR)"Maximized",
                    857:                                    (LPSTR)szInt,
                    858:                                    (LPSTR)szIniFile);
                    859:             wsprintf((LPSTR)szInt, (LPSTR)"%i", (INT)rCoordRect.left);
                    860:             WritePrivateProfileString((LPSTR)szSection,
                    861:                                (LPSTR)"Left",
                    862:                                (LPSTR)szInt,
                    863:                                        (LPSTR)szIniFile);
                    864:             wsprintf((LPSTR)szInt, (LPSTR)"%i", (INT)rCoordRect.top);
                    865:             WritePrivateProfileString((LPSTR)szSection,
                    866:                            (LPSTR)"Top",
                    867:                            (LPSTR)szInt,
                    868:                                        (LPSTR)szIniFile);
                    869:             wsprintf((LPSTR)szInt, (LPSTR)"%i", (INT)rCoordRect.right);
                    870:             WritePrivateProfileString((LPSTR)szSection,
                    871:                            (LPSTR)"Right",
                    872:                            (LPSTR)szInt,
                    873:                                        (LPSTR)szIniFile);
                    874:             wsprintf((LPSTR)szInt, (LPSTR)"%i", (INT)rCoordRect.bottom);
                    875:             WritePrivateProfileString((LPSTR)szSection,
                    876:                            (LPSTR)"Bottom",
                    877:                            (LPSTR)szInt,
                    878:                                        (LPSTR)szIniFile);
                    879:             PostQuitMessage(0);
                    880:             break;
                    881:         }
                    882: 
                    883:         case WM_WININICHANGE:
                    884:             /* FALSE indicates that we don't want to change the display format */
                    885:             FormatInit(hInst, FALSE);
                    886:             InvalidateRect(hWnd, (LPRECT)NULL, TRUE);
                    887:             break;
                    888: 
                    889:         case WM_PAINT:
                    890:             /* 25-Mar-1987. Added to force total repaint to solve
                    891:              * problem of garbage under second hand when hidden
                    892:              * by menu or popup.
                    893:              */
                    894:             InvalidateRect(hWnd, (LPRECT)NULL, TRUE);
                    895:             BeginPaint(hWnd, (LPPAINTSTRUCT)&ps);
                    896: 
                    897:             if (ClockDisp.wFormat == IDM_DIGITAL)
                    898:                 {
                    899:                 hbrBackground = hbrColorBlack;
                    900:                 FillRect(ps.hdc, (LPRECT)&clockRect, hbrBackground);
                    901:                 }
                    902:             else
                    903:                 hbrBackground=hbrColorWindow;
                    904: 
                    905:             ClockPaint(hWnd, ps.hdc, REPAINT);
                    906:             EndPaint(hWnd, (LPPAINTSTRUCT)&ps);
                    907:             break;
                    908: 
                    909:         case WM_TIMECHANGE:
                    910:             /* Redraw. */
                    911:             InvalidateRect(hWnd, (LPRECT)NULL, TRUE);
                    912: 
                    913:         case WM_TIMER:
                    914:             ClockTimer(hWnd, (WORD)wParam);
                    915:             break;
                    916: 
                    917:         case WM_SYSCOMMAND:
                    918:             switch (wParam)
                    919:             {
                    920:                 case SC_MINIMIZE:
                    921:                     if (!IsZoomed(hWnd))
                    922:                         GetWindowRect(hWnd, (LPRECT)&rCoordRect);
                    923:                     break;
                    924:                 case SC_MAXIMIZE:
                    925:                     if (!IsIconic(hWnd))
                    926:                         GetWindowRect(hWnd, (LPRECT)&rCoordRect);
                    927:                     break;
                    928:             }
                    929:             return(DefWindowProc(hWnd, message, wParam, lParam));
                    930:             break;
                    931: 
                    932:         case WM_SYSCOLORCHANGE:
                    933:             DeleteTools();
                    934:             CreateTools();
                    935:             break;
                    936: 
                    937:         case WM_ERASEBKGND:
                    938:             {
                    939:             RECT rect;
                    940: 
                    941:             GetClientRect(hWnd, (LPRECT)&rect);
                    942:             SelectObject((HDC)wParam, hbrBackground);
                    943:             FillRect((HDC)wParam, (LPRECT)&rect, hbrBackground);
                    944:             break;
                    945:             }
                    946: 
                    947:         default:
                    948: defproc:
                    949:         return(DefWindowProc(hWnd, message, wParam, lParam));
                    950:     }
                    951:     return(0L);
                    952: }
                    953: 
                    954: 
                    955: 
                    956: /*
                    957:  *  WinMain()
                    958:  */
                    959: 
                    960: int APIENTRY WinMain(
                    961:     HANDLE hInstance,
                    962:     HANDLE hPrev,
                    963:     LPSTR lpCmdLine,
                    964:     int cmdShow
                    965:     )
                    966: {
                    967: register HWND hWnd;
                    968: MSG        msg;
                    969: TIME       nTime;
                    970: PSTR       szTooMany;
                    971: INT        iMinimized, iMaximized;
                    972: 
                    973:     LoadString(hInstance, IDS_USNAME, (LPSTR)szBuffer, BUFLEN);
                    974:     LoadString(hInstance, IDS_INIFILE, (LPSTR)szIniFile, 20);
                    975:     LoadString(hInstance, IDS_USNAME, (LPSTR)szSection, 30);
                    976: 
                    977:     if (!ClockInit(hInstance))
                    978:         return(FALSE);
                    979: 
                    980:     ClockCreate((HWND)NULL);
                    981: 
                    982:     LoadString(hInstance, IDS_APPNAME, (LPSTR)szBuffer, BUFLEN);
                    983: 
                    984:     rCoordRect.top=GetPrivateProfileInt((LPSTR)szSection,
                    985:                                          (LPSTR)"Top",
                    986:                                         (DWORD)-1, (LPSTR)szIniFile);
                    987:     rCoordRect.left=GetPrivateProfileInt((LPSTR)szSection,
                    988:                                          (LPSTR)"Left",
                    989:                                         (DWORD)-1, (LPSTR)szIniFile);
                    990:     rCoordRect.right=GetPrivateProfileInt((LPSTR)szSection,
                    991:                                          (LPSTR)"Right",
                    992:                                         (DWORD)-1, (LPSTR)szIniFile);
                    993:     rCoordRect.bottom=GetPrivateProfileInt((LPSTR)szSection,
                    994:                                          (LPSTR)"Bottom",
                    995:                                         (DWORD)-1, (LPSTR)szIniFile);
                    996: 
                    997:     hWnd = CreateWindow((LPSTR)"Clock",        /* The class name.             */
                    998:             (LPSTR)szBuffer,        /* The window instance name.     */
                    999:             WS_TILEDWINDOW,
                   1000:             (rCoordRect.left < 0) ? CW_USEDEFAULT : rCoordRect.left,
                   1001:             (rCoordRect.top  < 0) ? CW_USEDEFAULT : rCoordRect.top,
                   1002:         (rCoordRect.left < 0) ? (INT)( (HorzRes/3) + GetSystemMetrics(SM_CXFRAME)*2 )
                   1003:                                  : rCoordRect.right - rCoordRect.left,
                   1004:         (rCoordRect.left < 0) ? (INT)( (((HorzRes/3)*aspectN)/aspectD)+GetSystemMetrics(SM_CYCAPTION)+GetSystemMetrics(SM_CYFRAME)*2 )
                   1005:                                  : rCoordRect.bottom - rCoordRect.top,
                   1006:             NULL,
                   1007:             NULL,
                   1008:             hInstance,
                   1009:             (LPSTR)NULL);
                   1010: 
                   1011:     hWindow=hWnd;
                   1012: 
                   1013:     // Loop if control panel time being changed.
                   1014:     GetTime((TIME *)&nTime);
                   1015:     do {
                   1016:         GetTime((TIME *)&oTime);
                   1017:     } while (nTime.second == oTime.second && nTime.minute == oTime.minute &&
                   1018:            nTime.hour24 == oTime.hour24);
                   1019: 
                   1020:     if (!SetTimer(hWnd, TimerID, OPEN_TLEN, 0L))
                   1021:         {
                   1022:         /* Windows only supports 16 public timers */
                   1023:         szTooMany = (PSTR)LocalAlloc(LPTR, 160);
                   1024:         LoadString(hInstance, IDS_TOOMANY, (LPSTR)szTooMany, 160);
                   1025:         MessageBox((HWND)NULL, (LPSTR)szTooMany, (LPSTR)szBuffer, MB_OK | MB_ICONHAND | MB_SYSTEMMODAL);
                   1026:         DeleteTools();
                   1027:         return(FALSE);
                   1028:     }
                   1029: 
                   1030:     /* Check the default menu item either analog or digital */
                   1031:     CheckMenuItem(GetMenu(hWnd), ClockDisp.wFormat, MF_BYCOMMAND | MF_CHECKED);
                   1032: 
                   1033:     hInst = hInstance;
                   1034: 
                   1035:     iMinimized=GetPrivateProfileInt((LPSTR)szSection,
                   1036:                                          (LPSTR)"Minimized",
                   1037:                                          0, (LPSTR)szIniFile);
                   1038:     if (!iMinimized)
                   1039:     {
                   1040:         iMaximized=GetPrivateProfileInt((LPSTR)szSection,
                   1041:                                          (LPSTR)"Maximized",
                   1042:                                          0, (LPSTR)szIniFile);
                   1043:         if (iMaximized)
                   1044:             ShowWindow(hWnd, SW_MAXIMIZE);
                   1045:         else
                   1046:         {
                   1047:             ShowWindow(hWnd, cmdShow);
                   1048:             GetWindowRect(hWnd, (LPRECT)&rCoordRect);
                   1049:         }
                   1050:     }
                   1051:     else
                   1052:         ShowWindow(hWnd, SW_MINIMIZE);
                   1053: 
                   1054:     DdeInitialize(&idInst, (PFNCALLBACK)MakeProcInstance((FARPROC)DdeCallback, hInstance),
                   1055:             CBF_FAIL_EXECUTES | CBF_SKIP_ALLNOTIFICATIONS, 0L);
                   1056: 
                   1057: 
                   1058:     hszTime = DdeCreateStringHandle(idInst, "Time", 0);
                   1059:     hszNow = DdeCreateStringHandle(idInst, "Now", 0);
                   1060:     hszClock = DdeCreateStringHandle(idInst, "Clock", 0);
                   1061:     DdeNameService(idInst, hszClock, 0L, DNS_REGISTER);
                   1062: 
                   1063:     while (GetMessage((LPMSG)&msg, NULL, 0, 0))
                   1064:         {
                   1065:         TranslateMessage((LPMSG)&msg);
                   1066:         DispatchMessage((LPMSG)&msg);
                   1067:         }
                   1068: 
                   1069:     DdeUninitialize(idInst);
                   1070: 
                   1071:     return(msg.wParam);
                   1072: }
                   1073: 
                   1074: 
                   1075: VOID GetTime(
                   1076: TIME *ptime)
                   1077: {
                   1078:     time_t t;
                   1079:     struct tm *ptm;
                   1080: 
                   1081:     time(&t);
                   1082:     ptm = localtime(&t);
                   1083:     ptime->second = ptm->tm_sec;
                   1084:     ptime->minute = ptm->tm_min;
                   1085:     ptime->hour12 =
                   1086:     ptime->hour = ptm->tm_hour > 12 ? ptm->tm_hour - 12 : ptm->tm_hour;
                   1087:     ptime->hour24 = ptm->tm_hour;
                   1088:     ptime->ampm = ptm->tm_hour > 12 ? 1 : 0;
                   1089: }
                   1090: 
                   1091: 
                   1092: HDDEDATA EXPENTRY DdeCallback(
                   1093: WORD usType,
                   1094: WORD usFmt,
                   1095: HCONV hConv,
                   1096: HSZ hsz1,
                   1097: HSZ hsz2,
                   1098: HDDEDATA hData,
                   1099: DWORD lData1,
                   1100: DWORD lData2)
                   1101: {
                   1102:     if (usType == XTYP_CONNECT) {
                   1103:         return(TRUE);
                   1104:     }
                   1105: 
                   1106:     if (usType == XTYP_WILDCONNECT) {
                   1107:         HDDEDATA hData;
                   1108:         HSZPAIR FAR *phszp;
                   1109:         DWORD cb;
                   1110: 
                   1111:         if ((!hsz1 || hsz1 == hszTime) && (!hsz2 || hsz2 == hszClock)) {
                   1112:             if ((hData = DdeCreateDataHandle(idInst, NULL,
                   1113:                     2 * sizeof(HSZPAIR), 0L, 0, 0, 0))) {
                   1114:                 phszp = (HSZPAIR FAR *)DdeAccessData(hData, &cb);
                   1115:                 phszp[0].hszSvc = hszClock;
                   1116:                 phszp[0].hszTopic = hszTime;
                   1117:                 phszp[1].hszSvc = phszp[1].hszTopic = 0;
                   1118:                 DdeUnaccessData(hData);
                   1119:                 return(hData);
                   1120:             }
                   1121:         }
                   1122:         return(0);
                   1123:     }
                   1124: 
                   1125:     if (usFmt == CF_TEXT) {
                   1126:         CHAR sz[40];
                   1127: 
                   1128:         if (usType == XTYP_ADVSTART || usType == XTYP_ADVSTOP) {
                   1129:             return(TRUE);
                   1130:         }
                   1131: 
                   1132:         if (hsz1 == hszTime && hsz2 == hszNow) {
                   1133:             if (usType == XTYP_REQUEST || usType == XTYP_ADVREQ) {
                   1134: 
                   1135:                 itoa(oTime.hour, sz, 10);
                   1136:                 strcat(sz, ":");
                   1137:                 itoa(oTime.minute, &sz[strlen(sz)], 10);
                   1138:                 strcat(sz, ":");
                   1139:                 itoa(oTime.second, &sz[strlen(sz)], 10);
                   1140:                 return(DdeCreateDataHandle(idInst, (LPBYTE)sz, strlen(sz) + 1, 0L,
                   1141:                         hszNow, CF_TEXT, 0));
                   1142:             }
                   1143:             if (usType == XTYP_POKE) {
                   1144:                 SYSTEMTIME SysTime;
                   1145: 
                   1146:                 DdeGetData(hData, (LPBYTE)sz, 40L, 0L);
                   1147:                 GetSystemTime(&SysTime);
                   1148:                 sscanf(sz, "%d:%d:%d", &SysTime.wHour, &SysTime.wMinute, &SysTime.wSecond);
                   1149:                 SetSystemTime(&SysTime);
                   1150:                 DdePostAdvise(idInst, hszTime, hszNow);
                   1151:                 return(DDE_FACK);
                   1152:             }
                   1153:         }
                   1154:     }
                   1155:     return(0);
                   1156:        UNREFERENCED_PARAMETER(lData1);
                   1157:        UNREFERENCED_PARAMETER(lData2);
                   1158:        UNREFERENCED_PARAMETER(hConv);
                   1159: }
                   1160: 

unix.superglobalmegacorp.com

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