Disclaimer: This is an experiment. I do not intend you to use this for any real day to day use. If you DO use it you do so at your own risk. I can't help you if this causes your computer to melt or makes your shoes catch on fire or worse.

Click to invoke the Color Picker.
Image © Kevin C. Smith


Known Issues:

How it works

The application creates a div element that will hold the hex value, a div element who's background color will be set to that hex value and an activeX component with two public methods called grabScreen and publicHexValue.

When the activeX compontent instantiates, it does a screen capture of the desktop and sets the resulting image to a picture box control. The picture box is set to the width and height of the screen.

The document's onmouseover event is routed to a javascript function called getHex, which passes the X and Y coordinates of the mouse to the publicHexValue method of the activeX component. That method then passes the Window's Long RGB color of the corresponding point in the picture box control to a sub called HexRGB which was written (years ago) by my good friend Dean Taylor. That function converts the Long value into a hexidecimal value, returns it to publicHexValue which then returns it to the calling javascript method.

The grabScreen method is called from the window's onscrollcomplete and onresize methods to refresh the screen capture. The onscrollcomplete doesnt actually work.

Source code follows in all it's unoptimized, ugly glory:

Javascript Source

document.onmousemove=getHexValue;
window.onresize=refreshScreenCapture;
window.onscrollcomplete=refreshScreenCapture;
window.onmove=refreshScreenCapture;

function init() {

	mObj = document.body.appendChild(document.createElement("div"));
	mObj.id="hexDisplay";
	mObj.style.font="9px verdana";
	mObj.style.backgroundColor="#FFF";
	mObj.style.border="1px solid #000";
	mObj.style.position="absolute";

	cObj = document.body.appendChild(document.createElement("div"));
	cObj.id="colorDisplay";
	cObj.style.border="1px solid #FFF";
	cObj.style.position="absolute";

	aObj=document.body.appendChild(document.createElement("div"));
	aObj.innerHTML='<OBJECT name="cPick" CLASSID="CLSID:68863C58-17C6-4885-9983-2FA56B6B5CE0" CODEBASE="http://slayeroffice.com/test/cpick/Project1.CAB#version=1,0,0,0" style="display:none;"></OBJECT>';
}

function getHexValue() {
	try {
	pX= window.event.screenX;
	pY= window.event.screenY;

	x=window.event.clientX+returnScrollDimensions(0);
	y=window.event.clientY+returnScrollDimensions(1);

	document.getElementById("hexDisplay").style.top = y+15;
	document.getElementById("hexDisplay").style.left= x+15;
	document.getElementById("colorDisplay").style.top = y+30;
	document.getElementById("colorDisplay").style.left = x+15;

	pHEX = document.applets.cPick.publicHexValue(pX,pY);

	document.getElementById("hexDisplay").innerHTML ="#"+pHEX;
	document.getElementById("colorDisplay").style.backgroundColor="#"+pHEX;
	document.getElementById("colorDisplay").style.width = document.getElementById("hexDisplay").offsetWidth;
	document.getElementById("colorDisplay").style.height = document.getElementById("hexDisplay").offsetHeight;
	} catch(err) { document.getElementById("hexDisplay").innerHTML = err.message; }
}

function refreshScreenCapture() {
	document.applets.cPick.grabScreen();
}

function returnScrollDimensions(which) {
	if(which) {
		if(document.body.scrollTop != 0)return document.body.scrollTop;
		if(document.documentElement.scrollTop != 0)return document.documentElement.scrollTop;
	} else {
		if(document.body.scrollLeft != 0)return document.body.scrollTop;
		if(document.documentElement.scrollLeft != 0)return document.documentElement.scrollLeft;
	}
	return 0;
}

init();

The Visual Basic Source:

Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
Private Declare Function GetDesktopWindow Lib "user32" () As Long
Private Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long

Private Function HexRGB(lCdlColor As Long)

    Dim lCol As Long
    Dim iRed, iGreen, iBlue As Integer
    Dim vHexR, vHexG, vHexB As Variant    'Break out the R, G, B values from the common dialog color
    lCol = lCdlColor
    iRed = lCol Mod &H100
    lCol = lCol \ &H100
    iGreen = lCol Mod &H100
    lCol = lCol \ &H100
    iBlue = lCol Mod &H100
    
    'Determine Red Hex
    vHexR = Hex(iRed)

    If Len(vHexR) < 2 Then
     vHexR = "0" & vHexR
    End If

    'Determine Green Hex
    vHexG = Hex(iGreen)

    If Len(vHexG) < 2 Then
     vHexG = "0" & iGreen
    End If

    'Determine Blue Hex
    vHexB = Hex(iBlue)

    If Len(vHexB) < 2 Then
     vHexB = "0" & vHexB
    End If

     'Add it up, return the function value
     HexRGB = vHexR & vHexG & vHexB
     
 
End Function

Public Sub grabScreen()
    Dim aa As Long, bb As Long, xx As Long, yy As Long, blitit As Long

    Picture1.Width = Screen.Width
    Picture1.Height = Screen.Height

    aa = GetDesktopWindow()
    bb = GetDC(aa)

    blitit = BitBlt(Picture1.hDC, 0, 0, Picture1.Width, Picture1.Height, bb, 0, 0, &HCC0020)
    Picture1.Refresh
End Sub

Public Function publicHexValue(x As Single, y As Single)
 publicHexValue = HexRGB(Picture1.Point(x, y))
End Function

Private Sub UserControl_Initialize()
    Call grabScreen
End Sub

slayeroffice Color Picker activeX Favelet
version 1.0
last revision: 04.19.2004
steve@slayeroffice.com
http://www.slayeroffice.com