Click here to Skip to main content
Click here to Skip to main content

CListCtrlExt and CListViewExt controls

By , 20 Feb 2012
 
TestList.zip
TestList6.2
Debug
TestList6.exe
res
TestList6.ico
TestList6Doc.ico
Toolbar.bmp
TestList6.clw
TestList6.dsp
TestList6.dsw
TestList6.3
Debug
TestList6.exe
res
TestList6.ico
TestList6Doc.ico
Toolbar.bmp
TestList6.clw
TestList6.dsp
TestList6.dsw
TestList6
Debug
TestList6.exe
res
TestList6.ico
TestList6Doc.ico
Toolbar.bmp
TestList6.clw
TestList6.dsp
TestList6.dsw
TestList6.zip
TestList6.exe
TestList6.ico
TestList6Doc.ico
Toolbar.bmp
TestList6.aps
TestList6.clw
TestList6.dsp
TestList6.dsw
TestList6.ncb
TestList6.opt
TestList6.plg
TestList6_2.zip
TestList6.exe
TestList6.ico
TestList6Doc.ico
Toolbar.bmp
TestList6.clw
TestList6.dsp
TestList6.dsw
TestList6_3.zip
TestList6.exe
TestList6.ico
TestList6Doc.ico
Toolbar.bmp
TestList6.clw
TestList6.dsp
TestList6.dsw
// MsgHook.cpp : implementation of the CMsgHook class
//
/////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "MsgHook.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CMsgHook

HHOOK CMsgHook::m_hHook = NULL;
int CMsgHook::m_nInstances = 0;
CMap<HWND, HWND&, CMsgHook*, CMsgHook*&> CMsgHook::m_MapHookedWindows;  // map of windows to hooks

CMsgHook::CMsgHook()
	:m_bDropDown(FALSE)
	,m_hWnd(NULL)
	,m_hParent(NULL)
	,m_hNotify(NULL)
{
	if(m_nInstances == 0)
	{
		m_hHook = SetWindowsHookEx(WH_CALLWNDPROCRET, CallWndRetProc, NULL, GetCurrentThreadId());
		ASSERT(m_hHook);
	}
	m_nInstances++;
}

CMsgHook::~CMsgHook()
{
	m_nInstances--;
	if(m_nInstances == 0)UnhookWindowsHookEx(m_hHook);
}

LRESULT CALLBACK CMsgHook::CallWndRetProc(int nCode, WPARAM wParam, LPARAM lParam)
{
	CWPRETSTRUCT* pMsg = (CWPRETSTRUCT*)lParam;
	if(pMsg)
	{
		CMsgHook* pHook = NULL;

		switch(pMsg->message)
		{
		case WM_KILLFOCUS:
			{
				HWND hWnd = (HWND)pMsg->hwnd;
				while(hWnd)
				{
					if(m_MapHookedWindows.Lookup(hWnd, pHook))
					{
						if(! pHook->m_bDropDown)
						{
							hWnd = (HWND)pMsg->wParam;
							while(hWnd && hWnd != pHook->m_hWnd)
							{	
								hWnd = GetParent(hWnd);
							}
							if(! hWnd)
							{
								SendMessage(pHook->m_hNotify ? pHook->m_hNotify : pHook->m_hParent, UM_HIDEEDITOR, TRUE, 0);
								break;
							}
						}
						break;
					}
					hWnd = GetParent(hWnd);
				}
			}
			break;
		case WM_NOTIFY:
			{
				LPNMHDR pnmh = (LPNMHDR)pMsg->lParam;
				if(pnmh->code == DTN_DROPDOWN || pnmh->code == DTN_CLOSEUP)
				{
					HWND hWnd = (HWND)pnmh->hwndFrom;
					while(hWnd)
					{
						if(m_MapHookedWindows.Lookup(hWnd, pHook))
						{
							pHook->m_bDropDown = (DTN_DROPDOWN == pnmh->code);						
							break;
						}
						hWnd = GetParent(hWnd);
					}
				}				
			}
			break;
		case WM_COMMAND:
			{
				WORD code = HIWORD(pMsg->wParam);
				if(code == CBN_DROPDOWN || code == CBN_CLOSEUP)
				{
					HWND hWnd = (HWND)pMsg->lParam;
					while(hWnd)
					{
						if(m_MapHookedWindows.Lookup(hWnd, pHook))
						{
							pHook->m_bDropDown = (CBN_DROPDOWN == code);
							break;
						}
						hWnd = GetParent(hWnd);
					}
				}				
			}
			break;
		case WM_KEYDOWN:
			{
				if(pMsg->wParam == VK_ESCAPE || pMsg->wParam == VK_RETURN)
				{
					HWND hWnd = (HWND)pMsg->hwnd;
					while(hWnd)
					{
						if(m_MapHookedWindows.Lookup(hWnd, pHook))
						{
							SendMessage(pHook->m_hNotify ? pHook->m_hNotify : pHook->m_hParent, UM_HIDEEDITOR, pMsg->wParam == VK_RETURN, 0);
							break;
						}
						hWnd = GetParent(hWnd);
					}
				}
			}
			break;
		case WM_DESTROY:
			{
				if(m_MapHookedWindows.Lookup(pMsg->hwnd, pHook))
				{
					pHook->Detach();
				}
			}
			break;
		case WM_LBUTTONDOWN:
		case WM_RBUTTONDOWN:
		case WM_MBUTTONDOWN:
		case WM_HSCROLL:
		case WM_VSCROLL:
		case WM_MENUSELECT:
		case WM_MOUSEWHEEL:
			{
				HWND hWnd = (HWND)pMsg->hwnd;
				while(hWnd && ! m_MapHookedWindows.Lookup(hWnd, pHook))
				{					
					hWnd = GetParent(hWnd);
				}
				if(! pHook)
				{
					POSITION pos = m_MapHookedWindows.GetStartPosition();
					HWND    hWnd;
					while(pos != NULL)
					{
						m_MapHookedWindows.GetNextAssoc(pos, hWnd, pHook);

						if(IsWindow(hWnd) && ! pHook->m_bDropDown)
						{
							BOOL dropDown = SendMessage(hWnd, CB_GETDROPPEDSTATE, 0, 0) || DateTime_GetMonthCal(hWnd);
							if(! dropDown)SendMessage(pHook->m_hNotify ? pHook->m_hNotify : pHook->m_hParent, UM_HIDEEDITOR, TRUE, 0);
						}
					}

				}
			}
			break;
		}		
	}

	return CallNextHookEx(m_hHook, nCode, wParam, lParam);
}

BOOL CMsgHook::Attach(HWND hWnd, HWND hParent, HWND hNotify)
{
	if(IsWindow(hWnd) && IsWindow(hParent))
	{
		Detach();
		m_hWnd = hWnd;
		m_hParent = hParent;
		m_hNotify = hNotify;
		m_MapHookedWindows[hWnd] = this;
		m_bDropDown = FALSE;
		return TRUE;
	}

	return FALSE;
}

BOOL CMsgHook::Detach(void)
{
	if(m_MapHookedWindows.RemoveKey(m_hWnd))
	{
		m_hWnd	= NULL;
		m_hParent = NULL;
		m_hNotify = NULL;
		m_bDropDown = FALSE;
		return TRUE;
	}

	return FALSE;
}

By viewing downloads associated with this article you agree to the Terms of use 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)

About the Author

Flaviu2
Romania Romania
Member
No Biography provided

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130523.1 | Last Updated 20 Feb 2012
Article Copyright 2011 by Flaviu2
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid