Click here to Skip to main content
6,295,667 members and growing! (11,295 online)
Email Password   helpLost your password?
Platforms, Frameworks & Libraries » MFC » General     Beginner License: The Code Project Open License (CPOL)

MFC, YOU, your display TUBE... easily !

By aljodav

Your preferred YouTube video is JUST 1 MFC coding line project away from you, or, when 'return' takes you foreward and not backward.
C++ (VC7.1, VC8.0, VC9.0), Windows (Win2K, WinXP, Win2003, Vista), MFC, Dev
Posted:1 Jun 2008
Views:9,675
Bookmarked:8 times
Unedited contribution
Announcements
Loading...
 
Search    
Advanced Search
printPrint   Broken Article?Report       add Share
  Discuss Discuss   Recommend Article Email
21 votes for this article.
Popularity: 2.79 Rating: 2.11 out of 5
10 votes, 47.6%
1
1 vote, 4.8%
2
2 votes, 9.5%
3
3 votes, 14.3%
4
5 votes, 23.8%
5

CEasyShockwaveflash class version CEasyShockwaveflash2 class version

CEasyShockwaveflash3 class version

Introduction

Going straight to the action! This was my goal when I started this article's really huge and challenging project. I wanted to see a YouTube video's motion in full screen right away, with no delay, no advertisement, no related videos, no nothing, just straight to the action!

I started a new Visual C++ project but quickly concluded it was a 50,000 coding lines project. So, cutting down the number of lines was essential. I had to do something, so I started choosing based on criteria, the right technology for implementing such a huge project!

That's why the very powerful, robust and reliable MFC framework is extremely necessary — it cuts the project size by 50%. Now, there are only 25,000 coding lines left. I still needed to cut them down. However, I'll be using an MFC derived class to do a thin wrapping on Shockwave Flash COM Object (also a very powerful, robust and reliable COM object) and this will add up more 49.998% of the total number of coding lines, to the number of coding lines being cut down.

Using a 256 digits astronomical calculator I borrowed from someone, I got the following equation solved:

total % of coding lines cut down = (50 + 49.998)% = 99.998%

Still using the astronomical calculator, I got the exact number of MFC coding lines I must implement:

# of MFC coding lines that I must implement = (100 - 99.998)% ×
    50,000 coding lines = 1 MFC coding line that I must implement.

Fantastic reduction! I only need to implement 1... I repeat... 1... MFC coding line! Now, I can happily say that I've got a project that I very much like implementing! All I have to do is use Shockwave Flash COM Object (through CEasyShockwaveflash) and implement a 1 MFC coding line project !

As I've just said, I'll be using a CEasyShockwaveflash MFC derived class from an old CodeProject's article to do a thin wrapping on Shockwave Flash COM Object. The wrapping is thin, nevertheless, this COM object is, as we all know, very powerful, robust and reliable, which lends to the CEasyShockwaveflash the same attributes.

If you don't have this class somewhere in your computer or your shirt pocket (or somewhere else), I provide the CEasyShockwaveflash2 class (also MFC derived), a simplified version of it, i.e., a simplified version of something already simple. This will add up just very few more lines to the project.

If you are a YouTube video addict, certainly, you don't have 1 preferred video, but 4 of them! And you'd like have them all at once in screen and choose which one to listen/watch to at any moment (maybe all of them at once)! And you don't want any more coding lines just because of that! Because of your addiction, I'll not wait the autumn leaves start to fall to provide you with (but if authorities ask me, I will deny everything) the CEasyShockwaveflash3 class, a templatized version of CEasyShockwaveflash2 class and, except for this class, still keeping the same number of coding lines, i.e., just 1.

Background

No astronomical calculator skill is needed — I asked someone to use it for me. No advanced counting knowledge needed this is a 1, just 1 MFC coding line project.

Is your preferred video's URL too complicated? Nevermind. No preferred YouTube video is needed. I provide one hardcoded that you can change to whatever you like better. However, a very basic MFC programming knowledge is required (though not much).

Building the Project

This project has only one small file, a .cpp one (no resources file, no header files, no pre-compiled header, no nothing else! I almost removed even this one).

The Code, Using CEasyShockwaveflash

Once I was told that every MFC project must have a class derived from CWinApp, and should implement it's virtual InitInstance() method (the application wizard chose the very appropriate name CMFCYOUyourdisplayTUBEeasilyApp). Thus, I must consider, at least, 1 coding line inside this method.

Also, I was told to derive a class from CFrameWnd, for creating the application's main frame window. That means another coding line at least (too bad...). However, sometimes this class isn't really needed.

After a long brainstorm, considering the pros and cons, I concluded that this project doesn't need a class derived from CFrameWnd because all the action will be happening inside CEasyShockwaveflash, deep inside Shockwave Flash COM Object. So, my decision is to use CFrameWnd directly, i.e., without derivation, and have this class object instance as the parent window when creating the ActiveX object.

In total, I'll be using 5 classes in this project, 3 MFC classes and 2 MFC derived ones:

  • CWinApp as base class for CMFCYOUyourdisplayTUBEeasilyApp.
  • CFrameWnd as the main window, directly.
  • CWnd as base class inside CEasyShockwaveflash (and CEasyShockwaveflash2) to stick the ActiveX control on it.
  • CMFCYOUyourdisplayTUBEeasilyApp, the application class.
  • CEasyShockwaveflash (or its substitute class CEasyShockwaveflash2), for (thin) wrapping on the ActiveX control.

Then, considering that the application will host an ActiveX control, the application class code becomes :

class CMFCYOUyourdisplayTUBEeasilyApp : public CWinApp {
    BOOL InitInstance() {
        return (AfxEnableControlContainer(), TRUE)
            && static_cast<CFrameWnd*>(m_pMainWnd = static_cast<CWnd*>(
               new CFrameWnd()))->Create(AfxRegisterWndClass(0)
            , _T("MFC, YOU, your display TUBE... easily !")
            , WS_VISIBLE | WS_POPUP
            , CRect(0, 0, ::GetSystemMetrics(SM_CXSCREEN), ::GetSystemMetrics(SM_CYSCREEN)))
            ;
    }
};

As you can see, I haven't included the ActiveX control yet.

I know that I must instantiate a CEasyShockwaveflash class object; however, I don't have a CFrameWnd derived class to do this inside it. We all know that MFC has not been designed with multiple inheritance in mind, but it can be used, and the compiler supports it... and this comes handy in this situation. Thus, I will use a double inheritance for CMFCYOUyourdisplayTUBEeasilyApp class :

// you must adapt the following path to something appropriate to you
#include "../MFC Shockwaveflashes Easily !/EasyShockwaveflash.h"
class CMFCYOUyourdisplayTUBEeasilyApp : public CWinApp, public CEasyShockwaveflash {
    BOOL InitInstance() {
    // ...
    }
};

The CEasyShockwaveflash class object now is instantiated. It should now be created as the main frame window's child. The only public method inside CEasyShockwaveflash class (and its substitute CEasyShockwaveflash2) is :

BOOL CEasyShockwaveflash::Draw(LPCTSTR pszURL, const CRect& rc, CWnd* pParent,
     BOOL b = TRUE)
//      pszURL : image's URL 
//          rc : control's frame 
//     pParent : control's parent 
//           b : defaults to TRUE. ( note that this does not exist for
//               CEasyShockwaveflash2)
//               TRUE  => redraws the window pointed by pParent. 
//               FALSE => does nothing. 
// 
// returned value : TRUE => ActiveX loaded (not the image). 
//                 FALSE => ActiveX did not load; maybe the ActiveX is not registered.

This method takes care of creating the control as a parent window's child, through CWnd::CreateControl(...) method, which returns TRUE if the ActiveX control (in this case the splendid Macromedia's control) is successfully loaded and ready for use.

Here is the complete and final code using CEasyShockwaveflash for the 50,000 coding lines project, transformed in 1 MFC coding line project with one, only one file (a .cpp one, that contains 2 versions for the same project) :

#include <afxwin.h>
#include <afxdisp.h>
// you must adapt the following path to something appropriate to you
#include "../MFC Shockwaveflashes Easily !/EasyShockwaveflash.h"
class CMFCYOUyourdisplayTUBEeasilyApp : public CWinApp, public CEasyShockwaveflash {
    CRect m_rc; // client rect
    BOOL InitInstance() {
        return (AfxEnableControlContainer(), TRUE)
            && static_cast<CFrameWnd*>(m_pMainWnd = static_cast<CWnd*>(
                new CFrameWnd()))->Create(AfxRegisterWndClass(0)
            , _T("MFC, YOU, your display TUBE... easily !")
            , WS_VISIBLE | WS_POPUP
            , CRect(0, 0, ::GetSystemMetrics(SM_CXSCREEN), ::GetSystemMetrics(SM_CYSCREEN)))
            && Draw(_T("http://www.YouTube.com/v/rhVwTrqcwHs&hl=en"),
                (m_pMainWnd->GetClientRect(m_rc), m_rc), m_pMainWnd, FALSE)
            ;
    }
} theApp;

As you can see, the CMFCYOUyourdisplayTUBEeasilyApp::InitInstance() method contains only 1 semi-colon! And that means to me, 1 (MFC) coding line, i.e., the long return keyword, that will take you foreward, to watch your preferred YouTube video.

