Click here to Skip to main content
12,819,248 members (31,013 online)
Click here to Skip to main content
Add your own
alternative version


19 bookmarked
Posted 22 Oct 2001

ColorCursor v. 2.2

, 22 Oct 2001
Rate this:
Please Sign up or sign in to vote.
ColorCursor v. 2.1 pops up RGB values for all visible objects found on your desktop
<!-- Download Links --> <!-- Article image -->

Sample Image - ColorCursor.jpg

<!-- Add the rest of your HTML here -->


ColorCursor 2.2 is a invisible tray-only application that pops up RGB values for all visible objects found on your desktop - pixel by pixel under the nose of your cursor (also known as its hot spot).

Starting cc.exe gives you a Woodstock or a Woodstock with a red line on top. This signals that ColorCursor is running/sleeping (1) - a normal icon means 'not-paused' and one with a red line means 'paused'. Interacting with it goes on from the Woodstock ctx. menu (2). Most items here are self explanatory I think.

On the menu you have several sections. The first one controls the way you log "color-pixels". ColorCursor enables you to track down mouse moves. This I refer to as recording. Nothing surprising about that (I'll come back to how it works in a moment). Next section sets up the format of the RBG-info. Third section controls the behavior of the ballooning.

It's all about hooking into other message queues of other processes. I've made a function for that in this dual workspace (one part for the app. and one for the hook-dll) called -

const bool HookInOtherMsgQueue();

And implementation like this -

const bool CCcFrameWnd::HookInOtherMsgQueue()
// Try to place a msg-hook under the queue of the window hoovered by the hotspot of the mouse to trap mouse events. It only happens if the mouse hoovers a new window.
	bool bNewHookNeeded = false;
	m_hWndMouseHoover_New = GetHWND_MouseHoover();
		// Hooked some window before.
		bNewHookNeeded = (m_hWndMouseHoover_New != m_hWndMouseHoover_Old);
		// First hook.
		bNewHookNeeded = true;
		// Tell hook-dll who we are.
		FNSetHook_Owner *SetHook_Owner = (FNSetHook_Owner*)::GetProcAddress(m_hInstanceDll, _T("SetHook_Owner"));
		DWORD dwThreadId = 0,
			  dwProcessId = 0;
		dwThreadId = ::GetWindowThreadProcessId(m_hWndMouseHoover_New, &dwProcessId);
			HOOKPROC hHookProcAdr = (HOOKPROC)::GetProcAddress(m_hInstanceDll, _T("MouseTrap"));
			// Change hook proc.
			m_hHook = ::SetWindowsHookEx(WH_MOUSE, hHookProcAdr, m_hInstanceDll, dwThreadId);
				// Tell hook-dll about new hook handle.
				FNSetHook *SetHook = (FNSetHook*)::GetProcAddress(m_hInstanceDll, _T("SetHook"));
				// New hook set.
				return true;
		m_hWndMouseHoover_Old = m_hWndMouseHoover_New;
	// No new hook set (old is reused (if any)).
	return false;

That's the far most interesting one in my (MFC) project. I don't say that this is indeed perfect but it works.

The point is that ColorCursor sets up a 100ms-timer when executed and not paused. On WM_TIMER events it asks if the mouse now hoovers a new window and, if so, it tries to hook into its msg. queue - tapping mouse events from it. What I'm interested here is only when L- and R- client and NonClient events go in for mouse-buttons. Now back to the timer -

void CCcFrameWnd::OnTimer(UINT uIdEvent) 
// The framework calls this member function after each interval specified in the SetTimer member function used to install a timer.
	if(uIdEvent == sm_uIdTimer_Pop)
		// If mouse hoovers a new window we try to hook into it now.
		// Show popup baloon.

TTShow(...) is called (TT == ToolTip). It prepares the balloon info for display and the overridden TTShow(const CString &cstrTTT) (TTT == ToolTipText) is called from it and pops the new TT only if (iff) it's now moved to a new pixel. To be able to show fast TT on demand I've made a by-proxy TT-class imitating a "real" TT (and 'proxy' because not based on native TT classes but on frame wnd's, in fact from ground up). This class along with other util. classes and functions (see lib. 'extra'), you get in addition to this project. I'll not go into details about how that works - you'll have to check that out yourself (or ask me).

Picture #3 shows you a balloon from the by-proxy class. Picture #4 is part of a RGB-log. To avoid stupid problems I let the app. go into a forced pause state on showing the log. Perhaps you can do better - forgive...

I've made the CCcFrameWnd::MouseTrap(...) event handler catch and filter the events I'll like to respond. A counterpart to it initiates it all inside the hook-dll -

LRESULT CALLBACK MouseTrap(int iCode, WPARAM wParam, LPARAM lParam)
// Call owner on interesting msg.
	if(iCode == HC_ACTION)
		HWND hWnd = ::FindWindow(NULL, I_Constant_Title);
		if(hWnd && ::IsWindow(hWnd))
			::PostMessage(hWnd, WM_MGSTRAP, wParam, lParam);
	return ::CallNextHookEx(g_hHook, iCode, wParam, lParam);

And naturally it all takes place because of the -

m_hHook = ::SetWindowsHookEx(WH_MOUSE, hHookProcAdr, m_hInstanceDll, dwThreadId);

In the CCcFrameWnd::HookInOtherMsgQueue() function.

One problem that I dit not solve was why the hWnd of the owner window did not match up the HWND of calling ::FindWindow(NULL, I_Constant_Title); in the hook-dll. This is not a huge problem though - but I can not understand why I can't tell my hook-dll about the owner hwnd, the hWnd to get the msg. next - cc in other words, from inside the hook-into-fct. (security obstruction?) I try to do that - but without much luck I'm afraid. Instead I have to use the title depended ::FindWindow(...) and that's a poor alternative I feel.

Enjoy - I'm looking forward to see what you all have to say about this. <p>


This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


About the Author

Michael Pauli
Software Developer (Senior)
Denmark Denmark
c/c++/c# -developer.

You may also be interested in...

Comments and Discussions

Generalhelp Pin
Kiethnt13-Nov-06 0:13
memberKiethnt13-Nov-06 0:13 
Generalnot running Pin
Anonymous26-Mar-02 5:23
memberAnonymous26-Mar-02 5:23 
GeneralNice to see "Snuden" on CodeProject Pin
Christian Skovdal Andersen24-Oct-01 23:29
memberChristian Skovdal Andersen24-Oct-01 23:29 
GeneralHang & Crash Pin
DarrenSchroeder24-Oct-01 5:17
memberDarrenSchroeder24-Oct-01 5:17 
GeneralRe: Hang & Crash Pin
Michael Mogensen24-Oct-01 15:20
memberMichael Mogensen24-Oct-01 15:20 
GeneralRe: Hang & Crash Pin
Yawar Maajed25-Oct-01 12:37
memberYawar Maajed25-Oct-01 12:37 
GeneralRe: Hang & Crash Pin
Yawar Maajed25-Oct-01 12:40
memberYawar Maajed25-Oct-01 12:40 
GeneralRe: Hang & Crash Pin
Michael Mogensen26-Oct-01 4:43
memberMichael Mogensen26-Oct-01 4:43 
GeneralRe: Hang & Crash Pin
Yawar Maajed26-Oct-01 8:03
memberYawar Maajed26-Oct-01 8:03 
GeneralRe: Hang & Crash (final one :-) Pin
Michael Mogensen27-Oct-01 3:23
memberMichael Mogensen27-Oct-01 3:23 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170308.1 | Last Updated 23 Oct 2001
Article Copyright 2001 by Michael Pauli
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid