Lecteur d'animations flash (100% api)

Soyez le premier à donner votre avis sur cette source.

Vue 21 041 fois - Téléchargée 1 660 fois

Description

Voici un autre exemple d'utilisation d'un Activex dans un programme win32 en pur API. Il s'agit de l'Activex Shockwave Flash de Macromedia présent dans pratiquement tous les ordinateurs sous Windows. Ce code source montre comment afficher une animation Flash dans la fenêtre d'une application. Voici la desciption de quelques fichiers du projet:
1- swf.h : Contient quelques définitions et surtout une fonction de récupération de données à partir de l'en-tête du fichier swf chargé.
2- zlib.dll : Contient la fonction uncompress() utilisé pour extraire la partie compressée d'un en-tête swf. Cette dll est gratuite : www.zlib.net
3- flash.h : Je l'ai conçu à partir des données fournies par l'outil OLE/COM Viewer de Visual C/C++ 6. Il contient deux GUID et le prototype de l'interface IShockwaveFlash avec toutes ses méthodes.

Projet réalisé sous Visual 6 et testé sous Windows XP sans problème. Je pense que ce sera pareil pour les autres versions de Windows.
Testez le et n'hésitez pas à signaler des bogues ou erreurs éventuelles (merci). Vos commentaires, suggestions et questions sont les bienvenus.

Source / Exemple :


// Les includes:
#include <windows.h>
#include "swf.h"
#include "flash.h"

// Déclarer un pointeur sur l'interface IShockwaveFlash:
IShockwaveFlash *pIswf;
// Déclarer le HWND de notre conteneur Activex en global:
HWND hConteneur;

// ----------- Fonction permettant de calculer la position et les dimensions de l'animation dans la fenêtre:
void PosDim (HWND wnd,int largeur, int hauteur, RECT* rec)
{
	// Obtenir les dimensions de la zone interne de la fenêtre:
	RECT wndrec;
	GetClientRect(wnd,&wndrec);
	// Fixer la largeur et hauteur utiles dans la fenêtre:
	int wndlarg=wndrec.right-6;
	int wndhaut=wndrec.bottom-38;
	// Déclaration d'un float pour calculer les rapports:
	float rap;
	// Si les dimensions de l'animation sont inférieurs à la fenêtre:
	if (largeur<=wndlarg && hauteur<=wndhaut)
	{
		// Centrer le rectangle:
		rec->left=(wndlarg-largeur)/2+2;
		rec->top=((wndhaut-hauteur)/2+2);
		rec->right=largeur;
		rec->bottom=hauteur;
		return;
	}
	// Si seule la hauteur est supérieure à la fenêtre:
	if (largeur<=wndlarg && hauteur>wndhaut)
	{
		// Redimensionner le rectangle pour qu'il tienne dans la fenêtre:
		rap=(float)hauteur/wndhaut;
		rec->right=(long)(largeur/rap);
		rec->bottom=wndhaut;
		rec->left=(wndlarg-rec->right)/2+2;
		rec->top=2;
		return;
	}
	// Si seule la largeur est supérieure à la fenêtre:
	if (largeur>wndlarg && hauteur<=wndhaut)
	{
		// Redimensionner le rectangle pour qu'il tienne dans la fenêtre:
		rap=(float)largeur/wndlarg;
		rec->right=wndlarg;
		rec->bottom=(long)(hauteur/rap);
		rec->left=2;
		rec->top=(wndhaut-rec->bottom)/2+2;
		return;
	}
	// Si la largeur et la hauteur sont supérieurs à la fenêtre:
	if (largeur>wndlarg && hauteur>wndhaut)
	{	
		// Déterminer les rapports avec les dimensions maximales de la fenêtre:
		float rapx=(float)largeur/wndlarg;
		float rapy=(float)hauteur/wndhaut;
		// si le rapport de la largeur est plus grand:
		if (rapx>rapy)
		{
			// Redimensionner le rectangle pour qu'il tienne dans la fenêtre:
			rec->right=wndlarg;
			rec->bottom=(long)(hauteur/rapx);
			rec->left=2;
			rec->top=(wndhaut-rec->bottom)/2+2;
			return;
		}
		// si le rapport de la hauteur est plus grand:
		if (rapx<=rapy)
		{
				//Redimensionner le rectangle pour qu'il tienne dans la fenêtre:
				rec->right=(long)(largeur/rapy);
				rec->bottom=wndhaut;
				rec->left=(wndlarg-rec->right)/2+2;;
				rec->top=2;
				return;
		}
	}	
}
//-----------------------------------------------------------------------------------//

