PDA

View Full Version : API Call Help (SendMessage user32.dll)



Centauri Soldier
02-26-2010, 10:51 PM
I am still lost on converting VB and C++ calls to AMS lua. I look at other examples of API calls but I am just not making the connection and how to determine the variable types used and how to formulate the statement.

Could anyone knowledgeable in this area provide a brief AMS code example of an API call to the user32.dll using the SendMessage function?

Imagine Programming
02-27-2010, 12:38 AM
What message do you want to send with what wParam and lParam?

It's basicly User32.dll:SendMessage(Windowhandle, Message, wParam, lParam)

A little function to ease the call:

function SendMessage(WindowHandle, Message, wParam, lParam)
local SMRes = DLL.CallFunction("user32.dll", "SendMessageA",
tostring(WindowHandle)..", "..
tostring(Message)..", "..
tostring(wParam)..", "..
tostring(lParam),
DLL_RETURN_TYPE_LONG,
DLL_CALL_STDCALL);
return SMRes
end

And then for instance simulate Window.Close(Application.GetWndHandle(),CLOSEWND_S ENDMESSAGE)


SendMessage(Application.GetWndHandle(),16,0,0);


Should work ^^
Which ofcourse doesn't work XD

Imagine Programming
02-27-2010, 01:00 AM
Which is weird, cuz


