📄 scicomm.c
字号:
nPrecNum=nTempCom=nLastCom=nOpCode=nParNum=bChangeOp=FALSE;
nFE = FMT_FLOAT; // back to the default number format
bNoPrevEqu=TRUE;
/* clear the paranthesis status box indicator, this will not be
cleared for CENTR */
SetDlgItemText(g_hwndDlg, IDC_PARTEXT, szBlank);
/* fall through */
case IDC_CENTR: /* Clear only temporary values. */
NumObjAssign( &ghnoNum, HNO_ZERO );
if (!nCalc)
{
// Clear the INV, HYP indicators & leave (=xx indicator active
SetBox (IDC_INV, bInv=FALSE);
SetBox (IDC_HYP, bHyp=FALSE);
}
bError=FALSE;
CIO_vClear(&gcio);
gbRecord = TRUE;
DisplayNum ();
break;
case IDC_STAT: /* Shift focus to Statistix Box if it's active. */
if (hStatBox)
SetFocus(hStatBox);
else
SetStat (TRUE);
break;
case IDC_BACK:
// Divide number by the current radix and truncate.
// Only allow backspace if we're recording.
if (gbRecord)
{
if (!CIO_bBackspace(&gcio))
MessageBeep(0);
DisplayNum();
}
else
MessageBeep(0);
break;
/* EQU enables the user to press it multiple times after and */
/* operation to enable repeats of the last operation. I don't */
/* know if I can explain what the hell I did here... */
case IDC_EQU:
do {
// BUGBUG: a static HNUMOBJ will cause a memory leak as it won't get freed
static HNUMOBJ hnoHold;
/* Last thing keyed in was an operator. Lets do the op on*/
/* a duplicate of the last entry. */
if ((nLastCom >= IDC_AND) && (nLastCom <= IDC_PWR))
NumObjAssign( &ghnoNum, ghnoLastNum );
if (nOpCode) /* Is there a valid operation around? */
{
/* If this is the first EQU in a string, set hnoHold=ghnoNum */
/* Otherwise let ghnoNum=hnoTemp. This keeps ghnoNum constant */
/* through all EQUs in a row. */
if (bNoPrevEqu)
NumObjAssign(&hnoHold, ghnoNum);
else
NumObjAssign(&ghnoNum, hnoHold);
/* Do the current or last operation. */
DoOperation (nOpCode, &ghnoNum, ghnoLastNum);
NumObjAssign(&ghnoLastNum, ghnoNum );
/* Check for errors. If this wasn't done, DisplayNum */
/* would immediately overwrite any error message. */
if (!bError)
DisplayNum ();
/* No longer the first EQU. */
bNoPrevEqu=FALSE;
}
else if (!bError)
DisplayNum();
if (nPrecNum==0 || nCalc==1)
break;
nOpCode=nPrecOp[--nPrecNum];
if (NumObjOK( ghnoPrecNum[nPrecNum] ))
NumObjAssign(&ghnoLastNum , ghnoPrecNum[nPrecNum]);
else
NumObjAssign(&ghnoLastNum, HNO_ZERO);
bNoPrevEqu=TRUE;
} while (nPrecNum >= 0);
bChangeOp=FALSE;
break;
case IDC_OPENP:
case IDC_CLOSEP:
nx=0;
if (wParam==IDC_OPENP)
nx=1;
// -IF- the Paren holding array is full and we try to add a paren
// -OR- the paren holding array is empty and we try to remove a
// paren
// -OR- the the precidence holding array is full
if ((nParNum >= 25 && nx) || (!nParNum && !nx)
|| ( (nPrecNum >= 25 && nPrecOp[nPrecNum-1]!=0) ) )
{
MessageBeep(0);
break;
}
if (nx)
{
/* Open level of parentheses, save number and operation. */
NumObjAssign( &ghnoParNum[nParNum], ghnoLastNum);
nOp[nParNum++]=nOpCode;
/* save a special marker on the precedence array */
nPrecOp[nPrecNum++]=0 ;
NumObjAssign( &ghnoLastNum, HNO_ZERO );
nTempCom=0;
nOpCode=IDC_ADD;
}
else
{
/* Get the operation and number and return result. */
DoOperation (nOpCode, &ghnoNum, ghnoLastNum);
/* now process the precedence stack till we get to an
opcode which is zero. */
while (nOpCode = nPrecOp[--nPrecNum])
{
if (NumObjOK( ghnoPrecNum[nPrecNum] ))
NumObjAssign(&ghnoLastNum , ghnoPrecNum[nPrecNum]);
else
NumObjAssign(&ghnoLastNum, HNO_ZERO);
DoOperation (nOpCode, &ghnoNum, ghnoLastNum);
}
/* now get back the operation and opcode at the begining
of this paranthesis pair */
nParNum -= 1;
NumObjAssign( &ghnoLastNum, ghnoParNum[nParNum] );
nOpCode=nOp[nParNum];
/* if nOpCode is a valid operator then set bChangeOp to
be true else set it false */
if (nOpCode)
bChangeOp=TRUE;
else
bChangeOp=FALSE ;
}
/* Set the "(=xx" indicator. */
lstrcpy(szJunk, TEXT("(="));
lstrcat(szJunk, UToDecT(nParNum, szTemp));
SetDlgItemText(g_hwndDlg, IDC_PARTEXT,
(nParNum) ? (szJunk) : (szBlank));
if (bError)
break;
if (nx)
{
/* Build a display string of nParNum "("'s. */
for (nx=0; nx < nParNum; nx++)
szJunk[nx]=TEXT('(');
szJunk[nx]=0; /* Null-terminate. */
SetDlgItemText(g_hwndDlg, IDC_DISPLAY, szJunk);
bChangeOp=FALSE;
}
else
DisplayNum ();
break;
case IDM_QWORD:
case IDM_DWORD:
case IDM_WORD:
case IDM_BYTE:
case IDM_DEG:
case IDM_RAD:
case IDM_GRAD:
if (!F_INTMATH())
{
// in decimal mode, these buttons simply set a flag which is
// passed to the ratpak to handle angle conversions
if (xwParam(IDM_DEG, IDM_GRAD))
{
nDecMode = (ANGLE_TYPE)(wParam - IDM_DEG);
CheckMenuRadioItem(GetSubMenu(GetMenu(g_hwndDlg), 1),
IDM_DEG, IDM_GRAD, IDM_DEG+nDecMode,
MF_BYCOMMAND);
CheckRadioButton(g_hwndDlg, IDC_DEG, IDC_GRAD,
IDC_DEG+nDecMode);
}
}
else
{
if (xwParam(IDM_DEG, IDM_GRAD))
{
// if in hex mode, but we got a decimal key press this
// likely is the accelorator. map this to the correct key
wParam=IDM_DWORD+(wParam-IDM_DEG);
}
if ( gbRecord )
{
CIO_vConvertToNumObj(&ghnoNum, &gcio);
gbRecord = FALSE;
}
// Compat. mode BaseX: Qword, Dword, Word, Byte
nHexMode = (int)(wParam - IDM_QWORD);
switch (nHexMode)
{
case 0: dwWordBitWidth = 64; break;
case 1: dwWordBitWidth = 32; break;
case 2: dwWordBitWidth = 16; break;
case 3: dwWordBitWidth = 8; break;
default:
ASSERT( 0 ); // Invalid Word Size
break;
}
// different wordsize means the new wordsize determines
// the precision
BaseOrPrecisionChanged();
CheckMenuRadioItem(GetSubMenu(GetMenu(g_hwndDlg), 1),
IDM_QWORD, IDM_BYTE, IDM_QWORD+nHexMode,
MF_BYCOMMAND);
CheckRadioButton(g_hwndDlg, IDC_QWORD, IDC_BYTE,
IDC_QWORD+nHexMode);
}
// BUGBUG: the call to display number is what actually does the
// chop. it would make more sense to do the chop here when the
// wordsize changes. the chop must be done when a different
// wordsize is selected AND when the base is changed to non-decimal
DisplayNum();
break;
case IDC_SIGN:
// Change the sign.
if (gbRecord)
CIO_vToggleSign(&gcio);
else {
NumObjNegate( &ghnoNum );
}
DisplayNum();
break;
case IDC_RECALL:
/* Recall immediate memory value. */
NumObjAssign( &ghnoNum, ghnoMem );
DisplayNum ();
break;
case IDC_MPLUS:
/* MPLUS adds ghnoNum to immediate memory and kills the "mem" */
/* indicator if the result is zero. */
addrat( &ghnoMem, ghnoNum);
SetDlgItemText(g_hwndDlg,IDC_MEMTEXT,
!NumObjIsZero(ghnoMem) ? (TEXT(" M")):(szBlank));
break;
case IDC_STORE:
case IDC_MCLEAR:
if (wParam==IDC_STORE)
{
NumObjAssign( &ghnoMem, ghnoNum );
}
else
{
NumObjAssign( &ghnoMem, HNO_ZERO );
}
SetDlgItemText(g_hwndDlg,IDC_MEMTEXT,
!NumObjIsZero(ghnoMem) ? (TEXT(" M")):(szBlank));
break;
case IDC_PI:
if (!F_INTMATH())
{
/* Return PI if bInv==FALSE, or 2PI if bInv==TRUE. */
if (bInv)
NumObjAssign( &ghnoNum, HNO_2PI );
else
NumObjAssign( &ghnoNum, HNO_PI );
DisplayNum();
SetBox(IDC_INV, bInv=FALSE);
}
else
MessageBeep(0);
break;
case IDC_FE:
// Toggle exponential notation display.
nFE = NUMOBJ_FMT(!(int)nFE);
DisplayNum();
break;
case IDC_EXP:
if (gbRecord && !F_INTMATH())
if (CIO_bExponent(&gcio))
{
DisplayNum();
break;
}
MessageBeep(0);
break;
case IDC_PNT:
if (gbRecord && !F_INTMATH()) {
if (CIO_bAddDecimalPt(&gcio)) {
DisplayNum();
break;
}
}
MessageBeep(0);
break;
case IDC_INV:
SetBox((int)wParam, bInv=!bInv);
break;
case IDC_HYP:
SetBox((int)wParam, bHyp=!bHyp);
break;
}
SetWaitCursor(FALSE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -