-
Jul 18th, 2018, 02:26 AM
#1
Thread Starter
Fanatic Member
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.
-
Jul 18th, 2018, 03:20 AM
#2
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>
-
Jul 18th, 2018, 04:01 AM
#3
Thread Starter
Fanatic Member
Re: CoGetObject API -- Initialize and get a pointer to the Office IRibbonUI Interface
Originally Posted by wqweto
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.
-
Jul 18th, 2018, 05:18 AM
#4
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>
-
Jul 18th, 2018, 05:25 AM
#5
Thread Starter
Fanatic Member
Re: CoGetObject API -- Initialize and get a pointer to the Office IRibbonUI Interface
Originally Posted by wqweto
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
-
Jul 19th, 2018, 07:19 AM
#6
Re: CoGetObject API -- Initialize and get a pointer to the Office IRibbonUI Interface
Originally Posted by JAAFAR
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.
-
Jul 19th, 2018, 04:27 PM
#7
Fanatic Member
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.
-
Jul 19th, 2018, 11:22 PM
#8
Thread Starter
Fanatic Member
Re: CoGetObject API -- Initialize and get a pointer to the Office IRibbonUI Interface
Originally Posted by DEXWERX
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.
-
Jul 20th, 2018, 07:32 AM
#9
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.
-
Jul 20th, 2018, 10:01 AM
#10
Thread Starter
Fanatic Member
Re: CoGetObject API -- Initialize and get a pointer to the Office IRibbonUI Interface
Originally Posted by DEXWERX
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.
-
Jul 20th, 2018, 01:21 PM
#11
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.
-
Jul 20th, 2018, 01:27 PM
#12
Thread Starter
Fanatic Member
Re: CoGetObject API -- Initialize and get a pointer to the Office IRibbonUI Interface
Originally Posted by DEXWERX
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.
-
Jul 20th, 2018, 01:28 PM
#13
Thread Starter
Fanatic Member
Re: CoGetObject API -- Initialize and get a pointer to the Office IRibbonUI Interface
-
Jul 20th, 2018, 01:59 PM
#14
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.
-
Jul 21st, 2018, 01:19 AM
#15
Thread Starter
Fanatic Member
Re: CoGetObject API -- Initialize and get a pointer to the Office IRibbonUI Interface
Originally Posted by JAAFAR
Duplicate post deleted.
Originally Posted by DEXWERX
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.
-
Jul 21st, 2018, 01:20 AM
#16
Thread Starter
Fanatic Member
Re: CoGetObject API -- Initialize and get a pointer to the Office IRibbonUI Interface
Originally Posted by JAAFAR
Duplicate post deleted.
Originally Posted by DEXWERX
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.
-
Jul 21st, 2018, 01:35 AM
#17
Thread Starter
Fanatic Member
Re: CoGetObject API -- Initialize and get a pointer to the Office IRibbonUI Interface
Originally Posted by DEXWERX
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.
-
Jul 21st, 2018, 01:36 AM
#18
Thread Starter
Fanatic Member
Re: CoGetObject API -- Initialize and get a pointer to the Office IRibbonUI Interface
Post deleted ... Automatic Duplicate post by the board !
-
Jul 21st, 2018, 06:29 AM
#19
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
-
Jul 21st, 2018, 10:06 PM
#20
Hyperactive Member
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";
}
}
-
Jul 21st, 2018, 10:07 PM
#21
Hyperactive Member
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|