Click here to Skip to main content
6,595,854 members and growing! (17,530 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 a one MFC code line project away from you, or, when 'return' takes you forwards and not backwards.
VC7.1, VC8.0, VC9.0Win2K, WinXP, Win2003, Vista, MFC, Flash, Dev
Version:2 (See All)
Posted:1 Jun 2008
Views:11,548
Bookmarked:8 times
Announcements
Loading...
 
Search    
Advanced Search
Add to IE Search
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
20 votes for this article.
Popularity: 2.80 Rating: 2.15 out of 5
9 votes, 45.0%
1
1 vote, 5.0%
2
2 votes, 10.0%
3
3 votes, 15.0%
4
5 votes, 25.0%
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 code 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 code lines left. I still needed to cut them down. However, I'll be using an MFC derived class to do a thin wrapping on the Shockwave Flash COM Object (also a very powerful, robust, and reliable COM object), and this will add up more than 49.998% of the total number of code lines, to the number of code lines being cut down.

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

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

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

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

Fantastic reduction! I only need to implement 1... I repeat... 1... MFC code 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 the Shockwave Flash COM Object (through CEasyShockwaveflash) and implement a one MFC code line project!

As I've just said, I'll be using a CEasyShockwaveflash MFC derived class from an old CodeProject article to do a thin wrapping on the 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 a 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 code lines just because of that! Because of your addiction, I'll not wait the autumn leaves to start to fall to provide you with (but if authorities ask me, I will deny everything) the CEasyShockwaveflash3 class, a templatized version of the CEasyShockwaveflash2 class and, except for this class, still keeping the same number of code 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 line MFC coding project.

Is your preferred video's URL too complicated? Never mind. No preferred YouTube video is needed. I provide a hardcoded one 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 headers, 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 its virtual InitInstance() method (the application wizard chose the very appropriate name CMFCYOUyourdisplayTUBEeasilyApp). Thus, I must consider, at least, one code 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 code 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 the 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 five classes in this project: three MFC classes and two 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 double inheritance for the 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 the 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 the CWnd::CreateControl(...) method, which returns TRUE if the ActiveX control (in this case, the splendid Macromedia control) is successfully loaded and ready for use.

Here is the complete and final code using CEasyShockwaveflash for the 50,000 code lines project, transformed in to a one MFC code line project with one, and only one file (a .cpp one, that contains two 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 one semi-colon! And that means to me, one (MFC) code line, i.e., the long return keyword, that will take you forward, 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 nice, although very simply coded (thanks to 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 code lines number inside the CMFCYOUyourdisplayTUBEeasilyApp::InitInstance() method, as follows, in the CEasyShockwaveflash2 version...

The Code, Using CEasyShockwaveflash2

Taking the code above as a reference, this part becomes quite trivial. The CEasyShockwaveflash2 class declaration and implementation will replace the #include-ing CEasyShockwaveflash class, and its 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 the 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 a few more lines were added to the project, for implementing CEasyShockwaveflash2. The CMFCYOUyourdisplayTUBEeasilyApp::InitInstance() method still contains only one semi-colon, indicating one (MFC) code 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 four controls at once, while keeping just a few code 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 the CMFCYOUyourdisplayTUBEeasilyApp::InitInstance() method still contains only one semi-colon, and this still means to me one (MFC) code 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 the YouTube site still happens when you run this article's executable, due to the Shockwave Flash COM Object and the YouTube site interaction.

Because the Shockwave Flash COM Object is used, you can change the URL in the 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 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 one MFC code line project?

History

  • 01/June/2008: Just posted.
  • 05/June/2008: Included the CEasyShockwaveflash3 class version for the addicts.
  • 05/July/2008: Included the 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 the 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 4 of 4 (Total in Forum: 4) (Refresh)FirstPrevNext
Generalhow to put a seek bar in shockwave ? Pinmemberapurv14620:38 30 Jul '09  
AnswerRe: how to put a seek bar in shockwave ? Pinmemberaljodav20:59 2 Aug '09  
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: Smitha Vijayan
Copyright 2008 by aljodav
Everything else Copyright © CodeProject, 1999-2009
Web22 | Advertise on the Code Project