COM Mapping ITaskbarlist3

607 views
Skip to first unread message

Joao Rasteiro

unread,
Mar 5, 2016, 9:29:21 AM3/5/16
to Java Native Access
Hello,

I've been trying to map ITaskBarList3  and I'm having some trouble with it.
I'm fairly new to JNA and haven't used COM with it before, however, by following some tutorials in c++ I've managed to find the (I think) correct CLSID's and map the correct methods.

After failing to initialise the object normally, I switched to ComLateBindingObject but I still cannot create an instance.

I've tried simply mapping the interface:

@ComInterface(iid = "{EA1AFB91-9E28-4B86-90E9-9E9F8A5EEFAF}")
public interface ITaskbarList3 extends ITaskbarList2 {

   
/* https://msdn.microsoft.com/en-us/library/windows/desktop/dd391703%28v=vs.85%29.aspx */
   
@ComMethod
   
public HRESULT ThumbBarAddButtons(HWND hWnd, int cButtons, THUMBBUTTON pButton);
   
   
/* https://msdn.microsoft.com/en-us/library/windows/desktop/dd391705%28v=vs.85%29.aspx */
   
@ComMethod
   
public HRESULT ThumbBarUpdateButtons(HWND hwnd, int cButtons, THUMBBUTTON pButton);
   
   
/* https://msdn.microsoft.com/en-us/library/windows/desktop/dd391697%28v=vs.85%29.aspx */
   
@ComMethod
   
public HRESULT SetProgressState(HWND hwnd, int tbpFlags);
   
   
/* https://msdn.microsoft.com/en-us/library/windows/desktop/dd391697%28v=vs.85%29.aspx */
   
@ComMethod
   
public HRESULT SetProgressValue(HWND hwnd, ULONGLONG ullCompleted, ULONGLONG ullTotal);
   
   
/* https://msdn.microsoft.com/pt-br/library/windows/desktop/dd562322.aspx */
   
public static interface THUMBBUTTONMASK {
       
public static final int THB_BITMAP = 0x00000001;
       
public static final int THB_ICON = 0x00000002;
       
public static final int THB_TOOLTIP = 0x00000004;
       
public static final int THB_FLAGS = 0x00000008;
   
}
   
   
/* https://msdn.microsoft.com/pt-br/library/windows/desktop/dd562321.aspx */
   
public static interface THUMBBUTTONFLAGS {
       
public static final int THBF_ENABLED = 0x00000000;
       
public static final int THBF_DISABLED = 0x00000001;
       
public static final int THBF_DISMISSONCLICK = 0x00000002;
       
public static final int THBF_NOBACKGROUND = 0x00000004;
       
public static final int THBF_HIDDEN = 0x00000008;
       
public static final int THBF_NONINTERACTIVE = 0x00000010;
   
}
   
   
/* https://msdn.microsoft.com/en-us/library/windows/desktop/dd391697%28v=vs.85%29.aspx */
   
public static interface TBPFLAG {
       
public static final int TBPF_NOPROGRESS = 0x00000000;
       
public static final int TBPF_INDETERMINATE  = 0x00000001;
       
public static final int TBPF_NORMAL = 0x00000002;
       
public static final int TBPF_ERROR = 0x00000004;
       
public static final int TBPF_PAUSED = 0x00000008;
   
}
}



And having a simple Late binding object class with just the constructor:

public class ExplorerFrames extends COMLateBindingObject {

   
public ExplorerFrames() {
       
super(new CLSID("EA1AFB91-9E28-4B86-90E9-9E9F8A5EEFAF"), false);
   
}
}




However, whenever I create a new ExplorerFrames object I always get a COMException:
com.sun.jna.platform.win32.COM.COMException: COM object with CLSID {EA1AFB91-9E28-4B86-90E9-9E9F8A5EEFAF} not registered properly!


I checked the HResult returned by the constructor and it's -2147221164 or 0x80040154 which appears to be "Class not registered"?

