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