Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a window appear on top of everything (even full screen games!) c++/Qt

Tags:

c++

qt

topmost

I'm trying to make an application displaying a crosshair at the center of the screen and staying on top of everything else. The aim is to have a crosshair in some FPS games that doesn't provide one. I've succesfully made my window topmost for everything except the games :/

Here is my code : (everything is in the main since im only testing the core functionalitys of my app, I've commented it extensively to try and make my problem more accessible)

QApplication app(argc, argv);

DWORD error;
QWidget window;
QLabel *label = new QLabel(&window);
label->setText("<strong>O<strong>");//I'm using an "O" as a crosshair until I can figure out how to display image transparency.
window.setGeometry(960-label->width()/2,540-label->height()/2,label->width(),label->height());//here I'm making my window appear in the center of my screen
window.setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);// here making the window frameless and topMost via qt
window.setAttribute(Qt::WA_TranslucentBackground);//making the window see through
window.setWindowTitle("Crosshair");
window.show();

//in this next part I tried using windows api to make my window appear on top of the game.
HWND handle, myHandle;
myHandle = FindWindow(NULL,TEXT("Crosshair"));//retieving my own application window handle
if(myHandle == 0){cout << "no own handle" << endl;}//it successfully retrieves it

handle = FindWindow(NULL,TEXT("Killing Floor"));//retrieving a game window handle
if(handle == 0){cout << "no KF handle" << endl;}//it successfully retrieves it

if(handle != 0 && myHandle != 0)
{
    if(SetWindowPos(handle,myHandle,0,0,0,0,SWP_NOSIZE | SWP_NOMOVE) == 0){cout << "couldnt set notopmost" << endl;}//here SetWindowPos returns 0 (function failed)
}
          // I've also tried using SetWindowPos to set the game to Not TOPMOST, it didnt work either.
          // here was my code : SetWindowPos(handle, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);

error = GetLastError();// i tried using GetLastError to understand what was happening
cout << error << endl;// but it only returns "5", I've read that you can look in WINNT.H for information about the meanings of error codes
                      // however its a pretty big file and I wasn't able to understand where the relevant part was.


return app.exec();

My guess is that application such as games have a more direct control over the display device. I'm looking for any solution to this problem (not neccesseraly one involving a transparent topmost window). Also on a sidenote if someone could explain to me how to effectively use GetLastError(), and also why are game behaving differently than a common window.

Thanks in advance.

like image 727
pogdhu Avatar asked Apr 18 '12 13:04

pogdhu


People also ask

How do you put a window on top of a game?

To make the active window always on top, press Ctrl + Spacebar (or the keyboard shortcut you assigned). Press the keyboard shortcut again to disable “always on top” for the active window. For script options, right-click on the AutoHotkey icon in the system tray.

How do I pin a window to a fullscreen game?

Click the icon in your taskbar, and the mouse icon turns into a small, red pin. Pin your window or program by clicking on the top portion of the window. A small, red pin icon appears in the title bar of the pinned window to show its status.

How do I get my game to open full screen?

To get full-screen mode while playing games, you can try the combination of ALT + Enter keys on the keyboard. It will switch you from windowed to full-screen mode. Pressing the same key again will switch you back to the windowed mode.


2 Answers

I know this doesn't really help you, but please have a look at this post from Raymond Chen: How do I create a topmost window that is never covered by other topmost windows?

like image 137
Stefan Avatar answered Sep 27 '22 20:09

Stefan


From the SetWindowPos() documentation:

A window can be made a topmost window either by setting the hWndInsertAfter parameter to HWND_TOPMOST and ensuring that the SWP_NOZORDER flag is not set, or by setting a window's position in the Z order so that it is above any existing topmost windows. When a non-topmost window is made topmost, its owned windows are also made topmost. Its owners, however, are not changed.

Also from the same page:

To use SetWindowPos to bring a window to the top, the process that owns the window must have SetForegroundWindow permission.

However, I guess the link is for Windows Vista and above.

like image 30
Donotalo Avatar answered Sep 27 '22 19:09

Donotalo