00001
00002
00003
00004
00005
00011 #ifndef HAPP_H
00012 # define HAPP_H
00013
00014 #include "HLayout.h"
00015 #include "HMenu.h"
00016 #include "HWindow.h"
00017
00018 #ifdef RESOURCE_FILE
00019 # include "HResMgr.h"
00020 #endif
00021
00032 #define DECLARE_HUMBLE_APP(x) \
00033 x theApp; \
00034 int main(int argc, char * argv[]) \
00035 { return theApp.Main(argc, argv); }
00036
00048 class HApp : public HWindow<HApp>
00049 {
00050 typedef HWindow<HApp> base_class;
00051 static StringPtr ClassName(void) { return "HApp"; }
00052
00053
00054
00055 protected:
00056 s_gi_msg m_msgLast;
00057 HLayout m_layout;
00058 HMenuBar m_menuBar;
00059 #ifdef RESOURCE_FILE
00060 HResMgr m_resources;
00061 #endif
00062
00063
00064
00065 public:
00066 HApp(void) : base_class()
00067 { GI_init(); }
00068
00069 virtual ~HApp(void)
00070 { }
00071
00072
00073
00074 protected:
00075 BEGIN_MSG_MAP("HApp")
00076 MAP_MSG( MSG_DESTROY, onDestroy )
00077
00078 CHAIN_MAP( base_class )
00079 END_MSG_MAP
00091 bool
00092 onDestroy(const s_gi_msg & msg, HRESULT & hr)
00093 {
00094 ASSERT(msg.type == MSG_DESTROY);
00095
00096 if (!Quit())
00097 hr = S_FAILED;
00098
00099 return true;
00100 }
00101
00102
00103
00104 protected:
00115 virtual ErrCode
00116 parseCmdLine(int32 argc, TextPtr argv[])
00117 { return NO_ERROR; }
00118 public:
00127 ErrCode
00128 Destroy(void)
00129 {
00130 ErrCode ec = HError::NoError();
00131 s_window * pwMe = static_cast<s_window *>(m_hMe);
00132
00133 DEBUG_LOG("HApp::Destroy() => %p\n", pwMe);
00134
00135 if (GOOD_PTR(pwMe) &&
00136 GI_destroy_window(pwMe->parent) != S_OK)
00137 {
00138 ec = HError::Set(ERR_API_ERROR, __FILE__, __LINE__);
00139 }
00140
00141 return ec;
00142 }
00152 ErrCode
00153 Draw(HRect & rDirty)
00154 {
00155 #if __DEBUG__
00156 if (rDirty.IsNotEmpty())
00157 {
00158 (void) m_gc.SetClipRect(rDirty);
00159 (void) m_gc.SetColors(Humble::kClrDebug, Humble::kClrDebug);
00160 (void) m_gc.FillRect(rDirty);
00161 }
00162 #endif
00163 return m_layout.Draw(rDirty);
00164 }
00191 virtual ErrCode
00192 Init(int32 argc, TextPtr argv[])
00193 {
00194 ErrCode ec = NO_ERROR;
00195
00196
00197
00198 Text szDir[MAX_PATH+1] = { 0x00 };
00199
00200 if (GetApplicationDirectory(szDir) == S_OK &&
00201 chdir(szDir) == 0)
00202 {
00203 DEBUG_LOG("HApp::Init() => app directory is \"%s\".\n", szDir);
00204 }
00205 else
00206 {
00207 DEBUG_LOG("HApp::Init() => no app directory?\n");
00208 }
00209
00210
00211
00212 #ifdef RESOURCE_FILE
00213 HFilename fnResFile = RESOURCE_FILE;
00214
00215 if ((ec = m_resources.Open(fnResFile)) != NO_ERROR)
00216 return ec;
00217 #endif
00218
00219
00220
00221 return parseCmdLine(argc, argv);
00222 }
00232 virtual void
00233 Kill(ErrCode ec)
00234 {
00235 DEBUG_LOG("HApp::Kill() => %ld\n", int32(ec));
00236
00237
00238
00239 #ifdef RESOURCE_FILE
00240 (void) m_resources.Close();
00241 #endif
00242 }
00255 int32
00256 Main(int32 argc, TextPtr argv[])
00257 {
00258 ErrCode ec = HError::NoError();
00259
00260 try
00261 {
00262 #if __DEBUG__
00263 HFilename fnLog = argv[0];
00264
00265 fnLog += ".debug-log.txt";
00266 if (HDebug::GetLog().Open(fnLog))
00267 {
00268 DEBUG_LOG("HApp::Main() => %s (HFramework %s) as of %s %s\n",
00269 GetAppName(), HUMBLE_VER, __TIME__, __DATE__);
00270 }
00271 #endif
00272
00273 if ((ec = Init(argc, argv)) != NO_ERROR)
00274 throw HError::GetLastError();
00275
00276 DEBUG_LOG("HApp::Main() => before main event loop.\n");
00277
00278 for (;;)
00279 {
00280 if (GI_wait_message(&m_msgLast, NULL))
00281 GI_dispatch_message( static_cast<s_window *>(m_msgLast.win), &m_msgLast);
00282 else if (m_msgLast.win == m_hMe)
00283 {
00284
00285
00286
00287
00288
00289 DEBUG_LOG("HApp::Main() => destroying application\n");
00290 (void) Destroy();
00291
00292 break;
00293 }
00294 }
00295
00296 DEBUG_LOG("HApp::Main() => after main event loop.\n");
00297
00298 Kill(ec);
00299 }
00300 catch (const std::exception & e)
00301 {
00302
00303
00304
00305
00306
00307 DEBUG_LOG("### Panic: %s ###\n", e.what());
00308
00309 (void) GI_messagebox( NULL, WGF_MB_ICON_STOP|WGF_MB_OK,
00310 const_cast<TextPtr>("PANIC!"),
00311 const_cast<TextPtr>(e.what()));
00312 ec = ErrCode( HError::GetLastError() );
00313 ASSERT( ec != NO_ERROR );
00314 }
00315
00316 return ec;
00317 }
00329 bool
00330 Quit(bool bForced = false)
00331 {
00332 bool bQuitting = false;
00333
00334 if (bForced ||
00335 Humble::PopUpYesNo(GetAppName(), "Do you really want to exit?") == ID_YES)
00336 {
00337 GI_post_quit( m_hMe );
00338 bQuitting = true;
00339 }
00340
00341 return bQuitting;
00342 }
00351 ErrCode
00352 Show(void) const
00353 {
00354 ErrCode ec = HError::NoError();
00355
00356 DEBUG_LOG("HApp[%p]::Show()\n", this);
00357
00358 if (IsValid())
00359 {
00360 if (GI_ShowApplicationWindow(m_hMe) != S_OK)
00361 ec = HError::Set(ERR_API_ERROR, __FILE__, __LINE__);
00362 }
00363 else
00364 ec = HError::Set(ERR_BAD_WINDOW, __FILE__, __LINE__);
00365
00366 return ec;
00367 }
00374
00378 ErrCode
00379 UpdateLayout(void)
00380 {
00381 ErrCode ec = HError::NoError();
00382 HRect rBounds;
00383
00384 if (m_layout.IsValid() && GetBounds(rBounds))
00385 ec = m_layout.SetBounds(rBounds);
00386
00387 return ec;
00388 }
00389
00390
00391
00392
00403 virtual StringPtr GetAppName(void) const
00404 { return kStrEmpty; }
00405
00406
00407
00419 inline ErrCode ExtractResource(StringPtr pstrSrc, StringPtr pstrDst = NULL)
00420 {
00421 #ifdef RESOURCE_FILE
00422 return m_resources.Extract(pstrSrc, pstrDst);
00423 #else
00424 return HError::Set(ERR_NOT_IMPLEMENTED, __FILE__, __LINE__);
00425 #endif
00426 }
00427 };
00428 #endif // HAPP_H
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460