建置一個 WINCE 下的 XML BASE 的人機介面引擎 ---- 繪圖引擎篇 (2)

本BLOG所有原創之原始程式碼皆為本人創作,非經本人同意不得轉載,非經本人授權不得使用在營利用途

資源正規化及圖像工廠

在上一篇中 点击打开链接 只是先把2個關鍵的Decoder 的實作,與相關的 INTERFACE POST 出來 ,至於要如何用在此要先說明一個觀念,

這也是這個 XML BASE 的人機介面引擎中極為重要的事,資源正規化在我簡介資源正規化前我先給大家看一下,已完成後的引擎,他所用的 XML 是如何寫的


Multimedia.XML

<?xml version="1.0" encoding="utf-8" ?>
<root boot="main" >
<dialog id="Multimedia" fullsize="1" url="\resource\Multimedia" background="img://Multimedia-Multimedia.png" font="Arial" font-width="5" font-height="18" font-color="16777215" font-weight="600" >

	<controls>
		<text value="@16" style="left" top="0" left="8" right="160" bottom="24" />

	   <clock top="8" left="348" right="435" bottom="24" font="Arial" font-width="6" font-height="18" font-color="16777215" font-weight="600" />
		<battery id="battery" proxy="battery" top="5" left="434" right="475" bottom="27" />

		<button top="70" left="15" text-top="190" text-bottom="218" value="@17" normal="img://Multimedia-135.png" active="img://Multimedia-135-a.png" οnclick="#window.Navigate('resource\music.xml','music')"/>

		<button top="70" left="135" text-top="190" text-bottom="218" value="@44" normal="img://Multimedia-136.png" active="img://Multimedia-136-a.png" οnclick="#window.Navigate('resource\video.xml','video')"/>

		<button top="70" left="245" text-top="190" text-bottom="218" value="@63" normal="img://Multimedia-137.png" active="img://Multimedia-137-a.png" οnclick="#window.Navigate('resource\photo.xml','photo')"/>

		<button top="70" left="370" text-top="190" text-bottom="218" value="@79" normal="img://Multimedia-138.png" active="img://Multimedia-138-a.png" οnclick="#window.closewindow(0)"/>
	</controls>
   </dialog>

</root>

這篇就是其中的一頁,用在一些Multimedia功能的設定,其他的 tag 都先不用管 ,我們先注意2點

1. url="\resource\Multimedia"

2. background="img://Multimedia-Multimedia.png"


有沒有注意到url="\resource\Multimedia",這是表示,這個 dialog 所用的資源在預設下都由"\resource\Multimedia"這目錄去找

所以當引擎看到 background 時便知道背景圖是去找 "\resource\Multimedia\Multimedia-Multimedia.png"

而如果沒定url 引擎便以父 dialog的url去找,一直找到根,如果連根的url也是沒定義,便以引擎預設值為url

而 img:// 便是型態工廠部份 ,當引擎看到background便以img://Multimedia-Multimedia.png去問型態工廠,

而型態工廠因為知道是background 而且是以圖型為主,便直接引至繪圖引擎,繪圖引擎便分析img://Multimedia-Multimedia.png,

知道要去找img 類別的decoder,於是便把imgdecoder載入,把Multimedia-Multimedia.png的完整路徑交給imgdecoder去load,這便是圖像工廠的觀念

而明定 url 資源的位置的表示規則,便是資源正規化的觀念


說了多那麼我們就直接看一下這部份的實作碼


CComPtr<IHLXImage>	CBackground::CreateImage( LPCWSTR lpCommand ,LONG lAlpha )
{
	WCHAR				buff[MAX_PATH];
	VARIANT_BOOL		varRet;	
	CComPtr<IHLXImage>	spImage;

#ifdef	_DEBUG
	DWORD	clk=::GetTickCount();
#endif
	if( ParseUrl(lpCommand,buff,MAX_PATH) )
	{

		if( CreateImageObject(lpCommand,&spImage) == true )		
		{
			spImage->put_AlphaMode(lAlpha);
			if( SUCCEEDED(spImage->load(buff,&varRet)) && varRet == VARIANT_TRUE )
			{
				CComPtr<IHLXAnimation>	spAnimation;

				if( SUCCEEDED(spImage.QueryInterface(&spAnimation)) )
				{
					LONG	count;

					if( spAnimation->frameCount(&count) == S_OK && count > 2 )
						SetTimeClick(10);
				}
#ifdef	_DEBUG
				m_dwCreateImageTickCount += ::GetTickCount()-clk;
#endif
				return spImage;
			}
#ifdef	_DEBUG
				m_dwCreateImageTickCount += ::GetTickCount()-clk;
#endif
		}
	}
	return NULL;
}

