OK... I have a program that runs and sends output to a game window. It is a magic roleplaying game online. I am using getpixel to look for when my energy is down and then I send a double click to my healing potions. All is well and working.

This program runs as AC2.exe in the process list however it runs in an infinite loop which is fine and what I want. What I want though is if a hotkey is pressed on the keyboard while playing the game it will completely terminate the program, and when another hotkey is pressed it will turn on the program.

So what I am figuring is I will code a seperate program which runs invisible and listens for hotkeys. When for example key "c" is presssed it will taskkill AC2.exe which is my autocure program, and then when for example "v" is pressed. It will then run AC2.exe.

To be simple. I will have my users keep both programs in the same folder, in which the program they run is simply the on\off program for AC2.exe.

What is the simplest way to do this?

psudeo

press a key, AC2.exe terminates, press another key AC2.exe gets executed.
I wish this program to be visible so this will be using some basic windows programming.

Code examples would be greatly appreciated I have been searching online allot and gathering bits and peices, but nothing clear and solid so I figured I would just outright ask for someones help to produce actual code, or GIVE me the wheel so to speak. In which I will learn allot from in due time.

Thank you,

Cody Oebel

RegisterHotKey(hWnd,1,MOD_ALT,0x53);
				 if(WM_HOTKEY == 1)
				 {
					 MessageBox::Show("fdg");
				 }

Put the Registerhotkey in the part that initialized the program.. for example:

private: System::Void Form1_Load(System::Object^  sender, System::EventArgs^  e) {
RegisterHotKey(hWnd,1,MOD_ALT,0x53);
}

Then call the If hotkey wherever its supposed to check..

or:
http://windowscoding.com/blogs/blake/archive/2009/05/19/how-to-register-a-keyboard-shortcut-hot-key-in-a-net-windows-forms-application.aspx

I tried that in my program but it is not working properly. Maybe I am not doing this correctly, but here is my code to give you an idea of what I am doing.

Basically I have windows.h for windows program and functions I am using.
A main, and a handle initialized to the games window to begin sending messages to the games window. I am sure I am using this registerkey function incorrectly.
I tried setting the hotkey. or if I could get the message que of my games window, and whenever Shift+Space is pressed it would process whatever I wanted.

My hotkey here of choice is Shift+Space. So what am I doing wrong here? When I am playing the game and press shift+alt the code to run a message box does not appear letting me know I am not using this properly. Below is my code with. I took out a bunch of functions as to not have such a large code snippet.

#include <windows.h>
//#include "DC.h"
//DC dc;
HWND hwndDC = FindWindow(0, "NOCTOROUS MAGICUS");
HDC hdcDC = GetDC(hwndDC);
COLORREF cr;
COLORREF cr2;
COLORREF cr3;
COLORREF cr4;
static COLORREF crGetHit = RGB(252,252,84);
static COLORREF crGreaterHeal = RGB(172,172,172);
static COLORREF crMassScroll = RGB(236,124,124);
static COLORREF NeedHeal = RGB(0,0,0);
static COLORREF crChatPoisoned = RGB(0,252,0);
// Get color for CR chat diseased when possible
static COLORREF crPoisoned = RGB(184,240,148);
static COLORREF crDiseased = RGB(200,176,136);
static COLORREF crMinorCure = RGB(240,112,0);
static COLORREF Cure = RGB(208,192,156);
static COLORREF RedDot = RGB(255,0,0);
static int my = 175;
int CurePot();
int MinorCurePot();
int MassHeal();
int CheckChatBox();
int CheckBody();
int GreaterHeal();
int CheckForHit();
int TurnOffReuse();
int HotKey();
//RegisterHotKey(hwndDC,1,MOD_SHIFT,0x20);

