Delphi programming blog
Источник: http://teran.karelia.pro/articles/item_4489.html
 

Мыльные пузыри в Delphi #4. Часть финальная

Опубликовано 31.08.2011 г. 23:04

Заключительная статья про реализацию "имитации" заставки Windows "Мыльные пузыри". В основном здесь речь пойдет о том, как сделать из исполняемого exe-файла "настоящую" scr-заставку.

Прежде чем перейду к описанию заставки, вернусь к вопросу производительности. Изначально при рисовании с использованием слоев загрузка процессора была 40%, после того как были убраны слои, и рисование стало основано на маске прозрачности, накладываемой на градиентный круг, загрузка упала до 20%. В текущей версии загрузка составляет 2-3%. Сделано это с помощью такой манипуляции - раньше маска прозрачности пузыря применялась к градиентному кругу. На самом деле изначально я хотел делать градиент цвета при заливке круга, но при реализации получилось что там цвет один, только в нижней части круга он более прозрачный. Так что это по сути была сплошная заливка с маской прозрачности. К этому виду я ее и привел. Теперь рисование проводится с помощью сплошной кисти, а в маску пузыря добавляется еще и градиентная прозрачность. Для достижения такого эффекта были вновь добавлены слои. Т.е градиентная маска применяется к слою, а затем на слое рисуется сама маска пузыря. Также была убрана обводка пузыря (отрисовка окружности после применения маски). Тут весьма интересная особенность: если каждый раз делать эту обводку (DrawGeometry(ID2D1EllipseGeometry)), то загрузка повышается то 8-10%. Странно, казалось бы просто рисование окружности. Зато обводка была добавлена в маску прозрачности. В маске я аналогично отрисовал окружность с непрозрачным цветом. Так же в текущей версии цвета пузыря меняются не в полете при касаниях об стенку, а раз в полсекунды (Здесь для анимации используются т.н key-frames - TUIAnimationKeyframe, для того чтобы в StoryBoard добавить изменения цвета последовательно). Ну а теперь вернемся к формированию заставки. Весьма логично предположение, что scr-заставка является обычным ехе-приложением. И это действительно так. Так что для начала изменим расширение исполняемого файла. Сделать это можно в меню Project -> Options -> Application -> Target file extension, либо директивой {$E scr} в dpr-файле проекта. Оба варианта равносильны. При разработке и тестировании заставки вы столкнетесь с тем, что заставку надо поместить в директорию System32. Сделать это можно несколькими путями. Но очевидный метод, предназначенный специально для таких целей, это Build Events. В меню Projects -> Options -> Build Events надо задать Post-Build команду:
copy $(OUTPUTPATH) $(WINDIR)\System32\$(OUTPUTFILENAME) /y
которая скопирует выходной файл OUTPUTPATH (полное имя) в системную папку. При необходимости ключом /y будет проведена перезапись файла. Наверное, стоит отметить, что до выхода Delphi 2010 подобная возможность (Build Events) отсутствовала, а в Delphi XE она была расширена и доработана, так что выглядит иначе. По сему, если вы не можете использовать Build Events, вы можете настроить output dir для файла в свойствах сборки проекта. Когда ваша заставка попала в системную директорию, вы можете открыть окно выбора экранных заставок (Персонализация - Заставка). Здесь вы заметите, что в списке ваша заставка перечислена по имени файла. Хотя все другие заставки имеют нормальное описание. Совсем немного поисков в интернете и вы найдете целую кучу ссылок говорящую о том, что надо включить описание в заголовок ехе-файла, используя директиву {$D} или {$DESCRIPTION} с текстом 'SCRNSAVE : Ваше название'. Возможно все это работало 10 лет назад, но сейчас эти манипуляции бесполезны. Таким путем результат вы не получите. Нам необходимо подключить ресурсный файл, в котором описать строку с названием. Для этого мы создаем текстовый файл а-ля myres.rc и подключаем его к проекту. В файле необходимо описать строковую таблицу и строку с идентификтором 1, например, так:
stringtable
begin
1 "Delphi bubbles Direct2D";
end;
Вообще мы должны знать, что подобное описание строк в ресурсах было заменено на определение resourcestring. Но я так и не понял как их использовать для наших целей, так что видимо никак. Если вы уже скопировали заставку в нужную директорию, и пробовали открыть окно настройки, то наверняка заметили, что при выборе пункта меню с вашей заставкой она запускалась. Есть несколько возможных вариантов запуска заставки.
  1. При настроке (контекстное меню файла) заставка запускается без параметров.
  2. При использовании кнопки Настройка в окне выбора заставки мы получаем параметры командной строки в таком виде: /c:HWND, где hwnd - дескриптор окна, поверх которого надо модально показать диалог настройки.
  3. Наверное вы замечали, что в окне выбора заставки, есть маленькое окошко предпросмотра, в котором рисуется ваша заставка. Так что при выборе вашей заставки в списке в качестве активной, она запускается с параметрами /p HWND. Заметьте тут два параметра, в отличие от предыдущего 1 параметра конфигурации, где дескриптор указан через двоеточие. Здесь дескриптор - окошко превью, в котором обычно и отображается уменьшенная заставка.
  4. Последний вариант - непосредственный просмотр заставки. Если вы нажимаете кнопку Просмотр, то заставка запускается с ключом /s. А если она запускается автоматически (согласно вашим настройкам системы), то с ключом /S.
Есть еще вариант /a но он использовался в win95, так что не актуален. Для перебора всех таких вариантов следует использовать примерно такой код:
  // Parameters :
  //
  //     no params -> Context menu -> Configure
  //    /p HWND   -> Install; hwnd - parent window
  //    /c:HWND   -> Configure, parent - modal
  //    /s - view

    if (paramCount = 0) or
       ((ParamCount = 1) and (StartsText('/c:', ParamStr(1)))) then begin
            //showModal configuration  window
           MessageDlg('Delphi bubbles ScreenSaver has no parameters!', mtInformation, [mbOk], 0);
       end
    else if (paramCount = 2) and (StrLower(PChar(ParamStr(1))) = '/p') then begin
        // set this screensaver as current
        // HWND - preview window HWND
    end
    else if (ParamCount = 1) and (StrLower(PChar(ParamStr(1))) = '/s') then begin
        Application.Initialize;
        Application.MainFormOnTaskbar := True;
        Application.Title := 'Delphi bubbles';
        Application.CreateForm(TScreenForm, ScreenForm);
        Application.Run;
    end;
Вот пожалуй и все, что требуется для создания вашей собственной заставки. Конечно требуется настроить заставку так чтобы она завершала работу при нажатии кнопки мыши или клавиатуры а так же при движении мыши. С последним, кстати, как ни странно у меня возникла проблема. Если форме назначить обработчик события OnMouseMove, в котором вызывается метод Close(), то почему то после запуска, и прорисовки первых нескольких кадров, работа завершается. Кажется это особо странным в свете того, что мышь лежит неподвижно, а запуск вообще производится с помощью клавиатуры. Так что тут я что то не понял :) К статье прикладываю исходный код последней версии пузырей, вместе со скомпилированным файлом: Исходный код и Exe Вид пузыриков в последнем варианте остается таким:
 
Метки:  Direct2D  |  animation  |  screensaver 

Комментарии

ter
17.12.2011 в 00:31
http://www.bilsen.com/windowsanimation/index.shtml
здесь хорошие хедеры, я их использовал.
там только в двух файлах они, во втором - UIAnimationMS - CLSID объектов, так что для себя CLSID перенес в первый файл и все.
- Имя
- e-mail*
- Сайт
вы можете использовать теги [i],[b],[code],[quote]
Дополнительно