Как визуализировать только в верхней части окнаC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Как визуализировать только в верхней части окна

Сообщение Anonymous »

По сути, я написал этот код, который создает прозрачное наложение поверх любой игры, одинакового размера и в том же месте.
Если я сверну игру, она перестанет рендериться, и это идеально. Однако, если я переключаю окна, не сворачивая игру, визуализируемый текст продолжает отображаться.
Я решил эту проблему, сделав созданное окно дочерним элементом игры, но это остановило работу функции «сквозного щелчка», предоставляемой атрибутом WS_EX_TRANSPARENT.
Как я могу сделать так, чтобы он отображался только поверх игры, даже если я открываю другое окно поверх игры?

введите описание изображения здесь - здесь работает хорошо

введите здесь описание изображения - если меня нет в окне игры, текст все равно отобразится
#include
#include
#include
using namespace std;

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){
switch(msg)
{
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);

// pintamos todo de negro (osea transparente)
HBRUSH brush = CreateSolidBrush(RGB(0,0,0));
FillRect(hdc, &ps.rcPaint, brush);
DeleteObject(brush);

// todo el renderizado va entre estas dos lineas //

HWND cs2 = FindWindowA(NULL, "Counter-Strike 2");
HWND overlay = FindWindowA("carloslorcas", NULL);

LPCSTR output = "carlos lorcas presente";

if(GetForegroundWindow() == overlay){
TextOutA(hdc, 30, 50, output, strlen(output));
}

// todo el renderizado va entre estas dos lineas //
EndPaint(hwnd, &ps);
return 0;
}

case WM_DESTROY:
PostQuitMessage(0);
return 0;
}

return DefWindowProc(hwnd, msg, wParam, lParam);
}

int main(){
HWND hwnd = FindWindowA(NULL, "Counter-Strike 2");

if(hwnd == NULL){
printf("no se pudo encontrar la ventana correctamente");
}
else{
printf("se encontro la ventana correctamente");
}

DWORD pid; GetWindowThreadProcessId(hwnd, &pid);

if(pid == 0){
printf("el pid no se pudo encontrar correctamente");
}
else{
printf("\nse encontro el pid: %i", pid);
}

RECT rect;
if(GetWindowRect(hwnd, &rect) == 0){
printf("\nhubo un error encontrando las dimensiones de la ventana");
}
else{
printf("\nse encontraron las dimensiones de la ventana del juego correctamente");
}

int width = rect.right - rect.left;
int height = rect.bottom - rect.top;;

printf("\nwidth: %i, height: %i", width, height);

//////////////////////////////////////////////////////////////////////////////////
////////////// creating window here! /////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

// aca definimos la clase
HINSTANCE hInstance = GetModuleHandle(NULL);
WNDCLASSEXW wc = {0};
wc.cbSize = sizeof(WNDCLASSEX);
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.lpszClassName = L"carloslorcas";

if (!RegisterClassExW(&wc)) {
printf("\nerror registrando clase: %lu\n", GetLastError());
return 0;
}

HWND window = CreateWindowExW(
// hacemos que la ventana sea layered ya que esto permite que tenga transparencia
WS_EX_TRANSPARENT |WS_EX_LAYERED, /*para que la ventana sea transparente y este encima de todas, para usar WX_EX_TOPMOST usar SetWindowPos. para lograr transparencia sin restricciones usar SetWindowRgn.*/
L"carloslorcas",
L"OVERLAY",
WS_POPUP , /*para ser transparente tiene que ser popup, asi no tendra bordes*/ // puede ser que si es popup y no dibujas nada, no se muestre absolutamente ninguna ventana
rect.left,
rect.top,
width,
height,
NULL,
NULL,
hInstance,
NULL
);

// aclaracion:
// por alguna razon aunque la documentacion de windows dice que las cosas son opcionales, bueno
// no lo son
// TENES que crear una clase, si no no se va a llamar a "WndProc", que es la funcion que maneja los eventos (no, la documentacion tampoco te avisa que tenes que usar esto)

if(!window){
printf("\nerror creando ventana");
//return 0;
}

ShowWindow(window, SW_SHOW);
UpdateWindow(window);
SetLayeredWindowAttributes(window, RGB(0,0,0), 0, LWA_COLORKEY); // todo lo que sea negro sera invisible // nos sirve para hacer que la ventana sea transparente pero no lo que dibujemos en ella
InvalidateRect(window, NULL, TRUE); // actualiza el texto constantemente

while(true){
MSG Msg;
while (PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}

GetWindowRect(hwnd, &rect);

SetWindowPos(
window,
HWND_TOPMOST,
rect.left,
rect.top,
width,
height,
SWP_SHOWWINDOW | SWP_ASYNCWINDOWPOS
);
}
return 0;
}


Подробнее здесь: https://stackoverflow.com/questions/798 ... f-a-window
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»