Procedure.l SndMsg(hWnd.l,Msg.l,wParam.l,lParam.l)
Protected lRes.l = 0
hLib = OpenLibrary(#PB_Any ,"User32.dll")
If hLib
lRes = CallFunction(hLib, "SendMessageA", hWnd,Msg,wParam,lParam)
CloseLibrary(hLib)
EndIf
ProcedureReturn lRes
EndProcedure

If OpenWindow(0,#PB_Ignore ,#PB_Ignore,200,200,"")
CreateGadgetList(WindowID(0))
ButtonGadget(0,0,0,200,200,"CLOSE")
Repeat
Event = WaitWindowEvent()
If Event = #PB_Event_Gadget And EventGadget() = 0
SndMsg(WindowID(0),$10,0,0) ; $10 = hex for 16, or simply #WM_CLOSE.
EndIf
Until Event = #PB_Event_CloseWindow
EndIf

in purebasic, does work 0.o Did I grow out of lua? XD

Just for testing, PureBasic has SendMessage_() included hehe

Centauri Soldier
02-27-2010, 01:18 AM
It's quite frustrating isn't it. I have been messing with it for about 3 hours straight now!
D&*% this function. I just want to send a string out to another app and have it pick it up and I want to do it without a plugin or third-party DLL.

Maybe I'm using the wrong function for that purpose.
*&%$ S*%#@*%#!!!!! :wow

EDIT: Well it's closing my window so I guess I'm falling off the right cliff now...

Ulrich
02-27-2010, 07:48 AM
And then for instance simulate Window.Close(Application.GetWndHandle(),CLOSEWND_S ENDMESSAGE)


SendMessage(Application.GetWndHandle(),16,0,0);


Should work ^^
Which ofcourse doesn't work XD

Read the help file carefully: It says that you have to inform the path to the DLL, not simply its name.


local SMRes = DLL.CallFunction(_SystemFolder .. "\\user32.dll", "SendMessageA",

Ulrich

Centauri Soldier
02-27-2010, 08:57 AM
I've tried this every which way and funny enough, the code is actually working for me as posted. (Although I did take your suggestion to make sur enothing was going in the path with FindWindow...thx)

Now I'm just trying to get FindWindow to work or at least some means to find a window handle based on it's Title or Process name or ID and also find the method by which I can send and receive text via SendMesssage between applications.

Centauri Soldier
02-27-2010, 09:14 AM
I have spent hours reading and trying code and the only example I can get to work is IP's.

I'm just not getting how to properly configure these API calls. For instance, to my mind this should work.


function SendMessage(WindowHandle, Message, wParam, lParam)
local SMRes = DLL.CallFunction(_SystemFolder.."\\user32.dll", "SendMessageA",
tostring(WindowHandle)..", "..
tostring(Message)..", "..
tostring(wParam)..", "..
tostring(lParam),
DLL_RETURN_TYPE_LONG,
DLL_CALL_STDCALL);
return SMRes
end



SendMessage(Application.GetWndHandle(),12,0,"Hello");

But it does not (and I've tried it a billion different ways like "\"".."Hello".."\"" for example).

If anyone could tell me how to configure the API calls (as far AMS syntax and string use etc.) then I could figure out the rest of the API functions by reading the MSDN and other web examples. I would much rather have the general knowledge here than a specific example (although I won't turn that down either :D).

Imagine Programming
02-27-2010, 09:45 AM
Read the help file carefully: It says that you have to inform the path to the DLL, not simply its name.


local SMRes = DLL.CallFunction(_SystemFolder .. "\\user32.dll", "SendMessageA",

Ulrich

Yes I know, I tried that, but I still get a 0 return and no window closure on SendMessage(Application.GetWndHandle(),16,0,0); 0.o



I have spent hours reading and trying code and the only example I can get to work is IP's.

I'm just not getting how to properly configure these API calls. For instance, to my mind this should work.


function SendMessage(WindowHandle, Message, wParam, lParam)
local SMRes = DLL.CallFunction(_SystemFolder.."\\user32.dll", "SendMessageA",
tostring(WindowHandle)..", "..
tostring(Message)..", "..
tostring(wParam)..", "..
tostring(lParam),
DLL_RETURN_TYPE_LONG,
DLL_CALL_STDCALL);
return SMRes
end



SendMessage(Application.GetWndHandle(),12,0,"Hello");

But it does not (and I've tried it a billion different ways like "\"".."Hello".."\"" for example).

If anyone could tell me how to configure the API calls (as far AMS syntax and string use etc.) then I could figure out the rest of the API functions by reading the MSDN and other web examples. I would much rather have the general knowledge here than a specific example (although I won't turn that down either :D).

Maybe allocate memory, and parse the pointer as lParam :) Because all arguments in SendMessageA must be of type Long :) So, a string will not work I guess.

But, I found this:


SendMessage(nHandle, 12, 0, "~||~AndSomeMessage");
by clueless, does that do anything for ya?

RizlaUK
02-27-2010, 11:21 AM
WinAPI, now you talking my language!

SendMessage is a useful function, i use it a lot, the arguments vary from each message, most will be pointers to a memory address or structure

so, how to use "SendMessage" depends on what message you are sending, each is different, there's no generic pattern except wParam and lParam contain some variables of variable type

to send a string variable you will need the memory plugin :yes

reteset
02-27-2010, 11:51 AM
this is a simple sendmessage() api example

WM_SETTEXT = Math.HexToNumber("0x000C");
hWnd = Application.GetWndHandle();
va_args = string.format("%d,%d,%d,\"%s\"",hWnd, WM_SETTEXT, 0, "Hello World")
DLL.CallFunction("User32.dll", "SendMessageA", va_args, DLL_RETURN_TYPE_INTEGER, DLL_CALL_STDCALL);

like you can see in exaple above i sent a string with lParam argument of SendMessage()

Centauri Soldier
02-27-2010, 12:43 PM
But, I found this:


SendMessage(nHandle, 12, 0, "~||~AndSomeMessage");
by clueless, does that do anything for ya?

No that didn't work but your original code does...not sure why it's not working for you. It worked right out of the box for me. Ya did good.


to send a string variable you will need the memory plugin :yes
I'm trying to do this (and I know it's possible somehow...) without any third-party plugins or dlls.


this is a simple sendmessage() api example
like you can see in exaple above i sent a string with lParam argument of SendMessage()

That's amazing! It works. So my question to you is, where do find the knowledge to make this work, like the number for the WM_SETTEXT value? How did you know that WM_SETTEXT was equal to 0x000C?

The problem I'm running into is that most examples are in C++ or VB and I'm sure how to translate that to lua.

I'm going to try your method of the argument set-up and format procedure for FindWindow.

Thanks for your input thus far everyone, it had been most helpful! I now have hope of being able to use the Windows API. :yes:yes:D

Centauri Soldier
02-27-2010, 01:07 PM
OM$G!!! :eek:
Forgive my enthusiasm but I'm quite ecstatic.

After three hours of trying, the code for FindWindow finally works. Thanks, reteset for the string formatting tip. You're a genius! :D



sNull = "";
sWindowName = string.format("\"%s\"", "RunScript Lua");

va_args = sNull..","..sWindowName;

sRet = DLL.CallFunction("User32.dll", "FindWindowA", va_args, DLL_RETURN_TYPE_INTEGER, DLL_CALL_STDCALL);
Dialog.Message("", sRet);

Imagine Programming
02-27-2010, 03:14 PM
My code worked? That strange, it should indeed, but it doesn't work over here haha :yes

Anyhow, to figure out what all the constant's values are, check the MSDN website and search for eg: WM_CLOSE or google for eg: user32.h
You'll usually find something :)

Eg: WM_CLOSE (http://msdn.microsoft.com/en-us/library/ms632617%28VS.85%29.aspx) - Scroll down for the value, 0x0010 = 16

I love the SendMessage procedure, you can do so much with it XD

*Edit, you should always check out MSDN.com out first IMO, they have
really helpful articles and topics over there :yes

Centauri Soldier
02-27-2010, 03:22 PM
*Edit, you should always check out MSDN.com out first IMO, they have
really helpful articles and topics over there :yes

That was the first place I went and I've been buried in it for hours, I'm just not very familiar with it yet.

Imagine Programming
02-27-2010, 03:47 PM
That was the first place I went and I've been buried in it for hours, I'm just not very familiar with it yet.

It can indeed be a bit hard to find stuff on MSDN, but in the end, you usually find what you want ^^
Good luck on winapi :D