Emulate mouse select messages between windows - c++

I've got two windows in the same process. Window 1 contains some text. Window 2 contains a bitmap of the contents of window 1.
Whenever I click (WM_LBUTTONDOWN ) or move (WM_MOUSEMOVE) the cursor in window 2, i pass the message into window 1 by posting the message to window 1's message queue.
I now want to emulate more complex interaction. I'd like to do a "mouse select", where the WM_LBUTTONDOWN goes down and several WM_MOUSEMOVE occur. This should select some text in window #1. (it works fine if I perform this action directly in window 1)
I haven't been able to get this working by just posting the messages. It seems that mouse capture needs to be held by window 1, but my clicks and moves are happening in window 2.
Any pointers on an implementation using only WIN32 API?
Thanks,
Chris

Why are you trying to do this using window messages? Can't you just have a common function that updates the selection in window 1, so that both window 1 and window 2 can just call this function to get the work done?

Related

GetWindowRect coordinates not screen-relative

I am working in Visual Studio 2008 C++. I have an MFC dialog with a control inside it. I am trying to position another dialog in the control.
SetWindowPos() on the second dialog is clearly using screen coordinates, so I need to get the screen coordinates of the control or the parent dialog. The MSDN documentation says GetWindowRect() provides "screen coordinates relative to the upper-left corner of the display screen" but this is NOT what I am getting. On the control it gives coordinates relative to the parent. On the parent it gives left=0 and top=0. I have tried the rectangle from GetWindowPlacement() as well and it gives the same thing. Everything is relative to the parent.
Why is GetWindowRect() not returning screen-relative coordinates? Is there another way to get them?
I'm not new to programming, but fairly new to Windows programming, Visual Studio, and MFC, so I may be missing something obvious.
Here is what I am doing in OnInitDialog for the parent dialog:
// TestApp message handlers
BOOL TestApp::OnInitDialog()
{
CDialog::OnInitDialog();
FILE * pFile = fopen("out.txt","w");
CRect winRect;
GetWindowRect(&winRect);
fprintf(pFile,"left=%li top=%li right=%li bottom=%li\n",winRect.left,winRect.top,winRect.right,winRect.bottom); fflush(pFile);
fclose(pFile);
return TRUE; // return TRUE unless you set the focus to a control
}
When run, the dialog does NOT appear at the upper-left corner of the screen, but out.txt contains:
left=0 top=0 right=297 bottom=400
OnInitDialog is called by the framework, before the dialog is shown. At this point, neither the final size nor position are known:
Windows sends the WM_INITDIALOG message to the dialog box during the Create, CreateIndirect, or DoModal calls, which occur immediately before the dialog box is displayed.
The final size and position of a dialog are the result of window positioning negotiations. The first message sent to a dialog where this information is available is WM_WINDOWPOSCHANGED. Using MFC, this message is handled through CWnd::OnWindowPosChanged. Custom handling code can be implemented by overriding OnWindowPosChanged in your CDialog-derived class.
As written in the other answer:
OnInitDialog is called before the window is moved to its final position. If you call GetWindowRect later you'll see it return the proper coordinates.
Just use PostMessage with a WM_APP+n message. This message will arrive when the message pump is running and the message will arrive when the window is positioned and shown on the screen.
Or use a timer. This has the same effect.
OnInitDialog is called before the window is moved to its final position. If you call GetWindowRect later you'll see it return the proper coordinates.

Reliably identifying any window's client area

I am working on a program that will replicate, and then extend the functionality of Aero Snap.
Aero Snap restores a maximized window, if the user "grabs" it's title bar, and I am having difficulties identifying this action.
Given a cursor position in screen coordinates, how would I check if the position is within the window's title bar? I am not really at home in the Win32 API, and could not find a way that works reliably for complicated scenarios such as:
Note that tabs that chrome inserts into the title bar. Office does something similar with the quick launch menu.
title bar hits are via the message "non client" messages - ie the area of a window that is not the client (or inner) window.
WM_NCLBUTTONDOWN is probably the message you want to trap.
You also probably want to set a window hook to hook mouse messages, if its the NC message you want, you handle it your way, if not - pass it on to the message chain.
Edit: if Chrome is using the DwmExtendFrameIntoClientArea calls to draw the tabs, then you will need to use WM_NCHITTEST.

Child Windows that does not occupy client area

In the Win32 API (pure win32), The Menu bar does not occupy any area from the client area of the window. Which means the origin coordinates of the client area is right under the menu bar to the left.
When we create child window controls using CreateWindow (or any other method), that window takes some area of the client-area.
eg:- Creating a button which is at (xPos = 0, yPos = 0) and (width=width_of_client_area, height=20).
After creating the button if you'll use a GDI function like this, it'll be drew below the button:
Rectangle(hdc, 0,0, 200, 200);
But when creating a menu bar, it doesn't occupy client area. (GDI will not be drew under menu).
FINAL QUESTION:
How can i create a control on my parent window like the menu bar ?
The menu is rendered in the non-client area of the window, which is driven by a completely different set of window messages. Keep in mind that you don't actually create child windows for these types of controls. You will need to provide all the rendering and event handling for the customization you want to add. This means that if you want to add a button or checkbox you will need to implement it yourself. You can get your started with a handful of steps but there may be other things that need to be done depending on your requirements.
The first step is to process the WM_NCCALCSIZE message. This will allow you to adjust the size of the non-client area so that you have more space to draw the custom control. Basically you will pass this message on to the default window proc then modify the location and dimensions (just drop the top down X pixels) before returning.
The next step is to handle WM_NCPAINT message. Pass the message on to the default window proc then draw your custom visuals in the area you have reserved. You will be working with a window DC so you can draw to the entire window. It's important to keep this in mind so you don't destroy anything in the client area.
The last item that needs to be done is to handle mouse messages like WM_NCMOUSEMOVE. If the mouse event occurs outside the area where your control is located pass the message to the default window proc, otherwise handle the message yourself and skip the default proc. you will need to manage some state data for keeping track of when a button is down or not so as not to cause conflicts with the default window proc.
Keep in mind that when you want to draw directly to the non-client area you need to call GetWindowDC() instead of GetDC() to acquire a device context.
[Note: A good Google dance will be something like "WinAPI non-client area"]

How to keep window inactive on simulated clicks?

I made a program in C++ that simulates clicks on an inactive window using:
PostMessage (z, WM_LBUTTONDOWN, 0,MAKELONG(t.left+x,t.top+y));
But whenever it makes a click it activates the window and the window moves to the top.
Is there a way I can make the window stay inactive or another way to click it?
I used SetWindowPos(z , HWND_BOTTOM,....) to make that window be at the bottom of the z-order list but it still activates.
EDIT: the window is a game console
Try switching from PostMessage to SendInput and see if you get the same effect.

How to get the window position and update to other windows?

I have 2 dialog boxes in which I will display 1 dialogbox at a time..If I click NEXT in the first dialog box,I will hide the first dialog box and display the second dialog and vice versa...Now say If I move the dialog box after clicking NEXT in the first dialog..and when I click BACK(in the second dialog) ...it goes back to its previous position(to diaplay the first dialog box)..so I have decided to get the current window's position and update to the other window position so that it doesnt move even If I click next/back..I am not sure how to get the windows position and update to other..please help me if you guys know about this..
You can create an OnMove handler for WM_MOVE messages to detect when your window moves. In the handler, you can either move the other window directly with MoveWindow, or you can send a private message to the window (something in the WM_APP range would be best) and let it move itself. Use GetWindowRect to get the width and height to pass to MoveWindow.