2 * Copyright 1999 Corel Corporation
4 * Copyright 2010 Geoffrey Hausheer
5 * Copyright 2010 Piotr Caban for CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #define NONAMELESSUNION
26 #define NONAMELESSSTRUCT
34 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
39 IPropertyPageSite IPropertyPageSite_iface
;
44 static inline PropertyPageSite
*impl_from_IPropertyPageSite(IPropertyPageSite
*iface
)
46 return CONTAINING_RECORD(iface
, PropertyPageSite
, IPropertyPageSite_iface
);
49 static INT_PTR CALLBACK
property_sheet_proc(HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
51 IPropertyPage
*property_page
= (IPropertyPage
*)GetWindowLongPtrW(hwnd
, DWLP_USER
);
57 property_page
= (IPropertyPage
*)((LPPROPSHEETPAGEW
)lparam
)->lParam
;
59 GetClientRect(hwnd
, &rect
);
60 IPropertyPage_Activate(property_page
, hwnd
, &rect
, TRUE
);
61 IPropertyPage_Show(property_page
, SW_SHOW
);
63 SetWindowLongPtrW(hwnd
, DWLP_USER
, (LONG_PTR
)property_page
);
67 IPropertyPage_Show(property_page
, SW_HIDE
);
68 IPropertyPage_Deactivate(property_page
);
75 static HRESULT WINAPI
PropertyPageSite_QueryInterface(IPropertyPageSite
* iface
,
76 REFIID riid
, void** ppv
)
78 TRACE("(%p riid: %s)\n",iface
, debugstr_guid(riid
));
80 if(IsEqualGUID(&IID_IUnknown
, riid
)
81 || IsEqualGUID(&IID_IPropertyPageSite
, riid
))
88 IUnknown_AddRef((IUnknown
*)*ppv
);
92 static ULONG WINAPI
PropertyPageSite_AddRef(IPropertyPageSite
* iface
)
94 PropertyPageSite
*this = impl_from_IPropertyPageSite(iface
);
95 LONG ref
= InterlockedIncrement(&this->ref
);
97 TRACE("(%p) ref=%d\n", this, ref
);
101 static ULONG WINAPI
PropertyPageSite_Release(IPropertyPageSite
* iface
)
103 PropertyPageSite
*this = impl_from_IPropertyPageSite(iface
);
104 LONG ref
= InterlockedDecrement(&this->ref
);
106 TRACE("(%p) ref=%d\n", this, ref
);
108 HeapFree(GetProcessHeap(), 0, this);
112 static HRESULT WINAPI
PropertyPageSite_OnStatusChange(
113 IPropertyPageSite
*iface
, DWORD dwFlags
)
115 TRACE("(%p, %x)\n", iface
, dwFlags
);
119 static HRESULT WINAPI
PropertyPageSite_GetLocaleID(
120 IPropertyPageSite
*iface
, LCID
*pLocaleID
)
122 PropertyPageSite
*this = impl_from_IPropertyPageSite(iface
);
124 TRACE("(%p, %p)\n", iface
, pLocaleID
);
125 *pLocaleID
= this->lcid
;
129 static HRESULT WINAPI
PropertyPageSite_GetPageContainer(
130 IPropertyPageSite
* iface
, IUnknown
** ppUnk
)
132 FIXME("(%p, %p)\n", iface
, ppUnk
);
136 static HRESULT WINAPI
PropertyPageSite_TranslateAccelerator(
137 IPropertyPageSite
* iface
, MSG
*pMsg
)
139 FIXME("(%p, %p)\n", iface
, pMsg
);
143 IPropertyPageSiteVtbl PropertyPageSiteVtbl
= {
144 PropertyPageSite_QueryInterface
,
145 PropertyPageSite_AddRef
,
146 PropertyPageSite_Release
,
147 PropertyPageSite_OnStatusChange
,
148 PropertyPageSite_GetLocaleID
,
149 PropertyPageSite_GetPageContainer
,
150 PropertyPageSite_TranslateAccelerator
153 /***********************************************************************
154 * OleCreatePropertyFrameIndirect (OLEAUT32.416)
156 HRESULT WINAPI
OleCreatePropertyFrameIndirect(LPOCPFIPARAMS lpParams
)
158 static const WCHAR comctlW
[] = { 'c','o','m','c','t','l','3','2','.','d','l','l',0 };
160 PROPSHEETHEADERW property_sheet
;
161 PROPSHEETPAGEW property_sheet_page
;
163 DLGTEMPLATE
template;
168 IPropertyPage
**property_page
;
169 PropertyPageSite
*property_page_site
;
173 HRSRC property_sheet_dialog_find
= NULL
;
174 HGLOBAL property_sheet_dialog_load
= NULL
;
175 WCHAR
*property_sheet_dialog_data
= NULL
;
179 LONG font_width
= 4, font_height
= 8;
184 TRACE("(%d %p %d %d %s %d %p %d %p %d %d)\n", lpParams
->cbStructSize
,
185 lpParams
->hWndOwner
, lpParams
->x
, lpParams
->y
,
186 debugstr_w(lpParams
->lpszCaption
), lpParams
->cObjects
,
187 lpParams
->lplpUnk
, lpParams
->cPages
, lpParams
->lpPages
,
188 lpParams
->lcid
, lpParams
->dispidInitialProperty
);
190 if(!lpParams
->lplpUnk
|| !lpParams
->lpPages
)
193 if(lpParams
->cbStructSize
!= sizeof(OCPFIPARAMS
)) {
194 WARN("incorrect structure size\n");
198 if(lpParams
->dispidInitialProperty
)
199 FIXME("dispidInitialProperty not yet implemented\n");
202 hcomctl
= LoadLibraryW(comctlW
);
204 property_sheet_dialog_find
= FindResourceW(hcomctl
,
205 MAKEINTRESOURCEW(1006 /*IDD_PROPSHEET*/), (LPWSTR
)RT_DIALOG
);
206 if(property_sheet_dialog_find
)
207 property_sheet_dialog_load
= LoadResource(hcomctl
, property_sheet_dialog_find
);
208 if(property_sheet_dialog_load
)
209 property_sheet_dialog_data
= LockResource(property_sheet_dialog_load
);
211 if(property_sheet_dialog_data
) {
212 if(property_sheet_dialog_data
[1] == 0xffff) {
213 ERR("Expected DLGTEMPLATE structure\n");
214 return E_OUTOFMEMORY
;
217 property_sheet_dialog_data
+= sizeof(DLGTEMPLATE
)/sizeof(WCHAR
);
218 /* Skip menu, class and title */
219 property_sheet_dialog_data
+= lstrlenW(property_sheet_dialog_data
)+1;
220 property_sheet_dialog_data
+= lstrlenW(property_sheet_dialog_data
)+1;
221 property_sheet_dialog_data
+= lstrlenW(property_sheet_dialog_data
)+1;
223 memset(&font_desc
, 0, sizeof(LOGFONTW
));
224 /* Calculate logical height */
225 font_desc
.lfHeight
= -MulDiv(property_sheet_dialog_data
[0],
226 GetDeviceCaps(hdc
, LOGPIXELSY
), 72);
227 font_desc
.lfCharSet
= DEFAULT_CHARSET
;
228 memcpy(font_desc
.lfFaceName
, property_sheet_dialog_data
+1,
229 sizeof(WCHAR
)*(lstrlenW(property_sheet_dialog_data
+1)+1));
230 hfont
= CreateFontIndirectW(&font_desc
);
233 hfont
= SelectObject(hdc
, hfont
);
234 font_width
= GdiGetCharDimensions(hdc
, NULL
, &font_height
);
235 SelectObject(hdc
, hfont
);
239 FreeLibrary(hcomctl
);
240 ReleaseDC(NULL
, hdc
);
242 memset(&property_sheet
, 0, sizeof(property_sheet
));
243 property_sheet
.dwSize
= sizeof(property_sheet
);
244 if(lpParams
->lpszCaption
) {
245 property_sheet
.dwFlags
= PSH_PROPTITLE
;
246 property_sheet
.pszCaption
= lpParams
->lpszCaption
;
249 property_sheet
.u3
.phpage
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
250 lpParams
->cPages
*sizeof(HPROPSHEETPAGE
));
251 property_page
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
252 lpParams
->cPages
*sizeof(IPropertyPage
*));
253 dialogs
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
254 lpParams
->cPages
*sizeof(*dialogs
));
255 if(!property_sheet
.u3
.phpage
|| !property_page
|| !dialogs
) {
256 HeapFree(GetProcessHeap(), 0, property_sheet
.u3
.phpage
);
257 HeapFree(GetProcessHeap(), 0, property_page
);
258 HeapFree(GetProcessHeap(), 0, dialogs
);
259 return E_OUTOFMEMORY
;
262 memset(&property_sheet_page
, 0, sizeof(PROPSHEETPAGEW
));
263 property_sheet_page
.dwSize
= sizeof(PROPSHEETPAGEW
);
264 property_sheet_page
.dwFlags
= PSP_DLGINDIRECT
|PSP_USETITLE
;
265 property_sheet_page
.pfnDlgProc
= property_sheet_proc
;
267 for(i
=0; i
<lpParams
->cPages
; i
++) {
268 PROPPAGEINFO page_info
;
270 res
= CoCreateInstance(&lpParams
->lpPages
[i
], NULL
, CLSCTX_INPROC_SERVER
,
271 &IID_IPropertyPage
, (void**)&property_page
[i
]);
275 property_page_site
= HeapAlloc(GetProcessHeap(), 0, sizeof(PropertyPageSite
));
276 if(!property_page_site
)
278 property_page_site
->IPropertyPageSite_iface
.lpVtbl
= &PropertyPageSiteVtbl
;
279 property_page_site
->ref
= 1;
280 property_page_site
->lcid
= lpParams
->lcid
;
282 res
= IPropertyPage_SetPageSite(property_page
[i
],
283 &property_page_site
->IPropertyPageSite_iface
);
284 IPropertyPageSite_Release(&property_page_site
->IPropertyPageSite_iface
);
288 res
= IPropertyPage_SetObjects(property_page
[i
],
289 lpParams
->cObjects
, lpParams
->lplpUnk
);
293 res
= IPropertyPage_GetPageInfo(property_page
[i
], &page_info
);
297 dialogs
[i
].template.cx
= MulDiv(page_info
.size
.cx
, 4, font_width
);
298 dialogs
[i
].template.cy
= MulDiv(page_info
.size
.cy
, 8, font_height
);
300 property_sheet_page
.u
.pResource
= &dialogs
[i
].template;
301 property_sheet_page
.lParam
= (LPARAM
)property_page
[i
];
302 property_sheet_page
.pszTitle
= page_info
.pszTitle
;
304 property_sheet
.u3
.phpage
[property_sheet
.nPages
++] =
305 CreatePropertySheetPageW(&property_sheet_page
);
308 PropertySheetW(&property_sheet
);
310 for(i
=0; i
<lpParams
->cPages
; i
++) {
311 if(property_page
[i
]) {
312 IPropertyPage_SetPageSite(property_page
[i
], NULL
);
313 IPropertyPage_Release(property_page
[i
]);
317 HeapFree(GetProcessHeap(), 0, dialogs
);
318 HeapFree(GetProcessHeap(), 0, property_page
);
319 HeapFree(GetProcessHeap(), 0, property_sheet
.u3
.phpage
);
323 /***********************************************************************
324 * OleCreatePropertyFrame (OLEAUT32.417)
326 HRESULT WINAPI
OleCreatePropertyFrame(
327 HWND hwndOwner
, UINT x
, UINT y
, LPCOLESTR lpszCaption
, ULONG cObjects
,
328 LPUNKNOWN
* ppUnk
, ULONG cPages
, LPCLSID pPageClsID
, LCID lcid
,
329 DWORD dwReserved
, LPVOID pvReserved
)
333 ocpf
.cbStructSize
= sizeof(OCPFIPARAMS
);
334 ocpf
.hWndOwner
= hwndOwner
;
337 ocpf
.lpszCaption
= lpszCaption
;
338 ocpf
.cObjects
= cObjects
;
339 ocpf
.lplpUnk
= ppUnk
;
340 ocpf
.cPages
= cPages
;
341 ocpf
.lpPages
= pPageClsID
;
343 ocpf
.dispidInitialProperty
= 0;
345 return OleCreatePropertyFrameIndirect(&ocpf
);