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