// Utils.cpp: implementation of the CUtils class
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Utils.h"
#include 
#pragma data_seg(".xkmcs")
char CUtils::m_szApplicationName[MAX_PATH] = {'\0'};
char CUtils::m_szIMEName[MAX_PATH] = {'\0'};
OSVERSIONINFO CUtils::m_OsVersionInfo = {sizeof(OSVERSIONINFO)};
#pragma data_seg()

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

CUtils::CUtils()
{

}

CUtils::~CUtils()
{

}

BOOL CUtils::GetFindDialogTitle(CString *szDialogTitle)
{
	{
		TCHAR buf[0x100] = {'\0'};
		GetWindowText(GetForegroundWindow(), buf, sizeof(buf));
//		CUtils::Log("Window Text --%s--", buf);
		szDialogTitle->Format("%s", buf);
	}

	if (!szDialogTitle->Compare("検索")					// notepad, wordpad, IE, regedit, 
														// Excel, Front Page, PowerPoint, Acrobat Reader, IBM HPB
	 || !szDialogTitle->Compare("Find")					// notepad, Outlook, Outlook Express, Opera
	 || !szDialogTitle->Compare("Find in this Page")	// Mozilla
	 || !szDialogTitle->Compare("Find/Replace")			// Eclipse
	 || !szDialogTitle->Compare("本文内検索")			// Becky!
	 || !szDialogTitle->Compare("メール検索")			// Becky!
	 || !szDialogTitle->Compare("文字列の検索")			// M$ VC++
	 || !szDialogTitle->Compare("検索と置換")			// M$ Word, 123
	 || !szDialogTitle->Compare("文書のテキストの検索")	// Lotus Notes
	 || !szDialogTitle->Compare("このページを検索")		// Netscape 6
	 || !szDialogTitle->Compare("文字列検索")			// Dana
	 || !szDialogTitle->Compare("検索/置換")			// PHP Editor
	 || !szDialogTitle->Compare("置換")
	 || !szDialogTitle->Compare("Replace")) {
		return TRUE;
	}

	szDialogTitle->Empty();
	return FALSE;
}

BOOL CUtils::IsFindDialog()
{
	CString szDialogTitle;
	return GetFindDialogTitle(&szDialogTitle);
}

BOOL CUtils::IsAstecX()
{
	return !stricmp(m_szApplicationName, "astecx.exe");
}

BOOL CUtils::IsBecky()
{
	return !stricmp(m_szApplicationName, "b2.exe");
}

BOOL CUtils::IsEmacs()
{
	return !stricmp(m_szApplicationName, "Emacs.exe");
}

BOOL CUtils::IsExplorer()
{
	return !stricmp(m_szApplicationName, "explorer.exe");
}

BOOL CUtils::IsHidemaru()
{
	return !stricmp(m_szApplicationName, "hidemaru.exe");
}

BOOL CUtils::IsInternetExplorer()
{
	return !stricmp(m_szApplicationName, "iexplore.exe");
}

BOOL CUtils::IsLotus123()
{
	return !stricmp(m_szApplicationName, "123w.exe");
}

BOOL CUtils::IsLotusNotes()
{
	return !stricmp(m_szApplicationName, "nlnotes.exe");
}

BOOL CUtils::IsLotusWordPro()
{
	return !stricmp(m_szApplicationName, "wordpro.exe");
}

BOOL CUtils::IsMeadow()
{
	return !stricmp(m_szApplicationName, "Meadow.exe")
		|| !stricmp(m_szApplicationName, "Meadow95.exe")
		|| !stricmp(m_szApplicationName, "MeadowNT.exe");
}

BOOL CUtils::IsMicrosoftFrontPage()
{
	return !stricmp(m_szApplicationName, "frontpg.exe");
}

BOOL CUtils::IsMicrosoftWord()
{
	return !stricmp(m_szApplicationName, "winword.exe");
}

BOOL CUtils::IsMozilla()
{
	return !stricmp(m_szApplicationName, "mozilla.exe");
}

BOOL CUtils::IsMuleForWin32()
{
	return !stricmp(m_szApplicationName, "mule.exe")
		|| !stricmp(m_szApplicationName, "mulent.exe")
		|| !stricmp(m_szApplicationName, "mulecd.exe");
}

BOOL CUtils::IsNetscape()
{
	return !stricmp(m_szApplicationName, "netscp6.exe")
		|| !stricmp(m_szApplicationName, "netscp.exe");
}

BOOL CUtils::IsNotepad()
{
	return !stricmp(m_szApplicationName, "notepad.exe");
}

BOOL CUtils::IsOpera()
{
	return !stricmp(m_szApplicationName, "opera.exe");
}