int main()
{   
   
    SendMessage(hwndDC,WM_KEYDOWN,VK_ESCAPE,0);
    SendMessage(hwndDC,WM_KEYUP,VK_ESCAPE,0);
    TurnOffReuse();
   
    MessageBox(hwndDC,"AUTO CURE\\HEALER note: This runs invisible","v1.2 by: Cody Oebel ",MB_OK|MB_ICONINFORMATION);
    for(;;)
    {

   
    HotKey();
    CheckChatBox();
    CheckChatBox();
    CheckBody();
    CheckForHit();
    // MassHeal();      //<---- This need not be commented out if used for mage
};   
end:
    return 0;
    
};

int CurePot()
{
      for(int bpy = 150; bpy != 400; bpy++)
                  { 
                     for(int bpx = 350; bpx != 480; bpx++)
                     {
                             cr = GetPixel(hdcDC,bpx,bpy); 
                             if(cr == Cure)
                              {
                                SendMessage(hwndDC,WM_LBUTTONDBLCLK,0,MAKELPARAM(bpx,bpy));
                                SendMessage(hwndDC,WM_LBUTTONDOWN,0,MAKELPARAM(bpx,bpy));
                                SendMessage(hwndDC,WM_LBUTTONUP,0,MAKELPARAM(bpx,bpy));
                                Sleep(800);
                                GreaterHeal();
                                return 0;
                              };
                              
                         //SetPixel(hdcDC,bpx,bpy,RedDot);    
                     };
                     
                                                         
                  };
return 0;
};



int MinorCurePot()
{
      for(int bpy = 150; bpy != 400; bpy++)
                  { 
                     for(int bpx = 350; bpx != 480; bpx++)
                     {
                             cr = GetPixel(hdcDC,bpx,bpy); 
                             if(cr == crMinorCure)
                              {
                                SendMessage(hwndDC,WM_LBUTTONDBLCLK,0,MAKELPARAM(bpx,bpy));
                                SendMessage(hwndDC,WM_LBUTTONDOWN,0,MAKELPARAM(bpx,bpy));
                                SendMessage(hwndDC,WM_LBUTTONUP,0,MAKELPARAM(bpx,bpy));
                                GreaterHeal();
                                return 0;
                              };
                              
                         //SetPixel(hdcDC,bpx,bpy,RedDot);    
                     };
                                                        
                  };
return 0;
};









/*  //OBSOLETE CODE UNLESS USING FOR MAGE SCROLL SEARCH\MASS HEAL
int MassHeal()
{
    
    cr4 = GetPixel(hdcDC,347,100);
if(cr4 == NeedHeal)
{ 
    for(int bpmhy = 150; bpmhy != 400; bpmhy++)
                                  { 
                      
                        for(int bpmhx = 350; bpmhx != 480; bpmhx++)
                         {
                             cr2 = GetPixel(hdcDC,bpmhx,bpmhy); 
                             if(cr2 == RGB(236,124,124)) //Mass Scroll Color
                              { 
                                  SendMessage(hwndDC,WM_LBUTTONDBLCLK,0,MAKELPARAM(bpmhx,bpmhy));
                              };
                              
                             //SetPixel(hdcDC,bpx,bpy,RedDot);                     
                     
                         }; 
                                
                                  };
};   
 
    
    return 0;
    
};

*/

int GreaterHeal()
{
    
cr4 = GetPixel(hdcDC,347,80);  //Check energy bar for energy level
if(cr4 == NeedHeal)
{ 
    for(int bpmhy = 150; bpmhy != 400; bpmhy++)
                                  { 
                      
                        for(int bpmhx = 350; bpmhx != 480; bpmhx++)
                         {
                             cr2 = GetPixel(hdcDC,bpmhx,bpmhy); 
                             if(cr2 == crGreaterHeal) //Greater Heal potion color
                              { 
                                  SendMessage(hwndDC,WM_LBUTTONDBLCLK,0,MAKELPARAM(bpmhx,bpmhy));
                                  Sleep(600);
                                  SendMessage(hwndDC,WM_LBUTTONDBLCLK,0,MAKELPARAM(bpmhx,bpmhy));
                                  Sleep(400);
                                  SendMessage(hwndDC,WM_LBUTTONDBLCLK,0,MAKELPARAM(bpmhx,bpmhy));
                                  Sleep(300);
                                  SendMessage(hwndDC,WM_LBUTTONDOWN,0,MAKELPARAM(bpmhx,bpmhy));
                                  SendMessage(hwndDC,WM_LBUTTONUP,0,MAKELPARAM(bpmhx,bpmhy));
                                  return 0;
                              };
                              
                             //SetPixel(hdcDC,bpx,bpy,RedDot);                     
                     
                         }; 
                                
                                  };
};   
 
    
    return 0;
    
};

