|
|
1.1 root 1: /*-------------------------
2: CLOCK.C -- Analog Clock
3: -------------------------*/
4:
5: #define INCL_WIN
6: #define INCL_GPI
7: #include <os2.h>
8: #include <stdlib.h>
9:
10: #define ID_TIMER 1
11:
12: typedef struct
13: {
14: SHORT cxClient ;
15: SHORT cyClient ;
16: SHORT cxPixelDiam ;
17: SHORT cyPixelDiam ;
18: }
19: WINDOWINFO ;
20:
21: typedef WINDOWINFO *PWINDOWINFO ;
22:
23: MRESULT EXPENTRY ClientWndProc (HWND, USHORT, MPARAM, MPARAM) ;
24:
25: int main (void)
26: {
27: static CHAR szClientClass[] = "Clock" ;
28: static ULONG flFrameFlags = FCF_TITLEBAR | FCF_SYSMENU |
29: FCF_SIZEBORDER | FCF_MINMAX |
30: FCF_SHELLPOSITION | FCF_TASKLIST ;
31: HAB hab ;
32: HMQ hmq ;
33: HWND hwndFrame, hwndClient ;
34: QMSG qmsg ;
35:
36: hab = WinInitialize (0) ;
37: hmq = WinCreateMsgQueue (hab, 0) ;
38:
39: WinRegisterClass (hab, szClientClass, ClientWndProc, CS_SIZEREDRAW, 0) ;
40:
41: hwndFrame = WinCreateStdWindow (HWND_DESKTOP, WS_VISIBLE,
42: &flFrameFlags, szClientClass, NULL,
43: 0L, NULL, 0, &hwndClient) ;
44:
45: if (WinStartTimer (hab, hwndClient, ID_TIMER, 1000))
46: {
47: while (WinGetMsg (hab, &qmsg, NULL, 0, 0))
48: WinDispatchMsg (hab, &qmsg) ;
49:
50: WinStopTimer (hab, hwndClient, ID_TIMER) ;
51: }
52: else
53: WinMessageBox (HWND_DESKTOP, hwndClient,
54: "Too many clocks or timers",
55: szClientClass, 0, MB_OK | MB_ICONEXCLAMATION) ;
56:
57: WinDestroyWindow (hwndFrame) ;
58: WinDestroyMsgQueue (hmq) ;
59: WinTerminate (hab) ;
60: return 0 ;
61: }
62:
63: VOID RotatePoint (POINTL aptl[], SHORT sNum, SHORT sAngle)
64: {
65: static SHORT sSin [60] =
66: {
67: 0, 105, 208, 309, 407, 500, 588, 669, 743, 809,
68: 866, 914, 951, 978, 995, 1000, 995, 978, 951, 914,
69: 866, 809, 743, 669, 588, 500, 407, 309, 208, 105,
70: 0, -104, -207, -308, -406, -499, -587, -668, -742, -808,
71: -865, -913, -950, -977, -994, -999, -994, -977, -950, -913,
72: -865, -808, -742, -668, -587, -499, -406, -308, -207, -104
73: } ;
74: POINTL ptlTemp ;
75: SHORT sIndex ;
76:
77: for (sIndex = 0 ; sIndex < sNum ; sIndex++)
78: {
79: ptlTemp.x = (aptl[sIndex].x * sSin [(sAngle + 15) % 60] +
80: aptl[sIndex].y * sSin [sAngle]) / 1000 ;
81:
82: ptlTemp.y = (aptl[sIndex].y * sSin [(sAngle + 15) % 60] -
83: aptl[sIndex].x * sSin [sAngle]) / 1000 ;
84:
85: aptl[sIndex] = ptlTemp ;
86: }
87: }
88:
89: VOID ScalePoint (POINTL aptl[], SHORT sNum, PWINDOWINFO pwi)
90: {
91: SHORT sIndex ;
92:
93: for (sIndex = 0 ; sIndex < sNum ; sIndex++)
94: {
95: aptl[sIndex].x = aptl[sIndex].x * pwi->cxPixelDiam / 200 ;
96: aptl[sIndex].y = aptl[sIndex].y * pwi->cyPixelDiam / 200 ;
97: }
98: }
99:
100: VOID TranslatePoint (POINTL aptl[], SHORT sNum, PWINDOWINFO pwi)
101: {
102: SHORT sIndex ;
103:
104: for (sIndex = 0 ; sIndex < sNum ; sIndex++)
105: {
106: aptl[sIndex].x += pwi->cxClient / 2 ;
107: aptl[sIndex].y += pwi->cyClient / 2 ;
108: }
109: }
110:
111: VOID DrawHand (HPS hps, POINTL aptlIn[], SHORT sNum, SHORT sAngle,
112: PWINDOWINFO pwi)
113: {
114: POINTL aptl [5] ;
115: SHORT sIndex ;
116:
117: for (sIndex = 0 ; sIndex < sNum ; sIndex++)
118: aptl [sIndex] = aptlIn [sIndex] ;
119:
120: RotatePoint (aptl, sNum, sAngle) ;
121: ScalePoint (aptl, sNum, pwi) ;
122: TranslatePoint (aptl, sNum, pwi) ;
123:
124: GpiMove (hps, aptl) ;
125: GpiPolyLine (hps, sNum - 1L, aptl + 1) ;
126: }
127:
128: MRESULT EXPENTRY ClientWndProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
129: {
130: static DATETIME dtPrevious ;
131: static HDC hdc ;
132: static LONG xPixelsPerMeter, yPixelsPerMeter ;
133: static POINTL aptlHour [5] = { 0,-15, 10,0, 0,60, -10,0, 0,-15 },
134: aptlMinute [5] = { 0,-20, 5,0, 0,80, -5,0, 0,-20 },
135: aptlSecond [2] = { 0, 0, 0,80 } ;
136: static WINDOWINFO wi ;
137: DATETIME dt ;
138: HPS hps ;
139: POINTL aptl [3] ;
140: SHORT sDiamMM, sAngle ;
141:
142: switch (msg)
143: {
144: case WM_CREATE:
145: hdc = WinOpenWindowDC (hwnd) ;
146:
147: DevQueryCaps (hdc, CAPS_VERTICAL_RESOLUTION,
148: 1L, &yPixelsPerMeter) ;
149: DevQueryCaps (hdc, CAPS_HORIZONTAL_RESOLUTION,
150: 1L, &xPixelsPerMeter) ;
151:
152: DosGetDateTime (&dtPrevious) ;
153: dtPrevious.hours = (dtPrevious.hours * 5) % 60 +
154: dtPrevious.minutes / 12 ;
155: return 0 ;
156:
157: case WM_SIZE:
158: wi.cxClient = SHORT1FROMMP (mp2) ;
159: wi.cyClient = SHORT2FROMMP (mp2) ;
160:
161: sDiamMM = (SHORT) min (wi.cxClient * 1000L / xPixelsPerMeter,
162: wi.cyClient * 1000L / yPixelsPerMeter) ;
163:
164: wi.cxPixelDiam = (SHORT) (xPixelsPerMeter * sDiamMM / 1000) ;
165: wi.cyPixelDiam = (SHORT) (yPixelsPerMeter * sDiamMM / 1000) ;
166: return 0 ;
167:
168: case WM_TIMER:
169: DosGetDateTime (&dt) ;
170: dt.hours = (dt.hours * 5) % 60 + dt.minutes / 12 ;
171:
172: hps = WinGetPS (hwnd) ;
173: GpiSetColor (hps, CLR_BACKGROUND) ;
174:
175: DrawHand (hps, aptlSecond, 2, dtPrevious.seconds, &wi) ;
176:
177: if (dt.hours != dtPrevious.hours ||
178: dt.minutes != dtPrevious.minutes)
179: {
180: DrawHand (hps, aptlHour, 5, dtPrevious.hours, &wi) ;
181: DrawHand (hps, aptlMinute, 5, dtPrevious.minutes, &wi) ;
182: }
183:
184: GpiSetColor (hps, CLR_NEUTRAL) ;
185:
186: DrawHand (hps, aptlHour, 5, dt.hours, &wi) ;
187: DrawHand (hps, aptlMinute, 5, dt.minutes, &wi) ;
188: DrawHand (hps, aptlSecond, 2, dt.seconds, &wi) ;
189:
190: WinReleasePS (hps) ;
191: dtPrevious = dt ;
192: return 0 ;
193:
194: case WM_PAINT:
195: hps = WinBeginPaint (hwnd, NULL, NULL) ;
196: GpiErase (hps) ;
197:
198: for (sAngle = 0 ; sAngle < 60 ; sAngle++)
199: {
200: aptl[0].x = 0 ;
201: aptl[0].y = 90 ;
202:
203: RotatePoint (aptl, 1, sAngle) ;
204: ScalePoint (aptl, 1, &wi) ;
205: TranslatePoint (aptl, 1, &wi) ;
206:
207: aptl[2].x = aptl[2].y = sAngle % 5 ? 2 : 10 ;
208:
209: ScalePoint (aptl + 2, 1, &wi) ;
210:
211: aptl[0].x -= aptl[2].x / 2 ;
212: aptl[0].y -= aptl[2].y / 2 ;
213:
214: aptl[1].x = aptl[0].x + aptl[2].x ;
215: aptl[1].y = aptl[0].y + aptl[2].y ;
216:
217: GpiMove (hps, aptl) ;
218: GpiBox (hps, DRO_OUTLINEFILL, aptl + 1,
219: aptl[2].x, aptl[2].y) ;
220: }
221: DrawHand (hps, aptlHour, 5, dtPrevious.hours, &wi) ;
222: DrawHand (hps, aptlMinute, 5, dtPrevious.minutes, &wi) ;
223: DrawHand (hps, aptlSecond, 2, dtPrevious.seconds, &wi) ;
224:
225: WinEndPaint (hps) ;
226: return 0 ;
227: }
228: return WinDefWindowProc (hwnd, msg, mp1, mp2) ;
229: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.