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

来源:互联网 发布:好玩的手游推荐 知乎 编辑:程序博客网 时间:2024/06/14 09:31

本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" onclick="#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" onclick="#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" onclick="#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" onclick="#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 ){WCHARbuff[MAX_PATH];VARIANT_BOOLvarRet;CComPtr<IHLXImage>spImage;#ifdef_DEBUGDWORDclk=::GetTickCount();#endifif( 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)) ){LONGcount;if( spAnimation->frameCount(&count) == S_OK && count > 2 )SetTimeClick(10);}#ifdef_DEBUGm_dwCreateImageTickCount += ::GetTickCount()-clk;#endifreturn spImage;}#ifdef_DEBUGm_dwCreateImageTickCount += ::GetTickCount()-clk;#endif}}return NULL;}

bool CCommonUtility::ParseUrl( LPCWSTR lpUrlName ,LPCWSTR lpTage ,LPWSTR buff ,UINT length ){DWORDdwUrl,dwTage;LPCWSTRpTargetName;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--;}elsewcscat(buff,pTargetName);buff[dwUrl+dwTage] = OLECHAR('\0');return true;}}return false;}

bool CCommonUtility::CreateImageObject(LPCWSTR lpFullName ,IHLXImage** ppImage ){CComPtr<IHLXImage>pImage;LPCWSTRkey=OLESTR("HLXLib.Typeinfo\\.");WCHARtype[25],value[MAX_PATH];LPCWSTRlpName;CRegKeyhkey;ULONGdwLength;#ifdef_DEBUGDWORDclk=::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_DEBUGm_dwImageTickCount += ::GetTickCount()-clk;#endifreturn true;}}}#ifdef_DEBUGm_dwImageTickCount += ::GetTickCount()-clk;#endifreturn 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 和繪圖引擎的關係