Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/dlls/compstui/compstui_main.c
4389 views
1
/*
2
* Implementation of the Common Property Sheets User Interface
3
*
4
* Copyright 2006 Detlef Riekenberg
5
*
6
* This library is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU Lesser General Public
8
* License as published by the Free Software Foundation; either
9
* version 2.1 of the License, or (at your option) any later version.
10
*
11
* This library is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
* Lesser General Public License for more details.
15
*
16
* You should have received a copy of the GNU Lesser General Public
17
* License along with this library; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19
*/
20
21
#include <assert.h>
22
#include <stdarg.h>
23
#include <stdlib.h>
24
#include <string.h>
25
26
#define COBJMACROS
27
28
#include "windef.h"
29
#include "winbase.h"
30
#include "winuser.h"
31
#include "commctrl.h"
32
#include "ddk/compstui.h"
33
34
#include "wine/debug.h"
35
#include "wine/list.h"
36
37
WINE_DEFAULT_DEBUG_CHANNEL(compstui);
38
39
static HMODULE compstui_hmod;
40
41
typedef struct
42
{
43
WORD size;
44
WORD flags;
45
union
46
{
47
WCHAR *titleW;
48
char *titleA;
49
};
50
HWND parent;
51
HINSTANCE hinst;
52
union
53
{
54
HICON hicon;
55
ULONG_PTR icon_id;
56
};
57
} PROPSHEETUI_INFO_HEADERAW;
58
59
struct propsheet
60
{
61
int pages_cnt;
62
HANDLE pages[100];
63
struct list funcs;
64
};
65
66
struct propsheetpage
67
{
68
HPROPSHEETPAGE hpsp;
69
DLGPROC dlg_proc;
70
};
71
72
struct propsheetfunc
73
{
74
struct list entry;
75
HANDLE handle;
76
PFNPROPSHEETUI func;
77
LPARAM lparam;
78
BOOL unicode;
79
ULONG_PTR user_data;
80
ULONG_PTR result;
81
};
82
83
#define HANDLE_FIRST 0x43440001
84
static struct cps_data
85
{
86
enum
87
{
88
HANDLE_FREE = 0,
89
HANDLE_PROPSHEET,
90
HANDLE_PROPSHEETPAGE,
91
HANDLE_PROPSHEETFUNC,
92
} type;
93
union
94
{
95
void *data;
96
struct cps_data *next_free;
97
struct propsheet *ps;
98
struct propsheetpage *psp;
99
struct propsheetfunc *psf;
100
};
101
} handles[0x1000];
102
static struct cps_data *first_free_handle = handles;
103
104
static CRITICAL_SECTION handles_cs;
105
static CRITICAL_SECTION_DEBUG handles_cs_debug =
106
{
107
0, 0, &handles_cs,
108
{ &handles_cs_debug.ProcessLocksList, &handles_cs_debug.ProcessLocksList },
109
0, 0, { (DWORD_PTR)(__FILE__ ": handles_cs") }
110
};
111
static CRITICAL_SECTION handles_cs = { &handles_cs_debug, -1, 0, 0, 0, 0 };
112
113
static LONG_PTR WINAPI cps_callback(HANDLE hcps, UINT func, LPARAM lparam1, LPARAM lparam2);
114
115
static struct cps_data* get_handle_data(HANDLE handle)
116
{
117
struct cps_data *ret;
118
119
if ((ULONG_PTR)handle < HANDLE_FIRST || (ULONG_PTR)handle >= HANDLE_FIRST + ARRAY_SIZE(handles))
120
return NULL;
121
122
ret = &handles[(ULONG_PTR)handle - HANDLE_FIRST];
123
return ret->type == HANDLE_FREE ? NULL : ret;
124
}
125
126
static HANDLE alloc_handle(struct cps_data **cps_data, int type)
127
{
128
void *data = NULL;
129
130
switch(type)
131
{
132
case HANDLE_PROPSHEET:
133
data = calloc(1, sizeof(struct propsheet));
134
break;
135
case HANDLE_PROPSHEETPAGE:
136
data = calloc(1, sizeof(struct propsheetpage));
137
break;
138
case HANDLE_PROPSHEETFUNC:
139
data = calloc(1, sizeof(struct propsheetfunc));
140
break;
141
}
142
143
if (!data)
144
return NULL;
145
146
EnterCriticalSection(&handles_cs);
147
148
if (first_free_handle >= handles + ARRAY_SIZE(handles))
149
{
150
LeaveCriticalSection(&handles_cs);
151
FIXME("out of handles\n");
152
free(data);
153
return NULL;
154
}
155
156
*cps_data = first_free_handle;
157
if ((*cps_data)->next_free)
158
first_free_handle = (*cps_data)->next_free;
159
else
160
first_free_handle = (*cps_data) + 1;
161
LeaveCriticalSection(&handles_cs);
162
163
(*cps_data)->type = type;
164
(*cps_data)->data = data;
165
return (HANDLE)(HANDLE_FIRST + ((*cps_data) - handles));
166
}
167
168
static void free_handle(HANDLE handle)
169
{
170
struct cps_data *data = get_handle_data(handle);
171
172
if (!data)
173
return;
174
175
data->type = HANDLE_FREE;
176
free(data->data);
177
178
EnterCriticalSection(&handles_cs);
179
data->next_free = first_free_handle;
180
first_free_handle = data;
181
LeaveCriticalSection(&handles_cs);
182
}
183
184
static HANDLE add_hpropsheetpage(HANDLE hcps, HPROPSHEETPAGE hpsp)
185
{
186
struct cps_data *cps_data = get_handle_data(hcps);
187
struct cps_data *cpsp_data;
188
HANDLE ret;
189
190
if (!cps_data || !hpsp)
191
return 0;
192
193
if (cps_data->type != HANDLE_PROPSHEET)
194
{
195
FIXME("unsupported handle type %d\n", cps_data->type);
196
return 0;
197
}
198
199
if (cps_data->ps->pages_cnt == ARRAY_SIZE(cps_data->ps->pages))
200
return 0;
201
202
ret = alloc_handle(&cpsp_data, HANDLE_PROPSHEETPAGE);
203
if (!ret)
204
return 0;
205
cpsp_data->psp->hpsp = hpsp;
206
207
cps_data->ps->pages[cps_data->ps->pages_cnt++] = ret;
208
return ret;
209
}
210
211
static HANDLE add_propsheetfunc(HANDLE hcps, PFNPROPSHEETUI func, LPARAM lparam, BOOL unicode)
212
{
213
struct cps_data *cps_data = get_handle_data(hcps);
214
struct cps_data *cpsf_data;
215
PROPSHEETUI_INFO info, callback_info;
216
HANDLE ret;
217
LONG lret;
218
219
if (!cps_data || !func)
220
return 0;
221
222
if (cps_data->type != HANDLE_PROPSHEET)
223
{
224
FIXME("unsupported handle type %d\n", cps_data->type);
225
return 0;
226
}
227
228
ret = alloc_handle(&cpsf_data, HANDLE_PROPSHEETFUNC);
229
if (!ret)
230
return 0;
231
cpsf_data->psf->handle = ret;
232
cpsf_data->psf->func = func;
233
cpsf_data->psf->unicode = unicode;
234
cpsf_data->psf->lparam = lparam;
235
236
memset(&info, 0, sizeof(info));
237
info.cbSize = sizeof(info);
238
info.Version = PROPSHEETUI_INFO_VERSION;
239
info.Flags = unicode ? PSUIINFO_UNICODE : 0;
240
info.Reason = PROPSHEETUI_REASON_INIT;
241
info.hComPropSheet = hcps;
242
info.pfnComPropSheet = cps_callback;
243
info.lParamInit = lparam;
244
245
callback_info = info;
246
lret = func(&callback_info, lparam);
247
cpsf_data->psf->user_data = callback_info.UserData;
248
cpsf_data->psf->result = callback_info.Result;
249
if (lret <= 0)
250
{
251
callback_info = info;
252
callback_info.Reason = PROPSHEETUI_REASON_DESTROY;
253
callback_info.UserData = cpsf_data->psf->user_data;
254
callback_info.Result = cpsf_data->psf->result;
255
free_handle(ret);
256
func(&callback_info, 0);
257
return 0;
258
}
259
260
list_add_tail(&cps_data->ps->funcs, &cpsf_data->psf->entry);
261
return ret;
262
}
263
264
static HANDLE add_propsheetpage(HANDLE hcps, void *psp, PSPINFO *info,
265
DLGPROC dlg_proc, BOOL unicode)
266
{
267
struct cps_data *cps_data = get_handle_data(hcps);
268
struct cps_data *cpsp_data;
269
HPROPSHEETPAGE hpsp;
270
HANDLE ret;
271
272
if (!cps_data)
273
return 0;
274
275
if (cps_data->type != HANDLE_PROPSHEET)
276
{
277
FIXME("unsupported handle type %d\n", cps_data->type);
278
return 0;
279
}
280
281
if (cps_data->ps->pages_cnt == ARRAY_SIZE(cps_data->ps->pages))
282
return 0;
283
284
ret = alloc_handle(&cpsp_data, HANDLE_PROPSHEETPAGE);
285
if (!ret)
286
return 0;
287
288
info->cbSize = sizeof(*info);
289
info->wReserved = 0;
290
info->hComPropSheet = hcps;
291
info->hCPSUIPage = ret;
292
info->pfnComPropSheet = cps_callback;
293
294
if (unicode)
295
hpsp = CreatePropertySheetPageW((PROPSHEETPAGEW*)psp);
296
else
297
hpsp = CreatePropertySheetPageA((PROPSHEETPAGEA*)psp);
298
if (!hpsp)
299
{
300
free_handle(ret);
301
return 0;
302
}
303
304
cpsp_data->psp->hpsp = hpsp;
305
cpsp_data->psp->dlg_proc = dlg_proc;
306
cps_data->ps->pages[cps_data->ps->pages_cnt++] = ret;
307
return ret;
308
}
309
310
static INT_PTR CALLBACK propsheetpage_dlg_procW(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
311
{
312
if (msg == WM_INITDIALOG)
313
{
314
PROPSHEETPAGEW *psp = (PROPSHEETPAGEW*)lparam;
315
PSPINFO *info = (PSPINFO*)((BYTE*)lparam + psp->dwSize - sizeof(*info));
316
struct cps_data *cpsp_data = get_handle_data(info->hCPSUIPage);
317
318
psp->dwSize -= sizeof(*info);
319
psp->pfnDlgProc = cpsp_data->psp->dlg_proc;
320
SetWindowLongPtrW(hwnd, DWLP_DLGPROC, (LONG_PTR)psp->pfnDlgProc);
321
return psp->pfnDlgProc(hwnd, msg, wparam, lparam);
322
}
323
324
return FALSE;
325
}
326
327
static HANDLE add_propsheetpageW(HANDLE hcps, PROPSHEETPAGEW *psp)
328
{
329
PROPSHEETPAGEW *psp_copy;
330
PSPINFO *info;
331
HANDLE ret;
332
333
if (!psp || psp->dwSize < PROPSHEETPAGEW_V1_SIZE)
334
return 0;
335
336
psp_copy = (PROPSHEETPAGEW*)malloc(psp->dwSize + sizeof(*info));
337
if (!psp_copy)
338
return 0;
339
memcpy(psp_copy, psp, psp->dwSize);
340
psp_copy->dwSize += sizeof(*info);
341
psp_copy->pfnDlgProc = propsheetpage_dlg_procW;
342
343
info = (PSPINFO*)((BYTE*)psp_copy + psp->dwSize);
344
ret = add_propsheetpage(hcps, psp_copy, info, psp->pfnDlgProc, TRUE);
345
free(psp_copy);
346
return ret;
347
}
348
349
static INT_PTR CALLBACK propsheetpage_dlg_procA(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
350
{
351
if (msg == WM_INITDIALOG)
352
{
353
PROPSHEETPAGEA *psp = (PROPSHEETPAGEA*)lparam;
354
PSPINFO *info = (PSPINFO*)((BYTE*)lparam + psp->dwSize - sizeof(*info));
355
struct cps_data *cpsp_data = get_handle_data(info->hCPSUIPage);
356
357
psp->dwSize -= sizeof(*info);
358
psp->pfnDlgProc = cpsp_data->psp->dlg_proc;
359
SetWindowLongPtrA(hwnd, DWLP_DLGPROC, (LONG_PTR)psp->pfnDlgProc);
360
return psp->pfnDlgProc(hwnd, msg, wparam, lparam);
361
}
362
363
return FALSE;
364
}
365
366
static HANDLE add_propsheetpageA(HANDLE hcps, PROPSHEETPAGEA *psp)
367
{
368
PROPSHEETPAGEA *psp_copy;
369
PSPINFO *info;
370
HANDLE ret;
371
372
if (!psp || psp->dwSize < PROPSHEETPAGEW_V1_SIZE)
373
return 0;
374
375
psp_copy = (PROPSHEETPAGEA*)malloc(psp->dwSize + sizeof(*info));
376
if (!psp_copy)
377
return 0;
378
memcpy(psp_copy, psp, psp->dwSize);
379
psp_copy->dwSize += sizeof(*info);
380
psp_copy->pfnDlgProc = propsheetpage_dlg_procA;
381
382
info = (PSPINFO*)((BYTE*)psp_copy + psp->dwSize);
383
ret = add_propsheetpage(hcps, psp_copy, info, psp->pfnDlgProc, FALSE);
384
free(psp_copy);
385
return ret;
386
}
387
388
static LONG_PTR WINAPI cps_callback(HANDLE hcps, UINT func, LPARAM lparam1, LPARAM lparam2)
389
{
390
TRACE("(%p, %u, %Ix, %Ix\n", hcps, func, lparam1, lparam2);
391
392
switch(func)
393
{
394
case CPSFUNC_ADD_HPROPSHEETPAGE:
395
return (LONG_PTR)add_hpropsheetpage(hcps, (HPROPSHEETPAGE)lparam1);
396
case CPSFUNC_ADD_PFNPROPSHEETUIA:
397
case CPSFUNC_ADD_PFNPROPSHEETUIW:
398
return (LONG_PTR)add_propsheetfunc(hcps, (PFNPROPSHEETUI)lparam1,
399
lparam2, func == CPSFUNC_ADD_PFNPROPSHEETUIW);
400
case CPSFUNC_ADD_PROPSHEETPAGEA:
401
return (LONG_PTR)add_propsheetpageA(hcps, (PROPSHEETPAGEA*)lparam1);
402
case CPSFUNC_ADD_PROPSHEETPAGEW:
403
return (LONG_PTR)add_propsheetpageW(hcps, (PROPSHEETPAGEW*)lparam1);
404
case CPSFUNC_ADD_PCOMPROPSHEETUIA:
405
case CPSFUNC_ADD_PCOMPROPSHEETUIW:
406
case CPSFUNC_DELETE_HCOMPROPSHEET:
407
case CPSFUNC_SET_HSTARTPAGE:
408
case CPSFUNC_GET_PAGECOUNT:
409
case CPSFUNC_SET_RESULT:
410
case CPSFUNC_GET_HPSUIPAGES:
411
case CPSFUNC_LOAD_CPSUI_STRINGA:
412
case CPSFUNC_LOAD_CPSUI_STRINGW:
413
case CPSFUNC_LOAD_CPSUI_ICON:
414
case CPSFUNC_GET_PFNPROPSHEETUI_ICON:
415
case CPSFUNC_INSERT_PSUIPAGEA:
416
case CPSFUNC_INSERT_PSUIPAGEW:
417
case CPSFUNC_SET_PSUIPAGE_TITLEA:
418
case CPSFUNC_SET_PSUIPAGE_TITLEW:
419
case CPSFUNC_SET_PSUIPAGE_ICON:
420
case CPSFUNC_SET_DATABLOCK:
421
case CPSFUNC_QUERY_DATABLOCK:
422
case CPSFUNC_SET_DMPUB_HIDEBITS:
423
case CPSFUNC_IGNORE_CPSUI_PSN_APPLY:
424
case CPSFUNC_DO_APPLY_CPSUI:
425
case CPSFUNC_SET_FUSION_CONTEXT:
426
FIXME("func not supported %d\n", func);
427
return 0;
428
default:
429
ERR("unknown func: %d\n", func);
430
return 0;
431
}
432
}
433
434
static LONG create_property_sheetW(struct propsheet *ps, PROPSHEETUI_INFO_HEADERAW *header)
435
{
436
HPROPSHEETPAGE hpsp[100];
437
PROPSHEETHEADERW psh;
438
WCHAR title[256];
439
LONG_PTR ret;
440
int i, len;
441
442
if (!ps->pages_cnt)
443
return ERR_CPSUI_NO_PROPSHEETPAGE;
444
445
memset(&psh, 0, sizeof(psh));
446
psh.dwSize = sizeof(psh);
447
if (header->flags & PSUIHDRF_NOAPPLYNOW)
448
psh.dwFlags |= PSH_NOAPPLYNOW;
449
psh.hwndParent = header->parent;
450
psh.hInstance = header->hinst;
451
psh.pszCaption = title;
452
453
if (!(header->flags & PSUIHDRF_USEHICON) && !header->icon_id)
454
header->icon_id = IDI_CPSUI_OPTION;
455
456
if (header->flags & PSUIHDRF_USEHICON)
457
{
458
psh.dwFlags |= PSH_USEHICON;
459
psh.hIcon = header->hicon;
460
}
461
else if (header->icon_id >= IDI_CPSUI_ICONID_FIRST &&
462
header->icon_id <= IDI_CPSUI_ICONID_LAST)
463
{
464
FIXME("icon not implemented: %Id\n", header->icon_id);
465
}
466
else
467
{
468
psh.dwFlags |= PSH_USEICONID;
469
psh.pszIcon = (WCHAR*)header->icon_id;
470
}
471
472
if (header->titleW)
473
wcscpy_s(title, ARRAY_SIZE(title), header->titleW);
474
else
475
LoadStringW(compstui_hmod, IDS_CPSUI_OPTIONS, title, ARRAY_SIZE(title));
476
477
if ((header->flags & PSUIHDRF_DEFTITLE) &&
478
(!header->titleW || !(header->flags & PSUIHDRF_EXACT_PTITLE)))
479
{
480
len = wcslen(title);
481
if (len < ARRAY_SIZE(title) - 1)
482
{
483
title[len++] = ' ';
484
LoadStringW(compstui_hmod, IDS_CPSUI_DEFAULT, title + len, ARRAY_SIZE(title) - len);
485
}
486
}
487
488
if ((header->flags & PSUIHDRF_PROPTITLE) &&
489
(!header->titleW || !(header->flags & PSUIHDRF_EXACT_PTITLE)))
490
{
491
len = wcslen(title);
492
if (len < ARRAY_SIZE(title) - 1)
493
{
494
title[len++] = ' ';
495
LoadStringW(compstui_hmod, IDS_CPSUI_PROPERTIES, title + len, ARRAY_SIZE(title) - len);
496
}
497
}
498
499
psh.nPages = ps->pages_cnt;
500
psh.phpage = hpsp;
501
for (i = 0; i < ps->pages_cnt; i++)
502
hpsp[i] = get_handle_data(ps->pages[i])->psp->hpsp;
503
504
ret = PropertySheetW(&psh);
505
506
switch(ret)
507
{
508
case -1:
509
return ERR_CPSUI_GETLASTERROR;
510
case ID_PSREBOOTSYSTEM:
511
return CPSUI_REBOOTSYSTEM;
512
case ID_PSRESTARTWINDOWS:
513
return CPSUI_RESTARTWINDOWS;
514
default:
515
return CPSUI_OK;
516
}
517
}
518
519
static LONG create_prop_dlg(HWND hwnd, PFNPROPSHEETUI callback, LPARAM lparam, DWORD *res, BOOL unicode)
520
{
521
PROPSHEETUI_INFO info, callback_info;
522
PROPSHEETUI_INFO_HEADERAW header;
523
struct cps_data *cps_data;
524
HANDLE cps_handle;
525
LONG ret;
526
int i;
527
528
if (!callback || !(cps_handle = alloc_handle(&cps_data, HANDLE_PROPSHEET)))
529
{
530
SetLastError(0);
531
return ERR_CPSUI_GETLASTERROR;
532
}
533
list_init(&cps_data->ps->funcs);
534
535
memset(&info, 0, sizeof(info));
536
info.cbSize = sizeof(info);
537
info.lParamInit = lparam;
538
callback_info = info;
539
callback_info.Reason = PROPSHEETUI_REASON_BEFORE_INIT;
540
callback(&callback_info, lparam);
541
542
info.Version = PROPSHEETUI_INFO_VERSION;
543
info.Flags = unicode ? PSUIINFO_UNICODE : 0;
544
info.hComPropSheet = cps_handle;
545
info.pfnComPropSheet = cps_callback;
546
callback_info = info;
547
callback_info.Reason = PROPSHEETUI_REASON_INIT;
548
ret = callback(&callback_info, lparam);
549
info.UserData = callback_info.UserData;
550
info.Result = callback_info.Result;
551
if (ret <= 0)
552
{
553
ret = ERR_CPSUI_GETLASTERROR;
554
goto destroy;
555
}
556
557
memset(&header, 0, sizeof(header));
558
header.size = sizeof(header);
559
header.parent = hwnd;
560
callback_info = info;
561
callback_info.Reason = PROPSHEETUI_REASON_GET_INFO_HEADER;
562
ret = callback(&callback_info, (LPARAM)&header);
563
info.UserData = callback_info.UserData;
564
info.Result = callback_info.Result;
565
if (ret <= 0)
566
{
567
ret = ERR_CPSUI_GETLASTERROR;
568
goto destroy;
569
}
570
571
ret = create_property_sheetW(cps_data->ps, &header);
572
573
destroy:
574
info.Reason = PROPSHEETUI_REASON_DESTROY;
575
while (!list_empty(&cps_data->ps->funcs))
576
{
577
struct propsheetfunc *func = LIST_ENTRY(list_head(&cps_data->ps->funcs),
578
struct propsheetfunc, entry);
579
580
list_remove(&func->entry);
581
582
callback_info = info;
583
callback_info.Flags = func->unicode ? PSUIINFO_UNICODE : 0;
584
callback_info.lParamInit = func->lparam;
585
callback_info.UserData = func->user_data;
586
callback_info.Result = func->result;
587
func->func(&callback_info, ret <= 0 ? 0 : 0x100);
588
free_handle(func->handle);
589
}
590
591
callback_info = info;
592
callback(&callback_info, ret <= 0 ? 0 : 0x100);
593
594
for (i = 0; i < cps_data->ps->pages_cnt; i++)
595
free_handle(cps_data->ps->pages[i]);
596
free_handle(cps_handle);
597
598
if (res) *res = callback_info.Result;
599
return ret;
600
}
601
602
/******************************************************************
603
* CommonPropertySheetUIA (COMPSTUI.@)
604
*
605
*/
606
LONG WINAPI CommonPropertySheetUIA(HWND hWnd, PFNPROPSHEETUI pfnPropSheetUI, LPARAM lparam, LPDWORD pResult)
607
{
608
FIXME("(%p, %p, 0x%Ix, %p)\n", hWnd, pfnPropSheetUI, lparam, pResult);
609
return CPSUI_CANCEL;
610
}
611
612
/******************************************************************
613
* CommonPropertySheetUIW (COMPSTUI.@)
614
*
615
*/
616
LONG WINAPI CommonPropertySheetUIW(HWND hwnd, PFNPROPSHEETUI callback, LPARAM lparam, LPDWORD res)
617
{
618
TRACE("(%p, %p, 0x%Ix, %p)\n", hwnd, callback, lparam, res);
619
return create_prop_dlg(hwnd, callback, lparam, res, TRUE);
620
}
621
622
/******************************************************************
623
* GetCPSUIUserData (COMPSTUI.@)
624
*
625
*/
626
ULONG_PTR WINAPI GetCPSUIUserData(HWND hDlg)
627
{
628
FIXME("(%p): stub\n", hDlg);
629
return 0;
630
}
631
632
/******************************************************************
633
* SetCPSUIUserData (COMPSTUI.@)
634
*
635
*/
636
BOOL WINAPI SetCPSUIUserData(HWND hDlg, ULONG_PTR UserData )
637
{
638
FIXME("(%p, %08Ix): stub\n", hDlg, UserData);
639
return TRUE;
640
}
641
642
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, void *reserved)
643
{
644
if (reason == DLL_PROCESS_ATTACH)
645
compstui_hmod = hinst;
646
return TRUE;
647
}
648
649