Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

An Alpha Channel Composited Windows Form with Designer Support

, 5 Oct 2009
An alpha channel composited form for image based Window frames
alphaformdemo.zip
TestFormGroBotoTV
bin
Release
AlphaFormTransformer.dll
TestForm.exe
TestFormSkinChange
bin
Release
AlphaFormTransformer.dll
TestFormSkinChange.exe
alphaformtransformer.zip
bin
Img Source
obj
Debug
TempPE
Release
TempPE
Properties
obj
Properties
Settings.settings
obj
Properties
Settings.settings
Resources
skin1.tif
skin2.tif
skin1.tif
skin2.tif
TutorialTemplate
bin
obj
Properties
Settings.settings
alphaform_1_1_1.zip
alphaform
ControlsOnTopOfSkin
Properties
Settings.settings
Help
afms.jpg
aform.jpg
AlphaForm API Help
AlphaForm Documentation.chm
CloseSearch.png
CollapseAll.bmp
Collapsed.gif
ExpandAll.bmp
Expanded.gif
fti
FTI_100.bin
FTI_101.bin
FTI_102.bin
FTI_103.bin
FTI_104.bin
FTI_105.bin
FTI_106.bin
FTI_108.bin
FTI_109.bin
FTI_110.bin
FTI_111.bin
FTI_112.bin
FTI_114.bin
FTI_115.bin
FTI_116.bin
FTI_117.bin
FTI_118.bin
FTI_119.bin
FTI_97.bin
FTI_98.bin
FTI_99.bin
FTI_Files.bin
html
icons
alert_caution.gif
alert_note.gif
alert_security.gif
Caution.gif
CFW.gif
collapse_all.gif
copycode.gif
expand_all.gif
LastChild.gif
NotLastChild.gif
privclass.gif
privdelegate.gif
privenum.gif
privevent.gif
privfield.gif
privinterface.gif
privmethod.gif
privproperty.gif
privstructure.gif
protclass.gif
protdelegate.gif
protenum.gif
protevent.gif
protfield.gif
protfield.png
protinterface.gif
protmethod.gif
protoperator.gif
protproperty.gif
protstructure.gif
pubclass.gif
pubdelegate.gif
pubenum.gif
pubevent.gif
pubfield.gif
pubinterface.gif
pubmethod.gif
puboperator.gif
pubproperty.gif
pubstructure.gif
security.gif
static.gif
Item.gif
LastBuild.log
scripts
Search.gif
Splitter.gif
styles
SyncTOC.gif
Tutorials
images
alpha controls splash.jpg
cntrldsk.jpg
controls splash.jpg
controlsontop small.jpg
cutout small.jpg
img0.jpg
img1.jpg
img1.png
img2.jpg
img2.png
img3.jpg
img3.png
img4.jpg
img5.jpg
interior.jpg
logo.gif
mainsplash.jpg
ontopdesign.jpg
ontopsplash.jpg
ontopwithcntrls.jpg
winmedia.jpg
marker.png
Properties
TestFormGroBotoTV
Properties
Settings.settings
TestFormSkinChange
Properties
Settings.settings
Resources
skin1.tif
skin2.tif
skin1.tif
skin2.tif
Transformer.png
TutorialTemplate
Properties
Settings.settings
TV Set
Properties
Settings.settings
tvpic1.jpg
tvpic2.jpg
AlphaForm_1_1_3_Part1.zip
AlphaForm_1_1_3
AlphaForm.csproj.user
AlphaForm.suo
ControlsOnTopOfSkin
bin
Debug
Properties
Settings.settings
LayerdOnBottom
Properties
Settings.settings
marker.png
Properties
TestFormGroBotoTV
bin
Debug
Properties
Settings.settings
TestFormSkinChange
bin
Debug
Properties
Settings.settings
Resources
skin1.tif
skin2.tif
Thumbs.db
skin1.tif
skin2.tif
Thumbs.db
Thumbs.db
Transformer.png
TutorialTemplate
bin
Debug
Properties
Settings.settings
TV Set
bin
Debug
Properties
Settings.settings
Thumbs.db
tvpic1.jpg
tvpic2.jpg
AlphaForm_1_1_3_Part2.zip
Help
afms.jpg
aform.jpg
AlphaForm API Help
AlphaForm Documentation.chm
CloseSearch.png
CollapseAll.bmp
Collapsed.gif
ExpandAll.bmp
Expanded.gif
fti
FTI_100.bin
FTI_101.bin
FTI_102.bin
FTI_103.bin
FTI_104.bin
FTI_105.bin
FTI_106.bin
FTI_108.bin
FTI_109.bin
FTI_110.bin
FTI_111.bin
FTI_112.bin
FTI_114.bin
FTI_115.bin
FTI_116.bin
FTI_117.bin
FTI_118.bin
FTI_119.bin
FTI_97.bin
FTI_98.bin
FTI_99.bin
FTI_Files.bin
html
icons
alert_caution.gif
alert_note.gif
alert_security.gif
Caution.gif
CFW.gif
collapse_all.gif
copycode.gif
expand_all.gif
LastChild.gif
NotLastChild.gif
privclass.gif
privdelegate.gif
privenum.gif
privevent.gif
privfield.gif
privinterface.gif
privmethod.gif
privproperty.gif
privstructure.gif
protclass.gif
protdelegate.gif
protenum.gif
protevent.gif
protfield.gif
protfield.png
protinterface.gif
protmethod.gif
protoperator.gif
protproperty.gif
protstructure.gif
pubclass.gif
pubdelegate.gif
pubenum.gif
pubevent.gif
pubfield.gif
pubinterface.gif
pubmethod.gif
puboperator.gif
pubproperty.gif
pubstructure.gif
security.gif
static.gif
Item.gif
LastBuild.log
scripts
Search.gif
Splitter.gif
styles
SyncTOC.gif
Thumbs.db
Tutorials
images
_vti_cnf
alpha controls splash.jpg
cntrldsk.jpg
controls splash.jpg
controlsontop small.jpg
cutout small.jpg
img0.jpg
img1.jpg
img1.png
img2.jpg
img2.png
img3.jpg
img3.png
img4.jpg
img5.jpg
interior.jpg
logo.gif
mainsplash.jpg
ontopdesign.jpg
ontopsplash.jpg
ontopwithcntrls.jpg
Thumbs.db
winmedia.jpg
alpha controls splash.jpg
cntrldsk.jpg
controls splash.jpg
controlsontop small.jpg
cutout small.jpg
img0.jpg
img1.jpg
img1.png
img2.jpg
img2.png
img3.jpg
img3.png
img4.jpg
img5.jpg
interior.jpg
logo.gif
mainsplash.jpg
ontopdesign.jpg
ontopsplash.jpg
ontopwithcntrls.jpg
Thumbs.db
winmedia.jpg
SlidingPanes
bin
Debug
Properties
Settings.settings
//=============================================================================
// System  : Sandcastle Help File Builder
// File    : TOC.js
// Author  : Eric Woodruff  (Eric@EWoodruff.us)
// Updated : 06/25/2007
// Note    : Copyright 2006, Eric Woodruff, All rights reserved
// Compiler: JavaScript
//
// This file contains the methods necessary to implement a simple tree view
// for the table of content with a resizable splitter and Ajax support to
// load tree nodes on demand.  It also contains the script necessary to do
// full-text searches.
//
// This file may be freely used for any purpose including commercial
// applications PROVIDING that this notice and the author's name and all
// copyright notices remain intact.  In addition, altered source versions of
// this file must be clearly marked as such.
//
// This code is provided "as is" with no warranty either express or implied.
// The author accepts no liability for any damage or loss of business that
// this product may cause.
//
// Version     Date     Who  Comments
// ============================================================================
// 1.3.0.0  09/12/2006  EFW  Created the code
// 1.4.0.2  06/15/2007  EFW  Reworked to get rid of frame set and to add
//                           support for Ajax to load tree nodes on demand.
// 1.5.0.0  06/24/2007  EFW  Added full-text search capabilities
//=============================================================================

