Given this code
And this version of the callback
PowerBASIC calls Release on oObject an [in] parameter which, in my opinion, is a violation of the
COM reference counting rules. The result is that the IUnknown pointer to the object, @pTenant.m_pIUnknown,
is no longer valid after frameIOleInPlaceFrame_RemoveMenus returns.
Code:
FUNCTION frameIOleInPlaceFrame_RemoveMenus(BYVAL pThis AS DWORD, BYVAL hmenuShared AS DWORD) AS LONG LOCAL riid AS GUID LOCAL pCIFace AS CIFace PTR LOCAL pCFrame AS CFrame PTR LOCAL ptocd AS OLECONTAINERDATA PTR LOCAL pTenant AS Tenant PTR LOCAL hWndSite AS DWORD LOCAL pUnk AS DWORD LOCAL lParam AS LONG LOCAL lpfnCallback AS DWORD LOCAL hr AS LONG pCIFace = pThis pCFrame = @pCIFace.pObject ' Tell the top-level window to remove its menus IF pCFrame THEN hWndSite = GetHostWindow(@pCFrame.m_pIOleIPActiveObject) IF IsWindow(hWndSite) THEN ptocd = GetWindowLong(hWndSite, 0) IF @ptocd.m_lpfnMenu THEN lpfnCallback = @ptocd.m_lpfnMenu lParam = @ptocd.m_lParam riid = $IID_IUNKNOWN pTenant = @ptocd.m_pObject IF pTenant THEN hr = IUnknown_QueryInterface(@pTenant.m_pIUnknown, riid, pUnk) IF hr = %S_OK THEN ' Call the InsertMenus callback function ! push ebx ! push esi ! push edi ! push lParam ! push %TRUE ! push %NULL ! push %NULL ! push %NULL ! push hmenuShared ! push pUnk ! call lpfnCallback ! pop edi ! pop esi ! pop ebx IUnknown_Release pUnk END IF END IF END IF END IF END IF FUNCTION = %S_OK END FUNCTION
Code:
FUNCTION InsertMenusCallback _ ( _ BYVAL oObject AS IUNKNOWN, _ ' [in] IUnknown pointer to active object BYVAL hMenuShared AS DWORD, _ ' [in] shared menu BYVAL ptomgw AS OLEMENUGROUPWIDTHS PTR, _ ' [out] array indicatiing number of items in each group BYVAL phMenuFrame AS DWORD PTR, _ ' [out] points to the handle of the original frame menu BYVAL phMenuWindow AS DWORD PTR, _ ' [out] points to the handle of the original window menu(MDI) BYVAL fRemove AS LONG, _ ' [in] true, items are being removed. False, items are being added BYVAL lParam AS LONG _ ' [in] application-defined value ) AS LONG END FUNCTION
COM reference counting rules. The result is that the IUnknown pointer to the object, @pTenant.m_pIUnknown,
is no longer valid after frameIOleInPlaceFrame_RemoveMenus returns.
Comment