Can I use Find window without using RegisterClass and CreateWindow - c++

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);
}

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.

Programmatically hide an application on windows

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.

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

How do I get a handle to the Start button in Windows 7?

I use:
Hwnd hStart = ::FindWindow ("Shell_TrayWnd",NULL); // get HWND of taskbar first
hStart = ::FindWindowEx (hStart, NULL,"BUTTON", NULL); // get HWND of start button
to get start button's handle. It's running properly on Windows XP,
but in Windows 7, ::FindWindowEx (hStart, NULL,"BUTTON", NULL) always returns 0, and GetLastError() returns 0, too.
Why is that?
In Windows 7 the start button, which has class name "Button", is a child of the desktop window. Your code assumes that the start button is a child of the window named "Shell_TrayWnd" which does indeed appear to be the way the taskbar and start menu were implemented on XP.
For Windows 7 you want to use something like this:
hStart = ::FindWindowEx(GetDesktopWindow(), NULL, "Button", NULL);
Although I think it would be better search for it by name to be sure that you get the right button.
hStart = ::FindWindowEx(GetDesktopWindow(), NULL, "Button", "Start");
I'm not sure how Vista implements its taskbar and start menu, but you can use Spy++ to find out.
Having said all of this, it would be much better if you can find a way to achieve your goals without poking around in such implementation specific details.
::FindWindow (L"Shell_TrayWnd",NULL);
this code is for complete taskbar

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.