home *** CD-ROM | disk | FTP | other *** search
- //---------------------------------------------------------------------------
- // MsgLoop.cpp
- //---------------------------------------------------------------------------
- // Implementation of message loop for application. Includes implementation
- // of IOleComponentManager.
- //---------------------------------------------------------------------------
- // (C) Copyright 1995-1996 by Microsoft Corporation. All rights reserved.
- //
- // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
- // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
- // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
- // PARTICULAR PURPOSE.
- //---------------------------------------------------------------------------
-
- #include "Main.h"
- #include "MsgLoop.h"
-
-
- //---------------------------------------------------------------------------
- // DEBUG info
- //---------------------------------------------------------------------------
- SZTHISFILE
-
-
- //---------------------------------------------------------------------------
- //
- //---------------------------------------------------------------------------
- CMsgLoop::CMsgLoop
- (
- HWND hwnd
- )
- {
- INIT_SIGNATURE(SIG_MsgLoop);
-
- for (int i=0; i<cCOMP; i++)
- m_rgcomp[i].pcomp = NULL;
-
- m_icompActive = icompNIL;
- m_fInState = FALSE;
- m_icompState = icompNIL;
- m_uStateID = 0;
- m_fScrptReset = FALSE;
- m_fQuitting = FALSE;
- m_hwnd = hwnd;
- m_haccel = NULL; // Load accel table here
- m_icompMsgLoop =icompNIL;
-
- m_cref = 1;
- m_cMsgLoop = 0;
- }
-
-
- //---------------------------------------------------------------------------
- //
- //---------------------------------------------------------------------------
- CMsgLoop::~CMsgLoop
- (
- void
- )
- {
- CHECK_SIGNATURE(SIG_MsgLoop);
-
- for (int i=0; i<cCOMP; i++)
- if (m_rgcomp[i].pcomp)
- {
- m_rgcomp[i].pcomp->Terminate();
- RELEASEPTR(m_rgcomp[i].pcomp);
- }
-
- DESTROY_SIGNATURE(SIG_MsgLoop);
- }
-
-
- //***************************************************************************
- // IUnknown methods
- //***************************************************************************
-
- //---------------------------------------------------------------------------
- //
- //---------------------------------------------------------------------------
- STDMETHODIMP CMsgLoop::QueryInterface
- (
- REFIID riid,
- void **ppvObj
- )
- {
- *ppvObj = NULL;
-
- if (riid == IID_IUnknown)
- *ppvObj = (LPVOID)(IUnknown *)(IOleComponentManager *)this;
- else if (riid == IID_IOleComponentManager)
- *ppvObj = (LPVOID)(IOleComponentManager *)this;
-
- if (*ppvObj)
- {
- this->AddRef();
- return S_OK;
- }
-
- return E_NOINTERFACE;
- }
-
-
- //---------------------------------------------------------------------------
- //
- //---------------------------------------------------------------------------
- STDMETHODIMP_(ULONG) CMsgLoop::AddRef
- (
- void
- )
- {
- CHECK_SIGNATURE(SIG_MsgLoop);
- return ++m_cref;
- }
-
-
- //---------------------------------------------------------------------------
- //
- //---------------------------------------------------------------------------
- STDMETHODIMP_(ULONG) CMsgLoop::Release
- (
- void
- )
- {
- CHECK_SIGNATURE(SIG_MsgLoop);
- if (--m_cref)
- return m_cref;
-
- delete this;
- return 0;
- }
-
-
-
- //***************************************************************************
- // IOleComponentManager Methods
- //***************************************************************************
-
- //---------------------------------------------------------------------------
- //
- //---------------------------------------------------------------------------
- STDMETHODIMP CMsgLoop::QueryService
- (
- REFGUID guidService,
- REFIID iid,
- void **ppvObjOut
- )
- {
- *ppvObjOut = NULL;
- return E_NOINTERFACE;
- }
-
-
- //---------------------------------------------------------------------------
- //
- //---------------------------------------------------------------------------
- STDMETHODIMP_(BOOL) CMsgLoop::FRegisterComponent
- (
- IOleComponent *piComponent,
- const CMGRRINFO *pcrinfo,
- DWORD *pdwCompIDOut
- )
- {
- for (int i=0; i<cCOMP; i++)
- if (!m_rgcomp[i].pcomp)
- {
- piComponent->AddRef();
- m_rgcomp[i].pcomp = piComponent;
- *pdwCompIDOut = i;
- return TRUE;
- }
-
- FAIL("Out of room!");
- return FALSE;
- }
-
-
- //---------------------------------------------------------------------------
- //
- //---------------------------------------------------------------------------
- STDMETHODIMP_(BOOL) CMsgLoop::FRevokeComponent
- (
- DWORD icomp
- )
- {
- ASSERT(m_rgcomp[icomp].pcomp, "Bogus icomp");
- RELEASEPTR(m_rgcomp[icomp].pcomp);
- if (m_icompActive == icomp)
- m_icompActive = icompNIL;
- if (m_icompMsgLoop == icomp)
- m_icompMsgLoop = icompNIL;
- return TRUE;
- }
-
-
- //---------------------------------------------------------------------------
- //
- //---------------------------------------------------------------------------
- STDMETHODIMP_(BOOL) CMsgLoop::FUpdateComponentRegistration
- (
- DWORD dwComponentID,
- const CMGRRINFO *pcrinfo
- )
- {
- // Don't track info anyway, so pretend it worked:
- return TRUE;
- }
-
-
- //---------------------------------------------------------------------------
- //
- //---------------------------------------------------------------------------
- STDMETHODIMP_(void) CMsgLoop::OnComponentActivate
- (
- DWORD icomp
- )
- {
- ASSERT(m_rgcomp[icomp].pcomp, "Bad icomp");
- m_icompActive = icomp;
- return;
- }
-
-
- //---------------------------------------------------------------------------
- //
- //---------------------------------------------------------------------------
- STDMETHODIMP_(BOOL) CMsgLoop::FSetTrackingComponent
- (
- DWORD dwComponentID,
- BOOL fTrack
- )
- {
- // UNDONE: Need to support
- return FALSE;
- }
-
-
- //---------------------------------------------------------------------------
- //
- //---------------------------------------------------------------------------
- STDMETHODIMP_(void) CMsgLoop::OnComponentEnterState
- (
- DWORD icomp,
- ULONG uStateID,
- ULONG uContext,
- ULONG cpicmExclude,
- IOleComponentManager **rgpicmExclude,
- DWORD dwReserved
- )
- {
- ASSERT(m_rgcomp[icomp].pcomp, "Bad icomp");
- ASSERT(uStateID==cmgrstateModal, "Not modal state");
- ASSERT(!m_fInState, "Nested modal states");
-
- m_icompState = icomp;
- m_fInState = TRUE;
- m_uStateID = uStateID;
- if (uStateID == cmgrstateModal)
- EnableWindow(m_hwnd, FALSE);
- }
-
-
- //---------------------------------------------------------------------------
- //
- //---------------------------------------------------------------------------
- STDMETHODIMP_(BOOL) CMsgLoop::FOnComponentExitState
- (
- DWORD icomp,
- ULONG uStateID,
- ULONG uContext,
- ULONG cpicmExclude,
- IOleComponentManager **rgpicmExclude
- )
- {
- ASSERT(m_rgcomp[icomp].pcomp, "Bad icomp");
- ASSERT(icomp==(DWORD)m_icompState, "icomp didn't own state");
- ASSERT(uStateID==cmgrstateModal, "Not modal state");
- ASSERT(uStateID==m_uStateID, "non-matching modal states on pop");
- ASSERT(m_fInState, "underflow of modal state");
-
- m_fInState = FALSE;
- m_icompState = icompNIL;
- if (uStateID == cmgrstateModal)
- EnableWindow(m_hwnd, TRUE);
- return TRUE;
- }
-
-
- //---------------------------------------------------------------------------
- //
- //---------------------------------------------------------------------------
- STDMETHODIMP_(BOOL) CMsgLoop::FInState
- (
- ULONG uStateID,
- void *pvoid
- )
- {
- return m_fInState && uStateID==m_uStateID;
- }
-
-
- //---------------------------------------------------------------------------
- //
- //---------------------------------------------------------------------------
- STDMETHODIMP_(BOOL) CMsgLoop::FContinueIdle
- (
- void
- )
- {
- return FALSE;
- }
-
-
- //---------------------------------------------------------------------------
- //
- //---------------------------------------------------------------------------
- STDMETHODIMP_(BOOL) CMsgLoop::FPushMessageLoop
- (
- DWORD icomp,
- ULONG uReason,
- void *pvLoopData
- )
- {
- MessageLoop(icomp, uReason, pvLoopData);
- return TRUE;
- }
-
-
- //---------------------------------------------------------------------------
- //
- //---------------------------------------------------------------------------
- STDMETHODIMP_(BOOL) CMsgLoop::FCreateSubComponentManager
- (
- IUnknown *piunkOuter,
- IUnknown *piunkServProv,
- REFIID riid,
- void **ppvObj
- )
- {
- ASSERT(!piunkOuter, "Don't support aggre. SubCompMgr");
- HRESULT hr = this->QueryInterface(riid, ppvObj);
- return !FAILED(hr);
- }
-
-
- //---------------------------------------------------------------------------
- //
- //---------------------------------------------------------------------------
- STDMETHODIMP_(BOOL) CMsgLoop::FGetParentComponentManager
- (
- IOleComponentManager **ppicm
- )
- {
- // UNDONE: Need to implement
- return FALSE;
- }
-
-
- //---------------------------------------------------------------------------
- //
- //---------------------------------------------------------------------------
- STDMETHODIMP_(BOOL) CMsgLoop::FGetActiveComponent
- (
- DWORD dwReserved,
- IOleComponent **ppcompOut
- )
- {
- // Do we have an active component?
- if (m_icompActive == icompNIL)
- {
- *ppcompOut = NULL;
- return FALSE;
- }
-
- // Yes, return it
- *ppcompOut = m_rgcomp[m_icompActive].pcomp;
- (*ppcompOut)->AddRef(); // for *ppcompOut
- return TRUE;
- }
-
-
-
- //***************************************************************************
- // Message Loop Implementation
- //***************************************************************************
-
- //---------------------------------------------------------------------------
- // This pushes a new message loop.
- //---------------------------------------------------------------------------
- void CMsgLoop::MessageLoop
- (
- DWORD icomp,
- ULONG uReason,
- void *pvLoopData
- )
- {
- BOOL fExitLoop = FALSE;
-
- m_cMsgLoop++;
-
- while (!fExitLoop)
- fExitLoop = PumpMessage(icomp, uReason, pvLoopData);
-
- m_cMsgLoop--;
-
- if (!m_cMsgLoop)
- m_fScrptReset = FALSE;
- }
-
-
- //---------------------------------------------------------------------------
- // This processes one message.
- // Returns TRUE if it is time to exit the current message loop.
- //---------------------------------------------------------------------------
- BOOL CMsgLoop::PumpMessage
- (
- DWORD icomp,
- ULONG uReason,
- void *pvLoopData
- )
- {
- BOOL fExitLoop = FALSE;
- BOOL fMsg;
- MSG msg;
-
- fMsg = PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE);
- if (fMsg)
- {
- if (msg.message == WM_QUIT)
- {
- // Since we're not really an app, re-post the WM_QUIT message, until
- // we can pop any msgloops we've pushed.
- if (m_cMsgLoop)
- PostQuitMessage(msg.wParam);
- return TRUE;
- }
- else
- ProcessMessage(&msg);
- }
-
- if (m_fScrptReset)
- return TRUE;
-
- // A Component told us to push this message loop, and so we
- // ask them whether it's time yet to exit the loop
- fExitLoop = !m_rgcomp[icomp].pcomp->FContinueMessageLoop(uReason, pvLoopData);
-
- if (!fMsg && !fExitLoop)
- {
- // There weren't any messages and we don't need to exit this message
- // loop yet. Therefore, now is the right time to do idle processing
- DoIdleProcessing();
- WaitMessage();
- }
-
- return fExitLoop;
- }
-
-
- //---------------------------------------------------------------------------
- // This processes one message.
- //---------------------------------------------------------------------------
- void CMsgLoop::ProcessMessage
- (
- MSG *pmsg
- )
- {
- // When a component is active give it a chance to translate
- // its accelerators.
- if (m_icompActive != icompNIL)
- {
- if (!m_rgcomp[m_icompActive].pcomp->FPreTranslateMessage(pmsg))
- {
- TranslateMessage(pmsg); // Translates virtual key codes
- DispatchMessage(pmsg); // Dispatches message to window
- }
- }
- else
- {
- if (!TranslateAccelerator(m_hwnd, m_haccel, pmsg))
- {
- TranslateMessage(pmsg); // Translates virtual key codes
- DispatchMessage(pmsg); // Dispatches message to window
- }
- }
- }
-
-
- //---------------------------------------------------------------------------
- // This is called at idle time.
- //---------------------------------------------------------------------------
- void CMsgLoop::DoIdleProcessing
- (
- void
- )
- {
- MSG msg;
- BOOL fContinue = TRUE;
-
- while (fContinue && !PeekMessage(&msg, NULL, NULL, NULL, PM_NOREMOVE))
- {
- fContinue = DoIdle();
- }
- }
-
-
- //---------------------------------------------------------------------------
- //
- //---------------------------------------------------------------------------
- BOOL CMsgLoop::DoIdle
- (
- void
- )
- {
- int i;
- BOOL fDidWork = FALSE;
-
- // if we have periodic idle tasks that to be done,
- // do them and return TRUE.
- for (i=0; i<cCOMP; i++)
- {
- if (m_rgcomp[i].pcomp)
- if (m_rgcomp[i].pcomp->FDoIdle(cmgridlefPeriodic))
- fDidWork = TRUE;
- if (fDidWork)
- return TRUE;
- }
-
- // if any high priority idle tasks need to be done,
- // do it, and return TRUE.
- for (i=0; i<cCOMP; i++)
- {
- if (m_rgcomp[i].pcomp)
- if (m_rgcomp[i].pcomp->FDoIdle(cmgridlefPriority))
- fDidWork = TRUE;
- if (fDidWork)
- return TRUE;
- }
-
- // if any lower priority idle tasks need to be done,
- // do it, and return TRUE.
- for (i=0; i<cCOMP; i++)
- {
- if (m_rgcomp[i].pcomp)
- if (m_rgcomp[i].pcomp->FDoIdle(cmgridlefNonPeriodic))
- fDidWork = TRUE;
- if (fDidWork)
- return TRUE;
- }
-
- return FALSE;
- }
-
- //--- EOF -------------------------------------------------------------------
-