Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.221.141.44] |
|
Сообщ.
#1
,
|
|
|
Данная статья посвящена тому, какими способами можно отображать Flash ролики на Windows.Forms и какими способами можно ими управлять.
Окружение: Windows XP, .NET 2.0, Flash Player Задача может и не относится к распространенным, но возможно кому-то захочется добавить "изюминку" в свое приложение в виде векторной графики, анимации, звуков и т д. Способов встроить Flash ролик в форму - 2 (представлены ниже). 1. С помощью компонента обозревателя - System.Windows.Forms.WebBrowser. Действия: перетянуть на форму компонент WebBrowser или создать и настроить его руками, установить ему свойство Url - путь к ролику (.swf) или к .html в котором всторен флеш объект. private System.Windows.Forms.WebBrowser webBrowser1; ... this.webBrowser1 = new System.Windows.Forms.WebBrowser(); this.webBrowser1.Location = new System.Drawing.Point(14, 236); this.webBrowser1.MinimumSize = new System.Drawing.Size(20, 20); this.webBrowser1.Name = "webBrowser1"; this.webBrowser1.Size = new System.Drawing.Size(250, 131); this.webBrowser1.Url = new System.Uri("c:\\tmp\\simple.swf", System.UriKind.Absolute); Достоинства: простота Недостатки: нет возможности получать комманды от ролика и управлять им Способ подходит для простого отображения флеш контента. Если роликом нужно управлять или получать от него комманды, - необходимо воспользоваться вторым способом. 2. С помощью AxtiveX компонента Shockware Flash Object. Действия: - в VS 2005 правой кнопкой кликнуть на поле Toolbox, в контекстном меню выбрать Choose Items. - в появившемся окне Choose Toolbox Items перейти на закладку COM Components, выбрать Shokware Flash Object (я использую Debug версию 9 плеера, у меня это - c:\Windows\system32\Macromed\Flash\FlDbg9.ocx). - теперь на закладке у нас появился Shockware Flash Object, который можно смело перетянуть на форму. private AxShockwaveFlashObjects.AxShockwaveFlash flashPlayer; this.flashPlayer = new AxShockwaveFlashObjects.AxShockwaveFlash(); this.flashPlayer.Enabled = true; this.flashPlayer.Location = new System.Drawing.Point(13, 12); this.flashPlayer.Name = "flashPlayer"; this.flashPlayer.OcxState = ((System.Windows.Forms.AxHost.State)(resources.GetObject("flashPlayer.OcxState"))); this.flashPlayer.Size = new System.Drawing.Size(300, 200); - замеченные баги: Если при первой компиляции после добавления ролика выдает ошибку, что не найден только что добавленный компонент - необходимо удалить папки obj, bin в проекте. Работа с компонентом: - загрузка ролика в компонент: string path = "c:\\tmp\\simple.swf"; flashPlayer.LoadMovie(0, path); здесь я надеюсь все понятно, смущение может вызвать первый параметр - для тех, кто знает флеш - это слой, на который будет загружен ролик. - получение команд от ролика: флеш ролик может взаимодействовать с окружением с помощью команды языка Action Sript - fscommand, например(обработчик нажатия кнопки во флеш ролике) - on(click) { fscommand("sendCmd", 1); } первый параметр - имя комманды, второй - аргумент комманды. Ловим эту комманду из Windows.Forms : //подписываемся на событие от ролика на получение fscommand flashPlayer.FSCommand += new AxShockwaveFlashObjects._IShockwaveFlashEvents_FSCommandEventHandler(flashPlayer_FSCommand); //подписчик: void flashPlayer_FSCommand(object sender, AxShockwaveFlashObjects._IShockwaveFlashEvents_FSCommandEvent e) { tbOut.Text += e.command + " (" + e.args + ")" + "\r\n"; } при этом - e.command - команда (строка), e.args - аргумент команды (строка). В примере команда добавляется в текстовое поле для отображения. - управление роликом: для управления роликом у компонента есть блок методов, начинающихся с T, вот некоторые: flashPlayer.TPlay("rect_mc"); //стартует MovieClip rect_mc, который находится на сцене ролика flashPlayer.TGotoFrame("rect_mc", 1); //переводит rect_mc на первый кадр flashPlayer.TCallFrame("rect_mc", 1); //вызывает первый кадр rect_mc flashPlayer.TStopPlay("rect_mc"); //останавливает проигрывание rect_mc flashPlayer.TSetProperty("rect_mc", 1, "50");//установить свойство c индексом 1 в значение "50" string s = flashPlayer.TGetProperty("rect_mc", 1); //считать первое свойство int frame = flashPlayer.TCurrentFrame("rect_mc"); //узнать на каком кадре находится ролик. и еще много вкусного Данная статья расчитана наверное не на очень широкий круг читателей форума, но вопрос не достаточно освещен в рунете, поэтому я думаю кому-то, но она пригодится. Может кто-то мечтал написать флеш игрушку, но при этом не знал Action Script, прочитав эту статью, это можно сделать теперь на родном C# :-) Проект с примером не выкладываю, по причине распространенности разных версий флеш плееров и ocx компонентов, но работоспособность приведенного кода будет соблюдаться при наличии флеш плеера версии 6 и старше, возможно и младше - не проверял. Вопросы и комментарии приветствуются. Спасибо прочитавшим, при распространении ставьте копирайты ;-) |
Сообщ.
#2
,
|
|
|
PIL, все хорошо.
Но а как во втором случае загрузить ролик из ресурса, без распаковывания и создания файла? |
Сообщ.
#3
,
|
|
|
Цитата GRIENDERS @ - вряд ли будет такая возможность, сомневаюсь без распаковывания и создания файла? Я этим направлением давно не занимался. Если разберешься - допиши |
Сообщ.
#4
,
|
|
|
На самом деле как то это провернуть можно. Например для Delphi существует компонент, который позволяет грузить из ресурсов, выводить на экран без окна формы (с поддержкой прозрачности). Но насколько я помню, там автор взламывал flash.ocx и переписывал его под свои нужды.
|
Сообщ.
#5
,
|
|
|
Грузить в ActiveX-плеер ролик из ресурса можно, используя его интерфейс IPersistStreamInit.
Как это делать в с++ с спользованием ATL примерно известно. LRESULT LoadMovieFromResource(UINT id, WCHAR* type) { HRESULT hr = S_FALSE; HRSRC hResource = FindResource(hModule, MAKEINTRESOURCE(id), type); HGLOBAL hResourceData = LoadResource(hModule, hResource); LPVOID lpResourceData = LockResource(hResourceData); DWORD dwResourceSize = SizeofResource(hModule, hResource); HGLOBAL hGlobalData = GlobalAlloc(GPTR, dwResourceSize+8); LPBYTE pMem = (LPBYTE)GlobalLock(hGlobalData); ((long*)pMem)[0] = 0x55665566; // это "загадочные" байты, о которых мне ничего не известно, но без них не грузится ((long*)pMem)[1] = dwResourceSize; CopyMemory((void*)(&(pMem[8])), lpResourceData, dwResourceSize); IStream* pStream = 0; hr = CreateStreamOnHGlobal(hGlobalData, TRUE, &pStream); if(SUCCEEDED(hr)) { //m_spPlayer - это инстанс плеера в хостящем окне hr = m_spPlayer->QueryInterface(IID_IUnknown, (void**)&m_spUnknown); CComQIPtr<IPersistStreamInit> pPersistStream(m_spUnknown); if(pPersistStream)hr = pPersistStream->Load(pStream); pStream->Release(); pStream = 0; } return hr; } Интересно, как такое провернуть на .NET? То, что можно - это точно. Смотрите www.f-in-box.com. |