/******************************************************************************
* These are static/global variables and internal data structures that the
- * OLE module uses to maintain it's state.
+ * OLE module uses to maintain its state.
*/
typedef struct tagTrackerWindowInfo
{
BOOL escPressed;
HWND curTargetHWND; /* window the mouse is hovering over */
- HWND curDragTargetHWND; /* might be a ancestor of curTargetHWND */
+ HWND curDragTargetHWND; /* might be an ancestor of curTargetHWND */
IDropTarget* curDragTarget;
POINTL curMousePos; /* current position of the mouse in screen coordinates */
DWORD dwKeyState; /* current state of the shift and ctrl keys and the mouse buttons */
*/
static void OLEDD_Initialize(void);
static LRESULT WINAPI OLEDD_DragTrackerWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
-static void OLEDD_TrackMouseMove(TrackerWindowInfo* trackerInfo);
static void OLEDD_TrackStateChange(TrackerWindowInfo* trackerInfo);
static DWORD OLEDD_GetButtonState(void);
*pdwStatus = 0;
+ if (actctx_get_miscstatus(clsid, dwAspect, pdwStatus)) return S_OK;
+
/*
* Open the class id Key
*/
if (SUCCEEDED(hres) && pClientSite)
/*
- * Inform the new object of it's client site.
+ * Inform the new object of its client site.
*/
hres = IOleObject_SetClientSite(pOleObject, pClientSite);
}
case WM_TIMER:
case WM_MOUSEMOVE:
- {
- OLEDD_TrackMouseMove((TrackerWindowInfo*)GetWindowLongPtrA(hwnd, 0));
- break;
- }
case WM_LBUTTONUP:
case WM_MBUTTONUP:
case WM_RBUTTONUP:
}
/***
- * OLEDD_TrackMouseMove()
+ * OLEDD_TrackStateChange()
*
* This method is invoked while a drag and drop operation is in effect.
- * it will generate the appropriate callbacks in the drop source
- * and drop target. It will also provide the expected feedback to
- * the user.
*
* params:
* trackerInfo - Pointer to the structure identifying the
* drag & drop operation that is currently
* active.
*/
-static void OLEDD_TrackMouseMove(TrackerWindowInfo* trackerInfo)
+static void OLEDD_TrackStateChange(TrackerWindowInfo* trackerInfo)
{
HWND hwndNewTarget = 0;
HRESULT hr = S_OK;
pt.y = trackerInfo->curMousePos.y;
hwndNewTarget = WindowFromPoint(pt);
+ trackerInfo->returnValue = IDropSource_QueryContinueDrag(trackerInfo->dropSource,
+ trackerInfo->escPressed,
+ trackerInfo->dwKeyState);
+
/*
* Every time, we re-initialize the effects passed to the
* IDropTarget to the effects allowed by the source.
IDropTarget_DragOver(trackerInfo->curDragTarget,
trackerInfo->dwKeyState,
trackerInfo->curMousePos,
- trackerInfo->pdwEffect);
+ trackerInfo->pdwEffect);
+ *trackerInfo->pdwEffect &= trackerInfo->dwOKEffect;
}
else
{
trackerInfo->dwKeyState,
trackerInfo->curMousePos,
trackerInfo->pdwEffect);
+ *trackerInfo->pdwEffect &= trackerInfo->dwOKEffect;
/* failed DragEnter() means invalid target */
if (hr != S_OK)
SetCursor(hCur);
}
-}
-
-/***
- * OLEDD_TrackStateChange()
- *
- * This method is invoked while a drag and drop operation is in effect.
- * It is used to notify the drop target/drop source callbacks when
- * the state of the keyboard or mouse button change.
- *
- * params:
- * trackerInfo - Pointer to the structure identifying the
- * drag & drop operation that is currently
- * active.
- */
-static void OLEDD_TrackStateChange(TrackerWindowInfo* trackerInfo)
-{
- /*
- * Ask the drop source what to do with the operation.
- */
- trackerInfo->returnValue = IDropSource_QueryContinueDrag(
- trackerInfo->dropSource,
- trackerInfo->escPressed,
- trackerInfo->dwKeyState);
/*
* All the return valued will stop the operation except the S_OK
*/
case DRAGDROP_S_DROP:
if (*trackerInfo->pdwEffect != DROPEFFECT_NONE)
- IDropTarget_Drop(trackerInfo->curDragTarget,
- trackerInfo->dataObject,
- trackerInfo->dwKeyState,
- trackerInfo->curMousePos,
- trackerInfo->pdwEffect);
+ trackerInfo->returnValue = IDropTarget_Drop(trackerInfo->curDragTarget,
+ trackerInfo->dataObject,
+ trackerInfo->dwKeyState,
+ trackerInfo->curMousePos,
+ trackerInfo->pdwEffect);
else
IDropTarget_DragLeave(trackerInfo->curDragTarget);
break;
/*
* If the source told us that we should cancel, fool the drop
- * target by telling it that the mouse left it's window.
+ * target by telling it that the mouse left its window.
* Also set the drop effect to "NONE" in case the application
* ignores the result of DoDragDrop.
*/
*/
HRESULT WINAPI OleDoAutoConvert(LPSTORAGE pStg, LPCLSID pClsidNew)
{
- FIXME("(%p,%p) : stub\n",pStg,pClsidNew);
- return E_NOTIMPL;
+ WCHAR *user_type_old, *user_type_new;
+ CLIPFORMAT cf;
+ STATSTG stat;
+ CLSID clsid;
+ HRESULT hr;
+
+ TRACE("(%p, %p)\n", pStg, pClsidNew);
+
+ *pClsidNew = CLSID_NULL;
+ if(!pStg)
+ return E_INVALIDARG;
+ hr = IStorage_Stat(pStg, &stat, STATFLAG_NONAME);
+ if(FAILED(hr))
+ return hr;
+
+ *pClsidNew = stat.clsid;
+ hr = OleGetAutoConvert(&stat.clsid, &clsid);
+ if(FAILED(hr))
+ return hr;
+
+ hr = IStorage_SetClass(pStg, &clsid);
+ if(FAILED(hr))
+ return hr;
+
+ hr = ReadFmtUserTypeStg(pStg, &cf, &user_type_old);
+ if(FAILED(hr)) {
+ cf = 0;
+ user_type_new = NULL;
+ }
+
+ hr = OleRegGetUserType(&clsid, USERCLASSTYPE_FULL, &user_type_new);
+ if(FAILED(hr))
+ user_type_new = NULL;
+
+ hr = WriteFmtUserTypeStg(pStg, cf, user_type_new);
+ CoTaskMemFree(user_type_new);
+ if(FAILED(hr))
+ {
+ CoTaskMemFree(user_type_old);
+ IStorage_SetClass(pStg, &stat.clsid);
+ return hr;
+ }
+
+ hr = SetConvertStg(pStg, TRUE);
+ if(FAILED(hr))
+ {
+ WriteFmtUserTypeStg(pStg, cf, user_type_old);
+ IStorage_SetClass(pStg, &stat.clsid);
+ }
+ else
+ *pClsidNew = clsid;
+ CoTaskMemFree(user_type_old);
+ return hr;
}
/******************************************************************************
case VT_UI2:
case VT_UI4:
case VT_UI8:
+ case VT_INT:
+ case VT_UINT:
case VT_LPSTR:
case VT_LPWSTR:
case VT_FILETIME:
hr = PROPVARIANT_ValidateType(pvar->vt);
if (FAILED(hr))
+ {
+ memset(pvar, 0, sizeof(*pvar));
return hr;
+ }
switch(pvar->vt)
{
case VT_UI2:
case VT_UI4:
case VT_UI8:
+ case VT_INT:
+ case VT_UINT:
case VT_FILETIME:
break;
case VT_STREAM:
}
}
else
+ {
WARN("Invalid/unsupported type %d\n", pvar->vt);
+ hr = STG_E_INVALIDPARAMETER;
+ }
}
- ZeroMemory(pvar, sizeof(*pvar));
-
- return S_OK;
+ memset(pvar, 0, sizeof(*pvar));
+ return hr;
}
/***********************************************************************
case VT_ERROR:
case VT_I8:
case VT_UI8:
+ case VT_INT:
+ case VT_UINT:
case VT_R8:
case VT_CY:
case VT_DATE:
case VT_STREAMED_OBJECT:
case VT_STORAGE:
case VT_STORED_OBJECT:
- IUnknown_AddRef((LPUNKNOWN)pvarDest->u.pStream);
+ if (pvarDest->u.pStream)
+ IStream_AddRef(pvarDest->u.pStream);
break;
case VT_CLSID:
pvarDest->u.puuid = CoTaskMemAlloc(sizeof(CLSID));
*pvarDest->u.puuid = *pvarSrc->u.puuid;
break;
case VT_LPSTR:
- len = strlen(pvarSrc->u.pszVal);
- pvarDest->u.pszVal = CoTaskMemAlloc((len+1)*sizeof(CHAR));
- CopyMemory(pvarDest->u.pszVal, pvarSrc->u.pszVal, (len+1)*sizeof(CHAR));
+ if (pvarSrc->u.pszVal)
+ {
+ len = strlen(pvarSrc->u.pszVal);
+ pvarDest->u.pszVal = CoTaskMemAlloc((len+1)*sizeof(CHAR));
+ CopyMemory(pvarDest->u.pszVal, pvarSrc->u.pszVal, (len+1)*sizeof(CHAR));
+ }
break;
case VT_LPWSTR:
- len = lstrlenW(pvarSrc->u.pwszVal);
- pvarDest->u.pwszVal = CoTaskMemAlloc((len+1)*sizeof(WCHAR));
- CopyMemory(pvarDest->u.pwszVal, pvarSrc->u.pwszVal, (len+1)*sizeof(WCHAR));
+ if (pvarSrc->u.pwszVal)
+ {
+ len = lstrlenW(pvarSrc->u.pwszVal);
+ pvarDest->u.pwszVal = CoTaskMemAlloc((len+1)*sizeof(WCHAR));
+ CopyMemory(pvarDest->u.pwszVal, pvarSrc->u.pwszVal, (len+1)*sizeof(WCHAR));
+ }
break;
case VT_BLOB:
case VT_BLOB_OBJECT:
return E_INVALIDARG;
}
len = pvarSrc->u.capropvar.cElems;
- pvarDest->u.capropvar.pElems = CoTaskMemAlloc(len * elemSize);
+ pvarDest->u.capropvar.pElems = len ? CoTaskMemAlloc(len * elemSize) : NULL;
if (pvarSrc->vt == (VT_VECTOR | VT_VARIANT))
{
for (i = 0; i < len; i++)