• Advertisement
Sign in to follow this  

WinAPI - wait for certain calls to finish before continuing?

This topic is 1228 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.

Share this post


Link to post
Share on other sites
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.

Edited by tonemgub

Share this post


Link to post
Share on other sites

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.

Edited by .chicken

Share this post


Link to post
Share on other sites

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...

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

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

Edited by Endurion

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

Ok, thanks for the links. I clicked through them a bit. First of all, it seems that I have to correct myself. I'm not making the windows children of my application, but I'm setting my application as the new owner, without changing the WS_CHILD attribute.

 

Now from what I understand, the problem is that while the message I sent is in the queue, the owner of the window changes and thus the message isn't processed anymore. Did I get that right?

What I don't really understand now: how do I fix that? :S

Share this post


Link to post
Share on other sites

Frankly, I'm not sure what you're trying to do is even supported, so it may not be easy to find a simple explanation of how to make it work.


It isn't.

If you want to fabricate mouse clicks the only way to do it reliably is via SendInput (or the older API call that SendInput replaced). What SendInput does is identical to what moving and clicking the mouse does. You can't send mouse clicks to a hidden, obscured, or minimized window with SendInput any more or less than you can send input to a hidden, obscured, or minimized window via the mouse.

You can try posting messages but this is not guaranteed to work. It may work. It may not. It depends how the receiving WM_LBUTTONDOWN or whatever handler was written. There is nothing forcing developers to make sure their message handlers work in situations that are impossible to encounter under normal usage i.e. a hidden window receiving a mouseclick. But more importantly much more happens when you click a mouse button than one or two messages being posted to a message queue, none of which is documented. SendInput guarantees that all of this extra stuff will happen. PostMessage doesn't.

Anyway cross-process Win32 programming is not easy. The OP probably will not be able to do what the OP wants to do without fabricating mouse moves to move the cursor around, unless the the OP controls both ends of the cross-process communication. For the OP's use case of cheating at online poker, the thing that will actually work is

  1. Not trying to fuck around with cross-process parenting.
  2. Tiling the poker windows so that they do not overlap with cross-process calls to MoveWindow.
  3. Fabricating mouse moves and mouse clicks with SendInput to interact with the tiled windows as a human user would.

But probably the OP wants to have many poker windows open but hidden and then play poker on them by sending Windows messages. This almost certainly won't work.

Edited by jwezorek

Share this post


Link to post
Share on other sites

First of all, it still isn't about cheating. If I had the knowledge to write a pokerbot, winning at stakes at which its worth, I probably wouldn't really worry about any of that shit, buy 10computers with 3 30"displays each and just tile the tables.

Unfortunately, I don't, so I'm still worried about getting good seats (which isn't forbidden) and since I don't wanne tile 30tables on 2additional monitors, I have to make it work, when they are stacked somehow.

 

I know it is possible, because I know people who are using such a script. Unfortunately I'm not willing to pay their prices.

What opportunities do I have from here on?

a) Could I just set the window owner to desktop, move the window to a fixed place, move the mouse there, click and move the mouse back, without noticing it while playing? Or would this make the mouse "wiggle" somehow?

b) It's not that I definitely want to own the different windows, I just thought it would be the easiest solution to having them stacked and move with my application window!? Is there an alternative?

 

What's weird is still, that my program works so far, as long as I have enough sleep-time inbetween. And I still don't fully understand why it only works then.

Edited by .chicken

Share this post


Link to post
Share on other sites

I know it is possible, because I know people who are using such a script. Unfortunately I'm not willing to pay their prices.
What opportunities do I have from here on?

Are you sure that the people selling tools like this are not working in conjunction with the developers of the poker app and thus have access to undocumented APIs?

 

What you are saying in a) would probably work, yes, except for the part where you want to play normally while it is doing it. Doing stuff with SendInput like this is going to be temperamental as hell.

 

On b.), I mean, your application doesn't need to have a window, it sounds to me that you don't really need a window for your process at all.

 

Anyway, what is the poker client app like anyway? Is it running in a browser? Because if that is case there are probably other ways to do automation beyond Win32 stuff. If it is not browser-based, have you looked at it with Spy++? Is it a .Net application, etc.?

Edited by jwezorek

Share this post


Link to post
Share on other sites

Yes I'm sure they are not working with the developers.

 

 

On b.), I mean, your application doesn't need to have a window, it sounds to me that you don't really need a window for your process at all.

It doesnt necessarily, but its just more comfortable, not having the windows take up desktop space.

 

 

Anyway, what is the poker client app like anyway? Is it running in a browser? Because if that is case there are probably other ways to do automation beyond Win32 stuff. If it is not browser-based, have you looked at it with Spy++? Is it a .Net application, etc.?

Its not browser based and I'm trying to be able to configure my program for different poker platforms. I havent looked at it with spy. Right now I'm just testing with FullTiltPoker, but I hope the software works for almost every client, later on.

 

Edit: I'm working through the loop of windows in a worker thread. Could that cause any problems?

Edited by .chicken

Share this post


Link to post
Share on other sites

Ok, I got this done now, using sleeps. It works pretty good so far. On some Poker Clients I have to use SendInput though. I checked them with spy++ now, and I think the following lines are what happens when I click the window.

 

b6e50da735e93fc748f6e3e26e5100b0.png

 

I tried sending those message with SendMessage, but couldn't get it to work. Where do I put the uMsg: WM_LBUTTONDOWN?

 

What I did was:

SendMessage(handle, WM_PARENTNOTIFY, WM_LBUTTONDOWN, MAKELPARAM(x,y));
SendMessage(handle, WM_MOUSEACTIVATE, handle, HTCLIENT); //where to add the uMsg: WM_LBUTTONDOWN?

I feel like I understood this completely wrong...

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement