How to determine if a window handle is the taskbar thumbnail view? - c++

I have a code that gets the window handle that the mouse cursor is pointing at, and I am required to determine if the mouse cursor points at a window that is not a part of the task bar. My code is able to recognize if I'm pointing at the task bar, the start button and the show desktop button (on windows 7). But I am not able to recognize if I'm pointing on the thumbnails view of combined windows (see image below).
This is the code that I use to recognize the task bar:
m_hTaskBar = FindWindow("Shell_TrayWnd", "");
m_hTaskBar = GetAncestor(m_hTaskBar, GA_ROOT);
// This code is at a mouse move event:
POINT p;
GetCursorPos(&p);
HWND hWnd = GetAncestor(WindowFromPoint(p), GA_ROOT);
m_hSelectedWin = hWnd;
bool isTaskBar = m_hSelectedWin == m_hTaskBar || GetParent(m_hSelectedWin) == m_hTaskBar;
How can I check if the cursor points at the thumbnails view of combined windows? Thanks.

I have managed to find a solution:
FindWindow("TaskListThumbnailWnd", "");
I used Spy++ to find the class name of the taskbar thumbnails window.
Spy++ can be used from Visual Studio (Tools > Spy++).

You can also find it through Autohotkey Window Spy.

Related

How do I programmatically maximize a top-level window in a Win32 C++ program?

I'm trying to programmatically maximize my top-level window in my Win32 C++ program. I'm using code similar to the following in the code that handles the WM_CREATE message:
WINDOWPLACEMENT windowPlacement = {};
windowPlacement.length = sizeof(WINDOWPLACEMENT);
windowPlacement.rcNormalPosition = newWindowRect;
windowPlacement.showCmd = SW_NORMAL;
if (maximized == TRUE)
{
windowPlacement.showCmd = SW_SHOWMAXIMIZED;
}
SetWindowPlacement(hwnd, &windowPlacement);
When this code executes, if maximized is TRUE, the window is set to the size of a maximized window, but the maximize/restore button is still a maximize button, not a restore button.
I've tried using the ShowWindow() function with the same results.
It turns out the WM_CREATE message handler was the wrong place to do this. After moving the code out of the window procedure and into the wWinMain() function after the call to CreateWindow() but before the call to ShowWindow(), it works as expected.

C++ Set window below (or above) the icons on the desktop

I'm trying to place a window either above or below the icons on the desktop. I mostly just want it to stay attached to the desktop at all times. Similar to Rainmeter or Wallpaper engine. So far, everything I tried either disables interaction, or gets minimized when you use the "Show Desktop" button. Any ideas on how to achieve this? I'm using electron and a native module in node to do this.
It's an old subject, but I'll find out how to do it recently and answer it.
The method is to find the handle of SHELLDLL_DefView, the parent of the desktop window, and then make the SHELLDLL_DefView handle the parent of my window to fix it to the desktop.
The method is to find the handle of SHELLDLL_DefView, the owner of the desktop window, and then make the SHELLDLL_DefView handle the owner of my window to fix it to the desktop.
SHELLDLL_DefView is located under the Progma or WorkerW handle. This is a code to prevent ShowDesktop from being used in the Electget package created by ffi-napi to attach the Electron browserWindow to the desktop.
const GWLP_HWNDPARENT = -8;
// find SHELLDLL_DefView in Progma
const progman = user32.FindWindowExA(ref.NULL, ref.NULL, 'Progman', ref.NULL);
let defView = user32.FindWindowExA(progman, ref.NULL, 'SHELLDLL_DefView', ref.NULL );
// find SHELLDLL_DefView in WorkerW
if (!defView) {
const desktopHWnd = user32.GetDesktopWindow();
let workerW = 0;
do {
workerW = user32.FindWindowExA(desktopHWnd, workerW, 'WorkerW', ref.NULL);
defView = user32.FindWindowExA(workerW, ref.NULL, 'SHELLDLL_DefView', ref.NULL );
} while (!defView && workerW);
}
if (!defView) return false;
// make the SHELLDLL_DefView handle the parent of my window
user32.SetWindowLongPtrA(hWnd, GWLP_HWNDPARENT, defView);
This allows you to create a window where you can click and interact without being hidden by ShowDesktop.
2022-03-29
There was a wrong word, so I corrected it. According to doc, it is not a parent window, but an owner window. In the doc, it is strange that the GWLP_HWNDPARENT constant is related to the parent window. However, when tested with Spy++, the corresponding constant changes the owner window.

