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