WinAPI - wait for certain calls to finish before continuing?

Started by
15 comments, last by .chicken 9 years, 6 months ago

Hi!

I have a little problem, I'm not sure where it comes from.

I'm posting click-messages to window-handles in a loop.


SendMessage(h, Msg1, param, MAKELPARAM(wx, wy));
SendMessage(h, Msg2, param, MAKELPARAM(wx, wy));

After that, I change the handles parent from my application to desktop.


SetParent(handle, GetDesktopWindow());

This works perfectly, for the first handle in the loop. The second handle (and all others after that), though, doesnt receive any clicks. I'm not sure why this is happening, but as soon as I add


std::this_thread::sleep_for(std::chrono::milliseconds(50));

after the SendMessages and before the SetParent, it works perfectly fine. Can anyone explain to me why this is happening, and maybe give me a better alternative than std::sleep? I'm afraid this might not work 100% and slows down the program more than necessary most of the time.

Thanks in advance.

Advertisement

Each two (or more) of your click messages (WM_LBUTTONDOWN immediately followed by WM_LBUTTONUP?) are probably getting translated (by TranslateMessage) into double-click messages (WM_LBUTTONDBLCLK) because they are happening faster than the double-click speed threshold. You can disable this behaviour by removing the CS_DBLCLKS class style from the window class(es) of the windows you're trying to click. But for this to happen, it also means that the windows you're sending the messages to belong to a different thread than the thread you're sending from?

Also, if you can let us know what exactly it is you're trying to do, we could propose alternative methods... Sending mouse messages to windows the way you're trying to doesn't feel like a very good idea to me.

What I'm trying to do is called a "seating-script". Basically, trying to get the best seat at an online poker table, once a new player joins (meaning the seat to his left).

I'm scanning the tables for a change in appearance - for every seat at the table, I'm scanning one specific pixel every few miliseconds, and if it changed, I'm trying to seat next to that seat, by clicking on it.

That's basically what I'm trying to accomplish. The windows I'm scanning are not from my application. I'm making them children tho, until I seat them, then I release them to the desktop, again.

Thanks so far.

Edit: I tried to remove the 2nd PostMessage( which is a mousebutton_up message btw, sorry that i didn't mention that), but it didn't change anything. :S

Still, the only sleep works, when the script tries to join multiple tables shortly after another.

Sorry, but I don't know what the forum rules are against what you are trying to do, and it sounds illegal, so I cannot help you further...

It isn't illegal. Most poker sites allow such software.

Why are you re-parenting windows across processes?

Whatever it is you are trying to accomplish by doing this is almost certainly not going to work.
The SendMessage function already does what you want, for threads within your process. The documentation (specifically under Remarks) is clear.

However, sending messages to other processes is typically... not advisable on Windows.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

As Raymond Chen advises, to send input use SendInput. It does what you want to do, and it knows how to do it properly.

SendInput at MSDN: http://msdn.microsoft.com/en-us/library/windows/desktop/ms646310(v=vs.85).aspx

There's some sample code at Old New Thing: http://blogs.msdn.com/b/oldnewthing/archive/2012/11/01/10364713.aspx

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

Why are you re-parenting windows across processes?

Whatever it is you are trying to accomplish by doing this is almost certainly not going to work.

I'm reparenting the windows, because I'll open alot of seperate windows and I want to hold them all in one place. So I'll set my application as a parent and put them in a frame there until I want to seat them.

SendInput is not an option for me I believe, because I can only click front windows with it, right? I can't simulate a click on a handle in the back? Additionally, I don't want my mouse to move in order to do the clicking.

I'm not sure I understand the SendMessage-remarks correctly. So, as I mentioned, my method works for one single window, or with std:sleep inbetween. So the problem is caused by

The sending thread is blocked until the receiving thread processes the message. However, the sending thread will process incoming nonqueued messages while waiting for its message to be processed.

this? So the mouseclick is sent, all other stuff inside my app continues to happen, but the next mouseclick isnt send, because its still waiting for an answer from the first? Did I get that right?

So in order to make it work, I need SendMessageTimeout

http://msdn.microsoft.com/en-us/library/windows/desktop/ms644952%28v=vs.85%29.aspx

with SMTO_BLOCK?

Is that right? Thanks so far.

Important reading:

http://blogs.msdn.com/b/oldnewthing/archive/2011/03/31/10147981.aspx
http://channel9.msdn.com/blogs/scobleizer/raymond-chen-pdc-05-talk-five-things-every-win32-programmer-needs-to-know
http://blogs.msdn.com/b/oldnewthing/archive/2003/08/21/54675.aspx

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

This topic is closed to new replies.

Advertisement