9

我正在尝试制作一个应用程序,在屏幕中心显示十字准线并保持在其他所有内容之上。目的是在一些没有提供十字准线的 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(),以及为什么游戏的行为与普通窗口不同。

提前致谢。

4

3 回答 3

2

我知道这对您没有帮助,但请看一下Raymond Chen 的这篇文章如何创建一个永远不会被其他最顶层窗口覆盖的最顶层窗口?

于 2012-04-18T14:13:11.457 回答
1

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

用于创建、管理和绘制 DirectDraw 覆盖的非托管 C++ 库。包含用于 .NET 客户端的 C++/CLI 包装器。

DirectDraw 覆盖是特殊的 DirectDraw 表面,显示在其他所有内容上,包括全屏游戏和应用程序。它们可用于实现像 XFire 这样在全屏游戏操作期间显示信息的程序。

于 2012-09-07T09:21:02.843 回答
1

SetWindowPos()文档:

可以通过将 hWndInsertAfter 参数设置为 HWND_TOPMOST 并确保未设置 SWP_NOZORDER 标志,或者通过设置窗口在 Z 顺序中的位置,使其位于任何现有的最顶层窗口之上,可以使窗口成为最顶层窗口。当非最顶层窗口成为最顶层时,其拥有的窗口也被置为最顶层。然而,它的所有者并没有改变。

同样来自同一页面:

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

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

于 2012-04-18T13:56:26.210 回答