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 からコピペしてきて、正規表現等で一括で変換してやればいいかと。