mam pytanie jak zmienić rozmiar okna konsoli z poziomu kodu w c++ i jak sprawdzic aktywnocs okna konsoli czy jest aktywne chodzi o to jak klikniesz na konsolowe okno to czy jest aktywne a poza oknem gdzies inaczej po za oknem ze jest nie aktywne
korzystaj z biblioteki Windows API:
https://cpp0x.pl/dokumentacja/WinAPI/Konsola/1038
GetConsoleScreenBufferInfo - Zawiera informacje o buforze ekranu konsoli.
https://learn.microsoft.com/en-us/windows/console/getconsolescreenbufferinfo?redirectedfrom=MSDN
SetConsoleWindowInfo - Ustawia rozmiar i pozycję okna bufora ekranu konsoli
https://learn.microsoft.com/en-us/windows/console/setconsolewindowinfo?redirectedfrom=MSDN
dokumentacje nie zawsze zawiera przykłady użycia, więc szukaj na Stack Overflow , GitHub czy wspomagaj się Ai
znam troche angielski ale to mi za bardzo nie pomaga nie moge sobie z tym faq poradzić , mozna prosic na jakims przykladzie w c++
Nie jestem pewny, czy w Windows to da się zrobić z identycznym skutkiem, ale w Linux i MacOS można to zrobić, jednak sam program obsługujący konsolę musi to obsługiwać.
Tu masz wszystkie komendy standardu VT100/ANSI/XTERM służące do współpracy z konsolą w Linux i MacOS X, w Windows 11 chyba też, ale pewności nie mam.
https://invisible-island.net/xterm/ctlseqs/ctlseqs.html
W Twoim przypadku potrzebne będą komendy XTWINOPS która umożliwia odczytanie i zmienianie właśnie wielkości okna, położenia okna, minimalizacji i przywracania. Będa też potrzebne komendy DECSET i DECRST w celu włączenia obsługi myszki (o ile pamiętam, są trzy tryby). W ramach obsługi myszki można też wychwycić zmianę aktywności/nieaktywnosci okna, czyli kazda aktywacja lub deaktywacja powoduje wysyłanie komendy do programu na standardowe wejście.
Komenda to jest ciąg tekstowy, który rozpoczyna się od bajtu 0x1B i wypuszczasz na standardowe wyjście. W przypadku komend żądających informacji z konsoli, odpowiedź należy odczytać ze standardowego wejścia.
Jest taki program VTTEST, który w w przypadku Linux można zainstalować za pomocą apt install vttest
, a w przypadku Windows można zainstalować po zainstalowaniu pakietu cygwin. Program VTTEST umożliwia przetestowanie działania wielu komend terminala, między innymi powyższych, czyli obsługa myszki, ustawianie i odczyt stanu okna. Musisz to sprawdzić, bo nie każda apka konsoli/terminala to obsługuje.
Jeżeli w konsoli u Ciebie będzie to działać, to już masz "z górki", ale jak nie będzie działać, to zrobienie tego, co chcesz będzie problematyczne i prawdopodobnie nie będzie możliwe zastosowanie rozwiązań niezależnych od systemu operacyjnego.
W rozdziale "Mouse Tracking" są opisane wszystkie tryby współpracy standardowej konsoli z myszką. Czy będzie to działać, musisz sprawdzić sam, najprościej programem VTTEST.
ja tego nie rozumiem, czy to są takie funkcje proceduralne jak w BASIC'u? jak tam wywołać procedure w c++ i pozyskać właściwe dane? moze jakis przyklatd w c++ , przecież to prawie wygląda jak assembler.te komendy.
Oto jak sprawdzić, czy okno konsoli jest aktywnym oknem:
#include <stdio.h>
/* To musi być na początku programu, żeby korzystać z WinAPI */
#define _WIN32_WINNT 0x0500
#include <windows.h>
/*-----------------------------------------------------------*/
/* Funkcja sprawdzająca, czy okno konsoli jest aktywne */
int aktywne () {
return GetForegroundWindow () == GetConsoleWindow ();
}
/*-----------------------------------------------------*/
int main () {
if (aktywne ())
puts ("Okno konsoli jest aktywne.");
else
puts ("Okno konsoli nie jest aktywne.");
puts ("Co bedzie za 5 sekund?");
Sleep (5000); /* Czekanie 5 sekund, żebyś zdążył uczynić okno
aktywnym lub nie i zauważył różnicę. */
if (aktywne ())
puts ("Okno konsoli jest teraz aktywne.");
else
puts ("Okno konsoli jest teraz nieaktywne.");
return 0;
}
don't like it ? remove all >>>
Natomiast zmienić rozmiary okna można tak:
#include <stdio.h>
#include <stdlib.h> /* Ze względu na funkcję system */
int main () {
/* Ustaw rozmiar okna.
Na systemach innych niż Windows nic nie rób. */
#ifdef _WIN32
system ("MODE 50,30"); /* 50 kolumn, 30 wierszy */
#endif
puts ("Rozmiar okna zostal zmieniony.");
return 0;
}
Testowane.
zrobiłęm poprawke tej funkcji poniewaz były błędy takie:
C:\projekty\konsola\konsola.cpp(9) : error C2065: 'GetConsoleWindow' : undeclared identifier
C:\projekty\konsola\konsola.cpp(9) : error C2446: '==' : no conversion from 'int' to 'struct HWND__ *'
Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast
C:\projekty\konsola\konsola.cpp(9) : error C2040: '==' : 'struct HWND__ *' differs in levels of indirection from 'int'
Error executing cl.exe.
HWND aktywne ()
{
return GetForegroundWindow ();
}
bool done=false;
do
{
cout << int(aktywne()) << endl;
}while(!done);
teraz opowiada wartosciami dwoma rodzajami i jednak rzeczywiscie reaguje
A masz tę linijkę #define _WIN32_WINNT 0x0500
nad #include <windows.h>
. Ona jest ważna, żeby była dostępna funkcja GetConsoleWindow
.
wilkwielki napisał(a):
HWND aktywne () { return GetForegroundWindow (); }
Ta funkcja nie ma sensu.
cout << int(aktywne()) << endl;
HWND jest rozmiaru wskaźnika, czyli jest 64-bitowe na 64-bitowych systemach, a ty rzutujesz na 32-bitowego inta, w efekcie patrząc tylko na połowę bitów uchwytu.
mam #define _WIN32_WINNT 0x0500 oraz #include <windows.h> i nic, ten sam błąd
Daj pełny kod, całego programu. Tak będzie najszybciej.
wilkwielki napisał(a):
ja tego nie rozumiem, czy to są takie funkcje proceduralne jak w BASIC'u? jak tam wywołać procedure w c++ i pozyskać właściwe dane? moze jakis przyklatd w c++ , przecież to prawie wygląda jak assembler.te komendy.
CSI to jest sekwencja znaków 0x1B i '['. Przykłady wywołania kilku komend (angielski opis skopiowany wprost z https://invisible-island.net/xterm/ctlseqs/ctlseqs.html więc wystarczy wyszukać ten opis, żeby trafić na daną komendę w tym dokumencie):
// Use All Motion Mouse Tracking, xterm
// Włączanie obsługi myszki w trybie śledzenia wszystkich zdarzeń
std::cout << (char)0x1B << "[?1003h";
// Od tej chwili, każde zdarzenie (klikniecie, przeciągnięcie, przejazd nad konsolą) wysyła komendę ze strony klienta. Opisane w dokumencie lub do wypróbowania w programie VTTEST.
// Don't use All Motion Mouse Tracking, xterm
// Wyłączenie obsługi myszki w trybie śledzenia wszystkich zdarzeń, od tej komendy konsola przestaje rejestrować zdarzenia myszki
std::cout << (char)0x1B << "[?1003l";
// Send FocusIn/FocusOut events, xterm
// Włącza rejestrowanie aktywacji i deaktywacji okna, co pozwala śledzić, czy w danym momencie okno konsoli jest aktywne
std::cout << (char)0x1B << "[?1004h";
// Po powyższej komendzie, obsługujące ją okno konsoli, wysyła na standardowe wejście następujące sekwencje:
// (char)0x1B + "[I" - każdorazowo przy aktywacji okna (kliknięcie myszką konsoli, wywołanie jej za pomocą alt+tab)
// (char)0x1B + "[O" - każdorazowo przy deaktywacji okna (wywołanie dowolnego innego okna lub pulpitu)
// Don't send FocusIn/FocusOut events, xterm
// Ta komenda wyłącza wysyłanie informacji od konsoli przy aktywacji i deaktywacji okna.
std::cout << (char)0x1B << "[?1004l";
// Resize the text area to given
// Zmiana rozdzielczości konsoli na 80 kolumn i 24 wierszy
std::cout << (char)0x1B << "[8;24;80t";
// Report the size of the text area in characters
// Sprawdzenie rozdzielczości konsoli
// 1. Wysyłanie żądania
std::cout << (char)0x1B << "[18t";
// 2. Odczytanie odpowiedzi - piszę w dużym uproszczeniu, prawidłowo, to należy czytać znak po znaku, każda odpowiedź rozpoczyna się od znaku 0x1B i kończy się literą.
std::string Resp = "";
std::cin >> Resp;
// 3. Odpowiedź powinna mieć postać "[8;24;80t" w przypadku konsoli 80x25
// De-iconify window.
// Przywołanie zminimalizowanego okna
std::cout << (char)0x1B << "[1t";
// Iconify window.
// Minimalizowanie okna konsoli
std::cout << (char)0x1B << "[2t";
// Report xterm window state
// Sprawdzenie, czy okno jest widoczne, czy zminimalizowane
std::cout << (char)0x1B << "[11t";
// Możliwe są dwie odpowiedzi:
// (char)0x1B + "[1t" --> Okno widoczne
// (char)0x1B + "[2t" --> Okno zminimalizowane
Tak, jak pisałem wcześniej, komendy wysyła się na standardowe wyjście (std::cout
lub printf
), a w przypadku, gdy komenda jest żądaniem informacji z konsoli, to odpowiedź należy odczytać ze standardowego wejścia (std::cin
lub scanf
). Podobnie, informacje generowane z inicjatywy konsoli (zmiana aktywności okna i zdarzenia myszki pod warunkiem, że generowanie tych informacji jest załączone) będą wprowadzane na standardowe wejście i należy je stamtąd odczytywać za pomocą std::cin
lub scanf
lub dowolnych innych poleceń umożliwiających odczytywanie standardowego wejścia znak po znaku.
Jednak przede wszystkim, zainstaluj sobie VTTEST (w Linux za pomocą apt
, w Windows po zainstalowaniu pakietu Cygwin) i sprawdź, czy konsola reaguje na zmianę wielkości okna, bo jak pisałem, nie każda aplikacja obsługująca konsolę obsługuje wszystkie komendy. Jeżeli okaże się, że nie obsługuje, a implementujesz pod Windows, to pozostają sposoby proponowane przez innych w tym wątku.
Aby uzmysłowić, jak te komendy zastosować, najprościej zrobić plik o takiej zawartości wyrażonej w hex:
1B 5B 38 3B 33 36 3B 35 30 74
Jako ASCII będzie to znak 0x1B i potem [8;36;50t
. Jest to komenda zmiany wielkości okna konsoli na 50x36.
Po zapisaniu tego jako KonsolaTest.bin
, w Linux wystarczy odpalić cat KonsolaTest.bin
, w Windows type KonsolaTest.bin
. To jest dokładnie to samo, jakbyś wypisał zawartość pliku w swoim programie za pomocą std::cout
lub printf
. Jeżeli konsola obsługuje komendy XTWINOPS, to po tej czynności, wielkość konsoli powinna zmienić się na 50 kolumn po 36 wierszy. Właśnie sprawdziłem i w Linux jest tak:
-
gnome-terminal
- działa bezwarunkowo. -
xterm
- działa pod warunkiem włączenia opcji Allow Window Ops w menu. -
konsole
- nie działa.
Co do Windows i innych programów konsoli, to nie wiem, nie sprawdzałem, może nawet to zależy od wersji OS, może w Powershell inaczej, a w cmd będzie inaczej, sprawdzisz sam.
Na Windows o wiele prościej użyć WinAPI, niż instalować specjalną powłokę, żeby obsługiwała te kody.
Zarejestruj się i dołącz do największej społeczności programistów w Polsce.
Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.