Patch feedback requested for OleCreatePropertyFrame()

Geoffrey Hausheer winedevel9605 at phracturedblue.com
Fri Jan 8 00:58:59 CST 2010


Ok, I have reimplemented OleCreatePropertyFrame() from scratch.  There
is no code from Hidenori's patch in mine, nor did I use it as a
reference (though of course I can't claim that I didn't learn anything
from his patch during my previous cleanup)

Would someone mind reviewing this for style/content?  I still have no
idea how to write a test for a modal dialog, so if a test is required
for submission, I'd really appreciate someone giving me pointers on
how to go about it.

There are some features I didn't implement because I didn't really
understand MDSN sufficiently (specifcially the IPropertyPageSite
stuff), but it is mostly complete.

.Geoff
-------------- next part --------------
From 07ca9bda0bd66e53cfbdc441b59fa4bc2e988171 Mon Sep 17 00:00:00 2001
From: Geoffrey Hausheer <winedevel9605 at phracturedblue.com>
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 <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 "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


More information about the wine-devel mailing list