Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2008.05.18;
Скачать: [xml.tar.bz2];

Вниз

Обработка сообщений (WM_SYSCOMMAND) в консольном приложении   Найти похожие ветки 

 
kernel ©   (2008-04-08 19:12) [0]

Обычно все это делается циклом с TranslateMessage, DispatchMessage. Но в данном случае, программа не стоит на месте, а все время выполняет какие-то действия, следуя пользовательским требованиям, т.е. никаких циклов нет. Собстно вопрос: как еще можно задействовать обработку WM_SYSCOMMAND в консольке?


 
Palladin ©   (2008-04-08 19:19) [1]

создать окно и цикл обработки сообщений. у консольного приложения нет понятия оконных сообщений. на то оно, понимаишь, и консольное.


 
kernel ©   (2008-04-08 19:31) [2]

В приложении используются SysUtils, Windows. Возможно ли создать невидимое окно без подключения других юнитов? Вообще мне это нужно, чтобы во время работы консольки не появился screensaver :)


 
Palladin ©   (2008-04-08 19:42) [3]

А для этого достаточно почитать про SystemParametersInfo


 
kernel ©   (2008-04-08 19:53) [4]

Выключать \ Включать заставку? Но ведь неизвестно каким способом пользователь выйдет из программы, т.е. если я отключу заставку, мне нужно будет при выходе из программы вернуть все на место - а этого может и не произойти.


 
Семеныч   (2008-04-08 19:57) [5]

kernel ©   (08.04.08 19:31) [2]

> В приложении используются SysUtils, Windows. Возможно ли создать
> невидимое окно без подключения других юнитов?

Еще Messages - и создавайте на здоровье. Размер программы это не увеличит.


 
Palladin ©   (2008-04-08 20:02) [6]

:) а по этому поводу смотри SetConsoleCtrlHandler


 
palva ©   (2008-04-08 20:26) [7]

Окно можно не создавать. Но нужно периодически опрашивать очередь сообщений. Проще всего это сделать в отдельном потоке.


 
palva ©   (2008-04-08 22:37) [8]

palva ©   (08.04.08 20:26) [7]
Например, так:

{$APPTYPE CONSOLE}
uses Windows, Messages;
var
 th, tid: DWORD;
 w: Integer;
function treadfun(p: Pointer): DWORD; stdcall;
var
 Msg: TMsg;
begin
 PeekMessage(Msg, 0, 0, 0, PM_NOREMOVE);
 while True do begin // Этот цикл будет висеть и ждать сообщений
   GetMessage(Msg, 0, 0, 0);
   WriteLn("Echo wParam: ", Msg.wParam);
   if Msg.wParam = 999 then break;
 end;
 Result := 0
end;

begin // основной поток посылает сообщения
 th := CreateThread(Nil, 0, @treadfun, Nil, 0, tid);
 Sleep(500);
 WriteLn("Input wParam (999 for ending)");
 while True do begin
   ReadLn(w);
   PostThreadMessage(tid, WM_SYSCOMMAND, w, 0);
   if w = 999 then break;
 end;
 WriteLn("Press "Enter" for ending");
 ReadLn
end.


 
Игорь Шевченко ©   (2008-04-08 22:51) [9]


> Собстно вопрос: как еще можно задействовать обработку WM_SYSCOMMAND
> в консольке?


Собстна, встречный вопрос - а кто их, сообщения, посылать-та будет ?


 
kernel ©   (2008-04-10 20:02) [10]

Вообще я думал перехватить WM_SYSCOMMAND для предотвращения запуска ScreenSaver. Но видимо у меня это не получится без окна :/


 
Palladin ©   (2008-04-10 22:26) [11]


> kernel ©   (10.04.08 20:02) [10]

ты издеваешься?


 
kernel ©   (2008-04-11 10:11) [12]


> Palladin ©   (10.04.08 22:26) [11]
>
>
> > kernel ©   (10.04.08 20:02) [10]
>
> ты издеваешься?


Почему ?)
Вариант с SystemParametersInfo мне не подходит либо я что-то не допонимаю :)


 
Palladin ©   (2008-04-11 10:13) [13]


> Вариант с SystemParametersInfo мне не подходит либо я что-
> то не допонимаю :)

почему не подходит? если по причине в kernel ©   (08.04.08 19:53) [4], то я тебе же написал Palladin ©   (08.04.08 20:02) [6], все просто как банан.


 
kernel ©   (2008-04-11 11:23) [14]

А разве SetConsoleCtrlHandler обрабатывает не только CTRL+C & CTRL+BREAK ?


 
Palladin ©   (2008-04-11 11:30) [15]

