• Welcome to Powerbasic Museum 2020-B.
 

News:

Forum in repository mode. No new members allowed.

Main Menu

GetIDsOfNames not unicode

Started by Edwin Knoppert, July 24, 2011, 11:01:53 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Edwin Knoppert

I am calling GetIDsOfNames() on a dispatch interface but changed the string to a wstring.
It seems incompatible, should i stick with ansi string here?

HRESULT GetIDsOfNames(
  REFIID riid,
  OLECHAR FAR* FAR* rgszNames,
  unsigned int cNames,
  LCID lcid,
  DISPID FAR* rgDispId
);

I am using it like:
hr = o.GetIDsOfNames( IID_NULL, sMemberName, 1, 0, rgDispID )

Thanks,

José Roca

 
It should be AS WSTRING, but the built-in implementation of IDispatch still uses AS STRING.

You must use hr = o.GetIDsOfNames(IID_NULL, UCODE$(sMemberName), 1, 0, rgDispID)

Edwin Knoppert

Thanks, great!

The original is a wstring so i'll use movememory into an ansistring :)

Edwin Knoppert

There is a good chance this wrapper never worked, for the old compiler i assume it should have been unicode as well.
Guess i never used this once actually..

José Roca

 
The build-in IDispatch interface declaration is undocumented and, therefore, subject to change.


' *** As built into the PowerBASIC compiler ***
' Note: GetIDsOfNames still uses AS STRING, instead of AS WSTRING, for the rgszNames parameter.
' Therefore, you must use a variable declared AS STRING and convert it to unicode with UCODE$.

'INTERFACE IDispatch $IID_IDispatch

'   INHERIT IUnknown

'   ' =====================================================================================
'   METHOD GetTypeInfoCount ( _                          ' VTable offset = 12
'     BYREF pctinfo AS DWORD _                           ' __out unsigned int *pctinfo
'   ) AS LONG                                            ' HRESULT
'   ' =====================================================================================
'   METHOD GetTypeInfo ( _                               ' VTable offset = 16
'     BYVAL iTInfo AS DWORD _                            ' __in unsigned int iTInfo
'   , BYVAL lcid AS DWORD _                              ' __in LCID lcid
'   , BYREF ppTInfo AS DWORD _                           ' __out ITypeInfo **ppTInfo
'   ) AS LONG                                            ' HRESULT
'   ' =====================================================================================
'   METHOD GetIDsOfNames ( _                             ' VTable offset = 20
'     BYREF riid AS GUID _                               ' __in REFIID riid
'   , BYREF rgszNames AS STRING _                        ' __in OLECHAR **rgszNames
'   , BYVAL cNames AS DWORD _                            ' __in unsigned int cNames
'   , BYVAL lcid AS DWORD _                              ' __in LCID lcid
'   , BYREF rgDispId AS LONG _                           ' __out DISPID *rgDispId
'   ) AS LONG                                            ' HRESULT
'   ' =====================================================================================
'   METHOD Invoke ( _                                    ' VTable offset = 24
'     BYVAL dispIdMember AS LONG _                       ' __in DISPID dispIdMember
'   , BYREF riid AS GUID _                               ' __in REFIID riid
'   , BYVAL lcid AS DWORD _                              ' __in LCID lcid
'   , BYVAL wFlags AS DWORD _                            ' __in WORD wFlags
'   , BYREF pDispParams AS DISPPARAMS _                  ' __in DISPPARAMS *pDispParams
'   , BYREF pVarResult AS VARIANT _                      ' __out VARIANT *pVarResult
'   , BYVAL pExcepInfo AS DWORD _                        ' __out EXCEPINFO *pExcepInfo
'   , BYREF puArgErr AS DWORD _                          ' __out unsigned int *puArgErr
'   ) AS LONG                                            ' HRESULT
'   ' =====================================================================================

'END INTERFACE


In my headers, I use COM_IDispatch instead:


INTERFACE COM_IDispatch $IID_IDispatch

   INHERIT IUnknown

   ' =====================================================================================
   METHOD GetTypeInfoCount ( _                          ' VTable offset = 12
     BYREF pctinfo AS DWORD _                           ' __out unsigned int *pctinfo
   ) AS LONG                                            ' HRESULT
   ' =====================================================================================
   METHOD GetTypeInfo ( _                               ' VTable offset = 16
     BYVAL iTInfo AS DWORD _                            ' __in unsigned int iTInfo
   , BYVAL lcid AS DWORD _                              ' __in LCID lcid
   , BYREF ppTInfo AS ITypeInfo _                       ' __out ITypeInfo **ppTInfo
   ) AS LONG                                            ' HRESULT
   ' =====================================================================================
   METHOD GetIDsOfNames ( _                             ' VTable offset = 20
     BYREF riid AS GUID _                               ' __in REFIID riid
   , BYREF rgszNames AS WSTRING _                       ' __in OLECHAR **rgszNames
   , BYVAL cNames AS DWORD _                            ' __in unsigned int cNames
   , BYVAL lcid AS DWORD _                              ' __in LCID lcid
   , BYREF rgDispId AS LONG _                           ' __out DISPID *rgDispId
   ) AS LONG                                            ' HRESULT
   ' =====================================================================================
   METHOD Invoke ( _                                    ' VTable offset = 24
     BYVAL dispIdMember AS LONG _                       ' __in DISPID dispIdMember
   , BYREF riid AS GUID _                               ' __in REFIID riid
   , BYVAL lcid AS DWORD _                              ' __in LCID lcid
   , BYVAL wFlags AS WORD _                             ' __in WORD wFlags
   , BYREF pDispParams AS DISPPARAMS _                  ' __in DISPPARAMS *pDispParams
   , BYREF pVarResult AS VARIANT _                      ' __out VARIANT *pVarResult
   , BYREF pExcepInfo AS EXCEPINFO _                    ' __out EXCEPINFO *pExcepInfo
   , BYREF puArgErr AS DWORD _                          ' __out unsigned int *puArgErr
   ) AS LONG                                            ' HRESULT
   ' =====================================================================================

END INTERFACE


Edwin Knoppert

I may need to use the vtable offset [5] directly then, already thought about that today but it's a bit old fashion :)

Frederick J. Harris

I've found that some of the 'built in' interface members are somewhat less than optimal; at least for me.  For example, I believe IConnectionPointContainer::FindConnectionPoint takes a Byref Dword as a first parameter instead of a Byref Guid (the IID of the event sink) which seems to make more sense.  Especially as PB has a GUID data type. 

José Roca

Don't forget that the compiler is written in assembler, not with PowerBASIC, and the assembler has not the GUID type defined.


' *** As built into the PowerBASIC compiler ***

'INTERFACE IConnectionPointContainer $IID_IConnectionPointContainer


'   INHERIT IUnknown

'   ' =====================================================================================
'   METHOD EnumConnectionPoints ( _                      ' VTable offset = 12
'     BYREF ppEnum AS DWORD _                            ' __out IEnumConnectionPoints **ppEnum
'   ) AS LONG                                            ' HRESULT
'   ' =====================================================================================
'   METHOD FindConnectionPoint ( _                       ' VTable offset = 14
'     BYREF riid AS DWORD _                              ' __in REFIID riid
'   , BYREF ppCP AS DWORD _                              ' __out IConnectionPoint **ppCP
'   ) AS LONG                                            ' HRESULT
'   ' =====================================================================================

'END INTERFACE


Frederick J. Harris

That thought occurred to me too Jose, but hearing you say it too confirms my thoughts.  I had studied your declare and the one you mentioned as being built in, and that was the only sense I could make out of it.

I was just working with this lately, and found this to be easier to work with...


Type IEnumConnectionPointsVtbl
  QueryInterface                      As Dword Ptr
  AddRef                              As Dword Ptr
  Release                             As Dword Ptr
  Next                                As Dword Ptr
  Skip                                As Dword Ptr
  Reset                               As Dword Ptr
  Clone                               As Dword Ptr
End Type

Type IEnumConnectionPoints1
  lpVtbl                              As IEnumConnectionPointsVtbl Ptr
End Type

Interface IMyConnPtContainer $IID_IConnectionPointContainer : Inherit IUnknown
  Method EnumConnectionPoints(Byref ppEnum As IEnumConnectionPoints1) As Long
  Method FindConnectionPoint(Byref riid As Guid, Byref ppCP As IConnectionPoint) As Long
End Interface


And then the call is more natural...


Call pConPtCon.FindConnectionPoint($IID_IGridEvents, pConPt) To hr


But in the end I decided to go with the built in interfaces to avoid having to provide alternate declares, and it can be made to work fairly easily too...


Global pSink                       As IGridEvents
Global pGrid                       As IGrid
Global pConnectionPointContainer   As IConnectionPointContainer
Global pConnectionPoint            As IConnectionPoint
Global dwCookie                    As Dword



Function fnWndProc_OnCreate(Wea As WndEventArgs) As Long
  Local pCreateStruct As CREATESTRUCT Ptr
  Local strSetup,strCoordinate As BStr
  Local EventGuid As Guid
  Local hCtl As Dword
  Register i As Long
  Register j As Long

  pCreateStruct=wea.lParam : wea.hInst=@pCreateStruct.hInstance                          'Get Module Instance Handle
  Let pGrid = NewCom "FJHGrid.Grid"                                                      'Load Com Component Containing Grid
  strSetup="120:Column 1:^,130:Column 2:^,140:Column 3:^,150:Column 4:^,160:Column 5:^"  'Comma delimited Column Setup String For Grid
  pGrid.Create(Wea.hWnd, strSetup, 10, 10, 570, 222, 25, 5, 20, "", 18, %FW_DONTCARE)    'Create Grid Through Method Call
  pConnectionPointContainer = pGrid                                                      'Do QueryInterface(IConnectionPointContainer)
  EventGuid=$IID_IGridEvents                                                             'Convert Guid String To Guid
  Call pConnectionPointContainer.FindConnectionPoint(Byval Varptr(EventGuid), Byval Varptr(pConnectionPoint)) 'Find Connection Point
  Let pSink = Class  "CEventClass"                                                       'Instantiate Event Sink Class
  Call pConnectionPoint.Advise(Byval Objptr(pSink), dwCookie)                            'Notify Grid Component of Sink Address
  For i=1 To 25                                                                          'Load Grid With Sample Strings
    For j=1 To 5                                                                         'Refresh() Method Needs To Be
      strCoordinate="(" & Trim$(Str$(i)) & "," & Trim$(Str$(j)) & ")"                    'Called Afterwards To Make Them Visible
      pGrid.SetData(i, j, strCoordinate)                                                 'The Button Lower Left Retrieves The
    Next j                                                                               'Text From Row 3, Col 2.  The Button
  Next i                                                                                 'Lower Right Unloads The Grid.
  pGrid.Refresh()
 
  fnWndProc_OnCreate=0
End Function


I guess I hijacked your thread Edwin.  Just lately I've been trying to see if I could use some of the built in interface declarations, so I thought it pertained somewhat.  I've found that usually interface pointers are passed in as Byref dwords.