bool CCommonUtility::ParseUrl( LPCWSTR lpUrlName ,LPCWSTR lpTage ,LPWSTR buff ,UINT length )
{
	DWORD	dwUrl,dwTage;
	LPCWSTR	pTargetName;

	if( ((dwUrl=wcslen(lpUrlName)) + (dwTage=wcslen(lpTage))) < length )
	{
		if( (pTargetName=wcsstr(lpTage,OLESTR("://"))) )
		{
			pTargetName += 3;
			wcscpy(buff,lpUrlName);
			buff[dwUrl] = OLECHAR('\0');
			if( *pTargetName == WCHAR('/') )
			{
				wcscat(buff,pTargetName+1);
				dwTage--;
			}
			else			
				wcscat(buff,pTargetName);
			buff[dwUrl+dwTage] = OLECHAR('\0');
			return true;
		}		
	}
	return false;
}

bool CCommonUtility::CreateImageObject(LPCWSTR lpFullName ,IHLXImage** ppImage )
{
	CComPtr<IHLXImage>	pImage;
	LPCWSTR	key=OLESTR("HLXLib.Typeinfo\\.");
	WCHAR	type[25],value[MAX_PATH];
	LPCWSTR	lpName;
	CRegKey	hkey;
	ULONG	dwLength;
#ifdef	_DEBUG
	DWORD	clk=::GetTickCount();
#endif
	::wmemset(type,0,sizeof(type)/sizeof(WCHAR));
	if( (lpName=wcsstr(lpFullName,OLESTR("://"))) != NULL && (lpName-lpFullName) == 3 )
	{		
		dwLength = MAX_PATH;
		wmemcpy( type ,key ,wcslen(key));
		wmemcpy( type+wcslen(key) ,lpFullName ,3);
		if( hkey.Open(HKEY_CLASSES_ROOT,type) == ERROR_SUCCESS && hkey.QueryStringValue(L"",value,&dwLength) == ERROR_SUCCESS )
		{			
			if( SUCCEEDED(pImage.CoCreateInstance(value)) && pImage != NULL )
			{
				*ppImage=pImage.Detach();
#ifdef	_DEBUG
				m_dwImageTickCount += ::GetTickCount()-clk;
#endif
				return true;
			}			
		}
	}
#ifdef	_DEBUG
	m_dwImageTickCount += ::GetTickCount()-clk;
#endif
	return false;
}



上面便是圖像工廠的實作部份,很簡單對不對


也許有人不能理解為什麼上面的碼有辦法正確找的到img 對映的decoder,其實關鍵是在

LPCWSTR key=OLESTR("HLXLib.Typeinfo\\."); 這行碼,還不了解嗎?

我們再看一個檔 IMGDecoder.rgs

HKCR
{
	HLXDocvw.IMGDecoder.1 = s 'IMGDecoder Class'
	{
		CLSID = s '{11D7BE59-D81D-48D3-A551-B9EB208F0123}'
	}
	HLXDocvw.IMGDecoder = s 'IMGDecoder Class'
	{
		CLSID = s '{11D7BE59-D81D-48D3-A551-B9EB208F0123}'
		CurVer = s 'HLXDocvw.IMGDecoder.1'
	}
	NoRemove CLSID
	{
		ForceRemove {11D7BE59-D81D-48D3-A551-B9EB208F0123} = s 'IMGDecoder Class'
		{
			ProgID = s 'HLXDocvw.IMGDecoder.1'
			VersionIndependentProgID = s 'HLXDocvw.IMGDecoder'
			ForceRemove 'Programmable'
			InprocServer32 = s '%MODULE%'
			{
				val ThreadingModel = s 'Both'
			}
			val AppID = s '%APPID%'
			'TypeLib' = s '{35CEFEE5-2058-4A33-B234-89AD330B5AD0}'
		}
	}
	NoRemove HLXLib.Typeinfo
	{
		.img = s 'HLXDocvw.IMGDecoder'
	}
}

這個是一般 ATL 會幫你產生的一個註冊檔,用來去登註去 Windows系統,這個COM才能正常使用,但是最後一段卻不像是ATL加入的?
沒錯!

{.img = s 'HLXDocvw.IMGDecoder'}

便是用來關連的部份,decoder 只要在註冊檔加入這段,圖像工廠便會去 HLXLib.Typeinfo 下找有沒有 img 這類別的decoder存在,如果找到

便用登註的progid 去建出 HLXDocvw.IMGDecoder ,並用IHLXImage界面把完整路徑交給IHLXImage去load,


像有人會問如果要用到 GIF,可是如果 img沒有 GIF的解碼,那這引擎不就是癈物一個? 

別急,由 imgdecoder 同理可知,只要寫出一個decoder ,依引擎定的規則去註冊,再提供IHLXImage 給引擎叫用,不就GIF可以解碼

所以只要有了圖像工廠不管以後有什麼新的圖像格式,只要寫個decoder再登註,引擎就有辦法把這個圖檔正確讀出,這便是把 Decoder 裝置化的過程

好了解釋完繪圖引擎如何把已知未知的圖片讀取整合的方式後,下篇再分別解釋 IHLXImage系列INTERFACE 和繪圖引擎的關係



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值