// This file is from Uwe Gottwald
//-------------------------------

#include <windows.h>

/*	With this little function one can send keystrokes to the window that stays on the top.
	In my application I've searched a window (program) and sent them the keys to get a macro
	started. This was the only way to get a macro started from outside the program.
	Handle of the window is known.
	Snippet:

			if (IsIconic(hWindow)!=0 )
				ShowWindow(hWindow,SW_RESTORE);
			else
			    SetForegroundWindow(hWindow);

			// To get a macro run one have to press CTRL+8 in custom program
			DoKeyPress("CTRL+8#",100);

			Sleep(200);

			// the macro to open was given trough commandline and
			// will be given to the application via clipboard.
			if (OpenClipboard(hwnd)!=0)
			{
				EmptyClipboard();
				hData = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE,lstrlen(cl)+1);
				pData = GlobalLock(hData);
				strcpy((LPSTR)pData, cl);
				GlobalUnlock(hData);
				SetClipboardData(CF_TEXT, hData);
				CloseClipboard();
			};
			// Paste given commandline to active control
			DoKeyPress("CTRL+V#",100);
			// Press Enter to start execution of the macro, cause "default button" is OK
			DoKeyPress("RETURN#",100);
	:snippet end.
	Worked better than other stuff like:
			SendMessage(hWindow,WM_KEYDOWN,VK_8,0);
			SendMessage(hWindow,WM_KEYUP,VK_8,0);
*/

// Key String must end with #, see above.
int DoKeyPress(TCHAR* szKeys, int nDelay)
{
	TCHAR szError[100] = {0};
	TCHAR szTmp[100] = {0};
	BOOL bWithAlt = FALSE;
	BOOL bWithShift = FALSE;
	BOOL bWithCtrl = FALSE;

	int i = 0;
	for (int n=0; szKeys[n]; n++)
	{
		szTmp[i++] = szKeys[n];

		if (szKeys[n] == '+')
		{
			szTmp[i-1] = 0;
			i = 0;

			if (stricmp(szTmp, "ALT") == 0)
				bWithAlt = TRUE;
			else if (stricmp(szTmp, "SHIFT") == 0)
				bWithShift = TRUE;
			else if (stricmp(szTmp, "CTRL") == 0)
				bWithCtrl = TRUE;
			else
			    {
				// wsprintf(szError, "<%s> muss sein ALT, SHIFT oder CTRL", szTmp);
				wsprintf(szError, "<%s> must be ALT, SHIFT or CTRL", szTmp);
				//MessageBox(NULL, szTmp, "Fehler in DoKeyPress()", MB_OK|MB_ICONERROR);
				MessageBox(NULL, szTmp, "Error in DoKeyPress()", MB_OK|MB_ICONERROR);
				return -1;
			}
		}
		else if (szKeys[n] == '#')
		{
			szTmp[i-1] = 0;
			i = 0;

			int nWert = -1;

			/* VK_0 thru VK_9 are the same as ASCII '0' thru '9' (0x30 - 0x39) */
			/* VK_A thru VK_Z are the same as ASCII 'A' thru 'Z' (0x41 - 0x5A) */
			if (stricmp(szTmp, "A") == 0)
				nWert = 'A';
			else if (stricmp(szTmp, "B") == 0)
				nWert = 'B';
			else if (stricmp(szTmp, "C") == 0)
				nWert = 'C';
			else if (stricmp(szTmp, "D") == 0)
				nWert = 'D';
			else if (stricmp(szTmp, "E") == 0)
				nWert = 'E';
			else if (stricmp(szTmp, "F") == 0)
				nWert = 'F';
			else if (stricmp(szTmp, "G") == 0)
				nWert = 'G';
			else if (stricmp(szTmp, "H") == 0)
				nWert = 'H';
			else if (stricmp(szTmp, "I") == 0)
				nWert = 'I';
			else if (stricmp(szTmp, "J") == 0)
				nWert = 'J';
			else if (stricmp(szTmp, "K") == 0)
				nWert = 'K';
			else if (stricmp(szTmp, "L") == 0)
				nWert = 'L';
			else if (stricmp(szTmp, "M") == 0)
				nWert = 'M';
			else if (stricmp(szTmp, "N") == 0)
				nWert = 'N';
			else if (stricmp(szTmp, "O") == 0)
				nWert = 'O';
			else if (stricmp(szTmp, "P") == 0)
				nWert = 'P';
			else if (stricmp(szTmp, "Q") == 0)
				nWert = 'Q';
			else if (stricmp(szTmp, "R") == 0)
				nWert = 'R';
			else if (stricmp(szTmp, "S") == 0)
				nWert = 'S';
			else if (stricmp(szTmp, "T") == 0)
				nWert = 'T';
			else if (stricmp(szTmp, "U") == 0)
				nWert = 'U';
			else if (stricmp(szTmp, "V") == 0)
				nWert = 'V';
			else if (stricmp(szTmp, "W") == 0)
				nWert = 'W';
			else if (stricmp(szTmp, "X") == 0)
				nWert = 'X';
			else if (stricmp(szTmp, "Y") == 0)
				nWert = 'Y';
			else if (stricmp(szTmp, "Z") == 0)
				nWert = 'Z';

			else if (stricmp(szTmp, "0") == 0)
				nWert = VK_0;
			else if (stricmp(szTmp, "1") == 0)
				nWert = VK_1;
			else if (stricmp(szTmp, "2") == 0)
				nWert = VK_2;
			else if (stricmp(szTmp, "3") == 0)
				nWert = VK_3;
			else if (stricmp(szTmp, "4") == 0)
				nWert = VK_4;
			else if (stricmp(szTmp, "5") == 0)
				nWert = VK_5;
			else if (stricmp(szTmp, "6") == 0)
				nWert = VK_6;
			else if (stricmp(szTmp, "7") == 0)
				nWert = VK_7;
			else if (stricmp(szTmp, "8") == 0)
				nWert = VK_8;
			else if (stricmp(szTmp, "9") == 0)
				nWert = VK_9;

			else if (stricmp(szTmp, "F1") == 0)
				nWert = VK_F1;
			else if (stricmp(szTmp, "F2") == 0)
				nWert = VK_F2;
			else if (stricmp(szTmp, "F3") == 0)
				nWert = VK_F3;
			else if (stricmp(szTmp, "F4") == 0)
				nWert = VK_F4;
			else if (stricmp(szTmp, "F5") == 0)
				nWert = VK_F5;
			else if (stricmp(szTmp, "F6") == 0)
				nWert = VK_F6;
			else if (stricmp(szTmp, "F7") == 0)
				nWert = VK_F7;
			else if (stricmp(szTmp, "F8") == 0)
				nWert = VK_F8;
			else if (stricmp(szTmp, "F9") == 0)
				nWert = VK_F9;
			else if (stricmp(szTmp, "F10") == 0)
				nWert = VK_F10;
			else if (stricmp(szTmp, "F11") == 0)
				nWert = VK_F11;
			else if (stricmp(szTmp, "F12") == 0)
				nWert = VK_F12;

			else if (stricmp(szTmp, "ESC") == 0)
				nWert = VK_ESCAPE;
			else if (stricmp(szTmp, "TAB") == 0)
				nWert = VK_TAB;
			else if (stricmp(szTmp, "PGUP") == 0)
				nWert = VK_PRIOR;
			else if (stricmp(szTmp, "PGDN") == 0)
				nWert = VK_NEXT;
			else if (stricmp(szTmp, "POS1") == 0)
				nWert = VK_HOME;
			else if (stricmp(szTmp, "END") == 0)
				nWert = VK_END;
			else if (stricmp(szTmp, "INS") == 0)
				nWert = VK_INSERT;
			else if (stricmp(szTmp, "DEL") == 0)
				nWert = VK_DELETE;
			else if (stricmp(szTmp, "RETURN") == 0)
				nWert = VK_RETURN;

			else if (stricmp(szTmp, "LEFT") == 0)
				nWert = VK_LEFT;
			else if (stricmp(szTmp, "RIGHT") == 0)
				nWert = VK_RIGHT;
			else if (stricmp(szTmp, "UP") == 0)
				nWert = VK_UP;
			else if (stricmp(szTmp, "DOWN") == 0)
				nWert = VK_DOWN;

			else
			    {
				wsprintf(szError, "Unknown or not implementet VK_xxx Code <%s>", szTmp);

				MessageBox(NULL, szTmp, "Error in DoKeyPress()", MB_OK|MB_ICONERROR);
				return -2;
			}

			// send event to process
			if (nWert > 0)
			{
				if (bWithAlt)
					keybd_event(VK_MENU, 0, 0, 0);
				if (bWithShift)
					keybd_event(VK_SHIFT, 0, 0, 0);
				if (bWithCtrl)
					keybd_event(VK_CONTROL, 0, 0, 0);

				keybd_event(nWert ,0,0,0);
				keybd_event(nWert ,0,KEYEVENTF_KEYUP,0);

				if (bWithAlt)
					keybd_event(VK_MENU, 0, KEYEVENTF_KEYUP, 0);
				if (bWithShift)
					keybd_event(VK_SHIFT, 0, KEYEVENTF_KEYUP, 0);
				if (bWithCtrl)
					keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);
			}

			Sleep(nDelay);
			bWithAlt = FALSE;
			bWithShift = FALSE;
			bWithCtrl = FALSE;
			i = 0;
		}
	}

	return 0;
};