// IE flag
var isIE = (navigator.userAgent.indexOf("MSIE") >= 0);

// Minimum width of the TOC div
var minWidth = 100;

// Elements and sizing info
var divTOC, divSizer, topicContent, divNavOpts, divSearchOpts, divSearchResults,
    divTree, docBody, maxWidth, offset, txtSearchText, chkSortByTitle;

// Last node selected
var lastNode, lastSearchNode;

//============================================================================

// Initialize the tree view and resize the content
function Initialize()
{
    docBody = document.getElementsByTagName("body")[0];
    divTOC = document.getElementById("TOCDiv");
    divSizer = document.getElementById("TOCSizer");
    topicContent = document.getElementById("TopicContent");
    divNavOpts = document.getElementById("divNavOpts");
    divSearchOpts = document.getElementById("divSearchOpts");
    divSearchResults = document.getElementById("divSearchResults");
    divTree = document.getElementById("divTree");
    txtSearchText = document.getElementById("txtSearchText");
    chkSortByTitle = document.getElementById("chkSortByTitle");

    // The sizes are bit off in FireFox
    if(!isIE)
        divNavOpts.style.width = divSearchOpts.style.width = 292;

    ResizeTree();
    SyncTOC();
}

//============================================================================
// Navigation and expand/collaps code

