📄 ole2.c
字号:
hOleMenu = (HOLEMENU)GetPropA( pMsg->hwnd, "PROP_OLEMenuDescriptor" );
if ( !hOleMenu )
goto NEXTHOOK;
/* Process menu messages */
switch( pMsg->message )
{
case WM_COMMAND:
{
wCode = HIWORD(pMsg->wParam); /* Get notification code */
if ( wCode )
goto NEXTHOOK; /* Not a menu message */
break;
}
default:
goto NEXTHOOK;
}
/* Get the menu descriptor */
pOleMenuDescriptor = (OleMenuDescriptor *) GlobalLock( hOleMenu );
if ( !pOleMenuDescriptor ) /* Bad descriptor! */
goto NEXTHOOK;
/* If the message was for the server dispatch it accordingly */
if ( pOleMenuDescriptor->bIsServerItem )
{
/* Change the hWnd in the message to the active objects hWnd.
* The message loop which reads this message will automatically
* dispatch it to the embedded objects window. */
pMsg->hwnd = pOleMenuDescriptor->hwndActiveObject;
}
NEXTHOOK:
if ( pOleMenuDescriptor )
GlobalUnlock( hOleMenu );
/* Lookup the hook item for the current thread */
if ( !( pHookItem = OLEMenu_IsHookInstalled( GetCurrentThreadId() ) ) )
{
/* This should never fail!! */
WARN("could not retrieve hHook for current thread!\n" );
return FALSE;
}
/* Pass on the message to the next hooker */
return CallNextHookEx( pHookItem->GetMsg_hHook, code, wParam, lParam );
}
/***********************************************************************
* OleCreateMenuDescriptor [OLE32.@]
* Creates an OLE menu descriptor for OLE to use when dispatching
* menu messages and commands.
*
* PARAMS:
* hmenuCombined - Handle to the objects combined menu
* lpMenuWidths - Pointer to array of 6 LONG's indicating menus per group
*
*/
HOLEMENU WINAPI OleCreateMenuDescriptor(
HMENU hmenuCombined,
LPOLEMENUGROUPWIDTHS lpMenuWidths)
{
HOLEMENU hOleMenu;
OleMenuDescriptor *pOleMenuDescriptor;
int i;
if ( !hmenuCombined || !lpMenuWidths )
return 0;
/* Create an OLE menu descriptor */
if ( !(hOleMenu = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,
sizeof(OleMenuDescriptor) ) ) )
return 0;
pOleMenuDescriptor = (OleMenuDescriptor *) GlobalLock( hOleMenu );
if ( !pOleMenuDescriptor )
return 0;
/* Initialize menu group widths and hmenu */
for ( i = 0; i < 6; i++ )
pOleMenuDescriptor->mgw.width[i] = lpMenuWidths->width[i];
pOleMenuDescriptor->hmenuCombined = hmenuCombined;
pOleMenuDescriptor->bIsServerItem = FALSE;
GlobalUnlock( hOleMenu );
return hOleMenu;
}
/***********************************************************************
* OleDestroyMenuDescriptor [OLE32.@]
* Destroy the shared menu descriptor
*/
HRESULT WINAPI OleDestroyMenuDescriptor(
HOLEMENU hmenuDescriptor)
{
if ( hmenuDescriptor )
GlobalFree( hmenuDescriptor );
return S_OK;
}
/***********************************************************************
* OleSetMenuDescriptor [OLE32.@]
* Installs or removes OLE dispatching code for the containers frame window.
*
* PARAMS
* hOleMenu Handle to composite menu descriptor
* hwndFrame Handle to containers frame window
* hwndActiveObject Handle to objects in-place activation window
* lpFrame Pointer to IOleInPlaceFrame on containers window
* lpActiveObject Pointer to IOleInPlaceActiveObject on active in-place object
*
* RETURNS
* S_OK - menu installed correctly
* E_FAIL, E_INVALIDARG, E_UNEXPECTED - failure
*
* FIXME
* The lpFrame and lpActiveObject parameters are currently ignored
* OLE should install context sensitive help F1 filtering for the app when
* these are non null.
*/
HRESULT WINAPI OleSetMenuDescriptor(
HOLEMENU hOleMenu,
HWND hwndFrame,
HWND hwndActiveObject,
LPOLEINPLACEFRAME lpFrame,
LPOLEINPLACEACTIVEOBJECT lpActiveObject)
{
OleMenuDescriptor *pOleMenuDescriptor = NULL;
/* Check args */
if ( !hwndFrame || (hOleMenu && !hwndActiveObject) )
return E_INVALIDARG;
if ( lpFrame || lpActiveObject )
{
FIXME("(%p, %p, %p, %p, %p), Context sensitive help filtering not implemented!\n",
hOleMenu,
hwndFrame,
hwndActiveObject,
lpFrame,
lpActiveObject);
}
/* Set up a message hook to intercept the containers frame window messages.
* The message filter is responsible for dispatching menu messages from the
* shared menu which are intended for the object.
*/
if ( hOleMenu ) /* Want to install dispatching code */
{
/* If OLEMenu hooks are already installed for this thread, fail
* Note: This effectively means that OleSetMenuDescriptor cannot
* be called twice in succession on the same frame window
* without first calling it with a null hOleMenu to uninstall */
if ( OLEMenu_IsHookInstalled( GetCurrentThreadId() ) )
return E_FAIL;
/* Get the menu descriptor */
pOleMenuDescriptor = (OleMenuDescriptor *) GlobalLock( hOleMenu );
if ( !pOleMenuDescriptor )
return E_UNEXPECTED;
/* Update the menu descriptor */
pOleMenuDescriptor->hwndFrame = hwndFrame;
pOleMenuDescriptor->hwndActiveObject = hwndActiveObject;
GlobalUnlock( hOleMenu );
pOleMenuDescriptor = NULL;
/* Add a menu descriptor windows property to the frame window */
SetPropA( hwndFrame, "PROP_OLEMenuDescriptor", hOleMenu );
/* Install thread scope message hooks for WH_GETMESSAGE and WH_CALLWNDPROC */
if ( !OLEMenu_InstallHooks( GetCurrentThreadId() ) )
return E_FAIL;
}
else /* Want to uninstall dispatching code */
{
/* Uninstall the hooks */
if ( !OLEMenu_UnInstallHooks( GetCurrentThreadId() ) )
return E_FAIL;
/* Remove the menu descriptor property from the frame window */
RemovePropA( hwndFrame, "PROP_OLEMenuDescriptor" );
}
return S_OK;
}
/******************************************************************************
* IsAccelerator [OLE32.@]
* Mostly copied from controls/menu.c TranslateAccelerator implementation
*/
BOOL WINAPI IsAccelerator(HACCEL hAccel, int cAccelEntries, LPMSG lpMsg, WORD* lpwCmd)
{
LPACCEL lpAccelTbl;
int i;
if(!lpMsg) return FALSE;
if (!hAccel)
{
WARN_(accel)("NULL accel handle\n");
return FALSE;
}
if((lpMsg->message != WM_KEYDOWN &&
lpMsg->message != WM_KEYUP &&
lpMsg->message != WM_SYSKEYDOWN &&
lpMsg->message != WM_SYSKEYUP &&
lpMsg->message != WM_CHAR)) return FALSE;
lpAccelTbl = HeapAlloc(GetProcessHeap(), 0, cAccelEntries * sizeof(ACCEL));
if (NULL == lpAccelTbl)
{
return FALSE;
}
if (CopyAcceleratorTableW(hAccel, lpAccelTbl, cAccelEntries) != cAccelEntries)
{
WARN_(accel)("CopyAcceleratorTableW failed\n");
HeapFree(GetProcessHeap(), 0, lpAccelTbl);
return FALSE;
}
TRACE_(accel)("hAccel=%p, cAccelEntries=%d,"
"msg->hwnd=%p, msg->message=%04x, wParam=%08x, lParam=%08lx\n",
hAccel, cAccelEntries,
lpMsg->hwnd, lpMsg->message, lpMsg->wParam, lpMsg->lParam);
for(i = 0; i < cAccelEntries; i++)
{
if(lpAccelTbl[i].key != lpMsg->wParam)
continue;
if(lpMsg->message == WM_CHAR)
{
if(!(lpAccelTbl[i].fVirt & FALT) && !(lpAccelTbl[i].fVirt & FVIRTKEY))
{
TRACE_(accel)("found accel for WM_CHAR: ('%c')\n", lpMsg->wParam & 0xff);
goto found;
}
}
else
{
if(lpAccelTbl[i].fVirt & FVIRTKEY)
{
INT mask = 0;
TRACE_(accel)("found accel for virt_key %04x (scan %04x)\n",
lpMsg->wParam, HIWORD(lpMsg->lParam) & 0xff);
if(GetKeyState(VK_SHIFT) & 0x8000) mask |= FSHIFT;
if(GetKeyState(VK_CONTROL) & 0x8000) mask |= FCONTROL;
if(GetKeyState(VK_MENU) & 0x8000) mask |= FALT;
if(mask == (lpAccelTbl[i].fVirt & (FSHIFT | FCONTROL | FALT))) goto found;
TRACE_(accel)("incorrect SHIFT/CTRL/ALT-state\n");
}
else
{
if(!(lpMsg->lParam & 0x01000000)) /* no special_key */
{
if((lpAccelTbl[i].fVirt & FALT) && (lpMsg->lParam & 0x20000000))
{ /* ^^ ALT pressed */
TRACE_(accel)("found accel for Alt-%c\n", lpMsg->wParam & 0xff);
goto found;
}
}
}
}
}
WARN_(accel)("couldn't translate accelerator key\n");
HeapFree(GetProcessHeap(), 0, lpAccelTbl);
return FALSE;
found:
if(lpwCmd) *lpwCmd = lpAccelTbl[i].cmd;
HeapFree(GetProcessHeap(), 0, lpAccelTbl);
return TRUE;
}
/***********************************************************************
* ReleaseStgMedium [OLE32.@]
*/
void WINAPI ReleaseStgMedium(
STGMEDIUM* pmedium)
{
switch (pmedium->tymed)
{
case TYMED_HGLOBAL:
{
if ( (pmedium->pUnkForRelease==0) &&
(pmedium->u.hGlobal!=0) )
GlobalFree(pmedium->u.hGlobal);
break;
}
case TYMED_FILE:
{
if (pmedium->u.lpszFileName!=0)
{
if (pmedium->pUnkForRelease==0)
{
DeleteFileW(pmedium->u.lpszFileName);
}
CoTaskMemFree(pmedium->u.lpszFileName);
}
break;
}
case TYMED_ISTREAM:
{
if (pmedium->u.pstm!=0)
{
IStream_Release(pmedium->u.pstm);
}
break;
}
case TYMED_ISTORAGE:
{
if (pmedium->u.pstg!=0)
{
IStorage_Release(pmedium->u.pstg);
}
break;
}
case TYMED_GDI:
{
if ( (pmedium->pUnkForRelease==0) &&
(pmedium->u.hBitmap!=0) )
DeleteObject(pmedium->u.hBitmap);
break;
}
case TYMED_MFPICT:
{
if ( (pmedium->pUnkForRelease==0) &&
(pmedium->u.hMetaFilePict!=0) )
{
LPMETAFILEPICT pMP = GlobalLock(pmedium->u.hMetaFilePict);
DeleteMetaFile(pMP->hMF);
GlobalUnlock(pmedium->u.hMetaFilePict);
GlobalFree(pmedium->u.hMetaFilePict);
}
break;
}
case TYMED_ENHMF:
{
if ( (pmedium->pUnkForRelease==0) &&
(pmedium->u.hEnhMetaFile!=0) )
{
DeleteEnhMetaFile(pmedium->u.hEnhMetaFile);
}
break;
}
case TYMED_NULL:
default:
break;
}
pmedium->tymed=TYMED_NULL;
/*
* After cleaning up, the unknown is released
*/
if (pmedium->pUnkForRelease!=0)
{
IUnknown_Release(pmedium->pUnkForRelease);
pmedium->pUnkForRelease = 0;
}
}
/***
* OLEDD_Initialize()
*
* Initializes the OLE drag and drop data structures.
*/
static void OLEDD_Initialize()
{
WNDCLASSA wndClass;
ZeroMemory (&wndClass, sizeof(WNDCLASSA));
wndClass.style = CS_GLOBALCLASS;
wndClass.lpfnWndProc = OLEDD_DragTrackerWindowProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = sizeof(TrackerWindowInfo*);
wndClass.hCursor = 0;
wndClass.hbrBackground = 0;
wndClass.lpszClassName = OLEDD_DRAGTRACKERCLASS;
RegisterClassA (&wndClass);
}
/***
* OLEDD_UnInitialize()
*
* Releases the OLE drag and drop data structures.
*/
static void OLEDD_UnInitialize()
{
/*
* Simply empty the list.
*/
while (targetListHead!=NULL)
{
RevokeDragDrop(targetListHead->hwndTarget);
}
}
/***
* OLEDD_InsertDropTarget()
*
* Insert the target node in the tree.
*/
static void OLEDD_InsertDropTarget(DropTargetNode* nodeToAdd)
{
DropTargetNode* curNode;
DropTargetNode** parentNodeLink;
/*
* Iterate the tree to find the insertion point.
*/
curNode = targetListHead;
parentNodeLink = &targetListHead;
while (curNode!=NULL)
{
if (nodeToAdd->hwndTarget<curNode->hwndTarget)
{
/*
* If the node we want to add has a smaller HWND, go left
*/
parentNodeLink = &curNode->prevDropTarget;
curNode = curNode->prevDropTarget;
}
else if (nodeToAdd->hwndTarget>curNode->hwndTarget)
{
/*
* If the node we want to add has a larger HWND, go right
*/
parentNodeLink = &curNode->nextDropTarget;
curNode = curNode->nextDropTarget;
}
else
{
/*
* The item was found in the list. It shouldn't have been there
*/
assert(FALSE);
return;
}
}
/*
* If we get here, we have found a spot for our item. The parentNodeLink
* pointer points to the pointer that we have to modify.
* The curNode should be NULL. We just have to establish the link and Voila!
*/
assert(curNode==NULL);
assert(parentNodeLink!=NULL);
assert(*parentNodeLink==NULL);
*parentNodeLink=nodeToAdd;
}
/***
* OLEDD_ExtractDropTarget()
*
* Removes the target node from the tree.
*/
static DropTargetNode* OLEDD_ExtractDropTarget(HWND hwndOfTarget)
{
DropTargetNode* curNode;
DropTargetNode** parentNodeLink;
/*
* Iterate the tree to find the insertion point.
*/
curNode = targetListHead;
parentNodeLink = &targetListHead;
while (curNode!=NULL)
{
if (hwndOfTarget<curNode->hwndTarget)
{
/*
* If the node we want to add has a smaller HWND, go left
*/
parentNodeLink = &curNode->prevDropTarget;
curNode = curNode->prevDropTarget;
}
else if (hwndOfTarget>curNode->hwndTarget)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -