2012-04-18 20 views
8

Tôi đang cố gắng tạo một ứng dụng hiển thị hình chữ thập ở giữa màn hình và luôn cập nhật mọi thứ khác. Mục đích là để có một crosshair trong một số trò chơi FPS mà không cung cấp một. Tôi đã tạo thành công cửa sổ ở trên cùng cho mọi thứ ngoại trừ các trò chơi:/Cách tạo cửa sổ xuất hiện trên đầu mọi thứ (ngay cả trò chơi toàn màn hình!) C++/Qt

Đây là mã của tôi: (tất cả mọi thứ là chính vì tôi chỉ thử nghiệm các chức năng chính của ứng dụng, tôi đã nhận xét nó rộng rãi để thử và làm cho vấn đề của tôi dễ truy cập hơn)

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

Tôi đoán là ứng dụng như trò chơi có quyền kiểm soát trực tiếp hơn thiết bị hiển thị. Tôi đang tìm bất kỳ giải pháp cho vấn đề này (không phải là một trong những cần thiết liên quan đến một cửa sổ trên cùng trong suốt). Cũng trên một sidenote nếu ai đó có thể giải thích cho tôi làm thế nào để sử dụng hiệu quả GetLastError(), và cũng tại sao trò chơi hoạt động khác với một cửa sổ chung.

Xin cảm ơn trước.

+0

+1 cho giải pháp công nghệ cao để vẽ một chấm trên màn hình có trung tâm ironsights: P – Bojangles

+0

Oh! Tôi biết rằng một trái tim. Đó là 'ACCESS_DENIED': (Có một số API để nhận được thông báo lỗi thực tế từ số GetLastError(), nhưng tôi đã quên nó ngay bây giờ. –

+0

Tôi thích điều này sử dụng thẻ 'topmost'. :) – unwind

Trả lời

1

Từ các tài liệu SetWindowPos():

Một cửa sổ có thể được thực hiện một cửa sổ topmost hoặc bằng cách thiết lập hWndInsertAfter tham số để HWND_TOPMOST và đảm bảo rằng lá cờ SWP_NOZORDER không được thiết lập, hoặc bằng cách thiết lập vị trí của một cửa sổ trong đơn đặt hàng Z để nó ở trên bất kỳ cửa sổ trên cùng nào hiện có. Khi một cửa sổ không phải là trên cùng của cửa sổ được tạo ở trên cùng, các cửa sổ được sở hữu cũng được thực hiện trên cùng. Chủ sở hữu của nó, tuy nhiên, không thay đổi.

Cũng từ cùng một trang:

Để sử dụng SetWindowPos để mang lại một cửa sổ để phía trên, quá trình mà sở hữu cửa sổ phải có sự cho phép SetForegroundWindow.

Tuy nhiên, tôi đoán liên kết dành cho Windows Vista trở lên.

1

tôi phát hiện ra rằng C++ thư viện DirectDrawOverlayLib sẽ có thể làm được điều này. Để trích dẫn trang web:

Thư viện C++ không được quản lý để tạo, quản lý và vẽ lớp phủ DirectDraw. A Trình bao bọc C++/CLI cho các máy khách .NET được bao gồm.

Lớp phủ DirectDraw là các bề mặt DirectDraw đặc biệt được hiển thị trên mọi thứ khác, bao gồm trò chơi và ứng dụng toàn màn hình. Chúng có thể được sử dụng để triển khai các chương trình như XFire hiển thị thông tin trong khi hoạt động trò chơi toàn màn hình.

Các vấn đề liên quan