2012-04-18 24 views
8

Estoy tratando de hacer que una aplicación muestre una cruz en el centro de la pantalla y esté al tanto de todo lo demás. El objetivo es tener una cruz en algunos juegos de FPS que no proporciona uno. He hecho con éxito mi ventana más alta para todo, excepto los juegos:/Cómo hacer que una ventana aparezca encima de todo (incluso juegos de pantalla completa) C++/Qt

Aquí está mi código: (todo está en general ya que solo estoy probando las funciones principales de mi aplicación, lo he comentado extensamente para probar y hacer que mi problema sea más accesible)

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

mi conjetura es que la aplicación tales como juegos tienen un control más directo sobre el dispositivo de visualización. Estoy buscando alguna solución a este problema (no necesariamente uno que implica una ventana superior transparente). También en una nota al margen si alguien podría explicarme cómo usar efectivamente GetLastError(), y también por qué los juegos se comportan de manera diferente a una ventana común.

Gracias de antemano.

+0

+1 para una solución de alta tecnología para dibujar un punto en la pantalla donde se encuentra el centro de mirillas: P – Bojangles

+0

¡Oh! Lo sé uno por descuido. Es 'ACCESS_DENIED' :(Hay alguna API para obtener el mensaje de error real del número GetLastError(), pero lo he olvidado por ahora. –

+0

Me gusta que esto use la etiqueta 'topmost'. :) – unwind

Respuesta

1

Desde el SetWindowPos() documentación:

Una ventana se puede hacer una ventana superior, ya sea estableciendo el parámetro hWndInsertAfter a HWND_TOPMOST y la garantía de que la bandera SWP_NOZORDER no está establecido, o mediante el establecimiento de la posición de una ventana en el orden Z para que esté encima de cualquier ventana superior existente. Cuando una ventana no superior se hace más arriba, sus propias ventanas también se hacen más arriba. Sus dueños, sin embargo, no han cambiado.

También desde la misma página:

Para utilizar SetWindowPos para traer una ventana a la parte superior, el proceso que posee la ventana debe tener permiso SetForegroundWindow.

Sin embargo, supongo que el enlace es para Windows Vista y superior.

1

me encontré con que la biblioteca de C++ DirectDrawOverlayLib debe ser capaz de hacer esto. Para citar el sitio web:

Una biblioteca C++ no administrada para crear, administrar y dibujar sobre superposiciones DirectDraw. Se incluye un contenedor C++/CLI para clientes .NET.

Las superposiciones DirectDraw son superficies DirectDraw especiales que se muestran sobre todo lo demás, incluidos los juegos y aplicaciones de pantalla completa. Se pueden usar para implementar programas como XFire que muestran información durante el funcionamiento del juego en pantalla completa.

Cuestiones relacionadas