Gimme Some Skin… VideoSkins

Introduction

What’s the big deal with skins anyway? 

In addition to looking very cool, they provide many programming advantages
in the development of all kinds of business applications.  Early examples
of skins simply painted the frame of a window to make it more visually
interesting, then someone added the concept of a non-rectangular shape
to the window itself.   And back in 1997, I decided to add one
more component to skins, a powerful SDK interface, namely the Internet
Explorer browser. 

The development time of Visual C++ applications is hampered by the time
it takes to develop the GUI for the application. But if we use a non-rectangular,
skinned Internet Explorer as our GUI for any Visual C++ application we
drastically reduce the development time and add enormous funtionally to
any application. In fact, a company’s artist or web page designer can easily
change or re-program an entire software application without the need for
a programmer which reduces the maintenence of software applications drastically. 
Skinned Internet Explorer interfaces can be displayed in any foreign language
instantly including Chinese and Japanese without increasing the size of
the executable file, and without the need for any additional programming.

In addition, a skinned application can be both client based and server
based making it possible to instantly change any screen or its functionality
on millions of computers without the necessity of the user downloading
a new update. This approach also serves to permanently link any company
with millions of people’s computer so that they can constantly advertise
to their users. And by making the screens of any application non-rectangular
skinned Internet Explorer Interfaces, we make the application self-distributing
and the perfect vehicle for Peer-to-Peer inter-application communications
thus eliminating the need for any bandwidth beyond a dial-up 28.8 modem
Internet connection needed by the company who distributes the software
to conduct their entire Internet business.

And finally, any non-rectangular skinned Internet Explorer application
that is both client and server based must sink the events of the user’s
browser to provide a truly interactive business application that responds
to the user’s Internet activity.  This article and sample code illustrate
the following software techniques:

  • Dynamically Create Microsoft’s WebBrowser Control in Modeless Skinned Dialogs 
  • Dynamically Create The WebBrowser Control in Any Window In Any Application
  • Use A Sink Library To Correctly Connect to Running Instances of Internet
    Explorer 
  • How To Resize Non-Rectangular Skin Regions Dynamically On Any Computer
  • Create Regions from Bitmaps, Save Regions to Files & Create Regions
    from Files
  • How To Play Video Anywhere In Any Window or In Any Shape 
  • Create New GUI Screens in Any Language INSTANTLY On Millions of Computers 
  • Connect Millions of Copies of This Software Via Peer-to-Peer Using DNS
    Datagrams
  • Many Skin Techniques & Tricks Never Seen Anywhere Before 

Application Structure

After you install the sample application make sure you set the pathways
for the 2 projects inside of Visual Studio.  to do this go to the
TOOLS menu in Visual Studio, then the OPTIONS menu, then select DIRECTORIES
and set the pathways for the include files which are located in the VideoSkins
directory, and the SinkLib directory.  If you fail to do this, then
Visual Studio will not be able to find all of the include files.

The overall structure of this sample is indicated below:



The actual screen content, skin region, and functionality of any GUI
screen can come from the installed application (client) or dynamically
from any company’s server or web page since the screen itself is just a
modeless dialog hosting a non-rectangular, skinned instance of the Internet
Explorer Web Browser Control.

Most software based dot com companies today use an Internet Application
that will “listen” to running instances of Internet Explorer (and/or Netscape)
to see if the user is on a “targeted” website indicated either by that
website’s URL or content. And if the user is on such a website, the Internet
Application will spring into action providing some service or product to
the customer. 

Most of these software applications really suck because they do not
correctly “Sink” into Internet Explorer’s events and because their Graphical
User Interfaces(GUI) is hard coded and requires replacing the software
to accommodate the rapid changes of an Internet environment. In addition,
most of these applications are NOT “self-distributing” like Napster’s software
that distributes itself by word of mouth. 

I originally wrote my VideoSkins Peer-to-Peer Internet Application
back in 1997, and made a lot of money marketing various versions of it
to major corporations under many different names with many different “looks”
for a wide variety of business applications. The sample here is a basic
example of my VideoSkins

