Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   Flash Приложения: AIR, Zinc и тд. (http://www.flasher.ru/forum/forumdisplay.php?f=94)
-   -   Как проиграть swf-ролик и ресурсов приложения (http://www.flasher.ru/forum/showthread.php?t=131300)

marek 16.10.2009 21:18

Как проиграть swf-ролик и ресурсов приложения
 
Уважаемые форумчане подскажите как запихнуть swf-ролик в ресурсы приложения, а затем воспроизвести его оттуда. Работаю на MS VC++.

Очень часто нужно swf в exe запаковывать, раньше пользовался SWF Maestro EXE. В принципе нормальная прога, и fscommand есть и удобная, но под Вистой SP2 скомпиленые программки не пашут.

Вот решил не пользоваться сторонними программами и запаковывать в exe самостоятельно. С fscommand разобрался, а вот запихнуть swf в ресурсы и воспроизвести его не удается (опыта программирования на с++ маловато).

Буду рад любому совету!

alexcon314 16.10.2009 23:40

Под виндой для ActiveX-плеера это сделать можно, за другие платформы не скажу.. Кстати, не припомню ни одной оболочки, где бы это было возможно, разве что у f-in-box что-то было похожее, не уверен. Посмотрите на сайте f-in-box.com, правда он платный.
Ну, а так, вобщем-то, плеер реализует COM-интерфейс IPersistStream, у него есть метод Load(), собственно, стрим ему надо подсунуть с данными из ресурсов и все. В подписи у меня была вроде ссыль на кусок с++ - кода в ветке форума codeproject.com. Да вот он, как пример c использованием ATL-библиотеки:
Код:

// это один из методов моего класса, хостящего флэш-контрол
LRESULT CFlashHost::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))
        {
                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;
}


marek 17.10.2009 02:19

alexcon314 спасибо большое за ответ. Но к сожалению в ATL я полный ноль. Разбираюсь пока только в Windows Forms Aplication, и то с переменным успехом. Я прошел по ссылке в твоей подписи и скачал пример. Это просто супер, и мувик в ресах и контрол. Приложение монолитное, ничего не "просит", прям сказка (как раз то что мне нужно). Ты не мог бы поделиться исходником. Я готов отблагодарить.

alexcon314 17.10.2009 16:35

Эмм.. вот так вот запросто - "поделись исходником"! )).
Как вы собиратетесь юзать исходник на ATL, если вы в нем полный ноль?:)

ЗЫ.Все начинают с "я полный ноль". В Windows Forms я и сейчас ноль). Просто я поставил себе когда-то цель сделать то, что в моей подписи, и добился своего. Ключевые ссылки я дал, а дальше... дорогу осилит идущий.

marek 17.10.2009 17:32

Цитата:

Сообщение от alexcon314 (Сообщение 858579)
Эмм.. вот так вот запросто - "поделись исходником"! )).

Почему же запросто, за деньги.
Цитата:

Сообщение от alexcon314 (Сообщение 858579)
Как вы собиратетесь юзать исходник на ATL, если вы в нем полный ноль?

Ну юзать исходник это же не писать его с нуля, разобраться можно (к тому же мне и юзать его не нужно, нужно просто заменить в ресах Ваш swf-ролик на свой и скомпилить). А по поводу дорогу осилит идущий это понятно, я сам такого мнения, но нужно срочно, поэтому разбираться в ATL нет времени. Раз уж Вы не хотите продавать свой исходник, значит придется обратиться к господам фрилансерам. Всего доброго.

alexcon314 18.10.2009 00:04

Простите за менторский тон в моем посте, если он был для вас неприятен.
Скомпилить + прикрутить fscommand (fscommand'a там нет) даже на готовом исходнике - по-любому вам понадобится помощь. Удачи с господами фрилансерами.
Тем более, половину исходника я уже выложил, и фактически, и в ссылках.

marek 18.10.2009 23:36

С фрилансерами решил подождать, это всегда успеется. Пробую самостоятельно, но пока безрезультатно.
Код:

HINSTANCE hinst = ::GetModuleHandle(NULL);
HRSRC hrsrc = FindResource(hinst, MAKEINTRESOURCE(IDR_SWF1), RT_RCDATA);

hrsrc у меня почему-то равно NULL. Подозреваю, что я либо hinst неправильно определяю, либо ролик неправильно в ресы загнал. Хотя вроде правильно.

И вот еще какой вопрос. Как до инициализации приложения определить установлен ли флеш-плеер? Чисто логически (ну то есть я так думаю) флеш-контрол (flashXX.осх) должен быть зарегистрирован в системе, т.е в реестре есть об этом запись, и скорее всего, прописан путь к файлу flashXX.осх Далее думаю, что нужно проверить есть ли такой файл, и если нет, выдать ошибку и выйти из приложения. Но вот как это реализовать...?

alexcon314 19.10.2009 09:22

Код:

//resourse.h
...
#define IDR_SWF1                        104
...

Цитата:

//res.rc
...
IDR_SWF1 SWF "movie.swf"
...
Вызов : LoadMovieFromResource(IDR_SWF1, L"SWF");
Гг-ы))ы. Можно открыть мой пример в резхакере ( Resourse Hacker) и тупо заменить мувик на любой другой.

Далее, проверку установки контрола можно сделать так:
Код:

