Improve company productivity with a Business Account.Sign Up

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 312
  • Last Modified:

Critique this approach and provide appropriate alternative if needed please

(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
PMH4514
Asked:
PMH4514
  • 2
  • 2
  • 2
2 Solutions
 
jkrCommented:
>>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
 
PMH4514Author Commented:
>>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
 
Jaime OlivaresSoftware ArchitectCommented:
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
Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

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.

 
PMH4514Author Commented:
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
 
Jaime OlivaresSoftware ArchitectCommented:
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
 
jkrCommented:
>> 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
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.

Join & Write a Comment

Featured Post

Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

  • 2
  • 2
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now