SlickSkins™... Give Your Browser A New Shape!
by Bill
SerGio
Bill
SerGio is a CTO, Project Leader, and Programmer
Visual C++ and Java. He specializes in GUI, 3D-Scaled Vector Graphics, Animation, Streaming Video, and DirectX. And, LARGE Databases & Servers, Winsock, Peer-to-Peer, and WAP(Pocket PC).
Introduction
Download Sample
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.
Consider all of the incredible functionality built into the Internet
Explorer browser(which is really just "shadocvw.dll") like DHTML, Java,
Video, and the ease of creating fantastic looking web pages which can reside
client side or come from a remote server. All we need to is to DISGUISE
the Internet Explorer browser so we can use all of the incredible GUI functionality
that is ALREADY resident in "shadocvw.dll" resident on every Windows platform.
Just think of the development time companies can save in creating and
updating their applications GUI screens because instead of hiring a
C++ programmer, they can have their artist change any program screen and
its functionality remotely or client side in just seconds! And any screen
can be displayed in any language, including Japaneese and Chinese instantly
without increasing the size of the executable file, and without the need
for any additional programming.
Disguising Internet Explorer
It's easy to disguise Internet Explorer so its looks exactly like any other
screen you would create in Visual C++ by simply creating a non-rectangular,
region, or skin.
The sample code with this article can make it easy to create and install
in just a FEW DAYS a "software package" that consists of a shopping
cart, a JRun sever or Apache server on the company's website connected
to an Oracle database, SQL database, or Visual FoxPro database that can
handle millions of hits per hour, and that
includes a client side Visual C++ or Java application of 300kb
or less that includes hundreds of spectacular GUI screens with ANY custom
functionality that can be instantly displayed in ANY language including
Japanese and Chinese on the user's computer.
The idea behind using these "Browser Skins" is to set up a company's
website using JSP or ASP, with a "Skins" application in Visual C++
or pure Java where each screen in the application was the Internet Explorer
WebBrowser Control (i.e., "Shdocvw.dll"). A company can then distribute
this type of Skins software to millions of people to provide users with
an application that "interfaces" in some way with their Internet Explorer
and Netscape browsers. For example, one common use, for such "Skins" applications
is to provide competitive pricing alternatives to users while they are
shopping on some website.
It's easy to write "scraping" code that can reside either on the client
side or server side to "scrap" any web page to provide an instant comparison
between any product on that web page with a company's competitively priced
similar products in a database. A JSP or ASP server can return the ACTUAL
ENTIRE SCREEN and ITS REGION back to the Visual C++ or Java application
running on the user's computer INSTANTLY in ANY language, including Japanese
or Chinese. Screens could also be generated from the client side as well.
Browser Skins lets you create applications smaller than 300kb in size
that can display an unlimted number of diferent screens in different shapes,
with different functionality, in ANY language INSTANTLY! Skin applications
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.
Skins Are "Self-Distributing"
Skins are by their very nature "self-distributing" which means that people
like to play with them so much that skins of any kind are the hottest downloads
on the Internet. Simply add a Peer-to-Peer server class and some
utility like a legal version of Napster, and you can find your skins application
on millions of computers in just weeks!
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:
-
Skins editor to create skins & regions from ANY type of image: .gif,
.jpg, .bmp, .avi, etc.
-
Dynamically create Microsoft's WebBrowser Control("Shdocvw.dll") in modeless
skinned dialogs
-
Sinking events correctly in Microsoft's WebBrowser Control("Shdocvw.dll")
-
Put Microsoft's WebBrowser Control("Shdocvw.dll") inside an AppBar, button
or control
-
Dynamically create WebBrowser Control in an ATL or MFC or Video window
in any application
-
Put WebBrowser Control in an ATL I.E. "Band" and dynamically change it
from a server
-
Resize non-rectangular skin regions dynamically on any computer
-
Save regions to files & create regions from files
-
Create new GUI screens in any language INSTANTLY on millions of computers
-
Create sinks that get around some ISPs using an ATL window to prevent sinking
I.E.
-
Many skin techniques & tricks never seen anywhere before
Application Pathway
Most applications place the INSTALLATION PATHWAY in the registry when the
user runs some installation program like InstallShield. Since this
is source code for Visual Studio, I assume that the user will run the programm
either in Debug or Release Mode from WITHIN the IDE. Therefore I
placed the skins directory one level ABOVE the Release and Debug directories
to what "GetCurrentDir" will return as the "executable" path from the IDE.
If you were to double-click on the .exe file in the Debug or Release directories
you will get a lot of errors and problems because the program will NOT
be able to find skins directory. To run the application by double-clicking
on an .exe, the skins directory MUST be in the SAME directory as the .exe
file. If the "Skins" directory is NOT inside of the same directory that
the application is running from, the application will prompt the user to
select the "Skins" directory so it can set the correct pathway to "Skins"
directory.
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 withou
// t 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.
I would have used a picture of a pretty model INSTEAD of my own head
but I don't own the copyright to any pictures of models that I could use
so I stuck in a picture of myself to illustrate the concept of "non-rectangular."
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:
BOOL File2Rgn(HWND hSkin, LPCSTR lpRgnPath);
BOOL Dll2Rgn(HWND hSkin, LPCSTR lpDLLFile);
BOOL Res2Rgn(HWND hSkin, UINT nRegionID);
BOOL Bmp2Rgn(HWND hSkin,HBITMAP hBmp,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)
{
//
Retrieve data as a string from a POST
if (PostData
!= NULL && PostData->vt == (VT_VARIANT|VT_BYREF) &&
PostData->pvarVal->vt != VT_EMPTY ){
*Cancel = TRUE;
char *szTemp = NULL, *szPostData = NULL;
long plLbound, plUbound;
SAFEARRAY *parrTemp = PostData -> pvarVal->parray;
SafeArrayAccessData(parrTemp , (void HUGEP **) &szTemp;);
SafeArrayGetLBound(parrTemp , 1, &plLbound;);
SafeArrayGetUBound(parrTemp , 1, &plUbound;);
szPostData = new char[plUbound - plLbound + 2];
StrCpyN(szPostData, szTemp, plUbound - plLbound + 1);
szPostData[plUbound-plLbound] = '\0';
SafeArrayUnaccessData(parrTemp);
// Do something here with posted data!
//MessageBox(szPostData);
delete[] szPostData;
}
// Retrieve
data from a Navigate to URL
try
{
csTestUrl = (CString)URL->bstrVal;
AfxExtractSubString(csEvent, csTestUrl, 0, (TCHAR)':');
AfxExtractSubString(csAction, csTestUrl, 1, (TCHAR)':');
AfxExtractSubString(csData, csTestUrl, 2, (TCHAR)':');
AfxExtractSubString(csQuestionMark, csTestUrl, 1, (TCHAR)'?');
}
catch(...)
{}
csEvent.MakeUpper();
if ( csEvent
!= "EVENT" ){
// Do Nothing!
}
else
{
try
{
csAction.MakeUpper();
if (csAction == "DRAG"){
*Cancel = TRUE;
//if (WM_LBUTTONDOWN && HTCLIENT && !::I
// sZoomed(GetSafeHwnd())){}
ReleaseCapture();
::SendMessage(GetSafeHwnd(),WM_NCLBUTTONDOWN,HTCAPTION,NULL);
//AfxGetApp()->OnIdle(0); // updates u
// ser interface
}
else if (csAction == "RGN"){
*Cancel = TRUE;
CString csRgnPath = csSkinsDir + "regions\\" + csData + ".rgn";
if ( FileExists( csRgnPath ) ){
File2Rgn(GetSafeHwnd(), csRgnPath);
}
}
else if (csAction == "MCLOSE"){
*Cancel = TRUE;
// Do some animation here
}
else if (csAction == "CLOSE"){
*Cancel = TRUE;
this->ShowWindow(SW_HIDE);
this->m_WebBrowser.Stop();
}
else if (csAction == "CANCEL"){
*Cancel = TRUE;
ShowWindow(SW_HIDE);
this->m_WebBrowser.Stop();
}
else if (csAction == "IEBROWSER"){
*Cancel = TRUE;
ShowWindow(SW_HIDE);
this->m_WebBrowser.Stop(); if ( !csData.IsEmpty() ) {
//ShellExecute(NULL, "open", sData, NULL, NULL, SW_SHOWNORMAL); // USE SINK FUNCTION TO LAUNCH IE BROWSER ((CMainFrame*)m_pParent)->LauchIEBrowser(csData); }
}else if (csAction == "MENUEXIT"){ // YOU MUST LOAD A QUIT RES FILE AND NOT CANCEL THE LOAD
ShowWindow(SW_HIDE);
this->m_WebBrowser.Stop();}}
catch( ... ) { *Cancel = TRUE;}}
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:
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:
SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, 1, NULL, SPIF_SENDWININICHANGE);
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, and I may post some of
these techniques in a future article.
The reader will have to supply their own sample videos, other than the
"mouse.avi" that is included 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.
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.
NOTE: While you are free to use the sample code, you may NOT
use my names SlickSkins™, VideoSkins™, or VideoAnyWhere™,
on anything you distribute. These are trademarks and copyrights of my company,
William SerGio & Co., Inc.
And Finally...
In future articles I would like to discuss how to:
-
New techniques for broadcasting video to millions of computers in minutes
using virtually no bandwidth!
-
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
-
How to display any streaming data like stock quotes or video in 3D Scaled
Vector Graphical Displays that make it easier for people to read and view
streaming data
If you have any question, please feel free to contact me at:
sergio@codearchive.com
afilmmogul@aol.com
Tel. 305-233-7654
|