... Application->ShowMainForm = false
//это я ставлю при старте проекта, сразу после Application->Initialize
//а далее идёт текст из cpp файла к MainForm (форма одна)
...
if (UpperCase(ParamStr(1)) == "/P")
{int n = ParamCount()+1;
if (n > 2)
{HWND parentInstance = HWND(StrToInt(ParamStr(2)));
TCanvas *mCanvas = new TCanvas();
mCanvas->Handle = GetDeviceContext(parentInstance);
RECT parentRect;
if (GetWindowRect(parentInstance, &parentRect))
{mCanvas->Brush->Color = clRed;
mCanvas->Brush->Style = bsDiagCross;
try
{if (IsWindowVisible(parentInstance))
{mCanvas->Rectangle(parentRect.left+1, parentRect.top+1, parentRect.right-1, parentRect.bottom-1);
}
}
__finally
{mCanvas->Free();
Application->Terminate();
}
}
else {mCanvas->Free();
Application->Terminate();
}
}
Application->Terminate();
}
Превью скринсейвера в Свойствах экрана
[ATTACH]3056[/ATTACH]
Пишу скринсейвер, столкнулся с этой проблемой - ну никак не удаётся что-то отрисовать в этом факин шит превью... :confused: В инете откопал следующую информацию: для отрисовки этого превью винда создаёт своё окошко, и передаёт в скринсейвер параметры "/p" (ну типа запуск в превью) и второй параметр типа "1313616" (я так понял, это хендл этого окошка или указатель на него - ну в этой области, в общем).
Если кто не знает, далее скринсейвер должен показывать превью так: никаких форм он не создаёт, и должен просто отрисовывать превью в это созданное виндой окошко. Я нашёл вроде полноценный исходник на делфи, но давно, видимо, торкал этот сибилдер, так как просто посмотреть в делфи и сделать тоже самое на билдере, я не смог :(
В общем, вот как выглядит кусок кода, обрабатывающий параметр /p у меня. Окна, хэндлы, их свойства, я не очень, к сожалению, шарю, поэтому буду рад, если кто поможет... Может быть, в этом коде даже написана откровенная чушь?.. не стесняйтесь, говорите )))
Код:
Как я полагал вчера, когда пробовал запустить это всё - я должен увидеть в окне превью красный прямоугольник :D в лучшем случае ничо не видел - чёрное превью, а в худшем - возникал такой звук, как будто произошёл вылет, но без сообщений, экран оставался чёрным. Я делал лог-файл и писал туда всё по шагам. До момента IsWindowVisible лагов не было, а потом почему-то возникал этот звук, но приложение завершалось нормально и не зависало в памяти... Так же интересно: я писал в лог файл размеры окна прямоугольника, которые там получаю. И где бы окно свойств экрана не находилось - они всегда одни и те же, значения не менялись... (((
Помогите, пожалуйста, кто-нибудь разобраться!
Оригинальный исходник делфи, по которому я пытался проникнуть в суть вопроса, во вложенном архиве.
Цитата: maxio
mCanvas->Free();
вот это точно херня полная, в С++ объекты удаляются так - delete mCanvas;
Пример сброшу может седня вечером, если будет настроение и время - а если не будет - ищите сами - вариантов в нете - вагон и маленькая тележка.
Ну а вообще, может, мы недопоняли друг друга - я говорю и говорил про превью, которое должно показываться в том маленьком мониторчике на окне свойств:
[ATTACH]3055[/ATTACH]
Если вы тоже имеете в виду именно это превью, то подскажите, пожалуйста, как получить мне координаты этой области монитора, куда поместить созданное и прорисованное окно?
Вторым параметром получает прога хендл какой-то. Проверял его IsWindow - возвращает true. И GetWindowRect возвращает в RECT постоянно одни и те же координаты...
Попробуйте следующий код (к сожалению проверять его времени нет, так что тут разбирайтесь сами):
Код:
TStartupInfo siInfo;
TProcessInformation piInfo;
setmem(siInfo,sizeof(siInfo),0);
siInfo.cb = sizeof(siInfo);
siInfo.dwFlags = START_USESHOWWINDOW;
siInfo.wShowWindow = SW_SHOWNORMAL;
Sttring path = FileName+" -p "+IntToStr(Panel1->Handle);
CreateProcess(NULL,path.c_str(),NULL,NULL,false,0,NULL,NULL,&siInfo,piInfo);
TProcessInformation piInfo;
setmem(siInfo,sizeof(siInfo),0);
siInfo.cb = sizeof(siInfo);
siInfo.dwFlags = START_USESHOWWINDOW;
siInfo.wShowWindow = SW_SHOWNORMAL;
Sttring path = FileName+" -p "+IntToStr(Panel1->Handle);
CreateProcess(NULL,path.c_str(),NULL,NULL,false,0,NULL,NULL,&siInfo,piInfo);
естественно у вас на форме должна быть панель с таким именем, и FileName - это имя файла скринсейвера, которое вы получите каким либо удобным для вас образом. Я надеюсь приводить код как получить имя текущего хранителя экрана и список присуствующих в системе не нужно? Если нужно - то текущий храниетель экрана храниться в реестре - в ветке HKEY_CURRENT_USER\Control Panel\Desktop - параметр SCRNSAVE.EXE. Список присутствующих в системе вы получите, найдя все файлы с соотвествующим расширением.
Код:
if(piInfo.hProcess !=0)
TerminateProcess(piInfo.hProcess,0);
TerminateProcess(piInfo.hProcess,0);
и вместе с CreateProcess поместите в обработчик например клика по элементу списка.
Ну а вообще я пишу сам скринсейвер, одну прогу. Он и есть некий src Файл. И когда юзер выбирает его в этом списке в свойствах экрана - в маленьком мониторе должен отображаться он в уменьшенном размере. Но, как я выяснил, это не просто показать форму нужного размера.
Я нашёл, что при нажатии кнопки Просмотр, винда вызывает мой файл скринсейвера с параметром /s - это типа полноценный запуск, при нажатии кнопки "Параметры" - вызывает мой файл с параметром /c (так же там через двоеточие передаётся ещё какое-то целое число большое - полагаю, эт тоже какой-то хендл) - типа "/c:6122039". А чтобы показать мой скринсейвер в этом маленьком мониторе, когда пользователь его выбрал - передаются параметры: "/p 234902" - вот, это все исходные данные для нахождения где и как надо рисовать.
Я не знаю, как именно надо рисовать, но в инете нашёл (как в первом прикреплённом делфи-файле - там даже со страницей описания) - что надо рисовать с помощью канвы именно в этом маленьком мониторчике. Но как получить его координаты, я уже вообще не могу допереть ((((
Цитата: maxio
А чтобы показать мой скринсейвер в этом маленьком мониторе, когда пользователь его выбрал - передаются параметры: "/p 234902" - вот, это все исходные данные для нахождения где и как надо рисовать.
Я не знаю, как именно надо рисовать, но в инете нашёл (как в первом прикреплённом делфи-файле - там даже со страницей описания) - что надо рисовать с помощью канвы именно в этом маленьком мониторчике. Но как получить его координаты, я уже вообще не могу допереть ((((
Там же все ясно вроде, вот хендл тебе передают:
Код:
ParentSaverHandle := StrToInt(Param);
а потом рисуют на нем (окне):
Код:
procedure TMainForm.DoPreviewDrawing;
var
Rect: TRect;
Bitmap: TBitmap;
Canvas: TCanvas;
begin
FreeMutex; // Free the mutex so that the screen saver will actually run in preview
Canvas := TCanvas.Create;
try
Canvas.Handle := GetDC(ParentSaverHandle);
try
GetWindowRect(ParentSaverHandle, Rect);
// и т.д.
var
Rect: TRect;
Bitmap: TBitmap;
Canvas: TCanvas;
begin
FreeMutex; // Free the mutex so that the screen saver will actually run in preview
Canvas := TCanvas.Create;
try
Canvas.Handle := GetDC(ParentSaverHandle);
try
GetWindowRect(ParentSaverHandle, Rect);
// и т.д.
Это не ваша задача - искать мониторчик :) вам ужет передают его хендл в параметре.
Исходник в делфи не смотрел - некогда.
Но возможно проблема в том что вы получаете дескритор и рисуете на канве - но после того как вы отрисовали - вам надо поместить нарисованное обратно в окно (типа CopyRect). Вы же канву удаляете - и с ней удаляется ваш рисунок. Может запутанно объяснил - но просто действительно времени особо нет.
Цитата: maxio
...что надо рисовать с помощью канвы именно в этом маленьком мониторчике. Но как получить его координаты, я уже вообще не могу допереть ((((
А зачем тебе получать его координаты?! Только размер!
И Rect(0,0,Width,Height) - в нем и рисуй!
но как же тогда попасть в этот дурацкий мониторчик?! )))
>> Новый эксперимент!
Прописал тот же код не в коде основной формы, а в коде первого файла проекта, ещё до Application->Initialize(); ... Ну что могу сказать, я вообще не понимаю, что происходит, второй параметр один и тот же в двух лог-файлах, а вот GetWindowRect по нему возвращает разные значения! И вот до Application->Initialize(); получается именно нужный прямоугольник!.. Кто-то может предположить, как такое может быть и почему?!... 8\
Как она не запустив твоей программы узнает хендл ею создаваемого окна??
Может, приложение, создавая форму, просто замещает это спец. окно, и становится само доступно по этому хендлу?..
В общем, я пробовал это делать прямо по исходнику делфи, там до создания формы определяется только сам хэндл, а все операции с ним уже после FormCreate. Может быть, в этом плане билдер по-другому запускает-выполняет все эти формы-окны, фиг знает...
Да, если кто-то будет смотреть исходники от делфи, которые я приаттачил к первому сообщению - вот наводка, что там где:
ScreenSaveUtils - непосредственно код, обрабатывающий параметр ком. строки
randimg.dpr - основной код проекта, до запуска Application->Run
MainFrm.pas - код формы, которая прорисовывает превью и скринсейвер
в этой форме Create - инициализирует, чо выполнять
DoPreviewDrawing - осуществляет прорисовку скринсейвера в окошко превью
Ві помоему сами запутались и других путаете. Зачем вам получать какие либо координаты? Причем тут "мониторчик"? Ваша задача - получить дескриптор того - куда рисовать - и туда рисовать. Все. Чего вы заморачиваетесь? Получения дескриптора "мониторчика" - не ваша задача, а того приложения которое этот "мониторчик" реализует.