int CheckForHit()
{
    //////////Checks for body flash
                for(int mx = 170; mx <= 180; mx++)
                 {
           cr = GetPixel(hdcDC,mx,my);
           if(cr == crGetHit)
           {
                 //Use Minor Cure Potion
                 
                 
                 GreaterHeal();
                
                 return 0;
                
           };
           
           //SetPixel(hdcDC,mx,my,RedDot);
};
                  
    
    
    
    return 0;
};





int CheckBody()
{
    //////////Checks for body flash
                for(int mx = 170; mx <= 180; mx++)
                 {
           cr = GetPixel(hdcDC,mx,my);
           if(cr == crPoisoned || cr == crDiseased) //For ripper avatar cannot add cdDiseased or runs in loop
           {
                 //Use Minor Cure Potion
                 MinorCurePot();
                 CurePot();
                 GreaterHeal();

                 return 0;
                
           };
           
           //SetPixel(hdcDC,mx,my,RedDot);
                  };
                  
    
    
    
    return 0;
};

int CheckChatBox()
{
    //Check chat box for disease message
    for(int y = 350; y <= 470; y++)
               {
                       for(int x = 10; x<= 150; x++)
                       {
                               cr3 = GetPixel(hdcDC,x,y);
                               if(cr3 == crChatPoisoned)
                               {
                                MinorCurePot();
                                CurePot();
                                GreaterHeal();
                                
                                return 0;
                                };
                                if(cr3 == crDiseased)
                                {
                                CurePot();
                                GreaterHeal();
                                
                                return 0;
                               };
                               
                       //SetPixel(hdcDC,x,y,RedDot);
                       };
                
                };
    return 0;
};

int TurnOffReuse()
{
    
    int my = 150;
    int mx = 360;
    Sleep(500);
    SendMessage(hwndDC,WM_KEYDOWN,VK_ESCAPE,0);
    SendMessage(hwndDC,WM_KEYUP,VK_ESCAPE,0);
    Sleep(500);
    SendMessage(hwndDC,WM_LBUTTONDOWN,0,MAKELPARAM(mx,my));
    SendMessage(hwndDC,WM_LBUTTONUP,0,MAKELPARAM(mx,my));  
    Sleep(1000);      
    PostMessage(hwndDC,WM_KEYDOWN,VK_ESCAPE,0);
    PostMessage(hwndDC,WM_KEYUP,VK_ESCAPE,0);
    
return 0;
};

int HotKey()
{
     if(WM_HOTKEY==1)
    {
                     MessageBox(hwndDC,"Program is terminated","v1.2 by: MANEGARD",MB_OK|MB_ICONINFORMATION);
                    //goto OffLoop;
    }
};

In Simple this could be sized down to the following.

windows.h
handler set to game window using findwindow()
int main()
{

return 0;

};


So where am I going wrong ? I made a hotkey function to be called etc.. but its not working properly. I am running the IF check in my forever loop.

If I can get my program to read keys pressed from my games window and when Shift+Space is pressed it processes whatever I want.

Oh damn that was hella hard to read!! Next time put it in code tags so I wont hurt my eyes..

.Net Version that I usually Use..:

