Back to Amir Israeli Homepage

[CILVideo : (Netscape,Explorer) video window ]

This article was contributed by Amir Israeli Amir Israeli.
Amir Israeli Web Site

Environment: Win 95/98 VC6 SP4

CILVideo is a very simple class .
This is a CWnd derived class which contains a bitmap. This bitmap represents several images : the same as an image-list. (Image lists are bitmaps , sometimes 2 bitmaps : 1 for mask) You create a window by calling 2 optional functions : the second function is useful on dialog windows , and it just determines the size of the wanted window and calls Create(...)

	BOOL Create(UINT nID,CWnd *pParent,RECT &rc);
	BOOL CreateFromStatic(UINT nID,CWnd *pParent);
Several functions are concerned with setting link to that image: when you set a hand cursor (by using SetHandCursor(TRUE) - You may also unset hand cursor- and sets valid links to the image : you provide means of navigation. The default of class sdemands a hand cursor when you want to navigate . (In order to make it appear like a browser)
	void SetLink(LPCTSTR lpszLink=NULL) {
		if (lpszLink) strLink=lpszLink;
	}
Navigation is activated when you double-click : then theres a check for valid hand cursor and non NULL link and , a call to ShellExecute. Invalidate is called in order to repaint the window. (Processing of ShellExecute is long and the window might not get WM_PAINT on time , if hidden ...)
void CILVideo::OnLButtonUp(UINT nFlags, CPoint point) 
{
	CWnd::OnLButtonUp(nFlags, point);
	if (hCursorHand && strLink.GetLength())
	{
		::ShellExecute(m_hWnd,_T("open"),strLink,NULL,NULL,SW_SHOWDEFAULT);
		Invalidate();
		UpdateWindow();
	}
}
Several functions manage playing images , stopping them and so on. When playing : a default timer is set and each time its function handler is called , a counter of the current step is incremented and the next step is done . Whenever I speak about steps , I mean the next episode (Image in series of images in image list) You may also want to reset the frequency (hou quick images are changed) : although the default is suitable for most scenarios, on doing that the Window stops immediately the timer (if its playing) and sets a new timer and replays animation.
You stop animation by calling Pause(). The timer is stop to conserve system resources. When you play again, it is being set again.
Two differnet function determine whats the order of showing images. The default behaviour shoes them by index order : from low->top. But you may also set a different behaviour .
Lets assume ythe bitmap represents 5 images indexed 0,1,2,3,4. The default behaviour calls them on this order : 0,1,2,3,4,0,1,2,3,4,0,1,2,3,4 ... Another way of showing : 0,1,2,3,4,3,2,1,0,1,2,3,4,3,2,1,0, ... This means that when we display an edge image the next step will return to that that preceded the current step.
When you play by order the first result is taken place. SetPlayMode(TRUE) or else you want to make (FALSE); The window also remembers the current step and behaviour (inside member variables : m_nPosition , m_bDoByOrder. On the second behaviour it also remembers direction (m_nDirection) whether its up/down.
	void SetPlayMode(BOOL bDoByOrder) { m_bDoByOrder=bDoByOrder; } 
	BOOL GetPlayMode() { return m_bDoByOrder; } 
Another feature that is added here is the ability to stretch each image to the size of the window , or to reset window size to the size of the image. You do it when you load that bitmap. The last parameter of LoadBitmap is a boolean: when bAdjust=TRUE you resize client rect to the size of each image (every images has the same size) On FALSE the image will be stretched to fit the size of the window. (This is useful when window is placed within rebar-ctrl , and moves between bands : which have different height , you may resize the window and images will automaticly be stretched . Internet Explorer loads several images into its video on top. (This is another approach).
	BOOL LoadBitmap(LPCTSTR lpszResourceName,int cx,int cy,BOOL bAdjust=TRUE);
	BOOL LoadBitmap(UINT nID,int cx,int cy,BOOL bAdjust=TRUE) {
		return LoadBitmap(MAKEINTRESOURCE(nID),cx,cy,bAdjust);
	}
Stretching is done on 2 ways the first is done by cally StretchBlt , the secont is BitBlt on a different mapping mode. I left 2 OnPaint() functions to demonstrate both ways . Which one is better ? (My eye doesnt notice any difference in speed nor clarity)
A look into OnPaint that is done by using map - mode shows that I assign MM_ANISOTROPIC to client area device context . All that steps a ssign a logical size of image to the whole client are. (The client are is -logicly- the same as image ) so BitBlt can be done easily. The mesurements of BitBlt is recalculated by CDC , to paint the proper sizes in device coordinates.
The second function of OnPaint (that uses StretchBlt) is easier to understand. : I simply stretch the size of image to the size of client rect.
void CILVideo::OnPaint() 
{
	// ...


	if (!bAdjustWindow2IconSize) { // do stretch
		nPrevMM = dc.SetMapMode(MM_ANISOTROPIC);
		szPrevWinExt = dc.SetWindowExt(m_ImageSize);
		szPrevVPExt = dc.SetViewportExt(rc.Width(),rc.Height());
	}
	// for all (BitBlt that does StretchBlt)
	::BitBlt(dc.GetSafeHdc(),0,0,m_ImageSize.cx,m_ImageSize.cy, 
				memDC.GetSafeHdc(),m_StartPoint.cx,m_StartPoint.cy,SRCCOPY);
	if (!bAdjustWindow2IconSize) { // do stretch
		dc.SetViewportExt(szPrevVPExt);
		dc.SetWindowExt(szPrevWinExt);
		dc.SetMapMode(nPrevMM);

	// ...

}

All images that you see are taken from Internet Explorer 4+5 Dlls : (property of Microsoft) : They really make a huge mess with their Dlls and resources , each version I need to relook for them again. Why messing them around? The application uses some resources I exported from (Internet Explorer 4) "msoleres.dll" this dll resides under \Program Files\Outlook Express\ you will find inside many of resources being used by microsoft applications . (the VB env. also contains a sample that uses a bitmap to do animation instead of an animation file. (Internet Explorer version 5+ {system directory}\\browseui.dll
This version doesnt use some additional features (remove to make everything lighter) such as loading Imagelist (variable : HIMAGELIST hImage; and rotation)
I also provided a demo project to show everything.

Move to downloads downloads

History

Date Posted: February 3, 2001

Home  |  Links  |  About