How to determine if the current window is the active window? - c++

How can I tell if my window is the current active window?
My current guess is to do GetForegroundWindow and compare the HWND with that of my window.
Is there a better method than that?
I'm using Win32 API / MFC.

Yes, that's the only way that I'm aware of.
But you have to handle the fact that GFW can return NULL. Typically, this happens when another desktop (e.g. the screen saver desktop) is active. Note that use of a saver password can affect whether a different desktop is used (this is windows version-dependent and I can't remember the details of how different versions work).
Also this code won't work properly in debug mode under Visual Studio, because you will get VS's window handle.
Other than that everything's peachy :-)

You can try to use WM_ACTIVATEAPP message.
First define a bool variable bool wActive = false, in the WndProc procedure, here is the next piece of code:
case WM_ACTIVATEAPP:
wActive = (bool)wParam;
return 0;
You can go to MSDN to find more information about WM_ACTIVATEAPP

Yes you are correct unless otherwise you want to check activewindow of every thread.

I assume that you mean the window which has the input focus when you say "active window"?
In that case, forget the GetForegroundWindow() API. That will return the topmost window - not always the window which has the input focus.
Use GetFocus() instead.

Yea, GetForgroundWindow() is a good way to check, behaves correctly even with a "Always on top" window aka HWND_TOPMOST .
Another way is with GetActiveWindow()
HWND temp = GetActiveWindow();
if (temp == hWnd) // Then your current window has focus
Alternatively the following messages report if the focus has changed
case WM_KILLFOCUS:
// windowHasFocus = false
break;
case WM_SETFOCUS:
// windowHasFocus = true;
break;

Related

What can reset cursor shape apart from SetCursor?

I maintain a C++ application that uses flash ocx to play SWF file.
When user hovers on button in SWF, flash internally makes a call to WinAPI SetCursor function to set IDC_HAND cursor - I can see that when I monitor WinAPI calls to cursor-related function via API Monitor V2 (rohitab.com). However, in my case the cursor is not changing, i.e. stays IDC_ARROW.
The application itself does not call SetCursor at all. The window of the application processes WM_SETCURSOR message as following, i.e. does not restore the cursor:
case WM_SETCURSOR:
{
static bool restoreCursor = false;
if (LOWORD(lParam) != HTCLIENT)
{
restoreCursor = true;
}
if (restoreCursor)
{
restoreCursor = false;
// DefWindowProc will set the cursor
break;
}
return 1;
}
Can anyone please let me know who can reset/change cursor shape in this case?
Update: The interesting part is the fact that I have 2 similar setups that produce the opposite results.
The application I maintain actually installs a WH_GETMESSAGE hook on "SysListView32" and launches a thread that creates Flash player. So the setup is not that straight-forward.
However, if I just create a simple example that creates a player at, basically, winmain, then the code above works perfectly and cursor gets changed.
So it appears that something does reset the cursor state in the first case. How to find out what resets the cursor?
OK, the real answer on this question is that non-GUI thread cannot change the cursor directly.
See the comments in the bottom of the page
http://msdn.microsoft.com/en-us/library/windows/desktop/ms648393%28v=vs.85%29.aspx
Another solution can be detouring/hooking the SetCursor function to ours that just sends a user message to GUI thread, signalling to set the cursor.
Both solutions have their pros and, of-course :), cons.
Your window (the parent) gets a crack at overriding the cursor and returning TRUE (1) indicated that you handled it and halts further processing. The arrow is probably coming from your WNDCLASS registration or from DefWindowProc.
So, it seems to me that you'd want to return FALSE to allow the child button a crack at actually setting the cursor. Or, remove handing WM_SETCURSOR altogether.

Validate HWND using Win32 API

