SetWindowPos doesn't work with put_Visible(false) - c++

I am trying to use SetWindowPos to put a new opened IE window in the background.
The problem is that it only works after I use put_Visible(VARIANT_TRUE). While the window is not visible, SetWindowPos won't do anything. If I use put_Visible(VARIANT_TRUE) before SetWindowPos this makes the window to appear on top for a second, and then go to the back.
How can I avoid this and make the new window appear in the background without appearing first on top?
Here is what I tried:
HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE
using put_Visible(VARIANT_TRUE) before SetWindowPos, and then it works, but it shows on top of all windows before going to the back.

Related

BringWindowToTop is not working in the ActiveX control

I have designed activeX control which consist of one editbox and one combobox.
I am trying to place the editbox over combobox so that whenever the user select any item from the combobox it should sit to the editbox. So my editbox should coveringup combobox'edit portion and only the arrow button is visible for the combobox.
Isuue: Whenever I am trying to move my mouse cursor over that control the combobox is coming front of editbox.I have made the design such as editbox is just covering up the combobox but only when the focus goes back to combobox and that is taking the combobox front.
Tried Approaches: In one of the my defined function I tried all the below function to make edit box over the combobox.
1)BringWindowToTop
2)SetForegroundWindow
3)SetWindowPos
My code for that Function:
void DetermineWindowsShown()
{
m_edit.EnableWindow(m_bEnabled);
m_combo.EnableWindow(m_bEnabled);
//here only I tried all the diff function
m_edit.BringWindowToTop();
//m_edit.SetForegroundWindow();
//m_combo.SetWindowPos(&CWnd::wndBottom ,0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
}.
I am calling DetermineWindowsShown many places so that always editbox is above the combobox.
BringWindowToTop is usually for MDI windows. SetForegroundWindow is for main window.
You should be able to use SetWindowPos, apply it to both, not just one:
m_combo.SetWindowPos(&CWnd::wndBottom, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
m_edit.SetWindowPos(&CWnd::wndTop, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);

Why HWND_NOTTOPMOST cannot bring the window foreground in xp?

I am using
SetWindowPos(m_hParsent, HWND_NOTOPMOST, 0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE)
to bring the window foreground, but it does not work in XP System, it work well in my win7.
HWND_NOTOPMOST doesn't move a window to the foreground per-se, it simply removes the topmost status from a window that has it, and a side effect of this is that the window will be left above other non-topmost windows. But the docs also say "This flag has no effect if the window is already a non-topmost window."
Use HWND_TOP to specifically move a window to the top of the z-order, or call SetForegroundWindow.

How to set window position to locate it to the top of the screen on MFC?

I'm trying to set position of new dialog in MFC, what i do:
SetWindowPos(&this->wndTopMost, 0,0,0,0, SWP_NOSIZE);
in the InitDialog() of this window, but after execution, this window appears on center of my screen... What am i doing wrong?
I'm not seeing anything wrong, I've used this as
Can you please try this with minor modification
::SetWindowPos(this->wndTopMost->GetSafeHwnd(), HWND_TOPMOST, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
or
this->wndTopMost.SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
Found solution!
When i set x = 0 and y = 0 in my case (Win7) window always appears in the center of the screen. Like if decart system...
But when i changed it.. to (1200, 0) it appears in the top right corner, just like i need to... do not know how it connected, but thanks all of you, who helped me.
Question: How to set window position to locate it to the top of the screen on MFC?
If you don't want to move the location of the window nor do you want to resize it;
SetWindowPos(&CWnd::wndTopMost, 0 , 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
If you call it inside a window/dialog, no :: prefix is needed since we can use MFC's version of the function

How to bring other app window to front without activating it?

I want to bring to front a window(from other application). Currently I'm using:
::SetWindowPos(hwnd, GetForegroundWindow(), 0, 0, 0, 0, SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
It works fine, but in some (unknown to me) cases, it makes the window always on top. According to MSDN, I should use HWND_NOTOPMOST in the place of GetForegroundWindow() but it doesn't work—the window stays under other (not always on top) windows.
How can I bring a window to the front without activating it?
The other application's window can be made temporarily 'top-most' to bring it to front without activating it, first by specifying HWND_TOPMOST as 'hWndInsertAfter' in a SetWindowPos call and then by specifying HWND_NOTOPMOST in a second call (both calls with SWP_NOACTIVATE in 'uFlags'). If there's a risk of removing the top-most style of a window which is already top-most as a consequence of the operation, the WS_EX_TOPMOST ex-style can be tested beforehand with a call to GetWindowLong[Ptr].
If there's a particular window that the other application's window need to be in front (as opposed to being in front of all windows), that window's owner can be set, again temporarily, to the window it needs to be in front. GetWindowLong[Ptr] with GWL_HWNDPARENT can be used to store the window's original owner, then a call to SetWindowLong[Ptr] to set the temporary owner, followed by a call to SetWindowPos with HWND_TOP, and then restoring the original owner with again SetWindowLong[Ptr].

Win32: Bring a window to top

I have a Windows program which has two 2 windows in it:
hwnd (main interface)
hwnd2 (toplevel window, no parent, created by hwnd)
When I double click on hwnd, I need hwnd2 to pop up and show some data, so I use this function to bring hwnd2 to top:
BringWindowToTop(hwnd2);
hwnd2 is brought to top, but there is one thing odd. When I click on hwnd2 again, hwnd (main interface) pops itself up again automatically.
I tried to use the following function to solve this problem, but non of them works.
SetWindowPos(hwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
//doesn't work
BringWindowToTop(hwnd2); //This is the function brings hwnd2 to top
SetForegroundWindow(hwnd2); //doesn't work
SetWindowPos(hwnd2, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
//doesn't work
SetWindowPos(hwnd2, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
// hwnd2 "always" on top, not what I want
SetActiveWindow(hwnd2); // doesn't work too (for replying to Magnus Skog, thanks)
SwitchToThisWindow(hwnd2, TRUE);// got the same problem with BringWindowToTop function
SwitchToThisWindow(hwnd2, FALSE);
How could I solve this problem?
Thanks in advance.
(for replying to aJ, hwnd2 doesn't have parent because it needs to be a toplevel window so it can be in front/back of other windows)
(hwnd2 is a media player which is composed of several windows, one of the windows is for video dispaly, two other trackbar controls for progress bar and volume bar, one Toolbar control for control panel.)
(There is one this might help, no matter which window I click on hwnd2, hwnd pops up automatically as loong as "the mouse is on top of hwnd in Z-order", including menu bar and non-client area, etc.)
(This media player is writen in Direct Show. I use IVideoWindow::put_Owner to put video window as the video owner, Direct Show internally creates a sub-video window as a child of the video window. Except for this sub-video window which I can't see the source code, I don't see any thing suspicious in hwnd2.)
I found the reason, which is because of Direct Show. I use multithread to execute it, and then the problem's solved. But...why??
This problem can be resolved by using PostMessage (rather than SendMessage).
try this,it is said coming from M$
HWND hCurWnd = ::GetForegroundWindow();
DWORD dwMyID = ::GetCurrentThreadId();
DWORD dwCurID = ::GetWindowThreadProcessId(hCurWnd, NULL);
::AttachThreadInput(dwCurID, dwMyID, TRUE);
::SetWindowPos(m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
::SetWindowPos(m_hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE);
::SetForegroundWindow(m_hWnd);
::SetFocus(m_hWnd);
::SetActiveWindow(m_hWnd);
::AttachThreadInput(dwCurID, dwMyID, FALSE);
In order to bring a window to top, you should get your window handle,thread handle, the windows thread handle who is in foreground
then we attach our thread to foreground window thread and get input by AttachThreadInput, then we set our window z order
to topmost and then restore its z order to normal, call SetForegroundWindow,SetFocus,SetActiveWindow to make sure our window is brought to top and is active and have focus
then deattach the input queue from the old foreground window thread, make our thread the only one who capture the input events
So why should We call AttachThreadInput, it is because
SetFocus sets the keyboard focus to the specified window. The window must be
attached to the calling thread's message queue.
What does AttachThreadInput do?
The AttachThreadInput function can be used to allow a set of threads
to share the same input state. By sharing input state, the threads
share their concept of the active window. By doing this, one thread
can always activate another thread's window. This function is also
useful for sharing focus state, mouse capture state, keyboard state,
and window Z-order state among windows created by different threads
whose input state is shared.
We use SetWindowPos to bring the windows to topmost and show the window if the window is hidding by using SWP_HIDEWINDOW
SetWindowPos function changes the size, position, and Z order of a
child, pop-up, or top-level window. These windows are ordered
according to their appearance on the screen. The topmost window
receives the highest rank and is the first window in the Z order
If your problem is your window is also minimized , you should add one line code to the end
ShowWindow(m_hWnd, SW_RESTORE);
Both work great:
::SetForegroundWindow(wnd)
or
::SetWindowPos(m_hWnd, // handle to window
HWND_TOPMOST, // placement-order handle
0, // horizontal position
0, // vertical position
0, // width
0, // height
SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE// window-positioning options
);
But remember that the last one sets the window always on top.
After many tries and errors.I found following solution to this problem:
SendMessage(hwnd, WM_SYSCOMMAND, SC_RESTORE, 0); // restore the minimize window
SetForegroundWindow(hwnd);
SetActiveWindow(hwnd);
SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
//redraw to prevent the window blank.
RedrawWindow(hwnd, NULL, 0, RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN );
The hwnd is your windows HWND . Please do not just copy and paste. You also need use GetLastError to check api error after every api call.
I have confirm following result on my win7:
Can restore minimize window and no error return.
If the window already top, the window title will blink and no error return.
If the window has closed, it will return the error "0x578 Invalid window handle."
It can bring the window to the top on all not top-most window and no error return.(For example it will behind the top-most taskmanager)
It do not make the window top-most. The user can make other window on top of it.
SwitchToThisWindow works best for me.
Have you tried SetActiveWindow()?
This will restore an app if minimized and bring it to the front:
ShowWindow(hWnd, SW_SHOW);
SetForegroundWindow(hWnd);
//work great!
Var
WndHandle:HWND;
begin
WndHandle :=FindWindowEx(0,0,nil,'Calculator');
PostMessage(WndHandle,WM_SHOWWINDOW,SW_RESTORE,0);
SetForegroundWindow(WndHandle);
end;