Since the CLSID's I'm using are the same I can find on several guides I'm fairly sure that is not the issue so I'm assuming the problem is on the way I'm trying to map or create the COM object with JNA
Can anyone give me some help in the correct way to do this?

Thanks in advance!

SevenOf9Sleeper

unread,
Mar 29, 2016, 3:52:52 PM3/29/16
to Java Native Access
Hello Joao,

please do not mix up IID and CLSID. The IID you have for ITaskbarList3 is the correct one. But you can't create a COM object with that id! It is an interface-id. So you need a class-id of an object that IMPLEMENTS this interface.
In your case it is : CLSID_TaskbarList: "56FDF344-FD6D-11d0-958A-006097C9A090".

Then you can create the object. With the IID as class-id windows is right: that class is not registered.

Hope this helps.

With kind regards,
                         Mathias

mbla...@doppel-helix.eu

unread,
Apr 3, 2016, 2:55:21 PM4/3/16
to Java Native Access
Hey Joao,


Am Samstag, 5. März 2016 15:29:21 UTC+1 schrieb Joao Rasteiro:
Hello,

I've been trying to map ITaskBarList3  and I'm having some trouble with it.
I'm fairly new to JNA and haven't used COM with it before, however, by following some tutorials in c++ I've managed to find the (I think) correct CLSID's and map the correct methods.

After failing to initialise the object normally, I switched to ComLateBindingObject but I still cannot create an instance.


you can't use the helpers, that are currently present in JNA. ITaskbarList3 is not derived from IDispatch and all the helpers asume that this is the case. ITaskbarList3 methods can only be called via a direct function call via the vtable.

I'll attach a sample maven projects that binds the three methods HrInit, SetProgressState and SetProgressValue. The project shows a JFrame, in which you can change the state and progress values directly (for progress the first value is the completed part and the second value is the total value).

The most difficult part is, that you'll need a windows SDK to gain access to "ShObjIdl.idl" - this file contains the interface definition you get the vtable value by counting methods:

- You trace from IUnknown (this is the base interface for _all_ COM interfaces) (this interface exposes three methods)
- ITaskbarList is derived directly from IUnknown and contains 5 methods
- ITaskbarList2 is derived from ITaskbarList and contains 1 method
- ITaskbarList3 is derived from ITaskbarList2 and contains 12 methods

This leads to:
HrInit is defined in ITaskbarList and is the first method, so we get Offset 3 (methods in IUnkown) + 0 (method offset in interface) => 3
SetProgressValue is defined in ITaskbarList3 and is the first method, so we get Offset 3 (IUnkown) + 5 (ITaskbarList) + 1 (ITaskbarList2) + 0 (offset) => 9
SetProgressState is defined in ITaskbarList3 and is the second method: 3 (IUnkown) + 5 (ITaskbarList) + 2 (ITaskbarList2) + 0 (offset) => 10

When building the argument array for use in _invokeNativeInt, you'll have to pass in the object pointer as first argument.

Hope this gets you going.

Greetings

Matthias
 
TaskbarTest.zip

L Will Ahonen

unread,
Apr 4, 2016, 2:47:20 AM4/4/16
to Java Native Access
Hi,

Not sure if you prefer doing this arithmetic, but I've always found it easier to look up the C vtable definition, as it includes all the inherited methods in the right order. Open Shobjidl.h and find ITaskbarList3Vtbl

Cheers,
Will

mbla...@doppel-helix.eu

unread,
Apr 4, 2016, 12:31:12 PM4/4/16
to Java Native Access
Hey Will,


Am Montag, 4. April 2016 08:47:20 UTC+2 schrieb L Will Ahonen:
Not sure if you prefer doing this arithmetic, but I've always found it easier to look up the C vtable definition, as it includes all the inherited methods in the right order. Open Shobjidl.h and find ITaskbarList3Vtbl

 actually I'm not sure which version I like more, but it was definitely good, that you added this here, as I was not aware of that option.

Thanks

Matthias
Reply all
Reply to author
Forward
0 new messages