2 * PROJECT: ReactOS Multimedia Control Panel
3 * FILE: dll/cpl/mmsys/sounds.c
4 * PURPOSE: ReactOS Multimedia Control Panel
5 * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com>
6 * Johannes Anderwald <janderwald@reactos.com>
7 * Dmitry Chapyshev <dmitry@reactos.org>
8 * Victor Martinez Calvo <victor.martinez@reactos.org>
9 * Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
20 typedef struct _LABEL_MAP
25 struct _APP_MAP
*AppMap
;
26 struct _LABEL_MAP
*Next
;
27 } LABEL_MAP
, *PLABEL_MAP
;
29 typedef struct _APP_MAP
31 TCHAR szName
[MAX_PATH
];
32 TCHAR szDesc
[MAX_PATH
];
33 TCHAR szIcon
[MAX_PATH
];
35 struct _APP_MAP
*Next
;
39 typedef struct _LABEL_CONTEXT
43 TCHAR szValue
[MAX_PATH
];
44 struct _LABEL_CONTEXT
*Next
;
45 } LABEL_CONTEXT
, *PLABEL_CONTEXT
;
47 typedef struct _SOUND_SCHEME_CONTEXT
49 TCHAR szName
[MAX_PATH
];
50 TCHAR szDesc
[MAX_PATH
];
51 PLABEL_CONTEXT LabelContext
;
52 } SOUND_SCHEME_CONTEXT
, *PSOUND_SCHEME_CONTEXT
;
54 typedef struct _GLOBAL_DATA
56 TCHAR szDefault
[MAX_PATH
];
57 HIMAGELIST hSoundsImageList
;
61 } GLOBAL_DATA
, *PGLOBAL_DATA
;
64 /* A filter string is a list separated by NULL and ends with double NULLs. */
65 LPWSTR
MakeFilter(LPWSTR psz
)
69 ASSERT(psz
[0] != UNICODE_NULL
&&
70 psz
[wcslen(psz
) - 1] == L
'|');
71 for (pch
= psz
; *pch
!= UNICODE_NULL
; pch
++)
73 /* replace vertical bar with NULL */
82 PLABEL_MAP
FindLabel(PGLOBAL_DATA pGlobalData
, PAPP_MAP pAppMap
, TCHAR
* szName
)
84 PLABEL_MAP pMap
= pGlobalData
->pLabelMap
;
90 if (!_tcscmp(pMap
->szName
, szName
))
96 pMap
= pAppMap
->LabelMap
;
101 ASSERT(pMap
->szName
);
102 if (!_tcscmp(pMap
->szName
, szName
))
108 pMap
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(LABEL_MAP
));
112 pMap
->szName
= pMap
->szDesc
= _tcsdup(szName
);
115 HeapFree(GetProcessHeap(), 0, pMap
);
119 pMap
->AppMap
= pAppMap
;
120 pMap
->Next
= pGlobalData
->pLabelMap
;
121 pGlobalData
->pLabelMap
= pMap
;
127 VOID
RemoveLabel(PGLOBAL_DATA pGlobalData
, PLABEL_MAP pMap
)
129 PLABEL_MAP pCurMap
= pGlobalData
->pLabelMap
;
133 pGlobalData
->pLabelMap
= pGlobalData
->pLabelMap
->Next
;
139 if (pCurMap
->Next
== pMap
)
141 pCurMap
->Next
= pCurMap
->Next
->Next
;
144 pCurMap
= pCurMap
->Next
;
150 FreeLabelMap(PGLOBAL_DATA pGlobalData
)
154 while (pGlobalData
->pLabelMap
)
156 pCurMap
= pGlobalData
->pLabelMap
->Next
;
157 HeapFree(GetProcessHeap(), 0, pGlobalData
->pLabelMap
);
158 pGlobalData
->pLabelMap
= pCurMap
;
162 PAPP_MAP
FindApp(PGLOBAL_DATA pGlobalData
, TCHAR
*szName
)
164 PAPP_MAP pMap
= pGlobalData
->pAppMap
;
168 if (!_tcscmp(pMap
->szName
, szName
))
179 FreeAppMap(PGLOBAL_DATA pGlobalData
)
183 while (pGlobalData
->pAppMap
)
185 pCurMap
= pGlobalData
->pAppMap
->Next
;
186 HeapFree(GetProcessHeap(), 0, pGlobalData
->pAppMap
);
187 pGlobalData
->pAppMap
= pCurMap
;
191 PLABEL_CONTEXT
FindLabelContext(PGLOBAL_DATA pGlobalData
, PSOUND_SCHEME_CONTEXT pSoundScheme
, TCHAR
* AppName
, TCHAR
* LabelName
)
193 PLABEL_CONTEXT pLabelContext
;
195 pLabelContext
= pSoundScheme
->LabelContext
;
197 while (pLabelContext
)
199 ASSERT(pLabelContext
->AppMap
);
200 ASSERT(pLabelContext
->LabelMap
);
202 if (!_tcsicmp(pLabelContext
->AppMap
->szName
, AppName
) && !_tcsicmp(pLabelContext
->LabelMap
->szName
, LabelName
))
204 return pLabelContext
;
206 pLabelContext
= pLabelContext
->Next
;
209 pLabelContext
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(LABEL_CONTEXT
));
213 pLabelContext
->AppMap
= FindApp(pGlobalData
, AppName
);
214 pLabelContext
->LabelMap
= FindLabel(pGlobalData
, pLabelContext
->AppMap
, LabelName
);
215 ASSERT(pLabelContext
->AppMap
);
216 ASSERT(pLabelContext
->LabelMap
);
217 pLabelContext
->szValue
[0] = _T('\0');
218 pLabelContext
->Next
= pSoundScheme
->LabelContext
;
219 pSoundScheme
->LabelContext
= pLabelContext
;
221 return pLabelContext
;
226 LoadEventLabel(PGLOBAL_DATA pGlobalData
, HKEY hKey
, TCHAR
* szSubKey
)
230 TCHAR szDesc
[MAX_PATH
];
231 TCHAR szData
[MAX_PATH
];
234 if (RegOpenKeyEx(hKey
,
238 &hSubKey
) != ERROR_SUCCESS
)
243 cbValue
= sizeof(szDesc
);
244 if (RegQueryValueEx(hSubKey
,
249 &cbValue
) != ERROR_SUCCESS
)
251 RegCloseKey(hSubKey
);
255 cbValue
= sizeof(szData
);
256 if (RegQueryValueEx(hSubKey
,
261 &cbValue
) != ERROR_SUCCESS
)
263 RegCloseKey(hSubKey
);
267 pMap
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(LABEL_MAP
));
273 pMap
->szName
= _tcsdup(szSubKey
);
274 pMap
->szDesc
= _tcsdup(szDesc
);
275 pMap
->szIcon
= _tcsdup(szData
);
277 if (pGlobalData
->pLabelMap
)
279 pMap
->Next
= pGlobalData
->pLabelMap
;
280 pGlobalData
->pLabelMap
= pMap
;
284 pGlobalData
->pLabelMap
= pMap
;
285 pGlobalData
->pLabelMap
->Next
= NULL
;
292 LoadEventLabels(PGLOBAL_DATA pGlobalData
)
296 TCHAR szName
[MAX_PATH
];
300 if (RegOpenKeyEx(HKEY_CURRENT_USER
,
301 _T("AppEvents\\EventLabels"),
304 &hSubKey
) != ERROR_SUCCESS
)
313 dwName
= _countof(szName
);
314 dwResult
= RegEnumKeyEx(hSubKey
,
323 if (dwResult
== ERROR_SUCCESS
)
325 if (LoadEventLabel(pGlobalData
, hSubKey
, szName
))
332 } while (dwResult
== ERROR_SUCCESS
);
334 RegCloseKey(hSubKey
);
335 return (dwCount
!= 0);
340 AddSoundProfile(HWND hwndDlg
, HKEY hKey
, TCHAR
* szSubKey
, BOOL SetDefault
)
343 TCHAR szValue
[MAX_PATH
];
344 DWORD cbValue
, dwResult
;
346 PSOUND_SCHEME_CONTEXT pScheme
;
348 if (RegOpenKeyEx(hKey
,
352 &hSubKey
) != ERROR_SUCCESS
)
357 cbValue
= sizeof(szValue
);
358 dwResult
= RegQueryValueEx(hSubKey
,
364 RegCloseKey(hSubKey
);
366 if (dwResult
!= ERROR_SUCCESS
)
369 /* Try to add the new profile */
370 lResult
= ComboBox_AddString(GetDlgItem(hwndDlg
, IDC_SOUND_SCHEME
), szValue
);
371 if (lResult
== CB_ERR
)
374 /* Allocate the profile scheme buffer */
375 pScheme
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(SOUND_SCHEME_CONTEXT
));
378 /* We failed to allocate the buffer, no need to keep a dangling string in the combobox */
379 ComboBox_DeleteString(GetDlgItem(hwndDlg
, IDC_SOUND_SCHEME
), lResult
);
383 StringCchCopy(pScheme
->szDesc
, MAX_PATH
, szValue
);
384 StringCchCopy(pScheme
->szName
, MAX_PATH
, szSubKey
);
386 /* Associate the value with the item in the combobox */
387 ComboBox_SetItemData(GetDlgItem(hwndDlg
, IDC_SOUND_SCHEME
), lResult
, pScheme
);
389 /* Optionally, select the profile */
392 ComboBox_SetCurSel(GetDlgItem(hwndDlg
, IDC_SOUND_SCHEME
), lResult
);
400 EnumerateSoundProfiles(PGLOBAL_DATA pGlobalData
, HWND hwndDlg
, HKEY hKey
)
403 DWORD dwName
, dwCurKey
, dwResult
, dwNumSchemes
;
405 TCHAR szName
[MAX_PATH
];
407 cbDefault
= sizeof(pGlobalData
->szDefault
);
408 if (RegQueryValueEx(hKey
,
412 (LPBYTE
)pGlobalData
->szDefault
,
413 &cbDefault
) != ERROR_SUCCESS
)
418 if (RegOpenKeyEx(hKey
,
422 &hSubKey
) != ERROR_SUCCESS
)
431 dwName
= _countof(szName
);
432 dwResult
= RegEnumKeyEx(hSubKey
,
441 if (dwResult
== ERROR_SUCCESS
)
443 if (AddSoundProfile(hwndDlg
, hSubKey
, szName
, (!_tcsicmp(szName
, pGlobalData
->szDefault
))))
450 } while (dwResult
== ERROR_SUCCESS
);
452 RegCloseKey(hSubKey
);
457 PSOUND_SCHEME_CONTEXT
FindSoundProfile(HWND hwndDlg
, TCHAR
* szName
)
459 LRESULT lCount
, lIndex
, lResult
;
460 PSOUND_SCHEME_CONTEXT pScheme
;
463 hwndComboBox
= GetDlgItem(hwndDlg
, IDC_SOUND_SCHEME
);
464 lCount
= ComboBox_GetCount(hwndComboBox
);
465 if (lCount
== CB_ERR
)
470 for (lIndex
= 0; lIndex
< lCount
; lIndex
++)
472 lResult
= ComboBox_GetItemData(hwndComboBox
, lIndex
);
473 if (lResult
== CB_ERR
)
478 pScheme
= (PSOUND_SCHEME_CONTEXT
)lResult
;
479 if (!_tcsicmp(pScheme
->szName
, szName
))
489 FreeSoundProfiles(HWND hwndDlg
)
491 LRESULT lCount
, lIndex
, lResult
;
492 PSOUND_SCHEME_CONTEXT pScheme
;
493 PLABEL_CONTEXT pLabelContext
;
496 hwndComboBox
= GetDlgItem(hwndDlg
, IDC_SOUND_SCHEME
);
497 lCount
= ComboBox_GetCount(hwndComboBox
);
498 if (lCount
== CB_ERR
)
501 for (lIndex
= 0; lIndex
< lCount
; lIndex
++)
503 lResult
= ComboBox_GetItemData(hwndComboBox
, lIndex
);
504 if (lResult
== CB_ERR
)
509 pScheme
= (PSOUND_SCHEME_CONTEXT
)lResult
;
511 while (pScheme
->LabelContext
)
513 pLabelContext
= pScheme
->LabelContext
->Next
;
514 HeapFree(GetProcessHeap(), 0, pScheme
->LabelContext
);
515 pScheme
->LabelContext
= pLabelContext
;
518 HeapFree(GetProcessHeap(), 0, pScheme
);
523 ImportSoundLabel(PGLOBAL_DATA pGlobalData
, HWND hwndDlg
, HKEY hKey
, TCHAR
* szProfile
, TCHAR
* szLabelName
, TCHAR
* szAppName
, PAPP_MAP AppMap
, PLABEL_MAP LabelMap
)
526 TCHAR szValue
[MAX_PATH
];
527 TCHAR szBuffer
[MAX_PATH
];
528 DWORD cbValue
, cchLength
;
529 PSOUND_SCHEME_CONTEXT pScheme
;
530 PLABEL_CONTEXT pLabelContext
;
531 BOOL bCurrentProfile
, bActiveProfile
;
533 //MessageBox(hwndDlg, szProfile, szLabelName, MB_OK);
535 bCurrentProfile
= !_tcsicmp(szProfile
, _T(".Current"));
536 bActiveProfile
= !_tcsicmp(szProfile
, pGlobalData
->szDefault
);
538 if (RegOpenKeyEx(hKey
,
542 &hSubKey
) != ERROR_SUCCESS
)
547 cbValue
= sizeof(szValue
);
548 if (RegQueryValueEx(hSubKey
,
553 &cbValue
) != ERROR_SUCCESS
)
559 pScheme
= FindSoundProfile(hwndDlg
, pGlobalData
->szDefault
);
561 pScheme
= FindSoundProfile(hwndDlg
, szProfile
);
565 //MessageBox(hwndDlg, szProfile, _T("no profile!!"), MB_OK);
568 pLabelContext
= FindLabelContext(pGlobalData
, pScheme
, AppMap
->szName
, LabelMap
->szName
);
570 cchLength
= ExpandEnvironmentStrings(szValue
, szBuffer
, _countof(szBuffer
));
571 if (cchLength
== 0 || cchLength
> _countof(szBuffer
))
578 _tcscpy(pLabelContext
->szValue
, szBuffer
);
579 else if (!bActiveProfile
)
580 _tcscpy(pLabelContext
->szValue
, szBuffer
);
587 ImportSoundEntry(PGLOBAL_DATA pGlobalData
, HWND hwndDlg
, HKEY hKey
, TCHAR
* szLabelName
, TCHAR
* szAppName
, PAPP_MAP pAppMap
)
594 TCHAR szProfile
[MAX_PATH
];
597 if (RegOpenKeyEx(hKey
,
601 &hSubKey
) != ERROR_SUCCESS
)
605 pLabel
= FindLabel(pGlobalData
, pAppMap
, szLabelName
);
608 RemoveLabel(pGlobalData
, pLabel
);
610 pLabel
->AppMap
= pAppMap
;
611 pLabel
->Next
= pAppMap
->LabelMap
;
612 pAppMap
->LabelMap
= pLabel
;
618 dwProfile
= _countof(szProfile
);
619 dwResult
= RegEnumKeyEx(hSubKey
,
628 if (dwResult
== ERROR_SUCCESS
)
630 if (ImportSoundLabel(pGlobalData
, hwndDlg
, hSubKey
, szProfile
, szLabelName
, szAppName
, pAppMap
, pLabel
))
637 } while (dwResult
== ERROR_SUCCESS
);
639 RegCloseKey(hSubKey
);
641 return dwNumProfiles
;
646 ImportAppProfile(PGLOBAL_DATA pGlobalData
, HWND hwndDlg
, HKEY hKey
, TCHAR
* szAppName
)
649 TCHAR szDefault
[MAX_PATH
];
655 TCHAR szName
[MAX_PATH
];
656 TCHAR szIcon
[MAX_PATH
];
659 //MessageBox(hwndDlg, szAppName, _T("Importing...\n"), MB_OK);
661 AppMap
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(APP_MAP
));
665 if (RegOpenKeyEx(hKey
,
669 &hSubKey
) != ERROR_SUCCESS
)
671 HeapFree(GetProcessHeap(), 0, AppMap
);
675 cbValue
= sizeof(szDefault
);
676 if (RegQueryValueEx(hSubKey
,
681 &cbValue
) != ERROR_SUCCESS
)
683 RegCloseKey(hSubKey
);
684 HeapFree(GetProcessHeap(), 0, AppMap
);
688 cbValue
= sizeof(szIcon
);
689 if (RegQueryValueEx(hSubKey
,
694 &cbValue
) != ERROR_SUCCESS
)
696 szIcon
[0] = _T('\0');
699 /* initialize app map */
700 _tcscpy(AppMap
->szName
, szAppName
);
701 _tcscpy(AppMap
->szDesc
, szDefault
);
702 _tcscpy(AppMap
->szIcon
, szIcon
);
704 AppMap
->Next
= pGlobalData
->pAppMap
;
705 pGlobalData
->pAppMap
= AppMap
;
712 dwName
= _countof(szName
);
713 dwResult
= RegEnumKeyEx(hSubKey
,
721 if (dwResult
== ERROR_SUCCESS
)
723 if (ImportSoundEntry(pGlobalData
, hwndDlg
, hSubKey
, szName
, szAppName
, AppMap
))
729 } while (dwResult
== ERROR_SUCCESS
);
731 RegCloseKey(hSubKey
);
737 ImportSoundProfiles(PGLOBAL_DATA pGlobalData
, HWND hwndDlg
, HKEY hKey
)
742 TCHAR szName
[MAX_PATH
];
745 if (RegOpenKeyEx(hKey
,
749 &hSubKey
) != ERROR_SUCCESS
)
758 dwResult
= RegEnumKey(hSubKey
,
763 if (dwResult
== ERROR_SUCCESS
)
765 if (ImportAppProfile(pGlobalData
, hwndDlg
, hSubKey
, szName
))
771 } while (dwResult
== ERROR_SUCCESS
);
773 RegCloseKey(hSubKey
);
775 return (dwNumApps
!= 0);
780 LoadSoundProfiles(PGLOBAL_DATA pGlobalData
, HWND hwndDlg
)
785 if (RegOpenKeyEx(HKEY_CURRENT_USER
,
786 _T("AppEvents\\Schemes"),
789 &hSubKey
) != ERROR_SUCCESS
)
794 dwNumSchemes
= EnumerateSoundProfiles(pGlobalData
, hwndDlg
, hSubKey
);
799 //MessageBox(hwndDlg, _T("importing sound profiles..."), NULL, MB_OK);
800 ImportSoundProfiles(pGlobalData
, hwndDlg
, hSubKey
);
803 RegCloseKey(hSubKey
);
809 LoadSoundFiles(HWND hwndDlg
)
812 WCHAR szPath
[MAX_PATH
];
814 WIN32_FIND_DATAW FileData
;
819 /* Add no sound listview item */
820 if (LoadString(hApplet
, IDS_NO_SOUND
, szList
, _countof(szList
)))
822 szList
[_countof(szList
) - 1] = TEXT('\0');
823 ComboBox_AddString(GetDlgItem(hwndDlg
, IDC_SOUND_LIST
), szList
);
826 /* Load sound files */
827 length
= GetWindowsDirectoryW(szPath
, MAX_PATH
);
828 if (length
== 0 || length
>= MAX_PATH
- 9)
832 if (szPath
[length
-1] != L
'\\')
834 szPath
[length
] = L
'\\';
837 wcscpy(&szPath
[length
], L
"media\\*");
840 hFile
= FindFirstFileW(szPath
, &FileData
);
841 if (hFile
== INVALID_HANDLE_VALUE
)
848 if (FileData
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
851 ptr
= wcsrchr(FileData
.cFileName
, L
'\\');
858 ptr
= FileData
.cFileName
;
860 lResult
= SendDlgItemMessageW(hwndDlg
, IDC_SOUND_LIST
, CB_ADDSTRING
, (WPARAM
)0, (LPARAM
)ptr
);
861 if (lResult
!= CB_ERR
)
863 wcscpy(&szPath
[length
-1], FileData
.cFileName
);
864 SendDlgItemMessageW(hwndDlg
, IDC_SOUND_LIST
, CB_SETITEMDATA
, (WPARAM
)lResult
, (LPARAM
)_wcsdup(szPath
));
866 } while (FindNextFileW(hFile
, &FileData
) != 0);
874 ShowSoundScheme(PGLOBAL_DATA pGlobalData
, HWND hwndDlg
)
877 PSOUND_SCHEME_CONTEXT pScheme
;
879 PLABEL_MAP pLabelMap
;
880 PLABEL_CONTEXT pLabelContext
;
881 HWND hDlgCtrl
, hList
;
882 TVINSERTSTRUCT tvItem
;
885 hDlgCtrl
= GetDlgItem(hwndDlg
, IDC_SOUND_SCHEME
);
886 hList
= GetDlgItem(hwndDlg
, IDC_SCHEME_LIST
);
888 if (pGlobalData
->hSoundsImageList
!= NULL
)
890 TreeView_SetImageList(hList
, pGlobalData
->hSoundsImageList
, TVSIL_NORMAL
);
893 lIndex
= SendMessage(hDlgCtrl
, CB_GETCURSEL
, (WPARAM
)0, (LPARAM
)0);
894 if (lIndex
== CB_ERR
)
899 lIndex
= SendMessage(hDlgCtrl
, CB_GETITEMDATA
, (WPARAM
)lIndex
, (LPARAM
)0);
900 if (lIndex
== CB_ERR
)
904 pScheme
= (PSOUND_SCHEME_CONTEXT
)lIndex
;
906 _tcscpy(pGlobalData
->szDefault
, pScheme
->szName
);
908 pAppMap
= pGlobalData
->pAppMap
;
911 ZeroMemory(&tvItem
, sizeof(tvItem
));
912 tvItem
.hParent
= TVI_ROOT
;
913 tvItem
.hInsertAfter
= TVI_FIRST
;
915 tvItem
.item
.mask
= TVIF_STATE
| TVIF_TEXT
| TVIF_PARAM
| TVIF_IMAGE
| TVIF_SELECTEDIMAGE
;
916 tvItem
.item
.state
= TVIS_EXPANDED
;
917 tvItem
.item
.stateMask
= TVIS_EXPANDED
;
918 tvItem
.item
.pszText
= pAppMap
->szDesc
;
919 tvItem
.item
.iImage
= IMAGE_SOUND_SECTION
;
920 tvItem
.item
.iSelectedImage
= IMAGE_SOUND_SECTION
;
921 tvItem
.item
.lParam
= (LPARAM
)NULL
;
923 hTreeItem
= TreeView_InsertItem(hList
, &tvItem
);
925 pLabelMap
= pAppMap
->LabelMap
;
928 pLabelContext
= FindLabelContext(pGlobalData
, pScheme
, pAppMap
->szName
, pLabelMap
->szName
);
930 ZeroMemory(&tvItem
, sizeof(tvItem
));
931 tvItem
.hParent
= hTreeItem
;
932 tvItem
.hInsertAfter
= TVI_SORT
;
934 tvItem
.item
.mask
= TVIF_STATE
| TVIF_TEXT
| TVIF_PARAM
| TVIF_IMAGE
| TVIF_SELECTEDIMAGE
;
935 tvItem
.item
.state
= TVIS_EXPANDED
;
936 tvItem
.item
.stateMask
= TVIS_EXPANDED
;
937 tvItem
.item
.pszText
= pLabelMap
->szDesc
;
938 if (pLabelContext
->szValue
&& _tcslen(pLabelContext
->szValue
) > 0)
940 tvItem
.item
.iImage
= IMAGE_SOUND_ASSIGNED
;
941 tvItem
.item
.iSelectedImage
= IMAGE_SOUND_ASSIGNED
;
945 tvItem
.item
.iImage
= IMAGE_SOUND_NONE
;
946 tvItem
.item
.iSelectedImage
= IMAGE_SOUND_NONE
;
948 tvItem
.item
.lParam
= (LPARAM
)FindLabelContext(pGlobalData
, pScheme
, pAppMap
->szName
, pLabelMap
->szName
);
950 TreeView_InsertItem(hList
, &tvItem
);
952 pLabelMap
= pLabelMap
->Next
;
954 pAppMap
= pAppMap
->Next
;
961 ApplyChanges(HWND hwndDlg
)
965 PSOUND_SCHEME_CONTEXT pScheme
;
967 PLABEL_CONTEXT pLabelContext
;
970 hDlgCtrl
= GetDlgItem(hwndDlg
, IDC_SOUND_SCHEME
);
972 lIndex
= SendMessage(hDlgCtrl
, CB_GETCURSEL
, (WPARAM
)0, (LPARAM
)0);
973 if (lIndex
== CB_ERR
)
978 lIndex
= SendMessage(hDlgCtrl
, CB_GETITEMDATA
, (WPARAM
)lIndex
, (LPARAM
)0);
979 if (lIndex
== CB_ERR
)
983 pScheme
= (PSOUND_SCHEME_CONTEXT
)lIndex
;
985 if (RegOpenKeyEx(HKEY_CURRENT_USER
,
986 _T("AppEvents\\Schemes"),
989 &hKey
) != ERROR_SUCCESS
)
994 RegSetValueEx(hKey
, NULL
, 0, REG_SZ
, (LPBYTE
)pScheme
->szName
, (_tcslen(pScheme
->szName
) +1) * sizeof(TCHAR
));
997 if (RegOpenKeyEx(HKEY_CURRENT_USER
,
998 _T("AppEvents\\Schemes\\Apps"),
1001 &hKey
) != ERROR_SUCCESS
)
1006 pLabelContext
= pScheme
->LabelContext
;
1008 while (pLabelContext
)
1010 _stprintf(Buffer
, _T("%s\\%s\\.Current"), pLabelContext
->AppMap
->szName
, pLabelContext
->LabelMap
->szName
);
1012 if (RegOpenKeyEx(hKey
, Buffer
, 0, KEY_WRITE
, &hSubKey
) == ERROR_SUCCESS
)
1014 RegSetValueEx(hSubKey
, NULL
, 0, REG_EXPAND_SZ
, (LPBYTE
)pLabelContext
->szValue
, (_tcslen(pLabelContext
->szValue
) +1) * sizeof(TCHAR
));
1015 RegCloseKey(hSubKey
);
1018 pLabelContext
= pLabelContext
->Next
;
1022 SetWindowLongPtr(hwndDlg
, DWLP_MSGRESULT
, (LONG_PTR
)PSNRET_NOERROR
);
1028 InitImageList(UINT StartResource
,
1039 /* Create the toolbar icon image list */
1040 himl
= ImageList_Create(Width
,
1042 ILC_MASK
| ILC_COLOR32
,
1043 EndResource
- StartResource
,
1049 for (i
= StartResource
; i
<= EndResource
&& ret
!= -1; i
++)
1051 hImage
= LoadImageW(hApplet
,
1052 MAKEINTRESOURCEW(i
),
1056 LR_LOADTRANSPARENT
);
1059 ImageList_Destroy(himl
);
1064 if (type
== IMAGE_BITMAP
)
1066 ret
= ImageList_AddMasked(himl
,
1070 else if (type
== IMAGE_ICON
)
1072 ret
= ImageList_AddIcon(himl
,
1076 DeleteObject(hImage
);
1081 ImageList_Destroy(himl
);
1089 /* Sounds property page dialog callback */
1092 SoundsDlgProc(HWND hwndDlg
,
1097 PGLOBAL_DATA pGlobalData
;
1100 WCHAR filename
[MAX_PATH
];
1101 WCHAR szFilter
[256], szTitle
[256];
1105 pGlobalData
= (PGLOBAL_DATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
1111 pGlobalData
= (PGLOBAL_DATA
)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(GLOBAL_DATA
));
1112 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pGlobalData
);
1114 pGlobalData
->NumWavOut
= waveOutGetNumDevs();
1116 SendMessage(GetDlgItem(hwndDlg
, IDC_PLAY_SOUND
),
1117 BM_SETIMAGE
,(WPARAM
)IMAGE_ICON
,
1118 (LPARAM
)(HANDLE
)LoadIcon(hApplet
, MAKEINTRESOURCE(IDI_PLAY_ICON
)));
1120 pGlobalData
->hSoundsImageList
= InitImageList(IDI_SOUND_SECTION
,
1122 GetSystemMetrics(SM_CXSMICON
),
1123 GetSystemMetrics(SM_CXSMICON
),
1126 LoadEventLabels(pGlobalData
);
1127 LoadSoundProfiles(pGlobalData
, hwndDlg
);
1128 LoadSoundFiles(hwndDlg
);
1129 ShowSoundScheme(pGlobalData
, hwndDlg
);
1131 if (wParam
== (WPARAM
)GetDlgItem(hwndDlg
, IDC_SOUND_SCHEME
))
1133 SetFocus(GetDlgItem(hwndDlg
, IDC_SOUND_SCHEME
));
1138 switch (LOWORD(wParam
))
1140 case IDC_BROWSE_SOUND
:
1142 ZeroMemory(&ofn
, sizeof(ofn
));
1143 ofn
.lStructSize
= sizeof(ofn
);
1144 ofn
.hwndOwner
= hwndDlg
;
1145 ofn
.lpstrFile
= filename
;
1146 ofn
.lpstrFile
[0] = L
'\0';
1147 ofn
.nMaxFile
= _countof(filename
);
1148 LoadStringW(hApplet
, IDS_WAVE_FILES_FILTER
, szFilter
, _countof(szFilter
));
1149 ofn
.lpstrFilter
= MakeFilter(szFilter
);
1150 ofn
.nFilterIndex
= 0;
1151 LoadStringW(hApplet
, IDS_BROWSE_FOR_SOUND
, szTitle
, _countof(szTitle
));
1152 ofn
.lpstrTitle
= szTitle
;
1153 ofn
.lpstrInitialDir
= L
"%SystemRoot%\\Media";
1154 ofn
.Flags
= OFN_FILEMUSTEXIST
| OFN_HIDEREADONLY
;
1156 if (GetOpenFileNameW(&ofn
) != FALSE
)
1158 // FIXME search if list already contains that sound
1160 // extract file name
1161 pFileName
= wcsrchr(filename
, L
'\\');
1162 ASSERT(pFileName
!= NULL
);
1166 lResult
= SendDlgItemMessageW(hwndDlg
, IDC_SOUND_LIST
, CB_ADDSTRING
, (WPARAM
)0, (LPARAM
)pFileName
);
1167 if (lResult
!= CB_ERR
)
1169 // add path and select item
1170 SendDlgItemMessageW(hwndDlg
, IDC_SOUND_LIST
, CB_SETITEMDATA
, (WPARAM
)lResult
, (LPARAM
)_wcsdup(filename
));
1171 SendDlgItemMessageW(hwndDlg
, IDC_SOUND_LIST
, CB_SETCURSEL
, (WPARAM
)lResult
, (LPARAM
)0);
1176 case IDC_PLAY_SOUND
:
1179 lIndex
= ComboBox_GetCurSel(GetDlgItem(hwndDlg
, IDC_SOUND_LIST
));
1180 if (lIndex
== CB_ERR
)
1185 lIndex
= ComboBox_GetItemData(GetDlgItem(hwndDlg
, IDC_SOUND_LIST
), lIndex
);
1186 if (lIndex
!= CB_ERR
)
1188 PlaySound((TCHAR
*)lIndex
, NULL
, SND_FILENAME
);
1192 case IDC_SOUND_SCHEME
:
1194 if (HIWORD(wParam
) == CBN_SELENDOK
)
1196 (void)TreeView_DeleteAllItems(GetDlgItem(hwndDlg
, IDC_SCHEME_LIST
));
1197 ShowSoundScheme(pGlobalData
, hwndDlg
);
1198 EnableWindow(GetDlgItem(hwndDlg
, IDC_SOUND_LIST
), FALSE
);
1199 EnableWindow(GetDlgItem(hwndDlg
, IDC_TEXT_SOUND
), FALSE
);
1200 EnableWindow(GetDlgItem(hwndDlg
, IDC_PLAY_SOUND
), FALSE
);
1201 EnableWindow(GetDlgItem(hwndDlg
, IDC_BROWSE_SOUND
), FALSE
);
1202 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
1206 case IDC_SOUND_LIST
:
1208 if (HIWORD(wParam
) == CBN_SELENDOK
)
1210 PLABEL_CONTEXT pLabelContext
;
1215 hItem
= TreeView_GetSelection(GetDlgItem(hwndDlg
, IDC_SCHEME_LIST
));
1221 lIndex
= ComboBox_GetCurSel(GetDlgItem(hwndDlg
, IDC_SOUND_LIST
));
1222 if (lIndex
== CB_ERR
)
1227 ZeroMemory(&item
, sizeof(item
));
1228 item
.mask
= TVIF_PARAM
;
1230 if (TreeView_GetItem(GetDlgItem(hwndDlg
, IDC_SCHEME_LIST
), &item
))
1233 pLabelContext
= (PLABEL_CONTEXT
)item
.lParam
;
1235 lResult
= ComboBox_GetItemData(GetDlgItem(hwndDlg
, IDC_SOUND_LIST
), lIndex
);
1236 if (lResult
== CB_ERR
|| lResult
== 0)
1238 if (lIndex
!= pLabelContext
->szValue
[0])
1239 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
1241 pLabelContext
->szValue
[0] = L
'\0';
1245 if (_tcsicmp(pLabelContext
->szValue
, (TCHAR
*)lResult
) || (lIndex
!= pLabelContext
->szValue
[0]))
1247 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
1249 /// Should store in current member
1251 _tcscpy(pLabelContext
->szValue
, (TCHAR
*)lResult
);
1253 if (_tcslen((TCHAR
*)lResult
) && lIndex
!= 0 && pGlobalData
->NumWavOut
!= 0)
1255 EnableWindow(GetDlgItem(hwndDlg
, IDC_PLAY_SOUND
), TRUE
);
1259 EnableWindow(GetDlgItem(hwndDlg
, IDC_PLAY_SOUND
), FALSE
);
1270 FreeSoundProfiles(hwndDlg
);
1271 FreeAppMap(pGlobalData
);
1272 FreeLabelMap(pGlobalData
);
1273 if (pGlobalData
->hSoundsImageList
)
1274 ImageList_Destroy(pGlobalData
->hSoundsImageList
);
1275 HeapFree(GetProcessHeap(), 0, pGlobalData
);
1280 PLABEL_CONTEXT pLabelContext
;
1283 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
1289 ApplyChanges(hwndDlg
);
1292 case TVN_SELCHANGED
:
1294 LPNMTREEVIEW nm
= (LPNMTREEVIEW
)lParam
;
1295 LRESULT lCount
, lIndex
, lResult
;
1297 pLabelContext
= (PLABEL_CONTEXT
)nm
->itemNew
.lParam
;
1298 if (pLabelContext
== NULL
)
1300 EnableWindow(GetDlgItem(hwndDlg
, IDC_SOUND_LIST
), FALSE
);
1301 EnableWindow(GetDlgItem(hwndDlg
, IDC_TEXT_SOUND
), FALSE
);
1302 EnableWindow(GetDlgItem(hwndDlg
, IDC_BROWSE_SOUND
), FALSE
);
1303 EnableWindow(GetDlgItem(hwndDlg
, IDC_PLAY_SOUND
), FALSE
);
1307 EnableWindow(GetDlgItem(hwndDlg
, IDC_SOUND_LIST
), TRUE
);
1308 EnableWindow(GetDlgItem(hwndDlg
, IDC_TEXT_SOUND
), TRUE
);
1309 EnableWindow(GetDlgItem(hwndDlg
, IDC_BROWSE_SOUND
), TRUE
);
1311 if (_tcslen(pLabelContext
->szValue
) == 0)
1313 lIndex
= ComboBox_SetCurSel(GetDlgItem(hwndDlg
, IDC_SOUND_LIST
), 0);
1314 EnableWindow(GetDlgItem(hwndDlg
, IDC_PLAY_SOUND
), FALSE
);
1318 if (pGlobalData
->NumWavOut
!= 0)
1319 EnableWindow(GetDlgItem(hwndDlg
, IDC_PLAY_SOUND
), TRUE
);
1321 lCount
= ComboBox_GetCount(GetDlgItem(hwndDlg
, IDC_SOUND_LIST
));
1322 for (lIndex
= 0; lIndex
< lCount
; lIndex
++)
1324 lResult
= ComboBox_GetItemData(GetDlgItem(hwndDlg
, IDC_SOUND_LIST
), lIndex
);
1325 if (lResult
== CB_ERR
|| lResult
== 0)
1328 if (!_tcscmp((TCHAR
*)lResult
, pLabelContext
->szValue
))
1330 ComboBox_SetCurSel(GetDlgItem(hwndDlg
, IDC_SOUND_LIST
), lIndex
);
1335 ptr
= _tcsrchr(pLabelContext
->szValue
, _T('\\'));
1342 ptr
= pLabelContext
->szValue
;
1345 lIndex
= ComboBox_AddString(GetDlgItem(hwndDlg
, IDC_SOUND_LIST
), ptr
);
1346 if (lIndex
!= CB_ERR
)
1348 ComboBox_SetItemData(GetDlgItem(hwndDlg
, IDC_SOUND_LIST
), lIndex
, _tcsdup(pLabelContext
->szValue
));
1349 ComboBox_SetCurSel(GetDlgItem(hwndDlg
, IDC_SOUND_LIST
), lIndex
);