📄 ole2.c
字号:
/***
* OLEDD_FindDropTarget()
*
* Finds information about the drop target.
*/
static DropTargetNode* OLEDD_FindDropTarget(HWND hwndOfTarget)
{
DropTargetNode* curNode;
/*
* Iterate the list to find the HWND value.
*/
LIST_FOR_EACH_ENTRY(curNode, &targetListHead, DropTargetNode, entry)
if (hwndOfTarget==curNode->hwndTarget)
return curNode;
/*
* If we get here, the item is not in the list
*/
return NULL;
}
/***
* OLEDD_DragTrackerWindowProc()
*
* This method is the WindowProcedure of the drag n drop tracking
* window. During a drag n Drop operation, an invisible window is created
* to receive the user input and act upon it. This procedure is in charge
* of this behavior.
*/
#define DRAG_TIMER_ID 1
static LRESULT WINAPI OLEDD_DragTrackerWindowProc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
switch (uMsg)
{
case WM_CREATE:
{
LPCREATESTRUCTA createStruct = (LPCREATESTRUCTA)lParam;
SetWindowLongA(hwnd, 0, (LONG)createStruct->lpCreateParams);
SetTimer(hwnd, DRAG_TIMER_ID, 50, NULL);
break;
}
case WM_TIMER:
case WM_MOUSEMOVE:
{
OLEDD_TrackMouseMove((TrackerWindowInfo*)GetWindowLongA(hwnd, 0));
break;
}
case WM_LBUTTONUP:
case WM_MBUTTONUP:
case WM_RBUTTONUP:
case WM_LBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_RBUTTONDOWN:
{
OLEDD_TrackStateChange((TrackerWindowInfo*)GetWindowLongA(hwnd, 0));
break;
}
case WM_DESTROY:
{
KillTimer(hwnd, DRAG_TIMER_ID);
break;
}
}
/*
* This is a window proc after all. Let's call the default.
*/
return DefWindowProcA (hwnd, uMsg, wParam, lParam);
}
/***
* OLEDD_TrackMouseMove()
*
* 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)
{
HWND hwndNewTarget = 0;
HRESULT hr = S_OK;
POINT pt;
/*
* Get the handle of the window under the mouse
*/
pt.x = trackerInfo->curMousePos.x;
pt.y = trackerInfo->curMousePos.y;
hwndNewTarget = WindowFromPoint(pt);
/*
* Every time, we re-initialize the effects passed to the
* IDropTarget to the effects allowed by the source.
*/
*trackerInfo->pdwEffect = trackerInfo->dwOKEffect;
/*
* If we are hovering over the same target as before, send the
* DragOver notification
*/
if ( (trackerInfo->curDragTarget != 0) &&
(trackerInfo->curTargetHWND == hwndNewTarget) )
{
IDropTarget_DragOver(trackerInfo->curDragTarget,
trackerInfo->dwKeyState,
trackerInfo->curMousePos,
trackerInfo->pdwEffect);
}
else
{
DropTargetNode* newDropTargetNode = 0;
/*
* If we changed window, we have to notify our old target and check for
* the new one.
*/
if (trackerInfo->curDragTarget!=0)
{
IDropTarget_DragLeave(trackerInfo->curDragTarget);
}
/*
* Make sure we're hovering over a window.
*/
if (hwndNewTarget!=0)
{
/*
* Find-out if there is a drag target under the mouse
*/
HWND nexttar = hwndNewTarget;
trackerInfo->curTargetHWND = hwndNewTarget;
do {
newDropTargetNode = OLEDD_FindDropTarget(nexttar);
} while (!newDropTargetNode && (nexttar = GetParent(nexttar)) != 0);
if(nexttar) hwndNewTarget = nexttar;
trackerInfo->curDragTargetHWND = hwndNewTarget;
trackerInfo->curDragTarget = newDropTargetNode ? newDropTargetNode->dropTarget : 0;
/*
* If there is, notify it that we just dragged-in
*/
if (trackerInfo->curDragTarget!=0)
{
IDropTarget_DragEnter(trackerInfo->curDragTarget,
trackerInfo->dataObject,
trackerInfo->dwKeyState,
trackerInfo->curMousePos,
trackerInfo->pdwEffect);
}
}
else
{
/*
* The mouse is not over a window so we don't track anything.
*/
trackerInfo->curDragTargetHWND = 0;
trackerInfo->curTargetHWND = 0;
trackerInfo->curDragTarget = 0;
}
}
/*
* Now that we have done that, we have to tell the source to give
* us feedback on the work being done by the target. If we don't
* have a target, simulate no effect.
*/
if (trackerInfo->curDragTarget==0)
{
*trackerInfo->pdwEffect = DROPEFFECT_NONE;
}
hr = IDropSource_GiveFeedback(trackerInfo->dropSource,
*trackerInfo->pdwEffect);
/*
* When we ask for feedback from the drop source, sometimes it will
* do all the necessary work and sometimes it will not handle it
* when that's the case, we must display the standard drag and drop
* cursors.
*/
if (hr==DRAGDROP_S_USEDEFAULTCURSORS)
{
if (*trackerInfo->pdwEffect & DROPEFFECT_MOVE)
{
SetCursor(LoadCursorA(OLE32_hInstance, MAKEINTRESOURCEA(1)));
}
else if (*trackerInfo->pdwEffect & DROPEFFECT_COPY)
{
SetCursor(LoadCursorA(OLE32_hInstance, MAKEINTRESOURCEA(2)));
}
else if (*trackerInfo->pdwEffect & DROPEFFECT_LINK)
{
SetCursor(LoadCursorA(OLE32_hInstance, MAKEINTRESOURCEA(3)));
}
else
{
SetCursor(LoadCursorA(OLE32_hInstance, MAKEINTRESOURCEA(0)));
}
}
}
/***
* 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
* return value.
*/
if (trackerInfo->returnValue!=S_OK)
{
/*
* Make sure the message loop in DoDragDrop stops
*/
trackerInfo->trackingDone = TRUE;
/*
* Release the mouse in case the drop target decides to show a popup
* or a menu or something.
*/
ReleaseCapture();
/*
* If we end-up over a target, drop the object in the target or
* inform the target that the operation was cancelled.
*/
if (trackerInfo->curDragTarget!=0)
{
switch (trackerInfo->returnValue)
{
/*
* If the source wants us to complete the operation, we tell
* the drop target that we just dropped the object in it.
*/
case DRAGDROP_S_DROP:
{
IDropTarget_Drop(trackerInfo->curDragTarget,
trackerInfo->dataObject,
trackerInfo->dwKeyState,
trackerInfo->curMousePos,
trackerInfo->pdwEffect);
break;
}
/*
* If the source told us that we should cancel, fool the drop
* target by telling it that the mouse left it's window.
* Also set the drop effect to "NONE" in case the application
* ignores the result of DoDragDrop.
*/
case DRAGDROP_S_CANCEL:
IDropTarget_DragLeave(trackerInfo->curDragTarget);
*trackerInfo->pdwEffect = DROPEFFECT_NONE;
break;
}
}
}
}
/***
* OLEDD_GetButtonState()
*
* This method will use the current state of the keyboard to build
* a button state mask equivalent to the one passed in the
* WM_MOUSEMOVE wParam.
*/
static DWORD OLEDD_GetButtonState(void)
{
BYTE keyboardState[256];
DWORD keyMask = 0;
GetKeyboardState(keyboardState);
if ( (keyboardState[VK_SHIFT] & 0x80) !=0)
keyMask |= MK_SHIFT;
if ( (keyboardState[VK_CONTROL] & 0x80) !=0)
keyMask |= MK_CONTROL;
if ( (keyboardState[VK_LBUTTON] & 0x80) !=0)
keyMask |= MK_LBUTTON;
if ( (keyboardState[VK_RBUTTON] & 0x80) !=0)
keyMask |= MK_RBUTTON;
if ( (keyboardState[VK_MBUTTON] & 0x80) !=0)
keyMask |= MK_MBUTTON;
return keyMask;
}
/***
* OLEDD_GetButtonState()
*
* This method will read the default value of the registry key in
* parameter and extract a DWORD value from it. The registry key value
* can be in a string key or a DWORD key.
*
* params:
* regKey - Key to read the default value from
* pdwValue - Pointer to the location where the DWORD
* value is returned. This value is not modified
* if the value is not found.
*/
static void OLEUTL_ReadRegistryDWORDValue(
HKEY regKey,
DWORD* pdwValue)
{
char buffer[20];
DWORD dwKeyType;
DWORD cbData = 20;
LONG lres;
lres = RegQueryValueExA(regKey,
"",
NULL,
&dwKeyType,
(LPBYTE)buffer,
&cbData);
if (lres==ERROR_SUCCESS)
{
switch (dwKeyType)
{
case REG_DWORD:
*pdwValue = *(DWORD*)buffer;
break;
case REG_EXPAND_SZ:
case REG_MULTI_SZ:
case REG_SZ:
*pdwValue = (DWORD)strtoul(buffer, NULL, 10);
break;
}
}
}
/******************************************************************************
* OleDraw (OLE32.@)
*
* The operation of this function is documented literally in the WinAPI
* documentation to involve a QueryInterface for the IViewObject interface,
* followed by a call to IViewObject::Draw.
*/
HRESULT WINAPI OleDraw(
IUnknown *pUnk,
DWORD dwAspect,
HDC hdcDraw,
LPCRECT lprcBounds)
{
HRESULT hres;
IViewObject *viewobject;
hres = IUnknown_QueryInterface(pUnk,
&IID_IViewObject,
(void**)&viewobject);
if (SUCCEEDED(hres))
{
RECTL rectl;
rectl.left = lprcBounds->left;
rectl.right = lprcBounds->right;
rectl.top = lprcBounds->top;
rectl.bottom = lprcBounds->bottom;
hres = IViewObject_Draw(viewobject, dwAspect, -1, 0, 0, 0, hdcDraw, &rectl, 0, 0, 0);
IViewObject_Release(viewobject);
return hres;
}
else
{
return DV_E_NOIVIEWOBJECT;
}
}
/***********************************************************************
* 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;
IUnknown * pUnk = NULL;
IOleObject *pOleObject = NULL;
TRACE("(%s, %s, %d, %p, %p, %p, %p)\n", debugstr_guid(rclsid),
debugstr_guid(riid), renderopt, pFormatEtc, pClientSite, pStg, ppvObj);
hres = CoCreateInstance(rclsid, 0, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, riid, (LPVOID*)&pUnk);
if (SUCCEEDED(hres))
hres = IStorage_SetClass(pStg, rclsid);
if (pClientSite && SUCCEEDED(hres))
{
hres = IUnknown_QueryInterface(pUnk, &IID_IOleObject, (LPVOID*)&pOleObject);
if (SUCCEEDED(hres))
{
DWORD dwStatus;
hres = IOleObject_GetMiscStatus(pOleObject, DVASPECT_CONTENT, &dwStatus);
}
}
if (SUCCEEDED(hres))
{
IPersistStorage * pPS;
if (SUCCEEDED((hres = IUnknown_QueryInterface(pUnk, &IID_IPersistStorage, (LPVOID*)&pPS))))
{
TRACE("trying to set stg %p\n", pStg);
hres = IPersistStorage_InitNew(pPS, pStg);
TRACE("-- result 0x%08x\n", hres);
IPersistStorage_Release(pPS);
}
}
if (pClientSite && SUCCEEDED(hres))
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -