int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
ShellExecute(0, NULL, "Notepad.exe", NULL, NULL, SW_SHOWDEFAULT);
Sleep(5000);
return 0;
}
"Фича" винды при работе со скринсейверами
Назрел такой вот животрепещущий вопрос - я написал 3Д скринсейвер (подробнее пока не буду, может потом выложу =)), все уже приготовил к релизу, и тут заметил странную "фичу" винды.
Обрисую суть проблемы:
есть файл .scr - лорадер, который содержит в себе гуи настроек скринсейвера, и, при соответствующих аргументах коммандной строки грузит экзешник, главную часть, при помощи Креэйт процесс а сама зовет ExitProcess(0);
Так вот, тестил - все ок, работает как атомные часы. НО! Когда устанавливаю его собственно как скринсейвер, жду пока его винда запустит сама, наблюдается такой эффект: Как только выходит лоадер, тутже вырубается и запущенный им экзешник. Т.е. если я после КреэйтПроцесса(...) поставлю Слип(10000) то экзешник проработает как раз эти 10000 мс. Что я только не делал - и заменя креэйт процесс на ШеллЭкзекьют и ВинЭкзек, и делал промежуточный экзешник (.скр запускает этот экзешник, а он - сам скринсейвер) - стабильно закрывает ВСЕ каким либо образом запущенное через .скр....
Помогает только одно - поставить после КреэйтПроцесса WainForSingleObject(hProcess,INFINITY); - чтобы .скр по тихому висел в памяти. Но что то мне такое не нравится.
Может кто расскажет, как можно еще бороться с этим?
P.S. - если хотите - проверьте сами: Делаем прогу из дух строк:
....
ShellExecute(0,NULL,"Notepad.exe",NULL,NULL,SW_SHOWDEFAULT);
Sleep(5000);
....
Компиллим, переименовываем ее в .scr, ставим текущим скринсейвером и ждем.
Ноутпад запустится на 5000 мс.
Код:
вылетает notepad.exe прога вырубается через пять секунд. В чем прикол-то???
для screensaver'ов существуют ее ключи командной строки. Это раз.
Также существуют спец-функции из scrnsave.h
Причем тут параметры коммандной строки? Разумеется я знаю о них, если написал скринсейвер, они обрабатываются в основной программе.
Заголовочный файл не имеет ничего что помогло бы решить проблему.
Notepad не закрывается, поток будет висеть пока его не прибьют снаружи. :-)))
[QUOTE=_RA_]Помогает только одно - поставить после КреэйтПроцесса WainForSingleObject(hProcess,INFINITY); - чтобы .скр по тихому висел в памяти. Но что то мне такое не нравится.
Может кто расскажет, как можно еще бороться с этим?
[/QUOTE]
ВэйтФорСинглОбжект в данном случае выступает как твой слип, только лучше - .скр висит в памяти не пока его не прибьют, а пока не завершиться основная часть... =)
твоего кода я не видел, разобраться в нем телепатически не могу.
Переформулирую вопрос так: есть следующий код
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
ShellExecute(0, NULL, "Notepad.exe", NULL, NULL, SW_SHOWDEFAULT);
Sleep(5000);
return 0;
}
Если скомпиллировать его, экзешник переименовать в .скр, и поставить как текущий скринсейвер, то при запуске его системой, ноутпад появляется на 5 сек. Из-за чего это и как с этим справится _НЕ_ оставляя .скр висеть в памяти.
Та ссылка к этому имеет очень мало отношения, хотя бы по тому, что там только .скр. У меня другая структура, потому и задал вопрос.
Если хочешь писать что-то нужно следовать стандартам. Если сказано что в скринсейвере ДОЛЖНЫ быть RegisterDialogClasses, ScreenSaverConfigureDialog и ScreenSaverPoc, то они там и должны быть!
Винда ведь ищет именно их в модуле, когда ты запускаешь свой scr. Это ВЕДУЩИЕ функции, и заметь, WinMain почему-то не входит в их число.
А твой переименованный exe в scr не содержит их - поведение системы непредсказуемо.
В статье ведь ясно сказано, что:
RegisterDialogClasses() - установка переменных для диалогового окна настроек скринсейвера,
ScreenSaverConfigureDialog() - оконная процедура этого окна настроек,
ScreenSaverProc() - ядро скринсейвера.
И она ищет именно их! Одному только Билу известно что будет если ты напишешь не по стандарту. :-)))