BOOL CUtils::IsOutlook()
{
	return !stricmp(m_szApplicationName, "outlook.exe");
}

BOOL CUtils::IsOutlookExpress()
{
	return !stricmp(m_szApplicationName, "msimn.exe");
}

BOOL CUtils::IsSakuraEditor()
{
	return !stricmp(m_szApplicationName, "sakura.exe");
}

BOOL CUtils::IsTeraTermPro()
{
	return !stricmp(m_szApplicationName, "ttermpro.exe");
}

BOOL CUtils::IsVisualCpp()
{
	return !stricmp(m_szApplicationName, "msdev.exe");
}

BOOL CUtils::IsWordpad()
{
	return !stricmp(m_szApplicationName, "wordpad.exe");
}

BOOL CUtils::IsXWin()
{
	return !stricmp(m_szApplicationName, "XWin.exe");
}

BOOL CUtils::IsXyzzy()
{
	return !stricmp(m_szApplicationName, "xyzzy.exe");
}

const char *const CUtils::GetApplicationName()
{
	return m_szApplicationName;
}

void CUtils::FairConsoleApplicationName(char *szApplicationName, int nApplicationNameLength, char *szWindowText, int nWindowTextLength)
{
	if (IsFindDialog()) {
		return;
	}

	if (*szWindowText == '"' && strchr(szWindowText+1, '"')) {		// "foo bar" -> foo bar
		int nApplicationName = strchr(szWindowText+1, '"') - szWindowText - 1;	// length of "foo bar"
		strncpy(szWindowText, szWindowText + 1, nApplicationName);
		memset(szWindowText + nApplicationName, 0, nWindowTextLength - nApplicationName);
	} else if (strchr(szWindowText, ' ')) {	// foo bar -> foo
		char *pFirstSpace = strchr(szWindowText, ' ');
		memset(pFirstSpace, 0, nWindowTextLength - (pFirstSpace - szWindowText));
	}

	memset(szApplicationName, 0, nApplicationNameLength);
	sprintf(szApplicationName, "%s", szWindowText);

	static const char* const szExe = ".exe";
	if (strnicmp(szApplicationName + strlen(szApplicationName) - strlen(szExe), szExe, strlen(szExe))) {
		strcat(szApplicationName, szExe);
	}
}

