Commit 8aef340c authored by Robert Shearman's avatar Robert Shearman Committed by Alexandre Julliard

- Fix IMemAlloc_Free when IMemAlloc_Alloc hasn't yet been called and

debugging is on. - Fix OleMetafilePictFromIconAndLabel (fixes attachments in Outlook2k). - Implement OleTranslateAccelerator. - Move OleCreate and a load of PropVariant functions out of stubs file. - Change OleCreate to a semi-stub.
parent d2c4cf14
...@@ -108,7 +108,14 @@ static int AddMemoryLocation(LPVOID * pMem) ...@@ -108,7 +108,14 @@ static int AddMemoryLocation(LPVOID * pMem)
static int RemoveMemoryLocation(LPVOID * pMem) static int RemoveMemoryLocation(LPVOID * pMem)
{ {
LPVOID * Current = Malloc32.SpyedBlocks; LPVOID * Current;
/* allocate the table if not already allocated */
if (!Malloc32.SpyedBlockTableLength) {
if (!SetSpyedBlockTableLength(0x1000)) return 0;
}
Current = Malloc32.SpyedBlocks;
/* find the location */ /* find the location */
while (*Current != pMem) { while (*Current != pMem) {
......
...@@ -2235,6 +2235,296 @@ HRESULT WINAPI OleDraw( ...@@ -2235,6 +2235,296 @@ HRESULT WINAPI OleDraw(
} }
} }
/***********************************************************************
* OleTranslateAccelerator [OLE32.@]
*/
HRESULT WINAPI OleTranslateAccelerator (LPOLEINPLACEFRAME lpFrame,
LPOLEINPLACEFRAMEINFO lpFrameInfo, LPMSG lpmsg)
{
WORD wID;
TRACE("(%p,%p,%p)\n", lpFrame, lpFrameInfo, lpmsg);
if (IsAccelerator(lpFrameInfo->haccel,lpFrameInfo->cAccelEntries,lpmsg,&wID))
return IOleInPlaceFrame_TranslateAccelerator(lpFrame,lpmsg,wID);
return S_FALSE;
}
/******************************************************************************
* OleCreate [OLE32.@]
*
*/
HRESULT WINAPI OleCreate(
REFCLSID rclsid,
REFIID riid,
DWORD renderopt,
LPFORMATETC pFormatEtc,
LPOLECLIENTSITE pClientSite,
LPSTORAGE pStg,
LPVOID* ppvObj)
{
HRESULT hres, hres1;
IUnknown * pUnk = NULL;
FIXME("\n\t%s\n\t%s semi-stub!\n", debugstr_guid(rclsid), debugstr_guid(riid));
if (SUCCEEDED((hres = CoCreateInstance(rclsid, 0, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER|CLSCTX_LOCAL_SERVER , riid, (LPVOID*)&pUnk))))
{
if (pClientSite)
{
IOleObject * pOE;
IPersistStorage * pPS;
if (SUCCEEDED((hres = IUnknown_QueryInterface( pUnk, &IID_IOleObject, (LPVOID*)&pOE))))
{
TRACE("trying to set clientsite %p\n", pClientSite);
hres1 = IOleObject_SetClientSite(pOE, pClientSite);
TRACE("-- result 0x%08lx\n", hres1);
IOleObject_Release(pOE);
}
if (SUCCEEDED((hres = IUnknown_QueryInterface( pUnk, &IID_IPersistStorage, (LPVOID*)&pPS))))
{
TRACE("trying to set stg %p\n", pStg);
hres1 = IPersistStorage_InitNew(pPS, pStg);
TRACE("-- result 0x%08lx\n", hres1);
IPersistStorage_Release(pPS);
}
}
}
*ppvObj = pUnk;
TRACE("-- %p \n", pUnk);
return hres;
}
/***********************************************************************
* OLE_FreeClipDataArray [internal]
*
* NOTES:
* frees the data associated with an array of CLIPDATAs
*/
static void OLE_FreeClipDataArray(ULONG count, CLIPDATA * pClipDataArray)
{
ULONG i;
for (i = 0; i < count; i++)
if (pClipDataArray[i].pClipData)
CoTaskMemFree(pClipDataArray[i].pClipData);
}
HRESULT WINAPI FreePropVariantArray(ULONG,PROPVARIANT*);
/***********************************************************************
* PropVariantClear [OLE32.@]
*/
HRESULT WINAPI PropVariantClear(PROPVARIANT * pvar) /* [in/out] */
{
TRACE("(%p)\n", pvar);
if (!pvar)
return S_OK;
switch(pvar->vt)
{
case VT_STREAM:
case VT_STREAMED_OBJECT:
case VT_STORAGE:
case VT_STORED_OBJECT:
IUnknown_Release((LPUNKNOWN)pvar->u.pStream);
break;
case VT_CLSID:
case VT_LPSTR:
case VT_LPWSTR:
/* pick an arbitary typed pointer - we don't care about the type
* as we are just freeing it */
CoTaskMemFree(pvar->u.puuid);
break;
case VT_BLOB:
case VT_BLOB_OBJECT:
CoTaskMemFree(pvar->u.blob.pBlobData);
break;
case VT_BSTR:
FIXME("Need to load OLEAUT32 for SysFreeString\n");
/* SysFreeString(pvar->u.bstrVal); */
break;
case VT_CF:
if (pvar->u.pclipdata)
{
OLE_FreeClipDataArray(1, pvar->u.pclipdata);
CoTaskMemFree(pvar->u.pclipdata);
}
break;
default:
if (pvar->vt & VT_ARRAY)
{
FIXME("Need to call SafeArrayDestroy\n");
/* SafeArrayDestroy(pvar->u.caub); */
}
switch (pvar->vt & VT_VECTOR)
{
case VT_VARIANT:
FreePropVariantArray(pvar->u.capropvar.cElems, pvar->u.capropvar.pElems);
break;
case VT_CF:
OLE_FreeClipDataArray(pvar->u.caclipdata.cElems, pvar->u.caclipdata.pElems);
break;
case VT_BSTR:
case VT_LPSTR:
case VT_LPWSTR:
FIXME("Freeing of vector sub-type not supported yet\n");
}
if (pvar->vt & VT_VECTOR)
{
/* pick an arbitary VT_VECTOR structure - they all have the same
* memory layout */
CoTaskMemFree(pvar->u.capropvar.pElems);
}
}
ZeroMemory(pvar, sizeof(*pvar));
return S_OK;
}
/***********************************************************************
* PropVariantCopy [OLE32.@]
*/
HRESULT WINAPI PropVariantCopy(PROPVARIANT *pvarDest, /* [out] */
const PROPVARIANT *pvarSrc) /* [in] */
{
ULONG len;
TRACE("(%p, %p): stub:\n", pvarDest, pvarSrc);
/* this will deal with most cases */
CopyMemory(pvarDest, pvarSrc, sizeof(*pvarDest));
switch(pvarSrc->vt)
{
case VT_STREAM:
case VT_STREAMED_OBJECT:
case VT_STORAGE:
case VT_STORED_OBJECT:
IUnknown_AddRef((LPUNKNOWN)pvarDest->u.pStream);
break;
case VT_CLSID:
pvarDest->u.puuid = CoTaskMemAlloc(sizeof(CLSID));
CopyMemory(pvarDest->u.puuid, pvarSrc->u.puuid, sizeof(CLSID));
break;
case VT_LPSTR:
len = strlen(pvarSrc->u.pszVal);
pvarDest->u.pszVal = CoTaskMemAlloc(len);
CopyMemory(pvarDest->u.pszVal, pvarSrc->u.pszVal, len);
break;
case VT_LPWSTR:
len = lstrlenW(pvarSrc->u.pwszVal);
pvarDest->u.pwszVal = CoTaskMemAlloc(len);
CopyMemory(pvarDest->u.pwszVal, pvarSrc->u.pwszVal, len);
break;
case VT_BLOB:
case VT_BLOB_OBJECT:
if (pvarSrc->u.blob.pBlobData)
{
len = pvarSrc->u.blob.cbSize;
pvarDest->u.blob.pBlobData = CoTaskMemAlloc(len);
CopyMemory(pvarDest->u.blob.pBlobData, pvarSrc->u.blob.pBlobData, len);
}
break;
case VT_BSTR:
FIXME("Need to copy BSTR\n");
break;
case VT_CF:
if (pvarSrc->u.pclipdata)
{
len = pvarSrc->u.pclipdata->cbSize - sizeof(pvarSrc->u.pclipdata->ulClipFmt);
CoTaskMemAlloc(len);
CopyMemory(pvarDest->u.pclipdata->pClipData, pvarSrc->u.pclipdata->pClipData, len);
}
break;
default:
if (pvarSrc->vt & VT_ARRAY)
{
FIXME("Need to call SafeArrayCopy\n");
/* SafeArrayCopy(...); */
}
if (pvarSrc->vt & VT_VECTOR)
{
int elemSize;
switch(pvarSrc->vt & VT_VECTOR)
{
case VT_I1: elemSize = sizeof(pvarSrc->u.cVal); break;
case VT_UI1: elemSize = sizeof(pvarSrc->u.bVal); break;
case VT_I2: elemSize = sizeof(pvarSrc->u.iVal); break;
case VT_UI2: elemSize = sizeof(pvarSrc->u.uiVal); break;
case VT_BOOL: elemSize = sizeof(pvarSrc->u.boolVal); break;
case VT_I4: elemSize = sizeof(pvarSrc->u.lVal); break;
case VT_UI4: elemSize = sizeof(pvarSrc->u.ulVal); break;
case VT_R4: elemSize = sizeof(pvarSrc->u.fltVal); break;
case VT_R8: elemSize = sizeof(pvarSrc->u.dblVal); break;
case VT_ERROR: elemSize = sizeof(pvarSrc->u.scode); break;
case VT_I8: elemSize = sizeof(pvarSrc->u.hVal); break;
case VT_UI8: elemSize = sizeof(pvarSrc->u.uhVal); break;
case VT_CY: elemSize = sizeof(pvarSrc->u.cyVal); break;
case VT_DATE: elemSize = sizeof(pvarSrc->u.date); break;
case VT_FILETIME: elemSize = sizeof(pvarSrc->u.filetime); break;
case VT_CLSID: elemSize = sizeof(*pvarSrc->u.puuid); break;
case VT_CF: elemSize = sizeof(*pvarSrc->u.pclipdata); break;
case VT_BSTR:
case VT_LPSTR:
case VT_LPWSTR:
case VT_VARIANT:
default:
FIXME("Invalid element type: %ul\n", pvarSrc->vt & VT_VECTOR);
return E_INVALIDARG;
}
len = pvarSrc->u.capropvar.cElems;
pvarDest->u.capropvar.pElems = CoTaskMemAlloc(len * elemSize);
if (pvarSrc->vt == (VT_VECTOR | VT_VARIANT))
{
ULONG i;
for (i = 0; i < len; i++)
PropVariantCopy(&pvarDest->u.capropvar.pElems[i], &pvarSrc->u.capropvar.pElems[i]);
}
else if (pvarSrc->vt == (VT_VECTOR | VT_CF))
{
FIXME("Copy clipformats\n");
}
else if (pvarSrc->vt == (VT_VECTOR | VT_BSTR))
{
FIXME("Copy BSTRs\n");
}
else if (pvarSrc->vt == (VT_VECTOR | VT_LPSTR))
{
FIXME("Copy LPSTRs\n");
}
else if (pvarSrc->vt == (VT_VECTOR | VT_LPSTR))
{
FIXME("Copy LPWSTRs\n");
}
else
CopyMemory(pvarDest->u.capropvar.pElems, pvarSrc->u.capropvar.pElems, len * elemSize);
}
}
return S_OK;
}
/***********************************************************************
* FreePropVariantArray [OLE32.@]
*/
HRESULT WINAPI FreePropVariantArray(ULONG cVariants, /* [in] */
PROPVARIANT *rgvars) /* [in/out] */
{
ULONG i;
TRACE("(%lu, %p)\n", cVariants, rgvars);
for(i = 0; i < cVariants; i++)
PropVariantClear(&rgvars[i]);
return S_OK;
}
/****************************************************************************** /******************************************************************************
* DllDebugObjectRPCHook (OLE32.@) * DllDebugObjectRPCHook (OLE32.@)
* turns on and off internal debugging, pointer is only used on macintosh * turns on and off internal debugging, pointer is only used on macintosh
......
...@@ -55,16 +55,6 @@ HRESULT WINAPI OleDuplicateData(HANDLE hSrc, CLIPFORMAT cfFormat, ...@@ -55,16 +55,6 @@ HRESULT WINAPI OleDuplicateData(HANDLE hSrc, CLIPFORMAT cfFormat,
} }
/***********************************************************************
* OleTranslateAccelerator [OLE32.@]
*/
HRESULT WINAPI OleTranslateAccelerator (LPOLEINPLACEFRAME lpFrame,
LPOLEINPLACEFRAMEINFO lpFrameInfo, LPMSG lpmsg)
{
FIXME("(%p,%p,%p),stub!\n", lpFrame, lpFrameInfo, lpmsg);
return S_OK;
}
/****************************************************************************** /******************************************************************************
* SetConvertStg [OLE32.@] * SetConvertStg [OLE32.@]
*/ */
...@@ -75,53 +65,6 @@ HRESULT WINAPI SetConvertStg(LPSTORAGE pStg, BOOL fConvert) ...@@ -75,53 +65,6 @@ HRESULT WINAPI SetConvertStg(LPSTORAGE pStg, BOOL fConvert)
} }
/****************************************************************************** /******************************************************************************
* OleCreate [OLE32.@]
*
*/
HRESULT WINAPI OleCreate(
REFCLSID rclsid,
REFIID riid,
DWORD renderopt,
LPFORMATETC pFormatEtc,
LPOLECLIENTSITE pClientSite,
LPSTORAGE pStg,
LPVOID* ppvObj)
{
HRESULT hres, hres1;
IUnknown * pUnk = NULL;
FIXME("\n\t%s\n\t%s stub!\n", debugstr_guid(rclsid), debugstr_guid(riid));
if (SUCCEEDED((hres = CoCreateInstance(rclsid, 0, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER|CLSCTX_LOCAL_SERVER , riid, (LPVOID*)&pUnk))))
{
if (pClientSite)
{
IOleObject * pOE;
IPersistStorage * pPS;
if (SUCCEEDED((hres = IUnknown_QueryInterface( pUnk, &IID_IOleObject, (LPVOID*)&pOE))))
{
TRACE("trying to set clientsite %p\n", pClientSite);
hres1 = IOleObject_SetClientSite(pOE, pClientSite);
TRACE("-- result 0x%08lx\n", hres1);
IOleObject_Release(pOE);
}
if (SUCCEEDED((hres = IUnknown_QueryInterface( pUnk, &IID_IPersistStorage, (LPVOID*)&pPS))))
{
TRACE("trying to set stg %p\n", pStg);
hres1 = IPersistStorage_InitNew(pPS, pStg);
TRACE("-- result 0x%08lx\n", hres1);
IPersistStorage_Release(pPS);
}
}
}
*ppvObj = pUnk;
TRACE("-- %p \n", pUnk);
return hres;
}
/******************************************************************************
* OleCreateLink [OLE32.@] * OleCreateLink [OLE32.@]
*/ */
HRESULT WINAPI OleCreateLink(LPMONIKER pmkLinkSrc, REFIID riid, DWORD renderopt, LPFORMATETC lpFormatEtc, HRESULT WINAPI OleCreateLink(LPMONIKER pmkLinkSrc, REFIID riid, DWORD renderopt, LPFORMATETC lpFormatEtc,
...@@ -208,266 +151,6 @@ HRESULT WINAPI OleRegEnumFormatEtc ( ...@@ -208,266 +151,6 @@ HRESULT WINAPI OleRegEnumFormatEtc (
} }
/*********************************************************************** /***********************************************************************
* OLE_FreeClipDataArray [internal]
*
* NOTES:
* frees the data associated with an array of CLIPDATAs
*/
static void OLE_FreeClipDataArray(ULONG count, CLIPDATA * pClipDataArray)
{
ULONG i;
for (i = 0; i < count; i++)
{
if (pClipDataArray[i].pClipData)
{
CoTaskMemFree(pClipDataArray[i].pClipData);
}
}
}
HRESULT WINAPI FreePropVariantArray(ULONG,PROPVARIANT*);
/***********************************************************************
* PropVariantClear [OLE32.@]
*/
HRESULT WINAPI PropVariantClear(PROPVARIANT * pvar) /* [in/out] */
{
TRACE("(%p)\n", pvar);
if (!pvar)
return S_OK;
switch(pvar->vt)
{
case VT_STREAM:
case VT_STREAMED_OBJECT:
case VT_STORAGE:
case VT_STORED_OBJECT:
IUnknown_Release((LPUNKNOWN)pvar->u.pStream);
break;
case VT_CLSID:
case VT_LPSTR:
case VT_LPWSTR:
CoTaskMemFree(pvar->u.puuid); /* pick an arbitary typed pointer - we don't care about the type as we are just freeing it */
break;
case VT_BLOB:
case VT_BLOB_OBJECT:
CoTaskMemFree(pvar->u.blob.pBlobData);
break;
case VT_BSTR:
FIXME("Need to load OLEAUT32 for SysFreeString\n");
/* SysFreeString(pvar->u.bstrVal); */
break;
case VT_CF:
if (pvar->u.pclipdata)
{
OLE_FreeClipDataArray(1, pvar->u.pclipdata);
CoTaskMemFree(pvar->u.pclipdata);
}
break;
default:
if (pvar->vt & VT_ARRAY)
{
FIXME("Need to call SafeArrayDestroy\n");
/* SafeArrayDestroy(pvar->u.caub); */
}
switch (pvar->vt & VT_VECTOR)
{
case VT_VARIANT:
FreePropVariantArray(pvar->u.capropvar.cElems, pvar->u.capropvar.pElems);
break;
case VT_CF:
OLE_FreeClipDataArray(pvar->u.caclipdata.cElems, pvar->u.caclipdata.pElems);
break;
case VT_BSTR:
case VT_LPSTR:
case VT_LPWSTR:
FIXME("Freeing of vector sub-type not supported yet\n");
}
if (pvar->vt & VT_VECTOR)
{
CoTaskMemFree(pvar->u.capropvar.pElems); /* pick an arbitary VT_VECTOR structure - they all have the same memory layout */
}
}
ZeroMemory(pvar, sizeof(*pvar));
return S_OK;
}
/***********************************************************************
* PropVariantCopy [OLE32.@]
*/
HRESULT WINAPI PropVariantCopy(PROPVARIANT *pvarDest, /* [out] FIXME: PROPVARIANT * */
const PROPVARIANT *pvarSrc) /* [in] FIXME: const PROPVARIANT * */
{
ULONG len;
TRACE("(%p, %p): stub:\n", pvarDest, pvarSrc);
/* this will deal with most cases */
CopyMemory(pvarDest, pvarSrc, sizeof(*pvarDest));
switch(pvarSrc->vt)
{
case VT_STREAM:
case VT_STREAMED_OBJECT:
case VT_STORAGE:
case VT_STORED_OBJECT:
IUnknown_AddRef((LPUNKNOWN)pvarDest->u.pStream);
break;
case VT_CLSID:
pvarDest->u.puuid = CoTaskMemAlloc(sizeof(CLSID));
CopyMemory(pvarDest->u.puuid, pvarSrc->u.puuid, sizeof(CLSID));
break;
case VT_LPSTR:
len = strlen(pvarSrc->u.pszVal);
pvarDest->u.pszVal = CoTaskMemAlloc(len);
CopyMemory(pvarDest->u.pszVal, pvarSrc->u.pszVal, len);
break;
case VT_LPWSTR:
len = lstrlenW(pvarSrc->u.pwszVal);
pvarDest->u.pwszVal = CoTaskMemAlloc(len);
CopyMemory(pvarDest->u.pwszVal, pvarSrc->u.pwszVal, len);
break;
case VT_BLOB:
case VT_BLOB_OBJECT:
if (pvarSrc->u.blob.pBlobData)
{
len = pvarSrc->u.blob.cbSize;
pvarDest->u.blob.pBlobData = CoTaskMemAlloc(len);
CopyMemory(pvarDest->u.blob.pBlobData, pvarSrc->u.blob.pBlobData, len);
}
break;
case VT_BSTR:
FIXME("Need to copy BSTR\n");
break;
case VT_CF:
if (pvarSrc->u.pclipdata)
{
len = pvarSrc->u.pclipdata->cbSize - sizeof(pvarSrc->u.pclipdata->ulClipFmt);
CoTaskMemAlloc(len);
CopyMemory(pvarDest->u.pclipdata->pClipData, pvarSrc->u.pclipdata->pClipData, len);
}
break;
default:
if (pvarSrc->vt & VT_ARRAY)
{
FIXME("Need to call SafeArrayCopy\n");
/* SafeArrayCopy(...); */
}
if (pvarSrc->vt & VT_VECTOR)
{
int elemSize;
switch(pvarSrc->vt & VT_VECTOR)
{
case VT_I1:
elemSize = sizeof(pvarSrc->u.cVal);
break;
case VT_UI1:
elemSize = sizeof(pvarSrc->u.bVal);
break;
case VT_I2:
elemSize = sizeof(pvarSrc->u.iVal);
break;
case VT_UI2:
elemSize = sizeof(pvarSrc->u.uiVal);
break;
case VT_BOOL:
elemSize = sizeof(pvarSrc->u.boolVal);
break;
case VT_I4:
elemSize = sizeof(pvarSrc->u.lVal);
break;
case VT_UI4:
elemSize = sizeof(pvarSrc->u.ulVal);
break;
case VT_R4:
elemSize = sizeof(pvarSrc->u.fltVal);
break;
case VT_R8:
elemSize = sizeof(pvarSrc->u.dblVal);
break;
case VT_ERROR:
elemSize = sizeof(pvarSrc->u.scode);
break;
case VT_I8:
elemSize = sizeof(pvarSrc->u.hVal);
break;
case VT_UI8:
elemSize = sizeof(pvarSrc->u.uhVal);
break;
case VT_CY:
elemSize = sizeof(pvarSrc->u.cyVal);
break;
case VT_DATE:
elemSize = sizeof(pvarSrc->u.date);
break;
case VT_FILETIME:
elemSize = sizeof(pvarSrc->u.filetime);
break;
case VT_CLSID:
elemSize = sizeof(*pvarSrc->u.puuid);
break;
case VT_CF:
elemSize = sizeof(*pvarSrc->u.pclipdata);
break;
case VT_BSTR:
case VT_LPSTR:
case VT_LPWSTR:
case VT_VARIANT:
default:
FIXME("Invalid element type: %ul\n", pvarSrc->vt & VT_VECTOR);
return E_INVALIDARG;
}
len = pvarSrc->u.capropvar.cElems;
pvarDest->u.capropvar.pElems = CoTaskMemAlloc(len * elemSize);
if (pvarSrc->vt == (VT_VECTOR | VT_VARIANT))
{
ULONG i;
for (i = 0; i < len; i++)
PropVariantCopy(&pvarDest->u.capropvar.pElems[i], &pvarSrc->u.capropvar.pElems[i]);
}
else if (pvarSrc->vt == (VT_VECTOR | VT_CF))
{
FIXME("Copy clipformats\n");
}
else if (pvarSrc->vt == (VT_VECTOR | VT_BSTR))
{
FIXME("Copy BSTRs\n");
}
else if (pvarSrc->vt == (VT_VECTOR | VT_LPSTR))
{
FIXME("Copy LPSTRs\n");
}
else if (pvarSrc->vt == (VT_VECTOR | VT_LPSTR))
{
FIXME("Copy LPWSTRs\n");
}
else
CopyMemory(pvarDest->u.capropvar.pElems, pvarSrc->u.capropvar.pElems, len * elemSize);
}
}
return S_OK;
}
/***********************************************************************
* FreePropVariantArray [OLE32.@]
*/
HRESULT WINAPI FreePropVariantArray(ULONG cVariants, /* [in] */
PROPVARIANT *rgvars) /* [in/out] */
{
ULONG i;
TRACE("(%lu, %p)\n", cVariants, rgvars);
for(i = 0; i < cVariants; i++)
PropVariantClear(&rgvars[i]);
return S_OK;
}
/***********************************************************************
* CoIsOle1Class [OLE32.@] * CoIsOle1Class [OLE32.@]
*/ */
BOOL WINAPI CoIsOle1Class(REFCLSID clsid) BOOL WINAPI CoIsOle1Class(REFCLSID clsid)
......
...@@ -19,12 +19,14 @@ ...@@ -19,12 +19,14 @@
*/ */
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h>
#include "windef.h" #include "windef.h"
#include "winerror.h" #include "winerror.h"
#include "winbase.h" #include "winbase.h"
#include "wingdi.h" #include "wingdi.h"
#include "winuser.h" #include "winuser.h"
#include "winnls.h"
#include "ole32_main.h" #include "ole32_main.h"
#include "wine/debug.h" #include "wine/debug.h"
...@@ -38,20 +40,23 @@ HINSTANCE OLE32_hInstance = 0; ...@@ -38,20 +40,23 @@ HINSTANCE OLE32_hInstance = 0;
HGLOBAL WINAPI OleMetafilePictFromIconAndLabel(HICON hIcon, LPOLESTR lpszLabel, HGLOBAL WINAPI OleMetafilePictFromIconAndLabel(HICON hIcon, LPOLESTR lpszLabel,
LPOLESTR lpszSourceFile, UINT iIconIndex) LPOLESTR lpszSourceFile, UINT iIconIndex)
{ {
HMETAFILE hmf; METAFILEPICT mfp;
HDC hdc; HDC hdc;
UINT dy, mfsize; UINT dy;
HGLOBAL hmem = 0; HGLOBAL hmem = NULL;
LPVOID mfdata; LPVOID mfdata;
static const char szIconOnly[] = "IconOnly";
TRACE("%p %p %p %d\n", hIcon, lpszLabel, lpszSourceFile, iIconIndex); TRACE("%p %p %s %d\n", hIcon, lpszLabel, debugstr_w(lpszSourceFile), iIconIndex);
if( !hIcon ) if( !hIcon )
return 0; return NULL;
hdc = CreateMetaFileW(NULL); hdc = CreateMetaFileW(NULL);
if( !hdc ) if( !hdc )
return 0; return NULL;
ExtEscape(hdc, MFCOMMENT, sizeof(szIconOnly), szIconOnly, 0, NULL);
/* FIXME: things are drawn in the wrong place */ /* FIXME: things are drawn in the wrong place */
DrawIcon(hdc, 0, 0, hIcon); DrawIcon(hdc, 0, 0, hIcon);
...@@ -59,30 +64,47 @@ HGLOBAL WINAPI OleMetafilePictFromIconAndLabel(HICON hIcon, LPOLESTR lpszLabel, ...@@ -59,30 +64,47 @@ HGLOBAL WINAPI OleMetafilePictFromIconAndLabel(HICON hIcon, LPOLESTR lpszLabel,
if(lpszLabel) if(lpszLabel)
TextOutW(hdc, 0, dy, lpszLabel, lstrlenW(lpszLabel)); TextOutW(hdc, 0, dy, lpszLabel, lstrlenW(lpszLabel));
hmf = CloseMetaFile(hdc); if (lpszSourceFile)
if( !hmf ) {
return 0; char szIconIndex[10];
int path_length = WideCharToMultiByte(CP_ACP,0,lpszSourceFile,-1,NULL,0,NULL,NULL);
if (path_length > 1)
{
char * szPath = CoTaskMemAlloc(path_length * sizeof(CHAR));
if (szPath)
{
WideCharToMultiByte(CP_ACP,0,lpszSourceFile,-1,szPath,path_length,NULL,NULL);
ExtEscape(hdc, MFCOMMENT, path_length, szPath, 0, NULL);
CoTaskMemFree(szPath);
}
}
snprintf(szIconIndex, 10, "%u", iIconIndex);
ExtEscape(hdc, MFCOMMENT, strlen(szIconIndex)+1, szIconIndex, 0, NULL);
}
mfsize = GetMetaFileBitsEx( hmf, 0, NULL); mfp.mm = MM_ISOTROPIC;
if( !mfsize ) mfp.xExt = mfp.yExt = 0; /* FIXME ? */
goto end; mfp.hMF = CloseMetaFile(hdc);
if( !mfp.hMF )
return NULL;
hmem = GlobalAlloc( GMEM_MOVEABLE, mfsize ); hmem = GlobalAlloc( GMEM_MOVEABLE, sizeof(mfp) );
if( !hmem ) if( !hmem )
goto end; {
DeleteMetaFile(mfp.hMF);
return NULL;
}
mfdata = GlobalLock( hmem ); mfdata = GlobalLock( hmem );
if( !mfdata ) if( !mfdata )
{ {
GlobalFree( hmem ); GlobalFree( hmem );
hmem = 0; DeleteMetaFile(mfp.hMF);
goto end; return NULL;
} }
GetMetaFileBitsEx( hmf, mfsize, mfdata ); memcpy(mfdata,&mfp,sizeof(mfp));
GlobalUnlock( hmem ); GlobalUnlock( hmem );
end:
DeleteMetaFile(hmf);
TRACE("returning %p\n",hmem); TRACE("returning %p\n",hmem);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment