00001 #ifndef TINY_SHELL_IMPLEMENTATION_FILE
00002 #define TINY_SHELL_IMPLEMENTATION_FILE
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "debugging_console_window.h"
00019 #include "tiny_shell.h"
00020
00021 #include <geometric/rectangle.cpp>
00022 #include <geometric/screen_rectangle.h>
00023 #include <opsystem/ini_config.h>
00024 #include <opsystem/path_configuration.h>
00025
00026 using namespace geometric;
00027
00028 #define INI_NAME(root) (root + istring(".ini"))
00029
00030 #define LOG_NAME(root) (path_configuration::make_logfile_name(root + istring(".log")))
00031
00032 DECLARE_BUG_EVENT;
00033
00035
00036 #define START_EXECUTION (WM_USER + 298)
00037
00038
00039
00040
00041 BEGIN_MESSAGE_MAP(tiny_shell, CFrameWnd)
00042
00043 ON_WM_CREATE()
00044 ON_WM_CLOSE()
00045 ON_WM_MOVE()
00046 ON_WM_SIZE()
00047
00048 ON_MESSAGE(START_EXECUTION, do_execute)
00049 ADD_DEBUGGER_MAP(print_debug)
00050 END_MESSAGE_MAP()
00051
00053
00054 tiny_shell::tiny_shell(const istring &window_title, const istring &root,
00055 int file_size, const istring &logfile_name)
00056 : CFrameWnd(),
00057 application_shell(root),
00058 _console(new debugging_console_window(file_size)),
00059 _debug(new debugger(0, debugger::delayed)),
00060 _icon(NIL),
00061 _menu(NIL),
00062 _win_title(new istring(window_title)),
00063 _exiting(false),
00064 _held_logger(NIL),
00065 _logfile_name(new istring(logfile_name)),
00066 _execute_returned(0)
00067 {}
00068
00069 tiny_shell::~tiny_shell()
00070 {
00071 WHACK(_debug);
00072 WHACK(_console);
00073 WHACK(_win_title);
00074 WHACK(_logfile_name);
00075 }
00076
00077 debugging_console_window &tiny_shell::console() const { return *_console; }
00078
00079 debugger &tiny_shell::debug() const { return *_debug; }
00080
00081 bool tiny_shell::good_version() const { return true; }
00082
00083 bool tiny_shell::Create()
00084 {
00085
00086 screen_rectangle win_size;
00087 CRect mfc_default = CFrameWnd::rectDefault;
00088 screen_rectangle default_size(mfc_default.TopLeft().x,
00089 mfc_default.TopLeft().y, mfc_default.BottomRight().x,
00090 mfc_default.BottomRight().y);
00091 istring tmp = ini().load(filename_root(), istring("window_size"),
00092 default_size.text_form());
00093 win_size.from_text(tmp);
00094
00095 CRect size(win_size.top_left().x(), win_size.top_left().y(),
00096 win_size.bottom_right().x(), win_size.bottom_right().y());
00097
00098
00099 if (!CFrameWnd::Create(NIL, to_unicode_temp(*_win_title),
00100 WS_OVERLAPPEDWINDOW, size, NIL, NIL, 0, NIL)) return false;
00101
00102 return true;
00103 }
00104
00105 void tiny_shell::OnSetFocus(CWnd *old_window)
00106 {
00107 CFrameWnd::OnSetFocus(old_window);
00108 if (::IsWindow(_console->GetSafeHwnd())) _console->SetFocus();
00109 }
00110
00111 afx_msg int tiny_shell::OnCreate(LPCREATESTRUCT lpCreateStruct)
00112 {
00113 if (CFrameWnd::OnCreate(lpCreateStruct) == -1) return -1;
00114
00115
00116 if (_logfile_name->t())
00117 _console->name(*_logfile_name);
00118 else
00119 _console->name(LOG_NAME(filename_root()));
00120
00121 if (!_console->Create(NIL, to_unicode_temp(filename_root()
00122 + istring(" Console")), WS_CHILD, CFrameWnd::rectDefault, this, 0, NIL))
00123 return false;
00124
00125 _console->show();
00126
00127 #ifndef OMIT_PROGRAM_WIDE_LOGGER
00128
00129 _held_logger = retask_program_wide_logger(&debug());
00130 #endif
00131
00132 if (menu()) {
00133 _mfc_menu.LoadMenu(menu());
00134 SetMenu(&_mfc_menu);
00135 }
00136
00137 if (icon()) {
00138 HICON tshell_icon = LoadIcon(AfxGetInstanceHandle(),
00139 MAKEINTRESOURCE(icon()));
00140 SetIcon(tshell_icon, false);
00141 SetIcon(tshell_icon, true);
00142 }
00143
00144
00145 _debug->reset_recipient(*_console);
00146
00147
00148
00149 ::PostMessage(*this, START_EXECUTION, 0, 0);
00150
00151 return 0;
00152 }
00153
00154 afx_msg void tiny_shell::OnClose()
00155 {
00156 FUNCDEF("OnClose");
00157 if (_exiting)
00158 non_continuable_error(class_name(), func, "exiting twice? already trying to exit.");
00159 _exiting = true;
00160 if (!IsIconic()) {
00161
00162 CRect rect;
00163 GetWindowRect(&rect);
00164 screen_rectangle win_size(rect.TopLeft().x, rect.TopLeft().y,
00165 rect.BottomRight().x, rect.BottomRight().y);
00166 ini().store(filename_root(), istring("window_size"), win_size.text_form());
00167 }
00168
00169 if (menu()) {
00170
00171 _mfc_menu.DestroyMenu();
00172 }
00173
00174 #ifndef OMIT_PROGRAM_WIDE_LOGGER
00175 log_base *ignore = retask_program_wide_logger(_held_logger);
00176
00177 _held_logger = NIL;
00178 #endif
00179
00180 CFrameWnd::OnClose();
00181 }
00182
00183 afx_msg void tiny_shell::OnMove(int x, int y)
00184 {
00185 CFrameWnd::OnMove(x, y);
00186 RECT client_size;
00187 GetClientRect(&client_size);
00188 _console->MoveWindow(&client_size);
00189 }
00190
00191 afx_msg void tiny_shell::OnSize(u_int nType, int cx, int cy)
00192 {
00193 CFrameWnd::OnSize(nType, cx, cy);
00194 if ( !(nType & SIZE_MINIMIZED) ) {
00195
00196 RECT client_size;
00197 GetClientRect(&client_size);
00198 _console->MoveWindow(&client_size);
00199 }
00200 }
00201
00202 LRESULT tiny_shell::do_execute(WPARAM , LPARAM )
00203 {
00204 _execute_returned = execute();
00205 return 0;
00206 }
00207
00208 LRESULT tiny_shell::print_debug(WPARAM wparam, LPARAM lparam)
00209 {
00210 if (_exiting) return 0;
00211 return _console->display_debug_message(wparam, lparam);
00212 }
00213
00214 outcome tiny_shell::print(const istring &to_print)
00215 {
00216 if (_exiting) return 0;
00217 return _debug->print(to_print);
00218 }
00219
00220 outcome tiny_shell::log(const istring &to_print)
00221 {
00222 if (_exiting) return 0;
00223 return _debug->log(to_print);
00224 }
00225
00226
00227 #endif //TINY_SHELL_IMPLEMENTATION_FILE
00228