mfplat: Read queue subscriber within the critical section.
[wine/zf.git] / dlls / oleaut32 / olepropframe.c
bloba351d73d46870463df1f939d6a28554d967cad57
1 /*
2 * Copyright 1999 Corel Corporation
3 * Sean Langley
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
22 #include <stdarg.h>
24 #define COBJMACROS
25 #define NONAMELESSUNION
27 #include "windef.h"
28 #include "winbase.h"
29 #include "wingdi.h"
30 #include "ole2.h"
31 #include "olectl.h"
32 #include "oledlg.h"
33 #include "wine/debug.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(ole);
37 typedef struct {
38 IPropertyPageSite IPropertyPageSite_iface;
39 LCID lcid;
40 LONG ref;
41 } PropertyPageSite;
43 static inline PropertyPageSite *impl_from_IPropertyPageSite(IPropertyPageSite *iface)
45 return CONTAINING_RECORD(iface, PropertyPageSite, IPropertyPageSite_iface);
48 static INT_PTR CALLBACK property_sheet_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
50 IPropertyPage *property_page = (IPropertyPage*)GetWindowLongPtrW(hwnd, DWLP_USER);
52 switch(msg) {
53 case WM_INITDIALOG: {
54 RECT rect;
56 property_page = (IPropertyPage*)((LPPROPSHEETPAGEW)lparam)->lParam;
58 GetClientRect(hwnd, &rect);
59 IPropertyPage_Activate(property_page, hwnd, &rect, TRUE);
60 IPropertyPage_Show(property_page, SW_SHOW);
62 SetWindowLongPtrW(hwnd, DWLP_USER, (LONG_PTR)property_page);
63 return FALSE;
65 case WM_DESTROY:
66 IPropertyPage_Show(property_page, SW_HIDE);
67 IPropertyPage_Deactivate(property_page);
68 return FALSE;
69 default:
70 return FALSE;
74 static HRESULT WINAPI PropertyPageSite_QueryInterface(IPropertyPageSite* iface,
75 REFIID riid, void** ppv)
77 TRACE("(%p riid: %s)\n",iface, debugstr_guid(riid));
79 if(IsEqualGUID(&IID_IUnknown, riid)
80 || IsEqualGUID(&IID_IPropertyPageSite, riid))
81 *ppv = iface;
82 else {
83 *ppv = NULL;
84 return E_NOINTERFACE;
87 IUnknown_AddRef((IUnknown*)*ppv);
88 return S_OK;
91 static ULONG WINAPI PropertyPageSite_AddRef(IPropertyPageSite* iface)
93 PropertyPageSite *this = impl_from_IPropertyPageSite(iface);
94 LONG ref = InterlockedIncrement(&this->ref);
96 TRACE("(%p) ref=%d\n", this, ref);
97 return ref;
100 static ULONG WINAPI PropertyPageSite_Release(IPropertyPageSite* iface)
102 PropertyPageSite *this = impl_from_IPropertyPageSite(iface);
103 LONG ref = InterlockedDecrement(&this->ref);
105 TRACE("(%p) ref=%d\n", this, ref);
106 if(!ref)
107 HeapFree(GetProcessHeap(), 0, this);
108 return ref;
111 static HRESULT WINAPI PropertyPageSite_OnStatusChange(
112 IPropertyPageSite *iface, DWORD dwFlags)
114 TRACE("(%p, %x)\n", iface, dwFlags);
115 return S_OK;
118 static HRESULT WINAPI PropertyPageSite_GetLocaleID(
119 IPropertyPageSite *iface, LCID *pLocaleID)
121 PropertyPageSite *this = impl_from_IPropertyPageSite(iface);
123 TRACE("(%p, %p)\n", iface, pLocaleID);
124 *pLocaleID = this->lcid;
125 return S_OK;
128 static HRESULT WINAPI PropertyPageSite_GetPageContainer(
129 IPropertyPageSite* iface, IUnknown** ppUnk)
131 FIXME("(%p, %p)\n", iface, ppUnk);
132 return E_NOTIMPL;
135 static HRESULT WINAPI PropertyPageSite_TranslateAccelerator(
136 IPropertyPageSite* iface, MSG *pMsg)
138 FIXME("(%p, %p)\n", iface, pMsg);
139 return E_NOTIMPL;
142 static IPropertyPageSiteVtbl PropertyPageSiteVtbl = {
143 PropertyPageSite_QueryInterface,
144 PropertyPageSite_AddRef,
145 PropertyPageSite_Release,
146 PropertyPageSite_OnStatusChange,
147 PropertyPageSite_GetLocaleID,
148 PropertyPageSite_GetPageContainer,
149 PropertyPageSite_TranslateAccelerator
152 /***********************************************************************
153 * OleCreatePropertyFrameIndirect (OLEAUT32.416)
155 HRESULT WINAPI OleCreatePropertyFrameIndirect(LPOCPFIPARAMS lpParams)
157 PROPSHEETHEADERW property_sheet;
158 PROPSHEETPAGEW property_sheet_page;
159 struct {
160 DLGTEMPLATE template;
161 WORD menu;
162 WORD class;
163 WORD title;
164 } *dialogs;
165 IPropertyPage **property_page;
166 PropertyPageSite *property_page_site;
167 HRESULT res;
168 ULONG i;
169 HMODULE hcomctl;
170 HRSRC property_sheet_dialog_find = NULL;
171 HGLOBAL property_sheet_dialog_load = NULL;
172 WCHAR *property_sheet_dialog_data = NULL;
173 HDC hdc;
174 LOGFONTW font_desc;
175 HFONT hfont;
176 LONG font_width = 4, font_height = 8;
178 if(!lpParams)
179 return E_POINTER;
181 TRACE("(%d %p %d %d %s %d %p %d %p %d %d)\n", lpParams->cbStructSize,
182 lpParams->hWndOwner, lpParams->x, lpParams->y,
183 debugstr_w(lpParams->lpszCaption), lpParams->cObjects,
184 lpParams->lplpUnk, lpParams->cPages, lpParams->lpPages,
185 lpParams->lcid, lpParams->dispidInitialProperty);
187 if(!lpParams->lpPages)
188 return E_POINTER;
190 if(lpParams->cbStructSize != sizeof(OCPFIPARAMS)) {
191 WARN("incorrect structure size\n");
192 return E_INVALIDARG;
195 if(lpParams->dispidInitialProperty)
196 FIXME("dispidInitialProperty not yet implemented\n");
198 hdc = GetDC(NULL);
199 hcomctl = LoadLibraryW(L"comctl32.dll");
200 if(hcomctl)
201 property_sheet_dialog_find = FindResourceW(hcomctl,
202 MAKEINTRESOURCEW(1006 /*IDD_PROPSHEET*/), (LPWSTR)RT_DIALOG);
203 if(property_sheet_dialog_find)
204 property_sheet_dialog_load = LoadResource(hcomctl, property_sheet_dialog_find);
205 if(property_sheet_dialog_load)
206 property_sheet_dialog_data = LockResource(property_sheet_dialog_load);
208 if(property_sheet_dialog_data) {
209 if(property_sheet_dialog_data[1] == 0xffff) {
210 ERR("Expected DLGTEMPLATE structure\n");
211 FreeLibrary(hcomctl);
212 return E_OUTOFMEMORY;
215 property_sheet_dialog_data += sizeof(DLGTEMPLATE)/sizeof(WCHAR);
216 /* Skip menu, class and title */
217 property_sheet_dialog_data += lstrlenW(property_sheet_dialog_data)+1;
218 property_sheet_dialog_data += lstrlenW(property_sheet_dialog_data)+1;
219 property_sheet_dialog_data += lstrlenW(property_sheet_dialog_data)+1;
221 memset(&font_desc, 0, sizeof(LOGFONTW));
222 /* Calculate logical height */
223 font_desc.lfHeight = -MulDiv(property_sheet_dialog_data[0],
224 GetDeviceCaps(hdc, LOGPIXELSY), 72);
225 font_desc.lfCharSet = DEFAULT_CHARSET;
226 memcpy(font_desc.lfFaceName, property_sheet_dialog_data+1,
227 sizeof(WCHAR)*(lstrlenW(property_sheet_dialog_data+1)+1));
228 hfont = CreateFontIndirectW(&font_desc);
230 if(hfont) {
231 hfont = SelectObject(hdc, hfont);
232 font_width = GdiGetCharDimensions(hdc, NULL, &font_height);
233 SelectObject(hdc, hfont);
236 if(hcomctl)
237 FreeLibrary(hcomctl);
238 ReleaseDC(NULL, hdc);
240 memset(&property_sheet, 0, sizeof(property_sheet));
241 property_sheet.dwSize = sizeof(property_sheet);
242 if(lpParams->lpszCaption) {
243 property_sheet.dwFlags = PSH_PROPTITLE;
244 property_sheet.pszCaption = lpParams->lpszCaption;
247 property_sheet.u3.phpage = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
248 lpParams->cPages*sizeof(HPROPSHEETPAGE));
249 property_page = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
250 lpParams->cPages*sizeof(IPropertyPage*));
251 dialogs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
252 lpParams->cPages*sizeof(*dialogs));
253 if(!property_sheet.u3.phpage || !property_page || !dialogs) {
254 HeapFree(GetProcessHeap(), 0, property_sheet.u3.phpage);
255 HeapFree(GetProcessHeap(), 0, property_page);
256 HeapFree(GetProcessHeap(), 0, dialogs);
257 return E_OUTOFMEMORY;
260 memset(&property_sheet_page, 0, sizeof(PROPSHEETPAGEW));
261 property_sheet_page.dwSize = sizeof(PROPSHEETPAGEW);
262 property_sheet_page.dwFlags = PSP_DLGINDIRECT|PSP_USETITLE;
263 property_sheet_page.pfnDlgProc = property_sheet_proc;
265 for(i=0; i<lpParams->cPages; i++) {
266 PROPPAGEINFO page_info;
268 res = CoCreateInstance(&lpParams->lpPages[i], NULL, CLSCTX_INPROC_SERVER,
269 &IID_IPropertyPage, (void**)&property_page[i]);
270 if(FAILED(res))
271 continue;
273 property_page_site = HeapAlloc(GetProcessHeap(), 0, sizeof(PropertyPageSite));
274 if(!property_page_site)
275 continue;
276 property_page_site->IPropertyPageSite_iface.lpVtbl = &PropertyPageSiteVtbl;
277 property_page_site->ref = 1;
278 property_page_site->lcid = lpParams->lcid;
280 res = IPropertyPage_SetPageSite(property_page[i],
281 &property_page_site->IPropertyPageSite_iface);
282 IPropertyPageSite_Release(&property_page_site->IPropertyPageSite_iface);
283 if(FAILED(res))
284 continue;
286 res = IPropertyPage_SetObjects(property_page[i],
287 lpParams->cObjects, lpParams->lplpUnk);
288 if(FAILED(res))
289 WARN("SetObjects() failed, hr %#x.\n", res);
291 res = IPropertyPage_GetPageInfo(property_page[i], &page_info);
292 if(FAILED(res))
293 continue;
295 dialogs[i].template.cx = MulDiv(page_info.size.cx, 4, font_width);
296 dialogs[i].template.cy = MulDiv(page_info.size.cy, 8, font_height);
298 property_sheet_page.u.pResource = &dialogs[i].template;
299 property_sheet_page.lParam = (LPARAM)property_page[i];
300 property_sheet_page.pszTitle = page_info.pszTitle;
302 property_sheet.u3.phpage[property_sheet.nPages++] =
303 CreatePropertySheetPageW(&property_sheet_page);
306 PropertySheetW(&property_sheet);
308 for(i=0; i<lpParams->cPages; i++) {
309 if(property_page[i])
310 IPropertyPage_Release(property_page[i]);
313 HeapFree(GetProcessHeap(), 0, dialogs);
314 HeapFree(GetProcessHeap(), 0, property_page);
315 HeapFree(GetProcessHeap(), 0, property_sheet.u3.phpage);
316 return S_OK;
319 /***********************************************************************
320 * OleCreatePropertyFrame (OLEAUT32.417)
322 HRESULT WINAPI OleCreatePropertyFrame(
323 HWND hwndOwner, UINT x, UINT y, LPCOLESTR lpszCaption, ULONG cObjects,
324 LPUNKNOWN* ppUnk, ULONG cPages, LPCLSID pPageClsID, LCID lcid,
325 DWORD dwReserved, LPVOID pvReserved)
327 OCPFIPARAMS ocpf;
329 ocpf.cbStructSize = sizeof(OCPFIPARAMS);
330 ocpf.hWndOwner = hwndOwner;
331 ocpf.x = x;
332 ocpf.y = y;
333 ocpf.lpszCaption = lpszCaption;
334 ocpf.cObjects = cObjects;
335 ocpf.lplpUnk = ppUnk;
336 ocpf.cPages = cPages;
337 ocpf.lpPages = pPageClsID;
338 ocpf.lcid = lcid;
339 ocpf.dispidInitialProperty = 0;
341 return OleCreatePropertyFrameIndirect(&ocpf);