📄 ole2.c
字号:
TrackerWindowInfo trackerInfo;
HWND hwndTrackWindow;
MSG msg;
TRACE("(DataObject %p, DropSource %p)\n", pDataObject, pDropSource);
/*
* Setup the drag n drop tracking window.
*/
if (!IsValidInterface((LPUNKNOWN)pDropSource))
return E_INVALIDARG;
trackerInfo.dataObject = pDataObject;
trackerInfo.dropSource = pDropSource;
trackerInfo.dwOKEffect = dwOKEffect;
trackerInfo.pdwEffect = pdwEffect;
trackerInfo.trackingDone = FALSE;
trackerInfo.escPressed = FALSE;
trackerInfo.curDragTargetHWND = 0;
trackerInfo.curTargetHWND = 0;
trackerInfo.curDragTarget = 0;
hwndTrackWindow = CreateWindowA(OLEDD_DRAGTRACKERCLASS,
"TrackerWindow",
WS_POPUP,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
0,
0,
0,
(LPVOID)&trackerInfo);
if (hwndTrackWindow!=0)
{
/*
* Capture the mouse input
*/
SetCapture(hwndTrackWindow);
msg.message = 0;
/*
* Pump messages. All mouse input should go the the capture window.
*/
while (!trackerInfo.trackingDone && GetMessageA(&msg, 0, 0, 0) )
{
trackerInfo.curMousePos.x = msg.pt.x;
trackerInfo.curMousePos.y = msg.pt.y;
trackerInfo.dwKeyState = OLEDD_GetButtonState();
if ( (msg.message >= WM_KEYFIRST) &&
(msg.message <= WM_KEYLAST) )
{
/*
* When keyboard messages are sent to windows on this thread, we
* want to ignore notify the drop source that the state changed.
* in the case of the Escape key, we also notify the drop source
* we give it a special meaning.
*/
if ( (msg.message==WM_KEYDOWN) &&
(msg.wParam==VK_ESCAPE) )
{
trackerInfo.escPressed = TRUE;
}
/*
* Notify the drop source.
*/
OLEDD_TrackStateChange(&trackerInfo);
}
else
{
/*
* Dispatch the messages only when it's not a keyboard message.
*/
DispatchMessageA(&msg);
}
}
/* re-post the quit message to outer message loop */
if (msg.message == WM_QUIT)
PostQuitMessage(msg.wParam);
/*
* Destroy the temporary window.
*/
DestroyWindow(hwndTrackWindow);
return trackerInfo.returnValue;
}
return E_FAIL;
}
/***********************************************************************
* OleQueryLinkFromData [OLE32.@]
*/
HRESULT WINAPI OleQueryLinkFromData(
IDataObject* pSrcDataObject)
{
FIXME("(%p),stub!\n", pSrcDataObject);
return S_OK;
}
/***********************************************************************
* OleRegGetMiscStatus [OLE32.@]
*/
HRESULT WINAPI OleRegGetMiscStatus(
REFCLSID clsid,
DWORD dwAspect,
DWORD* pdwStatus)
{
char keyName[60];
HKEY clsidKey;
HKEY miscStatusKey;
HKEY aspectKey;
LONG result;
/*
* Initialize the out parameter.
*/
*pdwStatus = 0;
/*
* Build the key name we're looking for
*/
sprintf( keyName, "CLSID\\{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\",
clsid->Data1, clsid->Data2, clsid->Data3,
clsid->Data4[0], clsid->Data4[1], clsid->Data4[2], clsid->Data4[3],
clsid->Data4[4], clsid->Data4[5], clsid->Data4[6], clsid->Data4[7] );
TRACE("(%s, %d, %p)\n", keyName, dwAspect, pdwStatus);
/*
* Open the class id Key
*/
result = RegOpenKeyA(HKEY_CLASSES_ROOT,
keyName,
&clsidKey);
if (result != ERROR_SUCCESS)
return REGDB_E_CLASSNOTREG;
/*
* Get the MiscStatus
*/
result = RegOpenKeyA(clsidKey,
"MiscStatus",
&miscStatusKey);
if (result != ERROR_SUCCESS)
{
RegCloseKey(clsidKey);
return REGDB_E_READREGDB;
}
/*
* Read the default value
*/
OLEUTL_ReadRegistryDWORDValue(miscStatusKey, pdwStatus);
/*
* Open the key specific to the requested aspect.
*/
sprintf(keyName, "%d", dwAspect);
result = RegOpenKeyA(miscStatusKey,
keyName,
&aspectKey);
if (result == ERROR_SUCCESS)
{
OLEUTL_ReadRegistryDWORDValue(aspectKey, pdwStatus);
RegCloseKey(aspectKey);
}
/*
* Cleanup
*/
RegCloseKey(miscStatusKey);
RegCloseKey(clsidKey);
return S_OK;
}
static HRESULT EnumOLEVERB_Construct(HKEY hkeyVerb, ULONG index, IEnumOLEVERB **ppenum);
typedef struct
{
const IEnumOLEVERBVtbl *lpvtbl;
LONG ref;
HKEY hkeyVerb;
ULONG index;
} EnumOLEVERB;
static HRESULT WINAPI EnumOLEVERB_QueryInterface(
IEnumOLEVERB *iface, REFIID riid, void **ppv)
{
TRACE("(%s, %p)\n", debugstr_guid(riid), ppv);
if (IsEqualIID(riid, &IID_IUnknown) ||
IsEqualIID(riid, &IID_IEnumOLEVERB))
{
IUnknown_AddRef(iface);
*ppv = iface;
return S_OK;
}
return E_NOINTERFACE;
}
static ULONG WINAPI EnumOLEVERB_AddRef(
IEnumOLEVERB *iface)
{
EnumOLEVERB *This = (EnumOLEVERB *)iface;
TRACE("()\n");
return InterlockedIncrement(&This->ref);
}
static ULONG WINAPI EnumOLEVERB_Release(
IEnumOLEVERB *iface)
{
EnumOLEVERB *This = (EnumOLEVERB *)iface;
LONG refs = InterlockedDecrement(&This->ref);
TRACE("()\n");
if (!refs)
{
RegCloseKey(This->hkeyVerb);
HeapFree(GetProcessHeap(), 0, This);
}
return refs;
}
static HRESULT WINAPI EnumOLEVERB_Next(
IEnumOLEVERB *iface, ULONG celt, LPOLEVERB rgelt,
ULONG *pceltFetched)
{
EnumOLEVERB *This = (EnumOLEVERB *)iface;
HRESULT hr = S_OK;
TRACE("(%d, %p, %p)\n", celt, rgelt, pceltFetched);
if (pceltFetched)
*pceltFetched = 0;
for (; celt; celt--, rgelt++)
{
WCHAR wszSubKey[20];
LONG cbData;
LPWSTR pwszOLEVERB;
LPWSTR pwszMenuFlags;
LPWSTR pwszAttribs;
LONG res = RegEnumKeyW(This->hkeyVerb, This->index, wszSubKey, sizeof(wszSubKey)/sizeof(wszSubKey[0]));
if (res == ERROR_NO_MORE_ITEMS)
{
hr = S_FALSE;
break;
}
else if (res != ERROR_SUCCESS)
{
ERR("RegEnumKeyW failed with error %d\n", res);
hr = REGDB_E_READREGDB;
break;
}
res = RegQueryValueW(This->hkeyVerb, wszSubKey, NULL, &cbData);
if (res != ERROR_SUCCESS)
{
ERR("RegQueryValueW failed with error %d\n", res);
hr = REGDB_E_READREGDB;
break;
}
pwszOLEVERB = CoTaskMemAlloc(cbData);
if (!pwszOLEVERB)
{
hr = E_OUTOFMEMORY;
break;
}
res = RegQueryValueW(This->hkeyVerb, wszSubKey, pwszOLEVERB, &cbData);
if (res != ERROR_SUCCESS)
{
ERR("RegQueryValueW failed with error %d\n", res);
hr = REGDB_E_READREGDB;
CoTaskMemFree(pwszOLEVERB);
break;
}
TRACE("verb string: %s\n", debugstr_w(pwszOLEVERB));
pwszMenuFlags = strchrW(pwszOLEVERB, ',');
if (!pwszMenuFlags)
{
hr = OLEOBJ_E_INVALIDVERB;
CoTaskMemFree(pwszOLEVERB);
break;
}
/* nul terminate the name string and advance to first character */
*pwszMenuFlags = '\0';
pwszMenuFlags++;
pwszAttribs = strchrW(pwszMenuFlags, ',');
if (!pwszAttribs)
{
hr = OLEOBJ_E_INVALIDVERB;
CoTaskMemFree(pwszOLEVERB);
break;
}
/* nul terminate the menu string and advance to first character */
*pwszAttribs = '\0';
pwszAttribs++;
/* fill out structure for this verb */
rgelt->lVerb = atolW(wszSubKey);
rgelt->lpszVerbName = pwszOLEVERB; /* user should free */
rgelt->fuFlags = atolW(pwszMenuFlags);
rgelt->grfAttribs = atolW(pwszAttribs);
if (pceltFetched)
(*pceltFetched)++;
This->index++;
}
return hr;
}
static HRESULT WINAPI EnumOLEVERB_Skip(
IEnumOLEVERB *iface, ULONG celt)
{
EnumOLEVERB *This = (EnumOLEVERB *)iface;
TRACE("(%d)\n", celt);
This->index += celt;
return S_OK;
}
static HRESULT WINAPI EnumOLEVERB_Reset(
IEnumOLEVERB *iface)
{
EnumOLEVERB *This = (EnumOLEVERB *)iface;
TRACE("()\n");
This->index = 0;
return S_OK;
}
static HRESULT WINAPI EnumOLEVERB_Clone(
IEnumOLEVERB *iface,
IEnumOLEVERB **ppenum)
{
EnumOLEVERB *This = (EnumOLEVERB *)iface;
HKEY hkeyVerb;
TRACE("(%p)\n", ppenum);
if (!DuplicateHandle(GetCurrentProcess(), This->hkeyVerb, GetCurrentProcess(), (HANDLE *)&hkeyVerb, 0, FALSE, DUPLICATE_SAME_ACCESS))
return HRESULT_FROM_WIN32(GetLastError());
return EnumOLEVERB_Construct(hkeyVerb, This->index, ppenum);
}
static const IEnumOLEVERBVtbl EnumOLEVERB_VTable =
{
EnumOLEVERB_QueryInterface,
EnumOLEVERB_AddRef,
EnumOLEVERB_Release,
EnumOLEVERB_Next,
EnumOLEVERB_Skip,
EnumOLEVERB_Reset,
EnumOLEVERB_Clone
};
static HRESULT EnumOLEVERB_Construct(HKEY hkeyVerb, ULONG index, IEnumOLEVERB **ppenum)
{
EnumOLEVERB *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
if (!This)
{
RegCloseKey(hkeyVerb);
return E_OUTOFMEMORY;
}
This->lpvtbl = &EnumOLEVERB_VTable;
This->ref = 1;
This->index = index;
This->hkeyVerb = hkeyVerb;
*ppenum = (IEnumOLEVERB *)&This->lpvtbl;
return S_OK;
}
/***********************************************************************
* OleRegEnumVerbs [OLE32.@]
*
* Enumerates verbs associated with a class stored in the registry.
*
* PARAMS
* clsid [I] Class ID to enumerate the verbs for.
* ppenum [O] Enumerator.
*
* RETURNS
* S_OK: Success.
* REGDB_E_CLASSNOTREG: The specified class does not have a key in the registry.
* REGDB_E_READREGDB: The class key could not be opened for some other reason.
* OLE_E_REGDB_KEY: The Verb subkey for the class is not present.
* OLEOBJ_E_NOVERBS: The Verb subkey for the class is empty.
*/
HRESULT WINAPI OleRegEnumVerbs (REFCLSID clsid, LPENUMOLEVERB* ppenum)
{
LONG res;
HKEY hkeyVerb;
DWORD dwSubKeys;
static const WCHAR wszVerb[] = {'V','e','r','b',0};
TRACE("(%s, %p)\n", debugstr_guid(clsid), ppenum);
res = COM_OpenKeyForCLSID(clsid, wszVerb, KEY_READ, &hkeyVerb);
if (FAILED(res))
{
if (res == REGDB_E_CLASSNOTREG)
ERR("CLSID %s not registered\n", debugstr_guid(clsid));
else if (res == REGDB_E_KEYMISSING)
ERR("no Verbs key for class %s\n", debugstr_guid(clsid));
else
ERR("failed to open Verbs key for CLSID %s with error %d\n",
debugstr_guid(clsid), res);
return res;
}
res = RegQueryInfoKeyW(hkeyVerb, NULL, NULL, NULL, &dwSubKeys, NULL,
NULL, NULL, NULL, NULL, NULL, NULL);
if (res != ERROR_SUCCESS)
{
ERR("failed to get subkey count with error %d\n", GetLastError());
return REGDB_E_READREGDB;
}
if (!dwSubKeys)
{
WARN("class %s has no verbs\n", debugstr_guid(clsid));
RegCloseKey(hkeyVerb);
return OLEOBJ_E_NOVERBS;
}
return EnumOLEVERB_Construct(hkeyVerb, 0, ppenum);
}
/******************************************************************************
* OleSetContainedObject [OLE32.@]
*/
HRESULT WINAPI OleSetContainedObject(
LPUNKNOWN pUnknown,
BOOL fContained)
{
IRunnableObject* runnable = NULL;
HRESULT hres;
TRACE("(%p,%x)\n", pUnknown, fContained);
hres = IUnknown_QueryInterface(pUnknown,
&IID_IRunnableObject,
(void**)&runnable);
if (SUCCEEDED(hres))
{
hres = IRunnableObject_SetContainedObject(runnable, fContained);
IRunnableObject_Release(runnable);
return hres;
}
return S_OK;
}
/******************************************************************************
* OleRun [OLE32.@]
*
* Set the OLE object to the running state.
*
* PARAMS
* pUnknown [I] OLE object to run.
*
* RETURNS
* Success: S_OK.
* Failure: Any HRESULT code.
*/
HRESULT WINAPI OleRun(LPUNKNOWN pUnknown)
{
IRunnableObject *runable;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -