⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scicomm.c

📁 计算器源代码c。和windows自带的功能差不多。很多科学计算还没有加入。
💻 C
📖 第 1 页 / 共 2 页
字号:
            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 + -