From 2843934af5515c7f2b8370324aa98d3964a40324 Mon Sep 17 00:00:00 2001 From: Hidenori Takeshima Date: Tue, 23 Oct 2001 19:59:24 +0000 Subject: [PATCH] Implemented OleCreatePropertyFrame and OleCreatePropertyFrameIndirect. --- dlls/Makefile.in | 5 +- dlls/oleaut32/Makefile.in | 1 + dlls/oleaut32/oleaut32.spec | 1 + dlls/oleaut32/propertyframe.c | 579 ++++++++++++++++++++++++++++++++++ dlls/oleaut32/stubs.c | 22 -- 5 files changed, 584 insertions(+), 24 deletions(-) create mode 100644 dlls/oleaut32/propertyframe.c diff --git a/dlls/Makefile.in b/dlls/Makefile.in index c02d42e8ee9..e7039d6b78f 100644 --- a/dlls/Makefile.in +++ b/dlls/Makefile.in @@ -541,8 +541,9 @@ ole32/libole32.$(LIBEXT): dummy libadvapi32.$(LIBEXT) libuser32.$(LIBEXT) \ libgdi32.$(LIBEXT) librpcrt4.$(LIBEXT) libkernel32.$(LIBEXT) libntdll.$(LIBEXT) @cd ole32 && $(MAKE) libole32.$(LIBEXT) -oleaut32/liboleaut32.$(LIBEXT): dummy libole32.$(LIBEXT) libuser32.$(LIBEXT) \ - libgdi32.$(LIBEXT) libadvapi32.$(LIBEXT) libkernel32.$(LIBEXT) libntdll.$(LIBEXT) +oleaut32/liboleaut32.$(LIBEXT): dummy libcomctl32.$(LIBEXT) libole32.$(LIBEXT) \ + libuser32.$(LIBEXT) libgdi32.$(LIBEXT) libadvapi32.$(LIBEXT) libkernel32.$(LIBEXT) \ + libntdll.$(LIBEXT) @cd oleaut32 && $(MAKE) liboleaut32.$(LIBEXT) olecli/libolecli32.$(LIBEXT): dummy libole32.$(LIBEXT) libgdi32.$(LIBEXT) \ diff --git a/dlls/oleaut32/Makefile.in b/dlls/oleaut32/Makefile.in index fe4fec55e4f..4bc354065b4 100644 --- a/dlls/oleaut32/Makefile.in +++ b/dlls/oleaut32/Makefile.in @@ -18,6 +18,7 @@ C_SRCS = \ olefont.c \ olepicture.c \ parsedt.c \ + propertyframe.c \ safearray.c \ stubs.c \ typelib.c \ diff --git a/dlls/oleaut32/oleaut32.spec b/dlls/oleaut32/oleaut32.spec index 9734216a8cb..87563c70637 100644 --- a/dlls/oleaut32/oleaut32.spec +++ b/dlls/oleaut32/oleaut32.spec @@ -2,6 +2,7 @@ name oleaut32 type win32 rsrc version.res +import -delay comctl32.dll import ole32.dll import user32.dll import gdi32.dll diff --git a/dlls/oleaut32/propertyframe.c b/dlls/oleaut32/propertyframe.c new file mode 100644 index 00000000000..1f3fb7dd378 --- /dev/null +++ b/dlls/oleaut32/propertyframe.c @@ -0,0 +1,579 @@ +/* + * Copyright 2001 TAKESHIMA Hidenori + * + * FIXME - use PropertySheetW. + * FIXME - not tested. + */ + +#include "config.h" + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "debugtools.h" +#include "ole2.h" +#include "olectl.h" +#include "oleauto.h" +#include "commctrl.h" + +DEFAULT_DEBUG_CHANNEL(ole); + +typedef struct CPropertyPageContainerImpl CPropertyPageContainerImpl; + +static const struct +{ + DLGTEMPLATE templ; + WORD wMenuName; + WORD wClassName; + WCHAR wDummyCaption; + BYTE padding[4]; +} propsite_dlg = +{ + { + WS_VISIBLE | WS_CHILD, /* style */ + 0, /* dwExtendedStyle */ + 0, /* cdit */ + 0, /* x */ + 0, /* y */ + 0, /* cx */ + 0, /* cy */ + }, + 0, 0, 0, +}; + +typedef struct CPropertyPageSiteImpl +{ + ICOM_VFIELD(IPropertyPageSite); + /* IUnknown fields */ + ULONG ref; + + /* IPropertyPageSite fields */ + CPropertyPageContainerImpl* pContainer; + IPropertyPage* pPage; + HWND hwnd; + BYTE templ[sizeof(propsite_dlg)]; + PROPPAGEINFO info; + BOOL bActivate; +} CPropertyPageSiteImpl; + +struct CPropertyPageContainerImpl +{ + ULONG ref; /* for IUnknown(not used now) */ + LCID lcid; + DWORD m_cSites; + CPropertyPageSiteImpl** m_ppSites; + PROPSHEETPAGEA* m_pPsp; + HRESULT m_hr; +}; + +/* for future use. */ +#define CPropertyPageContainerImpl_AddRef(pContainer) (++((pContainer)->ref)) +#define CPropertyPageContainerImpl_Release(pContainer) (--((pContainer)->ref)) + + +/***************************************************************************/ + +#define PropSiteDlg_Return(a) do{SetWindowLongA(hwnd,DWL_MSGRESULT,(LONG)a);return TRUE;}while(1) +static BOOL CALLBACK PropSiteDlgProc( + HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) +{ + CPropertyPageSiteImpl* This = (CPropertyPageSiteImpl*)GetWindowLongA( hwnd, DWL_USER ); + HRESULT hr; + RECT rc; + NMHDR* pnmh; + + switch ( msg ) + { + case WM_INITDIALOG: + This = (CPropertyPageSiteImpl*)(((PROPSHEETPAGEA*)lParam)->lParam); + SetWindowLongA( hwnd, DWL_USER, (LONG)This ); + TRACE("WM_INITDIALOG (%p) hwnd = %08x\n", This, hwnd ); + + This->hwnd = hwnd; + ZeroMemory( &rc, sizeof(rc) ); + GetClientRect( hwnd, &rc ); + hr = IPropertyPage_Activate(This->pPage,hwnd,&rc,TRUE); + if ( SUCCEEDED(hr) ) + { + This->bActivate = TRUE; + hr = IPropertyPage_Show(This->pPage,SW_SHOW); + } + if ( FAILED(hr) ) + This->pContainer->m_hr = hr; + break; + case WM_DESTROY: + TRACE("WM_DESTROY (%p)\n",This); + if ( This != NULL ) + { + if ( This->bActivate ) + { + IPropertyPage_Show(This->pPage,SW_HIDE); + IPropertyPage_Deactivate(This->pPage); + This->bActivate = FALSE; + } + This->hwnd = (HWND)NULL; + } + SetWindowLongA( hwnd, DWL_USER, (LONG)0 ); + break; + case WM_NOTIFY: + pnmh = (NMHDR*)lParam; + switch ( pnmh->code ) + { + case PSN_APPLY: + TRACE("PSN_APPLY (%p)\n",This); + hr = IPropertyPage_Apply(This->pPage); + if ( FAILED(hr) ) + PropSiteDlg_Return(PSNRET_INVALID_NOCHANGEPAGE); + PropSiteDlg_Return(PSNRET_NOERROR); + case PSN_QUERYCANCEL: + FIXME("PSN_QUERYCANCEL (%p)\n",This); + PropSiteDlg_Return(FALSE); + case PSN_RESET: + FIXME("PSN_RESET (%p)\n",This); + PropSiteDlg_Return(0); + case PSN_SETACTIVE: + TRACE("PSN_SETACTIVE (%p)\n",This); + PropSiteDlg_Return(0); + case PSN_KILLACTIVE: + TRACE("PSN_KILLACTIVE (%p)\n",This); + PropSiteDlg_Return(FALSE); + } + break; + } + + return FALSE; +} + +/***************************************************************************/ + +static HRESULT WINAPI +CPropertyPageSiteImpl_fnQueryInterface(IPropertyPageSite* iface,REFIID riid,LPVOID *ppobj) +{ + ICOM_THIS(CPropertyPageSiteImpl,iface); + + TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj); + + if ( ppobj == NULL ) + return E_POINTER; + *ppobj = NULL; + + if ( IsEqualGUID(riid,&IID_IUnknown) || + IsEqualGUID(riid,&IID_IPropertyPageSite) ) + { + *ppobj = (LPVOID)This; + IUnknown_AddRef((IUnknown*)(*ppobj)); + return S_OK; + } + + return E_NOINTERFACE; +} + +static ULONG WINAPI +CPropertyPageSiteImpl_fnAddRef(IPropertyPageSite* iface) +{ + ICOM_THIS(CPropertyPageSiteImpl,iface); + + TRACE("(%p)->()\n",This); + + return InterlockedExchangeAdd(&(This->ref),1) + 1; +} + +static ULONG WINAPI +CPropertyPageSiteImpl_fnRelease(IPropertyPageSite* iface) +{ + ICOM_THIS(CPropertyPageSiteImpl,iface); + LONG ref; + + TRACE("(%p)->()\n",This); + ref = InterlockedExchangeAdd(&(This->ref),-1) - 1; + if ( ref > 0 ) + return (ULONG)ref; + + if ( This->pContainer != NULL ) + CPropertyPageContainerImpl_Release(This->pContainer); + if ( This->pPage != NULL ) + IPropertyPage_Release(This->pPage); + if ( This->info.pszTitle != NULL ) + CoTaskMemFree( This->info.pszTitle ); + if ( This->info.pszDocString != NULL ) + CoTaskMemFree( This->info.pszDocString ); + if ( This->info.pszHelpFile != NULL ) + CoTaskMemFree( This->info.pszHelpFile ); + + HeapFree(GetProcessHeap(),0,This); + + return 0; +} + +static HRESULT WINAPI +CPropertyPageSiteImpl_fnOnStatusChange(IPropertyPageSite* iface,DWORD dwFlags) +{ + ICOM_THIS(CPropertyPageSiteImpl,iface); + + TRACE("(%p,%08lx)\n",This,dwFlags); + + if ( This->hwnd == (HWND)NULL ) + return E_UNEXPECTED; + + switch ( dwFlags ) + { + case PROPPAGESTATUS_DIRTY: + /* dirty */ + SendMessageA(GetParent(This->hwnd),PSM_CHANGED,(WPARAM)(This->hwnd),0); + break; + case PROPPAGESTATUS_VALIDATE: + /* validate */ + SendMessageA(GetParent(This->hwnd),PSM_UNCHANGED,(WPARAM)(This->hwnd),0); + break; + default: + FIXME("(%p,%08lx) unknown flags\n",This,dwFlags); + return E_INVALIDARG; + } + + return NOERROR; +} + +static HRESULT WINAPI +CPropertyPageSiteImpl_fnGetLocaleID(IPropertyPageSite* iface,LCID* pLocaleID) +{ + ICOM_THIS(CPropertyPageSiteImpl,iface); + + TRACE("(%p,%p)\n",This,pLocaleID); + + if ( pLocaleID == NULL ) + return E_POINTER; + + *pLocaleID = This->pContainer->lcid; + + return NOERROR; +} + +static HRESULT WINAPI +CPropertyPageSiteImpl_fnGetPageContainer(IPropertyPageSite* iface,IUnknown** ppUnk) +{ + ICOM_THIS(CPropertyPageSiteImpl,iface); + + FIXME("(%p,%p) - Win95 returns E_NOTIMPL\n",This,ppUnk); + + if ( ppUnk == NULL ) + return E_POINTER; + + *ppUnk = NULL; + + return E_NOTIMPL; +} + +static HRESULT WINAPI +CPropertyPageSiteImpl_fnTranslateAccelerator(IPropertyPageSite* iface,MSG* pMsg) +{ + ICOM_THIS(CPropertyPageSiteImpl,iface); + + FIXME("(%p,%p) - Win95 returns E_NOTIMPL\n",This,pMsg); + + if ( pMsg == NULL ) + return E_POINTER; + + return E_NOTIMPL; +} + +static ICOM_VTABLE(IPropertyPageSite) iproppagesite = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + /* IUnknown fields */ + CPropertyPageSiteImpl_fnQueryInterface, + CPropertyPageSiteImpl_fnAddRef, + CPropertyPageSiteImpl_fnRelease, + /* IPropertyPageSite fields */ + CPropertyPageSiteImpl_fnOnStatusChange, + CPropertyPageSiteImpl_fnGetLocaleID, + CPropertyPageSiteImpl_fnGetPageContainer, + CPropertyPageSiteImpl_fnTranslateAccelerator, +}; + +/***************************************************************************/ + +static +HRESULT OLEPRO32_CreatePropertyPageSite( + CPropertyPageContainerImpl* pContainer, + IPropertyPage* pPage, + CPropertyPageSiteImpl** ppSite, + PROPSHEETPAGEA* pPspReturned ) +{ + CPropertyPageSiteImpl* This = NULL; + HRESULT hr; + DLGTEMPLATE* ptempl; + + *ppSite = NULL; + ZeroMemory( pPspReturned, sizeof(PROPSHEETPAGEA) ); + + This = (CPropertyPageSiteImpl*)HeapAlloc( GetProcessHeap(), 0, + sizeof(CPropertyPageSiteImpl) ); + if ( This == NULL ) + return E_OUTOFMEMORY; + ZeroMemory( This, sizeof(CPropertyPageSiteImpl) ); + + ICOM_VTBL(This) = &iproppagesite; + This->ref = 1; + This->pContainer = pContainer; CPropertyPageContainerImpl_AddRef(pContainer); + This->pPage = pPage; IPropertyPage_AddRef(pPage); + This->hwnd = (HWND)NULL; + memcpy( &This->templ, &propsite_dlg, sizeof(propsite_dlg) ); + This->info.cb = sizeof(PROPPAGEINFO); + This->bActivate = FALSE; + ptempl = (DLGTEMPLATE*)&This->templ; + + /* construct */ + hr = IPropertyPage_SetPageSite(pPage,(IPropertyPageSite*)This); + if ( FAILED(hr) ) + goto end; + + hr = IPropertyPage_GetPageInfo(pPage,&This->info); + if ( FAILED(hr) ) + goto end; + + ptempl->cx = This->info.size.cx; + ptempl->cy = This->info.size.cy; + + pPspReturned->dwSize = sizeof(PROPSHEETPAGEA); + pPspReturned->dwFlags = PSP_DLGINDIRECT; + pPspReturned->u.pResource = ptempl; + if ( This->info.pszTitle != NULL ); + { + pPspReturned->dwFlags |= PSP_USETITLE; + pPspReturned->pszTitle = "Title";/*FIXME - This->info.pszTitle;*/ + } + pPspReturned->pfnDlgProc = PropSiteDlgProc; + pPspReturned->lParam = (LONG)This; + +end: + if ( FAILED(hr) ) + { + IUnknown_Release((IUnknown*)This); + return hr; + } + + *ppSite = This; + return NOERROR; +} + +/***************************************************************************/ + +static +void OLEPRO32_DestroyPropertyPageContainer( + CPropertyPageContainerImpl* This ) +{ + DWORD nIndex; + + if ( This->m_ppSites != NULL ) + { + for ( nIndex = 0; nIndex < This->m_cSites; nIndex++ ) + { + if ( This->m_ppSites[nIndex] != NULL ) + { + IPropertyPage_SetPageSite(This->m_ppSites[nIndex]->pPage,NULL); + IUnknown_Release((IUnknown*)This->m_ppSites[nIndex]); + } + } + HeapFree( GetProcessHeap(), 0, This->m_ppSites ); + This->m_ppSites = NULL; + } + if ( This->m_pPsp != NULL ) + { + HeapFree( GetProcessHeap(), 0, This->m_pPsp ); + This->m_pPsp = NULL; + } + HeapFree( GetProcessHeap(), 0, This ); +} + +static +HRESULT OLEPRO32_CreatePropertyPageContainer( + CPropertyPageContainerImpl** ppContainer, + ULONG cPages, const CLSID* pclsidPages, + LCID lcid ) +{ + CPropertyPageContainerImpl* This = NULL; + DWORD nIndex; + IPropertyPage* pPage; + HRESULT hr; + + This = (CPropertyPageContainerImpl*)HeapAlloc( GetProcessHeap(), 0, + sizeof(CPropertyPageContainerImpl) ); + if ( This == NULL ) + return E_OUTOFMEMORY; + ZeroMemory( This, sizeof(CPropertyPageContainerImpl) ); + This->ref = 1; + This->lcid = lcid; + This->m_cSites = cPages; + This->m_ppSites = NULL; + This->m_pPsp = NULL; + This->m_hr = S_OK; + + This->m_ppSites = (CPropertyPageSiteImpl**)HeapAlloc( GetProcessHeap(), 0, sizeof(CPropertyPageSiteImpl*) * cPages ); + if ( This->m_ppSites == NULL ) + { + hr = E_OUTOFMEMORY; + goto end; + } + ZeroMemory( This->m_ppSites, sizeof(CPropertyPageSiteImpl*) * cPages ); + + This->m_pPsp = (PROPSHEETPAGEA*)HeapAlloc( GetProcessHeap(), 0, sizeof(PROPSHEETPAGEA) * cPages ); + if ( This->m_pPsp == NULL ) + { + hr = E_OUTOFMEMORY; + goto end; + } + ZeroMemory( This->m_pPsp, sizeof(PROPSHEETPAGEA) * cPages ); + + for ( nIndex = 0; nIndex < cPages; nIndex ++ ) + { + hr = CoCreateInstance( + &pclsidPages[nIndex], NULL, CLSCTX_SERVER, + &IID_IPropertyPage, (void**)&pPage ); + if ( FAILED(hr) ) + goto end; + hr = OLEPRO32_CreatePropertyPageSite( + This, pPage, &This->m_ppSites[nIndex], &This->m_pPsp[nIndex] ); + IPropertyPage_Release(pPage); + if ( FAILED(hr) ) + goto end; + } + + hr = NOERROR; +end: + if ( FAILED(hr) ) + { + OLEPRO32_DestroyPropertyPageContainer( This ); + return hr; + } + + *ppContainer = This; + return NOERROR; +} + +static +HRESULT OLEPRO32_SetObjectsToPropertyPages( + CPropertyPageContainerImpl* This, + ULONG cObjects, IUnknown** ppunk ) +{ + DWORD nIndex; + HRESULT hr; + + for ( nIndex = 0; nIndex < This->m_cSites; nIndex ++ ) + { + if ( This->m_ppSites[nIndex] == NULL ) + return E_UNEXPECTED; + hr = IPropertyPage_SetObjects(This->m_ppSites[nIndex]->pPage,cObjects,ppunk); + if ( FAILED(hr) ) + return hr; + } + + return NOERROR; +} + + +/*********************************************************************** + * + * OleCreatePropertyFrameIndirect (OLEAUT32.416)(OLEPRO32.249) + * + */ + +HRESULT WINAPI OleCreatePropertyFrameIndirect( LPOCPFIPARAMS lpParams ) +{ + CPropertyPageContainerImpl* pContainer = NULL; + HRESULT hr; + PROPSHEETHEADERA psh; + int ret; + + TRACE("(%p)\n",lpParams); + + if ( lpParams == NULL ) + return E_POINTER; + if ( lpParams->cbStructSize != sizeof(OCPFIPARAMS) ) + { + FIXME("lpParams->cbStructSize(%lu) != sizeof(OCPFIPARAMS)(%lu)\n",lpParams->cbStructSize,(unsigned long)sizeof(OCPFIPARAMS)); + return E_INVALIDARG; + } + + hr = OLEPRO32_CreatePropertyPageContainer( + &pContainer, + lpParams->cPages, lpParams->lpPages, + lpParams->lcid ); + if ( FAILED(hr) ) + { + TRACE( "OLEPRO32_CreatePropertyPageContainer returns %08lx\n",hr); + return hr; + } + + hr = OLEPRO32_SetObjectsToPropertyPages( + pContainer, + lpParams->cObjects, lpParams->lplpUnk ); + if ( FAILED(hr) ) + { + TRACE("OLEPRO32_SetObjectsToPropertyPages returns %08lx\n",hr); + OLEPRO32_DestroyPropertyPageContainer(pContainer); + return hr; + } + + /* FIXME - use lpParams.x / lpParams.y */ + + ZeroMemory( &psh, sizeof(psh) ); + psh.dwSize = sizeof(PROPSHEETHEADERA); + psh.dwFlags = PSH_PROPSHEETPAGE; + psh.hwndParent = lpParams->hWndOwner; + psh.pszCaption = "Caption"; /* FIXME - lpParams->lpszCaption; */ + psh.nPages = pContainer->m_cSites; + psh.u2.nStartPage = lpParams->dispidInitialProperty; + psh.u3.ppsp = pContainer->m_pPsp; + + ret = PropertySheetA( &psh ); + OLEPRO32_DestroyPropertyPageContainer(pContainer); + + if ( ret == -1 ) + return E_FAIL; + + return S_OK; +} + + +/*********************************************************************** + * + * OleCreatePropertyFrame (OLEAUT32.417)(OLEPRO32.250) + * + */ + +HRESULT WINAPI OleCreatePropertyFrame( + HWND hwndOwner, UINT x, UINT y, LPCOLESTR lpszCaption,ULONG cObjects, + LPUNKNOWN* lplpUnk, ULONG cPages, LPCLSID pPageClsID, LCID lcid, + DWORD dwReserved, LPVOID pvReserved ) +{ + OCPFIPARAMS params; + + TRACE("(%x,%d,%d,%s,%ld,%p,%ld,%p,%x,%ld,%p)\n", + hwndOwner,x,y,debugstr_w(lpszCaption),cObjects,lplpUnk,cPages, + pPageClsID, (int)lcid,dwReserved,pvReserved); + + if ( dwReserved != 0 || pvReserved != NULL ) + { + FIXME("(%x,%d,%d,%s,%ld,%p,%ld,%p,%x,%ld,%p) - E_INVALIDARG\n", + hwndOwner,x,y,debugstr_w(lpszCaption),cObjects,lplpUnk,cPages, + pPageClsID, (int)lcid,dwReserved,pvReserved); + return E_INVALIDARG; + } + + ZeroMemory( ¶ms, sizeof(params) ); + params.cbStructSize = sizeof(OCPFIPARAMS); + params.hWndOwner = hwndOwner; + params.x = x; + params.y = y; + params.lpszCaption = lpszCaption; + params.cObjects = cObjects; + params.lplpUnk = lplpUnk; + params.cPages = cPages; + params.lpPages = pPageClsID; + params.lcid = lcid; + params.dispidInitialProperty = 0; + + return OleCreatePropertyFrameIndirect( ¶ms ); +} + diff --git a/dlls/oleaut32/stubs.c b/dlls/oleaut32/stubs.c index ac1e8327adb..4bc036f2916 100644 --- a/dlls/oleaut32/stubs.c +++ b/dlls/oleaut32/stubs.c @@ -25,26 +25,4 @@ HCURSOR WINAPI OleIconToCursor( HINSTANCE hinstExe, HICON hicon) return S_OK; } -/*********************************************************************** - * OleCreatePropertyFrameIndirect (OLEAUT32.416) - */ -HRESULT WINAPI OleCreatePropertyFrameIndirect( LPOCPFIPARAMS lpParams) -{ - FIXME("(%p), not implemented (olepro32.dll)\n",lpParams); - return S_OK; -} - -/*********************************************************************** - * OleCreatePropertyFrame (OLEAUT32.417) - */ -HRESULT WINAPI OleCreatePropertyFrame( - HWND hwndOwner, UINT x, UINT y, LPCOLESTR lpszCaption,ULONG cObjects, - LPUNKNOWN* ppUnk, ULONG cPages, LPCLSID pPageClsID, LCID lcid, - DWORD dwReserved, LPVOID pvReserved ) -{ - FIXME("(%x,%d,%d,%s,%ld,%p,%ld,%p,%x,%ld,%p), not implemented (olepro32.dll)\n", - hwndOwner,x,y,debugstr_w(lpszCaption),cObjects,ppUnk,cPages, - pPageClsID, (int)lcid,dwReserved,pvReserved); - return S_OK; -}