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

📄 scistat.c

📁 计算器源代码c。和windows自带的功能差不多。很多科学计算还没有加入。
💻 C
字号:
/**************************************************************************/
/*** SCICALC Scientific Calculator for Windows 3.00.12                  ***/
/*** By Kraig Brockschmidt, Microsoft Co-op, Contractor, 1988-1989      ***/
/*** (c)1989 Microsoft Corporation.  All Rights Reserved.               ***/
/***                                                                    ***/
/*** scistat.c                                                          ***/
/***                                                                    ***/
/*** Functions contained:                                               ***/
/***    SetStat--Enable/disable the stat box, show or destroy the       ***/
/***        modeless dialog box.                                        ***/
/***    StatBoxProc--procedure for the statbox.  Handles the RET, LOAD, ***/
/***        CD, and CAD buttons, and handles double-clicks.             ***/
/***    StatFunctions--routines for DATA, SUM, AVE, and deviations.     ***/
/***                                                                    ***/
/*** Functions called:                                                  ***/
/***    SetStat                                                         ***/
/***                                                                    ***/
/*** Last modification Thu  26-Jan-1990                                 ***/
/*** -by- Amit Chatterjee [amitc]  26-Jan-1990.                         ***/
/*** Following bug fix was made:                                        ***/
/***                                                                    ***/
/*** Bug # 8499.                                                        ***/
/*** While fixing numbers in the stat array in memory, instead of using ***/
/*** the following for statement:                                       ***/
/***      for (lIndex=lData; lIndex < lStatNum - 1 ; lIndex++)          ***/
/*** the fix was to use:                                                ***/
/***      for (lIndex=lData; lIndex < lStatNum ; lIndex++)              ***/
/*** This is because lStatNum has already been decremented to care of   ***/
/*** a number being deleted.                                            ***/
/*** This fix will be in build 1.59.                                    ***/
/**************************************************************************/

#include "scicalc.h"
#include "calchelp.h"
#include "unifunc.h"

#define GMEMCHUNK 96L  /* Amount of memory to allocate at a time.         */

extern HNUMOBJ  ghnoNum;
extern HWND     hStatBox, hListBox, hEdit;
extern TCHAR    szBlank[6], *rgpsz[CSTRINGS];
extern LPTSTR   gpszNum;
extern INT      nTempCom;
extern BOOL     gbRecord;

extern BOOL FireUpPopupMenu( HWND, HINSTANCE, LPARAM );

GLOBALHANDLE    hgMem, hMem;   /* Coupla global memory handles.        */
BOOL            bFocus=TRUE;
LONG            lStatNum=0,    /* Number of data.                      */
                lReAllocCount; /* Number of data before ReAlloc.       */
HNUMOBJ *       lphnoStatNum;   /* Holding place for stat data.         */


/* Initiate or destroy the Statistics Box.                                */

VOID  APIENTRY SetStat (BOOL bOnOff)
{
    static int aStatOnlyKeys[] = { IDC_AVE, IDC_B_SUM, IDC_DEV, IDC_DATA };
    int i;

    if (bOnOff)
    {
        /* Create.                                                        */
        lReAllocCount=GMEMCHUNK/sizeof(ghnoNum); /* Set up lReAllocCount.   */

        /* Start the box.                                                 */
        hStatBox=CreateDialog(hInst, MAKEINTRESOURCE(IDD_SB), NULL, StatBoxProc);

        /* Get a handle on some memory (16 bytes initially.               */
        if (!(hgMem=GlobalAlloc(GHND, 0L)))
        {
            StatError();
            SendMessage(hStatBox, WM_COMMAND, GET_WM_COMMAND_MPS(ENDBOX, 0, 0));
            return;
        }
        ShowWindow(hStatBox, SW_SHOWNORMAL);
    }
    else
    {
        int lIndex;

        if ( hStatBox )
        {
            DestroyWindow(hStatBox);

            // Free the numobj's
            lphnoStatNum=(HNUMOBJ *)GlobalLock(hgMem);
            for( lIndex = 0; lIndex < lStatNum; lIndex++ )
                NumObjDestroy( &lphnoStatNum[lIndex] );
            GlobalUnlock(hgMem);
            lStatNum = 0;

            GlobalFree(hgMem);  /* Free up the memory.                        */
            hStatBox=0;         /* Nullify handle.                            */
        }
    }

    // set the active state of the Ave, Sum, s, and Dat buttons
    for ( i=0; i<ARRAYSIZE(aStatOnlyKeys); i++)
        EnableWindow( GetDlgItem(g_hwndDlg, aStatOnlyKeys[i]), bOnOff );

    return;
}



