[SOLITAIRE]
[reactos.git] / reactos / dll / cpl / mmsys / sounds.c
1 /* $Id: main.c 12852 2005-01-06 13:58:04Z mf $
2 *
3 * PROJECT: ReactOS Multimedia Control Panel
4 * FILE: dll/cpl/mmsys/mmsys.c
5 * PURPOSE: ReactOS Multimedia Control Panel
6 * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com>
7 * Johannes Anderwald <janderwald@reactos.com>
8 * Dmitry Chapyshev <dmitry@reactos.org>
9 */
10
11 #include "mmsys.h"
12
13 struct __APP_MAP__;
14
15 typedef struct __LABEL_MAP__
16 {
17 TCHAR * szName;
18 TCHAR * szDesc;
19 TCHAR * szIcon;
20 struct __APP_MAP__ * AppMap;
21 struct __LABEL_MAP__ * Next;
22 } LABEL_MAP, *PLABEL_MAP;
23
24 typedef struct __APP_MAP__
25 {
26 TCHAR szName[MAX_PATH];
27 TCHAR szDesc[MAX_PATH];
28 TCHAR szIcon[MAX_PATH];
29
30 struct __APP_MAP__ *Next;
31 PLABEL_MAP LabelMap;
32 } APP_MAP, *PAPP_MAP;
33
34 typedef struct __LABEL_CONTEXT__
35 {
36 PLABEL_MAP LabelMap;
37 PAPP_MAP AppMap;
38 TCHAR szValue[MAX_PATH];
39 struct __LABEL_CONTEXT__ *Next;
40 } LABEL_CONTEXT, *PLABEL_CONTEXT;
41
42 typedef struct __SOUND_SCHEME_CONTEXT__
43 {
44 TCHAR szName[MAX_PATH];
45 TCHAR szDesc[MAX_PATH];
46 PLABEL_CONTEXT LabelContext;
47 } SOUND_SCHEME_CONTEXT, *PSOUND_SCHEME_CONTEXT;
48
49 static PLABEL_MAP s_Map = NULL;
50 static PAPP_MAP s_App = NULL;
51
52 TCHAR szDefault[MAX_PATH];
53
54
55 PLABEL_MAP FindLabel(PAPP_MAP pAppMap, TCHAR * szName)
56 {
57 PLABEL_MAP pMap = s_Map;
58
59 while (pMap)
60 {
61 ASSERT(pMap);
62 ASSERT(pMap->szName);
63 if (!_tcscmp(pMap->szName, szName))
64 return pMap;
65
66 pMap = pMap->Next;
67 }
68
69 pMap = pAppMap->LabelMap;
70
71 while (pMap)
72 {
73 ASSERT(pMap);
74 ASSERT(pMap->szName);
75 if (!_tcscmp(pMap->szName, szName))
76 return pMap;
77
78 pMap = pMap->Next;
79 }
80
81 pMap = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LABEL_MAP));
82 if (!pMap)
83 return NULL;
84
85 pMap->szName = pMap->szDesc = _tcsdup(szName);
86 if (!pMap->szName)
87 {
88 HeapFree(GetProcessHeap(), 0, pMap);
89 return NULL;
90 }
91
92 pMap->AppMap = pAppMap;
93 pMap->Next = s_Map;
94 s_Map = pMap;
95
96 return pMap;
97 }
98
99
100 VOID RemoveLabel(PLABEL_MAP pMap)
101 {
102 PLABEL_MAP pCurMap = s_Map;
103
104 if (pCurMap == pMap)
105 {
106 s_Map = s_Map->Next;
107 return;
108 }
109
110 while (pCurMap)
111 {
112 if (pCurMap->Next == pMap)
113 {
114 pCurMap->Next = pCurMap->Next->Next;
115 return;
116 }
117 pCurMap = pCurMap->Next;
118 }
119 }
120
121
122 PAPP_MAP FindApp(TCHAR * szName)
123 {
124 PAPP_MAP pMap = s_App;
125
126 while (pMap)
127 {
128 if (!_tcscmp(pMap->szName, szName))
129 return pMap;
130
131 pMap = pMap->Next;
132
133 }
134 return NULL;
135 }
136
137
138 PLABEL_CONTEXT FindLabelContext(PSOUND_SCHEME_CONTEXT pSoundScheme, TCHAR * AppName, TCHAR * LabelName)
139 {
140 PLABEL_CONTEXT pLabelContext;
141
142 pLabelContext = pSoundScheme->LabelContext;
143
144 while (pLabelContext)
145 {
146 ASSERT(pLabelContext->AppMap);
147 ASSERT(pLabelContext->LabelMap);
148
149 if (!_tcsicmp(pLabelContext->AppMap->szName, AppName) && !_tcsicmp(pLabelContext->LabelMap->szName, LabelName))
150 {
151 return pLabelContext;
152 }
153 pLabelContext = pLabelContext->Next;
154 }
155
156 pLabelContext = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LABEL_CONTEXT));
157 if (!pLabelContext)
158 return NULL;
159
160 pLabelContext->AppMap = FindApp(AppName);
161 pLabelContext->LabelMap = FindLabel(pLabelContext->AppMap, LabelName);
162 ASSERT(pLabelContext->AppMap);
163 ASSERT(pLabelContext->LabelMap);
164 pLabelContext->szValue[0] = _T('\0');
165 pLabelContext->Next = pSoundScheme->LabelContext;
166 pSoundScheme->LabelContext = pLabelContext;
167
168 return pLabelContext;
169 }
170
171
172 BOOL
173 LoadEventLabel(HKEY hKey, TCHAR * szSubKey)
174 {
175 HKEY hSubKey;
176 DWORD dwData;
177 DWORD dwDesc;
178 TCHAR szDesc[MAX_PATH];
179 TCHAR szData[MAX_PATH];
180 PLABEL_MAP pMap;
181
182 if (RegOpenKeyEx(hKey,
183 szSubKey,
184 0,
185 KEY_READ,
186 &hSubKey) != ERROR_SUCCESS)
187 {
188 return FALSE;
189 }
190
191 dwDesc = sizeof(szDesc) / sizeof(TCHAR);
192 if (RegQueryValueEx(hSubKey,
193 NULL,
194 NULL,
195 NULL,
196 (LPBYTE)szDesc,
197 &dwDesc) != ERROR_SUCCESS)
198 {
199 RegCloseKey(hSubKey);
200 return FALSE;
201 }
202
203 dwData = sizeof(szDesc) / sizeof(TCHAR);
204 if (RegQueryValueEx(hSubKey,
205 _T("DispFileName"),
206 NULL,
207 NULL,
208 (LPBYTE)szData,
209 &dwData) != ERROR_SUCCESS)
210 {
211 RegCloseKey(hSubKey);
212 return FALSE;
213 }
214
215 pMap = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LABEL_MAP));
216 if (!pMap)
217 {
218 return FALSE;
219 }
220 pMap->szName = _tcsdup(szSubKey);
221 pMap->szDesc = _tcsdup(szDesc);
222 pMap->szIcon = _tcsdup(szData);
223
224 if (s_Map)
225 {
226 pMap->Next = s_Map;
227 s_Map = pMap;
228 }
229 else
230 {
231 s_Map = pMap;
232 s_Map->Next = 0;
233 }
234 return TRUE;
235 }
236
237
238 BOOL
239 LoadEventLabels()
240 {
241 HKEY hSubKey;
242 DWORD dwCurKey;
243 TCHAR szName[MAX_PATH];
244 DWORD dwName;
245 DWORD dwResult;
246 DWORD dwCount;
247 if (RegOpenKeyEx(HKEY_CURRENT_USER,
248 _T("AppEvents\\EventLabels"),
249 0,
250 KEY_READ,
251 &hSubKey) != ERROR_SUCCESS)
252 {
253 return FALSE;
254 }
255
256 dwCurKey = 0;
257 dwCount = 0;
258 do
259 {
260 dwName = sizeof(szName) / sizeof(szName[0]);
261 dwResult = RegEnumKeyEx(hSubKey,
262 dwCurKey,
263 szName,
264 &dwName,
265 NULL,
266 NULL,
267 NULL,
268 NULL);
269
270 if (dwResult == ERROR_SUCCESS)
271 {
272 if (LoadEventLabel(hSubKey, szName))
273 {
274 dwCount++;
275 }
276 }
277 dwCurKey++;
278
279 } while (dwResult == ERROR_SUCCESS);
280
281 RegCloseKey(hSubKey);
282 return (dwCount != 0);
283 }
284
285
286 BOOL
287 AddSoundProfile(HWND hwndDlg, HKEY hKey, TCHAR * szSubKey, BOOL SetDefault)
288 {
289 HKEY hSubKey;
290 TCHAR szValue[MAX_PATH];
291 DWORD dwValue, dwResult;
292
293 if (RegOpenKeyEx(hKey,
294 szSubKey,
295 0,
296 KEY_READ,
297 &hSubKey) != ERROR_SUCCESS)
298 {
299 return FALSE;
300 }
301
302 dwValue = sizeof(szValue) / sizeof(TCHAR);
303 dwResult = RegQueryValueEx(hSubKey,
304 NULL,
305 NULL,
306 NULL,
307 (LPBYTE)szValue,
308 &dwValue);
309 RegCloseKey(hSubKey);
310 if (dwResult == ERROR_SUCCESS)
311 {
312 LRESULT lResult = SendDlgItemMessage(hwndDlg, IDC_SOUND_SCHEME, CB_ADDSTRING, (WPARAM)0, (LPARAM)szValue);
313 if (lResult != CB_ERR)
314 {
315 PSOUND_SCHEME_CONTEXT pScheme = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SOUND_SCHEME_CONTEXT));
316 if (pScheme != NULL)
317 {
318 _tcscpy(pScheme->szDesc, szValue);
319 _tcscpy(pScheme->szName, szSubKey);
320 }
321
322 SendDlgItemMessage(hwndDlg, IDC_SOUND_SCHEME, CB_SETITEMDATA, (WPARAM)lResult, (LPARAM)pScheme);
323 if (SetDefault)
324 {
325 SendDlgItemMessage(hwndDlg, IDC_SOUND_SCHEME, CB_SETCURSEL, (WPARAM)lResult, (LPARAM)0);
326 }
327 }
328 return TRUE;
329 }
330 return FALSE;
331 }
332
333
334 DWORD
335 EnumerateSoundProfiles(HWND hwndDlg, HKEY hKey)
336 {
337 HKEY hSubKey;
338 DWORD dwName, dwCurKey, dwResult, dwNumSchemes;
339 TCHAR szName[MAX_PATH];
340
341 dwName = sizeof(szDefault) / sizeof(TCHAR);
342 if (RegQueryValueEx(hKey,
343 NULL,
344 NULL,
345 NULL,
346 (LPBYTE)szDefault,
347 &dwName) != ERROR_SUCCESS)
348 {
349 return FALSE;
350 }
351
352
353
354 if (RegOpenKeyEx(hKey,
355 _T("Names"),
356 0,
357 KEY_READ,
358 &hSubKey) != ERROR_SUCCESS)
359 {
360 return FALSE;
361 }
362
363 dwNumSchemes = 0;
364 dwCurKey = 0;
365 do
366 {
367 dwName = sizeof(szName) / sizeof(szName[0]);
368 dwResult = RegEnumKeyEx(hSubKey,
369 dwCurKey,
370 szName,
371 &dwName,
372 NULL,
373 NULL,
374 NULL,
375 NULL);
376
377 if (dwResult == ERROR_SUCCESS)
378 {
379 if (AddSoundProfile(hwndDlg, hSubKey, szName, (!_tcsicmp(szName, szDefault))))
380 {
381 dwNumSchemes++;
382 }
383 }
384
385 dwCurKey++;
386 } while (dwResult == ERROR_SUCCESS);
387
388 RegCloseKey(hSubKey);
389 return dwNumSchemes;
390 }
391
392
393 PSOUND_SCHEME_CONTEXT FindSoundProfile(HWND hwndDlg, TCHAR * szName)
394 {
395 LRESULT lCount, lIndex, lResult;
396 PSOUND_SCHEME_CONTEXT pScheme;
397
398 lCount = SendDlgItemMessage(hwndDlg, IDC_SOUND_SCHEME, CB_GETCOUNT, (WPARAM)0, (LPARAM)0);
399 if (lCount == CB_ERR)
400 {
401 return NULL;
402 }
403
404 for(lIndex = 0; lIndex < lCount; lIndex++)
405 {
406 lResult = SendDlgItemMessage(hwndDlg, IDC_SOUND_SCHEME, CB_GETITEMDATA, (WPARAM)lIndex, (LPARAM)0);
407 if (lResult == CB_ERR)
408 {
409 continue;
410 }
411
412 pScheme = (PSOUND_SCHEME_CONTEXT)lResult;
413 if (!_tcsicmp(pScheme->szName, szName))
414 {
415 return pScheme;
416 }
417 }
418 return NULL;
419 }
420
421
422 BOOL
423 ImportSoundLabel(HWND hwndDlg, HKEY hKey, TCHAR * szProfile, TCHAR * szLabelName, TCHAR * szAppName, PAPP_MAP AppMap, PLABEL_MAP LabelMap)
424 {
425 HKEY hSubKey;
426 TCHAR szValue[MAX_PATH];
427 TCHAR szBuffer[MAX_PATH];
428 DWORD dwValue;
429 PSOUND_SCHEME_CONTEXT pScheme;
430 PLABEL_CONTEXT pLabelContext;
431 BOOL bCurrentProfile, bActiveProfile;
432
433 //MessageBox(hwndDlg, szProfile, szLabelName, MB_OK);
434
435 bCurrentProfile = !_tcsicmp(szProfile, _T(".Current"));
436 bActiveProfile = !_tcsicmp(szProfile, szDefault);
437
438 if (RegOpenKeyEx(hKey,
439 szProfile,
440 0,
441 KEY_READ,
442 &hSubKey) != ERROR_SUCCESS)
443 {
444 return FALSE;
445 }
446
447 dwValue = sizeof(szValue) / sizeof(TCHAR);
448 if (RegQueryValueEx(hSubKey,
449 NULL,
450 NULL,
451 NULL,
452 (LPBYTE)szValue,
453 &dwValue) != ERROR_SUCCESS)
454 {
455 return FALSE;
456 }
457
458 if (bCurrentProfile)
459 pScheme = FindSoundProfile(hwndDlg, szDefault);
460 else
461 pScheme = FindSoundProfile(hwndDlg, szProfile);
462
463 if (!pScheme)
464 {
465 //MessageBox(hwndDlg, szProfile, _T("no profile!!"), MB_OK);
466 return FALSE;
467 }
468 pLabelContext = FindLabelContext(pScheme, AppMap->szName, LabelMap->szName);
469
470 dwValue = ExpandEnvironmentStrings(szValue, szBuffer, sizeof(szBuffer) / sizeof(TCHAR));
471 if (dwValue == 0 || dwValue > (sizeof(szBuffer) / sizeof(TCHAR)))
472 {
473 /* fixme */
474 return FALSE;
475 }
476
477 if (bCurrentProfile)
478 _tcscpy(pLabelContext->szValue, szBuffer);
479 else if (!bActiveProfile)
480 _tcscpy(pLabelContext->szValue, szBuffer);
481
482 return TRUE;
483 }
484
485
486 DWORD
487 ImportSoundEntry(HWND hwndDlg, HKEY hKey, TCHAR * szLabelName, TCHAR * szAppName, PAPP_MAP pAppMap)
488 {
489 HKEY hSubKey;
490 DWORD dwNumProfiles;
491 DWORD dwCurKey;
492 DWORD dwResult;
493 DWORD dwProfile;
494 TCHAR szProfile[MAX_PATH];
495 PLABEL_MAP pLabel;
496
497 if (RegOpenKeyEx(hKey,
498 szLabelName,
499 0,
500 KEY_READ,
501 &hSubKey) != ERROR_SUCCESS)
502 {
503 return FALSE;
504 }
505 pLabel = FindLabel(pAppMap, szLabelName);
506
507 ASSERT(pLabel);
508 RemoveLabel(pLabel);
509
510 pLabel->AppMap = pAppMap;
511 pLabel->Next = pAppMap->LabelMap;
512 pAppMap->LabelMap = pLabel;
513
514 dwNumProfiles = 0;
515 dwCurKey = 0;
516 do
517 {
518 dwProfile = sizeof(szProfile) / sizeof(TCHAR);
519 dwResult = RegEnumKeyEx(hSubKey,
520 dwCurKey,
521 szProfile,
522 &dwProfile,
523 NULL,
524 NULL,
525 NULL,
526 NULL);
527
528 if (dwResult == ERROR_SUCCESS)
529 {
530 if (ImportSoundLabel(hwndDlg, hSubKey, szProfile, szLabelName, szAppName, pAppMap, pLabel))
531 {
532 dwNumProfiles++;
533 }
534 }
535
536 dwCurKey++;
537 } while (dwResult == ERROR_SUCCESS);
538
539 RegCloseKey(hSubKey);
540
541 return dwNumProfiles;
542 }
543
544
545 DWORD
546 ImportAppProfile(HWND hwndDlg, HKEY hKey, TCHAR * szAppName)
547 {
548 HKEY hSubKey;
549 TCHAR szDefault[MAX_PATH];
550 DWORD dwDefault;
551 DWORD dwCurKey;
552 DWORD dwResult;
553 DWORD dwNumEntry;
554 DWORD dwName;
555 TCHAR szName[MAX_PATH];
556 TCHAR szIcon[MAX_PATH];
557 PAPP_MAP AppMap;
558
559 //MessageBox(hwndDlg, szAppName, _T("Importing...\n"), MB_OK);
560
561 AppMap = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(APP_MAP));
562 if (!AppMap)
563 return 0;
564
565 if (RegOpenKeyEx(hKey,
566 szAppName,
567 0,
568 KEY_READ,
569 &hSubKey) != ERROR_SUCCESS)
570 {
571 HeapFree(GetProcessHeap(), 0, AppMap);
572 return 0;
573 }
574
575 dwDefault = sizeof(szDefault) / sizeof(TCHAR);
576 if (RegQueryValueEx(hSubKey,
577 NULL,
578 NULL,
579 NULL,
580 (LPBYTE)szDefault,
581 &dwDefault) != ERROR_SUCCESS)
582 {
583 RegCloseKey(hSubKey);
584 HeapFree(GetProcessHeap(), 0, AppMap);
585 return 0;
586 }
587
588 dwDefault = sizeof(szIcon) / sizeof(TCHAR);
589 if (RegQueryValueEx(hSubKey,
590 _T("DispFileName"),
591 NULL,
592 NULL,
593 (LPBYTE)szIcon,
594 &dwDefault) != ERROR_SUCCESS)
595 {
596 szIcon[0] = _T('\0');
597 }
598
599 /* initialize app map */
600 _tcscpy(AppMap->szName, szAppName);
601 _tcscpy(AppMap->szDesc, szDefault);
602 _tcscpy(AppMap->szIcon, szIcon);
603
604 AppMap->Next = s_App;
605 s_App = AppMap;
606
607
608 dwCurKey = 0;
609 dwNumEntry = 0;
610 do
611 {
612 dwName = sizeof(szName) / sizeof(TCHAR);
613 dwResult = RegEnumKeyEx(hSubKey,
614 dwCurKey,
615 szName,
616 &dwName,
617 NULL,
618 NULL,
619 NULL,
620 NULL);
621 if (dwResult == ERROR_SUCCESS)
622 {
623 if (ImportSoundEntry(hwndDlg, hSubKey, szName, szAppName, AppMap))
624 {
625 dwNumEntry++;
626 }
627 }
628 dwCurKey++;
629 } while (dwResult == ERROR_SUCCESS);
630
631 RegCloseKey(hSubKey);
632 return dwNumEntry;
633 }
634
635
636 BOOL
637 ImportSoundProfiles(HWND hwndDlg, HKEY hKey)
638 {
639 DWORD dwCurKey;
640 DWORD dwResult;
641 DWORD dwNumApps;
642 TCHAR szName[MAX_PATH];
643 HKEY hSubKey;
644
645 if (RegOpenKeyEx(hKey,
646 _T("Apps"),
647 0,
648 KEY_READ,
649 &hSubKey) != ERROR_SUCCESS)
650 {
651 return FALSE;
652 }
653
654 dwNumApps = 0;
655 dwCurKey = 0;
656 do
657 {
658 dwResult = RegEnumKey(hSubKey,
659 dwCurKey,
660 szName,
661 sizeof(szName) / sizeof(TCHAR));
662
663 if (dwResult == ERROR_SUCCESS)
664 {
665 if (ImportAppProfile(hwndDlg, hSubKey, szName))
666 {
667 dwNumApps++;
668 }
669 }
670 dwCurKey++;
671 } while (dwResult == ERROR_SUCCESS);
672
673 RegCloseKey(hSubKey);
674
675 return (dwNumApps != 0);
676 }
677
678
679 BOOL
680 LoadSoundProfiles(HWND hwndDlg)
681 {
682 HKEY hSubKey;
683 DWORD dwNumSchemes;
684
685 if (RegOpenKeyEx(HKEY_CURRENT_USER,
686 _T("AppEvents\\Schemes"),
687 0,
688 KEY_READ,
689 &hSubKey) != ERROR_SUCCESS)
690 {
691 return FALSE;
692 }
693
694 dwNumSchemes = EnumerateSoundProfiles(hwndDlg, hSubKey);
695
696
697 if (dwNumSchemes)
698 {
699 //MessageBox(hwndDlg, _T("importing sound profiles..."), NULL, MB_OK);
700 ImportSoundProfiles(hwndDlg, hSubKey);
701 }
702
703 RegCloseKey(hSubKey);
704 return FALSE;
705 }
706
707
708 BOOL
709 LoadSoundFiles(HWND hwndDlg)
710 {
711 WCHAR szPath[MAX_PATH];
712 WCHAR * ptr;
713 WIN32_FIND_DATAW FileData;
714 HANDLE hFile;
715 LRESULT lResult;
716 UINT length;
717
718 /* Add no sound listview item */
719 if (LoadString(hApplet, IDS_NO_SOUND, szPath, MAX_PATH))
720 {
721 szPath[(sizeof(szPath)/sizeof(WCHAR))-1] = L'\0';
722 SendDlgItemMessageW(hwndDlg, IDC_SOUND_LIST, CB_ADDSTRING, (WPARAM)0, (LPARAM)szPath);
723 }
724
725 /* Load sound files */
726 length = GetWindowsDirectoryW(szPath, MAX_PATH);
727 if (length == 0 || length >= MAX_PATH - 9)
728 {
729 return FALSE;
730 }
731 if (szPath[length-1] != L'\\')
732 {
733 szPath[length] = L'\\';
734 length++;
735 }
736 wcscpy(&szPath[length], L"media\\*");
737 length += 7;
738
739 hFile = FindFirstFileW(szPath, &FileData);
740 if (hFile == INVALID_HANDLE_VALUE)
741 {
742 return FALSE;
743 }
744
745 do
746 {
747 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
748 continue;
749
750 ptr = wcsrchr(FileData.cFileName, L'\\');
751 if (ptr)
752 {
753 ptr++;
754 }
755 else
756 {
757 ptr = FileData.cFileName;
758 }
759 lResult = SendDlgItemMessageW(hwndDlg, IDC_SOUND_LIST, CB_ADDSTRING, (WPARAM)0, (LPARAM)ptr);
760 if (lResult != CB_ERR)
761 {
762 wcscpy(&szPath[length-1], FileData.cFileName);
763 SendDlgItemMessageW(hwndDlg, IDC_SOUND_LIST, CB_SETITEMDATA, (WPARAM)lResult, (LPARAM)_wcsdup(szPath));
764 }
765 } while (FindNextFileW(hFile, &FileData) != 0);
766
767 FindClose(hFile);
768 return TRUE;
769 }
770
771
772 BOOL
773 ShowSoundScheme(HWND hwndDlg)
774 {
775 LRESULT lIndex;
776 PSOUND_SCHEME_CONTEXT pScheme;
777 PAPP_MAP pAppMap;
778 LV_ITEM listItem;
779 LV_COLUMN dummy;
780 HWND hDlgCtrl, hList;
781 RECT rect;
782 int ItemIndex;
783 hDlgCtrl = GetDlgItem(hwndDlg, IDC_SOUND_SCHEME);
784 hList = GetDlgItem(hwndDlg, IDC_SCHEME_LIST);
785
786 lIndex = SendMessage(hDlgCtrl, CB_GETCURSEL, (WPARAM)0, (LPARAM)0);
787 if (lIndex == CB_ERR)
788 {
789 return FALSE;
790 }
791
792 lIndex = SendMessage(hDlgCtrl, CB_GETITEMDATA, (WPARAM)lIndex, (LPARAM)0);
793 if (lIndex == CB_ERR)
794 {
795 return FALSE;
796 }
797 pScheme = (PSOUND_SCHEME_CONTEXT)lIndex;
798
799 _tcscpy(szDefault, pScheme->szName);
800
801 /* add column for app */
802 GetClientRect(hList, &rect);
803 ZeroMemory(&dummy, sizeof(LV_COLUMN));
804 dummy.mask = LVCF_WIDTH;
805 dummy.iSubItem = 0;
806 dummy.cx = rect.right - rect.left - GetSystemMetrics(SM_CXVSCROLL);
807 (void)ListView_InsertColumn(hList, 0, &dummy);
808 ItemIndex = 0;
809
810 pAppMap = s_App;
811 while (pAppMap)
812 {
813 PLABEL_MAP pLabelMap = pAppMap->LabelMap;
814 while (pLabelMap)
815 {
816 ZeroMemory(&listItem, sizeof(LV_ITEM));
817 listItem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
818 listItem.pszText = pLabelMap->szDesc;
819 listItem.lParam = (LPARAM)FindLabelContext(pScheme, pAppMap->szName, pLabelMap->szName);
820 listItem.iItem = ItemIndex;
821 listItem.iImage = -1;
822 (void)ListView_InsertItem(hList, &listItem);
823 ItemIndex++;
824
825 pLabelMap = pLabelMap->Next;
826 }
827 pAppMap = pAppMap->Next;
828 }
829 return TRUE;
830 }
831
832
833 BOOL
834 ApplyChanges(HWND hwndDlg)
835 {
836 HKEY hKey, hSubKey;
837 LRESULT lIndex;
838 PSOUND_SCHEME_CONTEXT pScheme;
839 HWND hDlgCtrl;
840 PLABEL_CONTEXT pLabelContext;
841 TCHAR Buffer[100];
842
843 hDlgCtrl = GetDlgItem(hwndDlg, IDC_SOUND_SCHEME);
844
845 lIndex = SendMessage(hDlgCtrl, CB_GETCURSEL, (WPARAM)0, (LPARAM)0);
846 if (lIndex == CB_ERR)
847 {
848 return FALSE;
849 }
850
851 lIndex = SendMessage(hDlgCtrl, CB_GETITEMDATA, (WPARAM)lIndex, (LPARAM)0);
852 if (lIndex == CB_ERR)
853 {
854 return FALSE;
855 }
856 pScheme = (PSOUND_SCHEME_CONTEXT)lIndex;
857
858 if (RegOpenKeyEx(HKEY_CURRENT_USER,
859 _T("AppEvents\\Schemes"),
860 0,
861 KEY_WRITE,
862 &hKey) != ERROR_SUCCESS)
863 {
864 return FALSE;
865 }
866
867 RegSetValueEx(hKey, NULL, 0, REG_SZ, (LPBYTE)pScheme->szName, (_tcslen(pScheme->szName) +1) * sizeof(TCHAR));
868 RegCloseKey(hKey);
869
870 if (RegOpenKeyEx(HKEY_CURRENT_USER,
871 _T("AppEvents\\Schemes\\Apps"),
872 0,
873 KEY_WRITE,
874 &hKey) != ERROR_SUCCESS)
875 {
876 return FALSE;
877 }
878
879 pLabelContext = pScheme->LabelContext;
880
881 while (pLabelContext)
882 {
883 _stprintf(Buffer, _T("%s\\%s\\.Current"), pLabelContext->AppMap->szName, pLabelContext->LabelMap->szName);
884
885 if (RegOpenKeyEx(hKey, Buffer, 0, KEY_WRITE, &hSubKey) == ERROR_SUCCESS)
886 {
887 RegSetValueEx(hSubKey, NULL, 0, REG_EXPAND_SZ, (LPBYTE)pLabelContext->szValue, (_tcslen(pLabelContext->szValue) +1) * sizeof(TCHAR));
888 RegCloseKey(hSubKey);
889 }
890
891 pLabelContext = pLabelContext->Next;
892 }
893 RegCloseKey(hKey);
894
895 SetWindowLong(hwndDlg, DWL_MSGRESULT, (LONG)PSNRET_NOERROR);
896 return TRUE;
897 }
898
899
900 /* Sounds property page dialog callback */
901 INT_PTR
902 CALLBACK
903 SoundsDlgProc(HWND hwndDlg,
904 UINT uMsg,
905 WPARAM wParam,
906 LPARAM lParam)
907 {
908 switch (uMsg)
909 {
910 case WM_INITDIALOG:
911 {
912 UINT NumWavOut = waveOutGetNumDevs();
913
914 SendMessage(GetDlgItem(hwndDlg, IDC_PLAY_SOUND),
915 BM_SETIMAGE,(WPARAM)IMAGE_ICON,
916 (LPARAM)(HANDLE)LoadIcon(hApplet, MAKEINTRESOURCE(IDI_PLAY_ICON)));
917
918 LoadEventLabels();
919 LoadSoundProfiles(hwndDlg);
920 LoadSoundFiles(hwndDlg);
921 ShowSoundScheme(hwndDlg);
922
923 if (!NumWavOut)
924 {
925 EnableWindow(GetDlgItem(hwndDlg, IDC_SOUND_SCHEME), FALSE);
926 EnableWindow(GetDlgItem(hwndDlg, IDC_SAVEAS_BTN), FALSE);
927 EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE_BTN), FALSE);
928 EnableWindow(GetDlgItem(hwndDlg, IDC_SCHEME_LIST), FALSE);
929 }
930
931 if (wParam == (WPARAM)GetDlgItem(hwndDlg, IDC_SOUND_SCHEME))
932 return TRUE;
933 SetFocus(GetDlgItem(hwndDlg, IDC_SOUND_SCHEME));
934 return FALSE;
935 }
936 case WM_COMMAND:
937 {
938 switch (LOWORD(wParam))
939 {
940 case IDC_PLAY_SOUND:
941 {
942 LRESULT lIndex;
943 lIndex = SendDlgItemMessage(hwndDlg, IDC_SOUND_LIST, CB_GETCURSEL, (WPARAM)0, (LPARAM)0);
944 if (lIndex == CB_ERR)
945 {
946 break;
947 }
948
949 lIndex = SendDlgItemMessage(hwndDlg, IDC_SOUND_LIST, CB_GETITEMDATA, (WPARAM)lIndex, (LPARAM)0);
950 if (lIndex != CB_ERR)
951 {
952 PlaySound((TCHAR*)lIndex, NULL, SND_FILENAME);
953 }
954 break;
955 }
956 case IDC_SOUND_SCHEME:
957 {
958 if (HIWORD(wParam) == CBN_SELENDOK)
959 {
960 (void)ListView_DeleteAllItems(GetDlgItem(hwndDlg, IDC_SCHEME_LIST));
961 ShowSoundScheme(hwndDlg);
962 EnableWindow(GetDlgItem(hwndDlg, IDC_SOUND_LIST), FALSE);
963 EnableWindow(GetDlgItem(hwndDlg, IDC_TEXT_SOUND), FALSE);
964 EnableWindow(GetDlgItem(hwndDlg, IDC_PLAY_SOUND), FALSE);
965 EnableWindow(GetDlgItem(hwndDlg, IDC_BROWSE_SOUND), FALSE);
966 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
967 }
968 break;
969 }
970 case IDC_SOUND_LIST:
971 {
972 if (HIWORD(wParam) == CBN_SELENDOK)
973 {
974 PLABEL_CONTEXT pLabelContext;
975 INT SelCount;
976 LVITEM item;
977 LRESULT lIndex;
978 SelCount = ListView_GetSelectionMark(GetDlgItem(hwndDlg, IDC_SCHEME_LIST));
979 if (SelCount == -1)
980 {
981 break;
982 }
983 lIndex = SendDlgItemMessage(hwndDlg, IDC_SOUND_LIST, CB_GETCURSEL, (WPARAM)0, (LPARAM)0);
984 if (lIndex == CB_ERR)
985 {
986 break;
987 }
988 ZeroMemory(&item, sizeof(LVITEM));
989 item.mask = LVIF_PARAM;
990 item.iItem = SelCount;
991 if (ListView_GetItem(GetDlgItem(hwndDlg, IDC_SCHEME_LIST), &item))
992 {
993 LRESULT lResult;
994 pLabelContext = (PLABEL_CONTEXT)item.lParam;
995
996 lResult = SendDlgItemMessage(hwndDlg, IDC_SOUND_LIST, CB_GETITEMDATA, (WPARAM)lIndex, (LPARAM)0);
997 if (lResult == CB_ERR || lResult == 0)
998 {
999 if (lIndex != pLabelContext->szValue[0])
1000 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
1001
1002 pLabelContext->szValue[0] = L'\0';
1003 break;
1004 }
1005
1006 if (_tcsicmp(pLabelContext->szValue, (TCHAR*)lResult) || (lIndex != pLabelContext->szValue[0]))
1007 {
1008 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
1009 ///
1010 /// Should store in current member
1011 ///
1012 _tcscpy(pLabelContext->szValue, (TCHAR*)lResult);
1013 }
1014 if (_tcslen((TCHAR*)lResult) && lIndex != 0)
1015 {
1016 EnableWindow(GetDlgItem(hwndDlg, IDC_PLAY_SOUND), TRUE);
1017 }
1018 else
1019 {
1020 EnableWindow(GetDlgItem(hwndDlg, IDC_PLAY_SOUND), FALSE);
1021 }
1022 }
1023 }
1024 break;
1025 }
1026 }
1027 break;
1028 }
1029 case WM_NOTIFY:
1030 {
1031 LVITEM item;
1032 PLABEL_CONTEXT pLabelContext;
1033 TCHAR * ptr;
1034
1035 LPNMHDR lpnm = (LPNMHDR)lParam;
1036
1037 switch(lpnm->code)
1038 {
1039 case PSN_APPLY:
1040 {
1041 ApplyChanges(hwndDlg);
1042 break;
1043 }
1044 case LVN_ITEMCHANGED:
1045 {
1046 LPNMLISTVIEW nm = (LPNMLISTVIEW)lParam;
1047
1048 if ((nm->uNewState & LVIS_SELECTED) == 0)
1049 {
1050 return FALSE;
1051 }
1052 ZeroMemory(&item, sizeof(LVITEM));
1053 item.mask = LVIF_PARAM;
1054 item.iItem = nm->iItem;
1055
1056 if (ListView_GetItem(GetDlgItem(hwndDlg, IDC_SCHEME_LIST), &item))
1057 {
1058 LRESULT lCount, lIndex, lResult;
1059 pLabelContext = (PLABEL_CONTEXT)item.lParam;
1060 if (!pLabelContext)
1061 {
1062 return FALSE;
1063 }
1064 EnableWindow(GetDlgItem(hwndDlg, IDC_SOUND_LIST), TRUE);
1065 EnableWindow(GetDlgItem(hwndDlg, IDC_TEXT_SOUND), TRUE);
1066 EnableWindow(GetDlgItem(hwndDlg, IDC_BROWSE_SOUND), TRUE);
1067 if (_tcslen(pLabelContext->szValue) == 0)
1068 {
1069 lIndex = SendDlgItemMessage(hwndDlg, IDC_SOUND_LIST, CB_SETCURSEL, (WPARAM)0, (LPARAM)0);
1070 EnableWindow(GetDlgItem(hwndDlg, IDC_PLAY_SOUND), FALSE);
1071 break;
1072
1073 }
1074 EnableWindow(GetDlgItem(hwndDlg, IDC_PLAY_SOUND), TRUE);
1075 lCount = SendDlgItemMessage(hwndDlg, IDC_SOUND_LIST, CB_GETCOUNT, (WPARAM)0, (LPARAM)0);
1076 for (lIndex = 0; lIndex < lCount; lIndex++)
1077 {
1078 lResult = SendDlgItemMessage(hwndDlg, IDC_SOUND_LIST, CB_GETITEMDATA, (WPARAM)lIndex, (LPARAM)0);
1079 if (lResult == CB_ERR || lResult == 0)
1080 continue;
1081
1082 if (!_tcscmp((TCHAR*)lResult, pLabelContext->szValue))
1083 {
1084 SendDlgItemMessage(hwndDlg, IDC_SOUND_LIST, CB_SETCURSEL, (WPARAM)lIndex, (LPARAM)0);
1085 return FALSE;
1086 }
1087 }
1088 ptr = _tcsrchr(pLabelContext->szValue, _T('\\'));
1089 if (ptr)
1090 {
1091 ptr++;
1092 }
1093 else
1094 {
1095 ptr = pLabelContext->szValue;
1096 }
1097 lIndex = SendDlgItemMessage(hwndDlg, IDC_SOUND_LIST, CB_ADDSTRING, (WPARAM)0, (LPARAM)ptr);
1098 if (lIndex != CB_ERR)
1099 {
1100 SendDlgItemMessage(hwndDlg, IDC_SOUND_LIST, CB_SETITEMDATA, (WPARAM)lIndex, (LPARAM)_tcsdup(pLabelContext->szValue));
1101 SendDlgItemMessage(hwndDlg, IDC_SOUND_LIST, CB_SETCURSEL, (WPARAM)lIndex, (LPARAM)0);
1102 }
1103 }
1104 break;
1105 }
1106 }
1107 }
1108 break;
1109 }
1110
1111 return FALSE;
1112 }