GIDForums  

Go Back   GIDForums > Computer Programming Forums > CPP / C++ Forum
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

 
 
Thread Tools Search this Thread Rate Thread
  #1  
Old 05-Jul-2005, 20:01
blank blank is offline
Junior Member
 
Join Date: May 2005
Posts: 39
blank is on a distinguished road

SendMessage (WinAPI)


Hello guys, I've been working on a program that will send text to a game, like a chatbot. The game is JO (Jedi Outcast) and it is Quake 3 Engine based. All commands are logged and can be issued through the console, which can be entered by pressing SHIFT and ~. I already have the console's name, it is 'jk2mp winconsole', thanks to some VB source code for a previous program of this sort. Here is the snippet of source I think is what finds the window and sends the text:

Code:
Dim jkmpwinconsole, editx As Integer jkmpwinconsole = FindWindow("jk2mp winconsole", vbNullString) editx = FindWindowEx(jkmpwinconsole, 0, "edit", vbNullString) editx = FindWindowEx(jkmpwinconsole, editx, "edit", vbNullString) ... SendMessageBystring(editx, WM_SETTEXT, 0, "") SendMessageLong(editx, WM_CHAR, 13, 0)

So the test function I've come up with in C++ is the following:

CPP / C++ / C Code:
#include <windows.h>
#include <stdio.h>
#include <iostream>

using namespace std;

#pragma comment(lib, "User32.lib")

int Say()
{
	HWND jkmpwinconsole, editx;
	char buffer[MAX_PATH];

	FindWindow("jk2mp winconsole", 0); 
	FindWindowEx(jkmpwinconsole, 0, "edit", NULL); 
        editx = FindWindowEx(jkmpwinconsole, editx, "edit", NULL);

	char *message = "hello";
	sprintf(buffer, "say %s", message);
	SendMessage(editx, WM_SETTEXT, 0, (LPARAM)buffer);
        SendMessage(editx, WM_CHAR, 13, 0);
	return 0;
}

int main(void)
{
	Say();
	system("PAUSE");
	return 0;
}

Notice I put say before the message in the buffer sent, that is the command to 'say' something in the game, anything after that command is shown to all players. Instead of \r after it to simulate the 'ENTER' key, I used the SendMessage with WM_CHAR wparam 13, is this correct?

When the game is running and I run this program, nothing shows up in the game. So I start up Spy++ and I go to the edit control under jk2mp winconsole, and it shows up there. I think the command is being typed in the console but not submitted, so the SendMessage WM_CHAR wparam 13 is possibly not working, maybe because in VB it was SendMessageByLong. After looking around the VB source code, I found declarations for the windows messages, could these possibly be customized for the game? (I might be wrong) I've heard that for VB you have to declare these things. Here they are:

Code:
Public Const CB_GETCOUNT As Short = &H146s Public Const CB_GETLBTEXT As Short = &H148s Public Const CB_SETCURSEL As Short = &H14Es Public Const GW_HWNDFIRST As Short = 0 Public Const GW_HWNDNEXT As Short = 2 Public Const GW_CHILD As Short = 5 Public Const LB_GETCOUNT As Short = &H18Bs Public Const LB_GETTEXT As Short = &H189s Public Const LB_SETCURSEL As Short = &H186s Public Const SW_HIDE As Short = 0 Public Const SW_MAXIMIZE As Short = 3 Public Const SW_MINIMIZE As Short = 6 Public Const SW_NORMAL As Short = 1 Public Const SW_SHOW As Short = 5 Public Const VK_SPACE As Short = &H20s Public Const WM_CHAR As Short = &H102s Public Const WM_CLOSE As Short = &H10s Public Const WM_COMMAND As Short = &H111s Public Const WM_GETTEXT As Short = &HDs Public Const WM_GETTEXTLENGTH As Short = &HEs Public Const WM_KEYDOWN As Short = &H100s Public Const WM_KEYUP As Short = &H101s Public Const WM_LBUTTONDBLCLK As Short = &H203s Public Const WM_LBUTTONDOWN As Short = &H201s Public Const WM_LBUTTONUP As Short = &H202s Public Const WM_MOVE As Short = &HF012s Public Const WM_RBUTTONDOWN As Short = &H204s Public Const WM_RBUTTONUP As Short = &H205s Public Const WM_SETTEXT As Short = &HCs Public Const WM_SYSCOMMAND As Short = &H112s

If they are, I think I would have to declare WM_SETTEXT is equal to up there.