How to detect if any app goes fullscreen or exiting fullscreen?

I need to disable notifications at my app when there is another app fullscreen like powerpoint or VLC to do not bother a user.
For now, I get to this code, but it always returns true. Whether there is some app fullscreen or not. I am not sure whether this should work only for app bars or also taskbar.
HWND hWnd;
hWnd = FindWindow(L"Shell_TrayWnd", nullptr);
if( hWnd )
{
APPBARDATA apd;
apd.cbSize = sizeof(APPBARDATA);
apd.hWnd = hWnd;
bool uState = bool(SHAppBarMessage(ABN_FULLSCREENAPP , &apd));
if(uState)
qDebug()<<"fullscreen";
else
qDebug()<<"not fullscreen";
}
ABN_FULLSCREENAPP is not a message you send to the shell, it's a message the shell sends to you when an application enters or leaves full screen mode. The message is sent to the owner of an app bar created with ABM_NEW.
Documentation is here.
My reading of the documentation is that you have to create an app bar to receive this message but you may be able to set it to zero height or width with ABM_SETPOS if you want to hide it.

c++ attaching to thread (taking focus)

So, (I rewrote this since a lot of people didn't understand me. I apologize.)
I'd like to bring the window of my qt application to the very front of ALL windows on screen.
I've heard you can do this by attaching to the thread of the foreground window and then "stealing focus" aka putting yourself where that foreground window was.
(I'm using OSX, so windows.h is no option for me.)
I hope you understand now.
To bring a window to the front, ensure the window is visible, then activate the window.
As the docs state: -
Sets the top-level widget containing this widget to be the active window.
And
If you want to ensure that the window is stacked on top as well you should also call raise().
So, assuming you have a window called pWindow, you can do something like this: -
pWindow->raise();
pWindow->show();
pWindow->activateWindow();
Also note that OS X can have multiple desktops (Spaces). If you also want the window to track the user's Space when they switch between them, you can add this function to your window class: -
void MyWindow::DisplayOnAllSpaces()
{
// ensure we stay on the active desktop
WId windowObject = this->winId();
objc_object* nsviewObject = reinterpret_cast<objc_object *>(windowObject);
objc_object* nsWindowObject = objc_msgSend(nsviewObject, sel_registerName("window"));
int NSWindowCollectionBehaviorCanJoinAllSpaces = 1 << 0;
objc_msgSend(nsWindowObject, sel_registerName("setCollectionBehavior:"), NSWindowCollectionBehaviorCanJoinAllSpaces);
}

Windows Mobile C++ Tray Icon

I'm trying to place my application that is mainly running in the background in a 'tray-like' area on the Windows Mobile 6.5.
I do it the obvious way by with Shell_NotifyIcon
BOOL ShowTrayIcon(HWND hWnd, HINSTANCE hIns, BOOL bShowIcon)
{
BOOL bRet = FALSE;
g_structNotifyIconData.cbSize = sizeof(NOTIFYICONDATA);
g_structNotifyIconData.hIcon = LoadIcon(hIns, MAKEINTRESOURCE(IDI_GPSCOMPASS));
g_structNotifyIconData.hWnd = hWnd;
g_structNotifyIconData.uCallbackMessage = WM_SYSTRAY_MSG;
g_structNotifyIconData.uFlags = NIF_MESSAGE | NIF_ICON;
g_structNotifyIconData.szTip[0] = 'Bzz';
g_structNotifyIconData.uID = ID_TRAY;
if (bShowIcon)
bRet = Shell_NotifyIcon(NIM_ADD, &g_structNotifyIconData);
else
bRet = Shell_NotifyIcon(NIM_DELETE, &g_structNotifyIconData);
return bRet;
}
This is where i am trying to place the icon :
Tray icon within the 'today' area http://www.fotoszok.pl/upload/666d99dc.jpg
The Shell_NotifyIcon does the thing but the Icon is not shown on the Today screen, i can see it's in the tray from any place except the Today/Home screen.
Now I've read somewhere that this is because the Tray area in Today screen is reserved for system notifications and 'we' can't place any icons in there - well if that's true, can somebody please confirm that?
Indeed, Shell_NotifyIcon doesn't support adding the icon in the Today screen. This is even one of the first things mentioned in the function documentation:
This function sends a message to the system to add, modify, or delete an application-specific icon from the taskbar status area. It does not affect icons appearing on the home screen.
You can try using SHNotificationAdd.