Click here to Skip to main content
15,881,882 members
Articles / Desktop Programming / MFC

CKeystrokeEngine

Rate me:
Please Sign up or sign in to vote.
4.98/5 (30 votes)
21 Jun 2004CPOL4 min read 301.9K   7.7K   108  
A set of classes used to send keystrokes to a selected window
/*********************************************************************
	Copyright (C) 2002 Mustafa Demirhan :)
	
	This software is provided 'as-is', without any express or implied
	warranty.  In no event will the authors be held liable for any damages
	arising from the use of this software.

	Permission is granted to anyone to use this software for any purpose,
	including commercial applications, and to alter it and redistribute it
	freely, subject to the following restrictions:

	1. The origin of this software must not be misrepresented; you must not
	   claim that you wrote the original software. If you use this software
	   in a product, an acknowledgment in the product documentation would be
	   appreciated but is not required.

	2. Altered source versions must be plainly marked as such, and must not be
	   misrepresented as being the original software.

	3. This notice may not be removed or altered from any source distribution.

	http://www.macroangel.com
	admin@macroangel.com
**********************************************************************/

#include "stdafx.h"
#include "WindowEngine.h"

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

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam);
BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam);
bool FindText (HWND hwnd);

CCriticalSection gWindowEngine;
CWindowEngine *pWndOp = NULL;
extern int wildcmp(LPCSTR wild, LPCSTR string) ;

#define FIND_EXACT			0x0001
#define FIND_TITLE			0x0002
#define FIND_CLASSNAME		0x0004
#define FIND_TEXT			0x0008
#define FIND_ALL			0x0010
#define FIND_CASESENSITIVE	0x0020

CWindowEngine::CWindowEngine(LPCSTR lpszTitle, LPCSTR lpszClass, LPCSTR lpszText, bool bExact, bool bApplyToAll, bool bCaseSensitive)
{
	m_sTitle = lpszTitle;
	m_sClass = lpszClass;
	m_sText = lpszText;
	m_bExact = bExact;
	m_bApplyToAll = bApplyToAll;
	m_bCaseSensitive = bCaseSensitive;
	
	if (!bCaseSensitive)
	{
		m_sTitleLower = lpszTitle;
		m_sTitleLower.MakeLower ();
		m_sTextLower = lpszText;
		m_sTextLower.MakeLower ();
	}
	m_Handles.clear ();
	FindAllWindows ();
}

CWindowEngine::~CWindowEngine()
{
	m_Handles.clear ();
}

bool CWindowEngine::FocusWindow()
{
	if (m_Handles.size () <= 0)
		return false;
	
	for (list<HWND>::iterator i = m_Handles.begin (); i != m_Handles.end (); i++)
		SetForegroundWindow (*i);
	
	return true;
}

bool CWindowEngine::CloseWindow()
{
	if (m_Handles.size () <= 0)
		return false;
	
	for (list<HWND>::iterator i = m_Handles.begin (); i != m_Handles.end (); i++)
		PostMessage (*i, WM_CLOSE, 0, 0);

	return true;
}

bool CWindowEngine::MinimizeWindow()
{
	if (m_Handles.size () <= 0)
		return false;
	
	for (list<HWND>::iterator i = m_Handles.begin (); i != m_Handles.end (); i++)
		ShowWindow (*i, SW_MINIMIZE);

	return true;
}

bool CWindowEngine::MaximizeWindow()
{
	if (m_Handles.size () <= 0)
		return false;
	
	for (list<HWND>::iterator i = m_Handles.begin (); i != m_Handles.end(); i++)
		ShowWindow (*i, SW_MAXIMIZE);

	return true;
}

bool CWindowEngine::RestoreWindow()
{
	if (m_Handles.size () <= 0)
		return false;
	
	for (list<HWND>::iterator i = m_Handles.begin (); i != m_Handles.end(); i++)
		ShowWindow (*i, SW_RESTORE);
	
	return true;
}

bool CWindowEngine::HideWindow()
{
	if (m_Handles.size () <= 0)
		return false;
	
	for (list<HWND>::iterator i = m_Handles.begin (); i != m_Handles.end (); i++)
		ShowWindow (*i, SW_HIDE);

	return true;
}

bool CWindowEngine::MoveWindow(int x, int y)
{
	if (m_Handles.size () <= 0)
		return false;
	
	for (list<HWND>::iterator i = m_Handles.begin (); i != m_Handles.end (); i++)
	{
		RECT rect;
		GetWindowRect (*i, &rect);
		::MoveWindow (*i, x, y, rect.right - rect.left, rect.bottom - rect.top, TRUE);
	}
	return true;
}

bool CWindowEngine::ResizeWindow(int w, int h)
{
	if (m_Handles.size () <= 0)
		return false;
	
	for (list<HWND>::iterator i = m_Handles.begin (); i != m_Handles.end (); i++)
	{
		RECT rect;
		GetWindowRect (*i, &rect);
		::MoveWindow (*i, rect.left, rect.top, w, h, TRUE);
	}
	return true;
}

bool CWindowEngine::WaitToAppear(int nTimeout)
{
	bool bTimeout = true;
	if (nTimeout == 0)
		bTimeout = false;
	else
		bTimeout = true;
	
	int tick = GetTickCount ();
	int iEndTime = tick + nTimeout;
	
	m_Handles.clear ();
	FindAllWindows ();
	
	if (m_Handles.size () > 0)
		return true;
	
	for (;;)
	{
		tick = GetTickCount ();
		
		if (bTimeout && (tick > iEndTime))
			return false;
		
		Sleep (750);
		
		m_Handles.clear ();
		FindAllWindows ();
		
		if (m_Handles.size () > 0)
			return true;
	}
	return true;
}

bool CWindowEngine::WaitToDisappear(int nTimeout)
{
	bool bTimeout = true;
	if(nTimeout == 0)
		bTimeout = false;
	else
		bTimeout = true;
	
	int tick = GetTickCount ();
	int iEndTime = tick + nTimeout;
	
	m_Handles.clear ();
	FindAllWindows ();
	
	if (m_Handles.size () == 0)
		return true;
	
	for (;;)
	{
		tick = GetTickCount ();
		
		if (bTimeout && (tick > iEndTime))
			return false;
		
		Sleep (750);
		
		m_Handles.clear ();
		FindAllWindows ();
		
		if (m_Handles.size () == 0)
			return true;
	}
	return true;
}

void CWindowEngine::FindAllWindows()
{
	LPARAM lParam = 0;
	
	if (m_bExact)
		lParam |= FIND_EXACT;
	if (!m_sTitle.IsEmpty ())
		lParam |= FIND_TITLE;
	if (!m_sClass.IsEmpty ())
		lParam |= FIND_CLASSNAME;
	if (!m_sText.IsEmpty ())
		lParam |= FIND_TEXT;
	if (m_bApplyToAll)
		lParam |= FIND_ALL;
	if (m_bCaseSensitive)
		lParam |= FIND_CASESENSITIVE;
	
	CSingleLock lock (&gWindowEngine);
	lock.Lock ();
	pWndOp = this;
    EnumWindows ((WNDENUMPROC)EnumWindowsProc, lParam);
	lock.Unlock ();
}

BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
	if (pWndOp == NULL)
		return FALSE;

	bool found = true;
	if (hwnd)
	{
		TCHAR szTemp [256];
		
		if ((lParam & FIND_TITLE))
		{
			GetWindowText (hwnd, szTemp, 255);
			CString sTitle (szTemp);
			if (!sTitle.IsEmpty ())
			{
				if ((lParam & FIND_EXACT))
				{
					if ((lParam & FIND_CASESENSITIVE))
					{
						if (sTitle.Compare (pWndOp->m_sTitle) != 0)
							found = false;
					}
					else
					{
						if (sTitle.CompareNoCase (pWndOp->m_sTitle) != 0)
							found = false;
					}
				}
				else
				{
					if ((lParam & FIND_CASESENSITIVE))
					{
						if ( sTitle.Find (pWndOp->m_sTitle, 0) == -1)
							found = false;
					}
					else
					{
						sTitle.MakeLower ();
						if ( sTitle.Find (pWndOp->m_sTitleLower, 0) == -1)
							found = false;
					}
						
				}
			}
			else
				found = false;
		}

		if (found && (lParam & FIND_CLASSNAME))
		{
			GetClassName (hwnd, szTemp, 255);
			CString sClass (szTemp);
			if (!sClass.IsEmpty ())
			{
				if ((lParam & FIND_CASESENSITIVE))
				{
					if (sClass.Compare (pWndOp->m_sClass) != 0)
						found = false;
				}
				else
				{
					if (sClass.CompareNoCase (pWndOp->m_sClass) != 0)
						found = false;
				}

			}
			else
				found = false;
		}
		
		if (found && (lParam & FIND_TEXT))
		{
			if (!FindText (hwnd))
				found = false;
		}
		
		if (found)
		{
			pWndOp->m_Handles.push_back (hwnd);
			if (!(lParam & FIND_ALL))
				return FALSE;
		}
		return TRUE;
	}
	else
		return FALSE;
}

bool FindText(HWND hwnd)
{
	if (pWndOp == NULL)
		return false;

	bool bResult = false;
	LPARAM lParam = (LPARAM)(&bResult);
	EnumChildWindows (hwnd, (WNDENUMPROC)EnumChildProc, lParam);

	return bResult;
}

BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam)
{
	if (pWndOp == NULL)
		return FALSE;
	
	if (hwnd)
	{
		TCHAR szTemp [1024] = {_T('\0')};
		
		//GetWindowText (hwnd, szTemp, 255);
		SendMessage (hwnd, WM_GETTEXT, sizeof(szTemp) / sizeof(TCHAR), (LPARAM)szTemp);
		
		CString sText (szTemp);
		if (!sText.IsEmpty ())
		{
			if (pWndOp->m_bCaseSensitive)
			{
				if (sText.Find (pWndOp->m_sText, 0) != -1)
				{
					*((bool*)lParam) = true;
					return FALSE;
				}
			}
			else
			{
				sText.MakeLower ();
				if (sText.Find (pWndOp->m_sTextLower, 0) != -1)
				{
					*((bool*)lParam) = true;
					return FALSE;
				}
				
			}
		}

		//if(FindText (hwnd))
		//{
		//	*((bool*)lParam) = true;
		//	return FALSE;
		//}
		return TRUE;
	}
	else
		return FALSE;
}

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)


Written By
Software Developer
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions