WWW.ИСХОДНИКИ.РУ cpp.sources.ru
java.sources.ru web.sources.ru soft.sources.ru
jdbc.sources.ru asp.sources.ru api.sources.ru

  Форум на исходниках
  C / C++ / Visual C++
  хендл консольного окна

СПРОСИТЬ  ОТВЕТИТЬ
профайл | регистрация | faq

Автор Тема:   хендл консольного окна
FtoR опубликован 26-03-2001 15:51 MSK   Click Here to See the Profile for FtoR   Click Here to Email FtoR  
Господа, подскажите чайнику, как узнать хендл консольного окна, хотя бы в 9x.
Функция API: GetConsoleTitle возвращает 0 при любом запущенном консольном приложении и название консольного окна не получается найти. (насколько я знаю в NT/2000 так определить хендл консоли не удается, но там есть свои недокументированные функции, которые позволяют теоретически (сам не пробовал) определить хендл.
С уважением, FtoR

OlegN опубликован 27-03-2001 12:32 MSK     Click Here to See the Profile for OlegN  Click Here to Email OlegN     
Пример из MSDN-а (сам не проверял)

The following function retrieves the current console application window handle (HWND). If the function succeeds, the return value is the handle of the console window. If the function fails, the return value is NULL. Some error checking is omitted, for brevity.


HWND GetConsoleHwnd(void)
{
#define MY_BUFSIZE 1024 // Buffer size for console window titles.
HWND hwndFound; // This is what is returned to the caller.
char pszNewWindowTitle[MY_BUFSIZE]; // Contains fabricated
// WindowTitle.
char pszOldWindowTitle[MY_BUFSIZE]; // Contains original
// WindowTitle.

// Fetch current window title.

GetConsoleTitle(pszOldWindowTitle, MY_BUFSIZE);

// Format a "unique" NewWindowTitle.

wsprintf(pszNewWindowTitle,"%d/%d",
GetTickCount(),
GetCurrentProcessId());

// Change current window title.

SetConsoleTitle(pszNewWindowTitle);

// Ensure window title has been updated.

Sleep(40);

// Look for NewWindowTitle.

hwndFound=FindWindow(NULL, pszNewWindowTitle);

// Restore original window title.

SetConsoleTitle(pszOldWindowTitle);

return(hwndFound);
}

FtoR опубликован 27-03-2001 17:20 MSK     Click Here to See the Profile for FtoR  Click Here to Email FtoR     
Спасибо OlegN, но самая заморочка и заключается в том, что именно весь этот код (я решил не писать его весь) НЕ ОТРАБАТЫВАЕТ. То есть там и идет как раз вот эта первая функция поиска заголовка (GetConsoleTitle(pszOldWindowTitle, MY_BUFSIZE)) консольного окна, которая по идее должна отрабатывать, но она возвращает 0. Я просто в недоумении, почему и решил посовещаться.
OlegN опубликован 27-03-2001 17:39 MSK     Click Here to See the Profile for OlegN  Click Here to Email OlegN     
А что возвращает GetActiveWindow(
?
FtoR опубликован 27-03-2001 18:47 MSK     Click Here to See the Profile for FtoR  Click Here to Email FtoR     
Самое интересное, что GetActiveWindow возвращает хендл обычного окна, ИЗ КОТОРОГО СОЗДАЕТСЯ ОКНО КОНСОЛИ. (По-видимому это связано с тем, что вызов CreateProcess осущетвляется в одной из функций окна!)

Может быть траблы с поиском хендла консольного окна и возникают, потому что я создаю его с помощью CreateProcess из обычного окна и вызываю досовский экзешник(батник)?
Потому как это созданное окно консоли не находится даже с помощью FindWindow. Проверил потоки, процесс, связанный с консольным окном (это PROCESS_INFORMATION СТРУКТУРА в CreateProcess - вроде бы есть...)
Возможно, что я где-то ошибаюсь при создании, но где пока понять не могу.
P.S.
Кстати хендл консольного окна нужен для перевода его в полноэкранный режим.

aldep опубликован 29-03-2001 02:14 MSK     Click Here to See the Profile for aldep  Click Here to Email aldep     
В голову приходит такой алгоритм. Дожен работать под 9x и 200. У тебея есть handle процесса. Вызываешь Thread32First, Thread32Next смотришь все нити принадлежащие данному процессу. И для каждой вызвать EnumThreadWindows. У консольного приложения как я понял одно окно. Поэтому первое найденное - твое.
FtoR опубликован 29-03-2001 09:46 MSK     Click Here to See the Profile for FtoR  Click Here to Email FtoR     
Tnanx, aldep, а то я уже РЕАЛЬНО запарился и начал делать вызов консоли через динамически создаваемый shortcut к батнику.
Flex Ferrum опубликован 29-03-2001 16:21 MSK     Click Here to See the Profile for Flex Ferrum  Click Here to Email Flex Ferrum     
Фишка вся в том, что даже если ты получишь хендл консольного окна, в полноэкранный режим ты его не переведешь. В свое время я сталкивался с такой проблемой, и едиственное решение, которое я смог найти (работающее на всех платформах) - запускать прогу через заранее созданный pif файл со всеми необходимыми настройками. Между прочим, наименее геморойное решение.
aldep опубликован 30-03-2001 02:10 MSK     Click Here to See the Profile for aldep  Click Here to Email aldep     
Кстати, если несложно, FtoR напиши, как в итоге реализовал все это.
FtoR опубликован 30-03-2001 10:27 MSK     Click Here to See the Profile for FtoR  Click Here to Email FtoR     
Господа, взгляните на ЭТО.

Q> Как переключить консоль в полный экран и обратно?
A> (c)1999 Ashot Oganesyan K, SmartLine, Inc mailto:ashot@aha.ru

Когда Вы запускаете свое приложение в консольном окне Вы можете нажать ALT+ENTER для переключения консоли в полный экран.Но нет документированных функций,чтобы сделать это.Однако Windows9X посылает сообщение WM_COMMAND со специальным идентификатором,когда пользователь нажимает ALT+ENTER:

#define ID_SWITCH_CONSOLEMODE 0xE00F
Для переключения режимов Вы можете использовать ф-ию SendMessage:
SendMessage(hWnd,WM_COMMAND,ID_SWITCH_CONSOLEMODE,0);

Однако это не работает в Windows NT/2000.
Windows NT/2000 содержит две недокументированные функции,которые
позволяют нам добраться до консольного окна:

BOOL SetConsoleDisplayMode (
HANDLE hOut, // standard output handle
DWORD dwNewMode, // specifies the display mode
LPDWORD lpdwOldMode, // address of variable for previous value of display mode
);

BOOL GetConsoleDisplayMode (
LPDWORD lpdwMode, // address of variable for current value of display mode
);

Эти функции экспортируются Kernel32.dll, но Kernel32.lib их не содержит.
Поэтому мы вынуждены использовать функцию GetProcAddress:

typedef BOOL (WINAPI *PROCSETCONSOLEDISPLAYMODE)(HANDLE,DWORD,LPDWORD);
typedef BOOL (WINAPI *PROCGETCONSOLEDISPLAYMODE)(LPDWORD);

PROCSETCONSOLEDISPLAYMODE SetConsoleDisplayMode;
PROCGETCONSOLEDISPLAYMODE GetConsoleDisplayMode;

HMODULE hKernel32 = GetModuleHandle("kernel32");

SetConsoleDisplayMode = (PROCSETCONSOLEDISPLAYMODEELLWND)
GetProcAddress(hKernel32,"SetConsoleDisplayMode");

GetConsoleDisplayModeplayMode = (PROCGETCONSOLEDISPLAYMODE)
GetProcAddress(hKernel32,"GetConsoleDisplayMode");

HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);

DWORD dwOldMode;
SetConsoleDisplayMode(hOut,1,&dwOldMode);
---------------------------------------------

Теперь насчет реализации.
1) До запуска CreateProcess, с целью уменьшения геморроя, создаю батник с двумя символами (это твоя идея Flex Ferrum) "%1", потом ДИНАМИЧЕСКИ (с помощью апишной ShellLink, тоже неочевидно сразу, если нужен код, пишите), создаю ярлык к этому батнику, далее, есс-но запускаю уже досовский бат-файл (или экзешник, без разницы), передавая его в качестве параметра созданному pif-файлу.
2) Реально столкнулся к совершенно НЕОЧЕВИДНОЙ проблемой даже при реализации этого метода. Оказывается при динамическом создании ярлыка к досовскому объекту, мы не можем программно установить параметры этого ярлыка (закрывать окно после завершения работы, полноэранный режим и т.д.). В в MS хеадер-файле shlobj.h нашел НЕДОКУМЕНТИРОВАННЫЕ структуры в духе NT_CONSOLE_PROPS, которые по видимому являюся заготовками, т.к. нигде не используются (их наполнения в духе BOOL bFullScreen или QuickMode дают нам понять, что это и есть нам нужные свойства pif-файлов). Вот так.
Поэтому для изменения свойств pif-файла планирую просто править его байты программно.
3) 2 aldep. Идея с нитями не прошла. Thread есть, а окон, ему принадлежащих НЕТ!! Ноль на выходе EnumThreadWindows и все...

Flex Ferrum опубликован 30-03-2001 13:37 MSK     Click Here to See the Profile for Flex Ferrum  Click Here to Email Flex Ferrum     
А зачем ты pif-файл создаешь динамически? Вариант с заранее подготовленным (буквально, сделанном руками в эксплорере) в твоем случае не применим? Я в свое время как-раз по такому пути и пошел: руами создал pif, включил в дистрибутив - и больше никаких проблем не испытывал - работало везде и на ура.
FtoR опубликован 30-03-2001 14:22 MSK     Click Here to See the Profile for FtoR  Click Here to Email FtoR     
Просто, как мне кажется, в программе все должно быть универсально или, по крайней мере, мы должны стремиться к универсальности. Взял кто-то, особо одаренный и любознательный, снес pif, к примеру, и все, программулина загнулась. Кстати, таким образом, еще и приобретаются столь необходимые и подчас очень нужные знания. Например, до этого я совершенно ничего не знал о динамическом создании ярлыков.
Flex Ferrum опубликован 02-04-2001 12:01 MSK     Click Here to See the Profile for Flex Ferrum  Click Here to Email Flex Ferrum     
А с другой стороны, кому какая разница, что там в рабочей директории программы лежит? С таким же успехом можно пришибить и сам экзешник (за ненадобностью :)). И никакая универсальность не поможет. :)) Ну а насчет приобретения знаний - это ты кончено прав. Только вот не всегда врямя позволяет производить подобные "раскопки". К тому же, универсальность не всегда достигается путем использования недокументированных фичей.
FtoR опубликован 02-04-2001 13:33 MSK     Click Here to See the Profile for FtoR  Click Here to Email FtoR     
Да, я вообщем-то, забыл подчеркнуть одну важную деталь. Сама програмка ориентирована на пользователей (то есть ни о каких дистрибутивах речи не идет, думаю, что таких прог навалом, в осбенности маленьких по размеру) и поэтому для ее распространения удобно использовать "голый" экзешник, который сам за себя все "творит". А то, что можно грохнуть рабочую директорию -согласен :))

СПРОСИТЬ  ОТВЕТИТЬ
Перейти:


E-mail | WWW.ИСХОДНИКИ.RU

Powered by: Ultimate Bulletin Board, Freeware Version 5.10a
Purchase our Licensed Version- which adds many more features!
© Infopop Corporation (formerly Madrona Park, Inc.), 1998 - 2000.