C++ SendMEssage Problem

02/10/2010 16:04 Σternαl.#1
Hey Comunity,
bin C++ Anfänger und hab da ein Problem.
Und zwar möchte ich Tastendrücke mithilfe meines Programms simulieren,
da hab ich mir gedacht, dass ich SendMessage benutze.
Mein Problem ist jetzt, dass ich nicht weiß, wo ich das Parameter
für die "zu drückende" Taste hinschreiben soll bzw. in welcher Form;
als Hex oder VK_KEY_? . Der Bot soll einfach nur ununterbrochen
"w" drücken, jedoch krig ich es einfach nicht hin.
Bei Google hab ich nix gefunden, MSDN hab ich nicht verstanden ;)
Hoffe, ihr könnt mir helfen,
thx schonmal im Voraus :)

PHP Code:
#include <iostream>
#include <windows.h>
#include <Winuser.h>




using namespace std;

int main()
{
    
cout << "Starteee!!!!" << endl;

    
HWND wHandle FindWindow(0,L"Guild Wars");
        if(!
wHandle)
        {
            
cout << "Starte das verdammte Spiiiieeeelll!!!!" 
            
<< " Errorcode: " << GetLastError() << '\n' << endl;
        }
    
        else
        {
            
cout << "WindowHandle: " << wHandle << endl;

                while(
wHandle)
                {
                    
LPARAM lParam 0x57;
                    
SendMessage(wHandleWM_KEYDOWNNULLlParam);
                    
SendMessage(wHandleWM_KEYUPNULLlParam); 

                }
        }

Btw: Habs mal mit "SendMessage(wHandle, WM_KEYDOWN, NULL, (LPARAM)"w")
hingekrigt, dass der Bot ingame i drückt.
Aber egal, was ich anstelle von "w" nehme, der Bot drückt immer i.
02/10/2010 16:59 MrSm!th#2
gibts nicht irgendwie so Makros wie MakeLPARAM oder so, die einen den richtigen hexwert geben, für das, was man möchte?
Denn einfach den hexwert einer taste angeben, geht glaub ich nicht....

btw. der include von Winuser ist unnötig, das wird schon in windows.h getan ;)
02/10/2010 17:04 flo8464#3
Hexdezimal ist keine andere Art von Zahlen, nur eine andere Darstellungsweise.
Das vorneweg, es ist absolut irrelevant ob du 12 oder 0xC schreibst.

Schau dir mal den Source an, er benutzt zwar keybd_event(), sollte dir aber helfen: [Only registered and activated users can see links. Click Here To Register...]
02/10/2010 17:09 Σternαl.#4
Quote:
keybd_event(VK_MENU, 0, KEYEVENTF_KEYUP, 0);
keybd_event(VK_TAB, 0, KEYEVENTF_KEYUP, 0);
Naja, soweit war ich mittlerweile auch schon.....
Und außerdem hatt das von Syntax her nix mit SendMessage zu tun...
02/10/2010 17:13 MrSm!th#5
Quote:
Originally Posted by flo8464 View Post
Hexdezimal ist keine andere Art von Zahlen, nur eine andere Darstellungsweise.
Das vorneweg, es ist absolut irrelevant ob du 12 oder 0xC schreibst.

Schau dir mal den Source an, er benutzt zwar keybd_event(), sollte dir aber helfen: [Only registered and activated users can see links. Click Here To Register...]
war mir auch klar :rolleyes:
mir ging es darum, den richtigen wert für das zu bekommen, was man möchte.
Gibt doch irgendwie so ein Makro wie MakeLParam oder nicht?
Da bekommt man dann für das was man möchte, den richtigen wert.
(so wie MAKEWORD für die version bei winsock)
02/10/2010 17:29 flo8464#6
Quote:
Originally Posted by FooFightah View Post
Naja, soweit war ich mittlerweile auch schon.....
Und außerdem hatt das von Syntax her nix mit SendMessage zu tun...
Source anschauen und nicht die Code-Snippets!
Den Source musst du downloaden und bietet hier eine komplette Implementierung einey Keystroke-Senders.

Und um mal einen generellen Fehler in deinem Verständnis zu klären:

Quote:
SendMessage(wHandle, WM_KEYDOWN, NULL, (LPARAM)"w")
"w" ist ein konstanter Zeiger auf ein Stringliteral, 'w' würde den ASCII-Wert des Zeichens zurückgeben, L' ' bei Unicode-Zeichen.
Der lparam-Parameter entspricht genau dem Char-Code, du musst weder etwas umwandeln geschweige denn hässliche C-Casts drauf loslassen. ;)
Du hast in deinem Beispiel die Addresse des Pointers zu einem Zeichen gecastet. Dass das nichts wird, ist klar.

So gehts:
Quote:
SendMessage(wHandle, WM_KEYDOWN, NULL, 'w')
MSDN solltest du schon verstehen, wo lag dein Problem?

Quote:
war mir auch klar
mir ging es darum, den richtigen wert für das zu bekommen, was man möchte.
Das war ja nicht auf dich bezogen.
Mir stößt es nur immer auf, wenn Leute von "Hex-Werten" sprechen. :)
02/10/2010 17:31 Bot_interesierter#7
Code:
SendMessage(wHandle, WM_KEYDOWN, 0x57/*VK W*/, NULL);
                    SendMessage(wHandle, WM_KEYUP, 0x57, NULL);
[Only registered and activated users can see links. Click Here To Register...]

War das jetzt so schwer zu finden, dass du das nicht selber konntest?

Wenn du nicht in der Lage bist anhand von MSDN zu begreifen wie eine API Funktion zu benutzten ist, dann solltest du das Programmieren aufgeben, du wirst auf keinen grünen Zweig kommen, weil du ständig nachfragen musst wie etwas funktioniert.
02/10/2010 17:50 P-a-i-n#8
er will eine taste simulieren die w drückt mhm willst du w spammen ich hätte mich ebenfalls für keybd_event entschieden

wenn man ist einer schleife drehen läßt drückt es w genauso z.B mit
wenn es in einer schleife ist die erfüllt ist dann wird es dauerhaft gedrückt
z.B ein fenstername

das drückt w

keybd_event(0x57, 0, 0, NULL);

das läßt es wieder los

keybd_event(0x57, 0, KEYEVENTF_KEYUP, 0);

also sendmassage ist mehr für texte übergeben aber zum tastendruck simulieren mehr ungeeignt find ich
jeder hat ja eine andere art und naja bei C++ gehen mehr wege zum ziel :)
02/10/2010 18:00 flo8464#9
Nein, keybd_event() sollte man nach Möglichkeit nicht nutzen, siehe MSDN.

Quote:
Windows NT/2000/XP/Vista:This function has been superseded. Use SendInput instead.
02/10/2010 18:01 Adroxxx#10
keybd_event und SendInput kann man beides auch verwenden. Geht aber dann nur im aktuellen Fensterm das gerade aktiv ist.
Mit Post/Send Message gehts an ein FensterHandle.
Blub:
[Only registered and activated users can see links. Click Here To Register...]

Kannste dir die SendKey Kopieren.
02/10/2010 18:05 P-a-i-n#11
Quote:
Originally Posted by flo8464 View Post
Nein, keybd_event() sollte man nach Möglichkeit nicht nutzen, siehe MSDN.

ob man es nutzen soll oder nicht ist ja mal dahingestellt hauptsache es funktioniert aufdauer ich hätte es per hand druck gelöst also mit getkeystate
lieber alles selberkontrollieren als vom system machen lassen :)

nagut jetzt sind so viele lösungen hier gepostet wird er ja wohl jetzt hinkriegen :)
02/10/2010 18:24 MrSm!th#12
Quote:
Originally Posted by Adroxxx View Post
keybd_event und SendInput kann man beides auch verwenden. Geht aber dann nur im aktuellen Fensterm das gerade aktiv ist.
Mit Post/Send Message gehts an ein FensterHandle.
Blub:
[Only registered and activated users can see links. Click Here To Register...]

Kannste dir die SendKey Kopieren.
man wollte ich gerade empfehlen^^

Foo wenn du mittlerweile VS mit MFC hast, kannst du adroxxxs klasse nutzen, ansonsten kann ich dir auch die *ohne MFC* version geben ;)
02/10/2010 20:30 Σternαl.#13
Express hab ich schon, aber ehrlich gesagt war mir das Downloaden von MFC
zu mühseelig und zum Kaufen isses mir zu teuer^^