// Set real application name in the szApplicationName.
void CUtils::SetCorrectApplicationName(char *szApplicationName, const int nApplicationNameLength, char *szWindowText, const int nWindowTextLength)
{
	if (IsConsole(szApplicationName, nApplicationNameLength)) {
		int i = 0;
		static const char* const szPromptName[] = {"Command Prompt", "Mark Command Prompt", "Select Command Prompt", "MS-DOS Prompt",
												   "Visual Studio .NET Command Prompt", "Visual Studio .NET 2003 Command Prompt",
												   "コマンド プロンプト", "範囲指定 コマンド プロンプト", "選択 コマンド プロンプト", "MS-DOS プロンプト",
												   "Visual Studio .NET コマンド プロンプト", "Visual Studio .NET 2003 コマンド プロンプト"};
		static const char* const szPromptPath[] = {"system32\\cmd.exe"};	// WindowText of Command Prompt is sometimes this style. But MS-DOS Prompt's is always MS-DOS Prompt.
		static const char* const szSeparator = " - ";

		for (i = 0; i < sizeof(szPromptName) / sizeof(szPromptName[0]); ++i) {
			if (!stricmp(szWindowText, szPromptName[i])) {	// "Command Prompt"
				return;
			}

			char sz[0x100] = {'\0'};
			sprintf(sz, "%s%s", szPromptName[i], szSeparator);

			if (!strnicmp(szWindowText, sz, strlen(sz))) {	// "Command Promp - foo"
				strcpy(szWindowText, szWindowText + strlen(sz));
				FairConsoleApplicationName(szApplicationName, nApplicationNameLength, szWindowText, nWindowTextLength);
				return;
			}
		}

		for (i = 0; i < sizeof(szPromptPath) / sizeof(szPromptPath[0]); ++i) {
			char szWindowTextLower[0x100] = {'\0'};
			strcpy(szWindowTextLower, szWindowText);
			strlwr(szWindowTextLower);

			if (strstr(szWindowTextLower, szPromptPath[i])) {
				char sz[0x100] = {'\0'};
				sprintf(sz, "%s%s", szPromptPath[i], szSeparator);

				if (strstr(szWindowTextLower, sz)) {				// "X:\WINNT\system32\cmd.exe - foo"
					strcpy(szWindowText, strstr(szWindowTextLower, sz) + strlen(sz));
					FairConsoleApplicationName(szApplicationName, nApplicationNameLength, szWindowText, nWindowTextLength);
					return;
				} else {									// "X:\WINNT\system32\cmd.exe"
					return;
				}
			}
		}

		if (!stricmp(szWindowText, "Cygwin Bash Shell")
		 || (*szWindowText == '~')
		 || (*szWindowText == '/')) {						// Bash
			memset(szApplicationName, 0, nApplicationNameLength);
			sprintf(szApplicationName, "bash.exe");
			memset(szWindowText, 0, nWindowTextLength);
			sprintf(szWindowText, "bash");
		} else if (!stricmp(szWindowText + strlen(szWindowText) - 8, " - pdksh")) {
			memset(szApplicationName, 0, nApplicationNameLength);
			sprintf(szApplicationName, "pdksh.exe");
			memset(szWindowText, 0, nWindowTextLength);
			sprintf(szWindowText, "pdksh");
		} else if (!stricmp(szWindowText + strlen(szWindowText) - 7, " - tcsh")) {
			memset(szApplicationName, 0, nApplicationNameLength);
			sprintf(szApplicationName, "tcsh.exe");
			memset(szWindowText, 0, nWindowTextLength);
			sprintf(szWindowText, "tcsh");
		} else if (!stricmp(szWindowText + strlen(szWindowText) - 6, " - zsh")) {
			memset(szApplicationName, 0, nApplicationNameLength);
			sprintf(szApplicationName, "zsh.exe");
			memset(szWindowText, 0, nWindowTextLength);
			sprintf(szWindowText, "zsh");
		} else if (!strnicmp(szWindowText, "MKS Korn Shell", 14)
				|| !strnicmp(szWindowText, "cat", 3)) {
			memset(szApplicationName, 0, nApplicationNameLength);
			sprintf(szApplicationName, "sh.exe");
			memset(szWindowText, 0, nWindowTextLength);
			sprintf(szWindowText, "MKS Korn Shell");
		} else if (!strnicmp(szWindowText + 1, ":/", 2)
				|| !strnicmp(szWindowText + 1, ":\\", 2)) {
			memset(szApplicationName, 0, nApplicationNameLength);
			sprintf(szApplicationName, "csh.exe");
			memset(szWindowText, 0, nWindowTextLength);
			sprintf(szWindowText, "C Shell");
		} else {											// unknown console application
			FairConsoleApplicationName(szApplicationName, nApplicationNameLength, szWindowText, nWindowTextLength);
		}
	} else if (IsJavaW(szApplicationName, nApplicationNameLength)) {
		if (!stricmp(szWindowText + strlen(szWindowText) - 19, " - Eclipse Platform")) {
			memset(szApplicationName, 0, nApplicationNameLength);
			sprintf(szApplicationName, "eclipse.exe");
		} else if (!stricmp(szWindowText, "BlueJ")
			    || !strnicmp(szWindowText, "BlueJ: ", 7)) {
			memset(szApplicationName, 0, nApplicationNameLength);
			sprintf(szApplicationName, "bluej.exe");
		} else if (!stricmp(szWindowText, "JUDE")
			    || !strnicmp(szWindowText, "JUDE - ", 7)) {
			memset(szApplicationName, 0, nApplicationNameLength);
			sprintf(szApplicationName, "jude.exe");
		}
	}
	return;
}