//------------------- Procédure de notre fenêtre principale -----------------------//
LRESULT CALLBACK WndProc( HWND hWnd, UINT messg, WPARAM wParam, LPARAM lParam )
{	
	// Déclaration des variables:
	static HWND hOuvrir,hLire,hArret,hRembob, hQuitter,hCadre1, hCadre2;//.....
	static SWFINFOS swi;

	// Interception et traitement des messages:
	switch(messg)
	{
		case WM_CREATE:
			// Créer tous les controles:
			hOuvrir=CreateWindow("BUTTON","Ouvrir",WS_CHILD | WS_VISIBLE,20,428,90,20,hWnd,0,0,0);
			hLire=CreateWindow("BUTTON","Lire",WS_CHILD | WS_VISIBLE,170,428,90,20,hWnd,0,0,0);
			hArret=CreateWindow("BUTTON","Arrêter",WS_CHILD | WS_VISIBLE,270,428,90,20,hWnd,0,0,0);
			hRembob=CreateWindow("BUTTON","Rembobiner",WS_CHILD | WS_VISIBLE,370,428,90,20,hWnd,0,0,0);
			hQuitter=CreateWindow("BUTTON","Quitter",WS_CHILD | WS_VISIBLE,520,428,90,20,hWnd,0,0,0);			
			hCadre1=CreateWindow("BUTTON","",BS_GROUPBOX | WS_CHILD | WS_VISIBLE,15,415,600,37,hWnd,0,0,0);
			hCadre2=CreateWindow("STATIC","",SS_SUNKEN | SS_CENTER | WS_CHILD | WS_VISIBLE,0,0,632,420,hWnd,0,0,0);
			break;

		case WM_COMMAND:
			if( (HWND)lParam ==  hOuvrir)
			{
				// Déclarer et intialiser un buffer:
				char tampon[MAX_PATH];
				tampon[0]=0;
				// Déclarer une structure OPENFILENAME:
				OPENFILENAME ofn;
                // Mettre tous les membres de la structure à 0:
                memset( &ofn, 0, sizeof(OPENFILENAME) );
                // Définir les membres:
                ofn.lStructSize = sizeof(OPENFILENAME);
				ofn.hwndOwner = hWnd;
                ofn.lpstrFilter = "Animations Macromedia Flash\0*.swf\0\0";				
                ofn.lpstrFile = tampon;
                ofn.nMaxFile = MAX_PATH;
                ofn.lpstrTitle = "Choisir un fichier :";
                ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
                // Lancer la boite de dialogue pour choisir un fichier:
                if(!GetOpenFileName(&ofn)) break;
				// Lire l'en-tête du fichier pour obtenir des infos sur l'animation:
				if(!LireEnTete(tampon,&swi)) 
				{
					// Afficher un message d'erreur quand le fichier n'est pas valide:
					MessageBox(hWnd,"\nLe fichier que vous avez tenté d'ouvrir n'est pas une animation Flash valide.","Lecteur d'animations Flash",0);
					break;
				}
				// Obtenir la version du composant ShockwaveFlash installé:
				long version;
				pIswf->FlashVersion(&version);
				if(swi.version>HIWORD(version))
				{
					// Afficher un message d'erreur quand la version de l'animation est plus récente que le composant installé:
					MessageBox(hWnd,"\nLa version de cette animation est plus récente que celle du composant installé.","Lecteur d'animations Flash",0);
					break;
				}
				// Appel de la fonction qui calcule la position et les dimensions du conteneur:
				RECT rct;
				PosDim(hWnd,swi.largeur,swi.hauteur,&rct);
				// Positionner le conteneur:
				MoveWindow(hConteneur,rct.left,rct.top,rct.right,rct.bottom,1);
				// Initialiser la couleur de fond de l'animation:
				pIswf->put_BackgroundColor(swi.fond);
				// Convertir le chemin en UNICODE:
				WCHAR fichier[MAX_PATH];
				MultiByteToWideChar (CP_ACP, 0, tampon, -1, fichier, MAX_PATH+1);
				// Charger et jouer l'animation:
				pIswf->put_Movie(fichier);
				break;
			}

			// Clic sur le bouton "Arrêter":
			if((HWND)lParam ==  hArret)
			{				
				pIswf->Stop();	
				break;
			}
			// Clic sur le bouton "Lire":
			if((HWND)lParam ==  hLire)
			{				
				pIswf->Play();	
				break;
			}
			// Clic sur le bouton "Rembobiner":
			if((HWND)lParam ==  hRembob)
			{
				pIswf->Rewind();
				break;
			}
			// Clic sur le bouton "Quitter":
			if((HWND)lParam ==  hQuitter)
			{
				// Envoi du message WM_CLOSE à notre fenêtre:
				SendMessage(hWnd,WM_CLOSE,0,0);
			}
			break;

		case WM_CLOSE:
			// Détruire la fenêtre principale:
			DestroyWindow(hWnd);
			break;

		case WM_DESTROY:
			// Envoyer le message de sortie du programme:
			PostQuitMessage(0);
			break;
	
		default:
			//Retour à la procédure par défaut:
			return( DefWindowProc( hWnd, messg, wParam, lParam ) );
	}
	return 0;
}
//---------------------------------------------------------------------------------//