Also erstmal danke an alle, die mir Tipps/Lösungen gegeben haben.
Und ich bin echt überrascht, dass mich nur einer angeflamed hat.
Naja, falls dus nicht gelesen haben solltest flo, ich bin ANFÄNGER.
Und Anfänger haben nunmal an sich, dass die mit etwas erst ANFANGEN
und deswegen noch nicht gleich alles verstehen/draufhaben.....
Btw ist msdn in englisch, zu mindest der SendMessage Post.
Ich kann zwar englisch, aber wenn man etwas lernen will, was man eh schon
nicht versteht, wiel einem keiner helfen kann, dann ist es nicht gerade vorteilhaft,
wenn das, was ich in msdn nicht verstehe, auch noch auf englisch ist.....
Aber schluss mit dem Flame, danke für den Tipp mit 'w', auch wenn ich die ganzen
Fachbegriffe nicht verstanden hab bzw. wo ich bitte nen Pointer gesetzt hab oO
Aber klappen tuts immernoch nicht, leider...
Hier nochmal der Source:
PHP Code:
#include <iostream> 
#include <windows.h> 

using namespace std

int main() 

    
cout << "Starteee!!!!" << endl

    
HWND wHandle FindWindow(0,L"Guild Wars"); 
        if(!
wHandle
        { 
            
cout << "Starte das verdammte Spiiiieeeelll!!!!"  
            
<< " Errorcode: " << GetLastError() << '\n' << endl
        } 
     
        else 
        { 
            
cout << "WindowHandle: " << wHandle << endl

                while(
wHandle
                {  
                    
SendMessage(wHandleWM_KEYDOWNNULL'w'); 
                    
SendMessage(wHandleWM_KEYUPNULL'w');  

                } 
        } 

Als kleine Info:
Wenn ich den "Bot" laufen lasse, wird ingame nur ein einziges mal i gedrückt,
also das seh ich daran, dass mein Inventar offen ist, aber mit w spammen is nich.
02/10/2010 20:55 Adroxxx#14
Zu MFC:

Die Klasse ist zu 90% non-mfc.
Das einzige wirkliche MFC ist einmal das Handle, weil ich da ein CWnd benutzte und CString.

Sonst kannste das eigentlich genauso kopieren.

PHP Code:
  LPARAM pmLparam = (::MapVirtualKey(KEY,0)<<16);
    
    
pWnd->PostMessage(WM_KEYDOWN,0,pmLparam);
    
pWnd->PostMessage(WM_CHAR,0,pmLparam);
    
Sleep(DELAY); 
    
pWnd->PostMessage(WM_KEYUP,0,pmLparam); 
So anstatt pWnd->PostMessage.... musste halt nur PostMessage(handle....usw)

du musst MapVirtualKey benutzten.

Und was auch wichtig ist, du brauchst da einen delay. Sonst simuliert er den druck der taste zu schnell.
02/10/2010 21:07 flo8464#15
Quote:
Naja, falls dus nicht gelesen haben solltest flo, ich bin ANFÄNGER.
Und Anfänger haben nunmal an sich, dass die mit etwas erst ANFANGEN
und deswegen noch nicht gleich alles verstehen/draufhaben.....
Wo hab ich geflamed? Geh mal ne Seite zurück, ich hab dir die Lösung auf dein Problem gepostet und dir erklärt was du falsch gemacht hast.

Quote:
wo ich bitte nen Pointer gesetzt hab
Wenn du jetzt soetwas schreibst:

Code:
do("Hallo");
dann legt der Compiler den String "Hallo" in einer read-only Datasection ab und fügt stattdessen einen Pointer zu diesem String ein.

Ein Zeichen in ' hingegen ist kein String und es wird direkt der Zahlenwert des Zeichens verwendet. Deswegen willst du das.

Quote:
nicht versteht, wiel einem keiner helfen kann, dann ist es nicht gerade vorteilhaft,
wenn das, was ich in msdn nicht verstehe, auch noch auf englisch ist.....
Ich habe dich ja gefragt, was du nicht verstehst.



-----------


Hast du es jetzt schon mal mit keybd_event()/SendInput() versucht?
DirectX nutzt nämlich keinen normalen Messagehandler.