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