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

📄 winecalc.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
 * WineCalc (winecalc.c)
 *
 * Copyright 2003 James Briggs
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <stdio.h> // sprintf
#include <math.h>
#include <stdlib.h>

#include <windows.h>
#include <tchar.h>
// #include <commctrl.h>

#include "winecalc.h"
#include "dialog.h"
#include "stats.h"
#include "resource.h"

// lame M$ math library doesn't support hyp functions
//#ifdef _MSC_VER
#define atanh(X) atan(X)
#define asinh(X) asin(X)
#define acosh(X) acos(X)
//#endif

// How winecalc works
//
// 1. In the original calculator, numbers are "extended precision".
//    We emulate with calcfloat (calcfloat floating point) for now.
//    Note that recent M$ compilers 5.0 and later do not implement double float,
//    and do not support 80-bit numbers. Max width is 64-bits.
//
// 2. 4 temp areas:
//
//    i) current edit buffer value for keystrokes
//   ii) computed value area for last computation
//  iii) memory area for MR, MC, MS, M+
//   iv) formatted display buffer
//
// 3. Memory Store works off current buffer, not value
//
// 4. display limit is 32 numbers plus 10 commas plus one period = 43 characters
//
// 5. original calc is better called SciCalc and saves settings in win.ini:
//
// [SciCalc]
// layout=1 (0 = scientific mode, 1 = basic mode)
// UseSep=1 (0 = no digits separator, 1 = enable digits separator)
//
// 6. Window Menus
//
//    The menus know their own states, so we don't need to track them
//    When switching to Standard Calculator Mode, number base is changed to Decimal and Trig Mode to Degrees,
//    but Word Size Mode is unchanged
//
// 7. It would be nice to add command line parsing for batch files
//

// various display error messages

static TCHAR err_invalid        [CALC_BUF_SIZE];
static TCHAR err_divide_by_zero [CALC_BUF_SIZE];
static TCHAR err_undefined      [CALC_BUF_SIZE];

// calculator state is kept here

CALC calc;

static RECT rFiller;

static int keys[CALC_NS_COUNT]['f'+1]; // note: sparse array

// map from button press to calc[] index
//  0,        ...                      9,  A,  B,  C,  D,  E,  F,FE,DMS,SIN,COS,TAN,EXP, PI
static const int h[] = {
    0, 0, 33, 34, 21, 22, 23, 10, 11, 12, 54, 55, 56 ,57, 58 ,59, 6, 17, 28, 39, 50, 18, 53 };

// enable status of various buttons on sci mode depending on number base
static const int btn_toggle[CALC_NS_COUNT][TOGGLE_COUNT] =
//    0, ...                     9, A, B, C, D, E, F,FE,DMS,SIN,COS,TAN,EXP,PI
{
    { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 },
    { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
    { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ,0 }
};

static int hms[] = { 64, 65, 66 };
static int hws[] = { 69, 70, 71, 72 };

static int sta[] = { 16, 27, 38, 49 };

static HMENU menus[3];

static TCHAR appname[40];

static int debug;

int parse(int wParam, int lParam);

HWND hWndDlgStats;

extern HWND hWndListBox;

HINSTANCE hInstance;

int WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR cmdline, int cmdshow )
{
    MSG msg;
    WNDCLASS wc;
    HWND hWnd;
    HACCEL haccel;
    TCHAR s[CALC_BUF_SIZE];
    int r;

    hInstance = hInst;

    r = GetProfileString(TEXT("SciCalc"),
                         TEXT("layout"),
                         TEXT("0"),
                         s,
                         CALC_BUF_SIZE
    );

    calc.sciMode  = _ttoi(s);

    if (calc.sciMode != 0 &&
        calc.sciMode != 1)
        calc.sciMode = 1; // Standard Mode

    r = GetProfileString(TEXT("SciCalc"),
                         TEXT("UseSep"),
                         TEXT("0"),
                         s,
                         CALC_BUF_SIZE
        );

    calc.digitGrouping  = _ttoi(s);

    if (calc.digitGrouping != 0 &&
        calc.digitGrouping != 1)
        calc.digitGrouping = 1;

    calc.new      = 1; // initialize struct values

    if (!LoadString( hInst, IDS_APPNAME,            appname,            sizeof(appname) / sizeof(appname[0])))
        exit(1);
    if (!LoadString( hInst, IDS_ERR_INVALID_INPUT,  err_invalid,        sizeof(err_invalid) / sizeof(err_invalid[0])))
        exit(1);
    if (!LoadString( hInst, IDS_ERR_DIVIDE_BY_ZERO, err_divide_by_zero, sizeof(err_divide_by_zero) / sizeof(err_divide_by_zero[0])))
        exit(1);
    if (!LoadString( hInst, IDS_ERR_UNDEFINED,      err_undefined,      sizeof(err_undefined) / sizeof(err_undefined[0])))
        exit(1);

    wc.style         = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc   = MainProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInst;
    wc.hIcon         = LoadIcon(hInst, MAKEINTRESOURCE(IDI_CALCICON));
    wc.hCursor       = LoadCursor( NULL, IDI_APPLICATION );
    wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = appname;

    if (!RegisterClass(&wc)) exit(1);

    hWnd = CreateWindow( appname,
        appname,
        WS_CLIPSIBLINGS | (WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX),
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        calc.sciMode ? CALC_STANDARD_WIDTH :  CALC_SCIENTIFIC_WIDTH,
        calc.sciMode ? CALC_STANDARD_HEIGHT : CALC_SCIENTIFIC_HEIGHT,
        NULL,
        NULL,
        hInst,
        NULL );

    if (!hWnd)
        exit(1);

    ShowWindow( hWnd, cmdshow );
    UpdateWindow( hWnd );

    if (!(haccel = LoadAccelerators(hInst, TEXT("MAIN_MENU"))))
        exit(1);

    while( GetMessage(&msg, NULL, 0, 0) ) {
        if (hWndDlgStats == 0 || !IsDialogMessage(hWndDlgStats, &msg)) {
           if (!TranslateAccelerator( hWnd, haccel, &msg )) {
              TranslateMessage( &msg );
              DispatchMessage( &msg );
            }
        }
    }

    return msg.wParam;
}

LRESULT WINAPI MainProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;

    switch (msg) {

    case WM_CREATE:
        calc.hInst = ((LPCREATESTRUCT) lParam)->hInstance;
        calc.hWnd = hWnd;

        InitLuts();
        InitCalc( &calc );
        InitMenus(calc.hInst);

        if (calc.sciMode)
            SetMenu(hWnd, menus[MENU_STD]);
        else
            SetMenu(hWnd, menus[MENU_SCIMS]);

        calc_buffer_display(&calc);

        return 0;

    case WM_PAINT:
        {
            HDC hMemDC;

            hdc = BeginPaint( hWnd, &ps );
            hMemDC = CreateCompatibleDC( hdc );

            DrawCalc( hdc, hMemDC, &ps, &calc );

            DeleteDC( hMemDC );
            EndPaint( hWnd, &ps );

            return 0;
        }

    case WM_MOVE:
        calc.pos.x = (unsigned) LOWORD(lParam);
        calc.pos.y = (unsigned) HIWORD(lParam);
        return 0;

    case WM_DESTROY:
        {
            int r;
            TCHAR s[CALC_BUF_SIZE];

            _stprintf(s, TEXT("%d"), calc.sciMode);
            r = WriteProfileString(TEXT("SciCalc"), TEXT("layout"), s);

            _stprintf(s, TEXT("%d"), calc.digitGrouping);
            r = WriteProfileString(TEXT("SciCalc"), TEXT("UseSep"), s);
        }

        DestroyCalc( &calc );
		DestroyMenus();
        PostQuitMessage( 0 );
        return 0;

    case WM_KEYDOWN:
        switch (wParam) {

        case VK_F1:
            calc.next = 1;
            MessageBox(hWnd, TEXT("No Help Available"), TEXT("Windows Help"), MB_OK);
            return 0;

        case VK_F2: // DWORD

            calc.next = 1;
            if (!calc.sciMode) {
                if (calc.numBase == NBASE_DECIMAL)
                    SendMessage(hWnd, WM_COMMAND, ID_CALC_MS_DEGREES, lParam);
                else
                    SendMessage(hWnd, WM_COMMAND, ID_CALC_WS_DWORD, lParam);
            }
            return 0;

        case VK_F3: // WORD

            calc.next = 1;
            if (!calc.sciMode) {
                if (calc.numBase == NBASE_DECIMAL)
                    SendMessage(hWnd, WM_COMMAND, ID_CALC_MS_RADIANS, lParam);
                else
                    SendMessage(hWnd, WM_COMMAND, ID_CALC_WS_WORD, lParam);
            }
            return 0;

        case VK_F4: // Byte

            // Grad
            calc.next = 1;
            if (!calc.sciMode) {
                if (calc.numBase == NBASE_DECIMAL)
                    SendMessage(hWnd, WM_COMMAND, ID_CALC_MS_GRADS, lParam);
                else
                    SendMessage(hWnd, WM_COMMAND, ID_CALC_WS_BYTE, lParam);
            }
            return 0;

        case VK_F5: // Hex

            calc.next = 1;
            if (!calc.sciMode)
                SendMessage(hWnd, WM_COMMAND, ID_CALC_NS_HEX, lParam);
            return 0;

        case VK_F6: // Decimal

            calc.next = 1;
            if (!calc.sciMode)
                SendMessage(hWnd, WM_COMMAND, ID_CALC_NS_DEC, lParam);
            return 0;

        case VK_F7: // Octal

            calc.next = 1;
            if (!calc.sciMode)
                SendMessage(hWnd, WM_COMMAND, ID_CALC_NS_OCT, lParam);
            return 0;

        case VK_F8: // Binary

            calc.next = 1;
            if (!calc.sciMode)
                SendMessage(hWnd, WM_COMMAND, ID_CALC_NS_BIN, lParam);
            return 0;

        case VK_F12: // QWORD

            calc.next = 1;
            if (!calc.sciMode)
                SendMessage(hWnd, WM_COMMAND, ID_CALC_WS_QWORD, lParam);
            return 0;

        case VK_F9: // +/-

            if (!calc.sciMode)
                SendMessage(hWnd, WM_CHAR, 'Z', lParam);
            return 0;

        case VK_INSERT: // Dat
            calc.next = 1;
            SendMessage(hWndListBox, LB_INSERTSTRING, -1, (LPARAM)calc.buffer);
            InvalidateRect(hWndDlgStats, NULL, TRUE); // update list count at bottom edge of dialog
            UpdateWindow(hWndDlgStats);
            return 0;

⌨️ 快捷键说明

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