diff --git a/src/pad.cpp b/src/pad.cpp new file mode 100644 index 0000000..49636e0 --- /dev/null +++ b/src/pad.cpp @@ -0,0 +1,452 @@ +/* + * This file is a part of TTCalc - a mathematical calculator + * and is distributed under the (new) BSD licence. + * Author: Tomasz Sowa + */ + +/* + * Copyright (c) 2006-2009, Tomasz Sowa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name Tomasz Sowa nor the names of contributors to this + * project may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "programresources.h" +#include "resource.h" +#include "messages.h" +#include "bigtypes.h" + + +namespace Pad +{ +HWND edit; +WNDPROC old_edit_proc; +std::string parse_string; +int precision; + +int base_input; +int base_output; +bool always_scientific; +int when_scientific; +int rounding; +bool remove_zeroes; +int angle_deg_rad_grad; +char decimal_point; +Languages::Country country; +ttmath::Objects * variables; +ttmath::Objects * functions; +ttmath::ErrorCode code; +bool calculated; + +std::string res, res2; + +#ifndef TTCALC_PORTABLE + ttmath::Parser parser1; + ttmath::Parser parser2; + ttmath::Parser parser3; +#else + ttmath::Parser parser1; +#endif + + +void PutChars(const char * str) +{ + SendMessage(edit, EM_REPLACESEL, true, (LPARAM)str); +} + + +void PutChars(std::string & str) +{ + PutChars(str.c_str()); +} + + +void PutOverflowMsg() +{ + PutChars(GetPrgRes()->GetLanguages()->ErrorMessage(country, ttmath::err_overflow)); + PutChars("\r\n"); +} + + +template +void PutResultFromParser(ttmath::Parser & matparser) +{ +unsigned int i = 0; + + res.clear(); + res2.clear(); + + for(i=0 ; iGetLanguages()->GuiMessage(country, Languages::overflow_during_printing); + } + catch(...) + { + res2 = GetPrgRes()->GetLanguages()->ErrorMessage(country, ttmath::err_internal_error); + } + + res += res2; + + if( i < matparser.stack.size()-1 ) + res += "\r\n"; + } + + res += ' '; + PutChars(res); +} + + +void PutResult() +{ + #ifndef TTCALC_PORTABLE + + switch( precision ) + { + case 0: + PutResultFromParser(parser1); + break; + + case 1: + PutResultFromParser(parser2); + break; + + default: + PutResultFromParser(parser3); + break; + } + + #else + + PutResultFromParser(parser1); + + #endif +} + + + +// line - index of a line -- as you see it on the edit control +// (if the text is wrapped then the line is larger) +void GetParseString(const char * buf, int line) +{ +int i; + + int first_line_char = SendMessage(edit, EM_LINEINDEX, line, 0); + // first_line_char takes into consideration \r\n characters + + if( first_line_char < 0 ) + // something wrong + return; + + // looking for the line + for(i=0 ; i0 && buf[i-1]!=10 ; --i); + + // copying the whole line + for( ; buf[i]!=0 && buf[i]!='\r' && buf[i]!='\n' ; ++i ) + parse_string += buf[i]; +} + + +void GetParseString() +{ +int line; + + parse_string.clear(); + + // index of a last line to parse (-1 because the ENTER has been put) + line = SendMessage(edit, EM_LINEFROMCHAR, -1, 0) - 1; + + if( line < 0 ) + // something wrong + return; + + + HLOCAL handle = (HLOCAL)SendMessage(edit, EM_GETHANDLE, 0, 0); + + if( handle == 0 ) + // something wrong + return; + + const char * buf = (const char*)LocalLock(handle); + + if( buf ) + GetParseString(buf, line); + + LocalUnlock(handle); +} + + +template +void ParseString(ttmath::Parser & matparser) +{ + matparser.SetBase(base_input); + matparser.SetDegRadGrad(angle_deg_rad_grad); + matparser.SetFunctions(functions); + matparser.SetVariables(variables); + + code = matparser.Parse(parse_string.c_str()); + + calculated = matparser.Calculated(); +} + + +void SetParameters() +{ + base_input = GetPrgRes()->GetBaseInput(); + base_output = GetPrgRes()->GetBaseOutput(); + always_scientific = GetPrgRes()->GetDisplayAlwaysScientific(); + when_scientific = GetPrgRes()->GetDisplayWhenScientific(); + rounding = GetPrgRes()->GetDisplayRounding(); + precision = GetPrgRes()->GetPrecision(); + remove_zeroes = GetPrgRes()->GetRemovingZeroes(); + angle_deg_rad_grad = GetPrgRes()->GetDegRadGrad(); + country = GetPrgRes()->GetLanguages()->GetCurrentLanguage(); + + if( GetPrgRes()->GetDecimalPoint() == 0 ) + decimal_point = '.'; + else + decimal_point = ','; + + variables = GetPrgRes()->GetVariables(); + functions = GetPrgRes()->GetFunctions(); +} + + +void ParseString() +{ + if( parse_string.empty() ) + return; + + SetParameters(); + + try + { + #ifndef TTCALC_PORTABLE + + switch( precision ) + { + case 0: + ParseString(parser1); + break; + + case 1: + ParseString(parser2); + break; + + default: + ParseString(parser3); + break; + } + + #else + ParseString(parser1); + #endif + } + catch(...) + { + code = ttmath::err_internal_error; + } + + + if( code==ttmath::err_ok && calculated ) + PutResult(); + else + if( code==ttmath::err_overflow ) + PutOverflowMsg(); +} + + +LRESULT EditReturnPressed(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ +DWORD sel_start, sel_end; + + SendMessage(edit, EM_GETSEL, (WPARAM)&sel_start, (LPARAM)&sel_end); + + if( sel_start != sel_end ) + // something is selected + return CallWindowProc(old_edit_proc, hwnd, msg, wParam, lParam); + + // putting the ENTER + LRESULT res = CallWindowProc(old_edit_proc, hwnd, msg, wParam, lParam); + + GetParseString(); + ParseString(); + +return res; +} + + + +LRESULT EditSubclass(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch( msg ) + { + case WM_CHAR: + if( wParam == VK_RETURN ) + { + return EditReturnPressed(hwnd, msg, wParam, lParam); + } + break; + } + +return CallWindowProc(old_edit_proc, hwnd, msg, wParam, lParam); +} + + + + +LRESULT PadCreate(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + edit = CreateWindow("edit", "", + WS_VISIBLE | WS_CHILD | WS_VSCROLL | ES_MULTILINE | ES_AUTOVSCROLL, + 0, 0, 100, 100, hwnd, 0, GetPrgRes()->GetInstance(), 0); + + old_edit_proc = (WNDPROC)SetWindowLong(edit, GWL_WNDPROC, (LONG)EditSubclass); + + return 0; +} + + +LRESULT PadSize(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ +int cx = LOWORD(lParam); +int cy = HIWORD(lParam); + + MoveWindow(edit, 0, 0, cx, cy, true); + +return 0; +} + + + +LRESULT PadClose(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + GetPrgRes()->TurnPad(); + +return 0; +} + + +LRESULT PadFocus(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + SetFocus(edit); + +return 0; +} + + +void CreatePadMessagesTable(Messages & messages) +{ + messages.Associate(WM_CREATE, PadCreate); + messages.Associate(WM_SIZE, PadSize); + messages.Associate(WM_CLOSE, PadClose); + messages.Associate(WM_SETFOCUS, PadFocus); +} + + +LRESULT CALLBACK WindowPadProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ +static Messages messages; +bool method_exists; +LRESULT res; + + if( messages.Empty() ) + // initiation + CreatePadMessagesTable(messages); + + res = messages.Call(msg, hwnd, msg, wParam, lParam, &method_exists); + + if( !method_exists ) + return DefWindowProc(hwnd, msg, wParam, lParam); + +return res; +} + + + +ATOM RegisterPadClass(const char * ttcalc_pad_class_name) +{ +WNDCLASS w; + + w.style = 0; + w.lpfnWndProc = WindowPadProc; + w.cbClsExtra = 0; + w.cbWndExtra = 0; + w.hInstance = GetPrgRes()->GetInstance(); + w.hIcon = LoadIcon(GetPrgRes()->GetInstance(), MAKEINTRESOURCE(IDI_ICON2)); + w.hCursor = 0; + w.hbrBackground = (HBRUSH)(COLOR_BACKGROUND+1); + w.lpszMenuName = 0; + w.lpszClassName = ttcalc_pad_class_name; + +return RegisterClass(&w); +} + + +} // namespace Pad + + + + + +bool CreatePadWindow() +{ +using namespace Pad; + +static char ttcalc_pad_class_name[] = "TTCalcPadWindow"; + +ATOM a = RegisterPadClass(ttcalc_pad_class_name); + + if( a == 0 ) + return false; + + HWND pad = CreateWindowEx(0, ttcalc_pad_class_name, + "Pad", + WS_OVERLAPPEDWINDOW | WS_POPUPWINDOW , + 100, 100, + 600, 450, + GetPrgRes()->GetMainWindow(), 0, GetPrgRes()->GetInstance(), 0); + + + GetPrgRes()->SetPadWindow(pad); + + +return pad != 0; +} + + + + diff --git a/src/pad.h b/src/pad.h new file mode 100644 index 0000000..ec2daae --- /dev/null +++ b/src/pad.h @@ -0,0 +1,47 @@ +/* + * This file is a part of TTCalc - a mathematical calculator + * and is distributed under the (new) BSD licence. + * Author: Tomasz Sowa + */ + +/* + * Copyright (c) 2006-2009, Tomasz Sowa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name Tomasz Sowa nor the names of contributors to this + * project may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef headerfilepad +#define headerfilepad + + + +bool CreatePadWindow(); + + + +#endif