Click here to Skip to main content
15,895,667 members
Articles / Desktop Programming / WTL

ScriptRunner Application

Rate me:
Please Sign up or sign in to vote.
4.97/5 (18 votes)
25 Mar 2007CPOL4 min read 88.6K   1.9K   90  
An Introduction to ScriptRunner. A scripting tool for user interface Unit Testing.
// ScriptRunner.cpp : main source file for ScriptRunner.exe
//

#include "stdafx.h"

#include "resource.h"

// Note: Proxy/Stub Information
//		To build a separate proxy/stub DLL, 
//		run nmake -f ScriptRunnerps.mk in the project directory.
#include "initguid.h"
#include "ScriptRunner.h"
#include "ScriptRunner_i.c"

#include "MainFrm.h"
#include "ScriptHost.h"
#include "SRWindowDisp.h"

#define SCRIPTRUNNER_OBJECT	_T("ScriptRunner_IsRunning")
#define SCRIPTRUNNER_SCHOST	_T("ScriptRunner.ScriptHost")

CAppModule _Module;

BEGIN_OBJECT_MAP(ObjectMap)
OBJECT_ENTRY(CLSID_ScriptHost, CScriptHost)
OBJECT_ENTRY(CLSID_SRWindowDisp, CSRWindowDisp)
END_OBJECT_MAP()

int Run(/*LPTSTR lpstrCmdLine = NULL, int nCmdShow = SW_SHOWDEFAULT*/)
{
	CMessageLoop theLoop;
	_Module.AddMessageLoop(&theLoop);

	CMainFrame wndMain;

	if(wndMain.CreateEx() == NULL)
	{
		ATLTRACE(_T("Main window creation failed!\n"));
		PostThreadMessage(_Module.m_dwMainThreadID, WM_QUIT, 0, NULL);
		return 0;
	}

	_Module.Lock();
	wndMain.ShowWindow(SW_SHOWDEFAULT);

	int nRet = theLoop.Run();

	_Module.Unlock();
	_Module.RemoveMessageLoop();
	PostThreadMessage(_Module.m_dwMainThreadID, WM_QUIT, 0, NULL);
	return nRet;
}

DWORD WINAPI MainWindowThread(LPVOID)
{
	HRESULT hRes = ::CoInitialize(NULL);
	Run();
	::CoUninitialize();
	return 0L;
}

LPCTSTR FindOneOf(LPCTSTR p1, LPCTSTR p2)
{
    while (p1 != NULL && *p1 != NULL)
    {
        LPCTSTR p = p2;
        while (p != NULL && *p != NULL)
        {
            if (*p1 == *p)
                return CharNext(p1);
            p = CharNext(p);
        }
        p1 = CharNext(p1);
    }
    return NULL;
}


int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpstrCmdLine, int nCmdShow)
{
	HANDLE hMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, SCRIPTRUNNER_OBJECT);
	if (hMutex)
	{
		CWindow winScripter = FindWindow(SCRIPTRUNNER_FRAME, NULL);
		if ( winScripter.IsWindow() )
		{
			::SetForegroundWindow(winScripter);
			MessageBeep(MB_OK);
		}
		CloseHandle( hMutex );
		return 0;
	}

	hMutex = CreateMutex(NULL, TRUE, SCRIPTRUNNER_OBJECT);
	if (!hMutex)
		return 0;
	HRESULT hRes = ::CoInitialize(NULL);
// If you are running on NT 4.0 or higher you can use the following call instead to 
// make the EXE free threaded. This means that calls come in on a random RPC thread.
//	HRESULT hRes = ::CoInitializeEx(NULL, COINIT_MULTITHREADED);
	ATLASSERT(SUCCEEDED(hRes));

	// this resolves ATL window thunking problem when Microsoft Layer for Unicode (MSLU) is used
	::DefWindowProc(NULL, 0, 0, 0L);

	AtlInitCommonControls(ICC_COOL_CLASSES | ICC_BAR_CLASSES);	// add flags to support other controls

	hRes = _Module.Init(ObjectMap, hInstance);
	ATLASSERT(SUCCEEDED(hRes));

	int nRet = 0;
	TCHAR szTokens[] = _T("-/");
	bool bRun = true;

	LPCTSTR lpszToken = FindOneOf(::GetCommandLine(), szTokens);
	while(lpszToken != NULL)
	{
		if(lstrcmpi(lpszToken, _T("UnregServer")) == 0)
		{
			nRet = _Module.UnregisterServer(TRUE);
			bRun = false;
			break;
		}
		else if(lstrcmpi(lpszToken, _T("RegServer")) == 0)
		{
			nRet = _Module.RegisterServer(TRUE);
			bRun = false;
			break;
		}
		lpszToken = FindOneOf(lpszToken, szTokens);
	}

	if(bRun)
	{
		// Autoregistration...
		CRegKey regkey;
		hRes = regkey.Open(HKEY_CLASSES_ROOT, SCRIPTRUNNER_SCHOST);
		regkey.Close();
		if (ERROR_SUCCESS != hRes)
		{
			_Module.RegisterServer(TRUE);
		}

		hRes = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE);
		ATLASSERT(SUCCEEDED(hRes));

		// Run main window thread -
		// to run the main window message loop
		AtlCreateThread<void>(MainWindowThread, NULL);

		// local-server thread loops here until
		// main window is destroyed...
		MSG msg;
		while (GetMessage(&msg, 0, 0, 0))
			DispatchMessage(&msg);

		_Module.RevokeClassObjects();
	}

	_Module.Term();
	::CoUninitialize();
	CloseHandle(hMutex);
	return nRet;
}

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)
United States United States
Ernest is a multi-discipline software engineer.
Skilled at software design and development for all Windows platforms.
-
MCSD (C#, .NET)
Interests: User Interface, GDI/GDI+, Scripting, Android, iOS, Windows Mobile.
Programming Skills: C/C++, C#, Java (Android), VB and ASP.NET.

I hope you will enjoy my contributions.

Comments and Discussions