From the native Win32 API using C++ is there a way to determine whether the window associated with an HWND is still valid?
You could use the Win32 API IsWindow.
It is not recommended to use it though for 2 reasons:
Windows handles can be re-used once the window is destroyed, so you don't know if you have a handle to an entirely different window or not.
The state could change directly after this call and you will think it is valid, but it may really not be valid.
From MSDN (same link as above):
A thread should not use IsWindow for a
window that it did not create because
the window could be destroyed after
this function was called. Further,
because window handles are recycled
the handle could even point to a
different window.
What can be done?
Perhaps your problem can be re-architected so that you do not have the need to check for a valid handle. Maybe for example you can establish a pipe from the client to the server.
You could also create a windows hook to detect when certain messages occur, but this is probably overkill for most needs.
This question is old, but I needed this functionality myself and was a bit disappointed after reading about the caveats. However, after doing a bit more digging it seems that all is well. Unless you're dealing with 16bit programs, IsWindow appears to be the way to go. The problem of handle re-use appears to have been sufficiently addressed according to this:
http://blogs.msdn.com/b/oldnewthing/archive/2007/07/17/3903614.aspx
So, because of the upper 16bit reuse counter, it is highly unlikely that you'll run into a window reuse problem.
You can use IsWindow() or also try to send the window a WM_NULL message with SendMessage(hWnd, WM_NULL) and see if it is successful.
Also, it is true that the window could be destroyed at any time if it isn't under your control. As others have stated the handle could potentially belong to another window as the handles are reused. In reality I don't know how likely that is.
The only solution that I know of the to create a system wide hook that looks for messages indicating a window is destroyed (WM_CLOSE, WM_DESTROY). Then you would compare the message window handle to ones you are holding to see if any of the windows you care about are affected. See here for more information on system wide hooks.
Maybe a combination of IsWindow, FindWindow and GetWindowThreadProcessId will be more accurate
HWND windowHandle = FindWindow(NULL, TEXT("window_title"));
LPDWORD oldpid = 0;
GetWindowThreadProcessId(windowHandle, &oldpid);
//after some time
if (IsWindow(windowHandle))
{
LPDWORD newpid = 0;
GetWindowThreadProcessId(windowHandle, &newpid);
if (newpid == oldpid)
{
//the window is still running
}else
{
//the window exists but has changed
}
}
If the window procedure for the window in question is under your control (or if you can subclass it), then I would suggest registering a custom message that the window responds to with a non-zero result. Sending that message to any other window (or an invalid HWND) will result in 0.
Of course, that only tells you if the HWND refers to one of the windows that you control -- but perhaps given other answers above that might even be advantageous.
Use RegisterWindowMessage to register the message, using a sufficiently unique name.
if(IsWindow(FindWindow(NULL , TEXT("Example Window Name")))){
// do stuff
}
will check if the window exists and has the appropriate name

how to find a window's SW_SHOW/SW_HIDE status

I am trying to determine a window control's visibility that has been hidden or enabled with CWnd::ShowWindow(). (or ::ShowWindow(hWnd,nCmdShow))
I cannot simply use ::IsWindowVisible(hWnd) as the control is on a tab sheet, which may itself be switched out, causing IsWindowVisible to return FALSE.
Is there a way to get the SW_SHOW/HIDE (or others) window status or do I need to use the retun value of ShowWindow() and reset accordingly?
edit:
as the control is enabled (or disabled) to show, but may not be currently visible, as the tab is switched ot, I would think that it's SW_SHOW status would remain the same, even if the window itself is not actually switched in. If I'm unrealistic in my expectations that that's fine.
So really I'm looking for 'can this window/control be shown'
Call GetWindowLong( handle, GWL_STYLE), check the returned value for WS_VISIBLE style presence.
Use GetWindowPlacement. It fills WINDOWPLACEMENT structure, which has field showCmd.
showCmd
Specifies the current show state of the window. This member can be one of the following values.
I would use GetWindowPlacement, however I am not sure if I understood what you want.
It fills in a WINDOWPLACEMENT structure and then use the showCmd member.
GetWindowPlacement() function will work only if the window is maximized or minimized. Otherwise, showCmd member will return SW_SHOWNORMAL also when window is hidden, as pointed out in this StackOverflow answer: WINDOWPLACEMENT's showCmd... always 1?
You can use the more straightforward boolean function IsWindowVisible() to get if the specified Window is in a visible state or not.
If it is a multi-tab dialog and not a control, then override as
void MyClass::OnShowWindow(BOOL bShow, UINT nStatus)
{
m_nCmdShow = bShow;
CDialog::OnShowWindow(bShow, nStatus);
}
In BEGIN_MESSAGE_MAP, add ON_WM_SHOWWINDOW().
m_nCmdShow now has the status if the window is SW_SHOW or SW_HIDE.
I don't know if there is a proper method for this task but I would try WindowFromPoint Function.
Remarks
The WindowFromPoint function does not retrieve a handle to a hidden or
disabled window, even if the point is
within the window. An application
should use the ChildWindowFromPoint
function for a nonrestrictive search.
For example I would convert control's corner coords into screen coords and then try to get it's handle from those points.