// консольное приложение-пример
#include "stdafx.h"
#include <stdlib.h>
#include <windows.h>
#include <OBJBASE.H>
#include <AtlBase.h>
// {D27CDB6E-AE6D-11cf-96B8-444553540000} - идентификатор флэш-контрола (CLSID)
int _tmain(int argc, _TCHAR* argv[])
{
        CLSID clsid;
        HRESULT res = CLSIDFromString(OLESTR("{D27CDB6E-AE6D-11cf-96B8-444553540000}"),&clsid);
        printf("%x\n",res);// 0 - S_OK
        OLECHAR* str;
        res = ProgIDFromCLSID(clsid,&str);
        printf("%x\n",res);// 0 - S_OK
        USES_CONVERSION; // это чисто для того, чтобы показать строку в консоли
        printf("%s\n",OLE2A(str)); // у меня выводит ShockwaveFlash.ShockwaveFlash.10
        Sleep(10000);
        return 0;
}

Только вот еще что. Мувик в ресах - это пожалуйста. А вот контрол в ресурсах - нарушение лицензионного соглашения от Адоба. Так контрол распространять нельзя.

marek 19.10.2009 23:57

Накорябал функцию, которая получает из реестра путь к файлу flashXX.осх, и проверяет существует ли файл. Т.е если существует, то контрол зарегистрирован в системе и файл на месте. Вот код функции:
Код:

//функция проверки установлен ли флеш контрол
bool activex_control(void){
  string out;
  HKEY hKey;
  unsigned char Reget[512];
  DWORD RegetPath = sizeof(Reget);
  DWORD type = REG_SZ;
  RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Classes\\CLSID\\{D27CDB6E-AE6D-11cf-96B8-444553540000}\\InprocServer32", NULL, KEY_QUERY_VALUE, &hKey);
  RegQueryValueEx(hKey, NULL, NULL, &type, Reget, &RegetPath);
  RegCloseKey(hKey);
  for(unsigned int i=0; i<RegetPath; i++){
      if(Reget[i] != '\0') out.push_back(Reget[i]);
  }
                       
  return  FileExists(out.data());
}

Проблема в том, что писал эту функцию в консольном приложении, и там она работала отлично. А когда перенес в Windows Forms, то при компиляции на стадии линковки вываливается куча ошибок. Вот они:
Код:

Linking...
psi-app.obj : error LNK2028: unresolved token (0A000372) "extern "C" long __stdcall RegCloseKey(struct HKEY__ *)" (?RegCloseKey@@$$J14YGJPAUHKEY__@@@Z) referenced in function "private: bool __clrcall psiapp::Form1::activex_control(void)" (?activex_control@Form1@psiapp@@$$FA$AAM_NXZ)
psi-app.obj : error LNK2028: unresolved token (0A000373) "extern "C" long __stdcall RegQueryValueExW(struct HKEY__ *,wchar_t const *,unsigned long *,unsigned long *,unsigned char *,unsigned long *)" (?RegQueryValueExW@@$$J224YGJPAUHKEY__@@PB_WPAK2PAE2@Z) referenced in function "private: bool __clrcall psiapp::Form1::activex_control(void)" (?activex_control@Form1@psiapp@@$$FA$AAM_NXZ)
psi-app.obj : error LNK2028: unresolved token (0A000374) "extern "C" long __stdcall RegOpenKeyExW(struct HKEY__ *,wchar_t const *,unsigned long,unsigned long,struct HKEY__ * *)" (?RegOpenKeyExW@@$$J220YGJPAUHKEY__@@PB_WKKPAPAU1@@Z) referenced in function "private: bool __clrcall psiapp::Form1::activex_control(void)" (?activex_control@Form1@psiapp@@$$FA$AAM_NXZ)
psi-app.obj : error LNK2019: unresolved external symbol "extern "C" long __stdcall RegCloseKey(struct HKEY__ *)" (?RegCloseKey@@$$J14YGJPAUHKEY__@@@Z) referenced in function "private: bool __clrcall psiapp::Form1::activex_control(void)" (?activex_control@Form1@psiapp@@$$FA$AAM_NXZ)
psi-app.obj : error LNK2019: unresolved external symbol "extern "C" long __stdcall RegQueryValueExW(struct HKEY__ *,wchar_t const *,unsigned long *,unsigned long *,unsigned char *,unsigned long *)" (?RegQueryValueExW@@$$J224YGJPAUHKEY__@@PB_WPAK2PAE2@Z) referenced in function "private: bool __clrcall psiapp::Form1::activex_control(void)" (?activex_control@Form1@psiapp@@$$FA$AAM_NXZ)
psi-app.obj : error LNK2019: unresolved external symbol "extern "C" long __stdcall RegOpenKeyExW(struct HKEY__ *,wchar_t const *,unsigned long,unsigned long,struct HKEY__ * *)" (?RegOpenKeyExW@@$$J220YGJPAUHKEY__@@PB_WKKPAPAU1@@Z) referenced in function "private: bool __clrcall psiapp::Form1::activex_control(void)" (?activex_control@Form1@psiapp@@$$FA$AAM_NXZ)

В чем причина, что я не учел?

alexcon314 20.10.2009 08:39

Похоже надо прилинковать advapi32.lib.


Часовой пояс GMT +4, время: 08:06.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.