2012-04-18 8 views
8

Próbuję zrobić aplikację wyświetlającą celownik na środku ekranu i pozostając na szczycie wszystkiego. Celem jest posiadanie krzyżyka w niektórych grach FPS, które go nie oferują. Z powodzeniem uczyniłem moje okno najwyższym z wyjątkiem gier:/Jak ustawić okno na górze wszystkiego (nawet na pełnoekranowe gry!) C++/Qt

Oto mój kod: (wszystko jest w głównej mierze, ponieważ testowałem tylko podstawowe funkcje mojej aplikacji, skomentowałem to szeroko, aby wypróbować i uczynić mój problem bardziej dostępne)

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

Domyślam się, że stosowanie takich jak gry mają bardziej bezpośrednią kontrolę nad urządzeniem wyświetlającym. Poszukuję rozwiązania tego problemu (niekoniecznie takiego, którego dotyczy przezroczyste okno najwyższego poziomu). Również na stronie internetowej, jeśli ktoś mógłby mi wytłumaczyć, jak skutecznie używać GetLastError(), a także dlaczego gra zachowuje się inaczej niż zwykłe okno.

Z góry dziękuję.

+0

+1 dla zaawansowanego technologicznie rozwiązania polegającego na narysowaniu kropki na ekranie, na której znajduje się centrum ironsights: P – Bojangles

+0

Oh! Wiem, że jest to coś niecodziennego. Jest to "ACCESS_DENIED" :(Jest trochę API, aby uzyskać aktualny komunikat o błędzie z numeru GetLastError(), ale na razie zapomniałem. –

+0

Cieszę się, że używa to tagu 'topmost'. :) – unwind

Odpowiedz

1

Z dokumentacji SetWindowPos():

okno może być wykonane z najwyższą okno albo przez ustawienie hWndInsertAfter parametr HWND_TOPMOST i zapewnienie, że flaga SWP_NOZORDER nie jest ustawiony, lub przez ustawienie pozycji oknem w Zlecenie tak, aby było ponad wszystkimi istniejącymi oknami najwyższego poziomu. Gdy najwyżej położone okno zostanie wykonane jako najwyższe, jego własne okna również zostaną wykonane na najwyższym poziomie. Jego właściciele jednak nie są zmienione.

Również z tej samej strony:

Aby korzystać SetWindowPos przynieść okno na górze, proces, który jest właścicielem okno musi mieć SetForegroundWindow zgody.

Jednak sądzę, że link jest dla systemu Windows Vista i nowszych.

1

okazało się, że biblioteka C++ DirectDrawOverlayLib powinien być w stanie to zrobić. Aby zacytować stronę:

Niezarządzana biblioteka C++ do tworzenia, zarządzania i rysowania nakładek DirectDraw. Dołączono opakowanie w języku C++/CLI dla klientów .NET.

Nakładki DirectDraw to specjalne powierzchnie DirectDraw pokazane jako dla wszystkich innych elementów, w tym gier pełnoekranowych i aplikacji. Można ich używać do wdrażania programów takich jak XFire, które wyświetlają informacje podczas pełnoekranowej obsługi gry.

Powiązane problemy