widl: Don't force removal of progids since "CLSID" is also a progid.
[wine.git] / dlls / oleaut32 / olepropframe.c
blob011fde1f50253dce5b2abde5a6f73286c3f83810
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
26 #define NONAMELESSSTRUCT
28 #include "windef.h"
29 #include "winbase.h"
30 #include "wingdi.h"
31 #include "ole2.h"
32 #include "olectl.h"
33 #include "oledlg.h"
34 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(ole);
38 typedef struct {
39 const IPropertyPageSiteVtbl *lpVtbl;
40 LCID lcid;
41 LONG ref;
42 } PropertyPageSite;
44 static INT_PTR CALLBACK property_sheet_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
46 IPropertyPage *property_page = (IPropertyPage*)GetWindowLongPtrW(hwnd, DWLP_USER);
48 switch(msg) {
49 case WM_INITDIALOG: {
50 RECT rect;
52 property_page = (IPropertyPage*)((LPPROPSHEETPAGEW)lparam)->lParam;
54 GetClientRect(hwnd, &rect);
55 IPropertyPage_Activate(property_page, hwnd, &rect, TRUE);
56 IPropertyPage_Show(property_page, SW_SHOW);
58 SetWindowLongPtrW(hwnd, DWLP_USER, (LONG_PTR)property_page);
59 return FALSE;
61 case WM_DESTROY:
62 IPropertyPage_Show(property_page, SW_HIDE);
63 IPropertyPage_Deactivate(property_page);
64 return FALSE;
65 default:
66 return FALSE;
70 static HRESULT WINAPI PropertyPageSite_QueryInterface(IPropertyPageSite* iface,
71 REFIID riid, void** ppv)
73 TRACE("(%p riid: %s)\n",iface, debugstr_guid(riid));
75 if(IsEqualGUID(&IID_IUnknown, riid)
76 || IsEqualGUID(&IID_IPropertyPageSite, riid))
77 *ppv = iface;
78 else {
79 *ppv = NULL;
80 return E_NOINTERFACE;
83 IUnknown_AddRef((IUnknown*)*ppv);
84 return S_OK;
87 static ULONG WINAPI PropertyPageSite_AddRef(IPropertyPageSite* iface)
89 PropertyPageSite *this = (PropertyPageSite*)iface;
90 LONG ref = InterlockedIncrement(&this->ref);
92 TRACE("(%p) ref=%d\n", this, ref);
93 return ref;
96 static ULONG WINAPI PropertyPageSite_Release(IPropertyPageSite* iface)
98 PropertyPageSite *this = (PropertyPageSite *)iface;
99 LONG ref = InterlockedDecrement(&this->ref);
101 TRACE("(%p) ref=%d\n", this, ref);
102 if(!ref)
103 HeapFree(GetProcessHeap(), 0, this);
104 return ref;
107 static HRESULT WINAPI PropertyPageSite_OnStatusChange(
108 IPropertyPageSite *iface, DWORD dwFlags)
110 TRACE("(%p, %x)\n", iface, dwFlags);
111 return S_OK;
114 static HRESULT WINAPI PropertyPageSite_GetLocaleID(
115 IPropertyPageSite *iface, LCID *pLocaleID)
117 PropertyPageSite *this = (PropertyPageSite *)iface;
119 TRACE("(%p, %p)\n", iface, pLocaleID);
120 *pLocaleID = this->lcid;
121 return S_OK;
124 static HRESULT WINAPI PropertyPageSite_GetPageContainer(
125 IPropertyPageSite* iface, IUnknown** ppUnk)
127 FIXME("(%p, %p)\n", iface, ppUnk);
128 return E_NOTIMPL;
131 static HRESULT WINAPI PropertyPageSite_TranslateAccelerator(
132 IPropertyPageSite* iface, MSG *pMsg)
134 FIXME("(%p, %p)\n", iface, pMsg);
135 return E_NOTIMPL;
138 IPropertyPageSiteVtbl PropertyPageSiteVtbl = {
139 PropertyPageSite_QueryInterface,
140 PropertyPageSite_AddRef,
141 PropertyPageSite_Release,
142 PropertyPageSite_OnStatusChange,
143 PropertyPageSite_GetLocaleID,
144 PropertyPageSite_GetPageContainer,
145 PropertyPageSite_TranslateAccelerator
148 /***********************************************************************
149 * OleCreatePropertyFrameIndirect (OLEAUT32.416)
151 HRESULT WINAPI OleCreatePropertyFrameIndirect(LPOCPFIPARAMS lpParams)
153 static const WCHAR comctlW[] = { 'c','o','m','c','t','l','3','2','.','d','l','l',0 };
155 PROPSHEETHEADERW property_sheet;
156 PROPSHEETPAGEW property_sheet_page;
157 struct {
158 DLGTEMPLATE template;
159 WORD menu;
160 WORD class;
161 WORD title;
162 } *dialogs;
163 IPropertyPage **property_page;
164 IPropertyPageSite *property_page_site;
165 HRESULT res;
166 int i;
167 HMODULE hcomctl;
168 HRSRC property_sheet_dialog_find = NULL;
169 HGLOBAL property_sheet_dialog_load = NULL;
170 WCHAR *property_sheet_dialog_data = NULL;
171 HDC hdc;
172 LOGFONTW font_desc;
173 HFONT hfont;
174 LONG font_width = 4, font_height = 8;
176 if(!lpParams)
177 return E_POINTER;
179 TRACE("(%d %p %d %d %s %d %p %d %p %d %d)\n", lpParams->cbStructSize,
180 lpParams->hWndOwner, lpParams->x, lpParams->y,
181 debugstr_w(lpParams->lpszCaption), lpParams->cObjects,
182 lpParams->lplpUnk, lpParams->cPages, lpParams->lpPages,
183 lpParams->lcid, lpParams->dispidInitialProperty);
185 if(!lpParams->lplpUnk || !lpParams->lpPages)
186 return E_POINTER;
188 if(lpParams->cbStructSize != sizeof(OCPFIPARAMS)) {
189 WARN("incorrect structure size\n");
190 return E_INVALIDARG;
193 if(lpParams->dispidInitialProperty)
194 FIXME("dispidInitialProperty not yet implemented\n");
196 hdc = GetDC(NULL);
197 hcomctl = LoadLibraryW(comctlW);
198 if(hcomctl)
199 property_sheet_dialog_find = FindResourceW(hcomctl,
200 MAKEINTRESOURCEW(1006 /*IDD_PROPSHEET*/), (LPWSTR)RT_DIALOG);
201 if(property_sheet_dialog_find)
202 property_sheet_dialog_load = LoadResource(hcomctl, property_sheet_dialog_find);
203 if(property_sheet_dialog_load)
204 property_sheet_dialog_data = LockResource(property_sheet_dialog_load);
206 if(property_sheet_dialog_data) {
207 if(property_sheet_dialog_data[1] == 0xffff) {
208 ERR("Expected DLGTEMPLATE structure\n");
209 return E_OUTOFMEMORY;
212 property_sheet_dialog_data += sizeof(DLGTEMPLATE)/sizeof(WCHAR);
213 /* Skip menu, class and title */
214 property_sheet_dialog_data += lstrlenW(property_sheet_dialog_data)+1;
215 property_sheet_dialog_data += lstrlenW(property_sheet_dialog_data)+1;
216 property_sheet_dialog_data += lstrlenW(property_sheet_dialog_data)+1;
218 memset(&font_desc, 0, sizeof(LOGFONTW));
219 /* Calculate logical height */
220 font_desc.lfHeight = -MulDiv(property_sheet_dialog_data[0],
221 GetDeviceCaps(hdc, LOGPIXELSY), 72);
222 font_desc.lfCharSet = DEFAULT_CHARSET;
223 memcpy(font_desc.lfFaceName, property_sheet_dialog_data+1,
224 sizeof(WCHAR*)*(lstrlenW(property_sheet_dialog_data+1)+1));
225 hfont = CreateFontIndirectW(&font_desc);
227 if(hfont) {
228 hfont = SelectObject(hdc, hfont);
229 font_width = GdiGetCharDimensions(hdc, NULL, &font_height);
230 SelectObject(hdc, hfont);
233 if(hcomctl)
234 FreeLibrary(hcomctl);
235 ReleaseDC(NULL, hdc);
237 memset(&property_sheet, 0, sizeof(property_sheet));
238 property_sheet.dwSize = sizeof(property_sheet);
239 if(lpParams->lpszCaption) {
240 property_sheet.dwFlags = PSH_PROPTITLE;
241 property_sheet.pszCaption = lpParams->lpszCaption;
244 property_sheet.u3.phpage = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
245 lpParams->cPages*sizeof(HPROPSHEETPAGE));
246 property_page = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
247 lpParams->cPages*sizeof(IPropertyPage*));
248 dialogs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
249 lpParams->cPages*sizeof(*dialogs));
250 if(!property_sheet.u3.phpage || !property_page || !dialogs) {
251 HeapFree(GetProcessHeap(), 0, property_sheet.u3.phpage);
252 HeapFree(GetProcessHeap(), 0, property_page);
253 HeapFree(GetProcessHeap(), 0, dialogs);
254 return E_OUTOFMEMORY;
257 memset(&property_sheet_page, 0, sizeof(PROPSHEETPAGEW));
258 property_sheet_page.dwSize = sizeof(PROPSHEETPAGEW);
259 property_sheet_page.dwFlags = PSP_DLGINDIRECT|PSP_USETITLE;
260 property_sheet_page.pfnDlgProc = property_sheet_proc;
262 for(i=0; i<lpParams->cPages; i++) {
263 PROPPAGEINFO page_info;
265 res = CoCreateInstance(&lpParams->lpPages[i], NULL, CLSCTX_INPROC_SERVER,
266 &IID_IPropertyPage, (void**)&property_page[i]);
267 if(FAILED(res))
268 continue;
270 property_page_site = HeapAlloc(GetProcessHeap(), 0, sizeof(PropertyPageSite));
271 if(!property_page_site)
272 continue;
273 ((PropertyPageSite*)property_page_site)->lpVtbl = &PropertyPageSiteVtbl;
274 ((PropertyPageSite*)property_page_site)->ref = 1;
275 ((PropertyPageSite*)property_page_site)->lcid = lpParams->lcid;
277 res = IPropertyPage_SetPageSite(property_page[i], property_page_site);
278 IPropertyPageSite_Release(property_page_site);
279 if(FAILED(res))
280 continue;
282 res = IPropertyPage_SetObjects(property_page[i],
283 lpParams->cObjects, lpParams->lplpUnk);
284 if(FAILED(res))
285 continue;
287 res = IPropertyPage_GetPageInfo(property_page[i], &page_info);
288 if(FAILED(res))
289 continue;
291 dialogs[i].template.cx = MulDiv(page_info.size.cx, 4, font_width);
292 dialogs[i].template.cy = MulDiv(page_info.size.cy, 8, font_height);
294 property_sheet_page.u.pResource = &dialogs[i].template;
295 property_sheet_page.lParam = (LPARAM)property_page[i];
296 property_sheet_page.pszTitle = page_info.pszTitle;
298 property_sheet.u3.phpage[property_sheet.nPages++] =
299 CreatePropertySheetPageW(&property_sheet_page);
302 PropertySheetW(&property_sheet);
304 for(i=0; i<lpParams->cPages; i++) {
305 if(property_page[i]) {
306 IPropertyPage_SetPageSite(property_page[i], NULL);
307 IPropertyPage_Release(property_page[i]);
311 HeapFree(GetProcessHeap(), 0, dialogs);
312 HeapFree(GetProcessHeap(), 0, property_page);
313 HeapFree(GetProcessHeap(), 0, property_sheet.u3.phpage);
314 return S_OK;
317 /***********************************************************************
318 * OleCreatePropertyFrame (OLEAUT32.417)
320 HRESULT WINAPI OleCreatePropertyFrame(
321 HWND hwndOwner, UINT x, UINT y, LPCOLESTR lpszCaption, ULONG cObjects,
322 LPUNKNOWN* ppUnk, ULONG cPages, LPCLSID pPageClsID, LCID lcid,
323 DWORD dwReserved, LPVOID pvReserved)
325 OCPFIPARAMS ocpf;
327 ocpf.cbStructSize = sizeof(OCPFIPARAMS);
328 ocpf.hWndOwner = hwndOwner;
329 ocpf.x = x;
330 ocpf.y = y;
331 ocpf.lpszCaption = lpszCaption;
332 ocpf.cObjects = cObjects;
333 ocpf.lplpUnk = ppUnk;
334 ocpf.cPages = cPages;
335 ocpf.lpPages = pPageClsID;
336 ocpf.lcid = lcid;
337 ocpf.dispidInitialProperty = 0;
339 return OleCreatePropertyFrameIndirect(&ocpf);