abef9d4de7ee103420c8f78b2e77c349f6c17244
[reactos.git] / reactos / subsys / system / calc / winecalc.c
1 /*
2 * WineCalc (winecalc.c)
3 *
4 * Copyright 2003 James Briggs
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 #include <stdio.h> // sprintf
22 #include <math.h>
23
24 #include <windows.h>
25 // #include <commctrl.h>
26
27 #include "winecalc.h"
28 #include "dialog.h"
29 #include "stats.h"
30 #include "resource.h"
31
32 // lame M$ math library doesn't support hyp functions
33 //#ifdef _MSC_VER
34 #define atanh(X) atan(X)
35 #define asinh(X) asin(X)
36 #define acosh(X) acos(X)
37 //#endif
38
39 // How winecalc works
40 //
41 // 1. In the original calculator, numbers are "extended precision".
42 // We emulate with calcfloat (calcfloat floating point) for now.
43 // Note that recent M$ compilers 5.0 and later do not implement double float,
44 // and do not support 80-bit numbers. Max width is 64-bits.
45 //
46 // 2. 4 temp areas:
47 //
48 // i) current edit buffer value for keystrokes
49 // ii) computed value area for last computation
50 // iii) memory area for MR, MC, MS, M+
51 // iv) formatted display buffer
52 //
53 // 3. Memory Store works off current buffer, not value
54 //
55 // 4. display limit is 32 numbers plus 10 commas plus one period = 43 characters
56 //
57 // 5. original calc is better called SciCalc and saves settings in win.ini:
58 //
59 // [SciCalc]
60 // layout=1 (0 = scientific mode, 1 = basic mode)
61 // UseSep=1 (0 = no digits separator, 1 = enable digits separator)
62 //
63 // 6. Window Menus
64 //
65 // The menus know their own states, so we don't need to track them
66 // When switching to Standard Calculator Mode, number base is changed to Decimal and Trig Mode to Degrees,
67 // but Word Size Mode is unchanged
68 //
69 // 7. It would be nice to add command line parsing for batch files
70 //
71
72 // various display error messages
73
74 static char err_invalid [CALC_BUF_SIZE];
75 static char err_divide_by_zero [CALC_BUF_SIZE];
76 static char err_undefined [CALC_BUF_SIZE];
77
78 // calculator state is kept here
79
80 CALC calc;
81
82 static RECT rFiller;
83
84 static int keys[CALC_NS_COUNT]['f'+1]; // note: sparse array
85
86 // map from button press to calc[] index
87 // 0, ... 9, A, B, C, D, E, F,FE,DMS,SIN,COS,TAN,EXP, PI
88 static const int h[] = {
89 0, 0, 33, 34, 21, 22, 23, 10, 11, 12, 54, 55, 56 ,57, 58 ,59, 6, 17, 28, 39, 50, 18, 53 };
90
91 // enable status of various buttons on sci mode depending on number base
92 static const int btn_toggle[CALC_NS_COUNT][TOGGLE_COUNT] =
93 // 0, ... 9, A, B, C, D, E, F,FE,DMS,SIN,COS,TAN,EXP,PI
94 {
95 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 },
96 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
97 { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
98 { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ,0 }
99 };
100
101 static int hms[] = { 64, 65, 66 };
102 static int hws[] = { 69, 70, 71, 72 };
103
104 static int sta[] = { 16, 27, 38, 49 };
105
106 static HMENU menus[3];
107
108 static char appname[40];
109
110 static int debug;
111
112 int parse(int wParam, int lParam);
113
114 HWND hWndDlgStats;
115
116 extern HWND hWndListBox;
117
118 HINSTANCE hInstance;
119
120 int WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR cmdline, int cmdshow )
121 {
122 MSG msg;
123 WNDCLASS wc;
124 HWND hWnd;
125 HACCEL haccel;
126
127 char s[CALC_BUF_SIZE];
128 int r;
129
130 hInstance = hInst;
131
132 r = GetProfileString("SciCalc",
133 "layout",
134 "0",
135 s,
136 CALC_BUF_SIZE
137 );
138
139 calc.sciMode = atoi(s);
140
141 if (calc.sciMode != 0 &&
142 calc.sciMode != 1)
143 calc.sciMode = 1; // Standard Mode
144
145 r = GetProfileString("SciCalc",
146 "UseSep",
147 "0",
148 s,
149 CALC_BUF_SIZE
150 );
151
152 calc.digitGrouping = atoi(s);
153
154 if (calc.digitGrouping != 0 &&
155 calc.digitGrouping != 1)
156 calc.digitGrouping = 1;
157
158 calc.new = 1; // initialize struct values
159
160 if (!LoadString( hInst, IDS_APPNAME, appname, sizeof(appname)))
161 exit(1);
162 if (!LoadString( hInst, IDS_ERR_INVALID_INPUT, err_invalid, sizeof(err_invalid)))
163 exit(1);
164 if (!LoadString( hInst, IDS_ERR_DIVIDE_BY_ZERO, err_divide_by_zero, sizeof(err_divide_by_zero)))
165 exit(1);
166 if (!LoadString( hInst, IDS_ERR_UNDEFINED, err_undefined, sizeof(err_undefined)))
167 exit(1);
168
169 wc.style = CS_HREDRAW | CS_VREDRAW;
170 wc.lpfnWndProc = MainProc;
171 wc.cbClsExtra = 0;
172 wc.cbWndExtra = 0;
173 wc.hInstance = hInst;
174 wc.hIcon = LoadIcon( hInst, appname );
175 wc.hCursor = LoadCursor( NULL, IDI_APPLICATION );
176 wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
177 wc.lpszMenuName = NULL;
178 wc.lpszClassName = appname;
179
180 if (!RegisterClass(&wc)) exit(1);
181
182 hWnd = CreateWindow( appname,
183 appname,
184 WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX,
185 CW_USEDEFAULT,
186 CW_USEDEFAULT,
187 calc.sciMode ? CALC_STANDARD_WIDTH : CALC_SCIENTIFIC_WIDTH,
188 calc.sciMode ? CALC_STANDARD_HEIGHT : CALC_SCIENTIFIC_HEIGHT,
189 NULL,
190 NULL,
191 hInst,
192 NULL );
193
194 if (!hWnd)
195 exit(1);
196
197 ShowWindow( hWnd, cmdshow );
198 UpdateWindow( hWnd );
199
200 if (!(haccel = LoadAccelerators(hInst, "MAIN_MENU")))
201 exit(1);
202
203 while( GetMessage(&msg, NULL, 0, 0) ) {
204 if (hWndDlgStats == 0 || !IsDialogMessage(hWndDlgStats, &msg)) {
205 if (!TranslateAccelerator( hWnd, haccel, &msg )) {
206 TranslateMessage( &msg );
207 DispatchMessage( &msg );
208 }
209 }
210 }
211
212 return msg.wParam;
213 }
214
215 LRESULT WINAPI MainProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
216 {
217 HDC hdc;
218 PAINTSTRUCT ps;
219
220 switch (msg) {
221
222 case WM_CREATE:
223 calc.hInst = ((LPCREATESTRUCT) lParam)->hInstance;
224 calc.hWnd = hWnd;
225
226 InitLuts();
227 InitCalc( &calc );
228 InitMenus(calc.hInst);
229
230 if (calc.sciMode)
231 SetMenu(hWnd, menus[MENU_STD]);
232 else
233 SetMenu(hWnd, menus[MENU_SCIMS]);
234
235 calc_buffer_display(&calc);
236
237 return 0;
238
239 case WM_PAINT:
240 {
241 HDC hMemDC;
242
243 hdc = BeginPaint( hWnd, &ps );
244 hMemDC = CreateCompatibleDC( hdc );
245
246 DrawCalc( hdc, hMemDC, &ps, &calc );
247
248 DeleteDC( hMemDC );
249 EndPaint( hWnd, &ps );
250
251 return 0;
252 }
253
254 case WM_MOVE:
255 calc.pos.x = (unsigned) LOWORD(lParam);
256 calc.pos.y = (unsigned) HIWORD(lParam);
257 return 0;
258
259 case WM_DESTROY:
260 {
261 int r;
262 char s[CALC_BUF_SIZE];
263
264 sprintf(s, "%d", calc.sciMode);
265 r = WriteProfileString("SciCalc", "layout", s);
266
267 sprintf(s, "%d", calc.digitGrouping);
268 r = WriteProfileString("SciCalc", "UseSep", s);
269 }
270
271 DestroyCalc( &calc );
272 PostQuitMessage( 0 );
273 return 0;
274
275 case WM_KEYDOWN:
276 switch (wParam) {
277
278 case VK_F1:
279 calc.next = 1;
280 MessageBox(hWnd, "No Help Available", "Windows Help", MB_OK);
281 return 0;
282
283 case VK_F2: // DWORD
284
285 calc.next = 1;
286 if (!calc.sciMode) {
287 if (calc.numBase == NBASE_DECIMAL)
288 SendMessage(hWnd, WM_COMMAND, ID_CALC_MS_DEGREES, lParam);
289 else
290 SendMessage(hWnd, WM_COMMAND, ID_CALC_WS_DWORD, lParam);
291 }
292 return 0;
293
294 case VK_F3: // WORD
295
296 calc.next = 1;
297 if (!calc.sciMode) {
298 if (calc.numBase == NBASE_DECIMAL)
299 SendMessage(hWnd, WM_COMMAND, ID_CALC_MS_RADIANS, lParam);
300 else
301 SendMessage(hWnd, WM_COMMAND, ID_CALC_WS_WORD, lParam);
302 }
303 return 0;
304
305 case VK_F4: // Byte
306
307 // Grad
308 calc.next = 1;
309 if (!calc.sciMode) {
310 if (calc.numBase == NBASE_DECIMAL)
311 SendMessage(hWnd, WM_COMMAND, ID_CALC_MS_GRADS, lParam);
312 else
313 SendMessage(hWnd, WM_COMMAND, ID_CALC_WS_BYTE, lParam);
314 }
315 return 0;
316
317 case VK_F5: // Hex
318
319 calc.next = 1;
320 if (!calc.sciMode)
321 SendMessage(hWnd, WM_COMMAND, ID_CALC_NS_HEX, lParam);
322 return 0;
323
324 case VK_F6: // Decimal
325
326 calc.next = 1;
327 if (!calc.sciMode)
328 SendMessage(hWnd, WM_COMMAND, ID_CALC_NS_DEC, lParam);
329 return 0;
330
331 case VK_F7: // Octal
332
333 calc.next = 1;
334 if (!calc.sciMode)
335 SendMessage(hWnd, WM_COMMAND, ID_CALC_NS_OCT, lParam);
336 return 0;
337
338 case VK_F8: // Binary
339
340 calc.next = 1;
341 if (!calc.sciMode)
342 SendMessage(hWnd, WM_COMMAND, ID_CALC_NS_BIN, lParam);
343 return 0;
344
345 case VK_F12: // QWORD
346
347 calc.next = 1;
348 if (!calc.sciMode)
349 SendMessage(hWnd, WM_COMMAND, ID_CALC_WS_QWORD, lParam);
350 return 0;
351
352 case VK_F9: // +/-
353
354 if (!calc.sciMode)
355 SendMessage(hWnd, WM_CHAR, 'Z', lParam);
356 return 0;
357
358 case VK_INSERT: // Dat
359 calc.next = 1;
360 SendMessage(hWndListBox, LB_INSERTSTRING, -1, (LPARAM)calc.buffer);
361 InvalidateRect(hWndDlgStats, NULL, TRUE); // update list count at bottom edge of dialog
362 UpdateWindow(hWndDlgStats);
363 return 0;
364
365 case VK_DELETE:
366
367 calc.next = 1;
368 calc.buffer[0] = '\0';
369 calc_buffer_display(&calc);
370 return 0;
371
372 default:
373 break;
374 }
375
376 return 0;
377
378 case WM_CHAR:
379 if (debug)
380 show_debug(&calc, "Start WM_CHAR", wParam, lParam);
381
382 switch (wParam) {
383
384 case '\x13': // Ctrl+S Sta Statistics
385
386 if (hWndDlgStats) { // Statistics Box already displayed, focus but don't create another one
387 // SetFocus(hWndDlgStats);
388 // SendMessage(hWndDlgStats, WM_SETFOCUS, 0, 0);
389 }
390 else {
391 int i;
392
393 if (lParam == 1) {
394 for (i=0;i<4;i++)
395 EnableWindow((HWND)calc.cb[sta[i]].hBtn, FALSE);
396 }
397 else {
398 for (i=0;i<4;i++)
399 EnableWindow((HWND)calc.cb[sta[i]].hBtn, TRUE);
400
401 hWndDlgStats = CreateDialog( // modeless dialog
402 calc.hInst, // handle to application instance
403 "DLG_STATS", // identifies dialog box template name
404 hWnd, // handle to owner window
405 StatsDlgProc); // pointer to dialog box procedure
406
407 if (!hWndDlgStats)
408 exit(1);
409
410 SendMessage(hWndDlgStats, WM_SETFOCUS, 0, 0);
411 }
412 }
413
414 break;
415
416 case '\x01': // Ctrl+A Ave Statistics
417 case '\x04': // Ctrl+D s Standard Deviation Statistics
418 case '\x14': // Ctrl+T Sum Statistics
419 {
420 int i;
421 int n;
422
423 char s[CALC_BUF_SIZE];
424 double val = 0L;
425 double avg = 0L;
426 double total = 0L;
427 double x[1024];
428
429 // This is all lame. Here we are querying the list control for items and calculating the total.
430 // We should have an array of intermediate results to work with to avoid roundoff errors, etc.
431
432 n = SendMessage(hWndListBox, LB_GETCOUNT, 0, 0);
433
434 for (i=0;i<n;i++) {
435 SendMessage(hWndListBox, LB_GETTEXT, i, (LPARAM)s);
436 val = calc_atof(s,calc.numBase);
437 total += val;
438 x[i] = val;
439 }
440
441 if (LOWORD(wParam) != '\x14') // not sum only
442 avg = total / n;
443
444 if (LOWORD(wParam == '\x04')) { // standard deviation is sqrt(sum( xbar - x )^2 / (n-1))
445 val = 0L;
446
447 for (i=0;i<n;i++)
448 val += pow(x[i] - avg, 2);
449
450 if (calc.invMode)
451 total = sqrt(val / n); // complete population
452 else
453 total = sqrt(val / (n - 1)); // sample of population
454 }
455
456 if (LOWORD(wParam) == '\x01') // average or mean
457 total = avg;
458
459 calc_ftoa(&calc, total, s);
460 strcpy(calc.buffer, s);
461 calc_buffer_display(&calc);
462 }
463
464 break;
465
466 case '\x03': // Ctrl+C Copy
467 {
468 int i;
469 int len;
470 char *s;
471 HGLOBAL hGlobalMemory;
472 PSTR pGlobalMemory;
473
474 if (!(len = strlen(calc.display)))
475 return 0;
476
477 if (!(hGlobalMemory = GlobalAlloc(GHND, len + 1)))
478 return 0;
479
480 if (!(pGlobalMemory = GlobalLock(hGlobalMemory)))
481 return 0;
482
483 if (!(s = calc.display))
484 return 0;
485
486 for (i = 0; i < len; i++)
487 *pGlobalMemory++ = *s++;
488
489 GlobalUnlock(hGlobalMemory); // call GetLastError() for exception handling
490
491 if (!OpenClipboard(hWnd))
492 return 0;
493
494 if (!EmptyClipboard())
495 return 0;
496
497 if (!SetClipboardData(CF_TEXT, hGlobalMemory))
498 return 0;
499
500 if (!CloseClipboard())
501 return 0;
502 }
503 break;
504
505 case '\x16': // Ctrl+V Paste
506 {
507 char *s;
508 int c;
509 int cmd = 0;
510 int size = 0;
511 int i = 0;
512 HGLOBAL hGlobalMemory;
513 PSTR pGlobalMemory;
514
515 if (IsClipboardFormatAvailable(CF_TEXT)) {
516 if (!OpenClipboard(hWnd))
517 return 0;
518
519 if (!(hGlobalMemory = GetClipboardData(CF_TEXT)))
520 return 0;
521
522 if (!(size = GlobalSize(hGlobalMemory)))
523 return 0;
524
525 if (!(s = (char *)malloc(size)))
526 return 0;
527
528 if (!(pGlobalMemory = GlobalLock(hGlobalMemory)))
529 return 0;
530
531 strcpy(s, pGlobalMemory);
532
533 GlobalUnlock(hGlobalMemory);
534
535 if (!CloseClipboard())
536 return 0;
537
538 // calc paste protocol
539 //
540 // :c clear memory WM_CHAR, 0x0c
541 // :e enable scientific notation WM_CHAR, 'v'
542 // :m store display in memory WM_CHAR, 0x0d
543 // :p add display to memory WM_CHAR, 0x10
544 // :q clear current calculation WM_CHAR, '\x1b'
545 // :r read memory into display WM_CHAR, 0x12
546 // \ Dat WM_CHAR, VK_INSERT
547 //
548 // parse the pasted data, validate and SendMessage it one character at a time.
549 // it would appear wincalc does it this way (slow), although very slow appearing on Wine.
550
551 while ((c = *s++) && (i++ < size)) {
552 if (c == ':') {
553 cmd = 1;
554 }
555 else if (c == '\\') {
556 SendMessage(hWnd, WM_KEYDOWN, VK_INSERT, lParam);
557 }
558 else {
559 if (cmd) {
560 cmd = 0;
561
562 switch(c) {
563 case 'c': // clear memory
564
565 case 'C':
566 SendMessage(hWnd, WM_CHAR, 0x0c, lParam);
567 break;
568 case 'e': // enable scientific notation
569
570 case 'E':
571 SendMessage(hWnd, WM_CHAR, 'v', lParam);
572 break;
573 case 'm': // store display in memory
574
575 case 'M':
576 SendMessage(hWnd, WM_CHAR, 0x0d, NUMBER_OF_THE_BEAST);
577 break;
578 case 'p': // add display to memory
579
580 case 'P':
581 SendMessage(hWnd, WM_CHAR, 0x10, lParam);
582 break;
583 case 'q': // clear current calculation
584
585 case 'Q':
586 SendMessage(hWnd, WM_CHAR, '\x1b', lParam);
587 break;
588 case 'r': // read memory into display
589
590 case 'R':
591 SendMessage(hWnd, WM_CHAR, 0x12, lParam);
592 break;
593 default: // just eat it but complain
594
595 MessageBeep(0);
596 break;
597 }
598 }
599 else {
600 if ((calc.numBase == NBASE_HEX) &&
601 ((c >= '0' && c <= '9') ||
602 (c >= 'a' && c <= 'f') ||
603 (c >= 'A' && c <= 'F'))) {
604
605 SendMessage(hWnd, WM_CHAR, c, lParam);
606 }
607 else if ((calc.numBase == NBASE_DECIMAL) &&
608 (c >= '0' && c <= '9')) {
609 SendMessage(hWnd, WM_CHAR, c, lParam);
610 }
611 else if ((calc.numBase == NBASE_OCTAL) &&
612 (c >= '0' && c <= '7')) {
613 SendMessage(hWnd, WM_CHAR, c, lParam);
614 }
615 else if ((calc.numBase == NBASE_BINARY) &&
616 (c == '0' || c == '1')) {
617 SendMessage(hWnd, WM_CHAR, c, lParam);
618 }
619 else if (c == '.' || c == ',' ||
620 c == 'e' || c == 'E' ||
621 c == '+' || c == '-') {
622 SendMessage(hWnd, WM_CHAR, c, lParam);
623 }
624 else if (c == ' ' || // eat harmless trash here
625 c == ';' ||
626 c == ':') {
627 ; // noop
628 }
629 else { // extra spicy trash gets noticed
630
631 MessageBeep(0); // uh, beeps can get annoying. maybe rate limit.
632 }
633 }
634 }
635 }
636 }
637 }
638
639 break;
640 default:
641 {
642 parse(wParam, lParam);
643 }
644 } // switch WM_CHAR
645
646 calc_buffer_display(&calc);
647 return 0;
648
649 case WM_COMMAND:
650 switch(LOWORD(wParam)) {
651
652 case IDM_COPY:
653 SendMessage(hWnd, WM_CHAR, '\x03', lParam);
654 return 0;
655
656 case IDM_PASTE:
657 SendMessage(hWnd, WM_CHAR, '\x16', lParam);
658 return 0;
659
660 case IDM_MODE_STANDARD:
661 if (!calc.sciMode) {
662 int i;
663 RECT lpRect;
664
665 calc.sciMode = 1;
666 calc.trigMode = TRIGMODE_DEGREES;
667 calc.numBase = NBASE_DECIMAL;
668
669 EnableWindow(hWnd, FALSE);
670
671
672 for (i=1;i<COUNT_MENUS;i++) {
673 if (calc.numBase != ID_CALC_NS_DEC) {
674 CheckMenuItem(menus[i], ID_CALC_NS_HEX, MF_UNCHECKED);
675 CheckMenuItem(menus[i], ID_CALC_NS_DEC, MF_CHECKED);
676 CheckMenuItem(menus[i], ID_CALC_NS_OCT, MF_UNCHECKED);
677 CheckMenuItem(menus[i], ID_CALC_NS_BIN, MF_UNCHECKED);
678 }
679 }
680
681 for (i=1;i<COUNT_MENUS;i++) {
682 CheckMenuItem(menus[i], ID_CALC_MS_DEGREES, MF_CHECKED);
683 CheckMenuItem(menus[i], ID_CALC_MS_RADIANS, MF_UNCHECKED);
684 CheckMenuItem(menus[i], ID_CALC_MS_GRADS, MF_UNCHECKED);
685 }
686
687 SetMenu(hWnd, menus[MENU_STD]);
688
689 // SendMessage(hWnd, WM_SIZE, SIZE_RESTORED, CALC_STANDARD_WIDTH | (CALC_STANDARD_HEIGHT << 8));
690 GetWindowRect(hWnd, &lpRect);
691 MoveWindow(hWnd, lpRect.left, lpRect.top, CALC_STANDARD_WIDTH, CALC_STANDARD_HEIGHT, TRUE);
692 DestroyCalc(&calc);
693 InitCalc(&calc);
694
695 EnableWindow(hWnd, TRUE);
696
697 }
698 return 0;
699
700 case IDM_MODE_SCIENTIFIC:
701 if (calc.sciMode) {
702 RECT lpRect;
703 calc.sciMode = 0;
704
705 EnableWindow(hWnd, FALSE);
706
707 SetMenu(hWnd, menus[MENU_SCIMS]);
708
709 GetWindowRect(hWnd, &lpRect);
710 MoveWindow(hWnd, lpRect.left, lpRect.top, CALC_SCIENTIFIC_WIDTH, CALC_SCIENTIFIC_HEIGHT, TRUE);
711 DestroyCalc(&calc);
712 InitCalc(&calc);
713
714 if (calc.invMode)
715 SendMessage(calc.cb[67].hBtn, BM_SETCHECK, TRUE, 0);
716
717 if (calc.hypMode)
718 SendMessage(calc.cb[68].hBtn, BM_SETCHECK, TRUE, 0);
719
720 EnableWindow(hWnd, TRUE);
721
722 }
723 return 0;
724
725 case IDM_DIGIT_GROUPING:
726 {
727 int i;
728 int n;
729
730 calc.digitGrouping = !calc.digitGrouping;
731
732 n = (calc.digitGrouping ? MF_CHECKED : MF_UNCHECKED);
733
734 for (i=0;i<COUNT_MENUS;i++)
735 CheckMenuItem(menus[i], IDM_DIGIT_GROUPING, n);
736
737 calc_buffer_display(&calc);
738 }
739 return 0;
740
741 case IDM_HELP_TOPICS:
742 MessageBox(hWnd, "No Help Available", "Windows Help", MB_OK);
743 return 0;
744
745 case IDM_ABOUT:
746 DialogBox( calc.hInst, "DLG_ABOUT", hWnd, AboutDlgProc );
747 return 0;
748
749 case ID_CALC_NS_HEX:
750 case ID_CALC_NS_DEC:
751 case ID_CALC_NS_OCT:
752 case ID_CALC_NS_BIN:
753 {
754 int i;
755 int w = LOWORD(wParam);
756
757 if (w == ID_CALC_NS_HEX) {
758 if (calc.numBase == NBASE_HEX)
759 return 0;
760 else
761 calc.numBase = NBASE_HEX;
762 }
763 else if (w == ID_CALC_NS_DEC) {
764 if (calc.numBase == NBASE_DECIMAL)
765 return 0;
766 else
767 calc.numBase = NBASE_DECIMAL;
768 }
769 else if (w == ID_CALC_NS_OCT) {
770 if (calc.numBase == NBASE_OCTAL)
771 return 0;
772 else
773 calc.numBase = NBASE_OCTAL;
774 }
775 else if (w == ID_CALC_NS_BIN) {
776 if (calc.numBase == NBASE_BINARY)
777 return 0;
778 else
779 calc.numBase = NBASE_BINARY;
780 }
781
782 for (i=0;i<CALC_NS_COUNT;i++)
783 SendMessage(calc.cb[60+i].hBtn, BM_SETCHECK, w == (ID_CALC_NS_HEX + i) ? 1 : 0, 0);
784
785 for (i=2;i<TOGGLE_COUNT;i++) { // skip 0 and 1, always valid
786 if (btn_toggle[w - ID_CALC_NS_HEX ][i]) {
787 if (!IsWindowEnabled((HWND)calc.cb[h[i]].hBtn))
788 EnableWindow((HWND)calc.cb[h[i]].hBtn, TRUE);
789
790 }
791 else {
792 if (IsWindowEnabled((HWND)calc.cb[h[i]].hBtn))
793 EnableWindow((HWND)calc.cb[h[i]].hBtn, FALSE);
794 }
795 }
796
797 if (w == ID_CALC_NS_DEC) {
798 for (i=0;i<CALC_WS_COUNT;i++) {
799 if (IsWindowEnabled((HWND)calc.cb[hws[i]].hBtn)) {
800 ShowWindow((HWND)calc.cb[hws[i]].hBtn, SW_HIDE);
801 EnableWindow((HWND)calc.cb[hws[i]].hBtn, FALSE);
802 }
803 }
804 for (i=0;i<CALC_MS_COUNT;i++) {
805 if (!IsWindowEnabled((HWND)calc.cb[hms[i]].hBtn)) {
806 ShowWindow((HWND)calc.cb[hms[i]].hBtn, SW_SHOWNORMAL);
807 EnableWindow((HWND)calc.cb[hms[i]].hBtn, TRUE);
808 }
809 }
810 }
811 else {
812 for (i=0;i<CALC_MS_COUNT;i++) {
813 if (IsWindowEnabled((HWND)calc.cb[hms[i]].hBtn)) {
814 ShowWindow((HWND)calc.cb[hms[i]].hBtn, SW_HIDE);
815 EnableWindow((HWND)calc.cb[hms[i]].hBtn, FALSE);
816 }
817 }
818 for (i=0;i<CALC_WS_COUNT;i++) {
819 if (!IsWindowEnabled((HWND)calc.cb[hws[i]].hBtn)) {
820 ShowWindow((HWND)calc.cb[hws[i]].hBtn, SW_SHOWNORMAL);
821 EnableWindow((HWND)calc.cb[hws[i]].hBtn, TRUE);
822 }
823 }
824 }
825
826 CheckMenuItem(menus[i], ID_CALC_MS_DEGREES, MF_CHECKED);
827
828 for (i=1;i<COUNT_MENUS;i++) { // skip the simple Standard calculator mode
829 CheckMenuItem(menus[i], ID_CALC_NS_HEX, (w == ID_CALC_NS_HEX ? MF_CHECKED : MF_UNCHECKED) );
830 CheckMenuItem(menus[i], ID_CALC_NS_DEC, (w == ID_CALC_NS_DEC ? MF_CHECKED : MF_UNCHECKED) );
831 CheckMenuItem(menus[i], ID_CALC_NS_OCT, (w == ID_CALC_NS_OCT ? MF_CHECKED : MF_UNCHECKED) );
832 CheckMenuItem(menus[i], ID_CALC_NS_BIN, (w == ID_CALC_NS_BIN ? MF_CHECKED : MF_UNCHECKED) );
833 }
834
835 if (wParam == ID_CALC_NS_DEC) {
836 SetMenu(hWnd, menus[MENU_SCIMS]);
837
838 }
839 else {
840 calc.displayMode = 0;
841 SetMenu(hWnd, menus[MENU_SCIWS]);
842 }
843 }
844 calc_buffer_display(&calc);
845
846 break;
847
848 case ID_CALC_MS_DEGREES:
849 case ID_CALC_MS_RADIANS:
850 case ID_CALC_MS_GRADS:
851 {
852 int i;
853 int w = LOWORD(wParam);
854
855 if (w == ID_CALC_MS_DEGREES)
856 calc.trigMode = TRIGMODE_DEGREES;
857 else if (w == ID_CALC_MS_RADIANS)
858 calc.trigMode = TRIGMODE_RADIANS;
859 else if (w == ID_CALC_MS_GRADS)
860 calc.trigMode = TRIGMODE_GRADS;
861 else
862 return 0;
863
864 for (i=0;i<CALC_MS_COUNT;i++)
865 SendMessage(calc.cb[64+i].hBtn, BM_SETCHECK, w == (ID_CALC_MS_DEGREES + i) ? 1 : 0, 0);
866
867 for (i=1;i<COUNT_MENUS;i++) { // skip the simple Standard calculator mode
868 CheckMenuItem(menus[i], ID_CALC_MS_DEGREES, (wParam == ID_CALC_MS_DEGREES) ? MF_CHECKED : MF_UNCHECKED);
869 CheckMenuItem(menus[i], ID_CALC_MS_RADIANS, (wParam == ID_CALC_MS_RADIANS) ? MF_CHECKED : MF_UNCHECKED);
870 CheckMenuItem(menus[i], ID_CALC_MS_GRADS, (wParam == ID_CALC_MS_GRADS) ? MF_CHECKED : MF_UNCHECKED);
871 }
872 }
873
874 SetFocus(hWnd);
875 return 0;
876
877 case ID_CALC_WS_QWORD:
878 case ID_CALC_WS_DWORD:
879 case ID_CALC_WS_WORD:
880 case ID_CALC_WS_BYTE:
881 {
882 int i;
883 int w = LOWORD(wParam);
884
885 calc.wordSize = w;
886
887 for (i=0;i<CALC_WS_COUNT;i++)
888 SendMessage(calc.cb[69+i].hBtn, BM_SETCHECK, LOWORD(wParam) == (ID_CALC_WS_QWORD + i) ? 1 : 0, 0);
889
890 for (i=1; i<COUNT_MENUS; i++) { // skip the simple Standard calculator mode
891 CheckMenuItem(menus[i], ID_CALC_WS_QWORD, (w == ID_CALC_WS_QWORD ? MF_CHECKED : MF_UNCHECKED) );
892 CheckMenuItem(menus[i], ID_CALC_WS_DWORD, (w == ID_CALC_WS_DWORD ? MF_CHECKED : MF_UNCHECKED) );
893 CheckMenuItem(menus[i], ID_CALC_WS_WORD, (w == ID_CALC_WS_WORD ? MF_CHECKED : MF_UNCHECKED) );
894 CheckMenuItem(menus[i], ID_CALC_WS_BYTE, (w == ID_CALC_WS_BYTE ? MF_CHECKED : MF_UNCHECKED) );
895 }
896 }
897
898 SetFocus(hWnd);
899 return 0;
900
901 case ID_CALC_CB_INV:
902 if (calc.invMode)
903 calc.invMode = 0;
904 else
905 calc.invMode = 1;
906
907 SendMessage(calc.cb[67].hBtn, BM_SETCHECK, calc.invMode ? TRUE : FALSE, 0);
908 SetFocus(hWnd);
909 return 0;
910
911 case ID_CALC_CB_HYP:
912 if (calc.hypMode)
913 calc.hypMode = 0;
914 else
915 calc.hypMode = 1;
916
917 SendMessage(calc.cb[68].hBtn, BM_SETCHECK, calc.hypMode ? TRUE : FALSE, 0);
918 SetFocus(hWnd);
919 return 0;
920
921 default:
922 if (HIWORD(wParam) == BN_CLICKED) {
923
924 if (calc.err &&
925 LOWORD(wParam) != ID_CALC_CLEAR_ENTRY &&
926 LOWORD(wParam) != ID_CALC_CLEAR_ALL) {
927
928 MessageBeep(0);
929 return 0;
930 }
931 else {
932 calc.err = 0;
933 }
934
935 switch (LOWORD(wParam)) {
936
937 case ID_CALC_ZERO:
938 case ID_CALC_ONE:
939 case ID_CALC_TWO:
940 case ID_CALC_THREE:
941 case ID_CALC_FOUR:
942 case ID_CALC_FIVE:
943 case ID_CALC_SIX:
944 case ID_CALC_SEVEN:
945 case ID_CALC_EIGHT:
946 case ID_CALC_NINE:
947 SendMessage(hWnd, WM_CHAR, LOWORD(wParam)+'0' , lParam);
948 break;
949
950 case ID_CALC_A:
951 SendMessage(hWnd, WM_CHAR, 'a', lParam);
952 break;
953
954 case ID_CALC_B:
955 SendMessage(hWnd, WM_CHAR, 'b', lParam);
956 break;
957
958 case ID_CALC_C:
959 SendMessage(hWnd, WM_CHAR, 'c', lParam);
960 break;
961
962 case ID_CALC_D:
963 SendMessage(hWnd, WM_CHAR, 'd', lParam);
964 break;
965
966 case ID_CALC_E:
967 SendMessage(hWnd, WM_CHAR, 'e', lParam);
968 break;
969
970 case ID_CALC_F:
971 SendMessage(hWnd, WM_CHAR, 'f', lParam);
972 break;
973
974 case ID_CALC_DECIMAL:
975 SendMessage(hWnd, WM_CHAR, '.', lParam);
976 break;
977
978 case ID_CALC_BACKSPACE:
979 SendMessage(hWnd, WM_CHAR, '\b', lParam);
980 break;
981
982 case ID_CALC_CLEAR_ENTRY:
983 SendMessage(hWnd, WM_KEYDOWN, VK_DELETE , lParam);
984 break;
985
986 case ID_CALC_CLEAR_ALL:
987 SendMessage(hWnd, WM_CHAR, '\x1b', lParam);
988 break;
989
990 case ID_CALC_MEM_CLEAR:
991 SendMessage(hWnd, WM_CHAR, 0x0c, lParam);
992 break;
993
994 case ID_CALC_MEM_RECALL:
995 SendMessage(hWnd, WM_CHAR, 0x12, lParam);
996 break;
997
998 case ID_CALC_MEM_STORE:
999 SendMessage(hWnd, WM_CHAR, 0x0d, NUMBER_OF_THE_BEAST); // trying to tell between Return and Ctrl+M
1000 break;
1001
1002 case ID_CALC_MEM_PLUS:
1003 SendMessage(hWnd, WM_CHAR, 0x10, lParam);
1004 break;
1005
1006 case ID_CALC_SQRT:
1007 SendMessage(hWnd, WM_CHAR, '?', lParam); // this is not a wincalc keystroke
1008 break;
1009
1010 case ID_CALC_SQUARE:
1011 SendMessage(hWnd, WM_CHAR, '@', lParam);
1012 break;
1013
1014 case ID_CALC_PI:
1015 SendMessage(hWnd, WM_CHAR, 'p', lParam);
1016 break;
1017
1018 case ID_CALC_LN:
1019 SendMessage(hWnd, WM_CHAR, 'n', lParam);
1020 break;
1021
1022 case ID_CALC_LOG10:
1023 SendMessage(hWnd, WM_CHAR, 'l', lParam);
1024 break;
1025
1026 case ID_CALC_CUBE:
1027 SendMessage(hWnd, WM_CHAR, '#', lParam);
1028 break;
1029
1030 case ID_CALC_POWER:
1031 SendMessage(hWnd, WM_CHAR, 'y', lParam);
1032 break;
1033
1034 case ID_CALC_SIN:
1035 SendMessage(hWnd, WM_CHAR, 's', lParam);
1036 break;
1037
1038 case ID_CALC_COS:
1039 SendMessage(hWnd, WM_CHAR, 'o', lParam);
1040 break;
1041
1042 case ID_CALC_TAN:
1043 SendMessage(hWnd, WM_CHAR, 't', lParam);
1044 break;
1045
1046 case ID_CALC_LSH:
1047 SendMessage(hWnd, WM_CHAR, '<', lParam);
1048 break;
1049
1050 case ID_CALC_NOT:
1051 SendMessage(hWnd, WM_CHAR, '~', lParam);
1052 break;
1053
1054 case ID_CALC_AND:
1055 SendMessage(hWnd, WM_CHAR, '&', lParam);
1056 break;
1057
1058 case ID_CALC_OR:
1059 SendMessage(hWnd, WM_CHAR, '|', lParam);
1060 break;
1061
1062 case ID_CALC_XOR:
1063 SendMessage(hWnd, WM_CHAR, '^', lParam);
1064 break;
1065
1066 case ID_CALC_INT:
1067 SendMessage(hWnd, WM_CHAR, ';', lParam);
1068 break;
1069
1070 case ID_CALC_FACTORIAL:
1071 SendMessage(hWnd, WM_CHAR, '!', lParam);
1072 break;
1073
1074 case ID_CALC_RECIPROCAL:
1075 SendMessage(hWnd, WM_CHAR, 'r', lParam);
1076 break;
1077
1078 case ID_CALC_SIGN:
1079 SendMessage(hWnd, WM_KEYDOWN, VK_F9, lParam);
1080 break;
1081
1082 case ID_CALC_PLUS:
1083 SendMessage(hWnd, WM_CHAR, '+', lParam);
1084 break;
1085
1086 case ID_CALC_MINUS:
1087 SendMessage(hWnd, WM_CHAR, '-', lParam);
1088 break;
1089
1090 case ID_CALC_MULTIPLY:
1091 SendMessage(hWnd, WM_CHAR, '*', lParam);
1092 break;
1093
1094 case ID_CALC_DIVIDE:
1095 SendMessage(hWnd, WM_CHAR, '/', lParam);
1096 break;
1097
1098 case ID_CALC_EQUALS:
1099 SendMessage(hWnd, WM_CHAR, '=', lParam);
1100 break;
1101
1102 case ID_CALC_PERCENT:
1103 SendMessage(hWnd, WM_CHAR, '%', lParam);
1104 break;
1105
1106 case ID_CALC_EXP:
1107 SendMessage(hWnd, WM_CHAR, 'x', lParam);
1108 break;
1109
1110 case ID_CALC_FE:
1111 SendMessage(hWnd, WM_CHAR, 'v', lParam);
1112 break;
1113
1114 case ID_CALC_LEFTPAREN:
1115 SendMessage(hWnd, WM_CHAR, '(', lParam);
1116 break;
1117
1118 case ID_CALC_RIGHTPAREN:
1119 SendMessage(hWnd, WM_CHAR, ')', lParam);
1120 break;
1121
1122 case ID_CALC_MOD:
1123 SendMessage(hWnd, WM_CHAR, '%', lParam);
1124 break;
1125
1126 case ID_CALC_DAT:
1127 SendMessage(hWnd, WM_KEYDOWN, VK_INSERT, lParam);
1128 break;
1129
1130 case ID_CALC_AVE:
1131 SendMessage(hWnd, WM_CHAR, '\x01', lParam); // Ctrl+A
1132 break;
1133
1134 case ID_CALC_S:
1135 SendMessage(hWnd, WM_CHAR, '\x04', lParam); // Ctrl+D
1136 break;
1137
1138 case ID_CALC_STA:
1139 SendMessage(hWnd, WM_CHAR, '\x13', lParam); // Ctrl+S
1140 break;
1141
1142 case ID_CALC_SUM:
1143 SendMessage(hWnd, WM_CHAR, '\x14', lParam); // Ctrl+T
1144 break;
1145
1146 case ID_CALC_DMS:
1147 SendMessage(hWnd, WM_CHAR, 'm', lParam);
1148 break;
1149
1150 default:
1151 break;
1152
1153 } // button message switch
1154
1155
1156 SetFocus(hWnd);
1157
1158 if (debug)
1159 show_debug(&calc, "After WM_CHAR", wParam, lParam);
1160
1161 return 0;
1162
1163 } // if BN_CLICKED
1164 } // WM_COMMAND switch
1165 } // Main Message switch
1166 return( DefWindowProc( hWnd, msg, wParam, lParam ));
1167 } // MainProc
1168
1169 void InitLuts(void)
1170 {
1171 int i;
1172
1173 // initialize keys lut for validating keystrokes in various number bases
1174
1175 for (i='0';i<='9';i++) {
1176 keys[NBASE_HEX][i] = 1;
1177 keys[NBASE_DECIMAL][i] = 1;
1178
1179 if (i <= '7')
1180 keys[NBASE_OCTAL][i] = 1;
1181
1182 if (i <= '1')
1183 keys[NBASE_BINARY][i] = 1;
1184 }
1185
1186 for (i='a';i<='f';i++)
1187 keys[NBASE_HEX][i] = 1;
1188
1189 for (i='A';i<='F';i++)
1190 keys[NBASE_HEX][i] = 1;
1191 }
1192
1193 void InitMenus(HINSTANCE hInst)
1194 {
1195 if (!(menus[MENU_STD] = LoadMenu(hInst,"MAIN_MENU")))
1196 exit(1);
1197
1198 if (!(menus[MENU_SCIMS] = LoadMenu(hInst,"SCIMS_MENU")))
1199 exit(1);
1200
1201 if (!(menus[MENU_SCIWS] = LoadMenu(hInst,"SCIWS_MENU")))
1202 exit(1);
1203
1204 CheckMenuItem(menus[MENU_STD], IDM_MODE_STANDARD, MF_CHECKED);
1205 if (calc.digitGrouping) {
1206 CheckMenuItem(menus[MENU_STD], IDM_DIGIT_GROUPING, MF_CHECKED);
1207 CheckMenuItem(menus[MENU_SCIMS], IDM_DIGIT_GROUPING, MF_CHECKED);
1208 CheckMenuItem(menus[MENU_SCIWS], IDM_DIGIT_GROUPING, MF_CHECKED);
1209 }
1210
1211 calc_setmenuitem_radio(menus[MENU_STD], IDM_MODE_STANDARD);
1212 calc_setmenuitem_radio(menus[MENU_STD], IDM_MODE_SCIENTIFIC);
1213
1214
1215 calc_setmenuitem_radio(menus[MENU_SCIMS], IDM_MODE_STANDARD);
1216 calc_setmenuitem_radio(menus[MENU_SCIMS], IDM_MODE_SCIENTIFIC);
1217
1218 calc_setmenuitem_radio(menus[MENU_SCIMS], ID_CALC_NS_HEX);
1219 calc_setmenuitem_radio(menus[MENU_SCIMS], ID_CALC_NS_DEC);
1220 calc_setmenuitem_radio(menus[MENU_SCIMS], ID_CALC_NS_OCT);
1221 calc_setmenuitem_radio(menus[MENU_SCIMS], ID_CALC_NS_BIN);
1222
1223 calc_setmenuitem_radio(menus[MENU_SCIMS], ID_CALC_MS_DEGREES);
1224 calc_setmenuitem_radio(menus[MENU_SCIMS], ID_CALC_MS_RADIANS);
1225 calc_setmenuitem_radio(menus[MENU_SCIMS], ID_CALC_MS_GRADS);
1226 CheckMenuItem(menus[MENU_SCIMS], IDM_MODE_SCIENTIFIC, MF_CHECKED);
1227 CheckMenuItem(menus[MENU_SCIMS], ID_CALC_NS_DEC, MF_CHECKED);
1228 CheckMenuItem(menus[MENU_SCIMS], ID_CALC_MS_DEGREES, MF_CHECKED);
1229
1230
1231 calc_setmenuitem_radio(menus[MENU_SCIWS], IDM_MODE_STANDARD);
1232 calc_setmenuitem_radio(menus[MENU_SCIWS], IDM_MODE_SCIENTIFIC);
1233
1234 calc_setmenuitem_radio(menus[MENU_SCIWS], ID_CALC_NS_HEX);
1235 calc_setmenuitem_radio(menus[MENU_SCIWS], ID_CALC_NS_DEC);
1236 calc_setmenuitem_radio(menus[MENU_SCIWS], ID_CALC_NS_OCT);
1237 calc_setmenuitem_radio(menus[MENU_SCIWS], ID_CALC_NS_BIN);
1238
1239 calc_setmenuitem_radio(menus[MENU_SCIWS], ID_CALC_WS_QWORD);
1240 calc_setmenuitem_radio(menus[MENU_SCIWS], ID_CALC_WS_DWORD);
1241 calc_setmenuitem_radio(menus[MENU_SCIWS], ID_CALC_WS_WORD);
1242 calc_setmenuitem_radio(menus[MENU_SCIWS], ID_CALC_WS_BYTE);
1243 CheckMenuItem(menus[MENU_SCIWS], IDM_MODE_SCIENTIFIC, MF_CHECKED);
1244 CheckMenuItem(menus[MENU_SCIWS], ID_CALC_NS_DEC, MF_CHECKED);
1245 CheckMenuItem(menus[MENU_SCIWS], ID_CALC_WS_QWORD, MF_CHECKED);
1246 }
1247
1248 void InitCalc (CALC *calc)
1249 {
1250 int n;
1251 int skipx;
1252 int skipy;
1253 int top_button;
1254
1255 HINSTANCE hInst = calc->hInst;
1256 HFONT hFont = GetStockObject(DEFAULT_GUI_FONT);
1257
1258 calc->trigMode = TRIGMODE_DEGREES;
1259 calc->numBase = NBASE_DECIMAL;
1260 calc->init = 1;
1261
1262 if (calc->new) {
1263 calc->new = 0;
1264 calc->value = 0;
1265 calc->memory = 0;
1266 calc->displayMode = 0;
1267 calc->buffer[0] = '\0';
1268 strcpy(calc->display, "0.");
1269
1270 calc->err = 0;
1271 calc->next = '\0';
1272
1273 calc->wordSize = WORDSIZE_QWORD;
1274 calc->invMode = 0;
1275 calc->hypMode = 0;
1276 }
1277
1278 if (calc->sciMode) {
1279 calc->numButtons = CALC_BUTTONS_STANDARD;
1280
1281 // Row 1 (top)
1282
1283 skipx = MARGIN_LEFT;
1284 skipy = CALC_STANDARD_MARGIN_TOP + CALC_EDIT_HEIGHT;
1285
1286 calc->cb[0].id = 0;
1287 strcpy(calc->cb[0].label,"FILLER");
1288 calc->cb[0].color = CALC_COLOR_BLUE;
1289 calc->cb[0].r.left = skipx + 4;
1290 calc->cb[0].r.top = skipy + 2;
1291 calc->cb[0].r.right = skipx + SZ_FILLER_X - 2;
1292 calc->cb[0].r.bottom = skipy + SZ_FILLER_Y - 2;
1293 calc->cb[0].enable = 1;
1294
1295 skipx = SZ_FILLER_X + MARGIN_STANDARD_BIG_X + 11;
1296
1297 calc->cb[1].id = ID_CALC_BACKSPACE;
1298 LoadString( hInst, IDS_BTN_BACKSPACE, calc->cb[1].label, sizeof(calc->cb[1].label));
1299 calc->cb[1].color = CALC_COLOR_RED;
1300 calc->cb[1].r.left = skipx;
1301 calc->cb[1].r.top = skipy;
1302 calc->cb[1].r.right = SZ_BIGBTN_X;
1303 calc->cb[1].r.bottom = SZ_BIGBTN_Y;
1304 calc->cb[1].enable = 1;
1305
1306 skipx += SZ_BIGBTN_X + MARGIN_SMALL_X;
1307
1308 calc->cb[2].id = ID_CALC_CLEAR_ENTRY;
1309 LoadString( hInst, IDS_BTN_CLEAR_ENTRY, calc->cb[2].label, sizeof(calc->cb[2].label));
1310 calc->cb[2].color = CALC_COLOR_RED;
1311 calc->cb[2].r.left = skipx;
1312 calc->cb[2].r.top = skipy;
1313 calc->cb[2].r.right = SZ_BIGBTN_X;
1314 calc->cb[2].r.bottom = SZ_BIGBTN_Y;
1315 calc->cb[2].enable = 1;
1316
1317 skipx += SZ_BIGBTN_X + MARGIN_SMALL_X;
1318
1319 calc->cb[3].id = ID_CALC_CLEAR_ALL;
1320 LoadString( hInst, IDS_BTN_CLEAR_ALL, calc->cb[3].label, sizeof(calc->cb[3].label));
1321 calc->cb[3].color = CALC_COLOR_RED;
1322 calc->cb[3].r.left = skipx;
1323 calc->cb[3].r.top = skipy;
1324 calc->cb[3].r.right = SZ_BIGBTN_X;
1325 calc->cb[3].r.bottom = SZ_BIGBTN_Y;
1326 calc->cb[3].enable = 1;
1327
1328 // Row 2
1329
1330 skipx = MARGIN_LEFT;
1331 skipy += SZ_BIGBTN_Y + MARGIN_BIG_Y;
1332
1333 calc->cb[4].id = ID_CALC_MEM_CLEAR;
1334 LoadString( hInst, IDS_BTN_MEM_CLEAR, calc->cb[4].label, sizeof(calc->cb[4].label));
1335 calc->cb[4].color = CALC_COLOR_RED;
1336 calc->cb[4].r.left = skipx;
1337 calc->cb[4].r.top = skipy;
1338 calc->cb[4].r.right = SZ_MEDBTN_X;
1339 calc->cb[4].r.bottom = SZ_MEDBTN_Y;
1340 calc->cb[4].enable = 1;
1341
1342 skipx += SZ_MEDBTN_X + MARGIN_STANDARD_BIG_X;
1343
1344 calc->cb[5].id = ID_CALC_SEVEN;
1345 strcpy(calc->cb[5].label,"7");
1346 calc->cb[5].color = CALC_COLOR_BLUE;
1347 calc->cb[5].r.left = skipx;
1348 calc->cb[5].r.top = skipy;
1349 calc->cb[5].r.right = SZ_MEDBTN_X;
1350 calc->cb[5].r.bottom = SZ_MEDBTN_Y;
1351 calc->cb[5].enable = 1;
1352
1353 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
1354
1355 calc->cb[6].id = ID_CALC_EIGHT;
1356 strcpy(calc->cb[6].label,"8");
1357 calc->cb[6].color = CALC_COLOR_BLUE;
1358 calc->cb[6].r.left = skipx;
1359 calc->cb[6].r.top = skipy;
1360 calc->cb[6].r.right = SZ_MEDBTN_X;
1361 calc->cb[6].r.bottom = SZ_MEDBTN_Y;
1362 calc->cb[6].enable = 1;
1363
1364 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
1365
1366 calc->cb[7].id = ID_CALC_NINE;
1367 strcpy(calc->cb[7].label,"9");
1368 calc->cb[7].color = CALC_COLOR_BLUE;
1369 calc->cb[7].r.left = skipx;
1370 calc->cb[7].r.top = skipy;
1371 calc->cb[7].r.right = SZ_MEDBTN_X;
1372 calc->cb[7].r.bottom = SZ_MEDBTN_Y;
1373 calc->cb[7].enable = 1;
1374
1375 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
1376
1377 calc->cb[8].id = ID_CALC_DIVIDE;
1378 strcpy(calc->cb[8].label,"/");
1379 calc->cb[8].color = CALC_COLOR_RED;
1380 calc->cb[8].r.left = skipx;
1381 calc->cb[8].r.top = skipy;
1382 calc->cb[8].r.right = SZ_MEDBTN_X;
1383 calc->cb[8].r.bottom = SZ_MEDBTN_Y;
1384 calc->cb[8].enable = 1;
1385
1386 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
1387
1388 calc->cb[9].id = ID_CALC_SQRT;
1389 LoadString( hInst, IDS_BTN_SQRT, calc->cb[9].label, sizeof(calc->cb[9].label));
1390 calc->cb[9].color = CALC_COLOR_BLUE;
1391 calc->cb[9].r.left = skipx;
1392 calc->cb[9].r.top = skipy;
1393 calc->cb[9].r.right = SZ_MEDBTN_X;
1394 calc->cb[9].r.bottom = SZ_MEDBTN_Y;
1395 calc->cb[9].enable = 1;
1396
1397 // Row 3
1398
1399 skipx = MARGIN_LEFT;
1400 skipy += SZ_MEDBTN_Y + MARGIN_SMALL_Y;
1401
1402 calc->cb[10].id = ID_CALC_MEM_RECALL;
1403 LoadString( hInst, IDS_BTN_MEM_RECALL, calc->cb[10].label, sizeof(calc->cb[10].label));
1404 calc->cb[10].color = CALC_COLOR_RED;
1405 calc->cb[10].r.left = skipx;
1406 calc->cb[10].r.top = skipy;
1407 calc->cb[10].r.right = SZ_MEDBTN_X;
1408 calc->cb[10].r.bottom = SZ_MEDBTN_Y;
1409 calc->cb[10].enable = 1;
1410
1411 skipx += SZ_MEDBTN_X + MARGIN_STANDARD_BIG_X;
1412
1413 calc->cb[11].id = ID_CALC_FOUR;
1414 strcpy(calc->cb[11].label,"4");
1415 calc->cb[11].color = CALC_COLOR_BLUE;
1416 calc->cb[11].r.left = skipx;
1417 calc->cb[11].r.top = skipy;
1418 calc->cb[11].r.right = SZ_MEDBTN_X;
1419 calc->cb[11].r.bottom = SZ_MEDBTN_Y;
1420 calc->cb[11].enable = 1;
1421
1422 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
1423
1424 calc->cb[12].id = ID_CALC_FIVE;
1425 strcpy(calc->cb[12].label,"5");
1426 calc->cb[12].color = CALC_COLOR_BLUE;
1427 calc->cb[12].r.left = skipx;
1428 calc->cb[12].r.top = skipy;
1429 calc->cb[12].r.right = SZ_MEDBTN_X;
1430 calc->cb[12].r.bottom = SZ_MEDBTN_Y;
1431 calc->cb[12].enable = 1;
1432
1433 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
1434
1435 calc->cb[13].id = ID_CALC_SIX;
1436 strcpy(calc->cb[13].label,"6");
1437 calc->cb[13].color = CALC_COLOR_BLUE;
1438 calc->cb[13].r.left = skipx;
1439 calc->cb[13].r.top = skipy;
1440 calc->cb[13].r.right = SZ_MEDBTN_X;
1441 calc->cb[13].r.bottom = SZ_MEDBTN_Y;
1442 calc->cb[13].enable = 1;
1443
1444 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
1445
1446 calc->cb[14].id = ID_CALC_MULTIPLY;
1447 strcpy(calc->cb[14].label,"*");
1448 calc->cb[14].color = CALC_COLOR_RED;
1449 calc->cb[14].r.left = skipx;
1450 calc->cb[14].r.top = skipy;
1451 calc->cb[14].r.right = SZ_MEDBTN_X;
1452 calc->cb[14].r.bottom = SZ_MEDBTN_Y;
1453 calc->cb[14].enable = 1;
1454
1455 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
1456
1457 calc->cb[15].id = ID_CALC_PERCENT;
1458 strcpy(calc->cb[15].label,"%");
1459 calc->cb[15].color = CALC_COLOR_BLUE;
1460 calc->cb[15].r.left = skipx;
1461 calc->cb[15].r.top = skipy;
1462 calc->cb[15].r.right = SZ_MEDBTN_X;
1463 calc->cb[15].r.bottom = SZ_MEDBTN_Y;
1464 calc->cb[15].enable = 1;
1465
1466 // Row 4
1467
1468 skipx = MARGIN_LEFT;
1469 skipy += SZ_MEDBTN_Y + MARGIN_SMALL_Y;
1470
1471 calc->cb[16].id = ID_CALC_MEM_STORE;
1472 LoadString( hInst, IDS_BTN_MEM_STORE, calc->cb[16].label, sizeof(calc->cb[16].label));
1473 calc->cb[16].color = CALC_COLOR_RED;
1474 calc->cb[16].r.left = skipx;
1475 calc->cb[16].r.top = skipy;
1476 calc->cb[16].r.right = SZ_MEDBTN_X;
1477 calc->cb[16].r.bottom = SZ_MEDBTN_Y;
1478 calc->cb[16].enable = 1;
1479
1480 skipx += SZ_MEDBTN_X + MARGIN_STANDARD_BIG_X;
1481
1482 calc->cb[17].id = ID_CALC_ONE;
1483 strcpy(calc->cb[17].label,"1");
1484 calc->cb[17].color = CALC_COLOR_BLUE;
1485 calc->cb[17].r.left = skipx;
1486 calc->cb[17].r.top = skipy;
1487 calc->cb[17].r.right = SZ_MEDBTN_X;
1488 calc->cb[17].r.bottom = SZ_MEDBTN_Y;
1489 calc->cb[17].enable = 1;
1490
1491 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
1492
1493 calc->cb[18].id = ID_CALC_TWO;
1494 strcpy(calc->cb[18].label,"2");
1495 calc->cb[18].color = CALC_COLOR_BLUE;
1496 calc->cb[18].r.left = skipx;
1497 calc->cb[18].r.top = skipy;
1498 calc->cb[18].r.right = SZ_MEDBTN_X;
1499 calc->cb[18].r.bottom = SZ_MEDBTN_Y;
1500 calc->cb[18].enable = 1;
1501
1502 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
1503
1504 calc->cb[19].id = ID_CALC_THREE;
1505 strcpy(calc->cb[19].label,"3");
1506 calc->cb[19].color = CALC_COLOR_BLUE;
1507 calc->cb[19].r.left = skipx;
1508 calc->cb[19].r.top = skipy;
1509 calc->cb[19].r.right = SZ_MEDBTN_X;
1510 calc->cb[19].r.bottom = SZ_MEDBTN_Y;
1511 calc->cb[19].enable = 1;
1512
1513 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
1514
1515 calc->cb[20].id = ID_CALC_MINUS;
1516 strcpy(calc->cb[20].label,"-");
1517 calc->cb[20].color = CALC_COLOR_RED;
1518 calc->cb[20].r.left = skipx;
1519 calc->cb[20].r.top = skipy;
1520 calc->cb[20].r.right = SZ_MEDBTN_X;
1521 calc->cb[20].r.bottom = SZ_MEDBTN_Y;
1522 calc->cb[20].enable = 1;
1523
1524 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
1525
1526 calc->cb[21].id = ID_CALC_RECIPROCAL;
1527 strcpy(calc->cb[21].label,"1/x");
1528 calc->cb[21].color = CALC_COLOR_RED;
1529 calc->cb[21].r.left = skipx;
1530 calc->cb[21].r.top = skipy;
1531 calc->cb[21].r.right = SZ_MEDBTN_X;
1532 calc->cb[21].r.bottom = SZ_MEDBTN_Y;
1533 calc->cb[21].enable = 1;
1534
1535 // Row 5 (bottom)
1536
1537 skipx = MARGIN_LEFT;
1538 skipy += SZ_MEDBTN_Y + MARGIN_SMALL_Y;
1539
1540 calc->cb[22].id = ID_CALC_MEM_PLUS;
1541 LoadString( hInst, IDS_BTN_MEM_PLUS, calc->cb[22].label, sizeof(calc->cb[22].label));
1542 calc->cb[22].color = CALC_COLOR_RED;
1543 calc->cb[22].r.left = skipx;
1544 calc->cb[22].r.top = skipy;
1545 calc->cb[22].r.right = SZ_MEDBTN_X;
1546 calc->cb[22].r.bottom = SZ_MEDBTN_Y;
1547 calc->cb[22].enable = 1;
1548
1549 skipx += SZ_MEDBTN_X + MARGIN_STANDARD_BIG_X;
1550
1551 calc->cb[23].id = ID_CALC_ZERO;
1552 strcpy(calc->cb[23].label,"0");
1553 calc->cb[23].color = CALC_COLOR_BLUE;
1554 calc->cb[23].r.left = skipx;
1555 calc->cb[23].r.top = skipy;
1556 calc->cb[23].r.right = SZ_MEDBTN_X;
1557 calc->cb[23].r.bottom = SZ_MEDBTN_Y;
1558 calc->cb[23].enable = 1;
1559
1560 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
1561
1562 calc->cb[24].id = ID_CALC_SIGN;
1563 strcpy(calc->cb[24].label,"+/-");
1564 calc->cb[24].color = CALC_COLOR_RED;
1565 calc->cb[24].r.left = skipx;
1566 calc->cb[24].r.top = skipy;
1567 calc->cb[24].r.right = SZ_MEDBTN_X;
1568 calc->cb[24].r.bottom = SZ_MEDBTN_Y;
1569 calc->cb[24].enable = 1;
1570
1571 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
1572
1573 calc->cb[25].id = ID_CALC_DECIMAL;
1574 strcpy(calc->cb[25].label,".");
1575 calc->cb[25].color = CALC_COLOR_BLUE;
1576 calc->cb[25].r.left = skipx;
1577 calc->cb[25].r.top = skipy;
1578 calc->cb[25].r.right = SZ_MEDBTN_X;
1579 calc->cb[25].r.bottom = SZ_MEDBTN_Y;
1580 calc->cb[25].enable = 1;
1581
1582 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
1583
1584 calc->cb[26].id = ID_CALC_PLUS;
1585 strcpy(calc->cb[26].label,"+");
1586 calc->cb[26].color = CALC_COLOR_RED;
1587 calc->cb[26].r.left = skipx;
1588 calc->cb[26].r.top = skipy;
1589 calc->cb[26].r.right = SZ_MEDBTN_X;
1590 calc->cb[26].r.bottom = SZ_MEDBTN_Y;
1591 calc->cb[26].enable = 1;
1592
1593 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
1594
1595 calc->cb[27].id = ID_CALC_EQUALS;
1596 strcpy(calc->cb[27].label,"=");
1597 calc->cb[27].color = CALC_COLOR_RED;
1598 calc->cb[27].r.left = skipx;
1599 calc->cb[27].r.top = skipy;
1600 calc->cb[27].r.right = SZ_MEDBTN_X;
1601 calc->cb[27].r.bottom = SZ_MEDBTN_Y;
1602 calc->cb[27].enable = 1;
1603 }
1604 else {
1605 calc->numButtons = CALC_BUTTONS_SCIENTIFIC;
1606
1607 // Row 1 (top)
1608
1609 skipx = MARGIN_LEFT;
1610 skipy = CALC_SCIENTIFIC_MARGIN_TOP + CALC_EDIT_HEIGHT - 1;
1611
1612 calc->cb[0].id = 0;
1613 strcpy(calc->cb[0].label,"FILLER");
1614 calc->cb[0].color = CALC_COLOR_BLUE;
1615 calc->cb[0].r.left = skipx + 4 * SZ_MEDBTN_X + 2 * SZ_SPACER_X + 2 * MARGIN_SMALL_X + 12;
1616 calc->cb[0].r.top = skipy;
1617 calc->cb[0].r.right = skipx + 4 * SZ_MEDBTN_X + 2 * SZ_SPACER_X + 2 * MARGIN_SMALL_X + SZ_FILLER_X + 4;
1618 calc->cb[0].r.bottom = skipy + SZ_FILLER_Y - 6;
1619 calc->cb[0].enable = 1;
1620
1621 calc->cb[1].id = 0;
1622 strcpy(calc->cb[1].label,"FILLER");
1623 calc->cb[1].color = CALC_COLOR_BLUE;
1624 calc->cb[1].r.left = skipx + 3 * SZ_MEDBTN_X + SZ_SPACER_X + 2 * MARGIN_SMALL_X + 8;
1625 calc->cb[1].r.top = skipy;
1626 calc->cb[1].r.right = skipx + 3 * SZ_MEDBTN_X + SZ_SPACER_X + 2 * MARGIN_SMALL_X + SZ_FILLER_X + 0;
1627 calc->cb[1].r.bottom = skipy + SZ_FILLER_Y - 6;
1628 calc->cb[1].enable = 1;
1629
1630 skipx += SZ_FILLER_X + MARGIN_SMALL_X;
1631
1632 skipx = MARGIN_BIG_X;
1633
1634 calc->cb[2].id = ID_CALC_BACKSPACE;
1635 LoadString( hInst, IDS_BTN_BACKSPACE, calc->cb[2].label, sizeof(calc->cb[2].label));
1636 calc->cb[2].color = CALC_COLOR_RED;
1637 calc->cb[2].r.left = skipx;
1638 calc->cb[2].r.top = skipy;
1639 calc->cb[2].r.right = SZ_BIGBTN_X;
1640 calc->cb[2].r.bottom = SZ_BIGBTN_Y;
1641 calc->cb[2].enable = 1;
1642
1643 skipx += SZ_BIGBTN_X + MARGIN_SMALL_X;
1644
1645 calc->cb[3].id = ID_CALC_CLEAR_ENTRY;
1646 LoadString( hInst, IDS_BTN_CLEAR_ENTRY, calc->cb[3].label, sizeof(calc->cb[3].label));
1647 calc->cb[3].color = CALC_COLOR_RED;
1648 calc->cb[3].r.left = skipx;
1649 calc->cb[3].r.top = skipy;
1650 calc->cb[3].r.right = SZ_BIGBTN_X;
1651 calc->cb[3].r.bottom = SZ_BIGBTN_Y;
1652 calc->cb[3].enable = 1;
1653
1654 skipx += SZ_BIGBTN_X + MARGIN_SMALL_X;
1655
1656 calc->cb[4].id = ID_CALC_CLEAR_ALL;
1657 LoadString( hInst, IDS_BTN_CLEAR_ALL, calc->cb[4].label, sizeof(calc->cb[4].label));
1658 calc->cb[4].color = CALC_COLOR_RED;
1659 calc->cb[4].r.left = skipx;
1660 calc->cb[4].r.top = skipy;
1661 calc->cb[4].r.right = SZ_BIGBTN_X;
1662 calc->cb[4].r.bottom = SZ_BIGBTN_Y;
1663 calc->cb[4].enable = 1;
1664
1665 // Row 2
1666
1667 skipx = MARGIN_LEFT;
1668 skipy += SZ_MEDBTN_Y + MARGIN_SMALL_Y;
1669
1670 calc->cb[5].id = ID_CALC_STA;
1671 strcpy(calc->cb[5].label,"Sta");
1672 calc->cb[5].color = CALC_COLOR_GRAY;
1673 calc->cb[5].r.left = skipx;
1674 calc->cb[5].r.top = skipy;
1675 calc->cb[5].r.right = SZ_MEDBTN_X;
1676 calc->cb[5].r.bottom = SZ_MEDBTN_Y;
1677 calc->cb[5].enable = 1;
1678
1679 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X + SZ_SPACER_X;
1680
1681 calc->cb[6].id = ID_CALC_FE;
1682 strcpy(calc->cb[6].label,"F-E");
1683 calc->cb[6].color = CALC_COLOR_MAGENTA;
1684 calc->cb[6].r.left = skipx;
1685 calc->cb[6].r.top = skipy;
1686 calc->cb[6].r.right = SZ_MEDBTN_X;
1687 calc->cb[6].r.bottom = SZ_MEDBTN_Y;
1688 calc->cb[6].enable = 1;
1689
1690 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
1691
1692 calc->cb[7].id = ID_CALC_LEFTPAREN;
1693 strcpy(calc->cb[7].label,"(");
1694 calc->cb[7].color = CALC_COLOR_MAGENTA;
1695 calc->cb[7].r.left = skipx;
1696 calc->cb[7].r.top = skipy;
1697 calc->cb[7].r.right = SZ_MEDBTN_X;
1698 calc->cb[7].r.bottom = SZ_MEDBTN_Y;
1699 calc->cb[7].enable = 0;
1700
1701 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
1702
1703 calc->cb[8].id = ID_CALC_RIGHTPAREN;
1704 strcpy(calc->cb[8].label,")");
1705 calc->cb[8].color = CALC_COLOR_MAGENTA;
1706 calc->cb[8].r.left = skipx;
1707 calc->cb[8].r.top = skipy;
1708 calc->cb[8].r.right = SZ_MEDBTN_X;
1709 calc->cb[8].r.bottom = SZ_MEDBTN_Y;
1710 calc->cb[8].enable = 0;
1711
1712 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X + SZ_SPACER_X;
1713
1714 calc->cb[9].id = ID_CALC_MEM_CLEAR;
1715 LoadString( hInst, IDS_BTN_MEM_CLEAR, calc->cb[9].label, sizeof(calc->cb[9].label));
1716 calc->cb[9].color = CALC_COLOR_RED;
1717 calc->cb[9].r.left = skipx;
1718 calc->cb[9].r.top = skipy;
1719 calc->cb[9].r.right = SZ_MEDBTN_X;
1720 calc->cb[9].r.bottom = SZ_MEDBTN_Y;
1721 calc->cb[9].enable = 1;
1722
1723 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X + SZ_SPACER_X;
1724
1725 calc->cb[10].id = ID_CALC_SEVEN;
1726 strcpy(calc->cb[10].label,"7");
1727 calc->cb[10].color = CALC_COLOR_BLUE;
1728 calc->cb[10].r.left = skipx;
1729 calc->cb[10].r.top = skipy;
1730 calc->cb[10].r.right = SZ_MEDBTN_X;
1731 calc->cb[10].r.bottom = SZ_MEDBTN_Y;
1732 calc->cb[10].enable = 1;
1733
1734 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
1735
1736 calc->cb[11].id = ID_CALC_EIGHT;
1737 strcpy(calc->cb[11].label,"8");
1738 calc->cb[11].color = CALC_COLOR_BLUE;
1739 calc->cb[11].r.left = skipx;
1740 calc->cb[11].r.top = skipy;
1741 calc->cb[11].r.right = SZ_MEDBTN_X;
1742 calc->cb[11].r.bottom = SZ_MEDBTN_Y;
1743 calc->cb[11].enable = 1;
1744
1745 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
1746
1747 calc->cb[12].id = ID_CALC_NINE;
1748 strcpy(calc->cb[12].label,"9");
1749 calc->cb[12].color = CALC_COLOR_BLUE;
1750 calc->cb[12].r.left = skipx;
1751 calc->cb[12].r.top = skipy;
1752 calc->cb[12].r.right = SZ_MEDBTN_X;
1753 calc->cb[12].r.bottom = SZ_MEDBTN_Y;
1754 calc->cb[12].enable = 1;
1755
1756 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
1757
1758 calc->cb[13].id = ID_CALC_DIVIDE;
1759 strcpy(calc->cb[13].label,"/");
1760 calc->cb[13].color = CALC_COLOR_RED;
1761 calc->cb[13].r.left = skipx;
1762 calc->cb[13].r.top = skipy;
1763 calc->cb[13].r.right = SZ_MEDBTN_X;
1764 calc->cb[13].r.bottom = SZ_MEDBTN_Y;
1765 calc->cb[13].enable = 1;
1766
1767 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
1768
1769 calc->cb[14].id = ID_CALC_MOD;
1770 strcpy(calc->cb[14].label,"Mod");
1771 calc->cb[14].color = CALC_COLOR_RED;
1772 calc->cb[14].r.left = skipx;
1773 calc->cb[14].r.top = skipy;
1774 calc->cb[14].r.right = SZ_MEDBTN_X;
1775 calc->cb[14].r.bottom = SZ_MEDBTN_Y;
1776 calc->cb[14].enable = 1;
1777
1778 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
1779
1780 calc->cb[15].id = ID_CALC_AND;
1781 strcpy(calc->cb[15].label,"And");
1782 calc->cb[15].color = CALC_COLOR_RED;
1783 calc->cb[15].r.left = skipx;
1784 calc->cb[15].r.top = skipy;
1785 calc->cb[15].r.right = SZ_MEDBTN_X;
1786 calc->cb[15].r.bottom = SZ_MEDBTN_Y;
1787 calc->cb[15].enable = 1;
1788
1789 // Row 3
1790
1791 skipx = MARGIN_LEFT;
1792 skipy += SZ_MEDBTN_Y + MARGIN_SMALL_Y;
1793
1794 calc->cb[16].id = ID_CALC_AVE;
1795 strcpy(calc->cb[16].label,"Ave");
1796 calc->cb[16].color = CALC_COLOR_GRAY;
1797 calc->cb[16].r.left = skipx;
1798 calc->cb[16].r.top = skipy;
1799 calc->cb[16].r.right = SZ_MEDBTN_X;
1800 calc->cb[16].r.bottom = SZ_MEDBTN_Y;
1801 calc->cb[16].enable = 0;
1802
1803 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X + SZ_SPACER_X;
1804
1805 calc->cb[17].id = ID_CALC_DMS;
1806 strcpy(calc->cb[17].label,"dms");
1807 calc->cb[17].color = CALC_COLOR_MAGENTA;
1808 calc->cb[17].r.left = skipx;
1809 calc->cb[17].r.top = skipy;
1810 calc->cb[17].r.right = SZ_MEDBTN_X;
1811 calc->cb[17].r.bottom = SZ_MEDBTN_Y;
1812 calc->cb[17].enable = 1;
1813
1814 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
1815
1816 calc->cb[18].id = ID_CALC_EXP;
1817 strcpy(calc->cb[18].label,"Exp");
1818 calc->cb[18].color = CALC_COLOR_MAGENTA;
1819 calc->cb[18].r.left = skipx;
1820 calc->cb[18].r.top = skipy;
1821 calc->cb[18].r.right = SZ_MEDBTN_X;
1822 calc->cb[18].r.bottom = SZ_MEDBTN_Y;
1823 calc->cb[18].enable = 1;
1824
1825 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
1826
1827 calc->cb[19].id = ID_CALC_LN;
1828 strcpy(calc->cb[19].label,"ln");
1829 calc->cb[19].color = CALC_COLOR_MAGENTA;
1830 calc->cb[19].r.left = skipx;
1831 calc->cb[19].r.top = skipy;
1832 calc->cb[19].r.right = SZ_MEDBTN_X;
1833 calc->cb[19].r.bottom = SZ_MEDBTN_Y;
1834 calc->cb[19].enable = 1;
1835
1836 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X + SZ_SPACER_X;
1837
1838 calc->cb[20].id = ID_CALC_MEM_RECALL;
1839 strcpy(calc->cb[20].label,"MR");
1840 calc->cb[20].color = CALC_COLOR_RED;
1841 calc->cb[20].r.left = skipx;
1842 calc->cb[20].r.top = skipy;
1843 calc->cb[20].r.right = SZ_MEDBTN_X;
1844 calc->cb[20].r.bottom = SZ_MEDBTN_Y;
1845 calc->cb[20].enable = 1;
1846
1847 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X + SZ_SPACER_X;
1848
1849 calc->cb[21].id = ID_CALC_FOUR;
1850 strcpy(calc->cb[21].label,"4");
1851 calc->cb[21].color = CALC_COLOR_BLUE;
1852 calc->cb[21].r.left = skipx;
1853 calc->cb[21].r.top = skipy;
1854 calc->cb[21].r.right = SZ_MEDBTN_X;
1855 calc->cb[21].r.bottom = SZ_MEDBTN_Y;
1856 calc->cb[21].enable = 1;
1857
1858 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
1859
1860 calc->cb[22].id = ID_CALC_FIVE;
1861 strcpy(calc->cb[22].label,"5");
1862 calc->cb[22].color = CALC_COLOR_BLUE;
1863 calc->cb[22].r.left = skipx;
1864 calc->cb[22].r.top = skipy;
1865 calc->cb[22].r.right = SZ_MEDBTN_X;
1866 calc->cb[22].r.bottom = SZ_MEDBTN_Y;
1867 calc->cb[22].enable = 1;
1868
1869 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
1870
1871 calc->cb[23].id = ID_CALC_SIX;
1872 strcpy(calc->cb[23].label,"6");
1873 calc->cb[23].color = CALC_COLOR_BLUE;
1874 calc->cb[23].r.left = skipx;
1875 calc->cb[23].r.top = skipy;
1876 calc->cb[23].r.right = SZ_MEDBTN_X;
1877 calc->cb[23].r.bottom = SZ_MEDBTN_Y;
1878 calc->cb[23].enable = 1;
1879
1880 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
1881
1882 calc->cb[24].id = ID_CALC_MULTIPLY;
1883 strcpy(calc->cb[24].label,"*");
1884 calc->cb[24].color = CALC_COLOR_RED;
1885 calc->cb[24].r.left = skipx;
1886 calc->cb[24].r.top = skipy;
1887 calc->cb[24].r.right = SZ_MEDBTN_X;
1888 calc->cb[24].r.bottom = SZ_MEDBTN_Y;
1889 calc->cb[24].enable = 1;
1890
1891 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
1892
1893 calc->cb[25].id = ID_CALC_OR;
1894 strcpy(calc->cb[25].label,"Or");
1895 calc->cb[25].color = CALC_COLOR_RED;
1896 calc->cb[25].r.left = skipx;
1897 calc->cb[25].r.top = skipy;
1898 calc->cb[25].r.right = SZ_MEDBTN_X;
1899 calc->cb[25].r.bottom = SZ_MEDBTN_Y;
1900 calc->cb[25].enable = 1;
1901
1902 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
1903
1904 calc->cb[26].id = ID_CALC_XOR;
1905 strcpy(calc->cb[26].label,"Xor");
1906 calc->cb[26].color = CALC_COLOR_RED;
1907 calc->cb[26].r.left = skipx;
1908 calc->cb[26].r.top = skipy;
1909 calc->cb[26].r.right = SZ_MEDBTN_X;
1910 calc->cb[26].r.bottom = SZ_MEDBTN_Y;
1911 calc->cb[26].enable = 1;
1912
1913 // Row 4
1914
1915 skipx = MARGIN_LEFT;
1916 skipy += SZ_MEDBTN_Y + MARGIN_SMALL_Y;
1917
1918 calc->cb[27].id = ID_CALC_SUM;
1919 strcpy(calc->cb[27].label,"Sum");
1920 calc->cb[27].color = CALC_COLOR_GRAY;
1921 calc->cb[27].r.left = skipx ;
1922 calc->cb[27].r.top = skipy;
1923 calc->cb[27].r.right = SZ_MEDBTN_X;
1924 calc->cb[27].r.bottom = SZ_MEDBTN_Y;
1925 calc->cb[27].enable = 0;
1926
1927 skipx += MARGIN_SMALL_X + SZ_MEDBTN_X + SZ_SPACER_X;
1928
1929 calc->cb[28].id = ID_CALC_SIN;
1930 strcpy(calc->cb[28].label,"sin");
1931 calc->cb[28].color = CALC_COLOR_MAGENTA;
1932 calc->cb[28].r.left = skipx;
1933 calc->cb[28].r.top = skipy;
1934 calc->cb[28].r.right = SZ_MEDBTN_X;
1935 calc->cb[28].r.bottom = SZ_MEDBTN_Y;
1936 calc->cb[28].enable = 1;
1937
1938 skipx += MARGIN_SMALL_X + SZ_MEDBTN_X;
1939
1940 calc->cb[29].id = ID_CALC_POWER ;
1941 strcpy(calc->cb[29].label,"x^y");
1942 calc->cb[29].color = CALC_COLOR_MAGENTA;
1943 calc->cb[29].r.left = skipx;
1944 calc->cb[29].r.top = skipy;
1945 calc->cb[29].r.right = SZ_MEDBTN_X;
1946 calc->cb[29].r.bottom = SZ_MEDBTN_Y;
1947 calc->cb[29].enable = 1;
1948
1949 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
1950
1951 calc->cb[30].id = ID_CALC_LOG10;
1952 strcpy(calc->cb[30].label,"log");
1953 calc->cb[30].color = CALC_COLOR_MAGENTA;
1954 calc->cb[30].r.left = skipx;
1955 calc->cb[30].r.top = skipy;
1956 calc->cb[30].r.right = SZ_MEDBTN_X;
1957 calc->cb[30].r.bottom = SZ_MEDBTN_Y;
1958 calc->cb[30].enable = 1;
1959
1960 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X + SZ_SPACER_X;
1961
1962 calc->cb[31].id = ID_CALC_MEM_STORE;
1963 LoadString( hInst, IDS_BTN_MEM_STORE, calc->cb[31].label, sizeof(calc->cb[31].label));
1964 calc->cb[31].color = CALC_COLOR_RED;
1965 calc->cb[31].r.left = skipx;
1966 calc->cb[31].r.top = skipy;
1967 calc->cb[31].r.right = SZ_MEDBTN_X;
1968 calc->cb[31].r.bottom = SZ_MEDBTN_Y;
1969 calc->cb[31].enable = 1;
1970
1971 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X + SZ_SPACER_X;
1972
1973 calc->cb[32].id = ID_CALC_ONE;
1974 strcpy(calc->cb[32].label,"1");
1975 calc->cb[32].color = CALC_COLOR_BLUE;
1976 calc->cb[32].r.left = skipx;
1977 calc->cb[32].r.top = skipy;
1978 calc->cb[32].r.right = SZ_MEDBTN_X;
1979 calc->cb[32].r.bottom = SZ_MEDBTN_Y;
1980 calc->cb[32].enable = 1;
1981
1982 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
1983
1984 calc->cb[33].id = ID_CALC_TWO;
1985 strcpy(calc->cb[33].label,"2");
1986 calc->cb[33].color = CALC_COLOR_BLUE;
1987 calc->cb[33].r.left = skipx;
1988 calc->cb[33].r.top = skipy;
1989 calc->cb[33].r.right = SZ_MEDBTN_X;
1990 calc->cb[33].r.bottom = SZ_MEDBTN_Y;
1991 calc->cb[33].enable = 1;
1992
1993 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
1994
1995 calc->cb[34].id = ID_CALC_THREE;
1996 strcpy(calc->cb[34].label,"3");
1997 calc->cb[34].color = CALC_COLOR_BLUE;
1998 calc->cb[34].r.left = skipx;
1999 calc->cb[34].r.top = skipy;
2000 calc->cb[34].r.right = SZ_MEDBTN_X;
2001 calc->cb[34].r.bottom = SZ_MEDBTN_Y;
2002 calc->cb[34].enable = 1;
2003
2004 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
2005
2006 calc->cb[35].id = ID_CALC_MINUS;
2007 strcpy(calc->cb[35].label,"-");
2008 calc->cb[35].color = CALC_COLOR_RED;
2009 calc->cb[35].r.left = skipx;
2010 calc->cb[35].r.top = skipy;
2011 calc->cb[35].r.right = SZ_MEDBTN_X;
2012 calc->cb[35].r.bottom = SZ_MEDBTN_Y;
2013 calc->cb[35].enable = 1;
2014
2015 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
2016
2017 calc->cb[36].id = ID_CALC_LSH;
2018 strcpy(calc->cb[36].label,"Lsh");
2019 calc->cb[36].color = CALC_COLOR_RED;
2020 calc->cb[36].r.left = skipx;
2021 calc->cb[36].r.top = skipy;
2022 calc->cb[36].r.right = SZ_MEDBTN_X;
2023 calc->cb[36].r.bottom = SZ_MEDBTN_Y;
2024 calc->cb[36].enable = 1;
2025
2026 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
2027
2028 calc->cb[37].id = ID_CALC_NOT;
2029 strcpy(calc->cb[37].label,"Not");
2030 calc->cb[37].color = CALC_COLOR_RED;
2031 calc->cb[37].r.left = skipx;
2032 calc->cb[37].r.top = skipy;
2033 calc->cb[37].r.right = SZ_MEDBTN_X;
2034 calc->cb[37].r.bottom = SZ_MEDBTN_Y;
2035 calc->cb[37].enable = 1;
2036
2037 // Row 5 (bottom)
2038
2039 skipx = MARGIN_LEFT;
2040 skipy += SZ_MEDBTN_Y + MARGIN_SMALL_Y;
2041
2042 calc->cb[38].id = ID_CALC_S;
2043 strcpy(calc->cb[38].label,"s");
2044 calc->cb[38].color = CALC_COLOR_GRAY;
2045 calc->cb[38].r.left = skipx;
2046 calc->cb[38].r.top = skipy;
2047 calc->cb[38].r.right = SZ_MEDBTN_X;
2048 calc->cb[38].r.bottom = SZ_MEDBTN_Y;
2049 calc->cb[38].enable = 0;
2050
2051 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X + SZ_SPACER_X;
2052
2053 calc->cb[39].id = ID_CALC_COS;
2054 strcpy(calc->cb[39].label,"cos");
2055 calc->cb[39].color = CALC_COLOR_MAGENTA;
2056 calc->cb[39].r.left = skipx;
2057 calc->cb[39].r.top = skipy;
2058 calc->cb[39].r.right = SZ_MEDBTN_X;
2059 calc->cb[39].r.bottom = SZ_MEDBTN_Y;
2060 calc->cb[39].enable = 1;
2061
2062 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
2063
2064 calc->cb[40].id = ID_CALC_CUBE;
2065 strcpy(calc->cb[40].label,"x^3");
2066 calc->cb[40].color = CALC_COLOR_MAGENTA;
2067 calc->cb[40].r.left = skipx;
2068 calc->cb[40].r.top = skipy;
2069 calc->cb[40].r.right = SZ_MEDBTN_X;
2070 calc->cb[40].r.bottom = SZ_MEDBTN_Y;
2071 calc->cb[40].enable = 1;
2072
2073 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
2074
2075 calc->cb[41].id = ID_CALC_FACTORIAL;
2076 strcpy(calc->cb[41].label,"n!");
2077 calc->cb[41].color = CALC_COLOR_MAGENTA;
2078 calc->cb[41].r.left = skipx;
2079 calc->cb[41].r.top = skipy;
2080 calc->cb[41].r.right = SZ_MEDBTN_X;
2081 calc->cb[41].r.bottom = SZ_MEDBTN_Y;
2082 calc->cb[41].enable = 1;
2083
2084 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X + SZ_SPACER_X;
2085
2086 calc->cb[42].id = ID_CALC_MEM_PLUS;
2087 LoadString( hInst, IDS_BTN_MEM_PLUS, calc->cb[42].label, sizeof(calc->cb[42].label));
2088 calc->cb[42].color = CALC_COLOR_RED;
2089 calc->cb[42].r.left = skipx;
2090 calc->cb[42].r.top = skipy;
2091 calc->cb[42].r.right = SZ_MEDBTN_X;
2092 calc->cb[42].r.bottom = SZ_MEDBTN_Y;
2093 calc->cb[42].enable = 1;
2094
2095 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X + SZ_SPACER_X;
2096
2097 calc->cb[43].id = ID_CALC_ZERO;
2098 strcpy(calc->cb[43].label,"0");
2099 calc->cb[43].color = CALC_COLOR_BLUE;
2100 calc->cb[43].r.left = skipx;
2101 calc->cb[43].r.top = skipy;
2102 calc->cb[43].r.right = SZ_MEDBTN_X;
2103 calc->cb[43].r.bottom = SZ_MEDBTN_Y;
2104 calc->cb[43].enable = 1;
2105
2106 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
2107
2108 calc->cb[44].id = ID_CALC_SIGN;
2109 strcpy(calc->cb[44].label,"+/-");
2110 calc->cb[44].color = CALC_COLOR_RED;
2111 calc->cb[44].r.left = skipx;
2112 calc->cb[44].r.top = skipy;
2113 calc->cb[44].r.right = SZ_MEDBTN_X;
2114 calc->cb[44].r.bottom = SZ_MEDBTN_Y;
2115 calc->cb[44].enable = 1;
2116
2117 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
2118
2119 calc->cb[45].id = ID_CALC_DECIMAL;
2120 strcpy(calc->cb[45].label,".");
2121 calc->cb[45].color = CALC_COLOR_BLUE;
2122 calc->cb[45].r.left = skipx;
2123 calc->cb[45].r.top = skipy;
2124 calc->cb[45].r.right = SZ_MEDBTN_X;
2125 calc->cb[45].r.bottom = SZ_MEDBTN_Y;
2126 calc->cb[45].enable = 1;
2127
2128 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
2129
2130 calc->cb[46].id = ID_CALC_PLUS;
2131 strcpy(calc->cb[46].label,"+");
2132 calc->cb[46].color = CALC_COLOR_RED;
2133 calc->cb[46].r.left = skipx;
2134 calc->cb[46].r.top = skipy;
2135 calc->cb[46].r.right = SZ_MEDBTN_X;
2136 calc->cb[46].r.bottom = SZ_MEDBTN_Y;
2137 calc->cb[46].enable = 1;
2138
2139 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
2140
2141 calc->cb[47].id = ID_CALC_EQUALS;
2142 strcpy(calc->cb[47].label,"=");
2143 calc->cb[47].color = CALC_COLOR_RED;
2144 calc->cb[47].r.left = skipx;
2145 calc->cb[47].r.top = skipy;
2146 calc->cb[47].r.right = SZ_MEDBTN_X;
2147 calc->cb[47].r.bottom = SZ_MEDBTN_Y;
2148 calc->cb[47].enable = 1;
2149
2150 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
2151
2152 calc->cb[48].id = ID_CALC_INT;
2153 strcpy(calc->cb[48].label,"Int");
2154 calc->cb[48].color = CALC_COLOR_RED;
2155 calc->cb[48].r.left = skipx;
2156 calc->cb[48].r.top = skipy;
2157 calc->cb[48].r.right = SZ_MEDBTN_X;
2158 calc->cb[48].r.bottom = SZ_MEDBTN_Y;
2159 calc->cb[48].enable = 1;
2160
2161
2162 // Row 6
2163
2164 skipx = MARGIN_LEFT;
2165 skipy += SZ_MEDBTN_Y + MARGIN_SMALL_Y;
2166
2167 calc->cb[49].id = ID_CALC_DAT;
2168 strcpy(calc->cb[49].label,"Dat");
2169 calc->cb[49].color = CALC_COLOR_GRAY;
2170 calc->cb[49].r.left = skipx;
2171 calc->cb[49].r.top = skipy;
2172 calc->cb[49].r.right = SZ_MEDBTN_X;
2173 calc->cb[49].r.bottom = SZ_MEDBTN_Y;
2174 calc->cb[49].enable = 0;
2175
2176 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X + SZ_SPACER_X;
2177
2178 calc->cb[50].id = ID_CALC_TAN;
2179 strcpy(calc->cb[50].label,"tan");
2180 calc->cb[50].color = CALC_COLOR_MAGENTA;
2181 calc->cb[50].r.left = skipx;
2182 calc->cb[50].r.top = skipy;
2183 calc->cb[50].r.right = SZ_MEDBTN_X;
2184 calc->cb[50].r.bottom = SZ_MEDBTN_Y;
2185 calc->cb[50].enable = 1;
2186
2187 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
2188
2189 calc->cb[51].id = ID_CALC_SQUARE;
2190 strcpy(calc->cb[51].label,"x^2");
2191 calc->cb[51].color = CALC_COLOR_MAGENTA;
2192 calc->cb[51].r.left = skipx;
2193 calc->cb[51].r.top = skipy;
2194 calc->cb[51].r.right = SZ_MEDBTN_X;
2195 calc->cb[51].r.bottom = SZ_MEDBTN_Y;
2196 calc->cb[51].enable = 1;
2197
2198 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
2199
2200 calc->cb[52].id = ID_CALC_RECIPROCAL;
2201 strcpy(calc->cb[52].label,"1/x");
2202 calc->cb[52].color = CALC_COLOR_MAGENTA;
2203 calc->cb[52].r.left = skipx;
2204 calc->cb[52].r.top = skipy;
2205 calc->cb[52].r.right = SZ_MEDBTN_X;
2206 calc->cb[52].r.bottom = SZ_MEDBTN_Y;
2207 calc->cb[52].enable = 1;
2208
2209 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X + SZ_SPACER_X;
2210
2211 calc->cb[53].id = ID_CALC_PI;
2212 strcpy(calc->cb[53].label,"pi");
2213 calc->cb[53].color = CALC_COLOR_BLUE;
2214 calc->cb[53].r.left = skipx;
2215 calc->cb[53].r.top = skipy;
2216 calc->cb[53].r.right = SZ_MEDBTN_X;
2217 calc->cb[53].r.bottom = SZ_MEDBTN_Y;
2218 calc->cb[53].enable = 1;
2219
2220 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X + SZ_SPACER_X;
2221
2222 calc->cb[54].id = ID_CALC_A;
2223 strcpy(calc->cb[54].label,"A");
2224 calc->cb[54].color = CALC_COLOR_GRAY;
2225 calc->cb[54].r.left = skipx;
2226 calc->cb[54].r.top = skipy;
2227 calc->cb[54].r.right = SZ_MEDBTN_X;
2228 calc->cb[54].r.bottom = SZ_MEDBTN_Y;
2229 calc->cb[54].enable = 0;
2230
2231 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
2232
2233 calc->cb[55].id = ID_CALC_B;
2234 strcpy(calc->cb[55].label,"B");
2235 calc->cb[55].color = CALC_COLOR_GRAY;
2236 calc->cb[55].r.left = skipx;
2237 calc->cb[55].r.top = skipy;
2238 calc->cb[55].r.right = SZ_MEDBTN_X;
2239 calc->cb[55].r.bottom = SZ_MEDBTN_Y;
2240 calc->cb[55].enable = 0;
2241
2242 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
2243
2244 calc->cb[56].id = ID_CALC_C;
2245 strcpy(calc->cb[56].label,"C");
2246 calc->cb[56].color = CALC_COLOR_GRAY;
2247 calc->cb[56].r.left = skipx;
2248 calc->cb[56].r.top = skipy;
2249 calc->cb[56].r.right = SZ_MEDBTN_X;
2250 calc->cb[56].r.bottom = SZ_MEDBTN_Y;
2251 calc->cb[56].enable = 0;
2252
2253 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
2254
2255 calc->cb[57].id = ID_CALC_D;
2256 strcpy(calc->cb[57].label,"D");
2257 calc->cb[57].color = CALC_COLOR_GRAY;
2258 calc->cb[57].r.left = skipx;
2259 calc->cb[57].r.top = skipy;
2260 calc->cb[57].r.right = SZ_MEDBTN_X;
2261 calc->cb[57].r.bottom = SZ_MEDBTN_Y;
2262 calc->cb[57].enable = 0;
2263
2264 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
2265
2266 calc->cb[58].id = ID_CALC_E;
2267 strcpy(calc->cb[58].label,"E");
2268 calc->cb[58].color = CALC_COLOR_GRAY;
2269 calc->cb[58].r.left = skipx;
2270 calc->cb[58].r.top = skipy;
2271 calc->cb[58].r.right = SZ_MEDBTN_X;
2272 calc->cb[58].r.bottom = SZ_MEDBTN_Y;
2273 calc->cb[58].enable = 0;
2274
2275 skipx += SZ_MEDBTN_X + MARGIN_SMALL_X;
2276
2277 calc->cb[59].id = ID_CALC_F;
2278 strcpy(calc->cb[59].label,"F");
2279 calc->cb[59].color = CALC_COLOR_GRAY;
2280 calc->cb[59].r.left = skipx;
2281 calc->cb[59].r.top = skipy;
2282 calc->cb[59].r.right = SZ_MEDBTN_X;
2283 calc->cb[59].r.bottom = SZ_MEDBTN_Y;
2284 calc->cb[59].enable = 0;
2285
2286 // Buttons
2287
2288 calc->cb[60].id = ID_CALC_NS_HEX;
2289 strcpy(calc->cb[60].label,"Hex");
2290 calc->cb[60].color = CALC_COLOR_GRAY;
2291 calc->cb[60].r.left = CALC_NS_HEX_LEFT;
2292 calc->cb[60].r.top = CALC_NS_HEX_TOP;
2293 calc->cb[60].r.right = SZ_RADIO_NS_X;
2294 calc->cb[60].r.bottom = SZ_RADIO_NS_Y;
2295 calc->cb[60].enable = 1;
2296
2297 calc->cb[61].id = ID_CALC_NS_DEC;
2298 strcpy(calc->cb[61].label,"Dec");
2299 calc->cb[61].color = CALC_COLOR_GRAY;
2300 calc->cb[61].r.left = CALC_NS_DEC_LEFT;
2301 calc->cb[61].r.top = CALC_NS_DEC_TOP;
2302 calc->cb[61].r.right = SZ_RADIO_NS_X;
2303 calc->cb[61].r.bottom = SZ_RADIO_NS_Y;
2304 calc->cb[61].enable = 1;
2305
2306 calc->cb[62].id = ID_CALC_NS_OCT;
2307 strcpy(calc->cb[62].label,"Oct");
2308 calc->cb[62].color = CALC_COLOR_GRAY;
2309 calc->cb[62].r.left = CALC_NS_OCT_LEFT;
2310 calc->cb[62].r.top = CALC_NS_OCT_TOP;
2311 calc->cb[62].r.right = SZ_RADIO_NS_X;
2312 calc->cb[62].r.bottom = SZ_RADIO_NS_Y;
2313 calc->cb[62].enable = 1;
2314
2315 calc->cb[63].id = ID_CALC_NS_BIN;
2316 strcpy(calc->cb[63].label,"Bin");
2317 calc->cb[63].color = CALC_COLOR_GRAY;
2318 calc->cb[63].r.left = CALC_NS_BIN_LEFT;
2319 calc->cb[63].r.top = CALC_NS_BIN_TOP;
2320 calc->cb[63].r.right = SZ_RADIO_NS_X;
2321 calc->cb[63].r.bottom = SZ_RADIO_NS_Y;
2322 calc->cb[63].enable = 1;
2323
2324 calc->cb[64].id = ID_CALC_MS_DEGREES;
2325 strcpy(calc->cb[64].label,"Degrees");
2326 calc->cb[64].color = CALC_COLOR_GRAY;
2327 calc->cb[64].r.left = CALC_MS_DEGREES_LEFT;
2328 calc->cb[64].r.top = CALC_MS_DEGREES_TOP;
2329 calc->cb[64].r.right = SZ_RADIO_MS_X;
2330 calc->cb[64].r.bottom = SZ_RADIO_MS_Y;
2331 calc->cb[64].enable = 1;
2332
2333 calc->cb[65].id = ID_CALC_MS_RADIANS;
2334 strcpy(calc->cb[65].label,"Radians");
2335 calc->cb[65].color = CALC_COLOR_GRAY;
2336 calc->cb[65].r.left = CALC_MS_RADIANS_LEFT;
2337 calc->cb[65].r.top = CALC_MS_RADIANS_TOP;
2338 calc->cb[65].r.right = SZ_RADIO_MS_X;
2339 calc->cb[65].r.bottom = SZ_RADIO_MS_Y;
2340 calc->cb[65].enable = 1;
2341
2342 calc->cb[66].id = ID_CALC_MS_GRADS;
2343 strcpy(calc->cb[66].label,"Grads");
2344 calc->cb[66].color = CALC_COLOR_GRAY;
2345 calc->cb[66].r.left = CALC_MS_GRADS_LEFT;
2346 calc->cb[66].r.top = CALC_MS_GRADS_TOP;
2347 calc->cb[66].r.right = SZ_RADIO_MS_X;
2348 calc->cb[66].r.bottom = SZ_RADIO_MS_Y;
2349 calc->cb[66].enable = 1;
2350
2351 calc->cb[67].id = ID_CALC_CB_INV;
2352 strcpy(calc->cb[67].label,"Inv");
2353 calc->cb[67].color = CALC_COLOR_GRAY;
2354 calc->cb[67].r.left = CALC_CB_INV_LEFT;
2355 calc->cb[67].r.top = CALC_CB_INV_TOP;
2356 calc->cb[67].r.right = SZ_RADIO_CB_X;
2357 calc->cb[67].r.bottom = SZ_RADIO_CB_Y;
2358 calc->cb[67].enable = 1;
2359
2360 calc->cb[68].id = ID_CALC_CB_HYP;
2361 strcpy(calc->cb[68].label,"Hyp");
2362 calc->cb[68].color = CALC_COLOR_GRAY;
2363 calc->cb[68].r.left = CALC_CB_HYP_LEFT;
2364 calc->cb[68].r.top = CALC_CB_HYP_TOP;
2365 calc->cb[68].r.right = SZ_RADIO_CB_X;
2366 calc->cb[68].r.bottom = SZ_RADIO_CB_Y;
2367 calc->cb[68].enable = 1;
2368
2369 calc->cb[69].id = ID_CALC_WS_QWORD;
2370 strcpy(calc->cb[69].label,"Qword");
2371 calc->cb[69].color = CALC_COLOR_GRAY;
2372 calc->cb[69].r.left = CALC_WS_QWORD_LEFT;
2373 calc->cb[69].r.top = CALC_WS_QWORD_TOP;
2374 calc->cb[69].r.right = SZ_RADIO_WS_X;
2375 calc->cb[69].r.bottom = SZ_RADIO_WS_Y;
2376 calc->cb[69].enable = 1;
2377
2378 calc->cb[70].id = ID_CALC_WS_DWORD;
2379 strcpy(calc->cb[70].label,"Dword");
2380 calc->cb[70].color = CALC_COLOR_GRAY;
2381 calc->cb[70].r.left = CALC_WS_DWORD_LEFT;
2382 calc->cb[70].r.top = CALC_WS_DWORD_TOP;
2383 calc->cb[70].r.right = SZ_RADIO_WS_X;
2384 calc->cb[70].r.bottom = SZ_RADIO_WS_Y;
2385 calc->cb[70].enable = 1;
2386
2387 calc->cb[71].id = ID_CALC_WS_WORD;
2388 strcpy(calc->cb[71].label,"Word");
2389 calc->cb[71].color = CALC_COLOR_GRAY;
2390 calc->cb[71].r.left = CALC_WS_WORD_LEFT;
2391 calc->cb[71].r.top = CALC_WS_WORD_TOP;
2392 calc->cb[71].r.right = SZ_RADIO_WS_X;
2393 calc->cb[71].r.bottom = SZ_RADIO_WS_Y;
2394 calc->cb[71].enable = 1;
2395
2396 calc->cb[72].id = ID_CALC_WS_BYTE;
2397 strcpy(calc->cb[72].label,"Byte");
2398 calc->cb[72].color = CALC_COLOR_GRAY;
2399 calc->cb[72].r.left = CALC_WS_BYTE_LEFT;
2400 calc->cb[72].r.top = CALC_WS_BYTE_TOP;
2401 calc->cb[72].r.right = SZ_RADIO_WS_X;
2402 calc->cb[72].r.bottom = SZ_RADIO_WS_Y;
2403 calc->cb[72].enable = 1;
2404 }
2405
2406 // preload clip region for filler squares
2407
2408 if (calc->sciMode) {
2409 n = 1;
2410
2411 rFiller.left = calc->cb[0].r.left;
2412 rFiller.top = calc->cb[0].r.top;
2413 rFiller.right = calc->cb[0].r.right;
2414 rFiller.bottom = calc->cb[0].r.bottom;
2415 }
2416 else {
2417 n = 2;
2418
2419 rFiller.left = calc->cb[1].r.left;
2420 rFiller.top = calc->cb[1].r.top;
2421 rFiller.right = calc->cb[0].r.right;
2422 rFiller.bottom = calc->cb[0].r.bottom;
2423 }
2424
2425 top_button = calc->numButtons - 1;
2426 if (!calc->sciMode)
2427 top_button -= CALC_NS_COUNT + CALC_MS_COUNT + CALC_CB_COUNT + CALC_WS_COUNT;
2428
2429 for (; n <= top_button; n++) {
2430 ;
2431
2432 calc->cb[n].hBtn = CreateWindow(
2433 "BUTTON",
2434 calc->cb[n].label,
2435 WS_VISIBLE | WS_CHILD | WS_BORDER | BS_CENTER | BS_VCENTER | BS_TEXT |
2436 (calc->cb[n].enable ? 0 : WS_DISABLED), // BS_FLAT
2437 calc->cb[n].r.left,
2438 calc->cb[n].r.top,
2439 calc->cb[n].r.right,
2440 calc->cb[n].r.bottom,
2441 calc->hWnd,
2442 (HMENU)calc->cb[n].id,
2443 calc->hInst,
2444 NULL
2445 );
2446
2447 if (!calc->cb[n].hBtn)
2448 exit(1);
2449
2450 SendMessage(calc->cb[n].hBtn, WM_SETFONT, (WPARAM)hFont, TRUE);
2451 }
2452
2453 if (!calc->sciMode) {
2454 top_button += CALC_NS_COUNT;
2455 for (; n<=top_button; n++) {
2456 int j = ID_CALC_NS_HEX + n - top_button + CALC_NS_COUNT - 1;
2457 calc->cb[n].hBtn = CreateWindow(
2458 "BUTTON",
2459 calc->cb[n].label,
2460 WS_VISIBLE | WS_CHILD | BS_LEFT | BS_VCENTER | BS_TEXT | BS_RADIOBUTTON,
2461 CALC_NS_OFFSET_X + calc->cb[n].r.left,
2462 CALC_NS_OFFSET_Y + calc->cb[n].r.top,
2463 calc->cb[n].r.right,
2464 calc->cb[n].r.bottom,
2465 calc->hWnd,
2466 (HMENU)(j),
2467 calc->hInst,
2468 NULL
2469 );
2470
2471 if (!calc->cb[n].hBtn)
2472 exit(1);
2473
2474 SendMessage(calc->cb[n].hBtn, WM_SETFONT, (WPARAM)hFont, TRUE);
2475 }
2476
2477 top_button += CALC_MS_COUNT;
2478
2479 for (; n<=top_button; n++) {
2480 calc->cb[n].hBtn = CreateWindow(
2481 "BUTTON",
2482 calc->cb[n].label,
2483 WS_VISIBLE | WS_CHILD | BS_LEFT | BS_VCENTER | BS_TEXT | BS_RADIOBUTTON,
2484 CALC_MS_OFFSET_X + calc->cb[n].r.left,
2485 CALC_MS_OFFSET_Y + calc->cb[n].r.top,
2486 calc->cb[n].r.right,
2487 calc->cb[n].r.bottom,
2488 calc->hWnd,
2489 (HMENU)(ID_CALC_MS_DEGREES + n - top_button + CALC_MS_COUNT - 1),
2490 calc->hInst,
2491 NULL
2492 );
2493
2494 if (!calc->cb[n].hBtn)
2495 exit(1);
2496
2497 SendMessage(calc->cb[n].hBtn, WM_SETFONT, (WPARAM)hFont, TRUE);
2498 }
2499
2500 top_button += CALC_CB_COUNT;
2501
2502 for (; n<=top_button; n++) {
2503 calc->cb[n].hBtn = CreateWindow(
2504 "BUTTON",
2505 calc->cb[n].label,
2506 WS_VISIBLE | WS_CHILD | BS_LEFT | BS_VCENTER | BS_TEXT | BS_CHECKBOX,
2507 CALC_CB_OFFSET_X + calc->cb[n].r.left,
2508 CALC_CB_OFFSET_Y + calc->cb[n].r.top,
2509 calc->cb[n].r.right,
2510 calc->cb[n].r.bottom,
2511 calc->hWnd,
2512 (HMENU)(ID_CALC_CB_INV + n - top_button + CALC_CB_COUNT - 1),
2513 calc->hInst,
2514 NULL
2515 );
2516
2517 if (!calc->cb[n].hBtn)
2518 exit(1);
2519
2520 SendMessage(calc->cb[n].hBtn, WM_SETFONT, (WPARAM)hFont, TRUE);
2521 }
2522
2523 top_button += CALC_WS_COUNT;
2524
2525 for (; n<=top_button; n++) {
2526 calc->cb[n].hBtn = CreateWindow(
2527 "BUTTON",
2528 calc->cb[n].label,
2529 WS_CHILD | BS_LEFT | BS_VCENTER | BS_TEXT | BS_RADIOBUTTON,
2530 CALC_WS_OFFSET_X + calc->cb[n].r.left,
2531 CALC_WS_OFFSET_Y + calc->cb[n].r.top,
2532 calc->cb[n].r.right,
2533 calc->cb[n].r.bottom,
2534 calc->hWnd,
2535 (HMENU)(ID_CALC_WS_QWORD + n - top_button + CALC_WS_COUNT - 1),
2536 calc->hInst,
2537 NULL
2538 );
2539
2540 if (!calc->cb[n].hBtn)
2541 exit(1);
2542
2543 EnableWindow(calc->cb[n].hBtn, FALSE);
2544 SendMessage(calc->cb[n].hBtn, WM_SETFONT, (WPARAM)hFont, TRUE);
2545 }
2546
2547 // set sci defaults
2548
2549 SendMessage(calc->cb[61].hBtn, BM_SETCHECK, 1, 0); // decimal
2550 SendMessage(calc->cb[64].hBtn, BM_SETCHECK, 1, 0); // degrees
2551 SendMessage(calc->cb[69].hBtn, BM_SETCHECK, 1, 0); // qword
2552 }
2553 }
2554
2555 void DrawCalcRect (HDC hdc, HDC hMemDC, PAINTSTRUCT *ps, CALC *calc, int object)
2556 {
2557 POINT pt;
2558 HPEN hPenGray;
2559 HPEN hPenBlack;
2560 HPEN hPenWhite;
2561 HPEN hPenOrg;
2562
2563 int WDISPLAY_LEFT;
2564 int WDISPLAY_TOP;
2565 int WDISPLAY_RIGHT;
2566 int WDISPLAY_BOTTOM;
2567
2568 if (!calc->sciMode) {
2569 WDISPLAY_LEFT = WDISPLAY_SCIENTIFIC_LEFT;
2570 WDISPLAY_TOP = WDISPLAY_SCIENTIFIC_TOP;
2571 WDISPLAY_RIGHT = WDISPLAY_SCIENTIFIC_RIGHT;
2572 WDISPLAY_BOTTOM = WDISPLAY_SCIENTIFIC_BOTTOM;
2573 }
2574 else {
2575 WDISPLAY_LEFT = WDISPLAY_STANDARD_LEFT;
2576 WDISPLAY_TOP = WDISPLAY_STANDARD_TOP;
2577 WDISPLAY_RIGHT = WDISPLAY_STANDARD_RIGHT;
2578 WDISPLAY_BOTTOM = WDISPLAY_STANDARD_BOTTOM;
2579 }
2580
2581 // never delete the active pen!
2582
2583 // Gray Pen
2584
2585 hPenGray = CreatePen(PS_SOLID, 1, RGB(CALC_GRAY,CALC_GRAY,CALC_GRAY));
2586 hPenBlack = CreatePen(PS_SOLID, 1, RGB(0,0,0));
2587 hPenWhite = CreatePen(PS_SOLID, 1, RGB(255,255,255));
2588
2589 hPenOrg = SelectObject(hdc, hPenGray);
2590
2591 MoveToEx(hdc,
2592 calc->cb[object].r.left,
2593 calc->cb[object].r.bottom,
2594 &pt);
2595
2596 LineTo(hdc, calc->cb[object].r.left, calc->cb[object].r.top);
2597 LineTo(hdc, calc->cb[object].r.right, calc->cb[object].r.top);
2598
2599 // Black Pen
2600
2601 SelectObject(hdc, hPenBlack);
2602
2603 MoveToEx(hdc,
2604 calc->cb[object].r.right-2,
2605 calc->cb[object].r.top+1,
2606 &pt);
2607
2608 LineTo(hdc, calc->cb[object].r.left+1, calc->cb[object].r.top+1);
2609 LineTo(hdc, calc->cb[object].r.left+1, calc->cb[object].r.bottom-1);
2610
2611 SelectObject(hdc, hPenBlack);
2612
2613 MoveToEx(hdc,
2614 WDISPLAY_LEFT - 1,
2615 WDISPLAY_BOTTOM,
2616 &pt);
2617
2618 LineTo(hdc, WDISPLAY_LEFT - 1, WDISPLAY_TOP - 1);
2619 LineTo(hdc, WDISPLAY_RIGHT + 1, WDISPLAY_TOP - 1);
2620
2621 SelectObject(hdc, hPenGray);
2622
2623 MoveToEx(hdc,
2624 WDISPLAY_RIGHT + 1,
2625 WDISPLAY_TOP - 2,
2626 &pt);
2627
2628 LineTo(hdc, WDISPLAY_LEFT - 2, WDISPLAY_TOP - 2);
2629 LineTo(hdc, WDISPLAY_LEFT - 2, WDISPLAY_BOTTOM + 1);
2630
2631 // White Pen
2632
2633 SelectObject(hdc, hPenWhite);
2634
2635 MoveToEx(hdc,
2636 calc->cb[object].r.left,
2637 calc->cb[object].r.bottom,
2638 &pt);
2639
2640 LineTo(hdc, calc->cb[object].r.right, calc->cb[object].r.bottom);
2641 LineTo(hdc, calc->cb[object].r.right, calc->cb[object].r.top);
2642
2643 SelectObject(hdc, hPenOrg);
2644 DeleteObject(hPenGray);
2645 DeleteObject(hPenBlack);
2646 DeleteObject(hPenWhite);
2647 }
2648
2649 void DrawCalcRectSci(HDC hdc, HDC hMemDC, PAINTSTRUCT *ps, CALC *calc, RECT *r)
2650 {
2651 POINT pt;
2652 HPEN hPen;
2653 HPEN hPenOrg;
2654
2655 // never delete the active pen!
2656
2657 // White Pen
2658
2659 hPen = CreatePen(PS_SOLID, 1, RGB(255,255,255));
2660 hPenOrg = SelectObject(hdc, hPen);
2661
2662 MoveToEx(hdc,
2663 r->left + 1,
2664 r->bottom + 1,
2665 &pt);
2666
2667 LineTo(hdc, r->left + 1, r->top + 1);
2668 LineTo(hdc, r->right + 1, r->top + 1);
2669 LineTo(hdc, r->right + 1, r->bottom + 1);
2670 LineTo(hdc, r->left + 1, r->bottom + 1);
2671
2672 SelectObject(hdc, hPenOrg);
2673 DeleteObject(hPen);
2674
2675 // Black Pen
2676
2677 hPen = CreatePen(PS_SOLID, 1, RGB(CALC_GRAY,CALC_GRAY,CALC_GRAY));
2678 hPenOrg = SelectObject(hdc, hPen);
2679
2680 MoveToEx(hdc,
2681 r->left,
2682 r->bottom,
2683 &pt);
2684
2685 LineTo(hdc, r->left, r->top);
2686 LineTo(hdc, r->right, r->top);
2687 LineTo(hdc, r->right, r->bottom);
2688 LineTo(hdc, r->left, r->bottom);
2689
2690 SelectObject(hdc, hPenOrg);
2691 DeleteObject(hPen);
2692 }
2693
2694 static RECT scirect1 = {
2695 WDISPLAY_SCIENTIFIC_LEFT - 2,
2696 WDISPLAY_SCIENTIFIC_TOP + 25,
2697 WDISPLAY_SCIENTIFIC_LEFT + 202,
2698 WDISPLAY_SCIENTIFIC_TOP + 51
2699 };
2700
2701 static RECT scirect2 = {
2702 WDISPLAY_SCIENTIFIC_LEFT + 205,
2703 WDISPLAY_SCIENTIFIC_TOP + 25,
2704 WDISPLAY_SCIENTIFIC_RIGHT,
2705 WDISPLAY_SCIENTIFIC_TOP + 51
2706 };
2707
2708 static RECT scirect3 = {
2709 WDISPLAY_SCIENTIFIC_LEFT - 2,
2710 WDISPLAY_SCIENTIFIC_TOP + 57,
2711 WDISPLAY_SCIENTIFIC_LEFT + 102,
2712 WDISPLAY_SCIENTIFIC_TOP + 81
2713 };
2714
2715 void DrawCalc (HDC hdc, HDC hMemDC, PAINTSTRUCT *ps, CALC *calc)
2716 {
2717 char s[CALC_BUF_SIZE];
2718
2719 scirect1.right = calc->cb[0].r.right + 2;
2720 scirect2.left = calc->cb[0].r.right + 5;
2721 scirect3.right = calc->cb[1].r.left - 10;
2722
2723 DrawCalcRect (hdc, hMemDC, ps, calc, 0);
2724
2725 if (!calc->sciMode) {
2726 DrawCalcRect (hdc, hMemDC, ps, calc, 1);
2727 DrawCalcRectSci(hdc, hMemDC, ps, calc, &scirect1);
2728 DrawCalcRectSci(hdc, hMemDC, ps, calc, &scirect2);
2729 DrawCalcRectSci(hdc, hMemDC, ps, calc, &scirect3);
2730 }
2731
2732 LoadString(calc->hInst, IDS_BTN_MEM_STATUS_M, s, sizeof(s));
2733
2734 DrawCalcText(hdc, hMemDC, ps, calc, 0, s);
2735 }
2736
2737 void DrawCalcText (HDC hdc, HDC hMemDC, PAINTSTRUCT *ps, CALC *calc, int object, char *s)
2738 {
2739 POINT pt;
2740 HFONT hFont;
2741 HFONT hFontOrg;
2742 HPEN hPen;
2743 HPEN hPenOrg;
2744
2745 char s2[CALC_BUF_SIZE];
2746
2747 int WDISPLAY_LEFT;
2748 int WDISPLAY_TOP;
2749 int WDISPLAY_RIGHT;
2750 int WDISPLAY_BOTTOM;
2751
2752 if (!calc->sciMode) {
2753 WDISPLAY_LEFT = WDISPLAY_SCIENTIFIC_LEFT;
2754 WDISPLAY_TOP = WDISPLAY_SCIENTIFIC_TOP;
2755 WDISPLAY_RIGHT = WDISPLAY_SCIENTIFIC_RIGHT;
2756 WDISPLAY_BOTTOM = WDISPLAY_SCIENTIFIC_BOTTOM;
2757 }
2758 else {
2759 WDISPLAY_LEFT = WDISPLAY_STANDARD_LEFT;
2760 WDISPLAY_TOP = WDISPLAY_STANDARD_TOP;
2761 WDISPLAY_RIGHT = WDISPLAY_STANDARD_RIGHT;
2762 WDISPLAY_BOTTOM = WDISPLAY_STANDARD_BOTTOM;
2763 }
2764
2765 // DEFAULT_GUI_FONT is Tahoma on 2000 and XP?
2766 // SYSTEM_FONT is MS Sans Serif?
2767
2768 hFont = GetStockObject(DEFAULT_GUI_FONT);
2769
2770 hFontOrg = SelectObject(hdc, hFont);
2771
2772 if (calc->memory) {
2773 SetBkMode(hdc, TRANSPARENT);
2774
2775 TextOut(hdc,
2776 calc->cb[object].r.left + 9,
2777 calc->cb[object].r.top + 7,
2778 s,
2779 strlen(s)
2780 );
2781
2782 SetBkMode(hdc, OPAQUE);
2783 }
2784
2785 if (calc->paren) {
2786 sprintf(s2, "(=%d",calc->paren);
2787
2788 SetBkMode(hdc, TRANSPARENT);
2789
2790 SetTextAlign(hdc, TA_CENTER);
2791
2792 TextOut(hdc,
2793 calc->cb[object+1].r.left + 13,
2794 calc->cb[object+1].r.top + 6,
2795 s2,
2796 strlen(s2)
2797 );
2798
2799 SetBkMode(hdc, OPAQUE);
2800 }
2801
2802 hPen = CreatePen(PS_SOLID, 1, RGB(255,255,255));
2803 hPenOrg = SelectObject(hdc, hPen);
2804
2805 MoveToEx(hdc,
2806 WDISPLAY_LEFT - 1,
2807 WDISPLAY_BOTTOM + 1,
2808 &pt
2809 );
2810
2811 LineTo(hdc, WDISPLAY_RIGHT + 1, WDISPLAY_BOTTOM + 1);
2812 LineTo(hdc, WDISPLAY_RIGHT + 1, WDISPLAY_TOP - 2);
2813
2814 Rectangle(hdc, WDISPLAY_LEFT, WDISPLAY_TOP, WDISPLAY_RIGHT, WDISPLAY_BOTTOM);
2815
2816 SelectObject(hdc, hPenOrg);
2817 DeleteObject(hPen);
2818
2819 SetBkMode(hdc, TRANSPARENT);
2820
2821 SetTextAlign(hdc, TA_RIGHT);
2822
2823 TextOut(hdc,
2824 WDISPLAY_RIGHT - 4,
2825 WDISPLAY_TOP + 1,
2826 calc->display,
2827 strlen(calc->display)
2828 );
2829
2830 SelectObject(hdc, hFontOrg);
2831 }
2832
2833 void DestroyCalc (CALC *calc)
2834 {
2835 int i;
2836
2837 for (i=0;i<calc->numButtons;i++)
2838 DestroyWindow(calc->cb[i].hBtn);
2839 }
2840
2841 void calc_buffer_format(CALC *calc) {
2842 char *p;
2843 int n;
2844 int flag = 0;
2845 int point = 0;
2846
2847 // calc_buffer_format: enforce buffer content rules
2848 //
2849 // disallow more than one point (beep)
2850 // remove leading zeros
2851 // remove trailing zeros after point (sprintf can cause this)
2852 // remove trailing points
2853 // chop at 32 digits. Though there could also be a point, and 10 separator characters.
2854
2855 p = calc->buffer;
2856 while (*p) {
2857 if (*p++ == '.')
2858 point++;
2859 }
2860
2861 if (point > 1) {
2862 calc->buffer[strlen(calc->buffer)-1] = '\0';
2863 MessageBeep(0);
2864 }
2865
2866 if (point) {
2867 p = calc->buffer;
2868 n = strlen(p) - 1;
2869 while (*(p+n) &&
2870 *(p+n) != '.' &&
2871 *(p+n) == '0') {
2872 calc->buffer[n] = '\0';
2873 n--;
2874 }
2875 }
2876
2877 // remove leading zeros
2878
2879 p = calc->buffer;
2880 while (*p) {
2881 if (*p != '0')
2882 break;
2883 p++;
2884 }
2885
2886 // remove trailing points
2887
2888 n = strlen(p);
2889
2890 while (n) {
2891 if (*(p+n-1) == '.') {
2892 if (flag) {
2893 *(p + n) = '\0';
2894 }
2895 else {
2896 flag = 1;
2897 }
2898 n--;
2899 }
2900 else {
2901 break;
2902 }
2903 }
2904
2905 // if (!*p)
2906 // strcpy(p, "0");
2907
2908 // chop at 32 digits
2909 if (flag)
2910 *(p+33) = '\0';
2911 else
2912 *(p+32) = '\0';
2913
2914 n = 0;
2915 while (*p)
2916 *(calc->buffer + n++) = *(p++);
2917 *(calc->buffer + n) = '\0';
2918 }
2919
2920 void calc_buffer_display(CALC *calc) {
2921 char *p;
2922 char s[CALC_BUF_SIZE];
2923 char r[CALC_BUF_SIZE] = "0";
2924 int point=0;
2925 calcfloat real;
2926
2927 switch (calc->numBase) {
2928 case NBASE_HEX:
2929 real = calc_atof(calc->buffer, calc->numBase);
2930 sprintf(calc->display, "%lx", (long)real);
2931 break;
2932
2933 case NBASE_OCTAL:
2934 sprintf(calc->display, "%lo", (long)calc->buffer);
2935 break;
2936
2937 case NBASE_BINARY:
2938 sprintf(calc->display, "%lx", (long)calc->buffer);
2939 break;
2940
2941 case NBASE_DECIMAL:
2942 calc_buffer_format(calc);
2943
2944 if (calc->displayMode) {
2945 if (!strcmp(calc->buffer, "0") || !calc->buffer[0]) {
2946 strcpy(calc->display, "0.e+0");
2947 }
2948 else {
2949 int i = 0;
2950 int lz = 0;
2951 calcfloat r;
2952 int exp = 0;
2953
2954 r = calc_atof(calc->buffer, calc->numBase);
2955 sprintf(s, FMT_DESC_EXP, r);
2956 // remove leading zeros in exponent
2957 p = s;
2958 while (*p) {
2959 if (*p == 'e') { // starting exponent parsing
2960
2961 exp = 1;
2962 }
2963 else if (exp) { // inside exponent, and haven't seen a digit, so could be a leading zero
2964
2965 if (*p == '0')
2966 lz = 1;
2967 }
2968
2969 if (exp && (*p != 'e') && (*p != '0') && (*p != '+') && (*p != '-')) {
2970 exp = 0;
2971 lz = 0;
2972 }
2973
2974 if (!lz)
2975 calc->display[i++] = *p;
2976
2977 p++;
2978 }
2979
2980 if (calc->display[i-1] == '+') // all trailing zeros
2981
2982 calc->display[i++] = '0';
2983
2984 calc->display[i] = 0;
2985 }
2986 }
2987 else {
2988 // calc_buffer_display: display buffer after formatting
2989 //
2990 // if digitGrouping, embed separators
2991 // add point if missing
2992 // display
2993
2994 strcpy(s,calc->buffer);
2995 p = s;
2996
2997 while (*p) {
2998 if (*p++ == '.')
2999 point = 1;
3000 }
3001
3002 if (!*s)
3003 strcpy(s, "0");
3004
3005 if (calc->digitGrouping)
3006 calc_sep(s);
3007
3008 if (!point && calc->numBase == NBASE_DECIMAL)
3009 strcat(s, ".");
3010
3011 if (*s == '.') {
3012 strcat(r, s);
3013 strcpy(calc->display, r);
3014 }
3015 else {
3016 strcpy(calc->display, s);
3017 }
3018 }
3019 }
3020 InvalidateRect(calc->hWnd, NULL, FALSE);
3021 UpdateWindow(calc->hWnd);
3022 }
3023
3024 char *calc_sep(char *s)
3025 {
3026 char c;
3027 char *p;
3028 int n;
3029 int x = 1;
3030 int i = 0;
3031 int point = 0;
3032 char r[CALC_BUF_SIZE];
3033
3034 n = strlen(s);
3035
3036 if (!*s)
3037 return s;
3038
3039 p = s;
3040
3041 // need to handle leading minus sign!
3042
3043 // see if there is a point character
3044
3045 while (*p) {
3046 if (*p++ == '.') {
3047 point = p - s;
3048 break;
3049 }
3050 }
3051
3052 // if there is a point character, skip over decimal places
3053
3054 if (point) {
3055 i = n - point + 1;
3056 n = point - 1;
3057 strcpy(r, s);
3058 strrev(r);
3059 }
3060
3061 // commify the integer part now
3062
3063 while ((c = *(s + --n))) {
3064 r[i++] = c;
3065 if (x++ % 3 == 0)
3066 r[i++] = ',';
3067 if (n == -1)
3068 break;
3069 }
3070
3071 if (r[i-1] == ',')
3072 r[--i] = '\0';
3073 else
3074 r[i] = '\0';
3075
3076 strcpy(s, strrev(r));
3077
3078 return s;
3079 }
3080
3081 long factorial(long n)
3082 {
3083 if (n <= 1L)
3084 return 1L;
3085
3086 return n * factorial(n - 1);
3087 }
3088
3089 void calc_setmenuitem_radio(HMENU hMenu, UINT id)
3090 {
3091 MENUITEMINFO menuItem;
3092
3093 menuItem.fMask = MIIM_FTYPE;
3094 menuItem.fType = MFT_STRING | MFT_RADIOCHECK;
3095 // menuItem.fState = MFS_ENABLED;
3096 // menuItem.wID = id;
3097 // menuItem.hSubMenu = NULL;
3098 // menuItem.hbmpChecked = NULL;
3099 // menuItem.hbmpUnchecked = NULL;
3100 // menuItem.dwItemData = 0;
3101 // menuItem.dwTypeData = "Hex\tF5";
3102 // menuItem.cch = sizeof("Hex\tF5");
3103 menuItem.cbSize = sizeof(MENUITEMINFO);
3104
3105 SetMenuItemInfo(hMenu, id, FALSE, &menuItem);
3106 }
3107
3108 calcfloat calc_convert_to_radians(CALC *calc)
3109 {
3110 calcfloat r = calc_atof(calc->buffer, calc->numBase);
3111
3112 if (calc->trigMode == TRIGMODE_RADIANS)
3113 return r;
3114 if (calc->trigMode == TRIGMODE_DEGREES)
3115 return r * CONST_PI / 180;
3116 else if (calc->trigMode == TRIGMODE_GRADS)
3117 return r * CONST_PI / 200; // 90 degrees == 100 grads
3118
3119 return 0L;
3120 }
3121
3122 calcfloat calc_convert_from_radians(CALC *calc)
3123 {
3124 calcfloat r = calc_atof(calc->buffer, calc->numBase);
3125
3126 if (calc->trigMode == TRIGMODE_RADIANS)
3127 return r;
3128 if (calc->trigMode == TRIGMODE_DEGREES)
3129 return r * 180 / CONST_PI;
3130 else if (calc->trigMode == TRIGMODE_GRADS)
3131 return r * 200 / CONST_PI; // 90 degrees == 100 grads
3132
3133 return 0L;
3134 }
3135
3136 void show_debug(CALC *calc, char *title, long w, long l)
3137 {
3138 char s[1024];
3139
3140 sprintf(s,
3141
3142 "wParam = (%c) %d:%d, %x:%xh\n \
3143 lParam = %d:%d, %x:%x\n \
3144 value = %.32g\n \
3145 memory = %.32g\n \
3146 buffer = \"%s\"\n \
3147 display = \"%s\"\n \
3148 numBase = %d\n \
3149 trigMode = %d\n \
3150 wordSize = %d\n \
3151 invMode = %d\n \
3152 hypMode = %d\n \
3153 oper = (%c)\n",
3154
3155 LOWORD(w),
3156 LOWORD(w),
3157 HIWORD(w),
3158 LOWORD(w),
3159 HIWORD(w),
3160 LOWORD(l),
3161 HIWORD(l),
3162 LOWORD(l),
3163 HIWORD(l),
3164 calc->value,
3165 calc->memory,
3166 calc->buffer,
3167 calc->display,
3168 calc->numBase,
3169 calc->trigMode,
3170 calc->wordSize,
3171 calc->invMode,
3172 calc->hypMode,
3173 calc->oper
3174 );
3175
3176 MessageBox(calc->hWnd, s, title, MB_OK);
3177 }
3178
3179 calcfloat calc_atof(char *s, int base)
3180 {
3181 // converts from another base to decimal calcfloat
3182
3183 switch (base) {
3184 case NBASE_DECIMAL:
3185 return CALC_ATOF(s);
3186 case NBASE_HEX:
3187 return (calcfloat)strtol(s, NULL, 16);
3188 case NBASE_OCTAL:
3189 return (calcfloat)strtol(s, NULL, 8);
3190 case NBASE_BINARY:
3191 return (calcfloat)strtol(s, NULL, 2);
3192 default:
3193 break;
3194 }
3195
3196 return 0L;
3197 }
3198
3199 void calc_ftoa(CALC *calc, calcfloat r, char *buf)
3200 {
3201 // converts from decimal calcfloat to another base
3202
3203 switch (calc->numBase) {
3204 case NBASE_DECIMAL:
3205 sprintf(buf, FMT_DESC_FLOAT, r);
3206 break;
3207 case NBASE_HEX:
3208 sprintf(buf, "%lX", (long)r);
3209 break;
3210 case NBASE_OCTAL:
3211 sprintf(buf, "%lo", (long)r);
3212 break;
3213 case NBASE_BINARY: // 911 - need routine here
3214
3215 break;
3216 default:
3217 break;
3218 }
3219 }
3220
3221 int parse(int wParam, int lParam)
3222 {
3223 switch (wParam) {
3224 case '\b': // backspace
3225
3226 if (calc.buffer[0])
3227 calc.buffer[strlen(calc.buffer)-1] = '\0';
3228 break;
3229
3230 case '\x1b': // ESC
3231
3232 calc.next = 1;
3233 calc.buffer[0] = '\0';
3234 calc.value = 0;
3235 break;
3236
3237 case '0':
3238 case '1':
3239 case '2':
3240 case '3':
3241 case '4':
3242 case '5':
3243 case '6':
3244 case '7':
3245 case '8':
3246 case '9':
3247 case 'a':
3248 case 'b':
3249 case 'c':
3250 case 'd':
3251 case 'e':
3252 case 'f':
3253 case 'A':
3254 case 'B':
3255 case 'C':
3256 case 'D':
3257 case 'E':
3258 case 'F':
3259 {
3260 char s22[CALC_BUF_SIZE];
3261 UCHAR w = (UCHAR)LOWORD(wParam);
3262
3263 if (!keys[calc.numBase][w]) {
3264 MessageBeep(0);
3265 return 0;
3266 }
3267
3268 if (calc.next) { // user first digit indicates new buffer needed after previous UI event
3269 calc.next = 0;
3270 calc.buffer[0] = '\0';
3271 }
3272 calc.newenter = 1;
3273
3274 sprintf(s22,"%c", w);
3275 strcat(calc.buffer, s22);
3276 }
3277 break;
3278
3279 case '.':
3280 case ',': // 911 - need to handle this, i18n
3281
3282 if (calc.numBase == NBASE_DECIMAL) {
3283 if (calc.next) { // first digit indicates new buffer needed after previous UI event
3284 calc.next = 0;
3285 calc.buffer[0] = '\0';
3286 }
3287
3288 strcat(calc.buffer, ".");
3289 }
3290 else {
3291 MessageBeep(0);
3292 return 0;
3293 }
3294 break;
3295
3296 case 'x':
3297 case 'X': // exp, e(1)=2.718
3298
3299 if (calc.numBase == NBASE_DECIMAL) {
3300 calc.next = 1;
3301 calc.value = exp(calc_atof(calc.buffer, calc.numBase));
3302 sprintf(calc.buffer, FMT_DESC_FLOAT, calc.value);
3303 }
3304 else {
3305 MessageBeep(0);
3306 return 0;
3307 }
3308 break;
3309
3310 case 'l':
3311 case 'L':
3312 calc.next = 1;
3313 if (calc_atof(calc.buffer, calc.numBase) == 0.0L) {
3314 strcpy(calc.buffer, err_invalid);
3315 }
3316 else {
3317 calc.value = log10(calc_atof(calc.buffer, calc.numBase));
3318 sprintf(calc.buffer, FMT_DESC_FLOAT, calc.value);
3319 }
3320 break;
3321
3322 case 'N':
3323 case 'n': // ln is natural logarithm
3324
3325 calc.next = 1;
3326 if (calc_atof(calc.buffer, calc.numBase) == 0.0L) {
3327 strcpy(calc.buffer, err_invalid);
3328 }
3329 else {
3330 calc.value = log(calc_atof(calc.buffer, calc.numBase));
3331 sprintf(calc.buffer, FMT_DESC_FLOAT, calc.value);
3332 }
3333 break;
3334
3335 case 'p':
3336 case 'P':
3337 if (calc.numBase == NBASE_DECIMAL) {
3338 calc.next = 1;
3339 sprintf(calc.buffer, FMT_DESC_FLOAT, CONST_PI);
3340 }
3341 else {
3342 MessageBeep(0);
3343 return 0;
3344 }
3345 break;
3346
3347 case '\x0c': // Ctrl+L MC (only need to invalid rectangle if wasn't already zero, no need to update display)
3348
3349 calc.next = 1;
3350 if (calc.memory) {
3351 calc.memory = 0.0;
3352 InvalidateRect(calc.hWnd, &rFiller, TRUE);
3353 UpdateWindow(calc.hWnd);
3354 }
3355
3356 return 0;
3357 break;
3358
3359 case '\x12': // Ctrl+R MR (value doesn't change, so no invalid rectangle. but display is updated.)
3360
3361 calc.next = 1;
3362 if (calc.memory != calc_atof(calc.buffer, calc.numBase))
3363 sprintf(calc.buffer,FMT_DESC_FLOAT,calc.memory);
3364 else
3365 return 0;
3366 break;
3367
3368 case '\x10': // Ctrl+P M+ (need to invalidate rectangle in many cases but not display)
3369
3370 calc.next = 1;
3371 InvalidateRect(calc.hWnd, &rFiller, TRUE);
3372 calc.memory += calc_atof(calc.buffer, calc.numBase);
3373 return 0;
3374 break;
3375
3376 case '\x0d': // Ctrl+M MS (only need to invalid rectangle if was zero and now not,
3377
3378 // or was not zero and now is, not display)
3379 calc.next = 1;
3380 {
3381 int x = GetKeyState(VK_CONTROL);
3382
3383 if (x < 0 || lParam == NUMBER_OF_THE_BEAST) {
3384 if ((!calc.memory && calc_atof(calc.buffer, calc.numBase)) ||
3385 (calc.memory && !calc_atof(calc.buffer, calc.numBase))) {
3386
3387 calc.memory = calc_atof(calc.buffer, calc.numBase);
3388 InvalidateRect(calc.hWnd, &rFiller, FALSE);
3389 UpdateWindow(calc.hWnd);
3390 }
3391 else {
3392 calc.memory = calc_atof(calc.buffer, calc.numBase);
3393 }
3394 }
3395 return 0;
3396 }
3397 break;
3398
3399 // fall through for Enter processing ... but there is a bug here in Ctrl+M vs. Return
3400 case '=':
3401 {
3402 calcfloat r = calc.operand;
3403
3404 if (calc.newenter) {
3405 calc.newenter = 0;
3406 calc.operand = calc_atof(calc.buffer, calc.numBase);
3407 r = calc_atof(calc.buffer, calc.numBase); // convert buffer from whatever base to decimal real
3408 }
3409
3410 if (calc.oper == '+') {
3411 calc.value += r;
3412 }
3413 else if (calc.oper == '-') {
3414 calc.value -= r;
3415 }
3416 else if (calc.oper == '*') {
3417 calc.value *= r;
3418 }
3419 else if (calc.oper == '%') {
3420 calc.value = (long)calc.value % (long)r;
3421 }
3422 else if (calc.oper == '/') {
3423 if (!calc_atof(calc.buffer, calc.numBase)) {
3424 strcpy(calc.buffer, err_undefined);
3425 calc.err = 1;
3426 }
3427 else {
3428 calc.value /= r;
3429 }
3430 }
3431 else if (calc.oper == '&') {
3432 calc.value = (calcfloat)((long)calc.value & (long)r);
3433 }
3434 else if (calc.oper == '|') {
3435 calc.value = (calcfloat)((long)calc.value | (long)r);
3436 }
3437 else if (calc.oper == '^') {
3438 calc.value = (calcfloat)((long)calc.value ^ (long)r);
3439 }
3440 else if (calc.oper == 'y') {
3441 calc.value = (calcfloat)pow(calc.value, r);
3442 }
3443 else if (calc.oper == '<') {
3444 if (calc.invMode)
3445 calc.value = (calcfloat)((long)calc.value >> (long)calc_atof(calc.buffer, calc.numBase));
3446 else
3447 calc.value = (calcfloat)((long)calc.value << (long)calc_atof(calc.buffer, calc.numBase));
3448 }
3449 else { // must have been a gratuitous user =
3450
3451 calc.value = calc_atof(calc.buffer, calc.numBase);
3452 }
3453
3454 calc_ftoa(&calc, calc.value, calc.buffer);
3455
3456 if (!calc.next)
3457 // calc.value = r;
3458 calc.next = 1;
3459 }
3460 break;
3461
3462 case 'R':
3463 case 'r': // 1/x
3464
3465 calc.next = 1;
3466 if (calc_atof(calc.buffer, calc.numBase) == 0) {
3467 calc.err = 1;
3468 strcpy(calc.buffer, err_divide_by_zero);
3469 }
3470 else {
3471 calc.value = 1/calc_atof(calc.buffer, calc.numBase);
3472 sprintf(calc.buffer, FMT_DESC_FLOAT, calc.value );
3473 }
3474 break;
3475
3476 case '@': // ^2 - sqrt in standard mode, squared in sci mode
3477
3478 calc.next = 1;
3479 calc.value = calc_atof(calc.buffer, calc.numBase);
3480
3481 if (!calc.sciMode)
3482 calc.value *= calc.value;
3483 else
3484 calc.value = sqrt(calc.value);
3485
3486 sprintf(calc.buffer, FMT_DESC_FLOAT, calc.value );
3487 break;
3488
3489 case '#': // ^3
3490
3491 calc.next = 1;
3492 calc.value = calc_atof(calc.buffer, calc.numBase);
3493 calc.value *= calc.value * calc.value;
3494 sprintf(calc.buffer, FMT_DESC_FLOAT, calc.value );
3495 break;
3496
3497 case 'Y':
3498 case 'y': // x^y
3499
3500 calc.next = 1;
3501 calc.value = calc_atof(calc.buffer, calc.numBase);
3502 calc.oper = 'y';
3503 calc.next = 1;
3504 break;
3505
3506 case '<': // Lsh
3507
3508 calc.next = 1;
3509 calc.value = calc_atof(calc.buffer, calc.numBase);
3510 calc.oper = '<';
3511 calc.next = 1;
3512 break;
3513
3514 case ';': // INT
3515
3516 calc.next = 1;
3517 calc.value = (long)calc_atof(calc.buffer, calc.numBase);
3518 sprintf(calc.buffer, FMT_DESC_FLOAT, calc.value );
3519 break;
3520
3521 case '!': // factorial, need to use gamma function for reals t^(z-1)*e^t dt
3522
3523 calc.next = 1;
3524 calc.value = calc_atof(calc.buffer, calc.numBase);
3525 calc.value = (calcfloat)factorial((long)calc.value);
3526 sprintf(calc.buffer, FMT_DESC_FLOAT, calc.value );
3527 break;
3528
3529 case '&': // bitwise and
3530
3531 calc.oper = '&';
3532 calc.next = 1;
3533 calc.value = calc_atof(calc.buffer, calc.numBase);
3534 break;
3535
3536 case '|': // bitwise or
3537
3538 calc.oper = '|';
3539 calc.next = 1;
3540 calc.value = calc_atof(calc.buffer, calc.numBase);
3541 break;
3542
3543 case '^': // bitwise xor
3544
3545 calc.oper = '^';
3546 calc.next = 1;
3547 calc.value = calc_atof(calc.buffer, calc.numBase);
3548 break;
3549
3550 case '~': // bitwise not
3551
3552 calc.next = 1;
3553 calc.value = ~ (long) calc_atof(calc.buffer, calc.numBase);
3554 sprintf(calc.buffer, FMT_DESC_FLOAT, calc.value );
3555 break;
3556
3557 case '+':
3558 calc.operand = calc_atof(calc.buffer, calc.numBase);
3559 calc.value += calc.operand;
3560 calc_ftoa(&calc, calc.value, calc.buffer);
3561 calc.oper = '+';
3562 calc.newenter = 1;
3563 calc.next = 1;
3564 break;
3565
3566 case '-':
3567 if (calc.init) {
3568 calc.init = 0;
3569 calc.operand = calc_atof(calc.buffer, calc.numBase);
3570 calc.value = calc.operand;
3571 }
3572 else {
3573 calc.value -= calc.operand;
3574 calc_ftoa(&calc, calc.value, calc.buffer);
3575 }
3576
3577 calc.oper = '-';
3578 calc.newenter = 1;
3579 calc.next = 1;
3580 break;
3581
3582 case '*':
3583 if (calc.init) {
3584 calc.init = 0;
3585 calc.operand = calc_atof(calc.buffer, calc.numBase);
3586 calc.value = calc.operand;
3587 }
3588 else {
3589 calc.value *= calc.operand;
3590 calc_ftoa(&calc, calc.value, calc.buffer);
3591 }
3592 calc.oper = '*';
3593 calc.newenter = 1;
3594 calc.next = 1;
3595 break;
3596
3597 case '/':
3598 if (calc.init) {
3599 calc.init = 0;
3600 calc.operand = calc_atof(calc.buffer, calc.numBase);
3601 calc.value = calc.operand;
3602 }
3603 else {
3604 calc.value /= calc.operand;
3605 calc_ftoa(&calc, calc.value, calc.buffer);
3606 }
3607 calc.oper = '/';
3608 calc.newenter = 1;
3609 calc.next = 1;
3610 break;
3611
3612 case '%':
3613 if (!calc.sciMode) {
3614 if (calc.init) {
3615 calc.init = 0;
3616 calc.operand = calc_atof(calc.buffer, calc.numBase);
3617 calc.value = calc.operand;
3618 }
3619 else {
3620 calc.value = (long)atof(calc.buffer) % (long)calc.operand;
3621 calc_ftoa(&calc, calc.value, calc.buffer);
3622 }
3623 }
3624 else {
3625 calcfloat r;
3626 r = calc_atof(calc.buffer, calc.numBase);
3627 calc.next = 1;
3628 sprintf(calc.buffer, FMT_DESC_FLOAT, r * calc.value / (calcfloat)100.0);
3629 }
3630
3631 calc.oper = '%';
3632 calc.newenter = 1;
3633 calc.next = 1;
3634 break;
3635
3636 case 'O': // cos
3637
3638 case 'o':
3639 if (calc.numBase == NBASE_DECIMAL) {
3640
3641 calcfloat r;
3642 calc.next = 1;
3643 r = calc_convert_to_radians(&calc);
3644 if (calc.hypMode && calc.invMode)
3645 calc.value = acosh(r);
3646 else if (calc.invMode)
3647 calc.value = acos(r);
3648 else if (calc.hypMode)
3649 calc.value = cosh(r);
3650 else
3651 calc.value = cos(calc_atof(calc.buffer, calc.numBase));
3652 sprintf(calc.buffer, FMT_DESC_FLOAT, calc.value );
3653 }
3654 else {
3655 MessageBeep(0);
3656 return 0;
3657 }
3658 break;
3659
3660 case 'S': // sin
3661
3662 case 's':
3663 if (calc.numBase == NBASE_DECIMAL) {
3664
3665 calcfloat r = calc_convert_to_radians(&calc);
3666 calc.next = 1;
3667 if (calc.hypMode && calc.invMode)
3668 calc.value = asinh(r);
3669 else if (calc.invMode)
3670 calc.value = asin(r);
3671 else if (calc.hypMode)
3672 calc.value = sinh(r);
3673 else
3674 calc.value = sin(r);
3675
3676 sprintf(calc.buffer, FMT_DESC_FLOAT, calc.value );
3677 }
3678 else {
3679 MessageBeep(0);
3680 return 0;
3681 }
3682 break;
3683
3684 case 'T': // tan
3685
3686 case 't':
3687 if (calc.numBase == NBASE_DECIMAL) {
3688 calcfloat r = calc_convert_to_radians(&calc);
3689 calc.next = 1;
3690 if (calc.hypMode && calc.invMode)
3691 calc.value = atanh(r);
3692 else if (calc.invMode)
3693 calc.value = atan(r);
3694 else if (calc.hypMode)
3695 calc.value = tanh(r);
3696 else
3697 calc.value = tan(r);
3698
3699 sprintf(calc.buffer, FMT_DESC_FLOAT, calc.value );
3700 }
3701 else {
3702 MessageBeep(0);
3703 return 0;
3704 }
3705 break;
3706
3707 case 'M': // dms = Degrees Minutes Seconds
3708
3709 case 'm':
3710 if (calc.numBase == NBASE_DECIMAL) {
3711 calcfloat r2;
3712 calcfloat r = calc_atof(calc.buffer, calc.numBase);
3713 calc.next = 1;
3714 r2 = r - (long)r;
3715
3716 r = (long)r + r2 * 0.6; // multiply by 60 and divide by 100
3717 calc.value = r;
3718 sprintf(calc.buffer, FMT_DESC_FLOAT, calc.value );
3719 }
3720 else {
3721 MessageBeep(0);
3722 return 0;
3723 }
3724 break;
3725
3726 case 'V': // toggle scientic notation like 1.e+2 or 100
3727
3728 case 'v':
3729 calc.displayMode = !calc.displayMode;
3730 break;
3731
3732 // non-standard keystrokes ...
3733
3734 case '?':
3735
3736 calc.next = 1;
3737 if (calc_atof(calc.buffer, calc.numBase) < 0) {
3738 calc.err = 1;
3739 strcpy(calc.buffer, err_invalid);
3740 }
3741 else {
3742 calc.value = sqrt(calc_atof(calc.buffer, calc.numBase));
3743 sprintf(calc.buffer, FMT_DESC_FLOAT, calc.value );
3744 }
3745 break;
3746
3747 case 'Z': // +/-
3748
3749 {
3750 char s[CALC_BUF_SIZE] = "-";
3751
3752 if (!strcmp(calc.buffer, "0"))
3753 return 0;
3754
3755 if (calc.buffer[0] == '-')
3756 strcpy(s, calc.buffer+1);
3757 else
3758 strcpy(s+1, calc.buffer);
3759
3760 strcpy(calc.buffer, s);
3761 }
3762 break;
3763
3764 case 'G': // debug mode
3765
3766 case 'g':
3767 calc.next = 1;
3768 debug = !debug;
3769 break;
3770
3771 default:
3772 MessageBeep(0);
3773 return 0;
3774 break;
3775 }
3776
3777 return 0;
3778 }
3779
3780 /*
3781 case WM_CONTEXTMENU: // need to subclass control and just call WinHelp!
3782 WinHelp((HWND) wParam, "c:/windows/help/calc.hlp", HELP_CONTEXTMENU, (DWORD)(LPVOID)2);
3783 return 0;
3784 }
3785 */