I would like to know what's going on here, I've tried all kinds of error detection things and the FindWindow functions seem to be working, otherwise the text wouldn't end up in the edit control of jk2mp winconsole in Spy++, and yes, that's where they should be, since when someone else says something, it shows up there. It might be that mine isn't being entered correctly. Thanks guys, I hope someone can help.

EDIT: The compiler shows a warning about the conversion from LPSTR to LRESULT might lead to loss of data, but it doesn't seem that way in Spy++.
  #2  
Old 06-Jul-2005, 02:35
maprich maprich is offline
Member
 
Join Date: May 2005
Posts: 163
maprich has a spectacular aura aboutmaprich has a spectacular aura about
I think you have errors in your VB to C++ conversion.

You forgot assign the return value of FindWindow(..). Your VB version assign it to the jkmpwinconsole. Also the assignment to editx..
so:
CPP / C++ / C Code:
////clips
  HWND jkmpwinconsole, editx;
  char buffer[MAX_PATH];

  jkmpwinconsole = FindWindow("jk2mp winconsole", 0); 
  editx = FindWindowEx(jkmpwinconsole, 0, "edit", NULL); 
  editx = FindWindowEx(jkmpwinconsole, editx, "edit", NULL);
////etc.etc.
  #3  
Old 06-Jul-2005, 08:59
blank blank is offline
Junior Member
 
Join Date: May 2005
Posts: 39
blank is on a distinguished road
Oh, right, I'm sorry I usually have always done that it's just that after trying different things I guess I did that instead, sorry. This is my code so far, just ignore the MyColor header along witth the MyColor classes, they shouldn't be a problem, those are just to change the text color:

CPP / C++ / C Code:
#include <windows.h>
#include <stdio.h>
#include <iostream>
#include "MyColor.h"

using namespace std;

#pragma comment(lib, "User32.lib")

void SearchWindow(MyColor *font)
{
	font->ChangeTextColor(14);
	cout << "Searching ";
	font->ChangeTextColor(15);
	cout << "for window..." << endl;
}

void FoundWindow(MyColor *font)
{
	cout << "Window ";
	font->ChangeTextColor(14);
	cout << "found." << endl;
	font->ChangeTextColor(15);
}

void WindowNotFound(MyColor *font)
{
	cout << "Window ";
	font->ChangeTextColor(14);
	cout << "NOT ";
	font->ChangeTextColor(15);
	cout << "found." << endl;
}

int Say()
{
	MyColor text;
	HWND jkmpwinconsole, editx;
	char buffer[MAX_PATH];
	char *message = "hello";
	int i = 0;
	
	SearchWindow(&text);

	if (((jkmpwinconsole = FindWindow("jk2mp winconsole", 0)) == NULL) || \
		((editx = FindWindowEx(jkmpwinconsole, 0, "edit", NULL)) == NULL) || \
		((editx = FindWindowEx(jkmpwinconsole, editx, "edit", NULL)) == NULL))
	{
		WindowNotFound(&text);
		return -1;
	}
	else
		FoundWindow(&text);

	sprintf(buffer, "say %s", message);

	SendMessage(editx, WM_SETTEXT, 0, (LPARAM)buffer);
	SendMessage(editx, WM_CHAR, 13, 0);

	return 0;
}

int main(void)
{
	Say();
	system("PAUSE");
	return 0;
}
  #4  
Old 08-Jul-2005, 01:01
Jeremiah Jeremiah is offline
New Member
 
Join Date: Jul 2005
Posts: 11
Jeremiah is on a distinguished road
You are'nt going to use this program for anything evil are you? I hate to imagine what would happen if this program were to somehow end up in an infinite loop.
  #5  
Old 08-Jul-2005, 09:11
blank blank is offline
Junior Member
 
Join Date: May 2005
Posts: 39
blank is on a distinguished road
The game has a delay between messages, dont worry, even if I could it wouldn't let me send messages that fast, and no, nothing evil. Dont see how something could be evil with chatting, just to send commands to it so it can play music etc. but this is the first step and was really hoping you guys would help out
  #6  
Old 08-Jul-2005, 12:49
WaltP's Avatar
WaltP WaltP is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Midwest US
Posts: 3,234
WaltP is a name known to allWaltP is a name known to allWaltP is a name known to allWaltP is a name known to allWaltP is a name known to allWaltP is a name known to all
Quote:
Originally Posted by blank
CPP / C++ / C Code:
	if (((jkmpwinconsole = FindWindow("jk2mp winconsole", 0)) == NULL) || \
		((editx = FindWindowEx(jkmpwinconsole, 0, "edit", NULL)) == NULL) || \
		((editx = FindWindowEx(jkmpwinconsole, editx, "edit", NULL)) == NULL))
	{
		WindowNotFound(&text);
		return -1;
	}
	else
		FoundWindow(&text);

	sprintf(buffer, "say %s", message);

	SendMessage(editx, WM_SETTEXT, 0, (LPARAM)buffer);
	SendMessage(editx, WM_CHAR, 13, 0);

	return 0;
}

