Humble Framework for SkyOS


Main Page | Modules | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

HApp.h

Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 **  $Header: /SkyOS.root/HFramework/HApp.h 5     4/17/05 12:29p Lee Neuse $
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 //  end of DECLARE_APP macro
00048 class HApp : public HWindow<HApp>
00049     {
00050     typedef HWindow<HApp>   base_class;
00051     static StringPtr        ClassName(void) { return "HApp"; }
00052 /*  ----------------------------------------------------------------------
00053     VARIABLES
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     CTOR / DTOR
00064     ----------------------------------------------------------------------  */
00065 public:
00066     HApp(void) : base_class()
00067         { GI_init(); }
00068         
00069     virtual ~HApp(void)
00070         { /* EMPTY DTOR */ }
00071 /*  ----------------------------------------------------------------------
00072     MESSAGE HANDLERS
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())        // if user canceled the quit request
00097             hr = S_FAILED;  // then fail to prevent window from closing
00098 
00099         return true;
00100         }
00101 /*  ----------------------------------------------------------------------
00102     METHODS
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         //  Switch to the application's working directory
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         //  Open the resource file
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         //  Parse the command line arguments
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         //  Close the resource file
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                     //  Destroy the main application window so that window
00286                     //  messages caused by the destruction are sent and
00287                     //  processed before Kill() is invoked.
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             //  This is the high-level catch block, which is effectively the
00304             //  last gasp of a dying application.  There's no going back from
00305             //  here, so put up a nastygram and die a horrible death.  
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 //  layout widget.
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     GETTERS & SETTERS
00392     ----------------------------------------------------------------------  */
00403     virtual StringPtr   GetAppName(void) const 
00404                             { return kStrEmpty; }
00405 /*  ----------------------------------------------------------------------
00406     INLINES
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 **  $History: HApp.h $
00432  * 
00433  * *****************  Version 5  *****************
00434  * User: Lee Neuse    Date: 4/17/05    Time: 12:29p
00435  * Updated in $/SkyOS.root/HFramework
00436  * Development snapshot 050417
00437  * 
00438  * *****************  Version 4  *****************
00439  * User: Neusel       Date: 2/04/05    Time: 10:45a
00440  * Updated in $/SkyOS.root/pig/Humble
00441  * 
00442  * *****************  Version 3  *****************
00443  * User: Neusel       Date: 12/08/04   Time: 5:06p
00444  * Updated in $/SkyOS.root/pig/Humble
00445  * 20041208
00446  * 
00447  * *****************  Version 2  *****************
00448  * User: Neusel       Date: 11/30/04   Time: 1:01p
00449  * Updated in $/SkyOS.root/pig/Humble
00450  * Released as HUMBLE_VER 20041130.
00451  * 
00452  * *****************  Version 1  *****************
00453  * User: Neusel       Date: 11/23/04   Time: 8:24a
00454  * Created in $/SkyOS.root/pig/Humble
00455 **
00456 **  -------------------------------------------------------------------------
00457 **
00458 **  End of HApp.h
00459 **
00460 ****************************************************************************/