Click here to Skip to main content
15,896,201 members
Articles / Programming Languages / C#

Automating Windows Applications

Rate me:
Please Sign up or sign in to vote.
4.95/5 (137 votes)
1 Feb 2003CPOL11 min read 393.1K   12.3K   309  
A Windows application that does not export any program interface, may be converted to automation server with COM object(s) injected into the application process.
// NotepadPlugin.cpp : Defines the entry point for the DLL application.
//

#include "stdafx.h"

// Import type library for IHandlerPtr
#include "ImportNotepadHandlerTlb.h"

// File contains functions to find/wait for window of specified class 
#include "GetTargetAppWindow.cpp"

static IHandlerPtr g_spHandler = NULL; // pointer to embedded COM object

static const UINT WM_CREATE_OBJECT = RegisterWindowMessage( _T("Create Object") );

static DWORD g_pfnOldFrameWndProc;	// pointer to original frame window procedure
static DWORD g_pfnOldViewWndProc;   // pointer to original view  window procedure


//
// New frame window procedure
//
LRESULT CALLBACK FrameWndProc(HWND hWnd, UINT dwMsg, WPARAM wParam, LPARAM lParam) 
{
	if ( WM_CREATE_OBJECT == dwMsg )
	{
		// Handler of special message to create embedded COM object
		if ( FAILED(CoInitialize(NULL)) )
		{
			// If COM initialization failed then restore original window procedure
			SetWindowLong( hWnd, GWL_WNDPROC, (DWORD)g_pfnOldFrameWndProc );
			return 0;
		}

		HRESULT hr = E_FAIL;
		if ( NULL == g_spHandler )
			// Create embedded COM object
			hr = g_spHandler.CreateInstance( __uuidof(Handler) );

		if ( SUCCEEDED(hr) )
			// Provide embedded COM object with Notepad frame window handle
			hr = g_spHandler->SetWnd( (DWORD)hWnd );

		if ( SUCCEEDED(hr) )
			// Register embedded COM object with Running Objects Table (ROT)
			hr = g_spHandler->RegisterWithROT();

		if ( SUCCEEDED(hr) )
			//MessageBox( hWnd, _T("I've been Automated!"), _T("Notepad"), MB_TOPMOST );
			SetWindowText( hWnd, _T("Notepad  [Automated]") );	

		return hr;
	}
	
	switch ( dwMsg )
	{
	case WM_DESTROY:
		if ( NULL != g_spHandler )
		{
			g_spHandler->UnregisterWithROT();
			g_spHandler = NULL;
			MessageBox( hWnd, _T("Bye-Bye..."), _T("Notepad"), MB_TOPMOST );
		}
		break;
	}

	// Pass message on to the original window procedure
	return CallWindowProc( (WNDPROC)g_pfnOldFrameWndProc, hWnd, dwMsg, wParam, lParam );
}


//
// New view window procedure
//
LRESULT CALLBACK ViewWndProc(HWND hWnd, UINT dwMsg, WPARAM wParam, LPARAM lParam) 
{
	switch ( dwMsg )
	{
	case WM_CHAR:
		// Key pressed, char inserted to view window
		if ( g_spHandler )
		{
			TCHAR szChar[2];
			_stprintf( szChar, _T("%c"), (TCHAR)wParam );

			// Pass inserted character to embedded COM object
			g_spHandler->SetText( (_bstr_t)szChar );
		}
		break;
	}

	// Pass message on to the original window procedure
	return CallWindowProc( (WNDPROC)g_pfnOldViewWndProc, hWnd, dwMsg, wParam, lParam );
}


//
// Injected DLL activities function
//
BOOL PluginProc()
{
	BOOL br = FALSE;

	// Find/wait for window of specified class
	HWND hWnd = WaitForWndOfClass( g_szTargetWndClass );
	if ( 0 != hWnd )
	{
		// Subclass frame window of target application
		g_pfnOldFrameWndProc = GetWindowLong( hWnd, GWL_WNDPROC );
		SetWindowLong( hWnd, GWL_WNDPROC, (DWORD)FrameWndProc );

		// Subclass view window
		HWND hClientWnd = GetWindow( hWnd, GW_CHILD );
		g_pfnOldViewWndProc = GetWindowLong( hClientWnd, GWL_WNDPROC );
		SetWindowLong( hClientWnd, GWL_WNDPROC, (DWORD)ViewWndProc );

		// Post message to new window procedure to create COM object
		PostMessage( hWnd, WM_CREATE_OBJECT, 0, 0 );
		br = TRUE;
	}

	return br;
}

	
//
// Dll entry point
//
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD nReason, LPVOID pReserved)
{
	BOOL br = FALSE;
	if ( nReason == DLL_PROCESS_ATTACH )
		br = PluginProc();

	return br;
}

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 (Senior)
Israel Israel


  • Nov 2010: Code Project Contests - Windows Azure Apps - Winner
  • Feb 2011: Code Project Contests - Windows Azure Apps - Grand Prize Winner



Comments and Discussions