// Synchronize the table of content with the selected page if possible
function SyncTOC()
{
    var idx, anchor, base, href, url, anchors, treeNode, saveNode;

    base = window.location.href;
    base = base.substr(0, base.lastIndexOf("/") + 1);

    if(base.substr(0, 5) == "file:" && base.substr(0, 8) != "file:///")
        base = base.replace("file://", "file:///");

    url = GetCurrentUrl();
    if(url == "")
        return false;

    if(url.substr(0, 5) == "file:" && url.substr(0, 8) != "file:///")
        url = url.replace("file://", "file:///");

    while(true)
    {
        anchors = divTree.getElementsByTagName("A");
        anchor = null;

        for(idx = 0; idx < anchors.length; idx++)
        {
            href = anchors[idx].href;

            if(href.substring(0, 7) != 'http://' &&
              href.substring(0, 8) != 'https://' &&
              href.substring(0, 7) != 'file://')
                href = base + href;

            if(href == url)
            {
                anchor = anchors[idx];
                break;
            }
        }

        if(anchor == null)
        {
            // If it contains a "#", strip anything after that and try again
            if(url.indexOf("#") != -1)
            {
                url = url.substr(0, url.indexOf("#"));
                continue;
            }

            return;
        }

        break;
    }

    // If found, select it and find the parent tree node
    SelectNode(anchor);
    saveNode = anchor;
    lastNode = null;

    while(anchor != null)
    {
        if(anchor.className == "TreeNode")
        {
            treeNode = anchor;
            break;
        }

        anchor = anchor.parentNode;
    }

    // Expand it and all of its parents
    while(anchor != null)
    {
        Expand(anchor);

        anchor = anchor.parentNode;

        while(anchor != null)
        {
            if(anchor.className == "TreeNode")
                break;

            anchor = anchor.parentNode;
        }
    }

    lastNode = saveNode;

    // Scroll the node into view
    var windowTop = lastNode.offsetTop - divTree.offsetTop - divTree.scrollTop;
    var windowBottom = divTree.clientHeight - windowTop - lastNode.offsetHeight;

    if(windowTop < 0)
        divTree.scrollTop += windowTop - 30;
    else
        if(windowBottom < 0)
            divTree.scrollTop -= windowBottom - 30;
}

// Get the currently loaded URL from the IFRAME
function GetCurrentUrl()
{
    var base, url = "";

    try
    {
        url = window.parent.frames["TopicContent"].document.URL.replace(/\\/g, "/");
    }
    catch(e)
    {
        // If this happens the user probably navigated to another frameset
        // that didn't make itself the topmost frameset and we don't have
        // control of the other frame anymore.  In that case, just reload
        // our index page.
        base = window.location.href;
        base = base.substr(0, base.lastIndexOf("/") + 1);

        if(base.substr(0, 5) == "file:" && base.substr(0, 8) != "file:///")
            base = base.replace("file://", "file:///");

        if(base.substr(0, 5) == "file:")
            window.location.href = base + "Index.html";
        else
            window.location.href = base + "Index.aspx";
    }

    return url;
}

// Expand or collapse all nodes
function ExpandOrCollapseAll(expandNodes)
{
    var divIdx, childIdx, img, divs = document.getElementsByTagName("DIV");
    var childNodes, child, div, link, img;

    for(divIdx = 0; divIdx < divs.length; divIdx++)
        if(divs[divIdx].className == "Hidden" ||
          divs[divIdx].className == "Visible")
        {
            childNodes = divs[divIdx].parentNode.childNodes;

            for(childIdx = 0; childIdx < childNodes.length; childIdx++)
            {
                child = childNodes[childIdx];

                if(child.className == "TreeNodeImg")
                    img = child;

                if(child.className == "Hidden" || child.className == "Visible")
                {
                    div = child;
                    break;
                }
            }

            if(div.className == "Visible" && !expandNodes)
            {
                div.className = "Hidden";
                img.src = "Collapsed.gif";
            }
            else
                if(div.className == "Hidden" && expandNodes)
                {
                    div.className = "Visible";
                    img.src = "Expanded.gif";

                    if(div.innerHTML == "")
                        FillNode(div, true)
                }
        }
}

// Toggle the state of the specified node
function Toggle(node)
{
    var i, childNodes, child, div, link;

    childNodes = node.parentNode.childNodes;

    for(i = 0; i < childNodes.length; i++)
    {
        child = childNodes[i];

        if(child.className == "Hidden" || child.className == "Visible")
        {
            div = child;
            break;
        }
    }

    if(div.className == "Visible")
    {
        div.className = "Hidden";
        node.src = "Collapsed.gif";
    }
    else
    {
        div.className = "Visible";
        node.src = "Expanded.gif";

        if(div.innerHTML == "")
            FillNode(div, false)
    }
}

// Expand the selected node
function Expand(node)
{
    var i, childNodes, child, div, img;

    // If not valid, don't bother
    if(GetCurrentUrl() == "")
        return false;

    if(node.tagName == "A")
        childNodes = node.parentNode.childNodes;
    else
        childNodes = node.childNodes;

    for(i = 0; i < childNodes.length; i++)
    {
        child = childNodes[i];

        if(child.className == "TreeNodeImg")
            img = child;

        if(child.className == "Hidden" || child.className == "Visible")
        {
            div = child;
            break;
        }
    }

    if(lastNode != null)
        lastNode.className = "UnselectedNode";

    div.className = "Visible";
    img.src = "Expanded.gif";

    if(node.tagName == "A")
    {
        node.className = "SelectedNode";
        lastNode = node;
    }

    if(div.innerHTML == "")
        FillNode(div, false)

    return true;
}

// Set the style of the specified node to "selected"
function SelectNode(node)
{
    // If not valid, don't bother
    if(GetCurrentUrl() == "")
        return false;

    if(lastNode != null)
        lastNode.className = "UnselectedNode";

    node.className = "SelectedNode";
    lastNode = node;

    return true;
}

//============================================================================
// Ajax-related code used to fill the tree nodes on demand

function GetXmlHttpRequest()
{
    var xmlHttp = null;

    // If IE7, Mozilla, Safari, etc., use the native object.
    // Otherwise, use the ActiveX control for IE5.x and IE6.
    if(window.XMLHttpRequest)
        xmlHttp = new XMLHttpRequest();
    else
        if(window.ActiveXObject)
            xmlHttp = new ActiveXObject("MSXML2.XMLHTTP.3.0");

    return xmlHttp;
}

// Perform an AJAX-style request for the contents of a node and put the
// contents into the empty div.
function FillNode(div, expandChildren)
{
    var xmlHttp = GetXmlHttpRequest(), now = new Date();

    if(xmlHttp == null)
    {
        div.innerHTML = "<b>XML HTTP request not supported!</b>";
        return;
    }

    div.innerHTML = "Loading...";

    // Add a unique hash to ensure it doesn't use cached results
    xmlHttp.open("GET", "FillNode.aspx?Id=" + div.id + "&hash=" +
        now.getTime(), true);

    xmlHttp.onreadystatechange = function()
    {
        if(xmlHttp.readyState == 4)
        {
            div.innerHTML = xmlHttp.responseText;

            if(expandChildren)
                ExpandOrCollapseAll(true);
        }
    }

    xmlHttp.send(null)
}

//============================================================================
// Resizing code

// Resize the tree div so that it fills the document body
function ResizeTree()
{
    var y, newHeight;

    if(self.innerHeight)    // All but IE
        y = self.innerHeight;
    else    // IE - Strict
        if(document.documentElement && document.documentElement.clientHeight)
            y = document.documentElement.clientHeight;
        else    // Everything else
            if(document.body)
                y = document.body.clientHeight;

    newHeight = y - parseInt(divNavOpts.style.height) - 6;

    if(newHeight < 50)
        newHeight = 50;

    divTree.style.height = newHeight;

    newHeight = y - parseInt(divSearchOpts.style.height) - 6;

    if(newHeight < 100)
        newHeight = 100;

    divSearchResults.style.height = newHeight;

    // Resize the content div
    ResizeContent();
}

// Resize the content div
function ResizeContent()
{
    if(isIE)
        maxWidth = docBody.clientWidth;
    else
        maxWidth = docBody.clientWidth - 4;

    topicContent.style.width = maxWidth - (divSizer.offsetLeft +
        divSizer.offsetWidth);
    maxWidth -= minWidth;
}

// This is called to prepare for dragging the sizer div
function OnMouseDown(event)
{
    var x;

    // Make sure the splitter is at the top of the z-index
    divSizer.style.zIndex = 5000;

    // The content is in an IFRAME which steals mouse events so
    // hide it while resizing.
    topicContent.style.display = "none";

    if(isIE)
        x = window.event.clientX + document.documentElement.scrollLeft +
            document.body.scrollLeft;
    else
        x = event.clientX + window.scrollX;

    // Save starting offset
    offset = parseInt(divSizer.style.left, 10);

    if(isNaN(offset))
        offset = 0;

    offset -= x;

    if(isIE)
    {
        document.attachEvent("onmousemove", OnMouseMove);
        document.attachEvent("onmouseup", OnMouseUp);
        window.event.cancelBubble = true;
        window.event.returnValue = false;
    }
    else
    {
        document.addEventListener("mousemove", OnMouseMove, true);
        document.addEventListener("mouseup", OnMouseUp, true);
        event.preventDefault();
    }
}

// Resize the TOC and content divs as the sizer is dragged
function OnMouseMove(event)
{
    var x, pos;

    // Get cursor position with respect to the page
    if(isIE)
        x = window.event.clientX + document.documentElement.scrollLeft +
            document.body.scrollLeft;
    else
        x = event.clientX + window.scrollX;

    left = offset + x;

    // Adjusts the width of the TOC divs
    pos = (event.clientX > maxWidth) ? maxWidth :
        (event.clientX < minWidth) ? minWidth : event.clientX;

    divTOC.style.width = divSearchResults.style.width =
        divTree.style.width = pos;

    if(!isIE)
        pos -= 8;

    divNavOpts.style.width = divSearchOpts.style.width = pos;

    // Resize the content div to fit in the remaining space
    ResizeContent();
}

// Finish the drag operation when the mouse button is released
function OnMouseUp(event)
{
    if(isIE)
    {
        document.detachEvent("onmousemove", OnMouseMove);
        document.detachEvent("onmouseup", OnMouseUp);
    }
    else
    {
        document.removeEventListener("mousemove", OnMouseMove, true);
        document.removeEventListener("mouseup", OnMouseUp, true);
    }

    // Show the content div again
    topicContent.style.display = "inline";
}

//============================================================================
// Search code

function ShowHideSearch(show)
{
    if(show)
    {
        divNavOpts.style.display = divTree.style.display = "none";
        divSearchOpts.style.display = divSearchResults.style.display = "";
    }
    else
    {
        divSearchOpts.style.display = divSearchResults.style.display = "none";
        divNavOpts.style.display = divTree.style.display = "";
    }
}

// When enter is hit in the search text box, do the search
function OnSearchTextKeyPress(evt)
{
    if(evt.keyCode == 13)
    {
        PerformSearch();
        return false;
    }

    return true;
}

// Perform a keyword search
function PerformSearch()
{
    var xmlHttp = GetXmlHttpRequest(), now = new Date();

    if(xmlHttp == null)
    {
        divSearchResults.innerHTML = "<b>XML HTTP request not supported!</b>";
        return;
    }

    divSearchResults.innerHTML = "<span class=\"PaddedText\">Searching...</span>";

    // Add a unique hash to ensure it doesn't use cached results
    xmlHttp.open("GET", "SearchHelp.aspx?Keywords=" + txtSearchText.value +
        "&SortByTitle=" + (chkSortByTitle.checked ? "true" : "false") +
        "&hash=" + now.getTime(), true);

    xmlHttp.onreadystatechange = function()
    {
        if(xmlHttp.readyState == 4)
        {
            divSearchResults.innerHTML = xmlHttp.responseText;

            lastSearchNode = divSearchResults.childNodes[0].childNodes[1];

            if(lastSearchNode.tagName != "A")
                lastSearchNode = lastSearchNode.nextSibling;

            SelectSearchNode(lastSearchNode);
            topicContent.src = lastSearchNode.href;
        }
    }

    xmlHttp.send(null)
}

// Set the style of the specified search result node to "selected"
function SelectSearchNode(node)
{
    if(lastSearchNode != null)
        lastSearchNode.className = "UnselectedNode";

    node.className = "SelectedNode";
    lastSearchNode = node;

    return true;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

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

Share

About the Author

Jeff J Anderson
Software Developer
United States United States
Jeff Anderson has been a computer graphics software developer for over twenty years.
 
He is a co-founder of Braid Art Labs and a developer of Braid's GroBoto 3D software. Jeff also dabbles in shareware with an expanded version of the AlphaForm control and other programs here.

| Advertise | Privacy | Mobile
Web01 | 2.8.140827.1 | Last Updated 5 Oct 2009
Article Copyright 2007 by Jeff J Anderson
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid