如何使窗口出现在所有内容之上(甚至是全屏游戏!)c ++ / Qt

时间:2012-04-18 13:47:10

标签: c++ qt topmost

我正在尝试使应用程序在屏幕中央显示十字准线并保持其他所有内容。 目的是在一些没有提供的FPS游戏中使用十字准线。 除了游戏之外,我已经成功地将窗口放在最顶层:/

这是我的代码:(一切都在主要,因为我只测试我的应用程序的核心功能,我已经广泛评论它试图让我的问题更容易访问)

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

我的猜测是游戏等应用程序可以更直接地控制显示设备。 我正在寻找这个问题的任何解决方案(不是一个涉及透明的最顶层窗口的问题)。 另外,如果有人可以向我解释如何有效地使用GetLastError(),以及为什么游戏的行为与普通窗口的不同,也会在旁边。

提前致谢。

3 个答案:

答案 0 :(得分:2)

我知道这对你没有帮助,但请看看Raymond Chen的this postHow do I create a topmost window that is never covered by other topmost windows?

答案 1 :(得分:1)

来自SetWindowPos()文档:

  

通过设置窗口,窗口可以成为最顶层的窗口   hWndInsertAfter参数到HWND_TOPMOST并确保   未设置SWP_NOZORDER标志,或者通过设置窗口的位置   Z顺序,使其高于任何现有的最顶层窗口。当一个   非最顶层的窗户是最顶层的,它也拥有自己的窗户   最上面。但是,它的所有者没有改变。

同样来自同一页:

  

使用SetWindowPos将窗口置于顶部,即进程   拥有该窗口必须具有SetForegroundWindow权限。

但是,我猜这个链接适用于Windows Vista及更高版本。

答案 2 :(得分:1)

我发现c ++库DirectDrawOverlayLib应该能够做到这一点。引用网站:

  

用于创建,管理和绘制DirectDraw叠加层的非托管C ++库。一个   包含了.NET客户端的C ++ / CLI包装器。

     

DirectDraw叠加层是显示的特殊DirectDraw表面   其他一切,包括全屏游戏和应用程序。   它们可用于实现在全屏游戏操作期间显示信息的XFire等程序。