|
|
/**************************************************************************/ /*** SCICALC Scientific Calculator for Windows 3.00.12 ***/ /*** By Kraig Brockschmidt, Microsoft Co-op, Contractor, 1988-1989 ***/ /*** (c)1989 Microsoft Corporation. All Rights Reserved. ***/ /*** ***/ /*** scimenu.c ***/ /*** ***/ /*** Functions contained: ***/ /*** MenuFunctions--handles menu options. ***/ /*** ***/ /*** Functions called: ***/ /*** DisplayNum ***/ /*** ***/ /*** Last modification Thu 06-Dec-1989 ***/ /*** (-by- Amit Chatterjee [amitc]) ***/ /*** ***/ /*** Modified the 'PASTE' menu to check for unary minus, e, e+ & e- ***/ /*** in DEC mode. ***/ /*** ***/ /*** Also modified the COPY code to not copy the last '.' in the display***/ /*** if a decimal point has not been hit. ***/ /*** ***/ /**************************************************************************/
#include "scicalc.h"
#include "unifunc.h"
#include "input.h"
#include <shellapi.h>
#include <ctype.h>
#define CHARSCAN 66
extern HWND hEdit, hStatBox; extern TCHAR szAppName[10], szDec[5], gszSep[5], *rgpsz[CSTRINGS]; extern LPTSTR gpszNum; extern BOOL bError; extern INT nLayout;
extern HMENU g_hDecMenu; extern HMENU g_hHexMenu;
extern CALCINPUTOBJ gcio; extern BOOL gbRecord; extern BOOL gbUseSep;
/* Menu handling routine for COPY, PASTE, ABOUT, and HELP. */ VOID NEAR PASCAL MemErrorMessage(VOID) { MessageBeep(0); MessageBox(g_hwndDlg,rgpsz[IDS_STATMEM],NULL,MB_OK|MB_ICONHAND); }
VOID APIENTRY MenuFunctions(DWORD nFunc) { INT nx; static const int rgbMap[CHARSCAN * 2]= { TEXT('0'),IDC_0, TEXT('1'),IDC_1, TEXT('2'),IDC_2, TEXT('3'),IDC_3,
TEXT('4'),IDC_4, TEXT('5'),IDC_5, TEXT('6'),IDC_6, TEXT('7'),IDC_7,
TEXT('8'),IDC_8, TEXT('9'),IDC_9, TEXT('A'),IDC_A, TEXT('B'),IDC_B,
TEXT('C'),IDC_C, TEXT('D'),IDC_D, TEXT('E'),IDC_E, TEXT('F'),IDC_F,
TEXT('!'),IDC_FAC, TEXT('S'),IDC_SIN, TEXT('O'),IDC_COS, TEXT('T'),IDC_TAN,
TEXT('R'),IDC_REC, TEXT('Y'),IDC_PWR, TEXT('#'),IDC_CUB, TEXT('@'),IDC_SQR, TEXT('M'),IDM_DEG, TEXT('N'),IDC_LN, TEXT('L'),IDC_LOG, TEXT('V'),IDC_FE,
TEXT('X'),IDC_EXP, TEXT('I'),IDC_INV, TEXT('H'),IDC_HYP, TEXT('P'),IDC_PI,
TEXT('/'),IDC_DIV, TEXT('*'),IDC_MUL, TEXT('%'),IDC_MOD, TEXT('-'),IDC_SUB,
TEXT('='),IDC_EQU, TEXT('+'),IDC_ADD, TEXT('&'),IDC_AND, TEXT('|'),IDC_OR,
TEXT('^'),IDC_XOR, TEXT('~'),IDC_COM, TEXT(';'),IDC_CHOP, TEXT('<'),IDC_LSHF,
TEXT('('),IDC_OPENP,TEXT(')'),IDC_CLOSEP,
TEXT('\\'), IDC_DATA, TEXT('Q'), IDC_CLEAR, TEXT('Q')+128, IDC_CLEAR, // ":Q"=="Q"=>CLEAR
TEXT('S')+128, IDC_STAT, // ":S"=>CTRL-S
TEXT('M')+128, IDC_STORE, // ":M"=>CTRL-M
TEXT('P')+128, IDC_MPLUS, // ":P"=>CTRL-P
TEXT('C')+128, IDC_MCLEAR, // ":C"=>CTRL-C
TEXT('R')+128, IDC_RECALL, // ":R"=>CTRL-R
TEXT('A')+128, IDC_AVE, // ":A"=>CTRL-A
TEXT('T')+128, IDC_B_SUM, // ":T"=>CTRL-T
TEXT('D')+128, IDC_DEV, // ":D"=>CTRL-D
TEXT('2')+128, IDC_DWORD, // ":2"=>F2 IDC_DWORD
TEXT('3')+128, IDC_RAD, // ":3"=>F3 IDC_WORD
TEXT('4')+128, IDC_GRAD, // ":4"=>F4 IDC_BYTE
TEXT('5')+128, IDC_HEX, // ":5"=>F5
TEXT('6')+128, IDC_DEC, // ":6"=>F6
TEXT('7')+128, IDC_OCT, // ":7"=>F7
TEXT('8')+128, IDC_BIN, // ":8"=>F8
TEXT('9')+128, IDC_SIGN, // ":9"=>F9
TEXT('9')+3+128, IDC_QWORD // ":9"+2=>F12 (64 bit)
};
switch (nFunc) { case IDM_COPY: { TCHAR szJunk[256];
// Copy the string into a work buffer. It may be modified.
if (gbRecord) CIO_vConvertToString(&gpszNum, &gcio, nRadix);
lstrcpy(szJunk, gpszNum);
// Strip a trailing decimal point if it wasn't explicitly entered.
if (!gbRecord || !CIO_bDecimalPt(&gcio)) { nx = lstrlen(szJunk); if (szJunk[nx - 1] == szDec[0]) szJunk[nx - 1] = 0; }
/* Copy text to the clipboard through the hidden edit control.*/ SetWindowText(hEdit, szJunk); SendMessage(hEdit, EM_SETSEL, 0, -1); // select all text
SendMessage(hEdit, WM_CUT, 0, 0L); break; }
case IDM_PASTE: { HANDLE hClipData; char * lpClipData; char * lpEndOfBuffer; // used to ensure we don't GPF even if the clipboard data isn't NULL terminated
WORD b, bLast; INT nControl; BOOL bNeedIDC_SIGN = FALSE;
/* Get a handle on the clipboard data and paste by sending the*/ /* contents one character at a time like it was typed. */ if (!OpenClipboard(g_hwndDlg)) { MessageBox(g_hwndDlg, rgpsz[IDS_NOPASTE], rgpsz[IDS_CALC], MB_OK | MB_ICONEXCLAMATION); break; }
hClipData=GetClipboardData(CF_TEXT); if (hClipData) { lpClipData=(char *)GlobalLock(hClipData); if (lpClipData) { lpEndOfBuffer = lpClipData + GlobalSize(hClipData); bLast=0;
/* Continue this as long as no error occurs. If one */ /* does then it's useless to continue pasting. */ while (!bError && lpClipData < lpEndOfBuffer) { // we know that lpClipData points to a NULL terminated ansi
// string because this is the format we requested the data in.
// As a result we call CharNextA.
b = *lpClipData; lpClipData = CharNextA( lpClipData );
/* Skip spaces and LF and CR. */ if (b==32 || b==10 || b==13 || b==gszSep[0]) continue;
/* We're done if we get to a NULL character */ if ( b==0 ) break;
if (b == szDec[0]) { bLast = b; b = IDC_PNT; goto MappingDone; }
/*-----------------------------------------------------------------------------;
; Now we will check for certain special cases. These are: ; ; ; ; (1) Unary Minus. If bLast is still 0 and b is '-' we will force b to ; ; be the code for 'SIGN'. ; ; (2) If b is 'x' we will make it the code for EXP ; ; (3) if bLast is 'x' and b is '+' we will ignore b, as '+' is the dflt. ; ; (4) if bLast is 'x' and b is '-' we will force b to be SIGN. ; ; ; ; In case (3) we will go back to the top of the loop else we will jmp off ; ; to the sendmessage point, bypassing the table lookup. ; ;-----------------------------------------------------------------------------*/
/* check for unary minuses */ if (!bLast && b == TEXT('-')) { /* Doesn't work.
bLast = b ; b = IDC_SIGN ; goto MappingDone ; */ bNeedIDC_SIGN = TRUE ; continue ; }
/* check for 'x' */ if ((b == TEXT('x') || b == TEXT('e')) && nRadix == 10) { bLast = TEXT('x') ; b = IDC_EXP ; goto MappingDone ; }
/* if the last character was a 'x' & this is '+' - ignore */ if (bLast==TEXT('x') && b ==TEXT('+') && nRadix == 10) continue ;
/* if the last character was a 'x' & this is '-' - change
it to be the code for SIGN */ if (bLast==TEXT('x') && b==TEXT('-') && nRadix == 10) { bLast = b ; b = IDC_SIGN ; goto MappingDone ; }
/* -by- AmitC */ /*--------------------------------------------------------------------------*/
/* Check for control character. */ if (bLast==TEXT(':')) nControl=128; else nControl=0;
bLast=b; if (b==TEXT(':')) continue;
b=toupper(b)+nControl;
nx=0; while (b!=rgbMap[nx*2] && nx < CHARSCAN) nx++;
if (nx==CHARSCAN) break;
b=(WORD)rgbMap[(nx*2)+1];
if (nRadix != 10) { switch(b) { case IDC_DEG: case IDC_RAD: case IDC_GRAD: b=IDC_DWORD+(b-IDC_DEG); break; } } // REVIEW NOTE:
// Conversion of IDC_MOD to IDC_PERCENT done in WM_COMMAND
// processing so that keyboard accelerator and paste are
// handled in the same place. The old conversion was broken
// anyway and actually happened in
MappingDone: /* Send the message to the window. */ SendMessage(g_hwndDlg, WM_COMMAND, GET_WM_COMMAND_MPS(b, 0, 1)); /* Note that we may need to apply the "+/-" key (IDC_SIGN)
now. (If it had been applied earlier, it would have been ignored.) Note further that it can't be applied if we have seen only the "-0" of something like "-0.1". */ if(bNeedIDC_SIGN && (IDC_0 != b)) { SendMessage(g_hwndDlg, WM_COMMAND, GET_WM_COMMAND_MPS(IDC_SIGN, 0, 1)); bNeedIDC_SIGN = FALSE; } } GlobalUnlock(hClipData); } } CloseClipboard(); break; }
case IDM_ABOUT: /* Start the About Box. */ if(ShellAbout(g_hwndDlg, rgpsz[IDS_CALC], NULL, LoadIcon(hInst, (LPTSTR)TEXT("SC"))) == -1) MemErrorMessage();
break;
case IDM_SC: case IDM_SSC: { INT nTemp; TCHAR szWinIni[2];
nTemp = (INT) nFunc - IDM_SC; if (nCalc != nTemp) { szWinIni[0] = TEXT('0') + nTemp; szWinIni[1]=0; WriteProfileString(szAppName, TEXT("layout"), szWinIni);
if (hStatBox && !nCalc) SetStat(FALSE);
nCalc = nTemp; InitSciCalc(TRUE); } break; }
case IDM_USE_SEPARATOR: { gbUseSep = !gbUseSep;
CheckMenuItem(g_hDecMenu, IDM_USE_SEPARATOR, MF_BYCOMMAND|(gbUseSep ? MF_CHECKED : MF_UNCHECKED));
if (g_hHexMenu) { CheckMenuItem(g_hHexMenu, IDM_USE_SEPARATOR, MF_BYCOMMAND | \ (gbUseSep ? MF_CHECKED:MF_UNCHECKED)); }
WriteProfileString(szAppName,TEXT("UseSep"), (gbUseSep ? TEXT("1") : TEXT("0")));
break; }
case IDM_HELPTOPICS: HtmlHelp(GetDesktopWindow(), rgpsz[IDS_CHMHELPFILE], HH_DISPLAY_TOPIC, 0L); break; }
return; }
|