Results 1 to 21 of 21

Thread: CoGetObject API -- Initialize and get a pointer to the Office IRibbonUI Interface ?

  1. #1

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2013
    Posts
    658

    Exclamation CoGetObject API -- Initialize and get a pointer to the Office IRibbonUI Interface ?

    Hi all,

    I am trying to get a pointer to the OFFICE IRibbonUI Interface using the CoGetObject API in the code below but the last OUT argument (ByRef ppv As Any) of the CoGetObject function returns an UnKnown type or an Object type instead of IRibbonUI type .

    Can anyone shed a light on this ?

    Thank you.

    Code:
    Option Explicit
    
    Private Type GUID
        data1    As Long
        data2    As Integer
        data3    As Integer
        data4(7) As Byte
    End Type
     
    Private Declare Function IIDFromString Lib "Ole32" ( _
    ByVal lpszIID As Long, _
    iid As Any) As Long
    
    Private Declare _
    Function CoGetObject Lib "Ole32" ( _
            ByVal pszName As Long, _
            ByVal pBindOptions As Long, _
            ByRef riid As GUID, _
            ByRef ppv As Any) As Long
     
    
    Sub Test()
    
        Dim iRibbon As IUnknown  ' As Object
        Dim iid     As GUID
        Dim hRes As Long
        
        Const IID_UNKNOWN As String = "{00000000-0000-0000-C000-000000000046}" 'Iunknown Interface GUID.
        
        'get the iunknown interface
        hRes = IIDFromString(StrPtr(IID_UNKNOWN), iid)
        
        'get pointer to the iRibbonUI interface
        '"{926749fa-2615-4987-8845-c33e65f2b957}" = UIRibbonFramework ClassID
        hRes = CoGetObject(StrPtr("new:926749fa-2615-4987-8845-c33e65f2b957"), 0, iid, iRibbon)
        
        MsgBox TypeName(iRibbon) '<=== Should return IRibbonUI but returns UnKnown
    
    End Sub
    Last edited by JAAFAR; Jul 18th, 2018 at 02:31 AM.

  2. #2
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    5,425

    Re: CoGetObject API -- Initialize and get a pointer to the Office IRibbonUI Interface

    TypeName works by calling methods on IDispatch interface. If you pass an object that does not implement IDispatch you will get a generic Unknown.

    This apparently is the case with RibbonUI impl -- as a consequence you cannot call it's methods late-bound or dimension a var to hold reference to it As Object.

    cheers,
    </wqw>

  3. #3

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2013
    Posts
    658

    Re: CoGetObject API -- Initialize and get a pointer to the Office IRibbonUI Interface

    Quote Originally Posted by wqweto View Post
    TypeName works by calling methods on IDispatch interface. If you pass an object that does not implement IDispatch you will get a generic Unknown.

    This apparently is the case with RibbonUI impl -- as a consequence you cannot call it's methods late-bound or dimension a var to hold reference to it As Object.

    cheers,
    </wqw>
    You are right about the Typename function ..

    I wonder if anyone has a way of getting a reference to the office IRibbonUI ..

    Here is some C code that Initializes the Ribbon framework and bind a Ribbon to the application :
    https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx

    I wonder if anyone here can do this in VB ?

    Regards.

  4. #4
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    5,425

    Re: CoGetObject API -- Initialize and get a pointer to the Office IRibbonUI Interface

    This will certainly need (ton of) interfaces/coclasses declared in a typelib.

    Not sure if recent oleexp typelib support these though, might try asking @fafalone to add these as well -- as the ribbon is OS provided UI feature/control now.

    cheers,
    </wqw>

  5. #5

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2013
    Posts
    658

    Re: CoGetObject API -- Initialize and get a pointer to the Office IRibbonUI Interface

    Quote Originally Posted by wqweto View Post
    This will certainly need (ton of) interfaces/coclasses declared in a typelib.

    Not sure if recent oleexp typelib support these though, might try asking @fafalone to add these as well -- as the ribbon is OS provided UI feature/control now.

    cheers,
    </wqw>
    I was hoping to make this work without the need for exterrnal typelibs for portability reasons .. I thought getting a reference to the IRibonUI interface wasn't going to be that difficult and it could be done with some imagination and a few of API calls .

    Still hoping

  6. #6
    PowerPoster
    Join Date
    Jun 2015
    Posts
    2,224

    Re: CoGetObject API -- Initialize and get a pointer to the Office IRibbonUI Interface

    Quote Originally Posted by JAAFAR View Post
    I was hoping to make this work without the need for exterrnal typelibs for portability reasons .. I thought getting a reference to the IRibonUI interface wasn't going to be that difficult and it could be done with some imagination and a few of API calls .

    Still hoping
    you can keep the references as IUnknown, and then use DispCallFunc to call it's methods. You still need to know the interface from a typelib - but without needing a typelib.

  7. #7
    Fanatic Member
    Join Date
    Feb 2017
    Posts
    905

    Re: CoGetObject API -- Initialize and get a pointer to the Office IRibbonUI Interface

    Found this paragraph that may be of benefit.
    A COM object must implement at least one interface, but it can implement as many as it likes. Objects that implement multiple interfaces must allow clients to navigate among them by calling QueryInterface. A client passes a desired IID when it calls QueryInterface, and the object responds by returning a reference to the interface. If the client asks for an interface that's not supported, the call to QueryInterface fails. If the call fails, the client can determine that the requested functionality isn't available and thus degrade gracefully.

  8. #8

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2013
    Posts
    658

    Re: CoGetObject API -- Initialize and get a pointer to the Office IRibbonUI Interface

    Quote Originally Posted by DEXWERX View Post
    you can keep the references as IUnknown, and then use DispCallFunc to call it's methods. You still need to know the interface from a typelib - but without needing a typelib.
    This is how far I have gotten :
    Code:
    Option Explicit
    
    Private Type GUID
        data1    As Long
        data2    As Integer
        data3    As Integer
        data4(7) As Byte
    End Type
    
    Private Declare Function DispCallFunc Lib "oleaut32.dll" _
        (ByVal pvInstance As Long, ByVal offsetinVft As Long, _
        ByVal CallConv As Long, ByVal retTYP As Integer, ByVal paCNT As Long, _
        ByRef paTypes As Integer, ByRef paValues As Long, ByRef retVAR As Variant) As Long
        
    Private Const CC_STDCALL As Long = 4
      
    Private Declare Sub SetLastError Lib "kernel32.dll" (ByVal dwErrCode As Long)
    
    Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
    (Destination As Any, Source As Any, ByVal Length As Long)
    
    
    Private Declare Function IIDFromString Lib "ole32" _
      (ByVal lpsz As Long, ByVal lpiid As Long) As Long
    
            
    Private Declare Function CoGetObject Lib "ole32" ( _
            ByVal pszName As Long, _
            ByVal pBindOptions As Long, _
            ByVal riid As Long, _
            ByRef ppv As Any) As Long
            
            
    Private Declare  Function GetModuleHandle Lib "kernel32" _
    Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long
    
    
    Sub Test()
    
        Dim iRibbon As IUnknown
        Dim iid(0 To 3) As Long
        Dim aGUID(0 To 3) As Long
        Dim hRes As Long
        Dim lPtr As Long
        Dim IRibbonExt As Long
        
        Const IID_UNKNOWN As String = "{00000000-0000-0000-C000-000000000046}" 'Iunknown Interface GUID.
        
        'get the iunknown interface
        hRes = IIDFromString(StrPtr(IID_UNKNOWN), VarPtr(iid(0)))
        
        'get pointer to the iRibbonUI interface
        '"{926749fa-2615-4987-8845-c33e65f2b957}" = UIRibbonFramework ClassID
        hRes = CoGetObject(StrPtr("new:926749fa-2615-4987-8845-c33e65f2b957"), 0, VarPtr(iid(0)), iRibbon)
        Debug.Print hRes   '<=== S_OK sucees!
        
        
        Const IUIFramework = "{F4F0385D-6872-43A8-AD09-4C339CB3F5C5}"
        hRes = IIDFromString(StrPtr(IUIFramework), VarPtr(aGUID(0)))
        Debug.Print hRes   '<=== S_OK sucees!
        
        lPtr = ObjPtr(iRibbon)
        
        Const IUnknownQueryInterface = 0
        hRes = CallFunction_COM(lPtr, IUnknownQueryInterface, vbLong, CC_STDCALL, VarPtr(aGUID(0)), VarPtr(IRibbonExt))
        Debug.Print hRes   '<=== S_OK sucees!
        
        
        Const Initialize_Method_VTable = 12
        hRes = CallFunction_COM(IRibbonExt, Initialize_Method_VTable, vbLong, CC_STDCALL, Application.Hwnd, ObjPtr(Application))
        Debug.Print hRes   '<=== S_OK sucees!
        
        
        Const LoadUI_Method_VTable = 24
        hRes = CallFunction_COM(IRibbonExt, LoadUI_Method_VTable, vbLong, CC_STDCALL, Application.Hinstance, VarPtr("APPLICATION_RIBBON"))
        Debug.Print hRes   '<=== Fail !!!! error code =-2147024809
    
    End Sub
    
    
    
    Private Function CallFunction_COM(ByVal InterfacePointer As Long, ByVal VTableOffset As Long, _
                                ByVal FunctionReturnType As Long, _
                                ByVal CallConvention As Long, _
                                ParamArray FunctionParameters() As Variant) As Variant
    
        '// minimal sanity check for these 4 parameters:
        If InterfacePointer = 0& Or VTableOffset < 0& Then Exit Function
        If Not (FunctionReturnType And &HFFFF0000) = 0& Then Exit Function ' can only be 4 bytes
    
        Dim pIndex As Long, pCount As Long
        Dim vParamPtr() As Long, vParamType() As Integer
        Dim vRtn As Variant, vParams() As Variant
        
        vParams() = FunctionParameters()                    ' copy passed parameters, if any
        pCount = Abs(UBound(vParams) - LBound(vParams) + 1&)
        If pCount = 0& Then                                 ' no return value (sub vs function)
            ReDim vParamPtr(0 To 0)
            ReDim vParamType(0 To 0)
        Else
            ReDim vParamPtr(0 To pCount - 1&)               ' need matching array of parameter types
            ReDim vParamType(0 To pCount - 1&)              ' and pointers to the parameters
            For pIndex = 0& To pCount - 1&
                vParamPtr(pIndex) = VarPtr(vParams(pIndex))
                vParamType(pIndex) = VarType(vParams(pIndex))
            Next
        End If
                                                            ' call the function now
        pIndex = DispCallFunc(InterfacePointer, VTableOffset, CallConvention, FunctionReturnType, _
                              pCount, vParamType(0), vParamPtr(0), vRtn)
            
        If pIndex = 0& Then                                 ' 0 = S_OK
            CallFunction_COM = vRtn                         ' return result
        Else
            SetLastError pIndex                             ' set error & return Empty
        End If
    
    End Function
    As you can see from the above code, I have managed to initialize the ribbon framework via the use of the DispCallFunc API function but I have failed to call the LoadUI Method .

    The reason is the second argument of the LoadUI Method which according to the documentation, it says :
    Second arg: Type: LPCWSTR
    The name of the resource that contains the compiled, binary markup
    Note To initialize the Ribbon successfully, a compiled Ribbon markup file must be available as a resource. This markup file is an integral component of the Ribbon framework; it specifies the controls to use and their layout.
    Obviously, In the code that I have posted, I passed VarPtr("APPLICATION_RIBBON") which is wrong.

    According to this, http://blogs.microsoft.co.il/arik/20...d-application/
    I have to compile the Ribbon UI with the UICC compiler as follows :
    UICC.exe RibbonMarkup.xml RibbonUI.bml /header:RibbonIDs.h /res:RibbonResource.rc
    which I did and it compiled successfuly and generated the files RibbonUI.bml and RibbonResource.rc respectively.

    So far so good .

    Now the problem that I am facing is that I need to compile the entire application as a final step in order to generate the final resource file but, because I need this for an excel/vba userform and not for a VB6 form I cannot generate the resource file to pass in the second argument of the LoadUI method .

    The idea I have is that if I could develop the code for generating the resource file in a C++ dll (in Visual Studio) , compile it and after that load the dll (LoadLibrary) in the excel memory sapce then I hope I could pass the VarPtr("APPLICATION_RIBBON") in the second argument of the LoadUI Method or use the LoadResource API for that .

    This is the idea I have ... Do you or anyone else here, think that this is the way to go ?

    Any advice would be much appreciated.

    Thanks for your help.
    Last edited by JAAFAR; Jul 19th, 2018 at 11:34 PM.

  9. #9
    PowerPoster
    Join Date
    Jun 2015
    Posts
    2,224

    Re: CoGetObject API -- Initialize and get a pointer to the Office IRibbonUI Interface

    you can compile the resource into a DLL, and load it from that.

    edit: I see you've already thought of that. once you loadlibrary, you can call GetModuleHandle on it, to pass to IRibbonExt::LoadUI()

    Also don't forget to call Release (it's just good practice)
    And I think you want to pass StrPtr("APPLICATION_RIBBON") ?

    Another thing:
    I have no experience using Office to host the Ribbon. From VB6 you would have to implement IUIApplication (without a typelib, you need to create a Lightweight COM Object) and provide the hWnd from the host form. I just don't know how you would then capture any Ribbon Events from Office otherwise. In fact - why wouldn't you use the built in functionality to create your own ribbon? Isn't that how every other add-in works? Why use the API...
    Last edited by DEXWERX; Jul 20th, 2018 at 07:57 AM.

  10. #10

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2013
    Posts
    658

    Re: CoGetObject API -- Initialize and get a pointer to the Office IRibbonUI Interface

    Quote Originally Posted by DEXWERX View Post
    you can compile the resource into a DLL, and load it from that.

    edit: I see you've already thought of that. once you loadlibrary, you can call GetModuleHandle on it, to pass to IRibbonExt::LoadUI()

    Also don't forget to call Release (it's just good practice)
    And I think you want to pass StrPtr("APPLICATION_RIBBON") ?

    Another thing:
    I have no experience using Office to host the Ribbon. From VB6 you would have to implement IUIApplication (without a typelib, you need to create a Lightweight COM Object) and provide the hWnd from the host form. I just don't know how you would then capture any Ribbon Events from Office otherwise. In fact - why wouldn't you use the built in functionality to create your own ribbon? Isn't that how every other add-in works? Why use the API...
    Thanks for responding DEXWERX.
    I just don't know how you would then capture any Ribbon Events from Office otherwise
    Yes, I left the issue of capturing the Ribbon events till the end ..I was thinking maybe I could use the ConectToConnectionPoint API to sink the newly created ribbon events at runtime(Not sure if that would work though)

    Anyway, for now, I just want to succeed in loading the Ribbon.

    why wouldn't you use the built in functionality to create your own ribbon? Isn't that how every other add-in works? Why use the API...
    Office ribbon addins\workbooks use the Office Ribbon (NOT the Windows Ribbon) which I only realised after posting this question and searching the subject.

    The IUIFramework, IUIApplication and IUICommandHandler interfaces are all parts of the Windows Ribbon Framework not part of the ribbon that Office applications use although they look and feel very similar ... Windows Ribbon and Office Ribbon are two different animals.

    I can't use the built in functionality (ie: Office Ribbon) to create my custom ribbon in my excel project because I want to add the custom ribbon commandbar to a Userform not to the main excel application window... So the only way is the API way.

    Plus as usual, my ultimate objective is trying to learn how I can implemnt COM Interfaces in VBA without needing a typelib... APIs such as DispCallFunc and ConnectToConnectionPoint are two excellent potential candidates (both of which I have used with success in some vb\vba projects) but I believe they are under-explored in VB6/VBA.
    Last edited by JAAFAR; Jul 20th, 2018 at 10:07 AM.

  11. #11
    PowerPoster
    Join Date
    Jun 2015
    Posts
    2,224

    Re: CoGetObject API -- Initialize and get a pointer to the Office IRibbonUI Interface

    Ok, your example code confused me, because you call Initialize passing Application.hWnd, and the Office "Application" object.
    You want to use the user form's hWnd, and an implementation of IUIApplication.
    I don't think you're going to have any success with ConnectToConnectionPoint, MS didn't use COM events with the ribbon framework.
    You have implement IUIApplication yourself (via Light Weight COM, if you can't use a typelib)

    edit: a quick review of the framework shows there's a lot of interfaces you have to implement... i bit tedious without a typelib, but not impossible.
    Last edited by DEXWERX; Jul 20th, 2018 at 01:55 PM.

  12. #12

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2013
    Posts
    658

    Re: CoGetObject API -- Initialize and get a pointer to the Office IRibbonUI Interface

    Quote Originally Posted by DEXWERX View Post
    Ok, your example code confused me, because you call Initialize passing Application.hWnd, and the Office "Application" object.
    You want to use the user form's hWnd, and an implementation of IUIApplication.
    I don't think you're going to have any success with ConnectToConnectionPoint, MS didn't use COM events with the ribbon framework.
    You have implement IUIApplication yourself (via Light Weight COM, if you can't use a typelib)
    Sorry about the Application.Hwnd confusion ... That was just an illustrative example but I will be passing the actual UserForm HWND .
    I don't think you're going to have any success with ConnectToConnectionPoint, MS didn't use COM events with the ribbon framework.
    Too bad !

    You have implement IUIApplication yourself via Light Weight COM.
    I don't know anything about Light Weight COM but I'll look into it .. Can you suggest a reading material on the subject applied to VB/VBA ?

    Thanks.

  13. #13

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2013
    Posts
    658

    Re: CoGetObject API -- Initialize and get a pointer to the Office IRibbonUI Interface

    Duplicate post deleted.

  14. #14
    PowerPoster
    Join Date
    Jun 2015
    Posts
    2,224

    Re: CoGetObject API -- Initialize and get a pointer to the Office IRibbonUI Interface

    Here's probably the simplest example of creating a Lightweight COM Object. --> http://www.vbforums.com/showthread.p...hout-a-typelib

    If you're adapting this to VBA - you'll have to take care of the pointers in 32bit / 64bit. Also you'll want to replace GetMem4 with a PtrSafe version of CopyMemory. FncPtr just returns what you pass it. and CopyBytesZero should be replaced with CopyMemory+ZeroMemory.
    Last edited by DEXWERX; Jul 20th, 2018 at 02:05 PM.

  15. #15

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2013
    Posts
    658

    Re: CoGetObject API -- Initialize and get a pointer to the Office IRibbonUI Interface

    Quote Originally Posted by JAAFAR View Post
    Duplicate post deleted.
    Quote Originally Posted by DEXWERX View Post
    Here's probably the simplest example of creating a Lightweight COM Object. --> http://www.vbforums.com/showthread.p...hout-a-typelib

    If you're adapting this to VBA - you'll have to take care of the pointers in 32bit / 64bit. Also you'll want to replace GetMem4 with a PtrSafe version of CopyMemory. FncPtr just returns what you pass it. and CopyBytesZero should be replaced with CopyMemory+ZeroMemory.
    That code looks very interesting ! ... I will definitely study it .

    Thank you.

  16. #16

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2013
    Posts
    658

    Re: CoGetObject API -- Initialize and get a pointer to the Office IRibbonUI Interface

    Quote Originally Posted by JAAFAR View Post
    Duplicate post deleted.
    Quote Originally Posted by DEXWERX View Post
    Here's probably the simplest example of creating a Lightweight COM Object. --> http://www.vbforums.com/showthread.p...hout-a-typelib

    If you're adapting this to VBA - you'll have to take care of the pointers in 32bit / 64bit. Also you'll want to replace GetMem4 with a PtrSafe version of CopyMemory. FncPtr just returns what you pass it. and CopyBytesZero should be replaced with CopyMemory+ZeroMemory.
    That code looks very interesting ! ... I will definitely study it .

    Thank you.

  17. #17

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2013
    Posts
    658

    Re: CoGetObject API -- Initialize and get a pointer to the Office IRibbonUI Interface

    Quote Originally Posted by DEXWERX View Post
    you can compile the resource into a DLL, and load it from that.

    edit: I see you've already thought of that. once you loadlibrary, you can call GetModuleHandle on it, to pass to IRibbonExt::LoadUI()
    I tried compiling the resource into a dll but it seems that Visual Studio 2017 only generates resource files for windows executables and not for windows dlls .

    I followed the instructions laid out HERE step by step which do work for generating the ribbon xml .RC file when I choose a Win32 executable Project BUT, if I choose a Win32 DLL Project it fails to compile at Task 3 (Configure Visual Studio to automatically compile the Ribbonmarkup)

    I am not sure if I am doing something wrong and I can't find any examples online of how to compile a resource into a dll.
    Last edited by JAAFAR; Jul 21st, 2018 at 01:39 AM.

  18. #18

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2013
    Posts
    658

    Re: CoGetObject API -- Initialize and get a pointer to the Office IRibbonUI Interface

    Post deleted ... Automatic Duplicate post by the board !

  19. #19
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,384

    Re: CoGetObject API -- Initialize and get a pointer to the Office IRibbonUI Interface

    IMO, within the 3days you've now spend on the problem, you could have finished writing your own Ribbon-Implementation from scratch.

    When I look at the "Ribbon-Visuals" e.g. on the Windows-Explorer (in Win8.1 and 10),
    then the whole thing is only different combinations of "an Icon + LabelText".
    (in case you want to tackle that with the Win32-API, you'd basically only have DrawText and DrawIconEx calls to do).

    These Icon + LabelText combinations come in basically 2 categories:
    - horizontal (smaller) Icon + Labeltext
    - vertical (larger Icon) + LabelText
    some with an additional DropDown-Arrow at the end, which on click shows a normal Popup-Menu.

    The above can all be handled within a single ucIconLabel.ctl for example
    (the render-style depending on an Enum with 4 entries (Horz, Vert, Horz_PopupArrow, Vert_PopUpArrow)

    So,
    - if you're able to render an Icon (at different Positions or Sizes) on a VB6-UserControl
    - and are able to render a Label-Text (into different Rectangle-Positions or -Sizes)
    (Position and Size depending on one of the 4 Enum-Values) -
    then you're basically done (leaving out Popup-Management at the Moment, which should be simple enough to manage on that Control).

    This ucIconLabel.ctl could then be dynamically added into an appropriate Hierarchy of Parent-UserControls:
    - ucRibbon (representing the whole "Stripe-Container")
    - ... ucRibbonSection (representing a Sub-Area on ucRibbon, which contains dynamically added ucIconLabel-instances, later automatically arranging their sizes)

    Seriously, this is quite simple stuff - doable in 2 or 3 days.

    Olaf

  20. #20
    Hyperactive Member
    Join Date
    Jan 2015
    Posts
    334

    Re: CoGetObject API -- Initialize and get a pointer to the Office IRibbonUI Interface

    I translate msime.idl from msime.h for my vs2010 to compile msime.tlb
    maybe u can learn from this.
    Code:
    import "oaidl.idl";
    import "ocidl.idl";
    
    //宏定义
    #define STDMETHOD(method)        HRESULT __stdcall method
    #define PURE                    
    #define THIS_
    #define THIS                    void
    
    //类型定义
    
    typedef short WORD;
    typedef long		DWORD;
    typedef __int3264	HWND;
    typedef __int3264	LPWSTR;
    typedef __int3264	PWCHAR;
    typedef __int3264	PWORD;
    typedef __int3264	PWDD;
    typedef __int3264	PVOID;
    
    [
    	uuid("2CDBB8BD-AA43-4A55-B332-ADEEF18EA445"),   //类库id
    	helpstring("Microsoft Input Method Manager Type Library"),  //引用窗口的类库名称
    	version(0.1),  //类库版本号
    ]
    library msime      //F2窗口的类库名称
    {
    	interface   IFELanguage;
    
    	#pragma pack(1)            /* Assume byte packing throughout */
    
    //开始IFECommon
    
    	typedef struct IMEDLG {   //IFECommon的结构体
    		INT			cbIMEDLG;               //size of this structure, must set before using this structure
    		HWND        hwnd;                   //parent window handle of Register Word Dialog
    		LPWSTR      lpwstrWord;             //optional string
    		INT			nTabId;                 //specifies a tab in dialog
    	}IMEDLG;
    
    	[
    		uuid("019F7151-E6DB-11d0-83C3-00C04FDDB82E"),//IFECommon接口定义
    	]
    	interface		IFECommon : IUnknown
    	{    
        STDMETHOD(IsDefaultIME) (THIS_
                                [out, string]const CHAR *szName,         //(in) name of MS-IME
                                [in]INT  cszName						//(in) size of szName
                                ) PURE;
        STDMETHOD(SetDefaultIME)    (THIS) PURE;
        STDMETHOD(InvokeWordRegDialog) (THIS_
                                [in]IMEDLG *pimedlg             //(in) parameters
                                ) PURE;
        STDMETHOD(InvokeDictToolDialog) (THIS_
                                [in]IMEDLG *pimedlg             //(in) parameters
                                ) PURE;
    	}
    //结束IFECommon
    
    //开始IFELanguage
    	[helpstring("Conversion mode (dwRequest)")]  
    	typedef enum FELANG_REQUEST     //IFELanguage枚举
    	{
    		FELANG_REQ_CONV         = 0x00010000,
    		FELANG_REQ_RECONV       = 0x00020000,
    		FELANG_REQ_REV          = 0x00030000,
    	} FELANG_REQUEST;
    	
    	[helpstring("Conversion mode (dwCMode)")]
    	typedef enum FELANG_CMODE     //IFELanguage枚举
    	{
    		FELANG_CMODE_MONORUBY = 0x00000002,  //mono-ruby
    		FELANG_CMODE_NOPRUNING = 0x00000004,  //no pruning
    		FELANG_CMODE_KATAKANAOUT = 0x00000008,  //katakana output
    		FELANG_CMODE_HIRAGANAOUT = 0x00000000,  //default output
    		FELANG_CMODE_HALFWIDTHOUT = 0x00000010,  //half-width output
    		FELANG_CMODE_FULLWIDTHOUT = 0x00000020,  //full-width output
    		FELANG_CMODE_BOPOMOFO = 0x00000040, //繁体中文拼音
    		FELANG_CMODE_HANGUL = 0x00000080,   //
    		FELANG_CMODE_PINYIN = 0x00000100,   //简体中文拼音
    		FELANG_CMODE_PRECONV = 0x00000200,  //do conversion as follows:
    			// - roma-ji to kana
    			// - autocorrect before conversion
    			// - periods, comma, and brackets
    		FELANG_CMODE_RADICAL = 0x00000400,  //获取笔划
    		FELANG_CMODE_UNKNOWNREADING = 0x00000800,  //
    		FELANG_CMODE_MERGECAND = 0x00001000,  // merge display with same candidate
    		FELANG_CMODE_ROMAN = 0x00002000,  //
    		FELANG_CMODE_BESTFIRST = 0x00004000,  // only make 1st best
    		FELANG_CMODE_USENOREVWORDS = 0x00008000,  // use invalid revword on REV/RECONV.
    
    		FELANG_CMODE_NONE = 0x01000000,  // IME_SMODE_NONE
    		FELANG_CMODE_PLAURALCLAUSE = 0x02000000,  // IME_SMODE_PLAURALCLAUSE
    		FELANG_CMODE_SINGLECONVERT = 0x04000000,  // IME_SMODE_SINGLECONVERT
    		FELANG_CMODE_AUTOMATIC = 0x08000000,  // IME_SMODE_AUTOMATIC
    		FELANG_CMODE_PHRASEPREDICT = 0x10000000,  // IME_SMODE_PHRASEPREDICT
    		FELANG_CMODE_CONVERSATION = 0x20000000,  // IME_SMODE_CONVERSATION
    		FELANG_CMODE_NAME = FELANG_CMODE_PHRASEPREDICT,  // Name mode (MSKKIME)
    		FELANG_CMODE_NOINVISIBLECHAR = 0x40000000, // remove invisible chars (e.g. tone mark)
    	} FELANG_CMODE;
    
    	[helpstring("Error message")]
    	typedef enum FELANG_ERROR_MSG 
    	{
    		E_NOCAND            = 0x30,    //not enough candidates
    		E_NOTENOUGH_BUFFER  = 0x31,    //out of string buffer
    		E_NOTENOUGH_WDD     = 0x32,    //out of WDD buffer
    		E_LARGEINPUT        = 0x33,    //large input string
    	}FELANG_ERROR_MSG;
    
    	[helpstring("Morphology Info")]
    	typedef enum FELANG_CLMN
    	{
    		FELANG_CLMN_WBREAK      = 0x01,
    		FELANG_CLMN_NOWBREAK    = 0x02,
    		FELANG_CLMN_PBREAK      = 0x04,
    		FELANG_CLMN_NOPBREAK    = 0x08,
    		FELANG_CLMN_FIXR        = 0x10,
    		FELANG_CLMN_FIXD        = 0x20,    // fix display of word
    	}FELANG_CLMN;
    
    	const int FELANG_INVALD_PO      = 0xFFFF;  // unmatched position for input string
    
    	[helpstring("Word Descriptor")]   //IFELanguage 结构体
    	typedef struct WDD {
    		WORD        wDispPos;        // Offset of Output string
    		WORD		wReadCompPos;    // Offset of Reading string
    		WORD        cchDisp;         //number of ptchDisp
    		WORD		cchReadComp;     //number of ptchRead
    		DWORD       WDD_nReserve1;   //reserved
    		WORD        nPos;            //part of speech
    								     // implementation-defined
    	//	WORD        fPhrase : 1;        //start of phrase
    	//	WORD        fAutoCorrect : 1;   //auto-corrected
    	//	WORD        fNumericPrefix : 1; //kansu-shi expansion(JPN)
    	//	WORD        fUserRegistered : 1;//from user dictionary
    	//	WORD        fUnknown : 1;       //unknown word (duplicated information with nPos.)
    	//	WORD        fRecentUsed : 1;    //used recently flag
    	//  WORD                    : 10;   //
    		WORD        fFlags;
    		PVOID        pReserved; //points directly to WORDITEM
    	} WDD;
    
    	typedef struct MORRSLT {    //IFELanguage 结构体
    		DWORD       dwSize;             // total size of this block.
    		PWCHAR      pwchOutput;        // conversion result string.
    		WORD        cchOutput;          // lengh of result string.
    		PWCHAR		pwchReadComp;          // reading string
    		WORD		cchReadComp;            // length of reading string.
    		PWORD       pchInputPos;       // index array of reading to input character.
    		PWORD       pchOutputIdxWDD;   // index array of output character to WDD
    		PWORD		pchReadCompIdxWDD;     // index array of reading character to WDD
    		PWORD       paMonoRubyPos;     // array of position of monoruby
    		PWDD        pWDD;              // pointer to array of WDD
    		INT         cWDD;               // number of WDD
    		PVOID        pPrivate;          // pointer of private data area
    		//WCHAR       BLKBuff[];          // area for stored above members.   //VB6不支持的类型,只能注释掉
    										//  WCHAR   wchOutput[cchOutput];
    										//  WCHAR   wchRead[cchRead];
    										//  CHAR    chInputIdx[cwchInput];
    										//  CHAR    chOutputIdx[cchOutput];
    										//  CHAR    chReadIndx[cchRead];
    										//  ????    Private
    										//  WDD     WDDBlk[cWDD];
    	}MORRSLT;
    
    	[
    		uuid("019F7152-E6DB-11D0-83C3-00C04FDDB82E"),
    	]
    	interface       IFELanguage : IUnknown
    	{
    
    		STDMETHOD(Open)(THIS) PURE;
    		STDMETHOD(Close)(THIS) PURE;
    
    		STDMETHOD(GetJMorphResult)(THIS_
    			[in]FELANG_REQUEST   dwRequest,				// 
    			[in]FELANG_CMODE   dwCMode,					// Specifies the conversion output characters and conversion options.
    			[in]INT     cwchInput,						// The number of characters in pwchInput
    			[in, size_is(cwchInput), string]const WCHAR   *pwchInput,  //Input characters to be converted by the morphology engine. This must be a UNICODE string
    			[in, size_is(cwchInput)]DWORD   *pfCInfo,   //The information for each column, where each pfCInfo[x] corresponds to pwchInput[x]
    			[out,retval]DWORD *ppResult) PURE;  //The address of a MORRSLT structure that receives the morphology result data
    		                                        //使用完后,需要用CoTaskMemFree清空ppResult的上一级指针pResult
    
    		[propget]
    		STDMETHOD(GetConversionModeCaps)(THIS_ [out, retval]FELANG_CMODE *pdwCaps) PURE;
    
    		STDMETHOD(GetPhonetic)(THIS_
    			[in]BSTR    string,             // 
    			[in]LONG    start,              // 
    			[in]LONG    length,             // 
    			[out, retval]BSTR *phonetic) PURE;    // 
    
    		STDMETHOD(GetConversion)(THIS_
    			[in]BSTR    string,             // 
    			[in]LONG    start,              // 
    			[in]LONG    length,             // 
    			[out, retval]BSTR *result) PURE;      // 
    	};
    //结束IFELanguage
    
    
    	#pragma pack()
    
    	//[dllname("imm32.dll")]
    	module immAPI
    	{
    		
    		const BSTR szImeJapan          = L"MSIME.Japan";
    		const BSTR szImeKorea          = L"MSIME.Korea";
    		const BSTR szImeChina          = L"MSIME.China";
    		const BSTR szImeTaiwan         = L"MSIME.Taiwan";
    	}
    }

  21. #21
    Hyperactive Member
    Join Date
    Jan 2015
    Posts
    334

    Re: CoGetObject API -- Initialize and get a pointer to the Office IRibbonUI Interface

    I used to translate IFElanguge from msime.h for my vs2010 to compile msime.tlb
    maybe u can learn from this.
    Code:
    import "oaidl.idl";
    import "ocidl.idl";
    
    #define STDMETHOD(method)        HRESULT __stdcall method
    #define PURE                    
    #define THIS_
    #define THIS                    void
    
    typedef short WORD;
    typedef long		DWORD;
    typedef __int3264	HWND;
    typedef __int3264	LPWSTR;
    typedef __int3264	PWCHAR;
    typedef __int3264	PWORD;
    typedef __int3264	PWDD;
    typedef __int3264	PVOID;
    
    [
    	uuid("2CDBB8BD-AA43-4A55-B332-ADEEF18EA445"),   //类库id
    	helpstring("Microsoft Input Method Manager Type Library"),  //引用窗口的类库名称
    	version(0.1),  //类库版本号
    ]
    library msime      //F2窗口的类库名称
    {
    	interface   IFELanguage;
    
    	#pragma pack(1)            /* Assume byte packing throughout */
    
    //开始IFECommon
    
    	typedef struct IMEDLG {   //IFECommon的结构体
    		INT			cbIMEDLG;               //size of this structure, must set before using this structure
    		HWND        hwnd;                   //parent window handle of Register Word Dialog
    		LPWSTR      lpwstrWord;             //optional string
    		INT			nTabId;                 //specifies a tab in dialog
    	}IMEDLG;
    
    	[
    		uuid("019F7151-E6DB-11d0-83C3-00C04FDDB82E"),//IFECommon接口定义
    	]
    	interface		IFECommon : IUnknown
    	{    
        STDMETHOD(IsDefaultIME) (THIS_
                                [out, string]const CHAR *szName,         //(in) name of MS-IME
                                [in]INT  cszName						//(in) size of szName
                                ) PURE;
        STDMETHOD(SetDefaultIME)    (THIS) PURE;
        STDMETHOD(InvokeWordRegDialog) (THIS_
                                [in]IMEDLG *pimedlg             //(in) parameters
                                ) PURE;
        STDMETHOD(InvokeDictToolDialog) (THIS_
                                [in]IMEDLG *pimedlg             //(in) parameters
                                ) PURE;
    	}
    //结束IFECommon
    
    //开始IFELanguage
    	[helpstring("Conversion mode (dwRequest)")]  
    	typedef enum FELANG_REQUEST     //IFELanguage枚举
    	{
    		FELANG_REQ_CONV         = 0x00010000,
    		FELANG_REQ_RECONV       = 0x00020000,
    		FELANG_REQ_REV          = 0x00030000,
    	} FELANG_REQUEST;
    	
    	[helpstring("Conversion mode (dwCMode)")]
    	typedef enum FELANG_CMODE     //IFELanguage枚举
    	{
    		FELANG_CMODE_MONORUBY = 0x00000002,  //mono-ruby
    		FELANG_CMODE_NOPRUNING = 0x00000004,  //no pruning
    		FELANG_CMODE_KATAKANAOUT = 0x00000008,  //katakana output
    		FELANG_CMODE_HIRAGANAOUT = 0x00000000,  //default output
    		FELANG_CMODE_HALFWIDTHOUT = 0x00000010,  //half-width output
    		FELANG_CMODE_FULLWIDTHOUT = 0x00000020,  //full-width output
    		FELANG_CMODE_BOPOMOFO = 0x00000040, //繁体中文拼音
    		FELANG_CMODE_HANGUL = 0x00000080,   //
    		FELANG_CMODE_PINYIN = 0x00000100,   //简体中文拼音
    		FELANG_CMODE_PRECONV = 0x00000200,  //do conversion as follows:
    			// - roma-ji to kana
    			// - autocorrect before conversion
    			// - periods, comma, and brackets
    		FELANG_CMODE_RADICAL = 0x00000400,  //获取笔划
    		FELANG_CMODE_UNKNOWNREADING = 0x00000800,  //
    		FELANG_CMODE_MERGECAND = 0x00001000,  // merge display with same candidate
    		FELANG_CMODE_ROMAN = 0x00002000,  //
    		FELANG_CMODE_BESTFIRST = 0x00004000,  // only make 1st best
    		FELANG_CMODE_USENOREVWORDS = 0x00008000,  // use invalid revword on REV/RECONV.
    
    		FELANG_CMODE_NONE = 0x01000000,  // IME_SMODE_NONE
    		FELANG_CMODE_PLAURALCLAUSE = 0x02000000,  // IME_SMODE_PLAURALCLAUSE
    		FELANG_CMODE_SINGLECONVERT = 0x04000000,  // IME_SMODE_SINGLECONVERT
    		FELANG_CMODE_AUTOMATIC = 0x08000000,  // IME_SMODE_AUTOMATIC
    		FELANG_CMODE_PHRASEPREDICT = 0x10000000,  // IME_SMODE_PHRASEPREDICT
    		FELANG_CMODE_CONVERSATION = 0x20000000,  // IME_SMODE_CONVERSATION
    		FELANG_CMODE_NAME = FELANG_CMODE_PHRASEPREDICT,  // Name mode (MSKKIME)
    		FELANG_CMODE_NOINVISIBLECHAR = 0x40000000, // remove invisible chars (e.g. tone mark)
    	} FELANG_CMODE;
    
    	[helpstring("Error message")]
    	typedef enum FELANG_ERROR_MSG 
    	{
    		E_NOCAND            = 0x30,    //not enough candidates
    		E_NOTENOUGH_BUFFER  = 0x31,    //out of string buffer
    		E_NOTENOUGH_WDD     = 0x32,    //out of WDD buffer
    		E_LARGEINPUT        = 0x33,    //large input string
    	}FELANG_ERROR_MSG;
    
    	[helpstring("Morphology Info")]
    	typedef enum FELANG_CLMN
    	{
    		FELANG_CLMN_WBREAK      = 0x01,
    		FELANG_CLMN_NOWBREAK    = 0x02,
    		FELANG_CLMN_PBREAK      = 0x04,
    		FELANG_CLMN_NOPBREAK    = 0x08,
    		FELANG_CLMN_FIXR        = 0x10,
    		FELANG_CLMN_FIXD        = 0x20,    // fix display of word
    	}FELANG_CLMN;
    
    	const int FELANG_INVALD_PO      = 0xFFFF;  // unmatched position for input string
    
    	[helpstring("Word Descriptor")]   //IFELanguage 结构体
    	typedef struct WDD {
    		WORD        wDispPos;        // Offset of Output string
    		WORD		wReadCompPos;    // Offset of Reading string
    		WORD        cchDisp;         //number of ptchDisp
    		WORD		cchReadComp;     //number of ptchRead
    		DWORD       WDD_nReserve1;   //reserved
    		WORD        nPos;            //part of speech
    								     // implementation-defined
    	//	WORD        fPhrase : 1;        //start of phrase
    	//	WORD        fAutoCorrect : 1;   //auto-corrected
    	//	WORD        fNumericPrefix : 1; //kansu-shi expansion(JPN)
    	//	WORD        fUserRegistered : 1;//from user dictionary
    	//	WORD        fUnknown : 1;       //unknown word (duplicated information with nPos.)
    	//	WORD        fRecentUsed : 1;    //used recently flag
    	//  WORD                    : 10;   //
    		WORD        fFlags;
    		PVOID        pReserved; //points directly to WORDITEM
    	} WDD;
    
    	typedef struct MORRSLT {    //IFELanguage 结构体
    		DWORD       dwSize;             // total size of this block.
    		PWCHAR      pwchOutput;        // conversion result string.
    		WORD        cchOutput;          // lengh of result string.
    		PWCHAR		pwchReadComp;          // reading string
    		WORD		cchReadComp;            // length of reading string.
    		PWORD       pchInputPos;       // index array of reading to input character.
    		PWORD       pchOutputIdxWDD;   // index array of output character to WDD
    		PWORD		pchReadCompIdxWDD;     // index array of reading character to WDD
    		PWORD       paMonoRubyPos;     // array of position of monoruby
    		PWDD        pWDD;              // pointer to array of WDD
    		INT         cWDD;               // number of WDD
    		PVOID        pPrivate;          // pointer of private data area
    		//WCHAR       BLKBuff[];          // area for stored above members.   //VB6不支持的类型,只能注释掉
    										//  WCHAR   wchOutput[cchOutput];
    										//  WCHAR   wchRead[cchRead];
    										//  CHAR    chInputIdx[cwchInput];
    										//  CHAR    chOutputIdx[cchOutput];
    										//  CHAR    chReadIndx[cchRead];
    										//  ????    Private
    										//  WDD     WDDBlk[cWDD];
    	}MORRSLT;
    
    	[
    		uuid("019F7152-E6DB-11D0-83C3-00C04FDDB82E"),
    	]
    	interface       IFELanguage : IUnknown
    	{
    
    		STDMETHOD(Open)(THIS) PURE;
    		STDMETHOD(Close)(THIS) PURE;
    
    		STDMETHOD(GetJMorphResult)(THIS_
    			[in]FELANG_REQUEST   dwRequest,				// 
    			[in]FELANG_CMODE   dwCMode,					// Specifies the conversion output characters and conversion options.
    			[in]INT     cwchInput,						// The number of characters in pwchInput
    			[in, size_is(cwchInput), string]const WCHAR   *pwchInput,  //Input characters to be converted by the morphology engine. This must be a UNICODE string
    			[in, size_is(cwchInput)]DWORD   *pfCInfo,   //The information for each column, where each pfCInfo[x] corresponds to pwchInput[x]
    			[out,retval]DWORD *ppResult) PURE;  //The address of a MORRSLT structure that receives the morphology result data
    		                                        //使用完后,需要用CoTaskMemFree清空ppResult的上一级指针pResult
    
    		[propget]
    		STDMETHOD(GetConversionModeCaps)(THIS_ [out, retval]FELANG_CMODE *pdwCaps) PURE;
    
    		STDMETHOD(GetPhonetic)(THIS_
    			[in]BSTR    string,             // 
    			[in]LONG    start,              // 
    			[in]LONG    length,             // 
    			[out, retval]BSTR *phonetic) PURE;    // 
    
    		STDMETHOD(GetConversion)(THIS_
    			[in]BSTR    string,             // 
    			[in]LONG    start,              // 
    			[in]LONG    length,             // 
    			[out, retval]BSTR *result) PURE;      // 
    	};
    //结束IFELanguage
    
    
    	#pragma pack()
    
    	//[dllname("imm32.dll")]
    	module immAPI
    	{
    		
    		const BSTR szImeJapan          = L"MSIME.Japan";
    		const BSTR szImeKorea          = L"MSIME.Korea";
    		const BSTR szImeChina          = L"MSIME.China";
    		const BSTR szImeTaiwan         = L"MSIME.Taiwan";
    	}
    }

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width