From 07ca9bda0bd66e53cfbdc441b59fa4bc2e988171 Mon Sep 17 00:00:00 2001 From: Geoffrey Hausheer Date: Thu, 7 Jan 2010 22:45:28 -0800 Subject: Implement OleCreatePropertyFrame from scratch --- dlls/oleaut32/Makefile.in | 1 + dlls/oleaut32/olepropframe.c | 343 ++++++++++++++++++++++++++++++++++++++++++ dlls/oleaut32/stubs.c | 22 --- 3 files changed, 344 insertions(+), 22 deletions(-) create mode 100644 dlls/oleaut32/olepropframe.c diff --git a/dlls/oleaut32/Makefile.in b/dlls/oleaut32/Makefile.in index a8ab7b4..d304257 100644 --- a/dlls/oleaut32/Makefile.in +++ b/dlls/oleaut32/Makefile.in @@ -17,6 +17,7 @@ C_SRCS = \ oleaut.c \ olefont.c \ olepicture.c \ + olepropframe.c \ recinfo.c \ regsvr.c \ safearray.c \ diff --git a/dlls/oleaut32/olepropframe.c b/dlls/oleaut32/olepropframe.c new file mode 100644 index 0000000..cd1841c --- /dev/null +++ b/dlls/oleaut32/olepropframe.c @@ -0,0 +1,343 @@ +/* + * OleCreatePropertyFrame + * + * Copyright 2010 Geoffrey Hausheer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +#include "config.h" +#include "wine/port.h" + +#include +#include +#include +#include +#include + +#define COBJMACROS +#define NONAMELESSUNION +#define NONAMELESSSTRUCT + +#include "winerror.h" +#include "windef.h" +#include "winbase.h" +#include "winnls.h" +#include "winreg.h" +#include "winuser.h" +#include "lzexpand.h" + +#include "wine/unicode.h" +#include "objbase.h" +#include "typelib.h" +#include "wine/debug.h" +#include "variant.h" +#include "wine/list.h" +#include "ocidl.h" +#include "prsht.h" +#include "olectl.h" + +WINE_DEFAULT_DEBUG_CHANNEL(olepropframe); + +typedef struct +{ + const IPropertyPageSiteVtbl* lpVtbl; + LCID lcid; + LONG ref; +} OLEPropertyPageSite; + +typedef struct { + struct { + DLGTEMPLATE dlg; + WORD menu; + WORD class; + WORD caption; + WORD font; + } dialog; + OLEPropertyPageSite pps; + IPropertyPage *propPage; +} OLEPropertyFrame; + +static INT_PTR CALLBACK prop_sheet_proc(HWND hwnd, UINT msg, WPARAM wparam, + LPARAM lparam) +{ + + switch(msg) + { + case WM_INITDIALOG: + { + RECT rect; + HRESULT result; + PROPSHEETPAGEW *psp = (PROPSHEETPAGEW *)lparam; + OLEPropertyFrame *opf = (OLEPropertyFrame *)psp->lParam; + + TRACE("(%p, %s, %ld, %p)\n", hwnd, "WM_INITDIALOG", + wparam, opf->propPage); + ZeroMemory( &rect, sizeof(rect) ); + GetClientRect( hwnd, &rect ); + result = IPropertyPage_Activate(opf->propPage, hwnd, &rect, TRUE); + if(result == S_OK) { + result = IPropertyPage_Show(opf->propPage, SW_SHOW ); + if(result == S_OK) { + SetWindowLongPtrW( hwnd, DWLP_USER, (LONG)opf); + } + } + return FALSE; + } + case WM_DESTROY: + { + OLEPropertyFrame *opf = (OLEPropertyFrame *)GetWindowLongPtrW( hwnd, DWLP_USER ); + if (opf) { + IPropertyPage_Show(opf->propPage, SW_HIDE); + IPropertyPage_Deactivate(opf->propPage); + SetWindowLongPtrW( hwnd, DWLP_USER, (LONG)NULL); + } + } + case WM_NOTIFY: + { + OLEPropertyFrame *opf = (OLEPropertyFrame *)GetWindowLongPtrW( hwnd, DWLP_USER ); + NMHDR *nmhdr = (NMHDR *)lparam; + if(! opf) + break; + + switch(nmhdr->code) + { + case PSN_APPLY: + FIXME("(%p, %s, %s)\n", hwnd, "WM_NOTIFY", "PSN_APPLY"); + IPropertyPage_Apply(opf->propPage); + return TRUE; + default: + FIXME("(%p, %s, %d)\n", hwnd, "WM_NOTIFY", nmhdr->code); + return FALSE; + } + } + default: + FIXME("(%p, %d, %ld, %p)\n", hwnd, msg, wparam, (void *)lparam); + } + return FALSE; +} + +/******************************************************************************/ +static ULONG WINAPI PPS_AddRef(IPropertyPageSite* iface) +{ + OLEPropertyPageSite *this = (OLEPropertyPageSite *)iface; + TRACE("(%p)->(ref=%d)\n", this, this->ref); + return InterlockedIncrement(&this->ref); +} + +static ULONG WINAPI PPS_Release(IPropertyPageSite* iface) +{ + OLEPropertyPageSite *this = (OLEPropertyPageSite *)iface; + ULONG ret; + TRACE("(%p)->(ref=%d)\n", this, this->ref); + + /* Decrease the reference count for current interface */ + ret = InterlockedDecrement(&this->ref); + + return ret; +} + +static HRESULT WINAPI PPS_QueryInterface( + IPropertyPageSite* iface, + REFIID riid, + void** ppvObject) +{ + TRACE("(%p) riid: %s\n",iface, debugstr_guid(riid)); + + if ( (iface==0) || (ppvObject==0) ) + return E_INVALIDARG; + + if (IsEqualGUID(&IID_IUnknown, riid)) + *ppvObject = iface; + else if (IsEqualGUID(&IID_IPropertyPageSite, riid)) + *ppvObject = iface; + else + *ppvObject = 0; + if ((*ppvObject)==0) + { + return E_NOINTERFACE; + } + PPS_AddRef((IPropertyPageSite*)iface); + return S_OK; +} + +static HRESULT WINAPI PPS_OnStatusChange(IPropertyPageSite *iface, DWORD dwFlags) +{ + FIXME("(%p, %d)", iface, dwFlags); + return S_OK; +} + +static HRESULT WINAPI PPS_GetLocaleID(IPropertyPageSite *iface, LCID *pLocaleID) +{ + OLEPropertyPageSite *pps = (OLEPropertyPageSite *)iface; + TRACE("(%p, %p)", iface, pLocaleID); + if (pLocaleID == NULL) + return E_POINTER; + + *pLocaleID = pps->lcid; + return S_OK; +} + +static HRESULT WINAPI PPS_GetPageContainer(IPropertyPageSite* iface, IUnknown** ppUnk) +{ + TRACE("(%p, %p)", iface, ppUnk); + return E_NOTIMPL; +} + +static HRESULT WINAPI PPS_TranslateAccelerator(IPropertyPageSite* iface, MSG *pMsg) +{ + TRACE("(%p, %p)", iface, pMsg); + return E_NOTIMPL; +} + +IPropertyPageSiteVtbl PPS_Vtbl = { + PPS_QueryInterface, + PPS_AddRef, + PPS_Release, + PPS_OnStatusChange, + PPS_GetLocaleID, + PPS_GetPageContainer, + PPS_TranslateAccelerator +}; + +static void pixels_to_dialog_units(short *x_pixels, short *y_pixels) +{ + int basex, basey; + /* This was expected to work but didn't: + LONG baseunits = GetDialogBaseUnits(); + basex = LOWORD(baseunits); + basey = HIWORD(baseunits); + */ + + /* These came from inverting MapDialogRect */ + basex = 6; + basey = 13; + + *x_pixels = MulDiv(*x_pixels, 4, basex); + *y_pixels = MulDiv(*y_pixels, 8, basey); +} + +/******************************************************************************/ +HRESULT WINAPI OleCreatePropertyFrameIndirect(LPOCPFIPARAMS lpParams) +{ + PROPSHEETHEADERW propSheet; + PROPSHEETPAGEW psp; + PROPPAGEINFO pPageInfo; + HPROPSHEETPAGE *hpsp; + OLEPropertyFrame *opf; + int page; + HRESULT result; + + TRACE("(%p)\n** OCPFIPARAMS **\ncbStructSize\t%d\nhWndOwner\t%p\nx\t\t%d\n" + "y\t\t%d\nlpszCaption\t%p\ncObjects\t%d\nlplpUnk\t\t%p\ncPages\t%d\n" + "lpPages\t%p\nlcid\t\t%x\ndispidInitialProperty\t%d\n", + lpParams, lpParams->cbStructSize, lpParams->hWndOwner, lpParams->x, + lpParams->y, + lpParams->lpszCaption, lpParams->cObjects, lpParams->lplpUnk, + lpParams->cPages, lpParams->lpPages, (int)lpParams->lcid, + lpParams->dispidInitialProperty); + + ZeroMemory(&propSheet, sizeof(propSheet)); + + propSheet.dwSize = sizeof(propSheet); + propSheet.dwFlags = PSH_PROPTITLE; + + propSheet.pszCaption = lpParams->lpszCaption; + + hpsp = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + lpParams->cPages * sizeof(HPROPSHEETPAGE)); + opf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + lpParams->cPages * sizeof(OLEPropertyFrame)); + + propSheet.u3.phpage = hpsp; + + ZeroMemory(&psp, sizeof(psp)); + psp.dwSize=sizeof(psp); + psp.dwFlags = PSP_DLGINDIRECT | PSP_USETITLE; + psp.pfnDlgProc = prop_sheet_proc; + for(page = 0; page < lpParams->cPages; page++) { + + result = CoCreateInstance(&lpParams->lpPages[page],NULL, + CLSCTX_INPROC_SERVER,&IID_IPropertyPage, + (void**)&opf[page].propPage); + if (result != S_OK) { + continue; + } + + opf[page].pps.lpVtbl = &PPS_Vtbl; + opf[page].pps.lcid = lpParams->lcid; + + result = IPropertyPage_SetPageSite(opf[page].propPage, + (IPropertyPageSite*)&opf[page].pps); + if(result != S_OK) { + continue; + } + result = IPropertyPage_GetPageInfo(opf[page].propPage, &pPageInfo); + if(result != S_OK) { + continue; + } + result = IPropertyPage_SetObjects(opf[page].propPage, + lpParams->cObjects, lpParams->lplpUnk); + if(result != S_OK) { + continue; + } + opf[page].dialog.dlg.cx = pPageInfo.size.cx; + opf[page].dialog.dlg.cy = pPageInfo.size.cy; + pixels_to_dialog_units(&opf[page].dialog.dlg.cx, + &opf[page].dialog.dlg.cy); + psp.u.pResource = (DLGTEMPLATE *)&opf[page].dialog; + psp.lParam = (LPARAM) &opf[page]; + psp.pszTitle = pPageInfo.pszTitle; + hpsp[propSheet.nPages++] = CreatePropertySheetPageW(&psp); + } + result = PropertySheetW(&propSheet); + HeapFree(GetProcessHeap(), 0, hpsp); + HeapFree(GetProcessHeap(), 0, opf); + if (result == -1) + return E_UNEXPECTED; + return S_OK; +} + +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) +{ + OCPFIPARAMS ocpf; + + ocpf.cbStructSize = sizeof(OCPFIPARAMS); + ocpf.hWndOwner = hWndOwner; + ocpf.x = x; + ocpf.y = y; + ocpf.lpszCaption = lpszCaption; + ocpf.cObjects = cObjects; + ocpf.lplpUnk = ppUnk; + ocpf.cPages = cPages; + ocpf.lpPages = pPageClsID; + ocpf.lcid = lcid; + ocpf.dispidInitialProperty = 0; + + return OleCreatePropertyFrameIndirect(&ocpf); +} + diff --git a/dlls/oleaut32/stubs.c b/dlls/oleaut32/stubs.c index d87e76e..164be38 100644 --- a/dlls/oleaut32/stubs.c +++ b/dlls/oleaut32/stubs.c @@ -32,25 +32,3 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole); -/*********************************************************************** - * 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("(%p,%d,%d,%s,%d,%p,%d,%p,%x,%d,%p), not implemented (olepro32.dll)\n", - hwndOwner,x,y,debugstr_w(lpszCaption),cObjects,ppUnk,cPages, - pPageClsID, (int)lcid,dwReserved,pvReserved); - return S_OK; -} -- 1.5.4.3