void CUtils::SetApplicationName(BOOL bImeComposition)
{
//	CUtils::Log("SetApplicationName: start");

	memset(m_szApplicationName, 0, sizeof(m_szApplicationName));

	if (bImeComposition) {
//		CUtils::Log("SetApplicationName: bImeComposition");

		HKL hKL = GetKeyboardLayout(0);
		if (ImmIsIME(hKL)) {
			ImmGetIMEFileName(hKL, m_szApplicationName, sizeof(m_szApplicationName));
			strncpy(m_szIMEName, m_szApplicationName, sizeof(m_szIMEName));
		} else {
			// ImmIsIME return 0 on Word2002, Excel2002, etc. with IME2002, so...
			// strncpy(m_szApplicationName, "imjp81.ime", sizeof(m_szApplicationName));
			strncpy(m_szApplicationName, m_szIMEName, sizeof(m_szApplicationName));
		}
	} else {
//		CUtils::Log("SetApplicationName: appication (%s)", m_szApplicationName);

		GetModuleFileName(NULL, m_szApplicationName, sizeof(m_szApplicationName));
		CString szFn(m_szApplicationName);
		szFn.Delete(0, szFn.ReverseFind('\\') + 1);
		ZeroMemory(m_szApplicationName, sizeof(m_szApplicationName));
		strncpy(m_szApplicationName, szFn, szFn.GetLength());

//		CUtils::Log("SetApplicationName: appication [%s]", m_szApplicationName);

		if (IsConsole()) {
//			CUtils::Log("SetApplicationName: console");

			memset(m_szApplicationName, 0, sizeof(m_szApplicationName));
			if (IsNT()) {
				strcpy(m_szApplicationName, "CMD.exe");
			} else {
				strcpy(m_szApplicationName, "WINOA386.MOD");
			}
			TCHAR szWindowText[0x100] = {'\0'};
			GetWindowText(GetForegroundWindow(), szWindowText, sizeof(szWindowText));
			SetCorrectApplicationName(m_szApplicationName, sizeof(m_szApplicationName), szWindowText, sizeof(szWindowText));
		} else if (IsJavaW()) {
			TCHAR szWindowText[0x100] = {'\0'};
			GetWindowText(GetForegroundWindow(), szWindowText, sizeof(szWindowText));
			SetCorrectApplicationName(m_szApplicationName, sizeof(m_szApplicationName), szWindowText, sizeof(szWindowText));
		}
		if (!stricmp(m_szApplicationName, "Cygwin.exe")) {
//			CUtils::Log("SetApplicationName: cygwin");

			memset(m_szApplicationName, 0, sizeof(m_szApplicationName));
			strcpy(m_szApplicationName, "bash.exe");
		}
//		CUtils::Log("name: %s", m_szApplicationName);
	}
}

void CUtils::SetIMEName()
{
	HKL hKL = GetKeyboardLayout(0);
	if (ImmIsIME(hKL)) {
		ImmGetIMEFileName(hKL, m_szIMEName, sizeof(m_szIMEName));
	}
}

void CUtils::InitCUtils()
{
	GetVersionEx(&m_OsVersionInfo);
	SetIMEName();
}

BOOL CUtils::IsNTor9x()
{
	return ((m_OsVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) && (m_OsVersionInfo.dwMajorVersion <= 4))
		 || (m_OsVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS);
}

BOOL CUtils::IsXPorLater()
{
	return 5 < m_OsVersionInfo.dwMajorVersion
		|| 5 == m_OsVersionInfo.dwMajorVersion && 1 <= m_OsVersionInfo.dwMinorVersion;
}

BOOL CUtils::IsNT()
{
	return m_OsVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT;
}

BOOL CUtils::OpenClipboard()
{
	const int RETRY_COUNT = 0x10;

	BOOL bOpened = FALSE;
	for (int i = 0; i <= RETRY_COUNT; ++i) {
		if (::OpenClipboard(NULL)) {
//			Log("ok (%d)", i);
			bOpened = TRUE;
			break;
		} else {
			Sleep(1);	// for OpenOffice
//			Log("CUtils::OpenClipboard: %d (%d)", GetLastError(), i);
		}
	}
	ASSERT(bOpened);
	return bOpened;
}

BOOL CUtils::GetClipboardText(CString *szClipboardText)
{
	if (!szClipboardText) {
		return FALSE;
	}

	szClipboardText->Empty();

	if (!OpenClipboard()) {
//		CUtils::Log("Cannot open the Clipboard");
		return FALSE;
	}

/*
	{
		Log("GetClipboardText");
		UINT uFormat = 0;
		for (;;) {
			uFormat = EnumClipboardFormats(uFormat);
			if (uFormat) {
				Log("uFormat = %d", uFormat);
			} else {
				break;
			}
		}
// winuser.h
//#define CF_TEXT             1
//#define CF_METAFILEPICT     3
//#define CF_OEMTEXT          7
//#define CF_UNICODETEXT      13
//#define CF_ENHMETAFILE      14
//#define CF_LOCALE           16
//#define CF_DSPTEXT          0x0081
// OwnerLink						49155
// Native							49156
// DataObject						49161
// Embed Source						49163
// Object Descriptor				49166
// Ole Private Data					49171
// Rich Text Format					49311
// Rich Text Format					49312
// HTML Format						49360
// HTML Format						49361
// Link								49408
// RTF As Text						49595
// Rich Text Format Without Objects	49618
// Star Object Descriptor (XML)		49681
// Star Embed Source (XML)			49708
// HPB HTML Format					49742
	}
*/

	UINT uFormat = CF_OEMTEXT;
	if (IsSakuraEditor()) {
		uFormat = CF_TEXT;
	}

	HANDLE hClipboardText;
	if ((hClipboardText = ::GetClipboardData(uFormat)) == NULL) {
//		DWORD dw = GetLastError();
//		CUtils::Log("Unable to get Clipboard data: %d", dw);
		CloseClipboard();
		return FALSE;
	}

	szClipboardText->Format("%s", hClipboardText);
	EmptyClipboard();
	CloseClipboard();
	return TRUE;
}

BOOL CUtils::SetClipboardText(CString *szClipboardText)
{
	if (!OpenClipboard()) {
//		CUtils::Log("Cannot open the Clipboard in SetClipboardText");
		return FALSE;
	}

	int nLength = szClipboardText->GetLength() + 1;
	HGLOBAL hClipboardText = GlobalAlloc(GHND, nLength);
	if (hClipboardText == NULL) {
//		CUtils::Log("Failed: GlobalAlloc in SetClipboardText");
		return FALSE;
	}

	LPSTR lpStr = (LPSTR)GlobalLock(hClipboardText);
	lstrcpyn(lpStr, *szClipboardText, nLength);
	GlobalUnlock(hClipboardText);
	EmptyClipboard();

	UINT uFormat = CF_OEMTEXT;
	if (IsSakuraEditor()) {
		uFormat = CF_TEXT;
	}

	if ((hClipboardText = ::SetClipboardData(uFormat, hClipboardText)) == NULL) {
//		DWORD dw = GetLastError();
//		CUtils::Log("Unable to set Clipboard data: %d", dw);
		CloseClipboard();
		return FALSE;
	}

	CloseClipboard();
	return TRUE;
}

BOOL CUtils::IsDefaultIgnoreApplication()
{
	if (IsAstecX()
	 || IsBash()
	 || IsCsh()
	 || IsEmacs()
	 || IsLispWorksPersonalEdition()
	 || IsMeadow()
	 || IsMuleForWin32()
	 || IsPdksh()
	 || IsSh()
	 || IsTcsh()
	 || IsTeraTermPro() && !IsDialog()
	 || IsVisualSlickEdit() && !IsDialog()
	 || IsXWin()
	 || IsXyzzy() && !IsDialog()
	 || IsZsh()) {
		return TRUE;
	}
	return FALSE;
}

BOOL CUtils::IsDWFM()
{
	return !stricmp(m_szApplicationName, "dwfm.exe");
}

BOOL CUtils::IsK2Editor()
{
	return !stricmp(m_szApplicationName, "K2Editor.exe");
}

BOOL CUtils::IsEggExplorer()
{
	return !stricmp(m_szApplicationName, "EggExp.exe");
}

BOOL CUtils::IsDirector()
{
	return !stricmp(m_szApplicationName, "Director.exe");
}

BOOL CUtils::IsExcel()
{
	return !stricmp(m_szApplicationName, "Excel.exe");
}

BOOL CUtils::IsFireworks()
{
	return !stricmp(m_szApplicationName, "Fireworks 4.exe")
		|| !stricmp(m_szApplicationName, "Fireworks.exe");
}

BOOL CUtils::IsDreamweaver()
{
	return !stricmp(m_szApplicationName, "Dreamweaver.exe");
}

BOOL CUtils::IsFlash()
{
	return !stricmp(m_szApplicationName, "Flash.exe");
}

BOOL CUtils::IsPhotoshop()
{
	return !stricmp(m_szApplicationName, "Photoshp.exe");
}

BOOL CUtils::IsIllustrator()
{
	return !stricmp(m_szApplicationName, "Illustrator.exe");
}

BOOL CUtils::IsMicrosoftPowerPoint()
{
	return !stricmp(m_szApplicationName, "PowerPnt.exe");
}

BOOL CUtils::IsReget()
{
	return !stricmp(m_szApplicationName, "Regetdx.exe")
		|| !stricmp(m_szApplicationName, "Regetjr.exe");
}

BOOL CUtils::IsPaint()
{
	return !stricmp(m_szApplicationName, "mspaint.exe");
}

BOOL CUtils::IsConsole()
{
//	Log("_%s_", m_szApplicationName);
	return !m_szApplicationName[0]
		|| !stricmp(m_szApplicationName, "xkeymacs.exe")
		|| !stricmp(m_szApplicationName, "conime.exe")
		|| !stricmp(m_szApplicationName, "csh.exe")
		|| !stricmp(m_szApplicationName, "WINOA386.MOD")
		|| !stricmp(m_szApplicationName, "CMD.exe")
		|| !stricmp(m_szApplicationName, "bash.exe")
		|| !stricmp(m_szApplicationName, "ftp.exe")
		|| !stricmp(m_szApplicationName, "sh.exe")
		|| !stricmp(m_szApplicationName, "telnet.exe");
}