//------------------------------ Fonction WinMain -----------------------------------------//
int WINAPI WinMain( HINSTANCE hInst,HINSTANCE hPreInst,LPSTR lpszCmdLine, int nCmdShow )
{
	
	// Charger la zlib.dll:
	HINSTANCE hDLL1 = LoadLibrary("zlib.dll");
	// Si dll introuvable alors l'installer à partir de la resoource:
	if (!hDLL1) 
	{
		// Obtenir le chemin complet de l'application:
		char path[MAX_PATH]; 
		DWORD longueur=GetModuleFileName(0,path,MAX_PATH);
		// Supprimer le nom de fichier du chemin:
		for(int i=longueur;i>0;i--) 
		{
			if (path[i]=='\\') {path[i]=0; break;}
		}
		// Ajouter le nom de la dll au chemin:
		lstrcat(path,"\\zlib.dll");    
		// Trouver la ressource:
		HRSRC DLLressource=FindResource(0,"ID_DLL","RT_RCDATA");
		// Déterminer sa taille:
		DWORD taille=SizeofResource(0,DLLressource);
		// Charger la ressource en mémoire:
		HGLOBAL hRessource=LoadResource(0,DLLressource);
		// Obtenir un pointeur sur cette zone mémoire:
		LPVOID pointeur=LockResource(hRessource);
		// Créer le fichier destination:
		HANDLE  hFichier=CreateFile(path,GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
		// Copier la ressource dans le fichier:
		DWORD ecrits;
		WriteFile(hFichier,pointeur,taille,&ecrits,0);
		// Fermer le fichier:
		CloseHandle(hFichier);
		// Libérer la ressource de la mémoire:
		FreeResource (hRessource);
		// Charger la dll en mémoire:
		hDLL1 = LoadLibrary("zlib.dll");
		// Si erreur de chargement de la dll alors quitter:
		if (!hDLL1) return 1;
	}
	// Obtenir un pointeur sur la fonction "uncompress":
	uncompress = (Puncompress) GetProcAddress(hDLL1,"uncompress");
	// Définir type de pointeur pour la fonction AtlAxAttachControl:
	typedef HRESULT (WINAPI *PAttachControl)(IUnknown*, HWND,IUnknown**);
	// Charger la atl.dll:
	HINSTANCE hDLL2 = LoadLibrary("atl.dll");
	// Si dll non chargée alors quitter:
	if (!hDLL2) return 1;
	// Obtenir pointeur sur la fonction AtlAxAttachControl:
	PAttachControl AtlAxAttachControl = (PAttachControl) GetProcAddress(hDLL2, "AtlAxAttachControl");
	// Déclarer notre classe de fenêtre et définir ses membres:
	WNDCLASS wc;
	char NomClasse[]    = "Lecteur_Flash";
	wc.lpszClassName 	= NomClasse;
	wc.hInstance 		= hInst;
	wc.lpfnWndProc		= WndProc;
	wc.hCursor			= LoadCursor( 0, IDC_ARROW );
	wc.hIcon			= LoadIcon( hInst, "ID_ICO" );
	wc.lpszMenuName	    = 0;
	wc.hbrBackground	= GetSysColorBrush(COLOR_BTNFACE);
	wc.style			= 0;
	wc.cbClsExtra		= 0;
	wc.cbWndExtra		= 0;
	// Enregistrer la classe de notre fenêtre:
	if (!RegisterClass(&wc)) return 0;
	// Obtenir la hauteur de la barre de titre:
	int barre=GetSystemMetrics(SM_CYCAPTION);
	// Créer notre fenêtre principale:
	HWND hWnd = CreateWindow( NomClasse," Lecteur d'animations Flash",WS_SYSMENU | WS_MINIMIZEBOX  ,0,0,640,460+barre, 0, 0, hInst,0);
	// Montrer la fenêtre:
	ShowWindow(hWnd, nCmdShow );
	UpdateWindow( hWnd );
	// Créer notre EDIT conteneur:
	hConteneur=CreateWindow("STATIC","",WS_CHILD | WS_VISIBLE ,0,0,0,0,hWnd,0,0,0);
	// Initialiser la librairie COM:
	CoInitialize(0);
	// Créer une instance de l'interface IShockwaveFlash:
	HRESULT res=CoCreateInstance(CLSID_ShockwaveFlash,0,CLSCTX_ALL,IID_IShockwaveFlash,(void**)&pIswf);
	// Attacher l'interface à notre conteneur:
	res =AtlAxAttachControl(pIswf,hConteneur,NULL); 
	// Boucle des messages:
	MSG Msg;
	while( GetMessage(&Msg, 0, 0, 0))
	{
		TranslateMessage( &Msg );
		DispatchMessage( &Msg );
	}
	// Libérer notre instance de IShockwaveFlash;
	pIswf->Release();
	// Fermer la librairie COM:
	CoUninitialize();
	// Libérer les DLLs:
	FreeLibrary(hDLL1);
	FreeLibrary(hDLL2);
	// Quitter le programme:
	return( Msg.wParam);
}
//--------------------------------------------------------------------------------------------------//

Conclusion :


Le projet complet est dans le zip.

Codes Sources

A voir également

Ajouter un commentaire Commentaires
Messages postés
61
Date d'inscription
mercredi 24 septembre 2008
Statut
Membre
Dernière intervention
16 juin 2012
1
Bonjour,

Tout d'abord merci pour cette source très très bien codée et commentée.
J'ai essayé de le compiler avec Code::Blocks 8.02 et il me met les messages d'erreur suivant :

262|undefined reference to `_CoInitialize@4'|
264|undefined reference to `_CoCreateInstance@20'|
277|undefined reference to `_CoUninitialize@0'|

Est-ce que vous savez comment résoudre ce problème ???
Merci d'avance
Messages postés
4
Date d'inscription
mercredi 8 juillet 2009
Statut
Membre
Dernière intervention
31 juillet 2009

d'ailleurs la définition du conteneur n'a plus lieu d'être

donc la ligne HWND hConteneur; est inutile.
Messages postés
4
Date d'inscription
mercredi 8 juillet 2009
Statut
Membre
Dernière intervention
31 juillet 2009

// OPOS1000.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#import"C:\\Program Files\\Posiflex Inc\\Posiflex OPOS Control\\LineDisp\\OPOSLineDisplay.ocx"\
rename("CreateWindow", "CreateWindov")

OposLineDisplay_1_8_Lib::IOPOSLineDisplay *m_opos;

const GUID CLSID_IOPOSLineDisplay = {0xccb90102,0xb81e,0x11d2,{0xab,0x74,0x00,0x40,0x05,0x4c,0x37,0x19}};
const GUID IID_IOPOSLineDisplay = {0xccb94101,0xb81e,0x11d2,{0xab,0x74,0x00,0x40,0x05,0x4c,0x37,0x19}};

HWND hConteneur;

int main(int argc, char* argv[])
{
HRESULT res = 5;
short a = 10;
LPCTSTR DeviceName = "LD demo";

CoInitialize(0);
CoCreateInstance(CLSID_IOPOSLineDisplay,0,CLSCTX_ALL,IID_IOPOSLineDisplay,(void**)&m_opos);

res = m_opos->get_DeviceEnabled(&a);
printf("get()_DeviceEnabled() : %d\n",res);

res = m_opos->Open(DeviceName);
printf("Open() : %d\n",res);
res = m_opos->ClaimDevice(300);
//res = m_opos->put_DeviceEnabled(TRUE);
//res = m_opos->DisplayText("abc", 0 );
//res = m_opos->DisplayTextAt(1,0,"abc", 0 );

return 0;

}
je penses avoir réussi à ne pas le mettre dans un conteneur. En tout cas ça marche sous une application console.
C'est pas le même activex qu'avant mais en fait c'est celui que je voulais utilisé mais il avait un petit défaut de redéfinition de la fonction createwindow que j'ai réussi à corriger.
Messages postés
33
Date d'inscription
mercredi 12 septembre 2007
Statut
Membre
Dernière intervention
30 juin 2008

Si tu veux le rendre invisible à l'écran, tu peux toujours le mettre dans une fenêtre de dimensions 0x0.

Tu auras le son et pas la vidéo par exemple..
Messages postés
4
Date d'inscription
mercredi 8 juillet 2009
Statut
Membre
Dernière intervention
31 juillet 2009

Bonjour, en fait j'ai fini par réussir j'avais pas vu qu'il fallait utiliser un using name space dans le fichiers . tlh. Ce qui fait que maintenant je suis arrivé à appeler directement l'interface importé et donc ça marche beaucoup mieux.

Juste question il n'y a aucun moyen d'importer l'activex sans l'insérer dans une fenêtre ?

Merci
Afficher les 40 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.