а ты справку то читал?


 
kernel ©   (2008-04-11 11:42) [16]

Читал, именно оттуда у меня почему-то сложилось впечатление, что kernel ©   (11.04.08 11:23) [14]


 
Palladin ©   (2008-04-11 11:45) [17]

Ты какую то странную справку читал. Или ты дальше SetConsoleCtrHandler не читал? Там еще есть описание HandlerRoutine, ты это не читал? Или читал, но не проникнулся?


 
Palladin ©   (2008-04-11 11:48) [18]

Кстати невижу там ничего такого, что указывает на обработку только Ctrl-C&Ctrl-Break. А в самом конце remarks еще много чего написано... в общем так и скажи, что не читал ничего...


 
kernel ©   (2008-04-11 11:51) [19]

CTRL_C_EVENT A CTRL+C signal was received, either from keyboard input or from a signal generated by the GenerateConsoleCtrlEvent function.
CTRL_BREAK_EVENT A CTRL+BREAK signal was received, either from keyboard input or from a signal generated by GenerateConsoleCtrlEvent.
CTRL_CLOSE_EVENT A signal that the system sends to all processes attached to a console when the user closes the console (either by clicking Close on the console window"s window menu, or by clicking the End Task button command from Task Manager).
CTRL_LOGOFF_EVENT A signal that the system sends to all console processes when a user is logging off. This signal does not indicate which user is logging off, so no assumptions can be made.
CTRL_SHUTDOWN_EVENT A signal that the system sends to all console processes when the system is shutting down.
Note that this signal is received only by services. Interactive applications are terminated at logoff, so they are not present when the system sends this signal. Services also have their own notification mechanism for shutdown events. For more information, see Handler.


Какой из них то? :)


 
kernel ©   (2008-04-11 11:52) [20]


> Кстати невижу там ничего такого, что указывает на обработку
> только Ctrl-C&Ctrl-Break. А в самом конце remarks еще много
> чего написано... в общем так и скажи, что не читал ничего.
> ..

Скорее

> Или читал, но не проникнулся


 
Palladin ©   (2008-04-11 11:52) [21]


> kernel ©   (11.04.08 11:51) [19]

какой из них что?


 
kernel ©   (2008-04-11 12:18) [22]

Каждый консольный процесс имеет свой собственный список функций-обработчиков, которые вызываются системой, когда происходят определенные события, например при активном окне консоли пользователь нажимает комбинации клавиш Ctrl+C, Ctrl+Break или Ctrl+Close. При запуске консольного приложения список функций-обработчиков содержит только заданную по умолчанию функцию-обработчик, которая вызывает функцию ExitProcess. Консольный процесс может добавлять или удалять дополнительные функции-обработчики, вызывая функцию SetConsoleCtrlHandler.
B00L SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine. B00L Add): Данная функция имеет два параметра:
HandlerRoutine — указатель на определенную приложением функцию HandlerRoutine, которая должна быть добавлена или удалена;
Add — логическое значение, которое означает: 1 — функция должна быть
добавлена, 0 — функцию необходимо удалить.

Функция HandlerRoutine — это определенная приложением функция обратного вызова. Консольный процесс использует эту функцию, чтобы обработать нажатия клавиш управления. На самом деле HandlerRoutine — идентификатор-заполнитель для определенного приложением имени функции. B00L WINAPI HandIerRoutine(DWORD dwCtrlType):
Параметр DwCtrlType определяет тип сигнала управления, получаемого обработчиком. Этот параметр может принимать одно из следующих значений:
CTRL_C_EVENT=O — сигнал, имитирующий нажатие клавиш Ctrl+C, может быть получен из двух источников: с клавиатуры или как сигнал, сгенерированный функцией GenerateConsoleCtrl Event;
CTRL_BREAK_EVENT=1 — сигнал имитирующий нажатие клавиш Ctrl+Break, может быть получен из двух источников: с клавиатуры или как сигнал, сгенерированный функцией GenerateConsoleCtrl Event;
CTRL_CL0SE_EVENT=2 — сигнал, который система посылает всем процессам, подключенным к данному консольному приложению, когда пользователь его закрывает (либо выбирая пункт Close в системном меню окна консоли, либо щелкая на кнопке завершения задачи в диалоговом окне Менеджера задач);
CTRL_LOGOFF_EVENT=5 — сигнал, который посылается всем консольным процессам, когда пользователь завершает работу в системе (этот сигнал не указывает, какой именно пользователь завершает работу);
CTRL_SHUTD0WN_EVENT=6 — сигнал, который система посылает всем консольным процессам при подготовке к выключению машины. Функция HandlerRoutine должна возвратить логическое значение: 1 — если она обрабатывает конкретный сигнал управления; 0 — для обработки полученного события будет использоваться другая функция-обработчик HandlerRoutine из списка функций-обработчиков для этого процесса (то есть включенная в этот список раньше данной функции).