BOOL CUtils::IsConsole(char *szApplicationName, int nApplicationNameLength)
{
	return !strnicmp(szApplicationName, "WINOA386.MOD", nApplicationNameLength)
		|| !strnicmp(szApplicationName, "CMD.exe", nApplicationNameLength);
}

BOOL CUtils::IsJavaW(char *szApplicationName, int nApplicationNameLength)
{
	return !strnicmp(szApplicationName, "javaw.exe", nApplicationNameLength);
}

BOOL CUtils::IsSleipnir()
{
	return !stricmp(m_szApplicationName, "Sleipnir.exe");
}

BOOL CUtils::IsBash()
{
	return !stricmp(m_szApplicationName, "bash.exe");
}

// for debug
void CUtils::Log(char *fmt, ...)
{
	va_list ap;
	va_start(ap, fmt);

	static const int LOG_MAX = 0x10000;
	char szLog[LOG_MAX] = {'\0'};

	for (unsigned int nIndex = 0; nIndex < strlen(fmt); ) {
		char* pNextString = fmt + nIndex;
		char* pLogEnd = szLog + strlen(szLog);

		if (*pNextString == '%') {
			char szFormatTag[LOG_MAX] = {'0'};
			strcpy(szFormatTag, pNextString);

			switch (GetFormatTag(szFormatTag)) {
			case 'd':
			case 'i':
			case 'o':
			case 'x':
			case 'X':
			case 'u':
			case 'c':
				sprintf(pLogEnd, szFormatTag, va_arg(ap, int));
				break;
			case 's':
				sprintf(pLogEnd, szFormatTag, va_arg(ap, char *));
				break;
			case 'f':
			case 'e':
			case 'E':
			case 'g':
			case 'G':
				sprintf(pLogEnd, szFormatTag, va_arg(ap, double));
				break;
			case 'p':
				sprintf(pLogEnd, szFormatTag, va_arg(ap, void *));
				break;
			case 'n':
				sprintf(pLogEnd, szFormatTag, va_arg(ap, int *));
				break;
			case '%':
			default:
				sprintf(pLogEnd, "%s", szFormatTag);
				break;
			}

			nIndex += strlen(szFormatTag);
		} else {
			char szString[LOG_MAX] = {'0'};
			strcpy(szString, pNextString);
			char* pString = strtok(szString, "%");
			sprintf(pLogEnd, "%s", pString);

			nIndex += strlen(pString);
		}
	}

	va_end(ap);

	static int n = 0;
	FILE *fp = fopen("c:\\xkeylog.txt", "a");
	fprintf(fp, "%8d: %s	%s\n", n++, m_szApplicationName, szLog);
	fflush(fp);
	fclose(fp);
}

BOOL CUtils::IsSh()
{
	return !stricmp(m_szApplicationName, "sh.exe");
}

BOOL CUtils::IsCsh()
{
	return !stricmp(m_szApplicationName, "csh.exe");
}

BOOL CUtils::IsVisualStudioDotNet()
{
	return !stricmp(m_szApplicationName, "devenv.exe");
}

BOOL CUtils::IsAccess()
{
	return !stricmp(m_szApplicationName, "MSACCESS.EXE");
}

BOOL CUtils::IsProject()
{
	return !stricmp(m_szApplicationName, "WINPROJ.EXE");
}

BOOL CUtils::IsVisualBasic()
{
	return !stricmp(m_szApplicationName, "VB6.EXE");
}

BOOL CUtils::IsVisualBasicEditor()
{
	if (IsVisualBasic()) {
		return TRUE;
	}

	if (IsAccess()
	 || IsExcel()
	 || IsMicrosoftFrontPage()
	 || IsMicrosoftPowerPoint()
	 || IsMicrosoftWord()
	 || IsOutlook()
	 || IsProject()) {
		TCHAR szWindowText[0x100] = {'\0'};
		GetWindowText(GetForegroundWindow(), szWindowText, sizeof(szWindowText));
		static const char* const szVBE = "Microsoft Visual Basic - ";
		if (!strnicmp(szWindowText, szVBE, strlen(szVBE))) {
			return TRUE;
		}
	}
	return FALSE;
}

BOOL CUtils::IsEclipse()
{
	TCHAR szWindowText[0x100] = {'\0'};
	GetWindowText(GetForegroundWindow(), szWindowText, sizeof(szWindowText));

	const char *szEclipse = " - Eclipse Platform";
	const char *szFind = "Find/Replace";

	return IsJavaW()
		&& (strlen(szEclipse) < strlen(szWindowText) && !stricmp(szWindowText + strlen(szWindowText) - strlen(szEclipse), szEclipse)
		 || strlen(szFind) == strlen(szWindowText) && !stricmp(szWindowText, szFind));
}

int CUtils::GetClipboardTextLength()
{
	CString szClipboardText;
	CUtils::GetClipboardText(&szClipboardText);
	CUtils::SetClipboardText(&szClipboardText);

//	return sz.GetLength();

	int nLength = 0;
	for (int i = 0; i < szClipboardText.GetLength(); ++i) {
		if (szClipboardText.GetAt(i) & 0x80) {
			++i;
		}
		++nLength;
	}
	return nLength;
}

BOOL CUtils::IsDialog()
{
	return GetParent(GetForegroundWindow()) != NULL;
}

int CUtils::GetFormatTag(char *szFormatTag)
{
	if (*(szFormatTag) != '%') {
		return NULL;
	}

	unsigned int nIndex = 1;

	// flags
	while (nIndex < strlen(szFormatTag)) {
		switch (*(szFormatTag + nIndex)) {
		case '-':
		case '+':
		case ' ':
		case '0':
		case '#':
			++nIndex;
			continue;
		default:
			break;
		}

		break;
	}

	// width
	while (isdigit(*(szFormatTag + nIndex))) {
		++nIndex;
	}

	// precision
	if (*(szFormatTag + nIndex) == '.') {
		++nIndex;
		while (isdigit(*(szFormatTag + nIndex))) {
			++nIndex;
		}
	}

	// prefix
	switch (*(szFormatTag + nIndex)) {
	case 'h':
	case 'l':
	case 'L':
		++nIndex;
		break;
	}

	// type
	switch (*(szFormatTag + nIndex)) {
	case 'd':
	case 'i':
	case 'o':
	case 'x':
	case 'X':
	case 'u':
	case 'c':
	case 's':
	case 'f':
	case 'e':
	case 'E':
	case 'g':
	case 'G':
	case 'p':
	case 'n':
	case '%':
		*(szFormatTag + nIndex + 1) = NULL;
		return *(szFormatTag + nIndex);
	default:
		*(szFormatTag + nIndex) = NULL;
		return NULL;
	}
}

BOOL CUtils::IsEudora()
{
	return !stricmp(m_szApplicationName, "Eudora.exe");
}

BOOL CUtils::IsCodeWarrior()
{
	return !stricmp(m_szApplicationName, "IDE.exe");
}

BOOL CUtils::IseMemoPad()
{
	return !stricmp(m_szApplicationName, "eMemoPad.exe");
}

BOOL CUtils::IsStoryEditor()
{
	return !stricmp(m_szApplicationName, "STRYEDIT.EXE");
}

BOOL CUtils::IsNami2000()
{
	return !stricmp(m_szApplicationName, "Nami2000.exe");
}

BOOL CUtils::IsCorelDRAW()
{
	return !stricmp(m_szApplicationName, "CorelDrw.exe");
}

// If Clipboard data is empty, return ture.
// You must CopyNextCharacter in previous step.
// Clipboard data is destroyed.
BOOL CUtils::IsEOF()
{
	return IsTOForEOF();
}

// If Clipboard data is empty, return ture.
// You must CopyBackCharacter in previous step.
// Clipboard data is destroyed.
BOOL CUtils::IsTOF()
{
	return IsTOForEOF();
}

BOOL CUtils::IsTOForEOF()
{
	CString szClipboardText;
	GetClipboardText(&szClipboardText);
	return szClipboardText.IsEmpty()			// for normal application
		|| szClipboardText.GetLength() >= 3;	// for VC++
}

BOOL CUtils::IsHusen()
{
	return !stricmp(m_szApplicationName, "husen.exe");
}

BOOL CUtils::IsAdobeReader()
{
	return !stricmp(m_szApplicationName, "AcroRd32.exe");
}

BOOL CUtils::IsOpenOffice()
{
	return !stricmp(m_szApplicationName, "soffice.exe");
}

BOOL CUtils::IsTuruKameMail()
{
	return !stricmp(m_szApplicationName, "TuruKame.exe");
}

BOOL CUtils::IsOedit()
{
	return !stricmp(m_szApplicationName, "oedit.exe");
}

BOOL CUtils::IsAutla()
{
	return !stricmp(m_szApplicationName, "Autla.exe");
}

BOOL CUtils::IsShuriken()
{
	return !stricmp(m_szApplicationName, "JsvMail.exe");
}

BOOL CUtils::IsEdLeaf()
{
	return !stricmp(m_szApplicationName, "edleaf.exe");
}

BOOL CUtils::IsJmEditor()
{
	return !stricmp(m_szApplicationName, "JmEdit.exe")
		|| !stricmp(m_szApplicationName, "JmEdit2.exe");
}

BOOL CUtils::IsDana()
{
	return !stricmp(m_szApplicationName, "Dana.exe");
}

BOOL CUtils::IsIPMessenger()
{
	return !stricmp(m_szApplicationName, "ipmsg.exe");
}

BOOL CUtils::IsezHTML()
{
	return !stricmp(m_szApplicationName, "ezhtml.exe");
}

BOOL CUtils::IsTcsh()
{
	return !stricmp(m_szApplicationName, "tcsh.exe");
}

BOOL CUtils::IsZsh()
{
	return !stricmp(m_szApplicationName, "zsh.exe");
}

BOOL CUtils::IsPdksh()
{
	return !stricmp(m_szApplicationName, "pdksh.exe");
}

BOOL CUtils::IsFirefox()
{
	return !stricmp(m_szApplicationName, "firefox.exe");
}

BOOL CUtils::IsPHPEditor()
{
	return !stricmp(m_szApplicationName, "php_editor.exe");
}

BOOL CUtils::IsTeraPad()
{
	return !stricmp(m_szApplicationName, "TeraPad.exe");
}

BOOL CUtils::IsLispWorksPersonalEdition()
{
	CString szLispWorks("lispworks-personal-");
	return !strnicmp(m_szApplicationName, szLispWorks, szLispWorks.GetLength());

//	return !stricmp(m_szApplicationName, "lispworks-personal-4300.exe");
}

BOOL CUtils::IsBorlandCppBuilder()
{
	return !stricmp(m_szApplicationName, "bcb.exe");
}

BOOL CUtils::Run(CString szCommandLine, BOOL isWait)
{
	STARTUPINFO si;
	ZeroMemory(&si, sizeof(si));
	si.cb = sizeof(si);

	PROCESS_INFORMATION pi;
	ZeroMemory(&pi, sizeof(pi));

	BOOL rc = CreateProcess(NULL, szCommandLine.GetBuffer(szCommandLine.GetLength() + 1), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
	if (rc) {
		if (isWait) {
			WaitForSingleObject( pi.hProcess, INFINITE );
		}

		CloseHandle(pi.hThread);
		CloseHandle(pi.hProcess);
	}

	return rc;
}

BOOL CUtils::IsJavaW()
{
	return !stricmp(m_szApplicationName, "javaw.exe");
}

BOOL CUtils::IsMSDN()
{
	return !stricmp(m_szApplicationName, "hh.exe");
}

BOOL CUtils::IsVisualSlickEdit()
{
	return !stricmp(m_szApplicationName, "vs.exe");
}

void CUtils::PrintWindowInfo(WINDOWINFO *pwi)
{
	Log("windowinfo.cbSize: %d", pwi->cbSize);
	Log("windowinfo.rcWindow.top: %d", pwi->rcWindow.top);
	Log("windowinfo.rcWindow.bottom: %d", pwi->rcWindow.bottom);
	Log("windowinfo.rcWindow.left: %d", pwi->rcWindow.left);
	Log("windowinfo.rcWindow.right: %d", pwi->rcWindow.right);
	Log("windowinfo.rcClient.top: %d", pwi->rcClient.top);
	Log("windowinfo.rcClient.bottom: %d", pwi->rcClient.bottom);
	Log("windowinfo.rcClient.left: %d", pwi->rcClient.left);
	Log("windowinfo.rcClient.right: %d", pwi->rcClient.right);
	Log("windowinfo.dwStyle: %d", pwi->dwStyle);
	Log("windowinfo.dwExStyle: %d", pwi->dwExStyle);
	Log("windowinfo.dwWindowStatus: %d", pwi->dwWindowStatus);
	Log("windowinfo.cxWindowBorders: %d", pwi->cxWindowBorders);
	Log("windowinfo.cyWindowBorders: %d", pwi->cyWindowBorders);
	Log("windowinfo.atomWindowType: %d", pwi->atomWindowType);
	Log("windowinfo.wCreatorVersion: %d", pwi->wCreatorVersion);
}

BOOL CUtils::IsOpenJane()
{
	return !stricmp(m_szApplicationName, "Jane2ch.exe");
}

BOOL CUtils::UpdateKeyboardState(BYTE bVk, BYTE bState)
{
	BYTE ks[256] = {'\0'};
	BOOL rc = FALSE;

	if ((rc = GetKeyboardState(ks)) != FALSE) {
		ks[bVk] = bState;
		rc = SetKeyboardState(ks);
	}
	return rc;
}

BOOL CUtils::IsThunderbird()
{
	return !stricmp(m_szApplicationName, "thunderbird.exe");
}

(C) 2001-2005 oishi@cam.hi-ho.ne.jp