[KSPROXY]
[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: 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 <windows.h>
12 #include <commctrl.h>
13 #include <setupapi.h>
14 #include <cpl.h>
15 #include <tchar.h>
16 #include <stdio.h>
17 #include "mmsys.h"
18 #include "resource.h"
19 #include <debug.h>
20
21 struct __APP_MAP__;
22
23 typedef struct __LABEL_MAP__
24 {
25 TCHAR * szName;
26 TCHAR * szDesc;
27 TCHAR * szIcon;
28 struct __APP_MAP__ * AppMap;
29 struct __LABEL_MAP__ * Next;
30 }LABEL_MAP, *PLABEL_MAP;
31
32 typedef struct __APP_MAP__
33 {
34 TCHAR szName[MAX_PATH];
35 TCHAR szDesc[MAX_PATH];
36 TCHAR szIcon[MAX_PATH];
37
38 struct __APP_MAP__ *Next;
39 PLABEL_MAP LabelMap;
40 }APP_MAP, *PAPP_MAP;
41
42 typedef struct __LABEL_CONTEXT__
43 {
44 PLABEL_MAP LabelMap;
45 PAPP_MAP AppMap;
46 TCHAR szValue[MAX_PATH];
47 struct __LABEL_CONTEXT__ *Next;
48 }LABEL_CONTEXT, *PLABEL_CONTEXT;
49
50 typedef struct __SOUND_SCHEME_CONTEXT__
51 {
52 TCHAR szName[MAX_PATH];
53 TCHAR szDesc[MAX_PATH];
54 PLABEL_CONTEXT LabelContext;
55 }SOUND_SCHEME_CONTEXT, *PSOUND_SCHEME_CONTEXT;
56
57 static PLABEL_MAP s_Map = NULL;
58 static PAPP_MAP s_App = NULL;
59
60 TCHAR szDefault[MAX_PATH];
61
62
63 PLABEL_MAP FindLabel(PAPP_MAP pAppMap, TCHAR * szName)
64 {
65 PLABEL_MAP pMap = s_Map;
66
67 while(pMap)
68 {
69 ASSERT(pMap);
70 ASSERT(pMap->szName);
71 if (!_tcscmp(pMap->szName, szName))
72 return pMap;
73
74 pMap = pMap->Next;
75
76 }
77
78 pMap = pAppMap->LabelMap;
79
80 while(pMap)
81 {
82 ASSERT(pMap);
83 ASSERT(pMap->szName);
84 if (!_tcscmp(pMap->szName, szName))
85 return pMap;
86
87 pMap = pMap->Next;
88
89 }
90
91 pMap = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LABEL_MAP));
92 if (!pMap)
93 return NULL;
94
95 pMap->szName = pMap->szDesc = _tcsdup(szName);
96 if (!pMap->szName)
97 {
98 HeapFree(GetProcessHeap(), 0, pMap);
99 return NULL;
100 }
101 pMap->AppMap = pAppMap;
102 pMap->Next = s_Map;
103 s_Map = pMap;
104
105 return pMap;
106 }
107
108 VOID RemoveLabel(PLABEL_MAP pMap)
109 {
110 PLABEL_MAP pCurMap = s_Map;
111
112 if (pCurMap == pMap)
113 {
114 s_Map = s_Map->Next;
115 return;
116 }
117
118
119 while(pCurMap)
120 {
121 if (pCurMap->Next == pMap)
122 {
123 pCurMap->Next = pCurMap->Next->Next;
124 return;
125 }
126 pCurMap = pCurMap->Next;
127 }
128 }
129
130
131
132
133
134
135 PAPP_MAP FindApp(TCHAR * szName)
136 {
137 PAPP_MAP pMap = s_App;
138
139 while(pMap)
140 {
141 if (!_tcscmp(pMap->szName, szName))
142 return pMap;
143
144 pMap = pMap->Next;
145
146 }
147 return NULL;
148 }
149
150 PLABEL_CONTEXT FindLabelContext(PSOUND_SCHEME_CONTEXT pSoundScheme, TCHAR * AppName, TCHAR * LabelName)
151 {
152 PLABEL_CONTEXT pLabelContext;
153
154 pLabelContext = pSoundScheme->LabelContext;
155
156 while(pLabelContext)
157 {
158 ASSERT(pLabelContext->AppMap);
159 ASSERT(pLabelContext->LabelMap);
160
161 if(!_tcsicmp(pLabelContext->AppMap->szName, AppName) && !_tcsicmp(pLabelContext->LabelMap->szName, LabelName))
162 {
163 return pLabelContext;
164 }
165 pLabelContext = pLabelContext->Next;
166 }
167
168 pLabelContext = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LABEL_CONTEXT));
169 if (!pLabelContext)
170 return NULL;
171
172 pLabelContext->AppMap = FindApp(AppName);
173 pLabelContext->LabelMap = FindLabel(pLabelContext->AppMap, LabelName);
174 ASSERT(pLabelContext->AppMap);
175 ASSERT(pLabelContext->LabelMap);
176 pLabelContext->szValue[0] = _T('\0');
177 pLabelContext->Next = pSoundScheme->LabelContext;
178 pSoundScheme->LabelContext = pLabelContext;
179
180 return pLabelContext;
181 }
182
183 BOOL
184 LoadEventLabel(HKEY hKey, TCHAR * szSubKey)
185 {
186 HKEY hSubKey;
187 DWORD dwData;
188 DWORD dwDesc;
189 TCHAR szDesc[MAX_PATH];
190 TCHAR szData[MAX_PATH];
191 PLABEL_MAP pMap;
192
193 if (RegOpenKeyEx(hKey,
194 szSubKey,
195 0,
196 KEY_READ,
197 &hSubKey) != ERROR_SUCCESS)
198 {
199 return FALSE;
200 }
201
202 dwDesc = sizeof(szDesc) / sizeof(TCHAR);
203 if (RegQueryValueEx(hSubKey,
204 NULL,
205 NULL,
206 NULL,
207 (LPBYTE)szDesc,
208 &dwDesc) != ERROR_SUCCESS)
209 {
210 RegCloseKey(hSubKey);
211 return FALSE;
212 }
213
214 dwData = sizeof(szDesc) / sizeof(TCHAR);
215 if (RegQueryValueEx(hSubKey,
216 _T("DispFileName"),
217 NULL,
218 NULL,
219 (LPBYTE)szData,
220 &dwData) != ERROR_SUCCESS)
221 {
222 RegCloseKey(hSubKey);
223 return FALSE;
224 }
225
226 pMap = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LABEL_MAP));
227 if (!pMap)
228 {
229 return FALSE;
230 }
231 pMap->szName = _tcsdup(szSubKey);
232 pMap->szDesc = _tcsdup(szDesc);
233 pMap->szIcon = _tcsdup(szData);
234
235 if (s_Map)
236 {
237 pMap->Next = s_Map;
238 s_Map = pMap;
239 }
240 else
241 {
242 s_Map = pMap;
243 s_Map->Next = 0;
244 }
245 return TRUE;
246 }
247
248 BOOL
249 LoadEventLabels()
250 {
251 HKEY hSubKey;
252 DWORD dwCurKey;
253 TCHAR szName[MAX_PATH];
254 DWORD dwName;
255 DWORD dwResult;
256 DWORD dwCount;
257 if (RegOpenKeyEx(HKEY_CURRENT_USER,
258 _T("AppEvents\\EventLabels"),
259 0,
260 KEY_READ,
261 &hSubKey) != ERROR_SUCCESS)
262 {
263 return FALSE;
264 }
265
266 dwCurKey = 0;
267 dwCount = 0;
268 do
269 {
270 dwName = sizeof(szName) / sizeof(szName[0]);
271 dwResult = RegEnumKeyEx(hSubKey,
272 dwCurKey,
273 szName,
274 &dwName,
275 NULL,
276 NULL,
277 NULL,
278 NULL);
279
280 if (dwResult == ERROR_SUCCESS)
281 {
282 if (LoadEventLabel(hSubKey, szName))
283 {
284 dwCount++;
285 }
286 }
287 dwCurKey++;
288
289 }while(dwResult == ERROR_SUCCESS);
290
291 RegCloseKey(hSubKey);
292 return (dwCount != 0);
293 }
294
295 BOOL
296 AddSoundProfile(HWND hwndDlg, HKEY hKey, TCHAR * szSubKey, BOOL SetDefault)
297 {
298 HKEY hSubKey;
299 TCHAR szValue[MAX_PATH];
300 DWORD dwValue, dwResult;
301
302 if (RegOpenKeyEx(hKey,
303 szSubKey,
304 0,
305 KEY_READ,
306 &hSubKey) != ERROR_SUCCESS)
307 {
308 return FALSE;
309 }
310
311 dwValue = sizeof(szValue) / sizeof(TCHAR);
312 dwResult = RegQueryValueEx(hSubKey,
313 NULL,
314 NULL,
315 NULL,
316 (LPBYTE)szValue,
317 &dwValue);
318 RegCloseKey(hSubKey);
319 if (dwResult == ERROR_SUCCESS)
320 {
321 LRESULT lResult = SendDlgItemMessage(hwndDlg, IDC_SOUND_SCHEME, CB_ADDSTRING, (WPARAM)0, (LPARAM)szValue);
322 if (lResult != CB_ERR)
323 {
324 PSOUND_SCHEME_CONTEXT pScheme = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SOUND_SCHEME_CONTEXT));
325 if (pScheme != NULL)
326 {
327 _tcscpy(pScheme->szDesc, szValue);
328 _tcscpy(pScheme->szName, szSubKey);
329 }
330
331 SendDlgItemMessage(hwndDlg, IDC_SOUND_SCHEME, CB_SETITEMDATA, (WPARAM)lResult, (LPARAM)pScheme);
332 if (SetDefault)
333 {
334 SendDlgItemMessage(hwndDlg, IDC_SOUND_SCHEME, CB_SETCURSEL, (WPARAM)lResult, (LPARAM)0);
335 }
336 }
337 return TRUE;
338 }
339 return FALSE;
340 }
341
342 DWORD
343 EnumerateSoundProfiles(HWND hwndDlg, HKEY hKey)
344 {
345 HKEY hSubKey;
346 DWORD dwName, dwCurKey, dwResult, dwNumSchemes;
347 TCHAR szName[MAX_PATH];
348
349 dwName = sizeof(szDefault) / sizeof(TCHAR);
350 if (RegQueryValueEx(hKey,
351 NULL,
352 NULL,
353 NULL,
354 (LPBYTE)szDefault,
355 &dwName) != ERROR_SUCCESS)
356 {
357 return FALSE;
358 }
359
360
361
362 if (RegOpenKeyEx(hKey,
363 _T("Names"),
364 0,
365 KEY_READ,
366 &hSubKey) != ERROR_SUCCESS)
367 {
368 return FALSE;
369 }
370
371 dwNumSchemes = 0;
372 dwCurKey = 0;
373 do
374 {
375 dwName = sizeof(szName) / sizeof(szName[0]);
376 dwResult = RegEnumKeyEx(hSubKey,
377 dwCurKey,
378 szName,
379 &dwName,
380 NULL,
381 NULL,
382 NULL,
383 NULL);
384
385 if (dwResult == ERROR_SUCCESS)
386 {
387 if (AddSoundProfile(hwndDlg, hSubKey, szName, (!_tcsicmp(szName, szDefault))))
388 {
389 dwNumSchemes++;
390 }
391 }
392
393 dwCurKey++;
394 }while(dwResult == ERROR_SUCCESS);
395
396 RegCloseKey(hSubKey);
397 return dwNumSchemes;
398 }
399
400 PSOUND_SCHEME_CONTEXT FindSoundProfile(HWND hwndDlg, TCHAR * szName)
401 {
402 LRESULT lCount, lIndex, lResult;
403 PSOUND_SCHEME_CONTEXT pScheme;
404
405 lCount = SendDlgItemMessage(hwndDlg, IDC_SOUND_SCHEME, CB_GETCOUNT, (WPARAM)0, (LPARAM)0);
406 if (lCount == CB_ERR)
407 {
408 return NULL;
409 }
410
411 for(lIndex = 0; lIndex < lCount; lIndex++)
412 {
413 lResult = SendDlgItemMessage(hwndDlg, IDC_SOUND_SCHEME, CB_GETITEMDATA, (WPARAM)lIndex, (LPARAM)0);
414 if (lResult == CB_ERR)
415 {
416 continue;
417 }
418
419 pScheme = (PSOUND_SCHEME_CONTEXT)lResult;
420 if (!_tcsicmp(pScheme->szName, szName))
421 {
422 return pScheme;
423 }
424 }
425 return NULL;
426 }
427 BOOL
428 ImportSoundLabel(HWND hwndDlg, HKEY hKey, TCHAR * szProfile, TCHAR * szLabelName, TCHAR * szAppName, PAPP_MAP AppMap, PLABEL_MAP LabelMap)
429 {
430 HKEY hSubKey;
431 TCHAR szValue[MAX_PATH];
432 TCHAR szBuffer[MAX_PATH];
433 DWORD dwValue;
434 PSOUND_SCHEME_CONTEXT pScheme;
435 PLABEL_CONTEXT pLabelContext;
436 BOOL bCurrentProfile, bActiveProfile;
437
438
439 //MessageBox(hwndDlg, szProfile, szLabelName, MB_OK);
440
441 bCurrentProfile = !_tcsicmp(szProfile, _T(".Current"));
442 bActiveProfile = !_tcsicmp(szProfile, szDefault);
443
444
445 if (RegOpenKeyEx(hKey,
446 szProfile,
447 0,
448 KEY_READ,
449 &hSubKey) != ERROR_SUCCESS)
450 {
451 return FALSE;
452 }
453
454 dwValue = sizeof(szValue) / sizeof(TCHAR);
455 if (RegQueryValueEx(hSubKey,
456 NULL,
457 NULL,
458 NULL,
459 (LPBYTE)szValue,
460 &dwValue) != ERROR_SUCCESS)
461 {
462 return FALSE;
463 }
464
465 if (bCurrentProfile)
466 pScheme = FindSoundProfile(hwndDlg, szDefault);
467 else
468 pScheme = FindSoundProfile(hwndDlg, szProfile);
469
470 if (!pScheme)
471 {
472 //MessageBox(hwndDlg, szProfile, _T("no profile!!"), MB_OK);
473 return FALSE;
474 }
475 pLabelContext = FindLabelContext(pScheme, AppMap->szName, LabelMap->szName);
476
477 dwValue = ExpandEnvironmentStrings(szValue, szBuffer, sizeof(szBuffer) / sizeof(TCHAR));
478 if (dwValue == 0 || dwValue > (sizeof(szBuffer) / sizeof(TCHAR)))
479 {
480 /* fixme */
481 return FALSE;
482 }
483
484 if (bCurrentProfile)
485 _tcscpy(pLabelContext->szValue, szBuffer);
486 else if (!bActiveProfile)
487 _tcscpy(pLabelContext->szValue, szBuffer);
488
489 return TRUE;
490 }
491
492
493 DWORD
494 ImportSoundEntry(HWND hwndDlg, HKEY hKey, TCHAR * szLabelName, TCHAR * szAppName, PAPP_MAP pAppMap)
495 {
496 HKEY hSubKey;
497 DWORD dwNumProfiles;
498 DWORD dwCurKey;
499 DWORD dwResult;
500 DWORD dwProfile;
501 TCHAR szProfile[MAX_PATH];
502 PLABEL_MAP pLabel;
503
504 if (RegOpenKeyEx(hKey,
505 szLabelName,
506 0,
507 KEY_READ,
508 &hSubKey) != ERROR_SUCCESS)
509 {
510 return FALSE;
511 }
512 pLabel = FindLabel(pAppMap, szLabelName);
513
514 ASSERT(pLabel);
515 RemoveLabel(pLabel);
516
517 pLabel->AppMap = pAppMap;
518 pLabel->Next = pAppMap->LabelMap;
519 pAppMap->LabelMap = pLabel;
520
521 dwNumProfiles = 0;
522 dwCurKey = 0;
523 do
524 {
525 dwProfile = sizeof(szProfile) / sizeof(TCHAR);
526 dwResult = RegEnumKeyEx(hSubKey,
527 dwCurKey,
528 szProfile,
529 &dwProfile,
530 NULL,
531 NULL,
532 NULL,
533 NULL);
534
535 if (dwResult == ERROR_SUCCESS)
536 {
537 if (ImportSoundLabel(hwndDlg, hSubKey, szProfile, szLabelName, szAppName, pAppMap, pLabel))
538 {
539 dwNumProfiles++;
540 }
541 }
542
543 dwCurKey++;
544 }while(dwResult == ERROR_SUCCESS);
545
546 RegCloseKey(hSubKey);
547
548 return dwNumProfiles;
549 }
550
551
552
553 DWORD
554 ImportAppProfile(HWND hwndDlg, HKEY hKey, TCHAR * szAppName)
555 {
556 HKEY hSubKey;
557 TCHAR szDefault[MAX_PATH];
558 DWORD dwDefault;
559 DWORD dwCurKey;
560 DWORD dwResult;
561 DWORD dwNumEntry;
562 DWORD dwName;
563 TCHAR szName[MAX_PATH];
564 TCHAR szIcon[MAX_PATH];
565 PAPP_MAP AppMap;
566
567 //MessageBox(hwndDlg, szAppName, _T("Importing...\n"), MB_OK);
568
569 AppMap = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(APP_MAP));
570 if (!AppMap)
571 return 0;
572
573 if (RegOpenKeyEx(hKey,
574 szAppName,
575 0,
576 KEY_READ,
577 &hSubKey) != ERROR_SUCCESS)
578 {
579 HeapFree(GetProcessHeap(), 0, AppMap);
580 return 0;
581 }
582
583 dwDefault = sizeof(szDefault) / sizeof(TCHAR);
584 if (RegQueryValueEx(hSubKey,
585 NULL,
586 NULL,
587 NULL,
588 (LPBYTE)szDefault,
589 &dwDefault) != ERROR_SUCCESS)
590 {
591 RegCloseKey(hSubKey);
592 HeapFree(GetProcessHeap(), 0, AppMap);
593 return 0;
594 }
595
596 dwDefault = sizeof(szIcon) / sizeof(TCHAR);
597 if (RegQueryValueEx(hSubKey,
598 _T("DispFileName"),
599 NULL,
600 NULL,
601 (LPBYTE)szIcon,
602 &dwDefault) != ERROR_SUCCESS)
603 {
604 szIcon[0] = _T('\0');
605 }
606
607 /* initialize app map */
608 _tcscpy(AppMap->szName, szAppName);
609 _tcscpy(AppMap->szDesc, szDefault);
610 _tcscpy(AppMap->szIcon, szIcon);
611
612 AppMap->Next = s_App;
613 s_App = AppMap;
614
615
616 dwCurKey = 0;
617 dwNumEntry = 0;
618 do
619 {
620 dwName = sizeof(szName) / sizeof(TCHAR);
621 dwResult = RegEnumKeyEx(hSubKey,
622 dwCurKey,
623 szName,
624 &dwName,
625 NULL,
626 NULL,
627 NULL,
628 NULL);
629 if (dwResult == ERROR_SUCCESS)
630 {
631 if (ImportSoundEntry(hwndDlg, hSubKey, szName, szAppName, AppMap))
632 {
633 dwNumEntry++;
634 }
635 }
636 dwCurKey++;
637 }while(dwResult == ERROR_SUCCESS);
638 RegCloseKey(hSubKey);
639 return dwNumEntry;
640 }
641
642 BOOL
643 ImportSoundProfiles(HWND hwndDlg, HKEY hKey)
644 {
645 DWORD dwCurKey;
646 DWORD dwResult;
647 DWORD dwNumApps;
648 TCHAR szName[MAX_PATH];
649 HKEY hSubKey;
650
651 if (RegOpenKeyEx(hKey,
652 _T("Apps"),
653 0,
654 KEY_READ,
655 &hSubKey) != ERROR_SUCCESS)
656 {
657 return FALSE;
658 }
659
660 dwNumApps = 0;
661 dwCurKey = 0;
662 do
663 {
664 dwResult = RegEnumKey(hSubKey,
665 dwCurKey,
666 szName,
667 sizeof(szName) / sizeof(TCHAR));
668
669 if (dwResult == ERROR_SUCCESS)
670 {
671 if (ImportAppProfile(hwndDlg, hSubKey, szName))
672 {
673 dwNumApps++;
674 }
675 }
676 dwCurKey++;
677 }while(dwResult == ERROR_SUCCESS);
678 RegCloseKey(hSubKey);
679
680 return (dwNumApps != 0);
681 }
682
683
684
685 BOOL
686 LoadSoundProfiles(HWND hwndDlg)
687 {
688 HKEY hSubKey;
689 DWORD dwNumSchemes;
690
691 if (RegOpenKeyEx(HKEY_CURRENT_USER,
692 _T("AppEvents\\Schemes"),
693 0,
694 KEY_READ,
695 &hSubKey) != ERROR_SUCCESS)
696 {
697 return FALSE;
698 }
699
700 dwNumSchemes = EnumerateSoundProfiles(hwndDlg, hSubKey);
701
702
703 if (dwNumSchemes)
704 {
705 //MessageBox(hwndDlg, _T("importing sound profiles..."), NULL, MB_OK);
706 ImportSoundProfiles(hwndDlg, hSubKey);
707 }
708 RegCloseKey(hSubKey);
709 return FALSE;
710 }
711 BOOL
712 LoadSoundFiles(HWND hwndDlg)
713 {
714 WCHAR szPath[MAX_PATH];
715 WCHAR * ptr;
716 WIN32_FIND_DATAW FileData;
717 HANDLE hFile;
718 LRESULT lResult;
719 UINT length;
720
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 if (LoadString(hApplet, IDS_NO_SOUND, szPath, MAX_PATH))
740 {
741 szPath[(sizeof(szPath)/sizeof(WCHAR))-1] = L'\0';
742 SendDlgItemMessageW(hwndDlg, IDC_SOUND_LIST, CB_ADDSTRING, (WPARAM)0, (LPARAM)szPath);
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
773 BOOL
774 ShowSoundScheme(HWND hwndDlg)
775 {
776 LRESULT lIndex;
777 PSOUND_SCHEME_CONTEXT pScheme;
778 PAPP_MAP pAppMap;
779 LV_ITEM listItem;
780 LV_COLUMN dummy;
781 HWND hDlgCtrl, hList;
782 RECT rect;
783 int ItemIndex;
784 hDlgCtrl = GetDlgItem(hwndDlg, IDC_SOUND_SCHEME);
785 hList = GetDlgItem(hwndDlg, IDC_SCHEME_LIST);
786
787 lIndex = SendMessage(hDlgCtrl, CB_GETCURSEL, (WPARAM)0, (LPARAM)0);
788 if (lIndex == CB_ERR)
789 {
790 return FALSE;
791 }
792
793 lIndex = SendMessage(hDlgCtrl, CB_GETITEMDATA, (WPARAM)lIndex, (LPARAM)0);
794 if (lIndex == CB_ERR)
795 {
796 return FALSE;
797 }
798 pScheme = (PSOUND_SCHEME_CONTEXT)lIndex;
799
800 _tcscpy(szDefault, pScheme->szName);
801
802 /* add column for app */
803 GetClientRect(hList, &rect);
804 ZeroMemory(&dummy, sizeof(LV_COLUMN));
805 dummy.mask = LVCF_WIDTH;
806 dummy.iSubItem = 0;
807 dummy.cx = rect.right - rect.left - GetSystemMetrics(SM_CXVSCROLL);
808 (void)ListView_InsertColumn(hList, 0, &dummy);
809 ItemIndex = 0;
810
811 pAppMap = s_App;
812 while(pAppMap)
813 {
814 PLABEL_MAP pLabelMap = pAppMap->LabelMap;
815 while(pLabelMap)
816 {
817 ZeroMemory(&listItem, sizeof(LV_ITEM));
818 listItem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
819 listItem.pszText = pLabelMap->szDesc;
820 listItem.lParam = (LPARAM)FindLabelContext(pScheme, pAppMap->szName, pLabelMap->szName);
821 listItem.iItem = ItemIndex;
822 listItem.iImage = -1;
823 (void)ListView_InsertItem(hList, &listItem);
824 ItemIndex++;
825
826 pLabelMap = pLabelMap->Next;
827 }
828 pAppMap = pAppMap->Next;
829 }
830 return TRUE;
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 LPPSHNOTIFY lppsn;
1034 TCHAR * ptr;
1035
1036 LPNMHDR lpnm = (LPNMHDR)lParam;
1037 lppsn = (LPPSHNOTIFY) lParam;
1038
1039 switch(lpnm->code)
1040 {
1041 case PSN_APPLY:
1042 {
1043 ApplyChanges(hwndDlg);
1044 break;
1045 }
1046 case LVN_ITEMCHANGED:
1047 {
1048 LPNMLISTVIEW nm = (LPNMLISTVIEW)lParam;
1049
1050 if ((nm->uNewState & LVIS_SELECTED) == 0)
1051 {
1052 return FALSE;
1053 }
1054 ZeroMemory(&item, sizeof(LVITEM));
1055 item.mask = LVIF_PARAM;
1056 item.iItem = nm->iItem;
1057 if (ListView_GetItem(GetDlgItem(hwndDlg, IDC_SCHEME_LIST), &item))
1058 {
1059 LRESULT lCount, lIndex, lResult;
1060 pLabelContext = (PLABEL_CONTEXT)item.lParam;
1061 if (!pLabelContext)
1062 {
1063 return FALSE;
1064 }
1065 EnableWindow(GetDlgItem(hwndDlg, IDC_SOUND_LIST), TRUE);
1066 EnableWindow(GetDlgItem(hwndDlg, IDC_TEXT_SOUND), TRUE);
1067 EnableWindow(GetDlgItem(hwndDlg, IDC_BROWSE_SOUND), TRUE);
1068 if (_tcslen(pLabelContext->szValue) == 0)
1069 {
1070 lIndex = SendDlgItemMessage(hwndDlg, IDC_SOUND_LIST, CB_SETCURSEL, (WPARAM)0, (LPARAM)0);
1071 EnableWindow(GetDlgItem(hwndDlg, IDC_PLAY_SOUND), FALSE);
1072 break;
1073
1074 }
1075 EnableWindow(GetDlgItem(hwndDlg, IDC_PLAY_SOUND), TRUE);
1076 lCount = SendDlgItemMessage(hwndDlg, IDC_SOUND_LIST, CB_GETCOUNT, (WPARAM)0, (LPARAM)0);
1077 for (lIndex = 0; lIndex < lCount; lIndex++)
1078 {
1079 lResult = SendDlgItemMessage(hwndDlg, IDC_SOUND_LIST, CB_GETITEMDATA, (WPARAM)lIndex, (LPARAM)0);
1080 if (lResult == CB_ERR || lResult == 0)
1081 continue;
1082
1083 if (!_tcscmp((TCHAR*)lResult, pLabelContext->szValue))
1084 {
1085 SendDlgItemMessage(hwndDlg, IDC_SOUND_LIST, CB_SETCURSEL, (WPARAM)lIndex, (LPARAM)0);
1086 return FALSE;
1087 }
1088 }
1089 ptr = _tcsrchr(pLabelContext->szValue, _T('\\'));
1090 if (ptr)
1091 {
1092 ptr++;
1093 }
1094 else
1095 {
1096 ptr = pLabelContext->szValue;
1097 }
1098 lIndex = SendDlgItemMessage(hwndDlg, IDC_SOUND_LIST, CB_ADDSTRING, (WPARAM)0, (LPARAM)ptr);
1099 if (lIndex != CB_ERR)
1100 {
1101 SendDlgItemMessage(hwndDlg, IDC_SOUND_LIST, CB_SETITEMDATA, (WPARAM)lIndex, (LPARAM)_tcsdup(pLabelContext->szValue));
1102 SendDlgItemMessage(hwndDlg, IDC_SOUND_LIST, CB_SETCURSEL, (WPARAM)lIndex, (LPARAM)0);
1103 }
1104 }
1105 break;
1106 }
1107 }
1108 }
1109 break;
1110 }
1111
1112 return FALSE;
1113 }