-#include "calc.h"
+/*
+ * ReactOS Calc (main program)
+ *
+ * Copyright 2007-2017, Carlo Bramini
+ *
+ * This program 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 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
-#include <winbase.h>
-#include <wingdi.h>
-#include <winreg.h>
+#include "calc.h"
-#define HTMLHELP_PATH(_pt) TEXT("%systemroot%\\Help\\calc.chm::") TEXT(_pt)
+#define HTMLHELP_PATH(_pt) _T("%systemroot%\\Help\\calc.chm::") _T(_pt)
#define MAKE_BITMASK4(_show_b16, _show_b10, _show_b8, _show_b2) \
(((_show_b2) << 0) | \
#define BITMASK_OCT_MASK 0x02
#define BITMASK_BIN_MASK 0x01
-#define CALC_CLR_RED 0x000000FF
-#define CALC_CLR_BLUE 0x00FF0000
-#define CALC_CLR_PURP 0x00FF00FF
+#define CALC_CLR_RED RGB(0xFF, 0x00, 0x00)
+#define CALC_CLR_BLUE RGB(0x00, 0x00, 0xFF)
+#define CALC_CLR_PURP RGB(0xFF, 0x00, 0xFF)
typedef struct {
CHAR key; // Virtual key identifier
IDC_BUTTON_MULT, // RPN_OPERATOR_MULT
IDC_BUTTON_DIV, // RPN_OPERATOR_DIV
IDC_BUTTON_MOD, // RPN_OPERATOR_MOD
+ IDC_BUTTON_XeY, // RPN_OPERATOR_POW
+ IDC_BUTTON_XrY, // RPN_OPERATOR_SQR
};
typedef void (*rpn_callback1)(calc_number_t *);
rpn_callback1 inv_hyp;
} function_table_t;
-static void run_pow(calc_number_t *number);
-static void run_sqr(calc_number_t *number);
static void run_fe(calc_number_t *number);
static void run_dat_sta(calc_number_t *number);
static void run_mp(calc_number_t *c);
{ IDC_BUTTON_LN, MODIFIER_INV, 1, rpn_ln, rpn_exp, NULL, NULL },
{ IDC_BUTTON_LOG, MODIFIER_INV, 1, rpn_log, rpn_exp10, NULL, NULL },
{ IDC_BUTTON_NF, 0, 1, rpn_fact, NULL, NULL, NULL },
- { IDC_BUTTON_AVE, 0, 0, rpn_ave, NULL, NULL, NULL },
- { IDC_BUTTON_SUM, 0, 0, rpn_sum, NULL, NULL, NULL },
+ { IDC_BUTTON_AVE, MODIFIER_INV, 0, rpn_ave, rpn_ave2, NULL, NULL },
+ { IDC_BUTTON_SUM, MODIFIER_INV, 0, rpn_sum, rpn_sum2, NULL, NULL },
{ IDC_BUTTON_S, MODIFIER_INV, 0, rpn_s_m1, rpn_s, NULL, NULL },
- { IDC_BUTTON_XeY, MODIFIER_INV, 1, run_pow, run_sqr, NULL, NULL },
{ IDC_BUTTON_SQRT, MODIFIER_INV, 1, rpn_sqrt, NULL, NULL, NULL },
{ IDC_BUTTON_DMS, MODIFIER_INV, 1, rpn_dec2dms, rpn_dms2dec, NULL, NULL },
{ IDC_BUTTON_FE, 0, 1, run_fe, NULL, NULL, NULL },
{ IDC_BUTTON_DAT, 0, 1, run_dat_sta, NULL, NULL, NULL, },
- { IDC_BUTTON_MP, MODIFIER_INV, 1, run_mp, run_mm, NULL, NULL, },
- { IDC_BUTTON_MS, MODIFIER_INV, 1, run_ms, run_mw, NULL, NULL, },
+ { IDC_BUTTON_MP, MODIFIER_INV|NO_CHAIN, 1, run_mp, run_mm, NULL, NULL, },
+ { IDC_BUTTON_MS, MODIFIER_INV|NO_CHAIN, 1, run_ms, run_mw, NULL, NULL, },
{ IDC_BUTTON_CANC, NO_CHAIN, 0, run_canc, NULL, NULL, NULL, },
{ IDC_BUTTON_RIGHTPAR, NO_CHAIN, 1, run_rpar, NULL, NULL, NULL, },
{ IDC_BUTTON_LEFTPAR, NO_CHAIN, 0, run_lpar, NULL, NULL, NULL, },
};
+/* Sub-classing information for theming support */
+typedef struct{
+ BOOL bHover;
+ WNDPROC oldProc;
+} BTNINFO,*LPBTNINFO;
+
+
/*
-*/
+ * Global variable declaration
+ */
-calc_t calc;
+calc_t calc;
-static void load_config(void)
+/* Hot-state info for theming support */
+BTNINFO BtnInfo[255];
+UINT BtnCount;
+
+static void UpdateNumberIntl(void)
{
- TCHAR buf[32];
+ /* Get current user defaults */
+ if (!GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, calc.sDecimal, SIZEOF(calc.sDecimal)))
+ _tcscpy(calc.sDecimal, _T("."));
+
+ if (!GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, calc.sThousand, SIZEOF(calc.sThousand)))
+ _tcscpy(calc.sThousand, _T(","));
+
+ /* get the string lengths */
+ calc.sDecimal_len = _tcslen(calc.sDecimal);
+ calc.sThousand_len = _tcslen(calc.sThousand);
+}
+
+static int LoadRegInt(LPCTSTR lpszApp, LPCTSTR lpszKey, int iDefault)
+{
+ HKEY hKey;
+ int iValue;
DWORD tmp;
-#if _WIN32_WINNT >= 0x0500
- HKEY hKey;
-#endif
- /* Try to load last selected layout */
- GetProfileString(TEXT("SciCalc"), TEXT("layout"), TEXT("0"), buf, SIZEOF(buf));
- if (_stscanf(buf, TEXT("%lu"), &calc.layout) != 1)
- calc.layout = CALC_LAYOUT_STANDARD;
+ if (RegOpenKeyEx(HKEY_CURRENT_USER, lpszApp, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
+ {
+ /* Try to load integer value */
+ tmp = sizeof(int);
- /* Try to load last selected formatting option */
- GetProfileString(TEXT("SciCalc"), TEXT("UseSep"), TEXT("0"), buf, SIZEOF(buf));
- if (_stscanf(buf, TEXT("%lu"), &tmp) != 1)
- calc.usesep = FALSE;
- else
- calc.usesep = (tmp == 1) ? TRUE : FALSE;
+ if (RegQueryValueEx(hKey, lpszKey, NULL, NULL, (LPBYTE)&iValue, &tmp) == ERROR_SUCCESS)
+ iDefault = iValue;
- /* memory is empty at startup */
- calc.is_memory = FALSE;
+ /* close the key */
+ RegCloseKey(hKey);
+ }
-#if _WIN32_WINNT >= 0x0500
- /* empty these values */
- calc.sDecimal[0] = TEXT('\0');
- calc.sThousand[0] = TEXT('\0');
+ return iDefault;
+}
- /* try to open the registry */
- if (RegOpenKeyEx(HKEY_CURRENT_USER,
- TEXT("Control Panel\\International"),
- 0,
- KEY_QUERY_VALUE,
- &hKey) == ERROR_SUCCESS) {
- /* get these values (ignore errors) */
- tmp = sizeof(calc.sDecimal);
- RegQueryValueEx(hKey, TEXT("sDecimal"), NULL, NULL, (LPBYTE)calc.sDecimal, &tmp);
+static void SaveRegInt(LPCTSTR lpszApp, LPCTSTR lpszKey, int iValue)
+{
+ HKEY hKey;
- tmp = sizeof(calc.sThousand);
- RegQueryValueEx(hKey, TEXT("sThousand"), NULL, NULL, (LPBYTE)calc.sThousand, &tmp);
+ if (RegCreateKeyEx(HKEY_CURRENT_USER, lpszApp, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hKey, NULL) == ERROR_SUCCESS)
+ {
+ RegSetValueEx(hKey, lpszKey, 0, REG_DWORD, (const BYTE*)&iValue, sizeof(int));
/* close the key */
RegCloseKey(hKey);
}
- /* if something goes wrong, let's apply the defaults */
- if (calc.sDecimal[0] == TEXT('\0'))
- _tcscpy(calc.sDecimal, TEXT("."));
+}
- if (calc.sThousand[0] == TEXT('\0'))
- _tcscpy(calc.sThousand, TEXT(","));
+static void load_config(void)
+{
+ OSVERSIONINFO osvi;
- /* get the string lengths */
- calc.sDecimal_len = _tcslen(calc.sDecimal);
- calc.sThousand_len = _tcslen(calc.sThousand);
-#else
- /* acquire regional settings */
- calc.sDecimal_len = GetProfileString(TEXT("intl"), TEXT("sDecimal"), TEXT("."), calc.sDecimal, SIZEOF(calc.sDecimal));
- calc.sThousand_len = GetProfileString(TEXT("intl"), TEXT("sThousand"), TEXT(","), calc.sThousand, SIZEOF(calc.sThousand));
-#endif
+ osvi.dwOSVersionInfoSize = sizeof(osvi);
+ GetVersionEx(&osvi);
+
+ switch (osvi.dwPlatformId) {
+ case VER_PLATFORM_WIN32s:
+ case VER_PLATFORM_WIN32_WINDOWS:
+ /* Try to load last selected layout */
+ calc.layout = GetProfileInt(_T("SciCalc"), _T("layout"), CALC_LAYOUT_STANDARD);
+
+ /* Try to load last selected formatting option */
+ calc.usesep = (GetProfileInt(_T("SciCalc"), _T("UseSep"), FALSE)) ? TRUE : FALSE;
+ break;
+
+ default: /* VER_PLATFORM_WIN32_NT */
+ /* Try to load last selected layout */
+ calc.layout = LoadRegInt(_T("SOFTWARE\\Microsoft\\Calc"), _T("layout"), CALC_LAYOUT_STANDARD);
+
+ /* Try to load last selected formatting option */
+ calc.usesep = (LoadRegInt(_T("SOFTWARE\\Microsoft\\Calc"), _T("UseSep"), FALSE)) ? TRUE : FALSE;
+ break;
+ }
+
+ /* memory is empty at startup */
+ calc.is_memory = FALSE;
+
+ /* Get locale info for numbers */
+ UpdateNumberIntl();
}
static void save_config(void)
{
TCHAR buf[32];
+ OSVERSIONINFO osvi;
+
+ osvi.dwOSVersionInfoSize = sizeof(osvi);
+ GetVersionEx(&osvi);
+
+ switch (osvi.dwPlatformId) {
+ case VER_PLATFORM_WIN32s:
+ case VER_PLATFORM_WIN32_WINDOWS:
+ _stprintf(buf, _T("%lu"), calc.layout);
+ WriteProfileString(_T("SciCalc"), _T("layout"), buf);
+ WriteProfileString(_T("SciCalc"), _T("UseSep"), (calc.usesep==TRUE) ? _T("1") : _T("0"));
+ break;
- _stprintf(buf, TEXT("%lu"), calc.layout);
- WriteProfileString(TEXT("SciCalc"), TEXT("layout"), buf);
- WriteProfileString(TEXT("SciCalc"), TEXT("UseSep"), (calc.usesep==TRUE) ? TEXT("1") : TEXT("0"));
+ default: /* VER_PLATFORM_WIN32_NT */
+ SaveRegInt(_T("SOFTWARE\\Microsoft\\Calc"), _T("layout"), calc.layout);
+ SaveRegInt(_T("SOFTWARE\\Microsoft\\Calc"), _T("UseSep"), calc.usesep);
+ break;
+ }
}
static LRESULT post_key_press(LPARAM lParam, WORD idc)
if (!GetClassName(hCtlWnd, ClassName, SIZEOF(ClassName)))
return 1;
- if (!_tcscmp(ClassName, TEXT("Button"))) {
+ if (!_tcscmp(ClassName, WC_BUTTON)) {
DWORD dwStyle = GetWindowLongPtr(hCtlWnd, GWL_STYLE) & 0xF;
/* Set states for press/release, but only for push buttons */
static void update_lcd_display(HWND hwnd)
{
/*
- * muliply size of calc.buffer by 2 because it may
+ * multiply size of calc.buffer by 2 because it may
* happen that separator is used between each digit.
* Also added little additional space for dot and '\0'.
*/
HMENU hMenu = GetSubMenu(GetMenu(hwnd), 1);
unsigned int x;
- for (x=0; x<SIZEOF(upd); x++) {
+ /* Sets the state of the layout in the menu based on the configuration file */
+ if (calc.layout == CALC_LAYOUT_SCIENTIFIC)
+ {
+ CheckMenuRadioItem(GetMenu(hwnd),
+ IDM_VIEW_STANDARD,
+ IDM_VIEW_CONVERSION,
+ IDM_VIEW_SCIENTIFIC,
+ MF_BYCOMMAND);
+ }
+ else if (calc.layout == CALC_LAYOUT_CONVERSION)
+ {
+ CheckMenuRadioItem(GetMenu(hwnd),
+ IDM_VIEW_STANDARD,
+ IDM_VIEW_CONVERSION,
+ IDM_VIEW_CONVERSION,
+ MF_BYCOMMAND);
+ }
+ else
+ {
+ CheckMenuRadioItem(GetMenu(hwnd),
+ IDM_VIEW_STANDARD,
+ IDM_VIEW_CONVERSION,
+ IDM_VIEW_STANDARD,
+ MF_BYCOMMAND);
+ }
+
+ for (x=3; x<SIZEOF(upd); x++) {
if (*(upd[x].sel) != upd[x].idc) {
CheckMenuItem(hMenu, upd[x].idm, MF_BYCOMMAND|MF_UNCHECKED);
SendMessage((HWND)GetDlgItem(hwnd,upd[x].idc),BM_SETCHECK,FALSE,0L);
return FALSE;
}
-static WPARAM idm_2_idc(int idm)
+static BOOL idm_2_idc(int idm, WPARAM *pIdc)
{
int x;
for (x=0; x<SIZEOF(upd); x++) {
if (upd[x].idm == idm)
- break;
+ {
+ *pIdc = (WPARAM)(upd[x].idc);
+ return TRUE;
+ }
}
- return (WPARAM)(upd[x].idc);
+ return FALSE;
}
static void CopyMemToClipboard(void *ptr)
return p;
}
-static void run_pow(calc_number_t *number)
-{
- exec_infix2postfix(number, RPN_OPERATOR_POW);
-}
-
-static void run_sqr(calc_number_t *number)
-{
- exec_infix2postfix(number, RPN_OPERATOR_SQR);
-}
-
static void run_fe(calc_number_t *number)
{
- calc.sci_out = ((calc.sci_out == TRUE) ? FALSE : TRUE);
+ calc.sci_out = ((calc.sci_out != FALSE) ? FALSE : TRUE);
}
static void handle_context_menu(HWND hWnd, WPARAM wp, LPARAM lp)
popup.rcMargins.left = -1;
popup.rcMargins.right = -1;
popup.idString = GetWindowLongPtr((HWND)wp, GWL_ID);
- HtmlHelp((HWND)wp, HTMLHELP_PATH("/popups.txt"), HH_DISPLAY_TEXT_POPUP, (DWORD_PTR)&popup);
+ calc_HtmlHelp((HWND)wp, HTMLHELP_PATH("/popups.txt"), HH_DISPLAY_TEXT_POPUP, (DWORD_PTR)&popup);
}
#else
(void)idm;
static LRESULT CALLBACK SubclassButtonProc(HWND hWnd, WPARAM wp, LPARAM lp)
{
LPDRAWITEMSTRUCT dis = (LPDRAWITEMSTRUCT)lp;
- DWORD dwStyle;
UINT dwText;
TCHAR text[64];
int dx, dy, len;
SIZE size;
POINT pt;
- if(dis->CtlType == ODT_BUTTON) {
+ if(dis->CtlType == ODT_BUTTON)
+ {
+ HTHEME hTheme = NULL;
+ LPBTNINFO lpBtnInfo;
+
+ if (calc_IsAppThemed() && calc_IsThemeActive())
+ hTheme = calc_OpenThemeData(hWnd, L"Button");
+
+ if (hTheme)
+ {
+ int iState = 0;
+
+ if ((dis->itemState & ODS_DISABLED))
+ iState |= PBS_DISABLED;
+ if ((dis->itemState & ODS_SELECTED))
+ iState |= PBS_PRESSED;
+
+ lpBtnInfo = (LPBTNINFO)GetWindowLongPtr(dis->hwndItem, GWLP_USERDATA);
+ if (lpBtnInfo != NULL)
+ {
+ if (lpBtnInfo->bHover)
+ iState |= PBS_HOT;
+ }
+
+ if (calc_IsThemeBackgroundPartiallyTransparent(hTheme, BP_PUSHBUTTON, iState))
+ {
+ calc_DrawThemeParentBackground(dis->hwndItem, dis->hDC, &dis->rcItem);
+ }
+
+ // Draw the frame around the control
+ calc_DrawThemeBackground(hTheme, dis->hDC, BP_PUSHBUTTON, iState, &dis->rcItem, NULL);
+
+ calc_CloseThemeData(hTheme);
+ } else {
+ /* default state: unpushed */
+ DWORD dwStyle = 0;
+
+ if ((dis->itemState & ODS_SELECTED))
+ dwStyle = DFCS_PUSHED;
+
+ DrawFrameControl(dis->hDC, &dis->rcItem, DFC_BUTTON, DFCS_BUTTONPUSH | dwStyle);
+ }
+
+ /* button text to write */
+ len = GetWindowText(dis->hwndItem, text, SIZEOF(text));
+
/*
* little exception: 1/x has different color
* in standard and scientific modes
break;
}
}
- /* button text to write */
- len = GetWindowText(dis->hwndItem, text, SIZEOF(text));
- /* default state: unpushed & enabled */
- dwStyle = 0;
+
+ /* No background, to avoid corruption of the texture */
+ SetBkMode(dis->hDC, TRANSPARENT);
+
+ /* Default state: enabled */
dwText = 0;
if ((dis->itemState & ODS_DISABLED))
dwText = DSS_DISABLED;
- if ((dis->itemState & ODS_SELECTED))
- dwStyle = DFCS_PUSHED;
- DrawFrameControl(dis->hDC, &dis->rcItem, DFC_BUTTON, DFCS_BUTTONPUSH | dwStyle);
+ /* Draw the text in the button */
GetTextExtentPoint32(dis->hDC, text, len, &size);
dx = ((dis->rcItem.right-dis->rcItem.left) - size.cx) >> 1;
dy = ((dis->rcItem.bottom-dis->rcItem.top) - size.cy) >> 1;
- if ((dwStyle & DFCS_PUSHED)) {
+ if ((dis->itemState & ODS_SELECTED)) {
dx++;
dy++;
}
return 1L;
}
+static INT_PTR CALLBACK HotButtonProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
+{
+ LPBTNINFO lpBtnInfo = (LPBTNINFO)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+ TRACKMOUSEEVENT mouse_event;
+
+ switch (msg) {
+ case WM_MOUSEMOVE:
+ mouse_event.cbSize = sizeof(TRACKMOUSEEVENT);
+ mouse_event.dwFlags = TME_QUERY;
+ if (!TrackMouseEvent(&mouse_event) || !(mouse_event.dwFlags & (TME_HOVER|TME_LEAVE)))
+ {
+ mouse_event.dwFlags = TME_HOVER|TME_LEAVE;
+ mouse_event.hwndTrack = hWnd;
+ mouse_event.dwHoverTime = 1;
+ TrackMouseEvent(&mouse_event);
+ }
+ break;
+
+ case WM_MOUSEHOVER:
+ lpBtnInfo->bHover = TRUE;
+ InvalidateRect(hWnd, NULL, FALSE);
+ break;
+
+ case WM_MOUSELEAVE:
+ lpBtnInfo->bHover = FALSE;
+ InvalidateRect(hWnd, NULL, FALSE);
+ break;
+ }
+
+ return CallWindowProc(lpBtnInfo->oldProc, hWnd, msg, wp, lp);
+}
+
+static BOOL CALLBACK EnumChildProc(HWND hWnd, LPARAM lParam)
+{
+ TCHAR szClass[64];
+
+ if (!GetClassName(hWnd, szClass, SIZEOF(szClass)))
+ return TRUE;
+
+ if (!_tcscmp(szClass, WC_BUTTON))
+ {
+ int *pnCtrls = (int *)lParam;
+ int nCtrls = *pnCtrls;
+
+ BtnInfo[nCtrls].oldProc = (WNDPROC)GetWindowLongPtr(hWnd, GWLP_WNDPROC);
+ BtnInfo[nCtrls].bHover = FALSE;
+
+ SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)&BtnInfo[nCtrls]);
+ SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)HotButtonProc);
+
+ *pnCtrls = ++nCtrls;
+ }
+ return TRUE;
+}
+
+static INT_PTR CALLBACK OnSettingChange(HWND hWnd, WPARAM wParam, LPARAM lParam)
+{
+ /* Check for user policy and area string valid */
+ if (wParam == 0 && lParam != 0)
+ {
+ LPTSTR lpArea = (LPTSTR)lParam;
+
+ /* Check if a parameter has been changed into the locale settings */
+ if (!_tcsicmp(lpArea, _T("intl")))
+ {
+ /* Re-load locale parameters */
+ UpdateNumberIntl();
+
+ /* Update text for decimal button */
+ SetDlgItemText(hWnd, IDC_BUTTON_DOT, calc.sDecimal);
+
+ /* Update text into the output display */
+ update_lcd_display(hWnd);
+ }
+ }
+ return 0;
+}
+
static INT_PTR CALLBACK DlgMainProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
unsigned int x;
RECT rc;
+ HMENU hMenu;
switch (msg) {
case WM_DRAWITEM:
return SubclassButtonProc(hWnd, wp, lp);
case WM_INITDIALOG:
+#ifdef DISABLE_HTMLHELP_SUPPORT
+ EnableMenuItem(GetMenu(hWnd), IDM_HELP_HELP, MF_BYCOMMAND | MF_GRAYED);
+#endif
calc.hWnd=hWnd;
+ /* Enumerate children and apply hover function */
+ BtnCount = 0;
+ EnumChildWindows(hWnd, EnumChildProc, (LPARAM)&BtnCount);
#ifdef USE_KEYBOARD_HOOK
calc.hKeyboardHook=SetWindowsHookEx(
/* remove keyboard focus */
SetFocus(GetDlgItem(hWnd, IDC_BUTTON_FOCUS));
/* set our calc icon */
- SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM)LoadIcon(calc.hInstance, MAKEINTRESOURCE(IDI_CALC_BIG)));
- SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(calc.hInstance, MAKEINTRESOURCE(IDI_CALC_SMALL)));
+ SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM)calc.hBgIcon);
+ SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LPARAM)calc.hSmIcon);
+
+ /* Sets the state of the option to group digits */
+ hMenu = GetSubMenu(GetMenu(hWnd), 1);
+ CheckMenuItem(hMenu, IDM_VIEW_GROUP, (calc.usesep ? MF_CHECKED : MF_UNCHECKED));
+
/* update text for decimal button */
SendDlgItemMessage(hWnd, IDC_BUTTON_DOT, WM_SETTEXT, (WPARAM)0, (LPARAM)calc.sDecimal);
/* Fill combo box for conversion */
case WM_COMMAND:
/*
* if selection of category is changed, we must
- * updatethe content of the "from/to" combo boxes.
+ * update the content of the "from/to" combo boxes.
*/
if (wp == MAKEWPARAM(IDC_COMBO_CATEGORY, CBN_SELCHANGE)) {
ConvAdjust(hWnd, SendDlgItemMessage(hWnd, IDC_COMBO_CATEGORY, CB_GETCURSEL, 0, 0));
SetFocus(GetDlgItem(hWnd, IDC_BUTTON_FOCUS));
switch (LOWORD(wp)) {
case IDM_HELP_ABOUT:
- DialogBox(calc.hInstance,MAKEINTRESOURCE(IDD_DIALOG_ABOUT), hWnd, AboutDlgProc);
+ {
+ TCHAR infotitle[100];
+ TCHAR infotext[200];
+ LoadString(calc.hInstance, IDS_CALC_NAME, infotitle, SIZEOF(infotitle));
+ LoadString(calc.hInstance, IDS_AUTHOR, infotext, SIZEOF(infotext));
+ ShellAbout(hWnd, infotitle, infotext, calc.hBgIcon);
return TRUE;
+ }
case IDM_HELP_HELP:
#ifndef DISABLE_HTMLHELP_SUPPORT
- HtmlHelp(hWnd, HTMLHELP_PATH("/general_information.htm"), HH_DISPLAY_TOPIC, (DWORD_PTR)NULL);
+ calc_HtmlHelp(hWnd, HTMLHELP_PATH("/general_information.htm"), HH_DISPLAY_TOPIC, (DWORD_PTR)NULL);
#endif
return TRUE;
case IDM_VIEW_STANDARD:
- calc.layout = CALC_LAYOUT_STANDARD;
- calc.action = IDM_VIEW_STANDARD;
- DestroyWindow(hWnd);
- save_config();
+ if (calc.layout != CALC_LAYOUT_STANDARD)
+ {
+ calc.layout = CALC_LAYOUT_STANDARD;
+ calc.action = IDM_VIEW_STANDARD;
+ DestroyWindow(hWnd);
+
+ CheckMenuRadioItem(GetMenu(hWnd),
+ IDM_VIEW_STANDARD,
+ IDM_VIEW_CONVERSION,
+ IDM_VIEW_STANDARD,
+ MF_BYCOMMAND);
+ }
return TRUE;
case IDM_VIEW_SCIENTIFIC:
- calc.layout = CALC_LAYOUT_SCIENTIFIC;
- calc.action = IDM_VIEW_SCIENTIFIC;
- DestroyWindow(hWnd);
- save_config();
+ if (calc.layout != CALC_LAYOUT_SCIENTIFIC)
+ {
+ calc.layout = CALC_LAYOUT_SCIENTIFIC;
+ calc.action = IDM_VIEW_SCIENTIFIC;
+ DestroyWindow(hWnd);
+
+ CheckMenuRadioItem(GetMenu(hWnd),
+ IDM_VIEW_STANDARD,
+ IDM_VIEW_CONVERSION,
+ IDM_VIEW_SCIENTIFIC,
+ MF_BYCOMMAND);
+ }
return TRUE;
case IDM_VIEW_CONVERSION:
- calc.layout = CALC_LAYOUT_CONVERSION;
- calc.action = IDM_VIEW_CONVERSION;
- DestroyWindow(hWnd);
- save_config();
+ if (calc.layout != CALC_LAYOUT_CONVERSION)
+ {
+ calc.layout = CALC_LAYOUT_CONVERSION;
+ calc.action = IDM_VIEW_CONVERSION;
+ DestroyWindow(hWnd);
+
+ CheckMenuRadioItem(GetMenu(hWnd),
+ IDM_VIEW_STANDARD,
+ IDM_VIEW_CONVERSION,
+ IDM_VIEW_CONVERSION,
+ MF_BYCOMMAND);
+ }
return TRUE;
case IDM_VIEW_HEX:
case IDM_VIEW_DEC:
case IDM_VIEW_DWORD:
case IDM_VIEW_WORD:
case IDM_VIEW_BYTE:
- SendMessage(hWnd, WM_COMMAND, idm_2_idc(LOWORD(wp)), 0);
- return TRUE;
+ {
+ WPARAM idc;
+ if(idm_2_idc(LOWORD(wp), &idc))
+ {
+ SendMessage(hWnd, WM_COMMAND, idc, 0);
+ return TRUE;
+ }
+ return FALSE;
+ }
case IDM_EDIT_COPY:
handle_copy_command(hWnd);
return TRUE;
calc.usesep = (calc.usesep ? FALSE : TRUE);
update_menu(hWnd);
update_lcd_display(hWnd);
- save_config();
return TRUE;
case IDC_BUTTON_CONVERT:
ConvExecute(hWnd);
case IDC_BUTTON_LSH:
case IDC_BUTTON_RSH:
case IDC_BUTTON_EQU:
+ case IDC_BUTTON_XeY:
+ case IDC_BUTTON_XrY:
if (calc.is_nan) break;
/*
- * LSH button holds the RSH function too with INV modifier,
- * but since it's a two operand operator, it must be handled here.
+ * LSH and XeY buttons hold also the RSH and XrY functions with INV modifier,
+ * but since they are two operand operators, they must be handled here.
*/
- if (LOWORD(wp) == IDC_BUTTON_LSH &&
- (get_modifiers(hWnd) & MODIFIER_INV)) {
- PostMessage(hWnd, WM_COMMAND, MAKEWPARAM(IDC_BUTTON_RSH, BN_CLICKED), 0);
- SendDlgItemMessage(hWnd, IDC_CHECK_INV, BM_SETCHECK, 0, 0);
- break;
+ if ((get_modifiers(hWnd) & MODIFIER_INV))
+ {
+ WPARAM IdcSim = IDC_STATIC;
+
+ switch (LOWORD(wp)) {
+ case IDC_BUTTON_LSH: IdcSim = MAKEWPARAM(IDC_BUTTON_RSH, BN_CLICKED); break;
+ case IDC_BUTTON_XeY: IdcSim = MAKEWPARAM(IDC_BUTTON_XrY, BN_CLICKED); break;
+ }
+
+ if (IdcSim != IDC_STATIC)
+ {
+ PostMessage(hWnd, WM_COMMAND, IdcSim, 0);
+ CheckDlgButton(hWnd, IDC_CHECK_INV, BST_UNCHECKED);
+ }
}
+
for (x=0; x<SIZEOF(operator_codes); x++) {
if (LOWORD(wp) == operator_codes[x]) {
convert_text2number(&calc.code);
case IDC_BUTTON_SIN:
case IDC_BUTTON_COS:
case IDC_BUTTON_TAN:
- case IDC_BUTTON_XeY:
case IDC_BUTTON_MS:
for (x=0; x<SIZEOF(function_table); x++) {
if (LOWORD(wp) == function_table[x].idc) {
convert_text2number(&calc.code);
cb(&calc.code);
display_rpn_result(hWnd, &calc.code);
- if (!(function_table[x].range & NO_CHAIN))
- exec_infix2postfix(&calc.code, RPN_OPERATOR_NONE);
+// if (!(function_table[x].range & NO_CHAIN))
+// exec_infix2postfix(&calc.code, RPN_OPERATOR_NONE);
if (function_table[x].range & MODIFIER_INV)
SendDlgItemMessage(hWnd, IDC_CHECK_INV, BM_SETCHECK, 0, 0);
if (function_table[x].range & MODIFIER_HYP)
calc.action = IDC_STATIC;
DestroyWindow(hWnd);
return TRUE;
+
case WM_DESTROY:
/* Get (x,y) position of the calculator */
GetWindowRect(hWnd, &rc);
case WM_EXITMENULOOP:
calc.is_menu_on = FALSE;
break;
+
+ case WM_SETTINGCHANGE:
+ return OnSettingChange(hWnd, wp, lp);
+
+ case WM_THEMECHANGED:
+ InvalidateRect(hWnd, NULL, FALSE);
+ break;
}
return FALSE;
}
MSG msg;
DWORD dwLayout;
+ /* Initialize controls for theming & manifest support */
+ InitCommonControls();
+
calc.hInstance = hInstance;
calc.x_coord = -1;
load_config();
start_rpn_engine();
+ HtmlHelp_Start(hInstance);
+
+ Theme_Start(hInstance);
+
+ calc.hBgIcon = LoadImage(
+ hInstance,
+ MAKEINTRESOURCE(IDI_CALC),
+ IMAGE_ICON,
+ GetSystemMetrics(SM_CXICON),
+ GetSystemMetrics(SM_CYICON),
+ 0);
+
+ calc.hSmIcon = LoadImage(
+ hInstance,
+ MAKEINTRESOURCE(IDI_CALC),
+ IMAGE_ICON,
+ GetSystemMetrics(SM_CXSMICON),
+ GetSystemMetrics(SM_CYSMICON),
+ 0);
+
do {
/* ignore hwnd: dialogs are already visible! */
if (calc.layout == CALC_LAYOUT_SCIENTIFIC)
dwLayout = IDD_DIALOG_SCIENTIFIC;
- else
- if (calc.layout == CALC_LAYOUT_CONVERSION)
+ else if (calc.layout == CALC_LAYOUT_CONVERSION)
dwLayout = IDD_DIALOG_CONVERSION;
else
dwLayout = IDD_DIALOG_STANDARD;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
+
+ save_config();
} while (calc.action != IDC_STATIC);
+ if (calc.hBgIcon != NULL)
+ DestroyIcon(calc.hBgIcon);
+
+ if (calc.hSmIcon != NULL)
+ DestroyIcon(calc.hSmIcon);
+
stop_rpn_engine();
+ Theme_Stop();
+ HtmlHelp_Stop();
+
return 0;
}