core/vgui/impl/mfc/vgui_mfc_app.cxx
Go to the documentation of this file.
00001 // This is core/vgui/impl/mfc/vgui_mfc_app.cxx
00002 #include "StdAfx.h"
00003 #include "vgui_mfc_app.h"
00004 //:
00005 // \file
00006 // \brief   See vgui_mfc_app.h for a description of this file.
00007 // \author  Marko Bacic, Oxford RRG
00008 // \date    27 July 2000
00009 //
00010 // \verbatim
00011 //  Modifications
00012 //   K.Y.McGaul  18-SEP-2001   Changed indentation from 8 spaces to 2 spaces.
00013 // \endverbatim
00014 //-----------------------------------------------------------------------------
00015 
00016 #include "vgui_mfc_view.h"
00017 #include "vgui_mfc_doc.h"
00018 #include "vgui_mfc_mainfrm.h"
00019 #include "resource.h"
00020 #if 0
00021   #ifdef _DEBUG
00022   #define new DEBUG_NEW
00023   #undef THIS_FILE
00024   static char THIS_FILE[] = __FILE__;
00025   #endif
00026 #endif
00027 
00028 /////////////////////////////////////////////////////////////////////////////
00029 //: vgui_mfc_app construction
00030 vgui_mfc_app::vgui_mfc_app()
00031 {
00032   // TODO: add construction code here,
00033   // Place all significant initialization in InitInstance
00034 }
00035 
00036 /////////////////////////////////////////////////////////////////////////////
00037 //: The one and only vgui_mfc_app object
00038 class vgui_mfc_app_command_line_info : public CCommandLineInfo
00039 {
00040  public:
00041   void ParseParam( LPCTSTR lpszParam, BOOL bFlag, BOOL bLast )
00042   {
00043     CCommandLineInfo::ParseParam(lpszParam, bFlag, bLast);
00044   }
00045 };
00046 
00047 static void f();
00048 
00049 /////////////////////////////////////////////////////////////////////////////
00050 //: vgui_mfc_app initialization
00051 BOOL vgui_mfc_app::InitInstance()
00052 {
00053   AfxEnableControlContainer();
00054 
00055   // Standard initialization
00056   // If you are not using these features and wish to reduce the size
00057   //  of your final executable, you should remove from the following
00058   //  the specific initialization routines you do not need.
00059 #if 0
00060   #ifdef _DEBUG
00061     Enable3dControls();       // Call this when using MFC in a shared DLL
00062   #else
00063     Enable3dControlsStatic(); // Call this when linking to MFC statically
00064   #endif
00065 #endif
00066   // Change the registry key under which our settings are stored.
00067   // TODO: You should modify this string to be something appropriate
00068   // such as the name of your company or organization.
00069   SetRegistryKey(_T("Local AppWizard-Generated Applications"));
00070 
00071   LoadStdProfileSettings();  // Load standard INI file options (including MRU)
00072 
00073   // Register the application's document templates.  Document templates
00074   //  serve as the connection between documents, frame windows and views.
00075   CSingleDocTemplate *pDocTemplate;
00076   pDocTemplate = new CSingleDocTemplate(
00077     IDR_MAINFRAME,
00078     RUNTIME_CLASS(vgui_mfc_doc),
00079     RUNTIME_CLASS(vgui_mfc_mainfrm),// main SDI frame window
00080     RUNTIME_CLASS(vgui_mfc_view));
00081   AddDocTemplate(pDocTemplate);
00082 
00083   // Parse command line for standard shell commands, DDE, file open
00084   vgui_mfc_app_command_line_info cmdInfo;
00085 #if 0
00086   ParseCommandLine(cmdInfo);
00087 #endif
00088 
00089   // *** IMPORTANT STUFF (marko) ***
00090   CDocument *pDocument = pDocTemplate->CreateNewDocument();
00091   // pDocument->m_bAutoDelete = FALSE; //awf added to stop segv on exit.
00092   //  probly wrong.  Then removed as it did nowt.
00093 
00094   CFrameWnd* pFrame = (CFrameWnd *)(RUNTIME_CLASS(vgui_mfc_mainfrm)->CreateObject());
00095   CCreateContext context;
00096   context.m_pCurrentFrame = pFrame;
00097   context.m_pCurrentDoc = pDocument;
00098   context.m_pNewViewClass = RUNTIME_CLASS(vgui_mfc_view);
00099   context.m_pNewDocTemplate = pDocTemplate;
00100   pFrame->Create(NULL, _T("VGUI"), WS_OVERLAPPEDWINDOW /*|WS_HSCROLL|WS_VSCROLL*/,
00101                  pFrame->rectDefault,NULL,NULL,0,&context);
00102   m_pMainWnd = pFrame;
00103   pDocTemplate->InitialUpdateFrame(pFrame,pDocument);
00104   // The one and only window has been initialized, so show and update it.
00105 #if 0
00106   m_pMainWnd->SetScrollRange(SB_HORZ,-1024,1024);
00107   m_pMainWnd->SetScrollRange(SB_VERT,-1024,1024);
00108   m_pMainWnd->SetScrollPos(SB_HORZ,0);
00109   m_pMainWnd->SetScrollPos(SB_VERT,0);
00110 #endif
00111   m_pMainWnd->ShowWindow(SW_SHOW);
00112   m_pMainWnd->UpdateWindow();
00113 
00114   return TRUE;
00115 }
00116 
00117 //: CWinApp::Run() calls CWinThread::Run().
00118 BOOL vgui_mfc_app::Run()
00119 {
00120   // for tracking the idle time state
00121   BOOL bIdle = TRUE;
00122   LONG lIdleCount = 0;
00123   MSG msgCur;
00124 
00125   // acquire and dispatch messages until a WM_QUIT message is received.
00126   for (;;)
00127   {
00128     // phase1: check to see if we can do idle work
00129     while (bIdle && !::PeekMessage(&msgCur, NULL, NULL, NULL, PM_NOREMOVE))
00130     {
00131       // call OnIdle while in bIdle state
00132       if (!OnIdle(lIdleCount++))
00133         bIdle = FALSE; // assume "no idle" state
00134     }
00135 
00136     // phase2: pump messages while available
00137     do
00138     {
00139       MSG tmp_msg;
00140       if (::PeekMessage(&tmp_msg,NULL,NULL,NULL,PM_NOREMOVE))
00141       {
00142         if (true)
00143         {
00144           // Collapse multiple move events...
00145           while (tmp_msg.message == WM_MOVE)
00146           {
00147             // Remove the message from the queue
00148             ::PeekMessage(&tmp_msg,NULL,NULL,NULL,PM_REMOVE);
00149             // Get the next message
00150             BOOL status = ::PeekMessage(&tmp_msg,NULL,NULL,NULL,PM_NOREMOVE);
00151             // If there were no more messages in the queue or
00152             // the next message retrieved is not a move
00153             // process the message
00154             if (!status || !(tmp_msg.message == WM_MOVE))
00155             {
00156               ::TranslateMessage(&tmp_msg);
00157               ::DispatchMessage(&tmp_msg);
00158             }
00159           }
00160         }
00161       }
00162 
00163       // Set up a breakpoint place for interesting msgs
00164       {
00165         switch (tmp_msg.message)
00166         {
00167          case 0x036a: // kickidle
00168          case 0x0362: // setmessagestring
00169          case WM_PAINT:
00170          case WM_KEYUP:
00171          default: f(); break;
00172         }
00173       }
00174 
00175       // pump message, but quit on WM_QUIT
00176       if (!PumpMessage())
00177         return ExitInstance();
00178 
00179       // reset "no idle" state after pumping "normal" message
00180       if (IsIdleMessage(&msgCur))
00181       {
00182         bIdle = TRUE;
00183         lIdleCount = 0;
00184       }
00185     } while (::PeekMessage(&msgCur, NULL, NULL, NULL, PM_NOREMOVE));
00186   }
00187   ASSERT(FALSE);  // not reachable
00188 }
00189 
00190 /////////////////////////////////////////////////////////////////////////////
00191 //: vgui_mfc_app message handlers
00192 void f() {}
00193 
00194 BOOL vgui_mfc_app::OnIdle( LONG lCount )
00195 {
00196   // counts 0 and 1 are used by the MFC framework to update menus and
00197   // such. Process those first.
00198   //
00199   if (CWinApp::OnIdle(lCount))
00200     return TRUE;
00201 
00202   // Send an idle event to each adaptor.
00203   POSITION tmpl_pos = this->GetFirstDocTemplatePosition();
00204   while ( tmpl_pos )
00205   {
00206     CDocTemplate *tmpl = this->GetNextDocTemplate(tmpl_pos);
00207     POSITION doc_pos = tmpl->GetFirstDocPosition();
00208     while ( doc_pos )
00209     {
00210       CDocument *pdoc = tmpl->GetNextDoc(doc_pos);
00211       POSITION view_pos = pdoc->GetFirstViewPosition();
00212       while ( view_pos )
00213       {
00214         vgui_mfc_adaptor *adaptor = (vgui_mfc_adaptor *)pdoc->GetNextView(view_pos);
00215         if ( adaptor->do_idle() ) {
00216           return TRUE;
00217         }
00218       }
00219     }
00220   }
00221 
00222   return FALSE;
00223 }