RegisterHotKey(NULL,1,0x4000,0x7A);  //0x7A is 'F11'         <---- 0x4000 is MOD_NOREPEAT

MSG msg = {0};
  while (GetMessage(&msg, NULL, 0, 0) != 0)           <--- Notice the while...
   {
	if (msg.message == WM_HOTKEY)
	{
	 //MessageBox::Show("WM_HOTKEY received");
	   ::SendMessage(Simba, WM_KEYDOWN, VK_F12,0);
	}
   }

For what u need..:

#include "stdafx.h"

int _cdecl _tmain (
    int argc, 
    TCHAR *argv[])
{           
    if (RegisterHotKey(
        NULL,
        1,
        MOD_ALT | MOD_NOREPEAT,
        0x42))  //0x42 is 'b'
    {
        _tprintf(_T("Hotkey 'ALT+b' registered, using MOD_NOREPEAT flag\n"));
    }
 
    MSG msg = {0};
    while (GetMessage(&msg, NULL, 0, 0) != 0)
    {
        if (msg.message == WM_HOTKEY)
        {
            _tprintf(_T("WM_HOTKEY received\n"));            
        }
    } 
 
    return 0;
}

http://msdn.microsoft.com/en-us/library/ms646309.aspx

Now I am having another problem.

On windows vista, a user with this OS reports nothing is happening what so ever.
My program is not working at all for him, but on another users XP machine it is working just like it should.

Also on my cousins win7 64bit OS my program is not working even if set for windows 32 bit compatability. Is there a header I can include on my 32bit xp development platform that can solve this issue?

It appears that SendMessage\PostMessage is not working on the 32bit Vista machine.

I can understand the win7 not working and it will maybe take some major changes in code\ , but the 32bit vista machine has me stumped.

MOD_NOREPEAT
0x4000

Changes the hotkey behavior so that the keyboard auto-repeat does not yield multiple hotkey notifications.

    Windows Vista and Windows XP/2000:  This flag is not supported.

Straight from microsoft's site..

As for compiling it for all platforms, I've had this problem in vs 2010.. Try using vs 2008 and select Win32 at the top.

MOD_NOREPEAT
0x4000

Changes the hotkey behavior so that the keyboard auto-repeat does not yield multiple hotkey notifications.

    Windows Vista and Windows XP/2000:  This flag is not supported.

Straight from microsoft's site..

As for compiling it for all platforms, I've had this problem in vs 2010.. Try using vs 2008 and select Win32 at the top.

I appreciate all the help Triumph

Ok I programmed my application to post a message box if the game window is ever terminated. So right now it's looking like send message is not the issue, but my

HWND hwndDC = FindWindow() is now the issue.
It's not getting the correct handler.. let me look into this, but any help would be great. This is my find window code.

It seems as though the findwindow is not working properly.

HWND hwndDC = FindWindow(0, "GAMES WINDOWS TITLE");
    if(hwndDC == 0)
    {
           MessageBox(hwndDC,"GAME Window Is Not Open Program is Closing","v1.2 by: CODY OEBEL", MB_OK|MB_ICONINFORMATION); 
           return 0;  
    };

when the games window is closed I get no message box. This is probably why the game window never gets any messsages I send to it. (googling now, but if u have an answer that would be great too).

try this:

if(hwnDC != 0)   //<---- Check to see if it is open.
{
   MessageBox(hwnDC, "The game window is still open", MB_OK|MB_ICONIFORMATION);
}

as for checking to see if its closed, u might have to do a check for the process. If the process isnt running, the window is closed. Why? Because sometimes it takes time for the system to realize that a program has stopped.

You can try doing Sleep(10000) and then check to see if its open and see if that helps.. But I dont think Sleeping to check is a good idea because it can always take more time or less time.

try this:

if(hwnDC != 0)   //<---- Check to see if it is open.
{
   MessageBox(hwnDC, "The game window is still open", MB_OK|MB_ICONIFORMATION);
}