Since it is generally frouned upon to have 2 returns in a single function unless absolutely necessary, you might consider this as an alternative:
CPP / C++ / C Code:
    int rtn = 0;


    if (((jkmpwinconsole = FindWindow("jk2mp winconsole", 0)) == NULL) || \
        ((editx = FindWindowEx(jkmpwinconsole, 0, "edit", NULL)) == NULL) || \
        ((editx = FindWindowEx(jkmpwinconsole, editx, "edit", NULL)) == NULL))
    {
        WindowNotFound(&text);
        rtn = -1;
    }
    else
    {
        FoundWindow(&text);

        sprintf(buffer, "say %s", message);

        SendMessage(editx, WM_SETTEXT, 0, (LPARAM)buffer);
        SendMessage(editx, WM_CHAR, 13, 0);
    }
    return rtn;
}
__________________

Cow: You're a lawyer too?
Mooseblood (mosquito): Ma'am, I was already a bloodsucking parasite. All I needed was a briefcase!
  #7  
Old 08-Jul-2005, 23:45
blank blank is offline
Junior Member
 
Join Date: May 2005
Posts: 39
blank is on a distinguished road
Thanks, I've been staring at the source for a long time now and still dont see what could be wrong. Here's what I have so far, it should send a message to the game:

CPP / C++ / C Code:
#include <windows.h>
#include <stdio.h>
#include <iostream>
#include "MyColor.h"

using namespace std;

#pragma comment(lib, "User32.lib")

void Status(MyColor *font, int id)
{
	if (id == 1)
	{
		font->ChangeTextColor(14);
		cout << "Searching ";
		font->ChangeTextColor(15);
		cout << "for window..." << endl;
	}

	else if (id == 2)
	{
		cout << "Window ";
		font->ChangeTextColor(14);
		cout << "found." << endl;
		font->ChangeTextColor(15);
	}

	else if (id == 3)
	{
		cout << "Window ";
		font->ChangeTextColor(14);
		cout << "NOT ";
		font->ChangeTextColor(15);
		cout << "found." << endl;
	}
}

int Say()
{
	enum id {SEARCHING = 1, FOUND, NOTFOUND, SNDINGMSG};
	MyColor text;
	HWND jkmpwinconsole, editx;
	char buffer[MAX_PATH];
	char *message = "hello";
	int i = 0, rtn;
	
	Status(&text, SEARCHING);

	if (((jkmpwinconsole = FindWindow("jk2mp winconsole", 0)) == NULL) || \
		((editx = FindWindowEx(jkmpwinconsole, 0, "edit", NULL)) == NULL) || \
		((editx = FindWindowEx(jkmpwinconsole, editx, "edit", NULL)) == NULL))
	{
		Status(&text, NOTFOUND);
		rtn = -1;
	}
	else
		Status(&text, FOUND);

	sprintf(buffer, "say %s", message);
	
	Status(&text, SNDINGMSG);
	SendMessage(editx, WM_SETTEXT, 0, (LPARAM)buffer);
	SendMessage(editx, WM_CHAR, 13, 0);
	rtn = 0;

	return rtn;
}

int main()
{
	Say();
	system("PAUSE");
	return 0;
}
  #8  
Old 04-Sep-2006, 15:23
Blackdog Blackdog is offline
New Member
 
Join Date: Sep 2006
Posts: 1
Blackdog is on a distinguished road

Re: SendMessage (WinAPI)


When I tried
::SendMessage(fwhs.hWndFound, WM_SETTEXT, 0, (LPARAM)buffer);
on Notepad it changed the main Title bar from Untitled - Notepad, lol.

Looks like WM_SETTEXT will set the window title unless the window has no title like an edit box.
 

Recent GIDBlogFirst week of IA training by crystalattice

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
yet another winapi problem ubergeek CPP / C++ Forum 7 20-Mar-2005 19:42

Network Sites: GIDNetwork · GIDWebHosts · GIDSearch · Learning Journal by J de Silva, The

All times are GMT -6. The time now is 01:35.


vBulletin, Copyright © 2000 - 2008, Jelsoft Enterprises Ltd.