У меня HandlerRoutine не реагирует ни на что, кроме Ctrl-C & Ctrl-Break & Close :"(

Добавляю его так: setconsolectrlhandler(@ctrlhndlr, true);

function ctrlhndlr(ctrltype : dword) : bool; stdcall; far;
begin
messagebox(...);
end.


 
Palladin ©   (2008-04-11 12:44) [23]

У меня все ловит. Как проверяешь, да и полный код обработчика давай.

ps. far то зачем? код скопировал, поди, откуда то...


 
kernel ©   (2008-04-11 19:51) [24]

а ctrlhndlr должен вообще реагировать на появление заставки? т.е. если я напишу так:

function ctrlhndlr(ctrltype : dword) : bool; stdcall; far;
begin
messagebox(0, "работает!", "!", MB_ICONINFORMATION);
end;

begin
setconsolectrlhandler(@ctrlhndlr, true);
end.


работать должно?


 
Palladin ©   (2008-04-11 20:07) [25]

в общем случае нет. как повезет. ты вообще результат возвращать собираешься?


 
kernel ©   (2008-04-18 16:26) [26]

Проблема так и не решилась :)

program Project1;

{$APPTYPE CONSOLE}

uses
 SysUtils, Windows;

function ctrlhndlr(ctrltype : dword) : bool; stdcall;
begin
messagebox(0, "работает!", "!", MB_ICONINFORMATION);
Result:=true;
end;

begin
setconsolectrlhandler(@ctrlhndlr, true);
readln;
end.


?


 
kernel ©   (2008-04-18 19:12) [27]

А может быть проще в потоке отсылать каждую минуту антихранителеэкранное сообщение?


 
kernel ©   (2008-04-19 14:40) [28]

Если какое-нибудь WM_сообщение , которое завершит работу заставки (но не отключит)?


 
Leonid Troyanovsky ©   (2008-04-19 16:41) [29]


> kernel ©   (19.04.08 14:40) [28]

http://support.microsoft.com/kb/140723/

--
Regards, LVT.


 
kernel ©   (2008-04-19 17:11) [30]


> Leonid Troyanovsky ©   (19.04.08 16:41) [29]


Спасибо за ссылку. Сделал так:

function KillScreenSaverFunc(hwd: HWND; lPrm: LPARAM): BOOL;
begin
if IsWindowVisible(hwd)
then PostMessage(hwd, WM_CLOSE, 0, 0);
Result:=true;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
hdsk: HDESK;
begin
hdsk:=OpenDesktop("Screen-saver", 0,
FALSE, DESKTOP_READOBJECTS or DESKTOP_WRITEOBJECTS);
if Boolean(hdsk) then
begin
EnumDesktopWindows(hdsk, @KillScreenSaverFunc, 0);
CloseDesktop(hdsk);
end else PostMessage(GetForegroundWindow(),
 WM_CLOSE, 0, 0);
end;


где таймер реагирует через 10 секунд после появления заставки (т.е. заставка появляется с интервалом 1 мин., а таймер срабатывает с интервалом 70 секунд). Так вот первые грабли: заставка убирается. Но она сразу же "продолжается"     8/  Т.е. будто запускается снова с того же места.


 
Leonid Troyanovsky ©   (2008-04-19 17:30) [31]


> kernel ©   (19.04.08 17:11) [30]

> function KillScreenSaverFunc(hwd: HWND; lPrm: LPARAM): BOOL;

stdcall;

> Спасибо за ссылку.

This can be done easily using:
SystemParametersInfo( SPI_SETSCREENSAVEACTIVE,
                     FALSE,
                     0,
                     SPIF_SENDWININICHANGE
                    );
--
Regards, LVT.



Страницы: 1 вся ветка

Форум: "Начинающим";
Текущий архив: 2008.05.18;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.54 MB
Время: 0.045 c
15-1207643753
samalex
2008-04-08 12:35
2008.05.18
Кодировка почтового сообщения


2-1208603961
lewka-serdceed
2008-04-19 15:19
2008.05.18
как убрать крестик, которым закрывается форма.


15-1207050353
snake-as
2008-04-01 15:45
2008.05.18
Графический редактор


2-1208350865
papa_roarch
2008-04-16 17:01
2008.05.18
Правый или левый клик?


15-1207574311
Дмитрий С
2008-04-07 17:18
2008.05.18
Свой протокол для IE





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский