Programmatically hide an application on windows - c++

Is there a way to programmatically hide an application on windows? I want to achieve the same thing as the windows+D shortcut, but for a single application. I want to do this from within that application (application consists of several windows, one of those can't be moved, resized, closed or minimized by the user). Application is written in c++ and uses Qt for the UI.

to do so it's so easy:
1- retrieve the handle to that window:
HWND hChild = GetDlgItem(hWnd, ID_MYCHILD);
2- send to it SW_SHOW either using ShowWindow or via SendMessage:
ShowWindow(hChild, SW_HIDE); // hide
ShowWindow(hChild, SW_SHOW); // show
SendMessage(hChild, SW_HIDE, 0, 0); // hide
SendMessage(hChild, SW_SHOW, 0, 0); // show
if the window doesn't belong to your application then:
1 - retrieve the main window with:
HWND hWnd = GetForegroundWindow(void);
2- use the above to hide/show it

ShowWindow(HwndWindow, SW_MINIMIZE);
Here's the MSDN ShowWindow documentation.
In addition you may find EnumChildWindows useful for finding all these windows if their handles aren't readily available to you.

Related

How to remove TOPMOST attribute from a window

I have a Windows C++ app that creates two separate windows
I need to be able to make one window topmost temporarily, and then later remove that attribute so that other windows can then overlay it.
I've tried this code:
void setWindowAlwaysOnTop(const std::string& windowTitle, bool onTop) {
HWND hwnd = FindWindowA(NULL, windowTitle.c_str());
HWND insertAfter;
if (onTop) insertAfter = HWND_TOPMOST; //set the window always-on-top
else insertAfter = HWND_BOTTOM;
SetWindowPos(hwnd, insertAfter, NULL, NULL, NULL, NULL, SWP_NOMOVE | SWP_NOSIZE);
}
But if I have previously called this code with onTop true it doesn't re-allow other windows to overlay the target window after I call it with onTop false.
I've also tried calling the function from the target window itself rather that from a separate window but it still doesn't work.
As far as I can see at https://learn.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setwindowpos it should work?
Is that correct, or is there another way of achieving this?
The documentation link that you provide in the question indicates that you should pass HWND_NOTOPMOST to hWndInsertAfter. Of this flag it says:
Places the window above all non-topmost windows (that is, behind all topmost windows). This flag has no effect if the window is already a non-topmost window.
Use SetWindowLongPtr.
This function will discard your window styles, but u can restore them, like the example
below:
SetWindowLongPtr(hWnd, GWL_STYLE, WS_OVERLAPPEDWINDOW); //Discard WS_EX_TOPMOST
IMPORTANT NOTE:
To write code that is compatible with both 32-bit and 64-bit versions of Windows, use SetWindowLongPtr. When compiling for 32-bit Windows, SetWindowLongPtr is defined as a call to the SetWindowLong function.
Hope this works.

how to make a clickable button in c++ win32

anyone can tell me how to use a bitmap as a button, actually i can create a static control and could set a picture to it but the thing is that i don't know how to use it as a button, i am using c++ win32.
This is how i create the bitmap
Code:
HWND Profile_Stuff(HWND hWnd, HINSTANCE hInst)
{
HWND Profile_Pic;
Profile_Pic = CreateWindow("STATIC", NULL, SS_BITMAP|WS_CHILD|WS_VISIBLE|WS_TABSTOP|WS_BORDER, 5,5,33,33, hWnd, NULL, hInst, NULL);
HBITMAP hBmp = (HBITMAP)LoadImage(NULL, "camera1.jpg", IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
if(hBmp == NULL){
MessageBox(NULL, "Error while loading image", "Error", MB_OK|MB_ICONERROR);
}
SendMessage(Profile_Pic, STM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)hBmp);
return 0;
}
then i call the function in main window wm_create message handler which creates it successfully, now i don't know to use it as a button, like we have a picture of an advertisement at the bottom of bit torrent application.
i am using visual studio c++ with win32 api.
If you want a button control, you should create a button control. The visual representation can be controlled by the application. To do so, specify the BS_OWNERDRAW Button Style. A button control with this style sends a WM_DRAWITEM message to the control parent whenever a visual aspect has changed. The control parent can then render the control as it sees fit.
An introduction to owner-drawn controls is available at Custom Controls. If you wish to retain some parts of the button control (e.g. its border), see Using Visual Styles with Custom and Owner-Drawn Controls for details (or DrawFrameControl if you aren't using Visual Styles).
Fully working sample code for an owner-drawn button control can be found in this answer.
In Windows, the windows belong to a class, a the class defines the windows procedure for all windows of that class, meaning how they react to events.
If you create a STATIC window, it will not react to any click and will not be useable as a button.
You could create a custom class, register it along with a custom windows procedure able to mimic a BUTTON. But unless you have very special requirements just create an owner drawn button as shown in #IInspectable's answer

Window does not get displayed(Maximized) after Minimizing

I have a Windows CE application which logs key strokes of the mobile device. There's a button to initialize the recording functionality, which forces the main window to minimize by calling:
ShowWindow (hWnd, SW_MINIMIZE);
Before minimizing the window, I register to the trigger button event (via a custom API). While the app is minimized I perform some button clicks and press the trigger button to end the session. When I receive the trigger button event, I call:
ShowWindow (hWnd, SW_MAXIMIZE);
The problem is that the window does not get maximized. If I debug the application, I could see that the ShowWindow function is called. I could bring it to the foreground via the TaskManager by switching to the application.
Can someone please explain the cause of this and suggest any solution that I can take?
EDIT:
Solution:
Call "SetForegroundWindow" before calling ShowWindow and use SW_RESTORE instead of SW_MAXIMIZE. SW_MAXIMIZE does not work.
SetForegroundWindow (g_hWndMain);
ShowWindow (g_hWndMain, SW_RESTORE);
Showwindow could fail by several reasons.
You could try:
1) Set foreground
SetForegroundWindow
For WinCE specifically refer to the following MSDN article.
http://msdn.microsoft.com/en-us/library/ms940024.aspx
SetForegroundWindow((HWND)(((ULONG) hwnd) | 0x01) );
2) Bring to front
BringWindowToTop
http://msdn.microsoft.com/en-us/library/ee504610.aspx
Second parameter in ShowWindow(HWND hWnd, int nCmdShow) can take a value:
SW_HIDE, SW_SHOW, SW_SHOWNA, SW_SHOWNORMAL
The last one activates and displays window; it will be restored to its original size and position.
About windows functions in WinCE you can read on MSDN.
Try to first restore window, then maximize.
I don't have Windows CE so can't test, but that should work.
Cheers & hth.,

Can I use Find window without using RegisterClass and CreateWindow

I am trying to bring my running application on click of windows rightclick. Please note I dont want a new instance of the same application but bringing the same application to the front by using SetForegroundWindow
I have tried using AfxRegisterClass and Createwindow (Previos post here) but this creates a new window and onclik bring the new window instead of my current application. Is there a way I can bring up my app instead of newly created window.
Probably better to use mutexes, but yes, you can use FindWindow for that. Something like this:
HWND hwnd = FindWindow(NULL, "My App's Hopefully Unique Title");
if (hwnd)
{
SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
SetFocus(hwnd);
}

Do you have to register a Dialog Box?

So, I am a total beginner in any kind of Windows related programming. I have been playing around with the Windows API and came across a couple of examples on how to initialize create windows and such.
One example creates a regular window (I abbreviated some of the code):
int WINAPI WinMain( [...] )
{
[...]
// Windows Class setup
wndClass.cbSize = sizeof( wndClass );
wndClass.style = CS_HREDRAW | CS_VREDRAW;
[...]
// Register class
RegisterClassEx( &wndClass );
// Create window
hWnd = CreateWindow( szAppName, "Win32 App",
WS_OVERLAPPEDWINDOW,
0, 0, 512, 384,
NULL, NULL, hInstance, NULL );
[...]
}
The second example creates a dialog box (no abbreviations except the WinMain arguments):
int WINAPI WinMain( [...] )
{
// Create dialog box
DialogBox(hInstance,
MAKEINTRESOURCE(IDD_MAIN_DLG),
NULL,
(DLGPROC)DialogProc);
}
The second example does not contain any call to the register function. It just creates the DialogBox with its DialogProc process attached.
This works fine, but I am wondering if there is a benefit of registering the window class and then creating the dialog box (if this is at all possible).
You do not have to register a dialog box.
Dialog boxes are predefined so (as you noted) there is no reference to a window class when you create a dialog. If you want more control of a dialog (like you get when you create your own window class) you would subclass the dialog which is a method by which you replace the dialogs window procedure with your own. When your procedure is called you modify the behavior of the dialog window; you then might or might not call the original window procedure depending upon what you're trying to do.
It's been a while since I've done this, but IIRC, the first case is for creating a dialog dynamically, from an in-memory template. The second example is for the far more common case of creating a dialog using a resource. The dynamic dialog stuff in Win32 was fairly complex, but it allowed you to create a true data-driven interface, and avoid issues with bundling resources with DLLs.
As for why use Win32 - if you need a windows app and you don't want to depend on MFC or the .NET runtime, then that's what you use.