- Update to r53061
[reactos.git] / 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: lib/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
70 pMap = pAppMap->LabelMap;
71
72 while(pMap)
73 {
74 ASSERT(pMap);
75 ASSERT(pMap->szName);
76 if (!_tcscmp(pMap->szName, szName))
77 return pMap;
78
79 pMap = pMap->Next;
80
81 }
82
83 pMap = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LABEL_MAP));
84 if (!pMap)
85 return NULL;
86
87 pMap->szName = pMap->szDesc = _tcsdup(szName);
88 if (!pMap->szName)
89 {
90 HeapFree(GetProcessHeap(), 0, pMap);
91 return NULL;
92 }
93 pMap->AppMap = pAppMap;
94 pMap->Next = s_Map;
95 s_Map = pMap;
96
97 return pMap;
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
111 while(pCurMap)
112 {
113 if (pCurMap->Next == pMap)
114 {
115 pCurMap->Next = pCurMap->Next->Next;
116 return;
117 }
118 pCurMap = pCurMap->Next;
119 }
120 }
121
122
123
124
125
126
127 PAPP_MAP FindApp(TCHAR * szName)
128 {
129 PAPP_MAP pMap = s_App;
130
131 while(pMap)
132 {
133 if (!_tcscmp(pMap->szName, szName))
134 return pMap;
135
136 pMap = pMap->Next;
137
138 }
139 return NULL;
140 }
141
142 PLABEL_CONTEXT FindLabelContext(PSOUND_SCHEME_CONTEXT pSoundScheme, TCHAR * AppName, TCHAR * LabelName)
143 {
144 PLABEL_CONTEXT pLabelContext;
145
146 pLabelContext = pSoundScheme->LabelContext;
147
148 while(pLabelContext)
149 {
150 ASSERT(pLabelContext->AppMap);
151 ASSERT(pLabelContext->LabelMap);
152
153 if(!_tcsicmp(pLabelContext->AppMap->szName, AppName) && !_tcsicmp(pLabelContext->LabelMap->szName, LabelName))
154 {
155 return pLabelContext;
156 }
157 pLabelContext = pLabelContext->Next;
158 }
159
160 pLabelContext = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LABEL_CONTEXT));
161 if (!pLabelContext)
162 return NULL;
163
164 pLabelContext->AppMap = FindApp(AppName);
165 pLabelContext->LabelMap = FindLabel(pLabelContext->AppMap, LabelName);
166 ASSERT(pLabelContext->AppMap);
167 ASSERT(pLabelContext->LabelMap);
168 pLabelContext->szValue[0] = _T('\0');
169 pLabelContext->Next = pSoundScheme->LabelContext;
170 pSoundScheme->LabelContext = pLabelContext;
171
172 return pLabelContext;
173 }
174
175 BOOL
176 LoadEventLabel(HKEY hKey, TCHAR * szSubKey)
177 {
178 HKEY hSubKey;
179 DWORD dwData;
180 DWORD dwDesc;
181 TCHAR szDesc[MAX_PATH];
182 TCHAR szData[MAX_PATH];
183 PLABEL_MAP pMap;
184
185 if (RegOpenKeyEx(hKey,
186 szSubKey,
187 0,
188 KEY_READ,
189 &hSubKey) != ERROR_SUCCESS)
190 {
191 return FALSE;
192 }
193
194 dwDesc = sizeof(szDesc) / sizeof(TCHAR);
195 if (RegQueryValueEx(hSubKey,
196 NULL,
197 NULL,
198 NULL,
199 (LPBYTE)szDesc,
200 &dwDesc) != ERROR_SUCCESS)
201 {
202 RegCloseKey(hSubKey);
203 return FALSE;
204 }
205
206 dwData = sizeof(szDesc) / sizeof(TCHAR);
207 if (RegQueryValueEx(hSubKey,
208 _T("DispFileName"),
209 NULL,
210 NULL,
211 (LPBYTE)szData,
212 &dwData) != ERROR_SUCCESS)
213 {
214 RegCloseKey(hSubKey);
215 return FALSE;
216 }
217
218 pMap = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LABEL_MAP));
219 if (!pMap)
220 {
221 return FALSE;
222 }
223 pMap->szName = _tcsdup(szSubKey);
224 pMap->szDesc = _tcsdup(szDesc);
225 pMap->szIcon = _tcsdup(szData);
226
227 if (s_Map)
228 {
229 pMap->Next = s_Map;
230 s_Map = pMap;
231 }
232 else
233 {
234 s_Map = pMap;
235 s_Map->Next = 0;
236 }
237 return TRUE;
238 }
239
240 BOOL
241 LoadEventLabels()
242 {
243 HKEY hSubKey;
244 DWORD dwCurKey;
245 TCHAR szName[MAX_PATH];
246 DWORD dwName;
247 DWORD dwResult;
248 DWORD dwCount;
249 if (RegOpenKeyEx(HKEY_CURRENT_USER,
250 _T("AppEvents\\EventLabels"),
251 0,
252 KEY_READ,
253 &hSubKey) != ERROR_SUCCESS)
254 {
255 return FALSE;
256 }
257
258 dwCurKey = 0;
259 dwCount = 0;
260 do
261 {
262 dwName = sizeof(szName) / sizeof(szName[0]);
263 dwResult = RegEnumKeyEx(hSubKey,
264 dwCurKey,
265 szName,
266 &dwName,
267 NULL,
268 NULL,
269 NULL,
270 NULL);
271
272 if (dwResult == ERROR_SUCCESS)
273 {
274 if (LoadEventLabel(hSubKey, szName))
275 {
276 dwCount++;
277 }
278 }
279 dwCurKey++;
280
281 }while(dwResult == ERROR_SUCCESS);
282
283 RegCloseKey(hSubKey);
284 return (dwCount != 0);
285 }
286
287 BOOL
288 AddSoundProfile(HWND hwndDlg, HKEY hKey, TCHAR * szSubKey, BOOL SetDefault)
289 {
290 HKEY hSubKey;
291 TCHAR szValue[MAX_PATH];
292 DWORD dwValue, dwResult;
293
294 if (RegOpenKeyEx(hKey,
295 szSubKey,
296 0,
297 KEY_READ,
298 &hSubKey) != ERROR_SUCCESS)
299 {
300 return FALSE;
301 }
302
303 dwValue = sizeof(szValue) / sizeof(TCHAR);
304 dwResult = RegQueryValueEx(hSubKey,
305 NULL,
306 NULL,
307 NULL,
308 (LPBYTE)szValue,
309 &dwValue);
310 RegCloseKey(hSubKey);
311 if (dwResult == ERROR_SUCCESS)
312 {
313 LRESULT lResult = SendDlgItemMessage(hwndDlg, IDC_SOUND_SCHEME, CB_ADDSTRING, (WPARAM)0, (LPARAM)szValue);
314 if (lResult != CB_ERR)
315 {
316 PSOUND_SCHEME_CONTEXT pScheme = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SOUND_SCHEME_CONTEXT));
317 if (pScheme != NULL)
318 {
319 _tcscpy(pScheme->szDesc, szValue);
320 _tcscpy(pScheme->szName, szSubKey);
321 }
322
323 SendDlgItemMessage(hwndDlg, IDC_SOUND_SCHEME, CB_SETITEMDATA, (WPARAM)lResult, (LPARAM)pScheme);
324 if (SetDefault)
325 {
326 SendDlgItemMessage(hwndDlg, IDC_SOUND_SCHEME, CB_SETCURSEL, (WPARAM)lResult, (LPARAM)0);
327 }
328 }
329 return TRUE;
330 }
331 return FALSE;
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 PSOUND_SCHEME_CONTEXT FindSoundProfile(HWND hwndDlg, TCHAR * szName)
393 {
394 LRESULT lCount, lIndex, lResult;
395 PSOUND_SCHEME_CONTEXT pScheme;
396
397 lCount = SendDlgItemMessage(hwndDlg, IDC_SOUND_SCHEME, CB_GETCOUNT, (WPARAM)0, (LPARAM)0);
398 if (lCount == CB_ERR)
399 {
400 return NULL;
401 }
402
403 for(lIndex = 0; lIndex < lCount; lIndex++)
404 {
405 lResult = SendDlgItemMessage(hwndDlg, IDC_SOUND_SCHEME, CB_GETITEMDATA, (WPARAM)lIndex, (LPARAM)0);
406 if (lResult == CB_ERR)
407 {
408 continue;
409 }
410
411 pScheme = (PSOUND_SCHEME_CONTEXT)lResult;
412 if (!_tcsicmp(pScheme->szName, szName))
413 {
414 return pScheme;
415 }
416 }
417 return NULL;
418 }
419 BOOL
420 ImportSoundLabel(HWND hwndDlg, HKEY hKey, TCHAR * szProfile, TCHAR * szLabelName, TCHAR * szAppName, PAPP_MAP AppMap, PLABEL_MAP LabelMap)
421 {
422 HKEY hSubKey;
423 TCHAR szValue[MAX_PATH];
424 TCHAR szBuffer[MAX_PATH];
425 DWORD dwValue;
426 PSOUND_SCHEME_CONTEXT pScheme;
427 PLABEL_CONTEXT pLabelContext;
428 BOOL bCurrentProfile, bActiveProfile;
429
430
431 //MessageBox(hwndDlg, szProfile, szLabelName, MB_OK);
432
433 bCurrentProfile = !_tcsicmp(szProfile, _T(".Current"));
434 bActiveProfile = !_tcsicmp(szProfile, szDefault);
435
436
437 if (RegOpenKeyEx(hKey,
438 szProfile,
439 0,
440 KEY_READ,
441 &hSubKey) != ERROR_SUCCESS)
442 {
443 return FALSE;
444 }
445
446 dwValue = sizeof(szValue) / sizeof(TCHAR);
447 if (RegQueryValueEx(hSubKey,
448 NULL,
449 NULL,
450 NULL,
451 (LPBYTE)szValue,
452 &dwValue) != ERROR_SUCCESS)
453 {
454 return FALSE;
455 }
456
457 if (bCurrentProfile)
458 pScheme = FindSoundProfile(hwndDlg, szDefault);
459 else
460 pScheme = FindSoundProfile(hwndDlg, szProfile);
461
462 if (!pScheme)
463 {
464 //MessageBox(hwndDlg, szProfile, _T("no profile!!"), MB_OK);
465 return FALSE;
466 }
467 pLabelContext = FindLabelContext(pScheme, AppMap->szName, LabelMap->szName);
468
469 dwValue = ExpandEnvironmentStrings(szValue, szBuffer, sizeof(szBuffer) / sizeof(TCHAR));
470 if (dwValue == 0 || dwValue > (sizeof(szBuffer) / sizeof(TCHAR)))
471 {
472 /* fixme */
473 return FALSE;
474 }
475
476 if (bCurrentProfile)
477 _tcscpy(pLabelContext->szValue, szBuffer);
478 else if (!bActiveProfile)
479 _tcscpy(pLabelContext->szValue, szBuffer);
480
481 return TRUE;
482 }
483
484
485 DWORD
486 ImportSoundEntry(HWND hwndDlg, HKEY hKey, TCHAR * szLabelName, TCHAR * szAppName, PAPP_MAP pAppMap)
487 {
488 HKEY hSubKey;
489 DWORD dwNumProfiles;
490 DWORD dwCurKey;
491 DWORD dwResult;
492 DWORD dwProfile;
493 TCHAR szProfile[MAX_PATH];
494 PLABEL_MAP pLabel;
495
496 if (RegOpenKeyEx(hKey,
497 szLabelName,
498 0,
499 KEY_READ,
500 &hSubKey) != ERROR_SUCCESS)
501 {
502 return FALSE;
503 }
504 pLabel = FindLabel(pAppMap, szLabelName);
505
506 ASSERT(pLabel);
507 RemoveLabel(pLabel);
508
509 pLabel->AppMap = pAppMap;
510 pLabel->Next = pAppMap->LabelMap;
511 pAppMap->LabelMap = pLabel;
512
513 dwNumProfiles = 0;
514 dwCurKey = 0;
515 do
516 {
517 dwProfile = sizeof(szProfile) / sizeof(TCHAR);
518 dwResult = RegEnumKeyEx(hSubKey,
519 dwCurKey,
520 szProfile,
521 &dwProfile,
522 NULL,
523 NULL,
524 NULL,
525 NULL);
526
527 if (dwResult == ERROR_SUCCESS)
528 {
529 if (ImportSoundLabel(hwndDlg, hSubKey, szProfile, szLabelName, szAppName, pAppMap, pLabel))
530 {
531 dwNumProfiles++;
532 }
533 }
534
535 dwCurKey++;
536 }while(dwResult == ERROR_SUCCESS);
537
538 RegCloseKey(hSubKey);
539
540 return dwNumProfiles;
541 }
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 RegCloseKey(hSubKey);
631 return dwNumEntry;
632 }
633
634 BOOL
635 ImportSoundProfiles(HWND hwndDlg, HKEY hKey)
636 {
637 DWORD dwCurKey;
638 DWORD dwResult;
639 DWORD dwNumApps;
640 TCHAR szName[MAX_PATH];
641 HKEY hSubKey;
642
643 if (RegOpenKeyEx(hKey,
644 _T("Apps"),
645 0,
646 KEY_READ,
647 &hSubKey) != ERROR_SUCCESS)
648 {
649 return FALSE;
650 }
651
652 dwNumApps = 0;
653 dwCurKey = 0;
654 do
655 {
656 dwResult = RegEnumKey(hSubKey,
657 dwCurKey,
658 szName,
659 sizeof(szName) / sizeof(TCHAR));
660
661 if (dwResult == ERROR_SUCCESS)
662 {
663 if (ImportAppProfile(hwndDlg, hSubKey, szName))
664 {
665 dwNumApps++;
666 }
667 }
668 dwCurKey++;
669 }while(dwResult == ERROR_SUCCESS);
670 RegCloseKey(hSubKey);
671
672 return (dwNumApps != 0);
673 }
674
675
676
677 BOOL
678 LoadSoundProfiles(HWND hwndDlg)
679 {
680 HKEY hSubKey;
681 DWORD dwNumSchemes;
682
683 if (RegOpenKeyEx(HKEY_CURRENT_USER,
684 _T("AppEvents\\Schemes"),
685 0,
686 KEY_READ,
687 &hSubKey) != ERROR_SUCCESS)
688 {
689 return FALSE;
690 }
691
692 dwNumSchemes = EnumerateSoundProfiles(hwndDlg, hSubKey);
693
694
695 if (dwNumSchemes)
696 {
697 //MessageBox(hwndDlg, _T("importing sound profiles..."), NULL, MB_OK);
698 ImportSoundProfiles(hwndDlg, hSubKey);
699 }
700 RegCloseKey(hSubKey);
701 return FALSE;
702 }
703 BOOL
704 LoadSoundFiles(HWND hwndDlg)
705 {
706 WCHAR szPath[MAX_PATH];
707 WCHAR * ptr;
708 WIN32_FIND_DATAW FileData;
709 HANDLE hFile;
710 LRESULT lResult;
711 UINT length;
712
713 /* Add no sound listview item */
714 if (LoadString(hApplet, IDS_NO_SOUND, szPath, MAX_PATH))
715 {
716 szPath[(sizeof(szPath)/sizeof(WCHAR))-1] = L'\0';
717 SendDlgItemMessageW(hwndDlg, IDC_SOUND_LIST, CB_ADDSTRING, (WPARAM)0, (LPARAM)szPath);
718 }
719
720 /* Load sound files */
721 length = GetWindowsDirectoryW(szPath, MAX_PATH);
722 if (length == 0 || length >= MAX_PATH - 9)
723 {
724 return FALSE;
725 }
726 if (szPath[length-1] != L'\\')
727 {
728 szPath[length] = L'\\';
729 length++;
730 }
731 wcscpy(&szPath[length], L"media\\*");
732 length += 7;
733
734 hFile = FindFirstFileW(szPath, &FileData);
735 if (hFile == INVALID_HANDLE_VALUE)
736 {
737 return FALSE;
738 }
739
740 do
741 {
742 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
743 continue;
744
745 ptr = wcsrchr(FileData.cFileName, L'\\');
746 if (ptr)
747 {
748 ptr++;
749 }
750 else
751 {
752 ptr = FileData.cFileName;
753 }
754 lResult = SendDlgItemMessageW(hwndDlg, IDC_SOUND_LIST, CB_ADDSTRING, (WPARAM)0, (LPARAM)ptr);
755 if (lResult != CB_ERR)
756 {
757 wcscpy(&szPath[length-1], FileData.cFileName);
758 SendDlgItemMessageW(hwndDlg, IDC_SOUND_LIST, CB_SETITEMDATA, (WPARAM)lResult, (LPARAM)_wcsdup(szPath));
759 }
760 }while(FindNextFileW(hFile, &FileData) != 0);
761
762 FindClose(hFile);
763 return TRUE;
764 }
765
766
767
768 BOOL
769 ShowSoundScheme(HWND hwndDlg)
770 {
771 LRESULT lIndex;
772 PSOUND_SCHEME_CONTEXT pScheme;
773 PAPP_MAP pAppMap;
774 LV_ITEM listItem;
775 LV_COLUMN dummy;
776 HWND hDlgCtrl, hList;
777 RECT rect;
778 int ItemIndex;
779 hDlgCtrl = GetDlgItem(hwndDlg, IDC_SOUND_SCHEME);
780 hList = GetDlgItem(hwndDlg, IDC_SCHEME_LIST);
781
782 lIndex = SendMessage(hDlgCtrl, CB_GETCURSEL, (WPARAM)0, (LPARAM)0);
783 if (lIndex == CB_ERR)
784 {
785 return FALSE;
786 }
787
788 lIndex = SendMessage(hDlgCtrl, CB_GETITEMDATA, (WPARAM)lIndex, (LPARAM)0);
789 if (lIndex == CB_ERR)
790 {
791 return FALSE;
792 }
793 pScheme = (PSOUND_SCHEME_CONTEXT)lIndex;
794
795 _tcscpy(szDefault, pScheme->szName);
796
797 /* add column for app */
798 GetClientRect(hList, &rect);
799 ZeroMemory(&dummy, sizeof(LV_COLUMN));
800 dummy.mask = LVCF_WIDTH;
801 dummy.iSubItem = 0;
802 dummy.cx = rect.right - rect.left - GetSystemMetrics(SM_CXVSCROLL);
803 (void)ListView_InsertColumn(hList, 0, &dummy);
804 ItemIndex = 0;
805
806 pAppMap = s_App;
807 while(pAppMap)
808 {
809 PLABEL_MAP pLabelMap = pAppMap->LabelMap;
810 while(pLabelMap)
811 {
812 ZeroMemory(&listItem, sizeof(LV_ITEM));
813 listItem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
814 listItem.pszText = pLabelMap->szDesc;
815 listItem.lParam = (LPARAM)FindLabelContext(pScheme, pAppMap->szName, pLabelMap->szName);
816 listItem.iItem = ItemIndex;
817 listItem.iImage = -1;
818 (void)ListView_InsertItem(hList, &listItem);
819 ItemIndex++;
820
821 pLabelMap = pLabelMap->Next;
822 }
823 pAppMap = pAppMap->Next;
824 }
825 return TRUE;
826 }
827
828 BOOL
829 ApplyChanges(HWND hwndDlg)
830 {
831 HKEY hKey, hSubKey;
832 LRESULT lIndex;
833 PSOUND_SCHEME_CONTEXT pScheme;
834 HWND hDlgCtrl;
835 PLABEL_CONTEXT pLabelContext;
836 TCHAR Buffer[100];
837
838 hDlgCtrl = GetDlgItem(hwndDlg, IDC_SOUND_SCHEME);
839
840 lIndex = SendMessage(hDlgCtrl, CB_GETCURSEL, (WPARAM)0, (LPARAM)0);
841 if (lIndex == CB_ERR)
842 {
843 return FALSE;
844 }
845
846 lIndex = SendMessage(hDlgCtrl, CB_GETITEMDATA, (WPARAM)lIndex, (LPARAM)0);
847 if (lIndex == CB_ERR)
848 {
849 return FALSE;
850 }
851 pScheme = (PSOUND_SCHEME_CONTEXT)lIndex;
852
853 if (RegOpenKeyEx(HKEY_CURRENT_USER,
854 _T("AppEvents\\Schemes"),
855 0,
856 KEY_WRITE,
857 &hKey) != ERROR_SUCCESS)
858 {
859 return FALSE;
860 }
861
862 RegSetValueEx(hKey, NULL, 0, REG_SZ, (LPBYTE)pScheme->szName, (_tcslen(pScheme->szName) +1) * sizeof(TCHAR));
863 RegCloseKey(hKey);
864
865 if (RegOpenKeyEx(HKEY_CURRENT_USER,
866 _T("AppEvents\\Schemes\\Apps"),
867 0,
868 KEY_WRITE,
869 &hKey) != ERROR_SUCCESS)
870 {
871 return FALSE;
872 }
873
874 pLabelContext = pScheme->LabelContext;
875
876 while(pLabelContext)
877 {
878 _stprintf(Buffer, _T("%s\\%s\\.Current"), pLabelContext->AppMap->szName, pLabelContext->LabelMap->szName);
879
880 if (RegOpenKeyEx(hKey, Buffer, 0, KEY_WRITE, &hSubKey) == ERROR_SUCCESS)
881 {
882 RegSetValueEx(hSubKey, NULL, 0, REG_EXPAND_SZ, (LPBYTE)pLabelContext->szValue, (_tcslen(pLabelContext->szValue) +1) * sizeof(TCHAR));
883 RegCloseKey(hSubKey);
884 }
885
886 pLabelContext = pLabelContext->Next;
887 }
888 RegCloseKey(hKey);
889
890 SetWindowLong(hwndDlg, DWL_MSGRESULT, (LONG)PSNRET_NOERROR);
891 return TRUE;
892 }
893
894
895 /* Sounds property page dialog callback */
896 INT_PTR
897 CALLBACK
898 SoundsDlgProc(HWND hwndDlg,
899 UINT uMsg,
900 WPARAM wParam,
901 LPARAM lParam)
902 {
903 switch(uMsg)
904 {
905 case WM_INITDIALOG:
906 {
907 UINT NumWavOut = waveOutGetNumDevs();
908
909 SendMessage(GetDlgItem(hwndDlg, IDC_PLAY_SOUND),
910 BM_SETIMAGE,(WPARAM)IMAGE_ICON,
911 (LPARAM)(HANDLE)LoadIcon(hApplet, MAKEINTRESOURCE(IDI_PLAY_ICON)));
912
913 LoadEventLabels();
914 LoadSoundProfiles(hwndDlg);
915 LoadSoundFiles(hwndDlg);
916 ShowSoundScheme(hwndDlg);
917
918 if (!NumWavOut)
919 {
920 EnableWindow(GetDlgItem(hwndDlg, IDC_SOUND_SCHEME), FALSE);
921 EnableWindow(GetDlgItem(hwndDlg, IDC_SAVEAS_BTN), FALSE);
922 EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE_BTN), FALSE);
923 EnableWindow(GetDlgItem(hwndDlg, IDC_SCHEME_LIST), FALSE);
924 }
925
926 if (wParam == (WPARAM)GetDlgItem(hwndDlg, IDC_SOUND_SCHEME))
927 return TRUE;
928 SetFocus(GetDlgItem(hwndDlg, IDC_SOUND_SCHEME));
929 return FALSE;
930 }
931 case WM_COMMAND:
932 {
933 switch(LOWORD(wParam))
934 {
935 case IDC_PLAY_SOUND:
936 {
937 LRESULT lIndex;
938 lIndex = SendDlgItemMessage(hwndDlg, IDC_SOUND_LIST, CB_GETCURSEL, (WPARAM)0, (LPARAM)0);
939 if (lIndex == CB_ERR)
940 {
941 break;
942 }
943
944 lIndex = SendDlgItemMessage(hwndDlg, IDC_SOUND_LIST, CB_GETITEMDATA, (WPARAM)lIndex, (LPARAM)0);
945 if (lIndex != CB_ERR)
946 {
947 PlaySound((TCHAR*)lIndex, NULL, SND_FILENAME);
948 }
949 break;
950 }
951 case IDC_SOUND_SCHEME:
952 {
953 if (HIWORD(wParam) == CBN_SELENDOK)
954 {
955 (void)ListView_DeleteAllItems(GetDlgItem(hwndDlg, IDC_SCHEME_LIST));
956 ShowSoundScheme(hwndDlg);
957 EnableWindow(GetDlgItem(hwndDlg, IDC_SOUND_LIST), FALSE);
958 EnableWindow(GetDlgItem(hwndDlg, IDC_TEXT_SOUND), FALSE);
959 EnableWindow(GetDlgItem(hwndDlg, IDC_PLAY_SOUND), FALSE);
960 EnableWindow(GetDlgItem(hwndDlg, IDC_BROWSE_SOUND), FALSE);
961 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
962 }
963 break;
964 }
965 case IDC_SOUND_LIST:
966 {
967 if (HIWORD(wParam) == CBN_SELENDOK)
968 {
969 PLABEL_CONTEXT pLabelContext;
970 INT SelCount;
971 LVITEM item;
972 LRESULT lIndex;
973 SelCount = ListView_GetSelectionMark(GetDlgItem(hwndDlg, IDC_SCHEME_LIST));
974 if (SelCount == -1)
975 {
976 break;
977 }
978 lIndex = SendDlgItemMessage(hwndDlg, IDC_SOUND_LIST, CB_GETCURSEL, (WPARAM)0, (LPARAM)0);
979 if (lIndex == CB_ERR)
980 {
981 break;
982 }
983 ZeroMemory(&item, sizeof(LVITEM));
984 item.mask = LVIF_PARAM;
985 item.iItem = SelCount;
986 if (ListView_GetItem(GetDlgItem(hwndDlg, IDC_SCHEME_LIST), &item))
987 {
988 LRESULT lResult;
989 pLabelContext = (PLABEL_CONTEXT)item.lParam;
990
991 lResult = SendDlgItemMessage(hwndDlg, IDC_SOUND_LIST, CB_GETITEMDATA, (WPARAM)lIndex, (LPARAM)0);
992 if (lResult == CB_ERR || lResult == 0)
993 {
994 if (lIndex != pLabelContext->szValue[0])
995 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
996
997 pLabelContext->szValue[0] = L'\0';
998 break;
999 }
1000
1001 if (_tcsicmp(pLabelContext->szValue, (TCHAR*)lResult) || (lIndex != pLabelContext->szValue[0]))
1002 {
1003 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
1004 ///
1005 /// should store in current member
1006 ///
1007 _tcscpy(pLabelContext->szValue, (TCHAR*)lResult);
1008 }
1009 if (_tcslen((TCHAR*)lResult) && lIndex != 0)
1010 {
1011 EnableWindow(GetDlgItem(hwndDlg, IDC_PLAY_SOUND), TRUE);
1012 }
1013 else
1014 {
1015 EnableWindow(GetDlgItem(hwndDlg, IDC_PLAY_SOUND), FALSE);
1016 }
1017 }
1018 }
1019 break;
1020 }
1021 }
1022 break;
1023 }
1024 case WM_NOTIFY:
1025 {
1026 LVITEM item;
1027 PLABEL_CONTEXT pLabelContext;
1028 LPPSHNOTIFY lppsn;
1029 TCHAR * ptr;
1030
1031 LPNMHDR lpnm = (LPNMHDR)lParam;
1032 lppsn = (LPPSHNOTIFY) lParam;
1033
1034 switch(lpnm->code)
1035 {
1036 case PSN_APPLY:
1037 {
1038 ApplyChanges(hwndDlg);
1039 break;
1040 }
1041 case LVN_ITEMCHANGED:
1042 {
1043 LPNMLISTVIEW nm = (LPNMLISTVIEW)lParam;
1044
1045 if ((nm->uNewState & LVIS_SELECTED) == 0)
1046 {
1047 return FALSE;
1048 }
1049 ZeroMemory(&item, sizeof(LVITEM));
1050 item.mask = LVIF_PARAM;
1051 item.iItem = nm->iItem;
1052
1053 if (ListView_GetItem(GetDlgItem(hwndDlg, IDC_SCHEME_LIST), &item))
1054 {
1055 LRESULT lCount, lIndex, lResult;
1056 pLabelContext = (PLABEL_CONTEXT)item.lParam;
1057 if (!pLabelContext)
1058 {
1059 return FALSE;
1060 }
1061 EnableWindow(GetDlgItem(hwndDlg, IDC_SOUND_LIST), TRUE);
1062 EnableWindow(GetDlgItem(hwndDlg, IDC_TEXT_SOUND), TRUE);
1063 EnableWindow(GetDlgItem(hwndDlg, IDC_BROWSE_SOUND), TRUE);
1064 if (_tcslen(pLabelContext->szValue) == 0)
1065 {
1066 lIndex = SendDlgItemMessage(hwndDlg, IDC_SOUND_LIST, CB_SETCURSEL, (WPARAM)0, (LPARAM)0);
1067 EnableWindow(GetDlgItem(hwndDlg, IDC_PLAY_SOUND), FALSE);
1068 break;
1069
1070 }
1071 EnableWindow(GetDlgItem(hwndDlg, IDC_PLAY_SOUND), TRUE);
1072 lCount = SendDlgItemMessage(hwndDlg, IDC_SOUND_LIST, CB_GETCOUNT, (WPARAM)0, (LPARAM)0);
1073 for (lIndex = 0; lIndex < lCount; lIndex++)
1074 {
1075 lResult = SendDlgItemMessage(hwndDlg, IDC_SOUND_LIST, CB_GETITEMDATA, (WPARAM)lIndex, (LPARAM)0);
1076 if (lResult == CB_ERR || lResult == 0)
1077 continue;
1078
1079 if (!_tcscmp((TCHAR*)lResult, pLabelContext->szValue))
1080 {
1081 SendDlgItemMessage(hwndDlg, IDC_SOUND_LIST, CB_SETCURSEL, (WPARAM)lIndex, (LPARAM)0);
1082 return FALSE;
1083 }
1084 }
1085 ptr = _tcsrchr(pLabelContext->szValue, _T('\\'));
1086 if (ptr)
1087 {
1088 ptr++;
1089 }
1090 else
1091 {
1092 ptr = pLabelContext->szValue;
1093 }
1094 lIndex = SendDlgItemMessage(hwndDlg, IDC_SOUND_LIST, CB_ADDSTRING, (WPARAM)0, (LPARAM)ptr);
1095 if (lIndex != CB_ERR)
1096 {
1097 SendDlgItemMessage(hwndDlg, IDC_SOUND_LIST, CB_SETITEMDATA, (WPARAM)lIndex, (LPARAM)_tcsdup(pLabelContext->szValue));
1098 SendDlgItemMessage(hwndDlg, IDC_SOUND_LIST, CB_SETCURSEL, (WPARAM)lIndex, (LPARAM)0);
1099 }
1100 }
1101 break;
1102 }
1103 }
1104 }
1105 break;
1106 }
1107
1108 return FALSE;
1109 }