OnIdle processing for specific view in an MDI application

I have an MDI application that has three views (see code excerpt below). Each view may be opened independently and are not automatically opened when the appplication starts. I want to do some background tasks on a specifc view only if the view has been activated and the message pump is idle. I know that I need to use the virtual OnIdle function from withing the CWinApp derived class.

My question is how do I access the proper view and call the appropriate background task. In this case the 'COrderEntryView'

BOOL COrderEntryApp::InitInstance() // partial code below...

                pOrderViewTemplate = new CMultiDocTemplate(
            IDR_ORDERETYPE,
            RUNTIME_CLASS(COrderEntryDoc),
            RUNTIME_CLASS(CChildFrame), // custom MDI child frame
            RUNTIME_CLASS(COrderEntryView));
      AddDocTemplate(pOrderViewTemplate);

      pLineSearchTemplate = new CMultiDocTemplate(
            IDR_LINEVIEWTYPE,
            RUNTIME_CLASS(CLineSearchDoc),
            RUNTIME_CLASS(CLineSearchFrame), // custom MDI child frame
            RUNTIME_CLASS(CLineSearchview));
      AddDocTemplate(pLineSearchTemplate);

      pReportViewTemplate = new CMultiDocTemplate(
            IDR_REPORTVIEWTYPE,
            RUNTIME_CLASS(CReportsDoc),
            RUNTIME_CLASS(CReportsFrame), // custom MDI child frame
            RUNTIME_CLASS(CReportsView));
      AddDocTemplate(pReportViewTemplate);

///////////////////////////////////////////////////////////////////////////////////////////////

BOOL COrderEntryApp::OnIdle(LONG lCount)
{

      if (CWinApp::OnIdle(lCount))
            return TRUE;  

               // If there are no messages in the pump I want to call a function within a particular view to do background processing
              //  For Example COrderEntryView::MyBackGroundTask()


               return TRUE;
}
LVL 4
carlmahonAsked:
Who is Participating?
 
mahesh1402Commented:
>>My question is how do I access the proper view and call the appropriate background task. In this case the 'COrderEntryView'

You can call  GetActiveView( ) from your CFramWnd class to get a pointer to your active view.  you have to cast your pointer from  GetActiveView( ) to your view class.

        CFrameWnd *pFrame = (CFrameWnd *) AfxGetMainWnd();
        COrderEntryView *pView = (COrderEntryView *) pFrame->GetActiveView();
   
-Otherwise you may use following function to get instance of 'Specific' view from your OnIdle function :

CWnd *FindClassView(CRuntimeClass *pViewClass)
{
    CWinApp* pApp = AfxGetApp();        
    CDocTemplate* pTemplate;
    POSITION pos = pApp->GetFirstDocTemplatePosition();
    while (pos != NULL)
    {
        pTemplate = pApp->GetNextDocTemplate(pos);
        ASSERT(pTemplate);

        POSITION pos2 = pTemplate->GetFirstDocPosition();
        while (pos2)
        {
            CDocument* pDoc = pTemplate->GetNextDoc(pos2);
            ASSERT(pDoc);

            POSITION pos3 = pDoc->GetFirstViewPosition();
            while (pos3 != NULL)
            {
                CView* pView = pDoc->GetNextView(pos3);
                ASSERT(pView);
                if (::IsWindow(pView->GetSafeHwnd()))
                {
                    if(pView->IsKindOf(pViewClass))
                    {
                        return pView;
                    }                    
                }
            }
        }
    }
    return NULL;
}


Use it like :---

BOOL COrderEntryApp::OnIdle(LONG lCount)
{

     if (CWinApp::OnIdle(lCount))
          return TRUE;  

    COrderEntryView *pView;
    pView=static_cast<COrderEntryView *>(FindClassView(RUNTIME_CLASS(COrderEntryView)));

   // Invoke function :
  if(pView)
    pView->MyFunction(...)
   
  //.......
 
  return TRUE;
}

-MAHESH
0
 
AndyAinscowFreelance programmer / ConsultantCommented:
Why not use a thread in the view?
0
 
carlmahonAuthor Commented:
MAHESH - Thanks for the code! I knew what had to be done I was just unsure of the casting to get the specific view I needed. The code plugged in and worked perfectly. I will award all points to you.

Thanks for other responses, I had thought about the thread as well too, but since the questions was how to to the onIdle() I will not split points for other alternatives.
0
 
AndyAinscowFreelance programmer / ConsultantCommented:
Fine by me - I mentioned it in case you either hadn't thought of it or just were afraid (too complex to code) of it.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.