ttcalc/src/winmain.cpp

200 lines
5.7 KiB
C++

/*
* This file is a part of TTCalc - a mathematical calculator
* and is distributed under the (new) BSD licence.
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
*/
/*
* 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 "compileconfig.h"
#include "winmain.h"
/*!
\file mainwin.cpp
\brief There's defined the entry point to the application in this file
*/
#include <string>
#include <ttmath/ttmath.h>
/*!
the application starts here
*/
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int)
{
GetPrgRes()->SetInstance(hInstance);
// we're using GetLanguages() simultaneously in two threads, this is to be sure
// that everything is initialized before the second thread is started
GetPrgRes()->GetLanguages()->InitAll();
GetPrgRes()->GetLanguages()->SetCurrentLanguage(Languages::en);
//GetPrgRes()->GetConvert()->Init();
GetPrgRes()->SetNameOfConfigurationFile();
GetPrgRes()->ReadFromFile();
INITCOMMONCONTROLSEX common_ctrl;
common_ctrl.dwSize = sizeof(common_ctrl);
common_ctrl.dwICC = ICC_WIN95_CLASSES;
if( !InitCommonControlsEx(&common_ctrl) )
return ShowError( Languages::cant_init_common_controls );
if( !GetPrgRes()->GetThreadController()->Init() )
return ShowError( Languages::cant_init_calculations );
unsigned int thread_id;
uintptr_t thread_handle;
if( (thread_handle = _beginthreadex(0,0,CalculationsProcedure, 0, 0, &thread_id)) == 0 )
return ShowError( Languages::cant_create_thread );
CreateDialog( hInstance, MAKEINTRESOURCE(IDD_MAIN_DIALOG), 0, MainWindowProc);
if( !GetPrgRes()->GetMainWindow() )
return ShowError( Languages::cant_create_main_window );
// there's the main loop of messages here
MainMessagesLoop();
// there can be another variables/functions saved by other instantion of TTCalc
// we're reading them now
GetPrgRes()->ReadVariablesFunctionsFromFile();
GetPrgRes()->SaveToFile();
CloseHandle( (HANDLE)thread_handle );
return 0;
}
/*!
it displays a message box with an error
(it's only used during initiation)
*/
int ShowError( Languages::GuiMsg error_code )
{
MessageBox(0, GetPrgRes()->GetLanguages()->GuiMessage( error_code ),
GetPrgRes()->GetLanguages()->GuiMessage( Languages::message_box_error_caption ),
MB_ICONERROR);
return static_cast<int>( error_code );
}
/*!
the main loop of messages
*/
void MainMessagesLoop()
{
MSG msg;
while( GetMessage(&msg,0,0,0) )
{
bool sent = false;
// if there's CTRL+C or CTRL+V pressed we're trying to copy
// a result from the output edit or trying to paste something from the clipboard
if( msg.message==WM_KEYDOWN && (GetKeyState(VK_CONTROL) & 0xff00)!=0 )
{
if( msg.wParam == 'C' )
{
if( MainWindowFunctions::CopyResult() )
sent = true;
}
else
if( msg.wParam == 'V' )
{
if( MainWindowFunctions::Paste() )
sent = true;
}
}
// we give our own special function for navigating from the keyboard
// if our function returns false then we use a standard navigation
// from the system
if( !sent && msg.message == WM_KEYDOWN &&
( msg.wParam == VK_TAB ||
msg.wParam == VK_DOWN || msg.wParam == VK_UP ||
msg.wParam == VK_LEFT || msg.wParam == VK_DOWN ) )
{
if( MainWindowFunctions::SetNextFocus(msg.wParam) )
sent = true;
}
// firt we try to send our message to dialogs
// (the dialogs on the tab control)
if( !sent )
{
for(unsigned int i=0 ; i<GetPrgRes()->HowManyTabWindows() && !sent ; ++i)
{
if( IsDialogMessage(GetPrgRes()->GetTabWindow(i), &msg) )
sent = true;
}
}
// if it's not a message to any of our dialogs we send it
// to the main window (it's a dialog as well)
if( !sent )
{
if( !IsDialogMessage(GetPrgRes()->GetMainWindow(), &msg) )
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
}
/*!
the window-procedure for the main window
*/
BOOL CALLBACK MainWindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static Messages messages;
if( messages.Empty() )
// initiation
MainWindowFunctions::CreateMainMessagesTable(messages);
// in the Messages class we're using the std::map
// so that we have the logarythmic time to find the special function to call
return messages.Call(message, hWnd, message, wParam, lParam);
}