Is it possible create MFC form that cold stay on the top of all applications on PC not allowing to do anything else without entering required information.
Win32 doesn't support system-modal dialogs any more, as far as I'm aware. This is a relic from 16 bit Windows versions.
You can try yourself with a MB_SYSTEMMODAL type MessageBox.
Closest thing would be to utilize a screen-sized window to display a dimmed desktop background while your dialog is shown. This simulates the behaviour of the user account control -- except that you still can switch tasks.
You can obtain something similar setting your window on "TopMost". You can do it on property sheet in design mode, or programmatically with this line:
SetWindowPos( pWnd->m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE );
Hope this will fit your needs.
Related
I know this sounds evil but my intention is not this at all.
A user has clicked "delay shot" and a countdown starts, during that time they go focus another application, then after countdown user expects my app to take back focus.
SetForegroundWindow fails when it runs from appliction with PID X while application with PID Y is focused.
This worked to bring my window forward, but it doesn't get focus:
SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
It sets the window to be always on top. However focus is not put into my window. And then setting it back to HWND_NOTOPMOST leaves it there, even though its not top most, but it still doesnt have focus. Running SetForegroundWindow won't do the trick after these calls to SetWindowPos Is there anyway to steal focus?
I have tried a combination of:
SwitchToThisWindow
SetWindowPos
ShowWindow
SetForegroundWindow
But can't seem to figure it out.
Another reason I think this has to be possible is because Mac OSX allows it with NSApplication activateIgnoringOtherApps: and Linux's allow it too. I'd like to get this cross platform.
As a last resort I was going to use the HWND_TOPMOST method, then GetWindowRect then SetCursorPos and send single click to my window at pos 0,0, I really don't want to though as there might be something at 0,0 and it shouldn't be auto clicked on.
This always works, no matter what app is in foreground (like Task Manager, etc.):
AllocConsole();
auto hWndConsole = GetConsoleWindow();
SetWindowPos(hWndConsole, 0, 0, 0, 0, 0, SWP_NOZORDER);
FreeConsole();
SetForegroundWindow(hWnd);
As the comment says, SetForegroundWindow is sometimes useless intentionally. Basically, two ways are used to bypass restrictions:
Simulate keyboards / mouses
Get privileges
There is some smarter magic to achieve the goal without directly clicking the window you are going to activate. Since I'm not familiar with GUI, I would suggest inject code directly into current foreground window and hand over the foreground right.
Besides there're some examples on simulating.
http://www.codeproject.com/Tips/76427/How-to-bring-window-to-top-with-SetForegroundWindo.aspx
SetWindowPos(hwnd, hWndTopMost, 0, 0,
Screen.PrimaryScreen.Bounds.Size.Width,
Screen.PrimaryScreen.Bounds.Size.Height,
SWP_NOOWNERZORDER);
This is my code to display my form full screen and at the top, but when I am inducing alt+ctrl+delete, the task manager is activated at the back of this form even though my form is not active. I understand by the colour of caption bar. This problem is only occuring in win8 os. I want to display the task manager which is active but without losing the properties of my app like hooking. How can I achieve it by changing the flags of the above?
You can't achieve it with documented WinAPI functions.
The Task Manager in Windows 8 uses an undocumented method in order to become on top of all windows, including the top-most ones.
Specifically, it uses the CreateWindowInBand WinAPI function to achieve the effect.
I'm writing a Windows application in Visual C++ 2008 and I want to embed the calculator (calc.exe) that comes with Windows in it. Does anyone know if that is possible, and if it is, can you give me hints on how I could achieve that?
Yes, it's possible to embed the calc in your own application but it will still run in it's own process space. There may also be some restrictions imposed by UAC but that will depend on how calc is launched. All you need to do is change the parent of the main calc window and change it's style to WS_CHILD.
void EmbedCalc(HWND hWnd)
{
HWND calcHwnd = FindWindow(L"CalcFrame", NULL);
if(calcHwnd != NULL)
{
// Change the parent so the calc window belongs to our apps main window
SetParent(calcHwnd, hWnd);
// Update the style so the calc window is embedded in our main window
SetWindowLong(calcHwnd, GWL_STYLE, GetWindowLong(calcHwnd, GWL_STYLE) | WS_CHILD);
// We need to update the position as well since changing the parent does not
// adjust it automatically.
SetWindowPos(calcHwnd, NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
}
}
Microsoft has various technologies to support embedding, most famously OLE which is a COM-based technology. This is, for example, how you can embed an Excel spreadsheet in your application. However, I'm fairly certain that calc does not implement any of the required interfaces for that to happen.
So that only leaves you with hacky solutions, like trying to launch it yourself and play games with the window hierarchy, or try to present it to users and then copy the results out through the clipboard, etc. This is all technically possible, but not a good idea. In fact, it's probably more difficult than just writing your own calculator app... depending on what you want to to enable users to do. If you explain why you want to do this someone may have some better solutions to propose.
I am having trouble with SetWindowPos failing to bring windows of external processes to the top of the z-order reliably. I am able to bring windows to the front like:
NativeMethods.SetWindowPos(hwnd, new IntPtr(-1), Left, Top, Width, Height, 0x10);
NativeMethods.SetWindowPos(hwnd, new IntPtr(-2), Left, Top, Width, Height, 0x10);
It doesn't work 100% of the time though. After some reading, I found a few things.
SetWindowPos documentation states:
To use SetWindowPos to bring a window to the top, the process that owns the window must have SetForegroundWindow permission.
An article on MSDN then states
A process that is started with UIAccess rights has the following abilities:
* Set the foreground window.
AllowSetForeground mentions
The calling process must already be able to set the foreground window
I have signed my .exe and enabled UIAccess so that I can set the foreground window like so in my manifest:
<requestedExecutionLevel level="highestAvailable" uiAccess="true" />
My program starts and I get the UAC prompt asking for permission. I then test for UIAccess, admin rights, and TokenElevationType. The first 2 return true, and the 3rd returns TokenElevationTypeFull. I still run into the same problems though with my new code though.
My code is:
uint processid=0;
NativeMethods.GetWindowThreadProcessId(hwnd, out processid);
NativeMethods.AllowSetForegroundWindow((int)processid);
NativeMethods.SetWindowPos(hwnd, IntPtr.Zero, Left, Top, Width, Height, 0x10);
NativeMethods.RedrawWindow(hwnd, IntPtr.Zero, IntPtr.Zero, NativeMethods.RedrawWindowFlags.Erase | NativeMethods.RedrawWindowFlags.Invalidate | NativeMethods.RedrawWindowFlags.NoChildren);
NativeMethods.RedrawWindow(hwnd, IntPtr.Zero, IntPtr.Zero, NativeMethods.RedrawWindowFlags.Erase | NativeMethods.RedrawWindowFlags.Invalidate | NativeMethods.RedrawWindowFlags.UpdateNow | NativeMethods.RedrawWindowFlags.AllChildren);
What you want to do is contrary to the (complicated) rules Windows has in place to prevent badly-behaved programs from wresting control away from the user. (Control doesn't just mean input focus, but also control of what's visible and what's not.) Although your intentions may be aligned with the user's, what you're asking for is indistinguishable from what disruptive programs often try to do.
There are alternative ways to signal the user that non-foreground windows need attention. Check out FlashWindowEx, for example. You might also consider a tray icon that pops notification balloons. These seem like they'd be appropriate and effective solutions.
I'm writing a small Windows application in Visual C++ without MVC. Its really small, it just contains one textfield, an OK-Button and an Cancel-Button.
The application is started by a background-process when user starts printing. When opening the application doesn't get focus, isn't even visible.
For the user it's importend that the application is directly in focus, so they have as lease clicks as possible to use it.
I tried many many things to get the application in focus:
SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
SetForegroundWindow(hWnd);
ShowWindow(hWnd, SW_RESTORE);
SetFocus(hWnd);
I even repeated this calls in a timer. All of this doesn't work. Now I found some remarks on MSDN:
The system restricts which processes can set the foreground window. A
process can set the foreground window only if one of the following
conditions is true:
The process is the foreground process.
The process was started by the foreground process.
The process received the last input event.
There is no foreground process.
The foreground process is being debugged.
The foreground is not locked (see LockSetForegroundWindow).
The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo).
No menus are active.
Anybody knows a workaround for this?
There is no workaround for this. The whole point of this new Windows behavior is to prevent applications from bringing themselves to the foreground on their own and being a nuisance. In your case, I would suggest using a notification icon and showing a balloon message when necessary instead of a window. However, even in this case your notification icon can be hidden by the user and there is no workaround, for the same reason as above.
Now, this is coming from a Java developer and not a Visual C++ developer, but can you maybe set the frame/window/whatever-its-called-in-visual-c to be always on top? In Java, if you have a JFrame, say myJFrame, you can call myJFrame.setAlwaysOnTop(true) and it stays on top of all other windows. This seems to be a simple workaround to your problem, however it may not be desirable for the user if it's blocking something of theirs on screen.
http://www.thescarms.com/vbasic/alttab.aspx seems to do the job
void forceToFront(HWND hWnd) {
HWND foregroundWindow = GetForegroundWindow();
if (foregroundWindow == hWnd) {
// Window is already Foreground-window
return;
}
if (SetForegroundWindow(hWnd)) {
// could set window to foreground without any tricks
return;
}
// attach thread of foreground-window to this window
DWORD foregroundThread = GetWindowThreadProcessId(foregroundWindow, NULL);
DWORD myThread = GetWindowThreadProcessId(hWnd, NULL);
AttachThreadInput(foregroundThread, myThread, true);
SetForegroundWindow(hWnd);
AttachThreadInput(foregroundThread, myThread, false);
}