[PATCH] Implement OleCreatePropertyFrame (try 2)
Geoffrey Hausheer
winedevel9605 at phracturedblue.com
Wed Jan 13 10:26:39 CST 2010
This patch implements OleCreatePropertyFrame() and
OleCreatePropertyFrameIndirect().
Second try incorporates recommendations from Piotr Caban
-------------- next part --------------
commit 0cf86283159aa17eeb9b985fe4fccf9dde0c4919
From: Geoffrey Hausheer <winedevel9605 at phracturedblue.com>
Date: Wed Jan 13 08:18:46 2010 -0800
Implement OleCreatePropertyFrame and OleCreatePropertyFrameIndirect
Adds recomended fixes from Piotr Caban
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..5a4d5b8
--- /dev/null
+++ b/dlls/oleaut32/olepropframe.c
@@ -0,0 +1,364 @@
+/*
+ * 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 <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <ctype.h>
+
+#define COBJMACROS
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+
+#include "winerror.h"
+#include "windef.h"
+#include "winbase.h"
+#include "winnls.h"
+#include "winreg.h"
+#include "wingdi.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:
+ TRACE("(%p, %s, %s)\n", hwnd, "WM_NOTIFY", "PSN_APPLY");
+ IPropertyPage_Apply(opf->propPage);
+ return TRUE;
+ default:
+ TRACE("(%p, %s, %d)\n", hwnd, "WM_NOTIFY", nmhdr->code);
+ return FALSE;
+ }
+ }
+ default:
+ TRACE("(%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;
+ TRACE("(%p)->(ref=%d)\n", this, this->ref);
+
+ /* Decrease the reference count for current interface */
+ return InterlockedDecrement(&this->ref);
+}
+
+static HRESULT WINAPI PPS_QueryInterface(
+ IPropertyPageSite* iface,
+ REFIID riid,
+ void** ppvObject)
+{
+ TRACE("(%p) riid: %s\n",iface, debugstr_guid(riid));
+
+ if(ppvObject == NULL)
+ return E_INVALIDARG;
+
+ if(IsEqualGUID(&IID_IUnknown, riid)
+ || IsEqualGUID(&IID_IPropertyPageSite, riid))
+ {
+ *ppvObject = iface;
+ } else {
+ *ppvObject = NULL;
+ 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
+};
+
+/* This function implements the inverse of MapDialogRect */
+static void pixels_to_dialog_units(short *x_pixels, short *y_pixels, int *basex, int *basey)
+{
+ /* This was expected to work but didn't:
+ * LONG baseunits = GetDialogBaseUnits();
+ * basex = LOWORD(baseunits);
+ * basey = HIWORD(baseunits);
+ */
+
+ if(! *basex || ! *basey) {
+ HFONT font = GetStockObject(DEFAULT_GUI_FONT);
+ HDC hdc = GetDC(NULL);
+ TEXTMETRICW tm;
+ SIZE size;
+
+ font = SelectObject(hdc, font);
+ GetTextMetricsW(hdc, &tm);
+ GetTextExtentPoint32A(hdc, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz", 52, &size);
+ SelectObject(hdc, font);
+
+ *basex = ((float)size.cx/26+1)/2;
+ *basey = tm.tmHeight;
+ TRACE("Computed basex=%d, basey=%d\n", *basex, *basey);
+ }
+
+ *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;
+ int basex, basey;
+
+ 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);
+
+ if(lpParams->dispidInitialProperty) {
+ FIXME("dispidInitialProperty is not yet implemented\n");
+ }
+
+ 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,
+ &basex, &basey);
+ psp.u.pResource = (DLGTEMPLATE *)&opf[page].dialog;
+ psp.lParam = (LPARAM) &opf[page];
+ psp.pszTitle = pPageInfo.pszTitle;
+ hpsp[propSheet.nPages++] = CreatePropertySheetPageW(&psp);
+ }
+ result = PropertySheetW(&propSheet);
+
+ for(page = 0; page < lpParams->cPages; page++) {
+ if(opf[page].propPage) {
+ IPropertyPage_SetPageSite(opf[page].propPage, NULL);
+ IPropertyPage_Release(opf[page].propPage);
+ }
+ }
+ 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;
-}
More information about the wine-patches
mailing list