source: trunk/src/oleaut32/propertyframe.c@ 8266

Last change on this file since 8266 was 7916, checked in by sandervl, 24 years ago

Wine 20020215 resync + added extended logging

File size: 13.7 KB
Line 
1/*
2 * Copyright 2001 TAKESHIMA Hidenori <hidenori@a2.ctktv.ne.jp>
3 *
4 * FIXME - use PropertySheetW.
5 * FIXME - not tested.
6 */
7
8#include "config.h"
9
10#include "windef.h"
11#include "winbase.h"
12#include "wingdi.h"
13#include "winuser.h"
14#include "debugtools.h"
15#include "ole2.h"
16#include "olectl.h"
17#include "oleauto.h"
18#include "commctrl.h"
19
20DEFAULT_DEBUG_CHANNEL(ole);
21
22typedef struct CPropertyPageContainerImpl CPropertyPageContainerImpl;
23
24static const struct
25{
26 DLGTEMPLATE templ;
27 WORD wMenuName;
28 WORD wClassName;
29 WCHAR wDummyCaption;
30 BYTE padding[4];
31} propsite_dlg =
32{
33 {
34 WS_VISIBLE | WS_CHILD, /* style */
35 0, /* dwExtendedStyle */
36 0, /* cdit */
37 0, /* x */
38 0, /* y */
39 0, /* cx */
40 0, /* cy */
41 },
42 0, 0, 0,
43};
44
45typedef struct CPropertyPageSiteImpl
46{
47 ICOM_VFIELD(IPropertyPageSite);
48 /* IUnknown fields */
49 ULONG ref;
50
51 /* IPropertyPageSite fields */
52 CPropertyPageContainerImpl* pContainer;
53 IPropertyPage* pPage;
54 HWND hwnd;
55 BYTE templ[sizeof(propsite_dlg)];
56 PROPPAGEINFO info;
57 BOOL bActivate;
58} CPropertyPageSiteImpl;
59
60struct CPropertyPageContainerImpl
61{
62 ULONG ref; /* for IUnknown(not used now) */
63 LCID lcid;
64 DWORD m_cSites;
65 CPropertyPageSiteImpl** m_ppSites;
66 PROPSHEETPAGEA* m_pPsp;
67 HRESULT m_hr;
68};
69
70/* for future use. */
71#define CPropertyPageContainerImpl_AddRef(pContainer) (++((pContainer)->ref))
72#define CPropertyPageContainerImpl_Release(pContainer) (--((pContainer)->ref))
73
74
75/***************************************************************************/
76
77#define PropSiteDlg_Return(a) do{SetWindowLongA(hwnd,DWL_MSGRESULT,(LONG)a);return TRUE;}while(1)
78static BOOL CALLBACK PropSiteDlgProc(
79 HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
80{
81 CPropertyPageSiteImpl* This = (CPropertyPageSiteImpl*)GetWindowLongA( hwnd, DWL_USER );
82 HRESULT hr;
83 RECT rc;
84 NMHDR* pnmh;
85
86 switch ( msg )
87 {
88 case WM_INITDIALOG:
89 This = (CPropertyPageSiteImpl*)(((PROPSHEETPAGEA*)lParam)->lParam);
90 SetWindowLongA( hwnd, DWL_USER, (LONG)This );
91 TRACE("WM_INITDIALOG (%p) hwnd = %08x\n", This, hwnd );
92
93 This->hwnd = hwnd;
94 ZeroMemory( &rc, sizeof(rc) );
95 GetClientRect( hwnd, &rc );
96 hr = IPropertyPage_Activate(This->pPage,hwnd,&rc,TRUE);
97 if ( SUCCEEDED(hr) )
98 {
99 This->bActivate = TRUE;
100 hr = IPropertyPage_Show(This->pPage,SW_SHOW);
101 }
102 if ( FAILED(hr) )
103 This->pContainer->m_hr = hr;
104 break;
105 case WM_DESTROY:
106 TRACE("WM_DESTROY (%p)\n",This);
107 if ( This != NULL )
108 {
109 if ( This->bActivate )
110 {
111 IPropertyPage_Show(This->pPage,SW_HIDE);
112 IPropertyPage_Deactivate(This->pPage);
113 This->bActivate = FALSE;
114 }
115 This->hwnd = (HWND)NULL;
116 }
117 SetWindowLongA( hwnd, DWL_USER, (LONG)0 );
118 break;
119 case WM_NOTIFY:
120 pnmh = (NMHDR*)lParam;
121 switch ( pnmh->code )
122 {
123 case PSN_APPLY:
124 TRACE("PSN_APPLY (%p)\n",This);
125 hr = IPropertyPage_Apply(This->pPage);
126 if ( FAILED(hr) )
127 PropSiteDlg_Return(PSNRET_INVALID_NOCHANGEPAGE);
128 PropSiteDlg_Return(PSNRET_NOERROR);
129 case PSN_QUERYCANCEL:
130 FIXME("PSN_QUERYCANCEL (%p)\n",This);
131 PropSiteDlg_Return(FALSE);
132 case PSN_RESET:
133 FIXME("PSN_RESET (%p)\n",This);
134 PropSiteDlg_Return(0);
135 case PSN_SETACTIVE:
136 TRACE("PSN_SETACTIVE (%p)\n",This);
137 PropSiteDlg_Return(0);
138 case PSN_KILLACTIVE:
139 TRACE("PSN_KILLACTIVE (%p)\n",This);
140 PropSiteDlg_Return(FALSE);
141 }
142 break;
143 }
144
145 return FALSE;
146}
147
148/***************************************************************************/
149
150static HRESULT WINAPI
151CPropertyPageSiteImpl_fnQueryInterface(IPropertyPageSite* iface,REFIID riid,LPVOID *ppobj)
152{
153 ICOM_THIS(CPropertyPageSiteImpl,iface);
154
155 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
156
157 if ( ppobj == NULL )
158 return E_POINTER;
159 *ppobj = NULL;
160
161 if ( IsEqualGUID(riid,&IID_IUnknown) ||
162 IsEqualGUID(riid,&IID_IPropertyPageSite) )
163 {
164 *ppobj = (LPVOID)This;
165 IUnknown_AddRef((IUnknown*)(*ppobj));
166 return S_OK;
167 }
168
169 return E_NOINTERFACE;
170}
171
172static ULONG WINAPI
173CPropertyPageSiteImpl_fnAddRef(IPropertyPageSite* iface)
174{
175 ICOM_THIS(CPropertyPageSiteImpl,iface);
176
177 TRACE("(%p)->()\n",This);
178
179 return InterlockedExchangeAdd(&(This->ref),1) + 1;
180}
181
182static ULONG WINAPI
183CPropertyPageSiteImpl_fnRelease(IPropertyPageSite* iface)
184{
185 ICOM_THIS(CPropertyPageSiteImpl,iface);
186 LONG ref;
187
188 TRACE("(%p)->()\n",This);
189 ref = InterlockedExchangeAdd(&(This->ref),-1) - 1;
190 if ( ref > 0 )
191 return (ULONG)ref;
192
193 if ( This->pContainer != NULL )
194 CPropertyPageContainerImpl_Release(This->pContainer);
195 if ( This->pPage != NULL )
196 IPropertyPage_Release(This->pPage);
197 if ( This->info.pszTitle != NULL )
198 CoTaskMemFree( This->info.pszTitle );
199 if ( This->info.pszDocString != NULL )
200 CoTaskMemFree( This->info.pszDocString );
201 if ( This->info.pszHelpFile != NULL )
202 CoTaskMemFree( This->info.pszHelpFile );
203
204 HeapFree(GetProcessHeap(),0,This);
205
206 return 0;
207}
208
209static HRESULT WINAPI
210CPropertyPageSiteImpl_fnOnStatusChange(IPropertyPageSite* iface,DWORD dwFlags)
211{
212 ICOM_THIS(CPropertyPageSiteImpl,iface);
213
214 TRACE("(%p,%08lx)\n",This,dwFlags);
215
216 if ( This->hwnd == (HWND)NULL )
217 return E_UNEXPECTED;
218
219 switch ( dwFlags )
220 {
221 case PROPPAGESTATUS_DIRTY:
222 /* dirty */
223 SendMessageA(GetParent(This->hwnd),PSM_CHANGED,(WPARAM)(This->hwnd),0);
224 break;
225 case PROPPAGESTATUS_VALIDATE:
226 /* validate */
227 SendMessageA(GetParent(This->hwnd),PSM_UNCHANGED,(WPARAM)(This->hwnd),0);
228 break;
229 default:
230 FIXME("(%p,%08lx) unknown flags\n",This,dwFlags);
231 return E_INVALIDARG;
232 }
233
234 return NOERROR;
235}
236
237static HRESULT WINAPI
238CPropertyPageSiteImpl_fnGetLocaleID(IPropertyPageSite* iface,LCID* pLocaleID)
239{
240 ICOM_THIS(CPropertyPageSiteImpl,iface);
241
242 TRACE("(%p,%p)\n",This,pLocaleID);
243
244 if ( pLocaleID == NULL )
245 return E_POINTER;
246
247 *pLocaleID = This->pContainer->lcid;
248
249 return NOERROR;
250}
251
252static HRESULT WINAPI
253CPropertyPageSiteImpl_fnGetPageContainer(IPropertyPageSite* iface,IUnknown** ppUnk)
254{
255 ICOM_THIS(CPropertyPageSiteImpl,iface);
256
257 FIXME("(%p,%p) - Win95 returns E_NOTIMPL\n",This,ppUnk);
258
259 if ( ppUnk == NULL )
260 return E_POINTER;
261
262 *ppUnk = NULL;
263
264 return E_NOTIMPL;
265}
266
267static HRESULT WINAPI
268CPropertyPageSiteImpl_fnTranslateAccelerator(IPropertyPageSite* iface,MSG* pMsg)
269{
270 ICOM_THIS(CPropertyPageSiteImpl,iface);
271
272 FIXME("(%p,%p) - Win95 returns E_NOTIMPL\n",This,pMsg);
273
274 if ( pMsg == NULL )
275 return E_POINTER;
276
277 return E_NOTIMPL;
278}
279
280static ICOM_VTABLE(IPropertyPageSite) iproppagesite =
281{
282 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
283 /* IUnknown fields */
284 CPropertyPageSiteImpl_fnQueryInterface,
285 CPropertyPageSiteImpl_fnAddRef,
286 CPropertyPageSiteImpl_fnRelease,
287 /* IPropertyPageSite fields */
288 CPropertyPageSiteImpl_fnOnStatusChange,
289 CPropertyPageSiteImpl_fnGetLocaleID,
290 CPropertyPageSiteImpl_fnGetPageContainer,
291 CPropertyPageSiteImpl_fnTranslateAccelerator,
292};
293
294/***************************************************************************/
295
296static
297HRESULT OLEPRO32_CreatePropertyPageSite(
298 CPropertyPageContainerImpl* pContainer,
299 IPropertyPage* pPage,
300 CPropertyPageSiteImpl** ppSite,
301 PROPSHEETPAGEA* pPspReturned )
302{
303 CPropertyPageSiteImpl* This = NULL;
304 HRESULT hr;
305 DLGTEMPLATE* ptempl;
306
307 *ppSite = NULL;
308 ZeroMemory( pPspReturned, sizeof(PROPSHEETPAGEA) );
309
310 This = (CPropertyPageSiteImpl*)HeapAlloc( GetProcessHeap(), 0,
311 sizeof(CPropertyPageSiteImpl) );
312 if ( This == NULL )
313 return E_OUTOFMEMORY;
314 ZeroMemory( This, sizeof(CPropertyPageSiteImpl) );
315
316 ICOM_VTBL(This) = &iproppagesite;
317 This->ref = 1;
318 This->pContainer = pContainer; CPropertyPageContainerImpl_AddRef(pContainer);
319 This->pPage = pPage; IPropertyPage_AddRef(pPage);
320 This->hwnd = (HWND)NULL;
321 memcpy( &This->templ, &propsite_dlg, sizeof(propsite_dlg) );
322 This->info.cb = sizeof(PROPPAGEINFO);
323 This->bActivate = FALSE;
324 ptempl = (DLGTEMPLATE*)&This->templ;
325
326 /* construct */
327 hr = IPropertyPage_SetPageSite(pPage,(IPropertyPageSite*)This);
328 if ( FAILED(hr) )
329 goto end;
330
331 hr = IPropertyPage_GetPageInfo(pPage,&This->info);
332 if ( FAILED(hr) )
333 goto end;
334
335 ptempl->cx = This->info.size.cx;
336 ptempl->cy = This->info.size.cy;
337
338 pPspReturned->dwSize = sizeof(PROPSHEETPAGEA);
339 pPspReturned->dwFlags = PSP_DLGINDIRECT;
340#ifdef __WIN32OS2__
341 pPspReturned->u1.pResource = ptempl;
342#else
343 pPspReturned->u.pResource = ptempl;
344#endif
345 if ( This->info.pszTitle != NULL );
346 {
347 pPspReturned->dwFlags |= PSP_USETITLE;
348 pPspReturned->pszTitle = "Title";/*FIXME - This->info.pszTitle;*/
349 }
350 pPspReturned->pfnDlgProc = PropSiteDlgProc;
351 pPspReturned->lParam = (LONG)This;
352
353end:
354 if ( FAILED(hr) )
355 {
356 IUnknown_Release((IUnknown*)This);
357 return hr;
358 }
359
360 *ppSite = This;
361 return NOERROR;
362}
363
364/***************************************************************************/
365
366static
367void OLEPRO32_DestroyPropertyPageContainer(
368 CPropertyPageContainerImpl* This )
369{
370 DWORD nIndex;
371
372 if ( This->m_ppSites != NULL )
373 {
374 for ( nIndex = 0; nIndex < This->m_cSites; nIndex++ )
375 {
376 if ( This->m_ppSites[nIndex] != NULL )
377 {
378 IPropertyPage_SetPageSite(This->m_ppSites[nIndex]->pPage,NULL);
379 IUnknown_Release((IUnknown*)This->m_ppSites[nIndex]);
380 }
381 }
382 HeapFree( GetProcessHeap(), 0, This->m_ppSites );
383 This->m_ppSites = NULL;
384 }
385 if ( This->m_pPsp != NULL )
386 {
387 HeapFree( GetProcessHeap(), 0, This->m_pPsp );
388 This->m_pPsp = NULL;
389 }
390 HeapFree( GetProcessHeap(), 0, This );
391}
392
393static
394HRESULT OLEPRO32_CreatePropertyPageContainer(
395 CPropertyPageContainerImpl** ppContainer,
396 ULONG cPages, const CLSID* pclsidPages,
397 LCID lcid )
398{
399 CPropertyPageContainerImpl* This = NULL;
400 DWORD nIndex;
401 IPropertyPage* pPage;
402 HRESULT hr;
403
404 This = (CPropertyPageContainerImpl*)HeapAlloc( GetProcessHeap(), 0,
405 sizeof(CPropertyPageContainerImpl) );
406 if ( This == NULL )
407 return E_OUTOFMEMORY;
408 ZeroMemory( This, sizeof(CPropertyPageContainerImpl) );
409 This->ref = 1;
410 This->lcid = lcid;
411 This->m_cSites = cPages;
412 This->m_ppSites = NULL;
413 This->m_pPsp = NULL;
414 This->m_hr = S_OK;
415
416 This->m_ppSites = (CPropertyPageSiteImpl**)HeapAlloc( GetProcessHeap(), 0, sizeof(CPropertyPageSiteImpl*) * cPages );
417 if ( This->m_ppSites == NULL )
418 {
419 hr = E_OUTOFMEMORY;
420 goto end;
421 }
422 ZeroMemory( This->m_ppSites, sizeof(CPropertyPageSiteImpl*) * cPages );
423
424 This->m_pPsp = (PROPSHEETPAGEA*)HeapAlloc( GetProcessHeap(), 0, sizeof(PROPSHEETPAGEA) * cPages );
425 if ( This->m_pPsp == NULL )
426 {
427 hr = E_OUTOFMEMORY;
428 goto end;
429 }
430 ZeroMemory( This->m_pPsp, sizeof(PROPSHEETPAGEA) * cPages );
431
432 for ( nIndex = 0; nIndex < cPages; nIndex ++ )
433 {
434 hr = CoCreateInstance(
435 &pclsidPages[nIndex], NULL, CLSCTX_SERVER,
436 &IID_IPropertyPage, (void**)&pPage );
437 if ( FAILED(hr) )
438 goto end;
439 hr = OLEPRO32_CreatePropertyPageSite(
440 This, pPage, &This->m_ppSites[nIndex], &This->m_pPsp[nIndex] );
441 IPropertyPage_Release(pPage);
442 if ( FAILED(hr) )
443 goto end;
444 }
445
446 hr = NOERROR;
447end:
448 if ( FAILED(hr) )
449 {
450 OLEPRO32_DestroyPropertyPageContainer( This );
451 return hr;
452 }
453
454 *ppContainer = This;
455 return NOERROR;
456}
457
458static
459HRESULT OLEPRO32_SetObjectsToPropertyPages(
460 CPropertyPageContainerImpl* This,
461 ULONG cObjects, IUnknown** ppunk )
462{
463 DWORD nIndex;
464 HRESULT hr;
465
466 for ( nIndex = 0; nIndex < This->m_cSites; nIndex ++ )
467 {
468 if ( This->m_ppSites[nIndex] == NULL )
469 return E_UNEXPECTED;
470 hr = IPropertyPage_SetObjects(This->m_ppSites[nIndex]->pPage,cObjects,ppunk);
471 if ( FAILED(hr) )
472 return hr;
473 }
474
475 return NOERROR;
476}
477
478
479/***********************************************************************
480 *
481 * OleCreatePropertyFrameIndirect (OLEAUT32.416)(OLEPRO32.249)
482 *
483 */
484
485HRESULT WINAPI OleCreatePropertyFrameIndirect( LPOCPFIPARAMS lpParams )
486{
487 CPropertyPageContainerImpl* pContainer = NULL;
488 HRESULT hr;
489 PROPSHEETHEADERA psh;
490 int ret;
491
492 TRACE("(%p)\n",lpParams);
493
494 if ( lpParams == NULL )
495 return E_POINTER;
496 if ( lpParams->cbStructSize != sizeof(OCPFIPARAMS) )
497 {
498 FIXME("lpParams->cbStructSize(%lu) != sizeof(OCPFIPARAMS)(%lu)\n",lpParams->cbStructSize,(unsigned long)sizeof(OCPFIPARAMS));
499 return E_INVALIDARG;
500 }
501
502 hr = OLEPRO32_CreatePropertyPageContainer(
503 &pContainer,
504 lpParams->cPages, lpParams->lpPages,
505 lpParams->lcid );
506 if ( FAILED(hr) )
507 {
508 TRACE( "OLEPRO32_CreatePropertyPageContainer returns %08lx\n",hr);
509 return hr;
510 }
511
512 hr = OLEPRO32_SetObjectsToPropertyPages(
513 pContainer,
514 lpParams->cObjects, lpParams->lplpUnk );
515 if ( FAILED(hr) )
516 {
517 TRACE("OLEPRO32_SetObjectsToPropertyPages returns %08lx\n",hr);
518 OLEPRO32_DestroyPropertyPageContainer(pContainer);
519 return hr;
520 }
521
522 /* FIXME - use lpParams.x / lpParams.y */
523
524 ZeroMemory( &psh, sizeof(psh) );
525 psh.dwSize = sizeof(PROPSHEETHEADERA);
526 psh.dwFlags = PSH_PROPSHEETPAGE;
527 psh.hwndParent = lpParams->hWndOwner;
528 psh.pszCaption = "Caption"; /* FIXME - lpParams->lpszCaption; */
529 psh.nPages = pContainer->m_cSites;
530 psh.u2.nStartPage = lpParams->dispidInitialProperty;
531 psh.u3.ppsp = pContainer->m_pPsp;
532
533 ret = PropertySheetA( &psh );
534 OLEPRO32_DestroyPropertyPageContainer(pContainer);
535
536 if ( ret == -1 )
537 return E_FAIL;
538
539 return S_OK;
540}
541
542
543/***********************************************************************
544 *
545 * OleCreatePropertyFrame (OLEAUT32.417)(OLEPRO32.250)
546 *
547 */
548
549HRESULT WINAPI OleCreatePropertyFrame(
550 HWND hwndOwner, UINT x, UINT y, LPCOLESTR lpszCaption,ULONG cObjects,
551 LPUNKNOWN* lplpUnk, ULONG cPages, LPCLSID pPageClsID, LCID lcid,
552 DWORD dwReserved, LPVOID pvReserved )
553{
554 OCPFIPARAMS params;
555
556 TRACE("(%x,%d,%d,%s,%ld,%p,%ld,%p,%x,%ld,%p)\n",
557 hwndOwner,x,y,debugstr_w(lpszCaption),cObjects,lplpUnk,cPages,
558 pPageClsID, (int)lcid,dwReserved,pvReserved);
559
560 if ( dwReserved != 0 || pvReserved != NULL )
561 {
562 FIXME("(%x,%d,%d,%s,%ld,%p,%ld,%p,%x,%ld,%p) - E_INVALIDARG\n",
563 hwndOwner,x,y,debugstr_w(lpszCaption),cObjects,lplpUnk,cPages,
564 pPageClsID, (int)lcid,dwReserved,pvReserved);
565 return E_INVALIDARG;
566 }
567
568 ZeroMemory( &params, sizeof(params) );
569 params.cbStructSize = sizeof(OCPFIPARAMS);
570 params.hWndOwner = hwndOwner;
571 params.x = x;
572 params.y = y;
573 params.lpszCaption = lpszCaption;
574 params.cObjects = cObjects;
575 params.lplpUnk = lplpUnk;
576 params.cPages = cPages;
577 params.lpPages = pPageClsID;
578 params.lcid = lcid;
579 params.dispidInitialProperty = 0;
580
581 return OleCreatePropertyFrameIndirect( &params );
582}
583
Note: See TracBrowser for help on using the repository browser.