?
Solved

Critique this approach and provide appropriate alternative if needed please

Posted on 2004-08-31
6
Medium Priority
?
302 Views
Last Modified: 2008-02-01
(this might be an MFC question, but I think it's more a C++ design question)

I'm Using VC++ 6.0 and MFC.

I have a class CMoviePage which is derived from CPropertyPage. This contains graphical controls and what not (it's an AVI player embedded in an application). I also have a class CMovieView which contains all of the filter graph and direct draw related stuff. CMovieView also has a message map setup, containing among others, this:

    ON_MESSAGE( WM_GRAPHNOTIFY, HandleGraphEvent )

which is defined in the header:
    #define WM_GRAPHNOTIFY  WM_USER+13

protected:
    afx_msg void HandleGraphEvent(WPARAM wParam, LPARAM lParam);

which my MediaEvent instance is told to watch:
    g_pMediaEvent->SetNotifyWindow((OAHWND)m_hWnd, WM_GRAPHNOTIFY, 0);


HandleGraphEvent looks like this:

void CMovieView::HandleGraphEvent(WPARAM wParam, LPARAM lParam)
{
LONG evCode, evParam1, evParam2;

HRESULT hr;
// Make sure that we don't access the media event interface
// after it has already been released.
if (g_pMediaEvent)
{
   // Process all queued events
   while(SUCCEEDED(g_pMediaEvent->GetEvent(&evCode, (LONG_PTR *) &evParam1, (LONG_PTR *) &evParam2, 0)))
   {

      hr = g_pMediaEvent->FreeEventParams(evCode, evParam1, evParam2);

      switch (evCode)
      {
          case EC_COMPLETE:
             // when done playing, rewind and pause.
             RewindClip();
           XXXXXXX -> UpdateVideoControlUI();

                break;

             // there are others, not relevant..

          }
      }
   }
}


So - what's that XXXXX? for? This is sorta the guts of the question. HandleGraphEvent() is a method within CMovieView.  CMovieView is contained by CMoviePage, which references it via private a member variable:
    CMovieView* pMovieView;

My UpdateVideoControlUI() is implemented by CMoviePage - as that is a UI related function.

So - the question is, I need CMovieView to be able to call "up into it's containing class", the UpdateVideoControlUI() method. My initial thought was to add a private member variable to CMovieView -- CMoviePage* m_pMoviePage  and then have CMovieView pass a 'this' reference into CMoviePage when it's instantiated or apply it via a non constructor method. That way when CMovieView::HandleGraphEvent() executes, it can execute m_pMovePage->UpdateVideoControlUI(), effectively calling a method in it's containing class.

That is in fact what I did, and yes, it works. But I'm not entirely comfortable with this for the following reasons:

1. I don't really like the idea of a class needing to be hard-wired to a specific containing class. While not doing so I believe is a sound design decision in theory for reuse and what not, I'm not sure how relevant it is in this particular situation.

2. I'm not yet fully comfortable enough with C++ to know if there is not a more appropriate mechanism to accomplish this (some kind of callback or MFC mechanism that I just don't know about.)

thougths?

thanks!
-Paul
0
Comment
Question by:PMH4514
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
  • 2
  • 2
6 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 11945597
>>I don't really like the idea of a class needing to be hard-wired to a specific containing class

Why not? This is a widely used approach. Just think of e.g. modeling a file system where you need to keep a pointer to the containing directory. If you don't like it, you could still send a message to the main window (available via 'AfxGetMainWnd()') to have it update the UI.
0
 

Author Comment

by:PMH4514
ID: 11945662
>>Why not? This is a widely used approach.

good 'nuff! If somebody with your expertise sees nothing wrong with it, then I guess I'm ok with it :-)
0
 
LVL 55

Accepted Solution

by:
Jaime Olivares earned 252 total points
ID: 11947356
You can work like old-style WinAPI, create a callback function, to make your view object independent from container.
Define a static function into your page, it will have some strict argument composition, then you can call callback function, passing parent pointer.

static void CYourPage::YourCallBack function(int arg1, float arg2, void *pointer)
{
    CYourPage *thePage = (CYourPage *)pointer;

    thePage->SomeFunc(arg1, arg2);
}

Now you can reuse your view object with any object that complains the same function structure, not only CYourPage.



0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 

Author Comment

by:PMH4514
ID: 11947420
jamie - yeah, that's more along the lines of what I was thinking would be appropriate. Either or I guess, both perfectly valid it seems given appropriate arguments pro or con.  it's all in context I guess.

0
 
LVL 55

Expert Comment

by:Jaime Olivares
ID: 11947501
Like you, I don't like to make a class dependant from other, because I have troubles when I want to reuse it, since I have many year working for the same contractor, I face this dilemma every day, so I have developed many tricks. The first is the callback, like explained, others are "windows message driven" and even "socket message driven" when working distributed apps.
0
 
LVL 86

Assisted Solution

by:jkr
jkr earned 248 total points
ID: 11948094
>> Like you, I don't like to make a class dependant from other

Actually, that's something I'd support, too, if possible. *I* actually would connect the objects in Question using pure abstract interfaces, thus making instatantions be more like

#define interface struct

interface IMediaEvent {

 virtual void FreeEventParams ( LONG, LONG, LONG) = 0;

   // more...
};


interface IVideoControlUI {

  virtual void Update () = 0;

   // more...
};

CMovieView* pmv = new CMovieView ();

IVideoControlUI* pUI = (IVideoControlUI*) this;

pmv->SetConnections ( pUI, (IMediaEvent*) GetTheMediaEventIF());

and have the containing class inherit from these and implement the methods. This keeps it nice, abstract and reusable :o)

Yet, your approach is not something that could not be used.
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
Suggested Courses
Course of the Month15 days, 15 hours left to enroll

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question