/* Windows procedure for the Dialog Statistix Box.                        */
INT_PTR FAR APIENTRY StatBoxProc (
     HWND           hStatBox,
     UINT           iMessage,
     WPARAM         wParam,
     LPARAM         lParam)
{
    static LONG lData=-1;  /* Data index in listbox.                   */
    LONG        lIndex;    /* Temp index for counting.                 */
    DWORD       dwSize;    /* Holding place for GlobalSize.            */
    static DWORD    control[] = {
        IDC_STATLIST,   CALC_SCI_STATISTICS_VALUE,
        IDC_CAD,        CALC_SCI_CAD,
        IDC_CD,         CALC_SCI_CD,
        IDC_LOAD,       CALC_SCI_LOAD,
        IDC_FOCUS,      CALC_SCI_RET,
        IDC_NTEXT,      CALC_SCI_NUMBER,
        IDC_NUMTEXT,    CALC_SCI_NUMBER,
        0,              0 };

    switch (iMessage)
    {
        case WM_HELP:
        {
            LPHELPINFO phi = (LPHELPINFO)lParam;
            HWND hwndChild = GetDlgItem(hStatBox,phi->iCtrlId);
            WinHelp( hwndChild, rgpsz[IDS_HELPFILE], HELP_WM_HELP, (ULONG_PTR)(void *)control );
            return TRUE;
        }

        case WM_CONTEXTMENU:
            WinHelp( (HWND)wParam, rgpsz[IDS_HELPFILE], HELP_CONTEXTMENU, (ULONG_PTR)(void *)control );
            return TRUE;

        case WM_CLOSE:
            SetStat(FALSE);

        case WM_DESTROY:
            lStatNum=0L; /* Reset data count.                     */
            return(TRUE);

        case WM_INITDIALOG:
            /* Get a handle to this here things listbox display.          */
            hListBox=GetDlgItem(hStatBox, IDC_STATLIST);
            return TRUE;

        case WM_COMMAND:
            /* Check for LOAD or double-click and recall number if so.    */

            if (GET_WM_COMMAND_CMD(wParam, lParam)==LBN_DBLCLK ||
                        GET_WM_COMMAND_ID(wParam, lParam)==IDC_LOAD)
            {
                /* Lock data, get pointer to it, and get index of item.   */
                lphnoStatNum=(HNUMOBJ *)GlobalLock(hgMem);
                lData=(LONG)SendMessage(hListBox,LB_GETCURSEL,0,0L);

                if (lStatNum>0 && lData !=LB_ERR)
                    // SPEED: REVIEW: can we use a pointer instead of Assign?
                    NumObjAssign( &ghnoNum, lphnoStatNum[lData]);  /* Get the data.         */
                else
                    MessageBeep(0); /* Cannodo if no data nor selection.  */

                // Cancel kbd input mode
                gbRecord = FALSE;

                DisplayNum ();
                nTempCom = 32;
                GlobalUnlock(hgMem); /* Let the memory move!              */
                break;
            }

            // switch (wParam)
            switch (GET_WM_COMMAND_ID(wParam, lParam))
            {
                case IDC_FOCUS:
                    /* Change focus back to main window.  Primarily for   */
                    /* use with the keyboard.                             */
                    SetFocus(g_hwndDlg);
                    return (TRUE);

                case IDC_CD:
                    /* Clear the selected item from the listbox.          */
                    /* Get the index and a pointer to the data.           */
                    lData=(LONG)SendMessage(hListBox,LB_GETCURSEL,0,0L);

                    /* Check for possible error conditions.               */
                    if (lData==LB_ERR || lData > lStatNum-1 || lStatNum==0)
                    {
                        MessageBeep (0);
                        break;
                    }

                    /* Fix listbox strings.                               */
                    lIndex=(LONG)SendMessage(hListBox, LB_DELETESTRING, (WORD)lData, 0L);

                    if ((--lStatNum)==0)
                        goto ClearItAll;

                    /* Place the highlight over the next one.             */
                    if (lData<lIndex || lIndex==0)
                        lIndex=lData+1;

                    SendMessage(hListBox, LB_SETCURSEL, (WORD)lIndex-1, 0L);

                    lphnoStatNum=(HNUMOBJ *)GlobalLock(hgMem);

                    /* Fix numbers in memory.                             */
                    for (lIndex=lData; lIndex < lStatNum ; lIndex++)
                    {
                        NumObjAssign( &lphnoStatNum[lIndex], lphnoStatNum[lIndex+1] );
                    }

                    GlobalUnlock(hgMem);  /* Movin' again.                */

                    /* Update the number by the "n=".                     */
                    SetDlgItemInt(hStatBox, IDC_NUMTEXT, lStatNum, FALSE);

                    dwSize=(DWORD)GlobalSize(hgMem); /* Get size of memory block.*/

                    /* Unallocate memory if not needed after data removal.*/
                    /* hMem is used so we don't possibly trach hgMem.     */
                    if ((lStatNum % lReAllocCount)==0)
                        if ((hMem=GlobalReAlloc(hgMem, dwSize-GMEMCHUNK, GMEM_ZEROINIT)))
                            hgMem=hMem;
                    return(TRUE);

                case IDC_CAD:
ClearItAll:
                    /* Nuke it all!                                       */
                    SendMessage(hListBox, LB_RESETCONTENT, 0L, 0L);
                    SetDlgItemInt(hStatBox, IDC_NUMTEXT, 0, FALSE);;

                    // Free the numobj's
                    lphnoStatNum=(HNUMOBJ *)GlobalLock(hgMem);
                    for( lIndex = 0; lIndex < lStatNum; lIndex++ )
                        NumObjDestroy( &lphnoStatNum[lIndex] );
                    GlobalUnlock(hgMem);

                    GlobalFree(hgMem); /* Drop the memory.                */
                    lStatNum = 0;
                    hgMem=GlobalAlloc(GHND, 0L); /* Get a CLEAN slate.    */
                    return(TRUE);
            }
    }
    return (FALSE);
}



/* Routine for functions AVE, SUM, DEV, and DATA.                         */

VOID  APIENTRY StatFunctions (WPARAM wParam)
    {
    LONG           lIndex; /* Temp index.                                 */
    DWORD          dwSize; /* Return value for GlobalSize.                */

    switch (wParam)
    {
        case IDC_DATA: /* Add current fpNum to listbox.                       */
            if ((lStatNum % lReAllocCount)==0)
            {
                /* If needed, allocate another 96 bytes.                  */

                dwSize=(DWORD)GlobalSize(hgMem);
                if (StatAlloc (1, dwSize))
                {
                    GlobalCompact((DWORD)-1L);
                    if (StatAlloc (1, dwSize))
                    {
                        StatError ();
                        return;
                    }
                }
                hgMem=hMem;
            }

            /* Add the display string to the listbox.                     */
            hListBox=GetDlgItem(hStatBox, IDC_STATLIST);

            lIndex=StatAlloc (2,0L);
            if (lIndex==LB_ERR || lIndex==LB_ERRSPACE)
            {
                GlobalCompact((DWORD)-1L);

                lIndex=StatAlloc (2,0L);
                if (lIndex==LB_ERR || lIndex==LB_ERRSPACE)
                {
                    StatError ();
                    return;
                }
            }

            /* Highlight last entered string.                             */
            SendMessage(hListBox, LB_SETCURSEL, (WORD)lIndex, 0L);

            /* Add the number and increase the "n=" value.                */
            lphnoStatNum=(HNUMOBJ *)GlobalLock(hgMem);

            NumObjAssign( &lphnoStatNum[lStatNum], ghnoNum );

            SetDlgItemInt(hStatBox, IDC_NUMTEXT, ++lStatNum, FALSE);
            break;

        case IDC_AVE: /* Calculate averages and sums.                         */
        case IDC_B_SUM: {
            DECLARE_HNUMOBJ( hnoTemp );

            lphnoStatNum=(HNUMOBJ *)GlobalLock(hgMem);

            /* Sum the numbers or squares, depending on bInv.             */
            NumObjAssign( &ghnoNum, HNO_ZERO );

            for (lIndex=0L; lIndex < lStatNum; lIndex++)
            {
                NumObjAssign( &hnoTemp, lphnoStatNum[lIndex] );
                if (bInv)
                {
                    DECLARE_HNUMOBJ( hno );
                    /* Get sum of squares.      */
                    NumObjAssign( &hno, hnoTemp );
                    mulrat( &hno, hnoTemp );
                    addrat( &ghnoNum, hno );
                    NumObjDestroy( &hno );
                }
                else
                {
                    /* Get sum.                          */
                    addrat( &ghnoNum, hnoTemp );
                }
            }

            if (wParam==IDC_AVE) /* Divide by lStatNum=# of items for mean.   */
            {
                DECLARE_HNUMOBJ( hno );
                if (lStatNum==0)
                {
                    DisplayError (SCERR_DIVIDEZERO);
                    break;
                }
                NumObjSetIntValue( &hno, lStatNum );
                divrat( &ghnoNum, hno );
                NumObjDestroy( &hno );
            }
            NumObjDestroy( &hnoTemp );
            /* Fall out for sums.                                         */
            break;
        }

        case IDC_DEV: { /* Calculate deviations.                                */
            DECLARE_HNUMOBJ(hnoTemp);
            DECLARE_HNUMOBJ(hnoX);
            DECLARE_HNUMOBJ( hno );

            if (lStatNum <=1) /* 1 item or less, NO deviation.            */
            {
                NumObjAssign( &ghnoNum, HNO_ZERO );
                return;
            }

            /* Get sum and sum of squares.                                */
            lphnoStatNum=(HNUMOBJ *)GlobalLock(hgMem);

            NumObjAssign( &ghnoNum, HNO_ZERO );
            NumObjAssign( &hnoTemp, HNO_ZERO );

            for (lIndex=0L; lIndex < lStatNum; lIndex++)
            {

                NumObjAssign(&hnoX, lphnoStatNum[lIndex]);

                addrat( &hnoTemp, hnoX );

                NumObjAssign( &hno, hnoX );
                mulrat( &hno, hnoX );
                addrat( &ghnoNum, hno );

            }


            /*      x

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -