Piotr Caban : oleaut32: Added OleCreatePropertyFrameIndirect implementation .

Alexandre Julliard julliard at winehq.org
Mon Sep 27 11:29:39 CDT 2010


Module: wine
Branch: master
Commit: 9ccbadc9a84251a0e58fe8a51143f6ef89909fd0
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=9ccbadc9a84251a0e58fe8a51143f6ef89909fd0

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Mon Sep 27 12:02:58 2010 +0200

oleaut32: Added OleCreatePropertyFrameIndirect implementation.

Based on patch written by Geoffrey Hausheer.

---

 dlls/oleaut32/olepropframe.c |  232 +++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 229 insertions(+), 3 deletions(-)

diff --git a/dlls/oleaut32/olepropframe.c b/dlls/oleaut32/olepropframe.c
index 23bd9e0..1a82290 100644
--- a/dlls/oleaut32/olepropframe.c
+++ b/dlls/oleaut32/olepropframe.c
@@ -2,6 +2,7 @@
  * Copyright 1999 Corel Corporation
  * Sean Langley
  * Copyright 2010  Geoffrey Hausheer
+ * Copyright 2010 Piotr Caban for Codeweavers
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,20 +21,245 @@
 
 #include <stdarg.h>
 
+#define COBJMACROS
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+
 #include "windef.h"
 #include "winbase.h"
-#include "wine/debug.h"
+#include "wingdi.h"
 #include "ole2.h"
 #include "olectl.h"
+#include "oledlg.h"
+#include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(ole);
 
