BREWアプリを Windows へ移植(3)
今移植している BREWアプリで使っている IShell インターフェースは、AddRef(), Release(), CreateInstance(), GetDeviceInfo(), SetTimer(), CancelTimer() ぐらいなので、それだけはちゃんと実装してやって、それ以外は例外を投げてやることにします。
まずは仮想テーブルの登録から。長いので注意。
class WinShell : public IShell{ public: WinShell(); public: void UpdateTimer(); private: static uint32 AddRef(IShell*); static uint32 Release(IShell*); static int CreateInstance(IShell * po, AEECLSID ClsId, void ** ppobj); static boolean QueryClass(IShell * po, AEECLSID cls, AEEAppInfo * pai); static void GetDeviceInfo(IShell * po, AEEDeviceInfo * pi); // Applet Launching/Close Routines... static int StartApplet(IShell *po, AEECLSID cls,uint16 wFlags, const char * pszArgs); static int CloseApplet(IShell * po, boolean bReturnToIdle); static boolean CanStartApplet(IShell * po, AEECLSID cls); static AEECLSID ActiveApplet(IShell * po); static void EnumAppletInit(IShell * po); static AEECLSID EnumNextApplet(IShell * po, AEEAppInfo * pai); // Time routines... static int SetTimer(IShell * po, int32 dwMsecs, PFNNOTIFY pfn, void * pUser); static int CancelTimer(IShell * po, PFNNOTIFY pfn, void * pUser); static uint32 GetTimerExpiration(IShell * po, PFNNOTIFY pfn, void * pUser); // Dialog Routines... static int CreateDialog_(IShell * po, const char * pszRes, uint16 wID, DialogInfo * pInfo); static IDialog * GetActiveDialog(IShell * po); static int EndDialog(IShell * po); // Resource file stuff... static int LoadResString(IShell * pShell, const char * pszBaseFile, uint16 nResID, AECHAR * pBuff, int nSize); static void * LoadResData(IShell * po, const char * pszResFile, uint16 nResID, ResType nType); static IBase * LoadResObject(IShell * pShell,const char * pszResFile, uint16 nResID, AEECLSID cls); static void FreeResData(IShell * po, void * pData); // Event handling... static boolean SendEvent(IShell * po, uint16 wFlags, AEECLSID clsApp,AEEEvent evt, uint16 wParam, uint32 dwParam); // Alerts... static boolean Beep(IShell * po, BeepType nBeepType, boolean bLoud); // Configuration - Deals with file system... static int GetPrefs(IShell * po, AEECLSID id,uint16 wVer, void * pCfg, uint16 nSize); static int SetPrefs(IShell * po, AEECLSID id,uint16 wVer, void * pCfg, uint16 nSize); // Item Style retrieval static void GetItemStyle(IShell * po, AEEItemType t, AEEItemStyle * pNormal, AEEItemStyle * pSel); // Message Box Stuff... static boolean Prompt(IShell * po, AEEPromptInfo * pi); static boolean MessageBox(IShell * po, const char * pszRes, uint16 wTitle, uint16 wText); static boolean MessageBoxText(IShell *po, const AECHAR * pTitle, const AECHAR * pText); // Alarm Stuff - Allows applets to register a persistent alarm without an in-memory timer... static int SetAlarm(IShell *po, AEECLSID cls, uint16 nUserCode, uint32 nMins); static int CancelAlarm(IShell *po, AEECLSID cls, uint16 nUserCode); static boolean AlarmsActive(IShell *po); // Registry static AEECLSID GetHandler(IShell * po, AEECLSID cls, const char * pszIn); static int RegisterHandler(IShell * po, AEECLSID clsBase, const char * pszIn, AEECLSID clsHandler); static int RegisterNotify(IShell * po, AEECLSID clsNotify, AEECLSID clsType, uint32 dwMask); static int Notify(IShell * po,AEECLSID clsType, uint32 dwMask, void * pData); // Resume... static void Resume(IShell * po, AEECallback * pcb); // Task Stuff... static boolean ForceExit(IShell * po); // gpsOne Interface(s) static int GetPosition(IShell * po, AEEPosAccuracy nPres, PFNPOSITIONCB pfn, void * pUser); // static boolean CheckPrivLevel(IShell * po, uint16 wPrivWant, boolean bQueryOnly); // Resource validation static boolean IsValidResource(IShell * po, const char * pszRes, uint16 wID,ResType t, AEECLSID cls); static void * LoadResDataEx(IShell * po, const char * pszResFile, uint16 nResID, ResType nType, void *pBuf, uint32 *pnLen); // System-level direct notifications static void RegisterSystemCallback(IShell * po, AEECallback * pcb, int nSCBType); // Detects type based on data in the buffer or name of the object and returns MIME. Buffer has the highest precedence. static int DetectType(IShell * po, const void * cpBuf, uint32 * pdwSize, const char * cpszName, const char ** pcpszMIME); //Get specific Device Info static int GetDeviceInfoEx(IShell *po, AEEDeviceItem nItem, void *pBuff, int *nSize); static uint32 GetClassItemID(IShell *po,AEECLSID cls); private: IShellVtbl _vtbl; uint32 _ref; }; WinShell::WinShell() : _ref( 1 ){ _vtbl.AddRef = &AddRef; _vtbl.Release = &Release; _vtbl.CreateInstance = &CreateInstance; _vtbl.QueryClass = &QueryClass; _vtbl.GetDeviceInfo = &GetDeviceInfo; _vtbl.StartApplet = &StartApplet; _vtbl.CloseApplet = &CloseApplet; _vtbl.CanStartApplet = &CanStartApplet; _vtbl.ActiveApplet = &ActiveApplet; _vtbl.EnumAppletInit = &EnumAppletInit; _vtbl.EnumNextApplet = &EnumNextApplet; _vtbl.SetTimer = &SetTimer; _vtbl.CancelTimer = &CancelTimer; _vtbl.GetTimerExpiration = &GetTimerExpiration; _vtbl.CreateDialog = &CreateDialog_; _vtbl.GetActiveDialog = &GetActiveDialog; _vtbl.EndDialog = &EndDialog; _vtbl.LoadResString = &LoadResString; _vtbl.LoadResData = &LoadResData; _vtbl.LoadResObject = &LoadResObject; _vtbl.FreeResData = &FreeResData; _vtbl.SendEvent = &SendEvent; _vtbl.Beep = &Beep; _vtbl.GetPrefs = &GetPrefs; _vtbl.SetPrefs = &SetPrefs; _vtbl.GetItemStyle = &GetItemStyle; _vtbl.Prompt = &Prompt; _vtbl.MessageBox = &MessageBox; _vtbl.MessageBoxText = &MessageBoxText; _vtbl.SetAlarm = &SetAlarm; _vtbl.CancelAlarm = &CancelAlarm; _vtbl.AlarmsActive = &AlarmsActive; _vtbl.GetHandler = &GetHandler; _vtbl.RegisterHandler = &RegisterHandler; _vtbl.RegisterNotify = &RegisterNotify; _vtbl.Notify = &Notify; _vtbl.Resume = &Resume; _vtbl.ForceExit = &ForceExit; _vtbl.GetPosition = &GetPosition; _vtbl.CheckPrivLevel = &CheckPrivLevel; _vtbl.IsValidResource = &IsValidResource; _vtbl.LoadResDataEx = &LoadResDataEx; _vtbl.RegisterSystemCallback = &RegisterSystemCallback; _vtbl.DetectType = &DetectType; _vtbl.GetDeviceInfoEx = &GetDeviceInfoEx; _vtbl.GetClassItemID = &GetClassItemID; this->pvt = &_vtbl; }
最後の、pvt に仮想テーブルへのポインタを渡しているところが、仮想テーブルを登録している部分です。
これで、ISHELL_* を介して自分の登録した関数が呼び出せるようになります。
あと、IShell インターフェースオブジェクトは関数の数が多いので、AEEShell.h からコピペしてきて、正規表現等で一括で変換してやればいいかと。