Managing Window Z-Order Like Photoshop CS

So I've got an application whose window behavior I would like to behave more like Photoshop CS. In Photoshop CS, the document windows always stay behind the tool windows, but are still top level windows. For MDI child windows, since the document window is actually a child, you can't move it outside of the main window. In CS, though, you can move your image to a different monitor fine, which is a big advantage over docked applications like Visual Studio, and over regular MDI applications.
Anyway, here's my research so far. I've tried to intercept the WM_MOUSEACTIVATE message, and use the DeferWindowPos commands to do my own ordering of the window, and then return MA_NOACTIVATEANDEAT, but that causes the window to not be activated properly, and I believe there are other commands that "activate" a window without calling WM_MOUSEACTIVATE (like SetFocus() I think), so that method probably won't work anyway.
I believe Windows' procedure for "activating" a window is
1. notify the unactivated window with the WM_NCACTIVATE and WM_ACTIVATE messages
2. move the window to the top of the z-order (sending WM_POSCHANGING, WM_POSCHANGED and repaint messages)
3. notify the newly activated window with WM_NCACTIVATE and WM_ACTIVATE messages.
It seems the cleanest way to do it would be to intercept the first WM_ACTIVATE message, and somehow notify Windows that you're going to override their way of doing the z-ordering, and then use the DeferWindowPos commands, but I can't figure out how to do it that way. It seems once Windows sends the WM_ACTIVATE message, it's already going to do the reordering its own way, so any DeferWindowPos commands I use are overridden.
Right now I've got a basic implementation quasy-working that makes the tool windows topmost when the app is activated, but then makes them non-topmost when it's not, but it's very quirky (it sometimes gets on top of other windows like the task manager, whereas Photoshop CS doesn't do that, so I think Photoshop somehow does it differently) and it just seems like there would be a more intuitive way of doing it.
Anyway, does anyone know how Photoshop CS does it, or a better way than using topmost?
I havn't seen anything remarkable about Photoshop CS that requries anything close to this level of hacking that can't instead be done simply by specifying the correct owner window relationships when creating windows. i.e. any window that must be shown above some other window specifies that window as its owner when being created - if you have multiple document windows, each one gets its own set of owned child windows that you can dynamically show and hide as the document window gains and looses activation.
You can try handle WM_WINDOWPOSCHANGING event to prevent overlaping another windows (with pseudo-topmost flag). So you are avoiding all problems with setting/clearing TopMost flag.
public class BaseForm : Form
{
public virtual int TopMostLevel
{
get { return 0; }
}
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool EnumThreadWindows(uint dwThreadId, Win32Callback lpEnumFunc, IntPtr lParam);
/// <summary>
/// Get process window handles sorted by z order from top to bottom.
/// </summary>
public static IEnumerable<IntPtr> GetWindowsSortedByZOrder()
{
List<IntPtr> handles = new List<IntPtr>();
EnumThreadWindows(GetCurrentThreadId(),
(hWnd, lparam) =>
{
handles.Add(hWnd);
return true;
}, IntPtr.Zero);
return handles;
}
protected override void WndProc(ref Message m)
{
if (m.Msg == (int)WindowsMessages.WM_WINDOWPOSCHANGING)
{
//Looking for Window at the bottom of Z-order, but with TopMostLevel > this.TopMostLevel
foreach (IntPtr handle in GetWindowsSortedByZOrder().Reverse())
{
var window = FromHandle(handle) as BaseForm;
if (window != null && this.TopMostLevel < window.TopMostLevel)
{
//changing hwndInsertAfter field in WindowPos structure
if (IntPtr.Size == 4)
{
Marshal.WriteInt32(m.LParam, IntPtr.Size, window.Handle.ToInt32());
}
else if (IntPtr.Size == 8)
{
Marshal.WriteInt64(m.LParam, IntPtr.Size, window.Handle.ToInt64());
}
break;
}
}
}
base.WndProc(ref m);
}
}
public class FormWithLevel1 : BaseForm
{
public override int TopMostLevel
{
get { return 1; }
}
}
So, FormWithLevel1 will be always over any BaseForm. You can add any number of Z-order Levels. Windows on the same level behave as usual, but will be always under Windows with level Current+1 and over Windows with level Current-1.
Not being familiar to Photoshop CS it is bit hard to know exactly what look and feel you are trying to achieve.
But I would have thought if you created a modeless dialog window as you tool window and you made sure it had the WS_POPUP style then the resulting tool window would not be clipped to the main parent window and Windows would automatically manage the z-Order making sure that the tool window stayed on top of the parent window.
And as the tool window dialog is modeless it would not interfere with the main window.
Managing Window Z-Order Like Photoshop CS
You should create the toolwindow with the image as the parent so that windows manage the zorder. There is no need to set WS_POPUP or WS_EX_TOOLWINDOW. Those flags only control the rendering of the window.
Call CreateWindowEx with the hwnd of the image window as the parent.
In reply to Chris and Emmanuel, the problem with using the owner window feature is that a window can only be owned by one other window, and you can't change who owns a window. So if tool windows A and B always need to be on top of document windows C and D, then when doc window C is active, I want it to own windows A and B so that A and B will always be on top of it. But when I activate doc window D, I would have to change ownership of tool windows A and B to D, or else they will go behind window D (since they're owned by window C). However, Windows doesn't allow you to change ownership of a window, so that option isn't available.
For now I've got it working with the topmost feature, but it is a hack at best. I do get some consolation in the fact that GIMP has tried themselves to emulate Photoshop with their version 2.6, but even their implementation occasionally acts quirky, which leads me to believe that their implementation was a hack as well.
Have you tried to make the tool windows topmost when the main window receives focus, and non-topmost when it loses focus? It sounds like you've already started to look at this sort of solution... but much more elaborate.
As a note, it seems to be quite well documented that tool windows exhibit unexpected behavior when it comes to z-ordering. I haven't found anything on MSDN to confirm it, but it could be that Windows manages them specially.
I would imagine they've, since they're not using .NET, rolled their own windowing code over the many years of its existence and it is now, like Amazon's original OBIDOS, so custom to their product that off-the-shelf (aka .NET's MDI support) just aren't going to come close.
I don't like answering without a real answer, but likely you'd have to spend a lot of time and effort to get something similar if Photoshop-like is truly your goal. Is it worth your time? Just remember many programmers over many years and versions have come together to get Photoshop's simple-seeming windowing behavior to work just right and to feel natural to you.
It looks like you're already having to delve pretty deep into Win32 API functions and values to even glimpse at a "solution" and that should be your first red flag. Is it eventually possible? Probably. But depending on your needs and your time and a lot of other factors only you could decide, it may not be practical.

How to add custom item to system menu in C++?

I need to enumerate all running applications. In particular, all top windows. And for every window I need to add my custom item to the system menu of that window.
How can I accomplish that in C++?
Update.
I would be more than happy to have a solution for Windows, MacOS, and Ubuntu (though, I'm not sure if MacOS and Ubuntu have such thing as 'system menu').
For Windows, another way to get the top-level windows (besides EnumWindows, which uses a callback) is to get the first child of the desktop and then retrieve all its siblings:
HWND wnd = GetWindow(GetDesktopWindow(), GW_CHILD);
while (wnd) {
// handle 'wnd' here
// ...
wnd = GetNextWindow(wnd, GW_HWNDNEXT);
}
As for getting the system menu, use the GetSystemMenu function, with FALSE as the second argument. The GetMenu mentioned in the other answers returns the normal window menu.
Note, however, that while adding a custom menu item to a foreign process's window is easy, responding to the selection of that item is a bit tricky. You'll either have to inject some code to the process in order to be able to subclass the window, or install a global hook (probably a WH_GETMESSAGE or WH_CBT type) to monitor WM_SYSCOMMAND messages.
Once you have another window's top level handle, you may be able to call GetMenu() to retrieve the Window's system menu and then modify it, eg:
HMENU hMenu = GetMenu(hwndNext);
You can use EnumWindows() to enumerate top level Windows.
I don't have a specific answer for the second part of your question, but if you subclass the window, I imagine you can modify the system menu.
EDIT: or do what Chris said: call GetMenu()
Re: the update - please note that not even Microsoft Windows requires windows to have a sytem menu. GetMenu( ) may return 0. You'll need to intercept window creation as well, because each new top window presumably needs it too.
Also, what you propose is rather intrusive to other applications. How are you going to ensure they don't break when you modify their menus? And how are you going to ensure you suppress the messages? In particular, how will you ensure you intercept them before anyone else sees them? To quote Raymond Chen, imagine what happens if two programs would try that.