NOTE: While you are free to use the sample code, you may NOT
use my names VideoSkins, or SlickSkins, on anything you
distribute. These are trademarks and copyrights of my company, William
SerGio & Co., Inc. 

Skinned Modeless Browser Dialogs

I created a Skin Browser Class called “CSkinDlg” that creates modeless
dialogs with a non-rectangular region and a dynamically created Microsoft
WebBrowser Control. 

By using modeless dialogs where the entire surface of the dialog is
covered with a browser we have a GUI screen that is instantly language
independent with incredible graphics and includes powerful XML functionality
without the need to write any code!  In addition, the GUI content
can be either client side based or server based which means that a company
can INSTANTLY change all of the screens and their functionality in their
software in less than one second on millions of computers without ever
re-installing one copy of their software! 

This means that ALL of the screens in this sample application are skinned,
non-rectangular browser windows filled with .htm files which allows for
spectacular looking screens that can be easily modified by anyone either
client side or server side. 

I have made millions of dollars from the sales of my custom skinned
peer-to-peer software programs that I have written and the key factors
in their sales was the “Skinned GUI.”   Skins provide a lot more
than simply a slick looking screen in that they drastically reduce the
cost and development time of any application, and allow a company to provide
information to installed applications on millions of computers instantly
without using anymore bandwidth than a dial-up modem!  That is why
“Skinned Server Based Business Applications” are so hot right now. 

Skinned Modeless Application Bars

I usually add a skinned Application Bar with a dynamically created WebBrowser
Control to this apllication as well.  I left it out to try to make
this sample easier to follow but I will either add it in a future update
to this article, or post another separate article and project on creating
a Skinned Application Bar, or “SkinBar
or “WebBar
as I call call them.

The advantage to making the entire face of any application bar a web
browser window is that anyone including an artist can completely change
the look and functionality of the SkinBar
remotely on millions of computers without the need of the user ever downloading
and installing any update.

Sample Wet Logo

On the pop-up menu from the icon in the taskbar, you will see a menu choice
entitled “Sample Wet Logo” which demonstrates several interesting effects. 
You will notice that as you move your mouse over the logo “SerGio” you
will get a nice water effect that is implemented with a Java applet but
could just as easily been done with DHTML.  When you press the “More”
link you will see how regions can be easily switched. And when you click
on the close button in the upper-left hand corner of the skin you will
see how to launch an instance of the Internet Explorer Browser through
an interface instead of using “ShellExecute” which, in turn, through the
Sink Library, will launch an animation in the Tray icon!

If you click anywhere on the picture of my head, you will notice that
the Internet Explorer GUI is “draggable” so that you can drag the ENTIRE
skin browser window anywhere on the desktop. 

The samples are simply meant to illustrate the incredible interfaces
you can achieve easily by using Internet Explorer as your GUI in your C++,
Visual C++, Visual Basic, and Visual FoxPro programs.

Creating Regions Dynamically

There are a lot of different ways to setup the skin and its region. In
this example, I have illustrated 2 of these ways:

  • Reading .htm and region file from a directory or zipped file that is located
    either on client or a server to create the skin. This allows you to create
    the region first while the browser is loading on a separate thread.
  • Reading .htm file from a directory or zipped file that is located either
    on client or a server, and then retrieving the region from the “OnDocumentComplete”
    event of the WebBrowser control. This technique means that the region can
    be read dynamically from an html tag that specifies the “.rgn” file or
    art file located on a remote server to use for the region and is better
    suited to some business applications.
  • For example, you could place the name of the region file, without the extension
    “.rgn,” in the <TITLE> tag or any other tag and extract the region file
    name and/or the region data structure itself to be used to create the non-rectangular
    shape of the WebBrowser Control or CHtmlView from the OnDocumentComplete
    Event. 

    I included a number of methods for creating regions in this sample including:

    // Create region from region file(.rgn)
    BOOL File2Rgn(HWND hSkin, LPCSTR lpRgnPath);
    
    // Create region from DLL region resource
    BOOL Dll2Rgn(HWND hSkin, LPCSTR lpDLLFile);
    
    // Create region from a Resource file
    BOOL Res2Rgn(HWND hSkin, UINT nRegionID);
    
    // Create region from a Bimap(file or resource)
    BOOL Bmp2Rgn(HWND hSkin,
                 UINT uBmpRes,
                 CString csBmpFile,
                 CString csRgnFile,
                 COLORREF cTolerance);
    

    Saving Regions As Files

    The menu that pops up from the icon in the taskbar has a selection
    called “Region from Bitmap” that will create a region from a bitmap
    and save that region to a file with the same name, in the same directory
    as the bitmap but with the extension “.rgn” so you can create and save
    your own region files.

    Dynamic Re-Sizing of Regions

    I resize  the non-rectangular regions dynamically using using
    a STATIC DATA FILE for the region and “GetRgnBox(LPRECT lpRect )” to resize
    the region so that it fits every screen exactly on any monitor or operating
    system. 

    You can include a region file (.rgn) as you would a .gif or .jpg file
    art file and the program will retrieve the region file from any website
    as it would any image file since region files are only 3k or 4k in size
    and can reside either on the client computer or server side. 

    How To Make Internet Explorer GUI “Draggable”

    One important requirement is that we make our Internet Explorer GUI “draggable”
    so that users can click on some image, region or text INSIDE OF the displayed
    web page and, holding down their mouse, drag the ENTIRE browser window
    anywhere on the desktop. There are several ways to do this but the easiestr
    and most reliable I’ve found so far is the following:

    // Use OnBeforeNavigae2 to trap the mousedown event
    // We check URL for: "EVENT:csAction:csData:csQuestionMark"
    
    void CSkinDlg::OnBeforeNavigate2(LPDISPATCH pDisp,
                                     VARIANT FAR* URL,
                                     VARIANT FAR* Flags,
                                     VARIANT FAR* TargetFrameName,
                                     VARIANT FAR* PostData,
                                     VARIANT FAR* Headers,
                                     BOOL FAR* Cancel)
    {
     try
     {
      csTestUrl = (CString)URL->bstrVal;
      AfxExtractSubString(csEvent, csTestUrl, 0, (TCHAR)':');
      AfxExtractSubString(csAction, csTestUrl, 1, (TCHAR)':');
      AfxExtractSubString(csData, csTestUrl, 2, (TCHAR)':');
      AfxExtractSubString(csQuestionMark, csTestUrl, 3, (TCHAR)':');
     }
     catch( ... )
     {
      return;
     }
    
     csEvent.MakeUpper();
    
     if ( csEvent != "EVENT" ) {return;}
    
     try
     {
      if ( csAction == "DRAG" )
      {
       *Cancel = TRUE;
       ReleaseCapture();
    
       // if (WM_LBUTTONDOWN && HTCLIENT
       // && !::IsZoomed(GetSafeHwnd()) ){}
    
       ::SendMessage(GetSafeHwnd(), WM_NCLBUTTONDOWN, HTCAPTION, NULL);
       // Update user interface if desired
       // AfxGetApp()->OnIdle(0);
      }
      // etc.
     }
     catch( ... )
     {
      return;
     }
    }
    

    The CORRECT WAY to prevent the right-mouse click from popping up a menu
    in a skin dialog is to add the following to the <body> tag:

    <body... oncontextmenu="return false">
    

    Another subtle feature that you must address is that when you drag the
    skin around is the problem of a LARGE rectangle that appears around the
    skin as you drag it thanks to Microsoft’s lack of attention to making things
    look good.  To solve this problem you need to the “SetViewWhileDrag”
    property and to make sure there is a registry entry for it as well. 
    This is done as follows:

    // Set registry "HKEY/Control Panel/Desktop/DragFullWindows" 
    // with string value "1" and set "SystemParametersInfo"
    SystemParametersInfo(SPI_SETDRAGFULLWINDOWS,
                         1,
                         NULL,
                         SPIF_SENDWININICHANGE);
    

    Video AnyWhere

    This feature allows you to play video in ANY button, window, taskbar, popup,
    namely ANYTHING on your desktop!  Simply drag the video tool over
    what you want to play the video inside of and select the video!

    Skinned Video

    I could easily fill a book with techniques on playing video in different
    ways but I decided for the sake of illustration here to include a very
    simple wrapper for playing video.  The idea is that you can skin any
    window with a non-rectangular shape that you want to play video inside
    of and that window can be either one you created or any other apllication’s
    window on the desktop. To illustrate the sample application let’s you play
    video in the taskbar and some other places. 

    A simple way of playing video in a skin is to simply use an <EMBED>
    tag and play the video inside of the web page being used for the skin itself.
    If you want to apply a non-rectangular region to the <EMBED> tag so
    that another image in the .htm file can shape its region you can do this
    easily by setting the property of the embedded object to “windowless.” 

    Another technique that I will illustrate in greater detail in an update
    to this article is to simply create a window dynamically inside of the
    skinned dialog and apply a region to it. 

    Multimedia programming in general is accomplished through a series of
    interfaces, or APIs that applications can utilize for this purpose. The
    Video.cpp class allows you to use the high-level interface based on the
    MCIWnd window class, and the mid-level interface called  the Media
    Control Interface, or MCI which provides a device-independent command-message
    and command-string interface for the playback and recording of audio and
    visual data.

    I spent a lot of time developing and perfecting ways of legally broadcasting
    large amounts of video to millions of computers without the need for any
    bandwidth using some clever peer-to-peer tricks. In a future update of
    this sample if there is any interest I might include some of those techniques.

    The reader will have to supply their own sample videos to test out some
    of the cool features in this project because I decided that packing cool
    sample video clips like “the chimp smelling his butt” would just make the
    zip file unnecessarily large. But I am sure the reader can come up with
    their own videos.

    “Internet Explorer Look-A-Like” MainFrame

    I decided to give users the ability to make the MainFrame window appear
    or dissappear and to make it look and behave exactly like the Internet
    Explorer Browser from Microsoft so users could distribute their own Internet
    Explorer look-a-like except for the change in logos.  This chamelion
    effect is controlled in the “videoskins.ini” file by setting the “ShowMainFrame”
    parameter to “1” to show the browser or “0” to hide it as follows:

    // Set the value of ShowMainFrame to turn 
    // on & off browser
    [Setup]
    ShowMainFrame=1
    

    The starting point I use for any Internet Application is a MainFrame Application
    where the “MainFrame” itself can be either hidden or used as one of the
    windows or screens in the application.  In this sample, I give the
    user the ability to make the MainFrame look exactly like Internet Explorer
    except for the Microsoft logo to provide a customizable “look-a-like” Internet
    Explorer Browser for users. This feature can be turned “on” or “off” in
    the file “videoskins.ini” that contains other setup parameters as well. 

    NOTE: All of your skins will be children of the MainFrame window
    which is perfect when you set “ShowMainFrame=no”.  If you want to
    show the Internet Explorer “look-a-like” MainFrame window, and you do NOT
    want the skins to appear inside of the MainFrame window, simply create
    the skins from an invisible parent window that is parent to both the visible
    MainFrame and the skins.

    Most of the time you will never want to show the Internet Explorer “look-a-like”
    MainFrame window but simply use it ir an invisible parent for messaging.

    The idea is to use the message handling ability of the MainFrame to
    receive events from a “IE Event Sink” library reporting events in any running
    instance of Internet Explorer, process those events, and control the behavior
    of the Graphical User interface(GUI) which consists of Modeless Skinned
    Browser Dialogs. 

    IE Event Sink Library

    I created an IE Event Sink Library that I use in my applications instead
    of a dll to sink the events coming from multiple running instances of Internet
    Explorer. 

    Don’t use a “Browser Helper Object” which the browser needs to instantiate
    to connect to the events of Internet explorer for many reasons including
    the fact that it is buggy and requires that if you really want it to work
    you need to place your registry entry ABOVE all of the other registry entries
    for helper objects.  However, you can use a browser helper dll to
    launch your software whenever the user launches Internet Explorer and/or
    an Explorer Shell but you would NEVER use it to connect or sink events
    of Internet explorer!  NEVER! 

    Get a reference to ShellWindows interface that keeps track of all the
    shell browsers (both Windows Explorer and Internet Explorer instances)
    that also notifies you whenever a new Explorer instance is created or deleted. 

    HRESULT thRes =
     m_spSHWinds.CreateInstance(__uuidof(SHDocVw::ShellWindows));
    
    CSBOOL blnRes =
     m_IEEventSink.Advise(m_spSHWinds,
                          IID_IDShellWindowsEventSink);
    

    When you enumerate these Explorer instances, you can query whether as to
    whether the entry supports the IWebBrowser interface. If it does, it could
    either be a WebBrowser or a ShellBrowser. Once you obtain the IWebBrowser2
    interface, you can either use that interface to manipulate (and communicate
    with) the Explorer instance or you can trap its events using the DWebBrowserEvents. 

    System Tray

    Nothing fancy here except to note that we use the System Tray as the main
    controlling interface for the sample and that we must handle all of the
    mouse events in the MainFrame itself for a number of reasons. The most
    important thing to understand is that the new trend is to not use Microsoft’s
    CMenu class for those typical crappy-looking popup menus, but instead to
    use a Skinned Modeless Browser Dialog which gives you incredible looking
    skinned menus over those of the CMenu class. 

    Peer-to-Peer(P2P)

    Most of the many applications I’ve written included some form of Peer-to-Peer
    servers for both exchange of data as well as a means of distributing updates
    to millions of already installed applications without using any significant
    bandwidth. I left out the Peer-to-Peer sample code from this sample because
    it has too many good tricks that I did not want to give away at this time. 
    But this sample application has been structed to easily include any peer-to-peer
    code you want to add. Two important tricks that I learned with peer-to-peer
    is to model your peer-to-peer code on Network News Protocol (NNTP) since
    news servers are the best prototype you can find, and to use modified DNS
    datagrams for communication between the peers to determine what data files
    each peer has from any given peer. 

    All P2P communication must be asynchronous and non-blocking I don’t
    recommend using Microsoft’s CAsyncSocket because it’s just as easy to write
    asynchronous I/O code straight to the Winsock API. In cases where you need
    to block, don’t use Microsoft’s CSocket class which is a subclass of CAsyncSocket
    that “fakes” blocking I/O using asynchronous sockets by using a message
    pump every time it gets a WSAEWOULDBLOCK error which can cause bizarre
    reentrancy effects. While CSocket is “blocking”, it’s pumping window messages,
    which allows a message to trigger another call to the blocking CSocket
    object.  Since true blocking sockets are easy to create using Winsock,
    why would you want to use buggy bogus blocking sockets instead of bug-free
    sockets that really block?

    Utilities

    In this sample I’ve placed the various utilities in MainFrame itself but
    you can create a separate COM DLL just for utility routines if you prefer
    which is what I’ve also done in many applcations.

    And Finally…

  • In future articles I would like to discuss how to:
    • Create a COM DLL for displaying skins
    • Create TRUE alpha-channel video animations better than Microsoft’s Agent
    • Add cool peer-to-peer features for legally sampling music videos
    • New skin techniques and skin creation tools for the Windows Media Player
      and Real Player
    • New skin techniques for creating multiple desktops in Windows 2000
    • Sample code to sink events from the Netscape’s browser
    • How to add a dynamic translucent drop shadow to skins
    • New techniques I developed for broadcasting video to millions of computers
      in just minutes using virtually no bandwidth! 

    If you have any question, please feel free to
    contact me.

    Downloads

    Download demo and source code – 605 Kb

    More by Author

    Get the Free Newsletter!

    Subscribe to Developer Insider for top news, trends & analysis

    Must Read