as for checking to see if its closed, u might have to do a check for the process. If the process isnt running, the window is closed. Why? Because sometimes it takes time for the system to realize that a program has stopped.

You can try doing Sleep(10000) and then check to see if its open and see if that helps.. But I dont think Sleeping to check is a good idea because it can always take more time or less time.

The problem seems that the FindWindow() is not being set to the games window.

In my forever loop. I run the constant check if the game window is open or not open, and on my xp box, and my two xp users. When the games window is closed my program then displays the message box saying the game window is now closed.

It works flawless on XP.
However it is not working one bit on vista.

The SendMessage\PostMessage are not working... for example.. if I send a double click to a potion to heal up on the xp machine.. the character gets healed, but on the vista box this never happens.
So I dont think its a problem with send\post message function, but that the HWND is not being set correctly, or at all. FindWindow() I am assuming is not finding the games window. Seems to be an issue with FindWindow.

Ok I put the following code below in my forever running for loop to catch messages as well as process other functions. The problem is the very bottom message box just under the jump to next: that message box never gets displayed unless I hit the hotkey. Which tells me my loop is hanging during this catch, and is not looping as I want it to unless I press the hotkey. Why is this? The hwndDC is the handler to the game I am making the program send messages to. So when I am playing the game and press the hotkey I do get the message box saying the hotkey was pressed, but no further code runs. What am I doing wrong or dont know that is causing this hang within this while get message loop? Ive altered the code.. took out the while loops since im running this within a forloop anyways but it made no difference it hangs.

Program main(){
for(;;)
{
      MSG msg = {0};    
              while(GetMessage(&msg, NULL, 0, 0) != 0)
             { 
              if(msg.message == WM_HOTKEY) 
                         {           
                                    MessageBox(hwndDC,"HOT KEY WAS PRESSED","v1.2 by: DRAXZ aka MANEGARD", MB_OK|MB_ICONINFORMATION);                         
                                    goto next;
                         };
              if(msg.message != WM_HOTKEY)                 
                  {
                            goto next;
                  };
             };
    next:

///The below message box never gets ran, or any code I have below it within the for loop.
//Unless I press the hotkey in which the message box below will then pop. Otherwise it
// nor any code below it gets ran. Letting me know some sort of hang is occuring within the
// while loop, or the GetMessage function.
  MessageBox(hwndDC,"AFTER MESSAGE RECEIVED FOR HOTKEY PRESSED","v1.2 by: DRAXZ aka MANEGARD", MB_OK|MB_ICONINFORMATION);

}; // End of forever for loop

Woa found PeekMessage and it solved my problem, GetMessage() is a loop and doesnt return until it gets something. IN my case I didnt need this as it hung up my code.

Self solved ;) woot!

But what if I want to register multiple hotkeys how to I handle which is which ?

Instead of

if(msg.message == WM_HOTKEY) 

Is there a way to handle the specific hotkey pressed?

enum {F9_KEYID = 1, F10_KEYID = 2} ;
RegisterHotKey(0, F9_KEYID, MOD_NOREPEAT, VK_F9);   //Please note that for Windows-7/Vista, MOD_NOREPEAT doesnt exist.. use 0x4000 instead
RegisterHotKey(0, F10_KEYID, MOD_NOREPEAT, VK_F10); //I used 0x79 for F10 instead of VK_F10.. they both work but I feel better using the hex

PeekMessage(&msg, 0, 0, 0, 0x0001);
TranslateMessage(&msg);
switch(msg.message)
  {
	case WM_HOTKEY:
	if(msg.wParam == F9_KEYID)
	{
		MessageBox::Show("F9 Pressed");
        }
	else if(msg.wParam == F10_KEYID)
	{
		MessageBox::Show("F10 Pressed");
	}
  }

I had the same problem with the loop aswell and found the peek message aswell... unfortunately no where on google could tell me how to register multiple messages in the same thread.. The solution above though worked quite well!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.