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