+typedef struct {
+    const IPropertyPageSiteVtbl *lpVtbl;
+    LCID lcid;
+    LONG ref;
+} PropertyPageSite;
+
+static INT_PTR CALLBACK property_sheet_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
+{
+    IPropertyPage *property_page = (IPropertyPage*)GetWindowLongPtrW(hwnd, DWLP_USER);
+
+    switch(msg) {
+    case WM_INITDIALOG: {
+        RECT rect;
+
+        property_page = (IPropertyPage*)((LPPROPSHEETPAGEW)lparam)->lParam;
+
+        GetClientRect(hwnd, &rect);
+        IPropertyPage_Activate(property_page, hwnd, &rect, TRUE);
+        IPropertyPage_Show(property_page, SW_SHOW);
+
+        SetWindowLongPtrW(hwnd, DWLP_USER, (LONG)property_page);
+        return FALSE;
+    }
+    case WM_DESTROY:
+        IPropertyPage_Show(property_page, SW_HIDE);
+        IPropertyPage_Deactivate(property_page);
+        return FALSE;
+    default:
+        return FALSE;
+    }
+}
+
+static HRESULT WINAPI PropertyPageSite_QueryInterface(IPropertyPageSite*  iface,
+        REFIID  riid, void**  ppv)
+{
+    TRACE("(%p riid: %s)\n",iface, debugstr_guid(riid));
+
+    if(IsEqualGUID(&IID_IUnknown, riid)
+            || IsEqualGUID(&IID_IPropertyPageSite, riid))
+        *ppv = iface;
+    else {
+        *ppv = NULL;
+        return E_NOINTERFACE;
+    }
+
+    IUnknown_AddRef((IUnknown*)*ppv);
+    return S_OK;
+}
+
+static ULONG WINAPI PropertyPageSite_AddRef(IPropertyPageSite* iface)
+{
+    PropertyPageSite *this = (PropertyPageSite*)iface;
+    LONG ref = InterlockedIncrement(&this->ref);
+
+    TRACE("(%p) ref=%d\n", this, ref);
+    return ref;
+}
+
+static ULONG WINAPI PropertyPageSite_Release(IPropertyPageSite* iface)
+{
+    PropertyPageSite *this = (PropertyPageSite *)iface;
+    LONG ref = InterlockedDecrement(&this->ref);
+
+    TRACE("(%p) ref=%d\n", this, ref);
+    if(!ref)
+        HeapFree(GetProcessHeap(), 0, this);
+    return ref;
+}
+
+static HRESULT WINAPI PropertyPageSite_OnStatusChange(
+        IPropertyPageSite *iface, DWORD dwFlags)
+{
+    TRACE("(%p, %x)\n", iface, dwFlags);
+    return S_OK;
+}
+
+static HRESULT WINAPI PropertyPageSite_GetLocaleID(
+        IPropertyPageSite *iface, LCID *pLocaleID)
+{
+    PropertyPageSite *this = (PropertyPageSite *)iface;
+
+    TRACE("(%p, %p)\n", iface, pLocaleID);
+    *pLocaleID = this->lcid;
+    return S_OK;
+}
+
+static HRESULT WINAPI PropertyPageSite_GetPageContainer(
+        IPropertyPageSite* iface, IUnknown** ppUnk)
+{
+    FIXME("(%p, %p)\n", iface, ppUnk);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI PropertyPageSite_TranslateAccelerator(
+        IPropertyPageSite* iface, MSG *pMsg)
+{
+    FIXME("(%p, %p)\n", iface, pMsg);
+    return E_NOTIMPL;
+}
+
+IPropertyPageSiteVtbl PropertyPageSiteVtbl = {
+    PropertyPageSite_QueryInterface,
+    PropertyPageSite_AddRef,
+    PropertyPageSite_Release,
+    PropertyPageSite_OnStatusChange,
+    PropertyPageSite_GetLocaleID,
+    PropertyPageSite_GetPageContainer,
+    PropertyPageSite_TranslateAccelerator
+};
+
 /***********************************************************************
  * OleCreatePropertyFrameIndirect (OLEAUT32.416)
  */
 HRESULT WINAPI OleCreatePropertyFrameIndirect(LPOCPFIPARAMS lpParams)
 {
-    FIXME("(%p), not implemented (olepro32.dll)\n", lpParams);
+    PROPSHEETHEADERW property_sheet;
+    PROPSHEETPAGEW property_sheet_page;
+    struct {
+        DLGTEMPLATE template;
+        WORD menu;
+        WORD class;
+        WORD title;
+    } *dialogs;
+    IPropertyPage **property_page;
+    IPropertyPageSite *property_page_site;
+    HRESULT res;
+    int i;
+
+    if(!lpParams)
+        return E_POINTER;
+
+    TRACE("(%d %p %d %d %s %d %p %d %p %d %d)\n", lpParams->cbStructSize,
+            lpParams->hWndOwner, lpParams->x, lpParams->y,
+            debugstr_w(lpParams->lpszCaption), lpParams->cObjects,
+            lpParams->lplpUnk, lpParams->cPages, lpParams->lpPages,
+            lpParams->lcid, lpParams->dispidInitialProperty);
+
+    if(!lpParams->lplpUnk || !lpParams->lpPages)
+        return E_POINTER;
+
+    if(lpParams->cbStructSize != sizeof(OCPFIPARAMS)) {
+        WARN("incorrect structure size\n");
+        return E_INVALIDARG;
+    }
+
+    if(lpParams->dispidInitialProperty)
+        FIXME("dispidInitialProperty not yet implemented\n");
+
+    memset(&property_sheet, 0, sizeof(property_sheet));
+    property_sheet.dwSize = sizeof(property_sheet);
+    if(lpParams->lpszCaption) {
+        property_sheet.dwFlags = PSH_PROPTITLE;
+        property_sheet.pszCaption = lpParams->lpszCaption;
+    }
+
+    property_sheet.u3.phpage = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+            lpParams->cPages*sizeof(HPROPSHEETPAGE));
+    property_page = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+            lpParams->cPages*sizeof(IPropertyPage*));
+    dialogs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+            lpParams->cPages*sizeof(*dialogs));
+    if(!property_sheet.u3.phpage || !property_page || !dialogs) {
+        HeapFree(GetProcessHeap(), 0, property_sheet.u3.phpage);
+        HeapFree(GetProcessHeap(), 0, property_page);
+        HeapFree(GetProcessHeap(), 0, dialogs);
+        return E_OUTOFMEMORY;
+    }
+
+    memset(&property_sheet_page, 0, sizeof(PROPSHEETPAGEW));
+    property_sheet_page.dwSize = sizeof(PROPSHEETPAGEW);
+    property_sheet_page.dwFlags = PSP_DLGINDIRECT|PSP_USETITLE;
+    property_sheet_page.pfnDlgProc = property_sheet_proc;
+
+    for(i=0; i<lpParams->cPages; i++) {
+        PROPPAGEINFO page_info;
+
+        res = CoCreateInstance(&lpParams->lpPages[i], NULL, CLSCTX_INPROC_SERVER,
+                &IID_IPropertyPage, (void**)&property_page[i]);
+        if(FAILED(res))
+            continue;
+
+        property_page_site = HeapAlloc(GetProcessHeap(), 0, sizeof(PropertyPageSite));
+        if(!property_page_site)
+            continue;
+        ((PropertyPageSite*)property_page_site)->lpVtbl = &PropertyPageSiteVtbl;
+        ((PropertyPageSite*)property_page_site)->ref = 1;
+        ((PropertyPageSite*)property_page_site)->lcid = lpParams->lcid;
+
+        res = IPropertyPage_SetPageSite(property_page[i], property_page_site);
+        IPropertyPageSite_Release(property_page_site);
+        if(FAILED(res))
+            continue;
+
+        res = IPropertyPage_SetObjects(property_page[i],
+                lpParams->cObjects, lpParams->lplpUnk);
+        if(FAILED(res))
+            continue;
+
+        res = IPropertyPage_GetPageInfo(property_page[i], &page_info);
+        if(FAILED(res))
+            continue;
+
+        dialogs[i].template.cx = page_info.size.cx;
+        dialogs[i].template.cy = page_info.size.cy;
+
+        property_sheet_page.u.pResource = &dialogs[i].template;
+        property_sheet_page.lParam = (LPARAM)property_page[i];
+        property_sheet_page.pszTitle = page_info.pszTitle;
+
+        property_sheet.u3.phpage[property_sheet.nPages++] =
+            CreatePropertySheetPageW(&property_sheet_page);
+    }
+
+    PropertySheetW(&property_sheet);
+
+    for(i=0; i<lpParams->cPages; i++) {
+        if(property_page[i]) {
+            IPropertyPage_SetPageSite(property_page[i], NULL);
+            IPropertyPage_Release(property_page[i]);
+        }
+    }
+
+    HeapFree(GetProcessHeap(), 0, dialogs);
+    HeapFree(GetProcessHeap(), 0, property_page);
+    HeapFree(GetProcessHeap(), 0, property_sheet.u3.phpage);
     return S_OK;
 }
 
@@ -41,7 +267,7 @@ HRESULT WINAPI OleCreatePropertyFrameIndirect(LPOCPFIPARAMS lpParams)
  * OleCreatePropertyFrame (OLEAUT32.417)
  */
 HRESULT WINAPI OleCreatePropertyFrame(
-        HWND hwndOwner, UINT x, UINT y, LPCOLESTR lpszCaption,ULONG cObjects,
+        HWND hwndOwner, UINT x, UINT y, LPCOLESTR lpszCaption, ULONG cObjects,
         LPUNKNOWN* ppUnk, ULONG cPages, LPCLSID pPageClsID, LCID lcid,
         DWORD dwReserved, LPVOID pvReserved)
 {




More information about the wine-cvs mailing list