If for some reason (impossible as I see it) this long return keyword returns FALSE, the CFrameWnd object instance is properly destroyed and auto deleted. For sure, the same happens when you finish (would you?) the application. As long as you are online, YouTube site presents to you, at the end of the video, a new selection of them, at the end of which, another new selection is presented. So, you have no reason at all to exit this very much nice, although very much simply coded (thanks, MFC), (rich internet?) application.

The executable corresponding to this code is zipped in the file at the top and prefixed with (1).

If we get this long return keyword even longer, we can add some initial visual effect, while keeping the same coding lines number inside CMFCYOUyourdisplayTUBEeasilyApp::InitInstance() method, as follows, in CEasyShockwaveflash2 version...

The Code, Using CEasyShockwaveflash2

Taking the code above as a reference, this part becomes quite trivial. The CEasyShockwaveflash2 class declaration and implementation shall replace the #include-ing CEasyShockwaveflash class, and it's name, the corresponding name in the CMFCYOUyourdisplayTUBEeasilyApp's base class. This code is also in the same .cpp file mentioned above.

Also, for having some initial visual effect, I remove WS_VISIBLE and WS_EX_CLIENTEDGE styles, and then, call the CWnd::AnimateWindow(...) method, resulting in a screen fading in (or should I say out ?) into a blank one.

After editing these few changes, the complete and final code using CEasyShockwaveflash2, becomes :

#define _WIN32_WINNT 0x0500
#include <afxwin.h>
#include <afxdisp.h>
class CEasyShockwaveflash2 {
    class CShockwaveflash : public CWnd {
    public : BOOL Draw(const LPCTSTR u, const CRect& r, CWnd* p) {
            if (!GetSafeHwnd() && CreateControl(_T("ShockwaveFlash.ShockwaveFlash"),
                NULL, WS_VISIBLE | WS_CHILD, r, p, 999)) {
                const BYTE pb1[] = VTS_I4; const BYTE pb2[] = VTS_BSTR;
                InvokeHelper(0x7b, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, pb1, 0);
                InvokeHelper(0x85, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, pb2,
                    _T("transparent"));
                InvokeHelper(0x66, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, pb2, u);
                return TRUE;
            }
            return FALSE;
        }
    } m_swf;
public: BOOL Draw(const LPCTSTR u, const CRect& r, CWnd* p) { return m_swf.Draw(u, r, p); }
};
class CMFCYOUyourdisplayTUBEeasilyApp : public CWinApp, public CEasyShockwaveflash2 {
    CRect m_rc; // client rect
    BOOL InitInstance() {
        return (AfxEnableControlContainer(), TRUE)
            && static_cast<CFrameWnd*>(m_pMainWnd = static_cast<CWnd*>(
                new CFrameWnd()))->Create(AfxRegisterWndClass(0)
            , _T("MFC, YOU, your display TUBE... easily !")
            , WS_POPUP
            , CRect(0, 0, ::GetSystemMetrics(SM_CXSCREEN), ::GetSystemMetrics(SM_CYSCREEN)))
            && m_pMainWnd->ModifyStyleEx(WS_EX_CLIENTEDGE, 0)
            && m_pMainWnd->AnimateWindow(2000, AW_ACTIVATE | AW_BLEND)
            && Draw(_T("http://www.YouTube.com/v/Q8Tiz6INF7I&hl=en"),
                (m_pMainWnd->GetClientRect(m_rc), m_rc), m_pMainWnd)
            ;
    }
} theApp;

Just very few more lines were added to the project, for implementing CEasyShockwaveflash2. The CMFCYOUyourdisplayTUBEeasilyApp::InitInstance() method still contains only 1 semi-colon, indicating 1 (MFC) coding line.

The executable corresponding to this code is zipped in the file at the top and prefixed with (2).

To let the compiler know which version to compile, I use the following :

#define use_ORIGINAL_CEasyShockwaveflash

If this constant is not defined, the second version is compiled. The project's .cpp file brings this line commented out to have the CEasyShockwaveflash2 version compiled.

Right from here, I can see your display screen is big enough to contain, not just one, but four preferred YouTube videos at the same time. So, why not have all four at once? All you need is CEasyShockwaveflash3, made out of CEasyShockwaveflash2 after a very little modification, as shown in the code that follows...

The Code, Using CEasyShockwaveflash3

This new class is a templatized version of CEasyShockwaveflash2, that parameterizes the ActiveX control ID so that we can instantiate 4 controls at once, while keeping few coding lines. Each control is linked to a video, positioned to a different screen quadrant, and can be played simultaneously if you'd like to. Except for the templatization and three more base classes, it is identical to the code above:

#define _WIN32_WINNT 0x0500
#include <afxwin.h>
#include <afxdisp.h>
template<UINT ID>
class CEasyShockwaveflash3 {
    class CShockwaveflash : public CWnd {
    public : BOOL Draw(const LPCTSTR u, const CRect& r, CWnd* p) {
                 if (!GetSafeHwnd() && CreateControl(_T("ShockwaveFlash.ShockwaveFlash"),
                     NULL, WS_VISIBLE | WS_CHILD, r, p, ID)) {
                     const BYTE pb1[] = VTS_I4; const BYTE pb2[] = VTS_BSTR;
                     InvokeHelper(0x7b, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, pb1,    0);
                     InvokeHelper(0x85, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, pb2,
                         _T("transparent"));
                     InvokeHelper(0x66, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, pb2,    u);
                     return TRUE;
                 }
                 return FALSE;
             }
    } m_swf;
public: BOOL Draw(const LPCTSTR u, const CRect& r, CWnd* p) { return m_swf.Draw(u, r, p); }
};
class CMFCYOUyourdisplayTUBEeasilyv2App : public CWinApp
    , public CEasyShockwaveflash3<1001>
    , public CEasyShockwaveflash3<1002>
    , public CEasyShockwaveflash3<1003>
    , public CEasyShockwaveflash3<1004> {
        CRect m_rc;
        BOOL InitInstance() {
            return (AfxEnableControlContainer(), TRUE)
                && static_cast<CFrameWnd*>(m_pMainWnd = static_cast<CWnd*>(
                     new CFrameWnd()))->Create(AfxRegisterWndClass(0)
                , _T("MFC, YOU, your display TUBE... easily ! (v.2)")
                , WS_POPUP
                , CRect(0, 0, ::GetSystemMetrics(SM_CXSCREEN), ::GetSystemMetrics(SM_CYSCREEN)))
                && m_pMainWnd->ModifyStyleEx(WS_EX_CLIENTEDGE, 0)
                && m_pMainWnd->AnimateWindow(2000, AW_ACTIVATE | AW_BLEND)
                && CEasyShockwaveflash3<1001>::Draw(URL1, RC1, m_pMainWnd)
                && CEasyShockwaveflash3<1002>::Draw(URL2, RC2, m_pMainWnd)
                && CEasyShockwaveflash3<1003>::Draw(URL3, RC3, m_pMainWnd)
                && CEasyShockwaveflash3<1004>::Draw(URL4, RC4, m_pMainWnd)
                ;
        }
    } theApp;

// Note:
// 1. URL1 ... URL4 are hardcoded in the project's .cpp file.
// 2. RC1 ... RC4 are CRect objects equal to either of the four screen quadrants.
//

You may note that CMFCYOUyourdisplayTUBEeasilyApp::InitInstance() method still contains only 1 semi-colon, and this still means to me 1 (MFC) coding line.

The executable corresponding to this code is zipped in the file at the top and prefixed with (3).

If your internet connection is as slow as mine, you will experiment many... many seconds before things start happening.

Now you have four times more reasons to keep this application running.

Points of Interest

Inserting an ActiveX control in a CWnd object and then in the main frame window object is quite easy, as we can see in the examples above; the last one shows a CFrameWnd object containing four of them without much effort from MFC programmers, due to very good job from MFC designers. The easiness in implementing this project assures me that MFC technology is the right choice for it.

You will notice that all those fancy things that happen inside the video's area when you access YouTube site still happen when you run this article's executable, due to Shockwave Flash COM Object and YouTube site interaction.

Because Shockwave Flash COM Object is used, you can change the URL in CEasyShockwaveflash(1, 2 & 3)::Draw(...) method to whatever is understandable by this magnificent COM object : .swf, .jpg, .gif, etc... .

If you own a slow internet connection (I doubt it is as slow as mine), you will appreciate very much the capability of watching your preferred YouTube video in offline mode.

A question, inevitably, comes to mind: Can I call this a Rich Internet Application in just 1 MFC coding line project?

History

01/june/2008 : just posted.
05/june/2008 : included CEasyShockwaveflash3 class version for the addicts.
05/july/2008 : included EasyShockwaveflash3.h file for reference when needed. The code is not changed.
23/july/2008 : cosmetic changes.
25/august/2008 : changed the broken link for the fabulous Nat King Cole in CEasyShockwaveflash3 class version, by a new one that, at least at the present date, is working.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

aljodav


Member

Location: Brazil Brazil

Other popular MFC articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 2 of 2 (Total in Forum: 2) (Refresh)FirstPrevNext
GeneralCool project PinmemberDr.Luiji6:06 22 Jul '08  
GeneralRe: Cool project Pinmemberaljodav20:27 22 Jul '08  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 1 Jun 2008
Editor: Sean Ewington
Copyright 2008 by aljodav
Everything else Copyright © CodeProject, 1999-2009
Web16 | Advertise on the Code Project