push b25f14be0dd3305724e1f1ef337bfe2a9ff59832
[wine/hacks.git] / dlls / msxml3 / text.c
blob7cb1d42e215a564796d73c79e6b9b04d5eec6c3e
1 /*
2 * DOM text node implementation
4 * Copyright 2006 Huw Davies
5 * Copyright 2007-2008 Alistair Leslie-Hughes
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #define COBJMACROS
24 #include "config.h"
26 #include <stdarg.h>
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winuser.h"
30 #include "ole2.h"
31 #include "msxml2.h"
33 #include "msxml_private.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
39 #ifdef HAVE_LIBXML2
41 typedef struct _domtext
43 const struct IXMLDOMTextVtbl *lpVtbl;
44 LONG ref;
45 IUnknown *node_unk;
46 IXMLDOMNode *node;
47 } domtext;
49 static inline domtext *impl_from_IXMLDOMText( IXMLDOMText *iface )
51 return (domtext *)((char*)iface - FIELD_OFFSET(domtext, lpVtbl));
54 static HRESULT WINAPI domtext_QueryInterface(
55 IXMLDOMText *iface,
56 REFIID riid,
57 void** ppvObject )
59 domtext *This = impl_from_IXMLDOMText( iface );
60 TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);
62 if ( IsEqualGUID( riid, &IID_IXMLDOMText ) ||
63 IsEqualGUID( riid, &IID_IXMLDOMCharacterData) ||
64 IsEqualGUID( riid, &IID_IDispatch ) ||
65 IsEqualGUID( riid, &IID_IUnknown ) )
67 *ppvObject = iface;
69 else if ( IsEqualGUID( riid, &IID_IXMLDOMNode ) )
71 return IUnknown_QueryInterface(This->node_unk, riid, ppvObject);
73 else
75 FIXME("Unsupported interface %s\n", debugstr_guid(riid));
76 return E_NOINTERFACE;
79 IXMLDOMText_AddRef( iface );
81 return S_OK;
84 static ULONG WINAPI domtext_AddRef(
85 IXMLDOMText *iface )
87 domtext *This = impl_from_IXMLDOMText( iface );
88 return InterlockedIncrement( &This->ref );
91 static ULONG WINAPI domtext_Release(
92 IXMLDOMText *iface )
94 domtext *This = impl_from_IXMLDOMText( iface );
95 ULONG ref;
97 ref = InterlockedDecrement( &This->ref );
98 if ( ref == 0 )
100 IUnknown_Release( This->node_unk );
101 HeapFree( GetProcessHeap(), 0, This );
104 return ref;
107 static HRESULT WINAPI domtext_GetTypeInfoCount(
108 IXMLDOMText *iface,
109 UINT* pctinfo )
111 domtext *This = impl_from_IXMLDOMText( iface );
113 TRACE("(%p)->(%p)\n", This, pctinfo);
115 *pctinfo = 1;
117 return S_OK;
120 static HRESULT WINAPI domtext_GetTypeInfo(
121 IXMLDOMText *iface,
122 UINT iTInfo, LCID lcid,
123 ITypeInfo** ppTInfo )
125 domtext *This = impl_from_IXMLDOMText( iface );
126 HRESULT hr;
128 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
130 hr = get_typeinfo(IXMLDOMText_tid, ppTInfo);
132 return hr;
135 static HRESULT WINAPI domtext_GetIDsOfNames(
136 IXMLDOMText *iface,
137 REFIID riid, LPOLESTR* rgszNames,
138 UINT cNames, LCID lcid, DISPID* rgDispId )
140 domtext *This = impl_from_IXMLDOMText( iface );
141 ITypeInfo *typeinfo;
142 HRESULT hr;
144 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
145 lcid, rgDispId);
147 if(!rgszNames || cNames == 0 || !rgDispId)
148 return E_INVALIDARG;
150 hr = get_typeinfo(IXMLDOMText_tid, &typeinfo);
151 if(SUCCEEDED(hr))
153 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
154 ITypeInfo_Release(typeinfo);
157 return hr;
160 static HRESULT WINAPI domtext_Invoke(
161 IXMLDOMText *iface,
162 DISPID dispIdMember, REFIID riid, LCID lcid,
163 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult,
164 EXCEPINFO* pExcepInfo, UINT* puArgErr )
166 domtext *This = impl_from_IXMLDOMText( iface );
167 ITypeInfo *typeinfo;
168 HRESULT hr;
170 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
171 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
173 hr = get_typeinfo(IXMLDOMText_tid, &typeinfo);
174 if(SUCCEEDED(hr))
176 hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams,
177 pVarResult, pExcepInfo, puArgErr);
178 ITypeInfo_Release(typeinfo);
181 return hr;
184 static HRESULT WINAPI domtext_get_nodeName(
185 IXMLDOMText *iface,
186 BSTR* p )
188 domtext *This = impl_from_IXMLDOMText( iface );
189 return IXMLDOMNode_get_nodeName( This->node, p );
192 static HRESULT WINAPI domtext_get_nodeValue(
193 IXMLDOMText *iface,
194 VARIANT* var1 )
196 domtext *This = impl_from_IXMLDOMText( iface );
197 return IXMLDOMNode_get_nodeValue( This->node, var1 );
200 static HRESULT WINAPI domtext_put_nodeValue(
201 IXMLDOMText *iface,
202 VARIANT var1 )
204 domtext *This = impl_from_IXMLDOMText( iface );
205 return IXMLDOMNode_put_nodeValue( This->node, var1 );
208 static HRESULT WINAPI domtext_get_nodeType(
209 IXMLDOMText *iface,
210 DOMNodeType* domNodeType )
212 domtext *This = impl_from_IXMLDOMText( iface );
213 return IXMLDOMNode_get_nodeType( This->node, domNodeType );
216 static HRESULT WINAPI domtext_get_parentNode(
217 IXMLDOMText *iface,
218 IXMLDOMNode** parent )
220 domtext *This = impl_from_IXMLDOMText( iface );
221 return IXMLDOMNode_get_parentNode( This->node, parent );
224 static HRESULT WINAPI domtext_get_childNodes(
225 IXMLDOMText *iface,
226 IXMLDOMNodeList** outList)
228 domtext *This = impl_from_IXMLDOMText( iface );
229 return IXMLDOMNode_get_childNodes( This->node, outList );
232 static HRESULT WINAPI domtext_get_firstChild(
233 IXMLDOMText *iface,
234 IXMLDOMNode** domNode)
236 domtext *This = impl_from_IXMLDOMText( iface );
237 return IXMLDOMNode_get_firstChild( This->node, domNode );
240 static HRESULT WINAPI domtext_get_lastChild(
241 IXMLDOMText *iface,
242 IXMLDOMNode** domNode)
244 domtext *This = impl_from_IXMLDOMText( iface );
245 return IXMLDOMNode_get_lastChild( This->node, domNode );
248 static HRESULT WINAPI domtext_get_previousSibling(
249 IXMLDOMText *iface,
250 IXMLDOMNode** domNode)
252 domtext *This = impl_from_IXMLDOMText( iface );
253 return IXMLDOMNode_get_previousSibling( This->node, domNode );
256 static HRESULT WINAPI domtext_get_nextSibling(
257 IXMLDOMText *iface,
258 IXMLDOMNode** domNode)
260 domtext *This = impl_from_IXMLDOMText( iface );
261 return IXMLDOMNode_get_nextSibling( This->node, domNode );
264 static HRESULT WINAPI domtext_get_attributes(
265 IXMLDOMText *iface,
266 IXMLDOMNamedNodeMap** attributeMap)
268 domtext *This = impl_from_IXMLDOMText( iface );
269 return IXMLDOMNode_get_attributes( This->node, attributeMap );
272 static HRESULT WINAPI domtext_insertBefore(
273 IXMLDOMText *iface,
274 IXMLDOMNode* newNode, VARIANT var1,
275 IXMLDOMNode** outOldNode)
277 domtext *This = impl_from_IXMLDOMText( iface );
278 return IXMLDOMNode_insertBefore( This->node, newNode, var1, outOldNode );
281 static HRESULT WINAPI domtext_replaceChild(
282 IXMLDOMText *iface,
283 IXMLDOMNode* newNode,
284 IXMLDOMNode* oldNode,
285 IXMLDOMNode** outOldNode)
287 domtext *This = impl_from_IXMLDOMText( iface );
288 return IXMLDOMNode_replaceChild( This->node, newNode, oldNode, outOldNode );
291 static HRESULT WINAPI domtext_removeChild(
292 IXMLDOMText *iface,
293 IXMLDOMNode* domNode, IXMLDOMNode** oldNode)
295 domtext *This = impl_from_IXMLDOMText( iface );
296 return IXMLDOMNode_removeChild( This->node, domNode, oldNode );
299 static HRESULT WINAPI domtext_appendChild(
300 IXMLDOMText *iface,
301 IXMLDOMNode* newNode, IXMLDOMNode** outNewNode)
303 domtext *This = impl_from_IXMLDOMText( iface );
304 return IXMLDOMNode_appendChild( This->node, newNode, outNewNode );
307 static HRESULT WINAPI domtext_hasChildNodes(
308 IXMLDOMText *iface,
309 VARIANT_BOOL* pbool)
311 domtext *This = impl_from_IXMLDOMText( iface );
312 return IXMLDOMNode_hasChildNodes( This->node, pbool );
315 static HRESULT WINAPI domtext_get_ownerDocument(
316 IXMLDOMText *iface,
317 IXMLDOMDocument** domDocument)
319 domtext *This = impl_from_IXMLDOMText( iface );
320 return IXMLDOMNode_get_ownerDocument( This->node, domDocument );
323 static HRESULT WINAPI domtext_cloneNode(
324 IXMLDOMText *iface,
325 VARIANT_BOOL pbool, IXMLDOMNode** outNode)
327 domtext *This = impl_from_IXMLDOMText( iface );
328 return IXMLDOMNode_cloneNode( This->node, pbool, outNode );
331 static HRESULT WINAPI domtext_get_nodeTypeString(
332 IXMLDOMText *iface,
333 BSTR* p)
335 domtext *This = impl_from_IXMLDOMText( iface );
336 return IXMLDOMNode_get_nodeTypeString( This->node, p );
339 static HRESULT WINAPI domtext_get_text(
340 IXMLDOMText *iface,
341 BSTR* p)
343 domtext *This = impl_from_IXMLDOMText( iface );
344 return IXMLDOMNode_get_text( This->node, p );
347 static HRESULT WINAPI domtext_put_text(
348 IXMLDOMText *iface,
349 BSTR p)
351 domtext *This = impl_from_IXMLDOMText( iface );
352 return IXMLDOMNode_put_text( This->node, p );
355 static HRESULT WINAPI domtext_get_specified(
356 IXMLDOMText *iface,
357 VARIANT_BOOL* pbool)
359 domtext *This = impl_from_IXMLDOMText( iface );
360 return IXMLDOMNode_get_specified( This->node, pbool );
363 static HRESULT WINAPI domtext_get_definition(
364 IXMLDOMText *iface,
365 IXMLDOMNode** domNode)
367 domtext *This = impl_from_IXMLDOMText( iface );
368 return IXMLDOMNode_get_definition( This->node, domNode );
371 static HRESULT WINAPI domtext_get_nodeTypedValue(
372 IXMLDOMText *iface,
373 VARIANT* var1)
375 domtext *This = impl_from_IXMLDOMText( iface );
376 return IXMLDOMNode_get_nodeTypedValue( This->node, var1 );
379 static HRESULT WINAPI domtext_put_nodeTypedValue(
380 IXMLDOMText *iface,
381 VARIANT var1)
383 domtext *This = impl_from_IXMLDOMText( iface );
384 return IXMLDOMNode_put_nodeTypedValue( This->node, var1 );
387 static HRESULT WINAPI domtext_get_dataType(
388 IXMLDOMText *iface,
389 VARIANT* var1)
391 domtext *This = impl_from_IXMLDOMText( iface );
392 return IXMLDOMNode_get_dataType( This->node, var1 );
395 static HRESULT WINAPI domtext_put_dataType(
396 IXMLDOMText *iface,
397 BSTR p)
399 domtext *This = impl_from_IXMLDOMText( iface );
400 return IXMLDOMNode_put_dataType( This->node, p );
403 static HRESULT WINAPI domtext_get_xml(
404 IXMLDOMText *iface,
405 BSTR* p)
407 domtext *This = impl_from_IXMLDOMText( iface );
408 return IXMLDOMNode_get_xml( This->node, p );
411 static HRESULT WINAPI domtext_transformNode(
412 IXMLDOMText *iface,
413 IXMLDOMNode* domNode, BSTR* p)
415 domtext *This = impl_from_IXMLDOMText( iface );
416 return IXMLDOMNode_transformNode( This->node, domNode, p );
419 static HRESULT WINAPI domtext_selectNodes(
420 IXMLDOMText *iface,
421 BSTR p, IXMLDOMNodeList** outList)
423 domtext *This = impl_from_IXMLDOMText( iface );
424 return IXMLDOMNode_selectNodes( This->node, p, outList );
427 static HRESULT WINAPI domtext_selectSingleNode(
428 IXMLDOMText *iface,
429 BSTR p, IXMLDOMNode** outNode)
431 domtext *This = impl_from_IXMLDOMText( iface );
432 return IXMLDOMNode_selectSingleNode( This->node, p, outNode );
435 static HRESULT WINAPI domtext_get_parsed(
436 IXMLDOMText *iface,
437 VARIANT_BOOL* pbool)
439 domtext *This = impl_from_IXMLDOMText( iface );
440 return IXMLDOMNode_get_parsed( This->node, pbool );
443 static HRESULT WINAPI domtext_get_namespaceURI(
444 IXMLDOMText *iface,
445 BSTR* p)
447 domtext *This = impl_from_IXMLDOMText( iface );
448 return IXMLDOMNode_get_namespaceURI( This->node, p );
451 static HRESULT WINAPI domtext_get_prefix(
452 IXMLDOMText *iface,
453 BSTR* p)
455 domtext *This = impl_from_IXMLDOMText( iface );
456 return IXMLDOMNode_get_prefix( This->node, p );
459 static HRESULT WINAPI domtext_get_baseName(
460 IXMLDOMText *iface,
461 BSTR* p)
463 domtext *This = impl_from_IXMLDOMText( iface );
464 return IXMLDOMNode_get_baseName( This->node, p );
467 static HRESULT WINAPI domtext_transformNodeToObject(
468 IXMLDOMText *iface,
469 IXMLDOMNode* domNode, VARIANT var1)
471 domtext *This = impl_from_IXMLDOMText( iface );
472 return IXMLDOMNode_transformNodeToObject( This->node, domNode, var1 );
475 static HRESULT WINAPI domtext_get_data(
476 IXMLDOMText *iface,
477 BSTR *p)
479 domtext *This = impl_from_IXMLDOMText( iface );
480 HRESULT hr = E_FAIL;
481 VARIANT vRet;
483 if(!p)
484 return E_INVALIDARG;
486 hr = IXMLDOMNode_get_nodeValue( This->node, &vRet );
487 if(hr == S_OK)
489 *p = V_BSTR(&vRet);
492 return hr;
495 static HRESULT WINAPI domtext_put_data(
496 IXMLDOMText *iface,
497 BSTR data)
499 domtext *This = impl_from_IXMLDOMText( iface );
500 HRESULT hr = E_FAIL;
501 VARIANT val;
503 TRACE("%p %s\n", This, debugstr_w(data) );
505 V_VT(&val) = VT_BSTR;
506 V_BSTR(&val) = data;
508 hr = IXMLDOMNode_put_nodeValue( This->node, val );
510 return hr;
513 static HRESULT WINAPI domtext_get_length(
514 IXMLDOMText *iface,
515 long *len)
517 domtext *This = impl_from_IXMLDOMText( iface );
518 xmlnode *pDOMNode = impl_from_IXMLDOMNode( This->node );
519 xmlChar *pContent;
520 long nLength = 0;
522 TRACE("%p\n", iface);
524 if(!len)
525 return E_INVALIDARG;
527 pContent = xmlNodeGetContent(pDOMNode->node);
528 if(pContent)
530 nLength = xmlStrlen(pContent);
531 xmlFree(pContent);
534 *len = nLength;
536 return S_OK;
539 static HRESULT WINAPI domtext_substringData(
540 IXMLDOMText *iface,
541 long offset, long count, BSTR *p)
543 domtext *This = impl_from_IXMLDOMText( iface );
544 xmlnode *pDOMNode = impl_from_IXMLDOMNode( This->node );
545 xmlChar *pContent;
546 long nLength = 0;
547 HRESULT hr = S_FALSE;
549 TRACE("%p\n", iface);
551 if(!p)
552 return E_INVALIDARG;
554 *p = NULL;
555 if(offset < 0 || count < 0)
556 return E_INVALIDARG;
558 if(count == 0)
559 return hr;
561 pContent = xmlNodeGetContent(pDOMNode->node);
562 if(pContent)
564 nLength = xmlStrlen(pContent);
566 if( offset < nLength)
568 BSTR sContent = bstr_from_xmlChar(pContent);
569 if(offset + count > nLength)
570 *p = SysAllocString(&sContent[offset]);
571 else
572 *p = SysAllocStringLen(&sContent[offset], count);
574 SysFreeString(sContent);
575 hr = S_OK;
578 xmlFree(pContent);
581 return hr;
584 static HRESULT WINAPI domtext_appendData(
585 IXMLDOMText *iface,
586 BSTR p)
588 domtext *This = impl_from_IXMLDOMText( iface );
589 xmlnode *pDOMNode = impl_from_IXMLDOMNode( This->node );
590 xmlChar *pContent;
591 HRESULT hr = S_FALSE;
593 TRACE("%p\n", iface);
595 /* Nothing to do if NULL or an Empty string passed in. */
596 if(p == NULL || SysStringLen(p) == 0)
597 return S_OK;
599 pContent = xmlChar_from_wchar( (WCHAR*)p );
600 if(pContent)
602 if(xmlTextConcat(pDOMNode->node, pContent, SysStringLen(p) ) == 0)
603 hr = S_OK;
604 else
605 hr = E_FAIL;
607 else
608 hr = E_FAIL;
610 return hr;
613 static HRESULT WINAPI domtext_insertData(
614 IXMLDOMText *iface,
615 long offset, BSTR p)
617 domtext *This = impl_from_IXMLDOMText( iface );
618 xmlnode *pDOMNode = impl_from_IXMLDOMNode( This->node );
619 xmlChar *pXmlContent;
620 BSTR sNewString;
621 HRESULT hr = S_FALSE;
622 long nLength = 0, nLengthP = 0;
623 xmlChar *str = NULL;
625 TRACE("%p\n", This);
627 /* If have a NULL or empty string, don't do anything. */
628 if(SysStringLen(p) == 0)
629 return S_OK;
631 if(offset < 0)
633 return E_INVALIDARG;
636 pXmlContent = xmlNodeGetContent(pDOMNode->node);
637 if(pXmlContent)
639 BSTR sContent = bstr_from_xmlChar( pXmlContent );
640 nLength = SysStringLen(sContent);
641 nLengthP = SysStringLen(p);
643 if(nLength < offset)
645 SysFreeString(sContent);
646 xmlFree(pXmlContent);
648 return E_INVALIDARG;
651 sNewString = SysAllocStringLen(NULL, nLength + nLengthP + 1);
652 if(sNewString)
654 if(offset > 0)
655 memcpy(sNewString, sContent, offset * sizeof(WCHAR));
657 memcpy(&sNewString[offset], p, nLengthP * sizeof(WCHAR));
659 if(offset+nLengthP < nLength)
660 memcpy(&sNewString[offset+nLengthP], &sContent[offset], (nLength-offset) * sizeof(WCHAR));
662 sNewString[nLengthP + nLength] = 0;
664 str = xmlChar_from_wchar((WCHAR*)sNewString);
665 if(str)
667 xmlNodeSetContent(pDOMNode->node, str);
668 hr = S_OK;
671 SysFreeString(sNewString);
674 SysFreeString(sContent);
676 xmlFree(pXmlContent);
679 return hr;
682 static HRESULT WINAPI domtext_deleteData(
683 IXMLDOMText *iface,
684 long offset, long count)
686 FIXME("\n");
687 return E_NOTIMPL;
690 static HRESULT WINAPI domtext_replaceData(
691 IXMLDOMText *iface,
692 long offset, long count, BSTR p)
694 FIXME("\n");
695 return E_NOTIMPL;
698 static HRESULT WINAPI domtext_splitText(
699 IXMLDOMText *iface,
700 long offset, IXMLDOMText **txtNode)
702 FIXME("\n");
703 return E_NOTIMPL;
707 static const struct IXMLDOMTextVtbl domtext_vtbl =
709 domtext_QueryInterface,
710 domtext_AddRef,
711 domtext_Release,
712 domtext_GetTypeInfoCount,
713 domtext_GetTypeInfo,
714 domtext_GetIDsOfNames,
715 domtext_Invoke,
716 domtext_get_nodeName,
717 domtext_get_nodeValue,
718 domtext_put_nodeValue,
719 domtext_get_nodeType,
720 domtext_get_parentNode,
721 domtext_get_childNodes,
722 domtext_get_firstChild,
723 domtext_get_lastChild,
724 domtext_get_previousSibling,
725 domtext_get_nextSibling,
726 domtext_get_attributes,
727 domtext_insertBefore,
728 domtext_replaceChild,
729 domtext_removeChild,
730 domtext_appendChild,
731 domtext_hasChildNodes,
732 domtext_get_ownerDocument,
733 domtext_cloneNode,
734 domtext_get_nodeTypeString,
735 domtext_get_text,
736 domtext_put_text,
737 domtext_get_specified,
738 domtext_get_definition,
739 domtext_get_nodeTypedValue,
740 domtext_put_nodeTypedValue,
741 domtext_get_dataType,
742 domtext_put_dataType,
743 domtext_get_xml,
744 domtext_transformNode,
745 domtext_selectNodes,
746 domtext_selectSingleNode,
747 domtext_get_parsed,
748 domtext_get_namespaceURI,
749 domtext_get_prefix,
750 domtext_get_baseName,
751 domtext_transformNodeToObject,
752 domtext_get_data,
753 domtext_put_data,
754 domtext_get_length,
755 domtext_substringData,
756 domtext_appendData,
757 domtext_insertData,
758 domtext_deleteData,
759 domtext_replaceData,
760 domtext_splitText
763 IUnknown* create_text( xmlNodePtr text )
765 domtext *This;
766 HRESULT hr;
768 This = HeapAlloc( GetProcessHeap(), 0, sizeof *This );
769 if ( !This )
770 return NULL;
772 This->lpVtbl = &domtext_vtbl;
773 This->ref = 1;
775 This->node_unk = create_basic_node( text, (IUnknown*)&This->lpVtbl );
776 if(!This->node_unk)
778 HeapFree(GetProcessHeap(), 0, This);
779 return NULL;
782 hr = IUnknown_QueryInterface(This->node_unk, &IID_IXMLDOMNode, (LPVOID*)&This->node);
783 if(FAILED(hr))
785 IUnknown_Release(This->node_unk);
786 HeapFree( GetProcessHeap(), 0, This );
787 return NULL;
789 /* The ref on This->node is actually looped back into this object, so release it */
790 IXMLDOMNode_Release(This->node);
792 return (IUnknown*) &This->lpVtbl;
795 #endif