Ignore DSR/DTR flow control in DCB. termios doesn't support it.
[wine] / dlls / oleaut32 / propertyframe.c
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
20 DEFAULT_DEBUG_CHANNEL(ole);
21
22 typedef struct CPropertyPageContainerImpl CPropertyPageContainerImpl;
23
24 static 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
45 typedef 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
60 struct 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)
78 static 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
150 static HRESULT WINAPI
151 CPropertyPageSiteImpl_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
172 static ULONG WINAPI
173 CPropertyPageSiteImpl_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
182 static ULONG WINAPI
183 CPropertyPageSiteImpl_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
209 static HRESULT WINAPI
210 CPropertyPageSiteImpl_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
237 static HRESULT WINAPI
238 CPropertyPageSiteImpl_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
252 static HRESULT WINAPI
253 CPropertyPageSiteImpl_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
267 static HRESULT WINAPI
268 CPropertyPageSiteImpl_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
280 static 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
296 static
297 HRESULT 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         pPspReturned->u.pResource = ptempl;
341         if ( This->info.pszTitle != NULL );
342         {
343                 pPspReturned->dwFlags |= PSP_USETITLE;
344                 pPspReturned->pszTitle = "Title";/*FIXME - This->info.pszTitle;*/
345         }
346         pPspReturned->pfnDlgProc = PropSiteDlgProc;
347         pPspReturned->lParam = (LONG)This;
348
349 end:
350         if ( FAILED(hr) )
351         {
352                 IUnknown_Release((IUnknown*)This);
353                 return hr;
354         }
355
356         *ppSite = This;
357         return NOERROR;
358 }
359
360 /***************************************************************************/
361
362 static
363 void OLEPRO32_DestroyPropertyPageContainer(
364         CPropertyPageContainerImpl* This )
365 {
366         DWORD   nIndex;
367
368         if ( This->m_ppSites != NULL )
369         {
370                 for ( nIndex = 0; nIndex < This->m_cSites; nIndex++ )
371                 {
372                         if ( This->m_ppSites[nIndex] != NULL )
373                         {
374                                 IPropertyPage_SetPageSite(This->m_ppSites[nIndex]->pPage,NULL);
375                                 IUnknown_Release((IUnknown*)This->m_ppSites[nIndex]);
376                         }
377                 }
378                 HeapFree( GetProcessHeap(), 0, This->m_ppSites );
379                 This->m_ppSites = NULL;
380         }
381         if ( This->m_pPsp != NULL )
382         {
383                 HeapFree( GetProcessHeap(), 0, This->m_pPsp );
384                 This->m_pPsp = NULL;
385         }
386         HeapFree( GetProcessHeap(), 0, This );
387 }
388
389 static
390 HRESULT OLEPRO32_CreatePropertyPageContainer(
391         CPropertyPageContainerImpl** ppContainer,
392         ULONG cPages, const CLSID* pclsidPages,
393         LCID lcid )
394 {
395         CPropertyPageContainerImpl*     This = NULL;
396         DWORD   nIndex;
397         IPropertyPage*  pPage;
398         HRESULT hr;
399
400         This = (CPropertyPageContainerImpl*)HeapAlloc( GetProcessHeap(), 0,
401                 sizeof(CPropertyPageContainerImpl) );
402         if ( This == NULL )
403                 return E_OUTOFMEMORY;
404         ZeroMemory( This, sizeof(CPropertyPageContainerImpl) );
405         This->ref = 1;
406         This->lcid = lcid;
407         This->m_cSites = cPages;
408         This->m_ppSites = NULL;
409         This->m_pPsp = NULL;
410         This->m_hr = S_OK;
411
412         This->m_ppSites = (CPropertyPageSiteImpl**)HeapAlloc( GetProcessHeap(), 0, sizeof(CPropertyPageSiteImpl*) * cPages );
413         if ( This->m_ppSites == NULL )
414         {
415                 hr = E_OUTOFMEMORY;
416                 goto end;
417         }
418         ZeroMemory( This->m_ppSites, sizeof(CPropertyPageSiteImpl*) * cPages );
419
420         This->m_pPsp = (PROPSHEETPAGEA*)HeapAlloc( GetProcessHeap(), 0, sizeof(PROPSHEETPAGEA) * cPages );
421         if ( This->m_pPsp == NULL )
422         {
423                 hr = E_OUTOFMEMORY;
424                 goto end;
425         }
426         ZeroMemory( This->m_pPsp, sizeof(PROPSHEETPAGEA) * cPages );
427
428         for ( nIndex = 0; nIndex < cPages; nIndex ++ )
429         {
430                 hr = CoCreateInstance(
431                         &pclsidPages[nIndex], NULL, CLSCTX_SERVER,
432                         &IID_IPropertyPage, (void**)&pPage );
433                 if ( FAILED(hr) )
434                         goto end;
435                 hr = OLEPRO32_CreatePropertyPageSite(
436                         This, pPage, &This->m_ppSites[nIndex], &This->m_pPsp[nIndex] );
437                 IPropertyPage_Release(pPage);
438                 if ( FAILED(hr) )
439                         goto end;
440         }
441
442         hr = NOERROR;
443 end:
444         if ( FAILED(hr) )
445         {
446                 OLEPRO32_DestroyPropertyPageContainer( This );
447                 return hr;
448         }
449
450         *ppContainer = This;
451         return NOERROR;
452 }
453
454 static
455 HRESULT OLEPRO32_SetObjectsToPropertyPages(
456         CPropertyPageContainerImpl* This,
457         ULONG cObjects, IUnknown** ppunk )
458 {
459         DWORD   nIndex;
460         HRESULT hr;
461
462         for ( nIndex = 0; nIndex < This->m_cSites; nIndex ++ )
463         {
464                 if ( This->m_ppSites[nIndex] == NULL )
465                         return E_UNEXPECTED;
466                 hr = IPropertyPage_SetObjects(This->m_ppSites[nIndex]->pPage,cObjects,ppunk);
467                 if ( FAILED(hr) )
468                         return hr;
469         }
470
471         return NOERROR;
472 }
473
474
475 /***********************************************************************
476  *
477  * OleCreatePropertyFrameIndirect (OLEAUT32.416)(OLEPRO32.249)
478  *
479  */
480
481 HRESULT WINAPI OleCreatePropertyFrameIndirect( LPOCPFIPARAMS lpParams )
482 {
483         CPropertyPageContainerImpl*     pContainer = NULL;
484         HRESULT hr;
485         PROPSHEETHEADERA        psh;
486         int ret;
487
488         TRACE("(%p)\n",lpParams);
489
490         if ( lpParams == NULL )
491                 return E_POINTER;
492         if ( lpParams->cbStructSize != sizeof(OCPFIPARAMS) )
493         {
494                 FIXME("lpParams->cbStructSize(%lu) != sizeof(OCPFIPARAMS)(%lu)\n",lpParams->cbStructSize,(unsigned long)sizeof(OCPFIPARAMS));
495                 return E_INVALIDARG;
496         }
497
498         hr = OLEPRO32_CreatePropertyPageContainer(
499                 &pContainer,
500                 lpParams->cPages, lpParams->lpPages,
501                 lpParams->lcid );
502         if ( FAILED(hr) )
503         {
504                 TRACE( "OLEPRO32_CreatePropertyPageContainer returns %08lx\n",hr);
505                 return hr;
506         }
507
508         hr = OLEPRO32_SetObjectsToPropertyPages(
509                 pContainer,
510                 lpParams->cObjects, lpParams->lplpUnk );
511         if ( FAILED(hr) )
512         {
513                 TRACE("OLEPRO32_SetObjectsToPropertyPages returns %08lx\n",hr);
514                 OLEPRO32_DestroyPropertyPageContainer(pContainer);
515                 return hr;
516         }
517
518         /* FIXME - use lpParams.x / lpParams.y */
519
520         ZeroMemory( &psh, sizeof(psh) );
521         psh.dwSize = sizeof(PROPSHEETHEADERA);
522         psh.dwFlags = PSH_PROPSHEETPAGE;
523         psh.hwndParent = lpParams->hWndOwner;
524         psh.pszCaption = "Caption"; /* FIXME - lpParams->lpszCaption; */
525         psh.nPages = pContainer->m_cSites;
526         psh.u2.nStartPage = lpParams->dispidInitialProperty;
527         psh.u3.ppsp = pContainer->m_pPsp;
528
529         ret = PropertySheetA( &psh );
530         OLEPRO32_DestroyPropertyPageContainer(pContainer);
531
532         if ( ret == -1 )
533                 return E_FAIL;
534
535         return S_OK;
536 }
537
538
539 /***********************************************************************
540  *
541  * OleCreatePropertyFrame (OLEAUT32.417)(OLEPRO32.250)
542  *
543  */
544
545 HRESULT WINAPI OleCreatePropertyFrame(
546     HWND hwndOwner, UINT x, UINT y, LPCOLESTR lpszCaption,ULONG cObjects,
547     LPUNKNOWN* lplpUnk, ULONG cPages, LPCLSID pPageClsID, LCID lcid, 
548     DWORD dwReserved, LPVOID pvReserved )
549 {
550         OCPFIPARAMS     params;
551
552         TRACE("(%x,%d,%d,%s,%ld,%p,%ld,%p,%x,%ld,%p)\n",
553                 hwndOwner,x,y,debugstr_w(lpszCaption),cObjects,lplpUnk,cPages,
554                 pPageClsID, (int)lcid,dwReserved,pvReserved);
555
556         if ( dwReserved != 0 || pvReserved != NULL )
557         {
558                 FIXME("(%x,%d,%d,%s,%ld,%p,%ld,%p,%x,%ld,%p) - E_INVALIDARG\n",
559                 hwndOwner,x,y,debugstr_w(lpszCaption),cObjects,lplpUnk,cPages,
560                 pPageClsID, (int)lcid,dwReserved,pvReserved);
561                 return E_INVALIDARG;
562         }
563
564         ZeroMemory( &params, sizeof(params) );
565         params.cbStructSize = sizeof(OCPFIPARAMS);
566         params.hWndOwner = hwndOwner;
567         params.x = x;
568         params.y = y;
569         params.lpszCaption = lpszCaption;
570         params.cObjects = cObjects;
571         params.lplpUnk = lplpUnk;
572         params.cPages = cPages;
573         params.lpPages = pPageClsID;
574         params.lcid = lcid;
575         params.dispidInitialProperty = 0;
576
577         return OleCreatePropertyFrameIndirect( &params );
578 }
579