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
;
60 } GLOBAL_DATA
, *PGLOBAL_DATA
;
63 /* A filter string is a list separated by NULL and ends with double NULLs. */
64 LPWSTR
MakeFilter(LPWSTR psz
)
68 ASSERT(psz
[0] != UNICODE_NULL
&&
69 psz
[wcslen(psz
) - 1] == L
'|');
70 for (pch
= psz
; *pch
!= UNICODE_NULL
; pch
++)
72 /* replace vertical bar with NULL */
81 PLABEL_MAP
FindLabel(PGLOBAL_DATA pGlobalData
, PAPP_MAP pAppMap
, TCHAR
* szName
)
83 PLABEL_MAP pMap
= pGlobalData
->pLabelMap
;
89 if (!_tcscmp(pMap
->szName
, szName
))
95 pMap
= pAppMap
->LabelMap
;
100 ASSERT(pMap
->szName
);
101 if (!_tcscmp(pMap
->szName
, szName
))
107 pMap
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(LABEL_MAP
));
111 pMap
->szName
= pMap
->szDesc
= _tcsdup(szName
);
114 HeapFree(GetProcessHeap(), 0, pMap
);
118 pMap
->AppMap
= pAppMap
;
119 pMap
->Next
= pGlobalData
->pLabelMap
;
120 pGlobalData
->pLabelMap
= pMap
;
126 VOID
RemoveLabel(PGLOBAL_DATA pGlobalData
, PLABEL_MAP pMap
)
128 PLABEL_MAP pCurMap
= pGlobalData
->pLabelMap
;
132 pGlobalData
->pLabelMap
= pGlobalData
->pLabelMap
->Next
;
138 if (pCurMap
->Next
== pMap
)
140 pCurMap
->Next
= pCurMap
->Next
->Next
;
143 pCurMap
= pCurMap
->Next
;
149 FreeLabelMap(PGLOBAL_DATA pGlobalData
)
153 while (pGlobalData
->pLabelMap
)
155 pCurMap
= pGlobalData
->pLabelMap
->Next
;
156 HeapFree(GetProcessHeap(), 0, pGlobalData
->pLabelMap
);
157 pGlobalData
->pLabelMap
= pCurMap
;
161 PAPP_MAP
FindApp(PGLOBAL_DATA pGlobalData
, TCHAR
*szName
)
163 PAPP_MAP pMap
= pGlobalData
->pAppMap
;
167 if (!_tcscmp(pMap
->szName
, szName
))
178 FreeAppMap(PGLOBAL_DATA pGlobalData
)
182 while (pGlobalData
->pAppMap
)
184 pCurMap
= pGlobalData
->pAppMap
->Next
;
185 HeapFree(GetProcessHeap(), 0, pGlobalData
->pAppMap
);
186 pGlobalData
->pAppMap
= pCurMap
;
190 PLABEL_CONTEXT
FindLabelContext(PGLOBAL_DATA pGlobalData
, PSOUND_SCHEME_CONTEXT pSoundScheme
, TCHAR
* AppName
, TCHAR
* LabelName
)
192 PLABEL_CONTEXT pLabelContext
;
194 pLabelContext
= pSoundScheme
->LabelContext
;
196 while (pLabelContext
)
198 ASSERT(pLabelContext
->AppMap
);
199 ASSERT(pLabelContext
->LabelMap
);
201 if (!_tcsicmp(pLabelContext
->AppMap
->szName
, AppName
) && !_tcsicmp(pLabelContext
->LabelMap
->szName
, LabelName
))
203 return pLabelContext
;
205 pLabelContext
= pLabelContext
->Next
;
208 pLabelContext
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(LABEL_CONTEXT
));
212 pLabelContext
->AppMap
= FindApp(pGlobalData
, AppName
);
213 pLabelContext
->LabelMap
= FindLabel(pGlobalData
, pLabelContext
->AppMap
, LabelName
);
214 ASSERT(pLabelContext
->AppMap
);
215 ASSERT(pLabelContext
->LabelMap
);
216 pLabelContext
->szValue
[0] = _T('\0');
217 pLabelContext
->Next
= pSoundScheme
->LabelContext
;
218 pSoundScheme
->LabelContext
= pLabelContext
;
220 return pLabelContext
;
225 LoadEventLabel(PGLOBAL_DATA pGlobalData
, HKEY hKey
, TCHAR
* szSubKey
)
229 TCHAR szDesc
[MAX_PATH
];
230 TCHAR szData
[MAX_PATH
];
233 if (RegOpenKeyEx(hKey
,
237 &hSubKey
) != ERROR_SUCCESS
)
242 cbValue
= sizeof(szDesc
);
243 if (RegQueryValueEx(hSubKey
,
248 &cbValue
) != ERROR_SUCCESS
)
250 RegCloseKey(hSubKey
);
254 cbValue
= sizeof(szData
);
255 if (RegQueryValueEx(hSubKey
,
260 &cbValue
) != ERROR_SUCCESS
)
262 RegCloseKey(hSubKey
);
266 pMap
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(LABEL_MAP
));
272 pMap
->szName
= _tcsdup(szSubKey
);
273 pMap
->szDesc
= _tcsdup(szDesc
);
274 pMap
->szIcon
= _tcsdup(szData
);
276 if (pGlobalData
->pLabelMap
)
278 pMap
->Next
= pGlobalData
->pLabelMap
;
279 pGlobalData
->pLabelMap
= pMap
;
283 pGlobalData
->pLabelMap
= pMap
;
284 pGlobalData
->pLabelMap
->Next
= NULL
;
291 LoadEventLabels(PGLOBAL_DATA pGlobalData
)
295 TCHAR szName
[MAX_PATH
];
299 if (RegOpenKeyEx(HKEY_CURRENT_USER
,
300 _T("AppEvents\\EventLabels"),
303 &hSubKey
) != ERROR_SUCCESS
)
312 dwName
= _countof(szName
);
313 dwResult
= RegEnumKeyEx(hSubKey
,
322 if (dwResult
== ERROR_SUCCESS
)
324 if (LoadEventLabel(pGlobalData
, hSubKey
, szName
))
331 } while (dwResult
== ERROR_SUCCESS
);
333 RegCloseKey(hSubKey
);
334 return (dwCount
!= 0);
339 AddSoundProfile(HWND hwndDlg
, HKEY hKey
, TCHAR
* szSubKey
, BOOL SetDefault
)
342 TCHAR szValue
[MAX_PATH
];
343 DWORD cbValue
, dwResult
;
345 PSOUND_SCHEME_CONTEXT pScheme
;
347 if (RegOpenKeyEx(hKey
,
351 &hSubKey
) != ERROR_SUCCESS
)
356 cbValue
= sizeof(szValue
);
357 dwResult
= RegQueryValueEx(hSubKey
,
363 RegCloseKey(hSubKey
);
365 if (dwResult
!= ERROR_SUCCESS
)
368 /* Try to add the new profile */
369 lResult
= ComboBox_AddString(GetDlgItem(hwndDlg
, IDC_SOUND_SCHEME
), szValue
);
370 if (lResult
== CB_ERR
)
373 /* Allocate the profile scheme buffer */
374 pScheme
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(SOUND_SCHEME_CONTEXT
));
377 /* We failed to allocate the buffer, no need to keep a dangling string in the combobox */
378 ComboBox_DeleteString(GetDlgItem(hwndDlg
, IDC_SOUND_SCHEME
), lResult
);
382 StringCchCopy(pScheme
->szDesc
, MAX_PATH
, szValue
);
383 StringCchCopy(pScheme
->szName
, MAX_PATH
, szSubKey
);
385 /* Associate the value with the item in the combobox */
386 ComboBox_SetItemData(GetDlgItem(hwndDlg
, IDC_SOUND_SCHEME
), lResult
, pScheme
);
388 /* Optionally, select the profile */
391 ComboBox_SetCurSel(GetDlgItem(hwndDlg
, IDC_SOUND_SCHEME
), lResult
);
399 EnumerateSoundProfiles(PGLOBAL_DATA pGlobalData
, HWND hwndDlg
, HKEY hKey
)
402 DWORD dwName
, dwCurKey
, dwResult
, dwNumSchemes
;
404 TCHAR szName
[MAX_PATH
];
406 cbDefault
= sizeof(pGlobalData
->szDefault
);
407 if (RegQueryValueEx(hKey
,
411 (LPBYTE
)pGlobalData
->szDefault
,
412 &cbDefault
) != ERROR_SUCCESS
)
417 if (RegOpenKeyEx(hKey
,
421 &hSubKey
) != ERROR_SUCCESS
)
430 dwName
= _countof(szName
);
431 dwResult
= RegEnumKeyEx(hSubKey
,
440 if (dwResult
== ERROR_SUCCESS
)
442 if (AddSoundProfile(hwndDlg
, hSubKey
, szName
, (!_tcsicmp(szName
, pGlobalData
->szDefault
))))
449 } while (dwResult
== ERROR_SUCCESS
);
451 RegCloseKey(hSubKey
);
456 PSOUND_SCHEME_CONTEXT
FindSoundProfile(HWND hwndDlg
, TCHAR
* szName
)
458 LRESULT lCount
, lIndex
, lResult
;
459 PSOUND_SCHEME_CONTEXT pScheme
;
462 hwndComboBox
= GetDlgItem(hwndDlg
, IDC_SOUND_SCHEME
);
463 lCount
= ComboBox_GetCount(hwndComboBox
);
464 if (lCount
== CB_ERR
)
469 for (lIndex
= 0; lIndex
< lCount
; lIndex
++)
471 lResult
= ComboBox_GetItemData(hwndComboBox
, lIndex
);
472 if (lResult
== CB_ERR
)
477 pScheme
= (PSOUND_SCHEME_CONTEXT
)lResult
;
478 if (!_tcsicmp(pScheme
->szName
, szName
))
488 FreeSoundProfiles(HWND hwndDlg
)
490 LRESULT lCount
, lIndex
, lResult
;
491 PSOUND_SCHEME_CONTEXT pScheme
;
492 PLABEL_CONTEXT pLabelContext
;
495 hwndComboBox
= GetDlgItem(hwndDlg
, IDC_SOUND_SCHEME
);
496 lCount
= ComboBox_GetCount(hwndComboBox
);
497 if (lCount
== CB_ERR
)
500 for (lIndex
= 0; lIndex
< lCount
; lIndex
++)
502 lResult
= ComboBox_GetItemData(hwndComboBox
, lIndex
);
503 if (lResult
== CB_ERR
)
508 pScheme
= (PSOUND_SCHEME_CONTEXT
)lResult
;
510 while (pScheme
->LabelContext
)
512 pLabelContext
= pScheme
->LabelContext
->Next
;
513 HeapFree(GetProcessHeap(), 0, pScheme
->LabelContext
);
514 pScheme
->LabelContext
= pLabelContext
;
517 HeapFree(GetProcessHeap(), 0, pScheme
);
522 ImportSoundLabel(PGLOBAL_DATA pGlobalData
, HWND hwndDlg
, HKEY hKey
, TCHAR
* szProfile
, TCHAR
* szLabelName
, TCHAR
* szAppName
, PAPP_MAP AppMap
, PLABEL_MAP LabelMap
)
525 TCHAR szValue
[MAX_PATH
];
526 TCHAR szBuffer
[MAX_PATH
];
527 DWORD cbValue
, cchLength
;
528 PSOUND_SCHEME_CONTEXT pScheme
;
529 PLABEL_CONTEXT pLabelContext
;
530 BOOL bCurrentProfile
, bActiveProfile
;
532 //MessageBox(hwndDlg, szProfile, szLabelName, MB_OK);
534 bCurrentProfile
= !_tcsicmp(szProfile
, _T(".Current"));
535 bActiveProfile
= !_tcsicmp(szProfile
, pGlobalData
->szDefault
);
537 if (RegOpenKeyEx(hKey
,
541 &hSubKey
) != ERROR_SUCCESS
)
546 cbValue
= sizeof(szValue
);
547 if (RegQueryValueEx(hSubKey
,
552 &cbValue
) != ERROR_SUCCESS
)
558 pScheme
= FindSoundProfile(hwndDlg
, pGlobalData
->szDefault
);
560 pScheme
= FindSoundProfile(hwndDlg
, szProfile
);
564 //MessageBox(hwndDlg, szProfile, _T("no profile!!"), MB_OK);
567 pLabelContext
= FindLabelContext(pGlobalData
, pScheme
, AppMap
->szName
, LabelMap
->szName
);
569 cchLength
= ExpandEnvironmentStrings(szValue
, szBuffer
, _countof(szBuffer
));
570 if (cchLength
== 0 || cchLength
> _countof(szBuffer
))
577 _tcscpy(pLabelContext
->szValue
, szBuffer
);
578 else if (!bActiveProfile
)
579 _tcscpy(pLabelContext
->szValue
, szBuffer
);
586 ImportSoundEntry(PGLOBAL_DATA pGlobalData
, HWND hwndDlg
, HKEY hKey
, TCHAR
* szLabelName
, TCHAR
* szAppName
, PAPP_MAP pAppMap
)
593 TCHAR szProfile
[MAX_PATH
];
596 if (RegOpenKeyEx(hKey
,
600 &hSubKey
) != ERROR_SUCCESS
)
604 pLabel
= FindLabel(pGlobalData
, pAppMap
, szLabelName
);
607 RemoveLabel(pGlobalData
, pLabel
);
609 pLabel
->AppMap
= pAppMap
;
610 pLabel
->Next
= pAppMap
->LabelMap
;
611 pAppMap
->LabelMap
= pLabel
;
617 dwProfile
= _countof(szProfile
);
618 dwResult
= RegEnumKeyEx(hSubKey
,
627 if (dwResult
== ERROR_SUCCESS
)
629 if (ImportSoundLabel(pGlobalData
, hwndDlg
, hSubKey
, szProfile
, szLabelName
, szAppName
, pAppMap
, pLabel
))
636 } while (dwResult
== ERROR_SUCCESS
);
638 RegCloseKey(hSubKey
);
640 return dwNumProfiles
;
645 ImportAppProfile(PGLOBAL_DATA pGlobalData
, HWND hwndDlg
, HKEY hKey
, TCHAR
* szAppName
)
648 TCHAR szDefault
[MAX_PATH
];
654 TCHAR szName
[MAX_PATH
];
655 TCHAR szIcon
[MAX_PATH
];
658 //MessageBox(hwndDlg, szAppName, _T("Importing...\n"), MB_OK);
660 AppMap
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(APP_MAP
));
664 if (RegOpenKeyEx(hKey
,
668 &hSubKey
) != ERROR_SUCCESS
)
670 HeapFree(GetProcessHeap(), 0, AppMap
);
674 cbValue
= sizeof(szDefault
);
675 if (RegQueryValueEx(hSubKey
,
680 &cbValue
) != ERROR_SUCCESS
)
682 RegCloseKey(hSubKey
);
683 HeapFree(GetProcessHeap(), 0, AppMap
);
687 cbValue
= sizeof(szIcon
);
688 if (RegQueryValueEx(hSubKey
,
693 &cbValue
) != ERROR_SUCCESS
)
695 szIcon
[0] = _T('\0');
698 /* initialize app map */
699 _tcscpy(AppMap
->szName
, szAppName
);
700 _tcscpy(AppMap
->szDesc
, szDefault
);
701 _tcscpy(AppMap
->szIcon
, szIcon
);
703 AppMap
->Next
= pGlobalData
->pAppMap
;
704 pGlobalData
->pAppMap
= AppMap
;
711 dwName
= _countof(szName
);
712 dwResult
= RegEnumKeyEx(hSubKey
,
720 if (dwResult
== ERROR_SUCCESS
)
722 if (ImportSoundEntry(pGlobalData
, hwndDlg
, hSubKey
, szName
, szAppName
, AppMap
))
728 } while (dwResult
== ERROR_SUCCESS
);
730 RegCloseKey(hSubKey
);
736 ImportSoundProfiles(PGLOBAL_DATA pGlobalData
, HWND hwndDlg
, HKEY hKey
)
741 TCHAR szName
[MAX_PATH
];
744 if (RegOpenKeyEx(hKey
,
748 &hSubKey
) != ERROR_SUCCESS
)
757 dwResult
= RegEnumKey(hSubKey
,
762 if (dwResult
== ERROR_SUCCESS
)
764 if (ImportAppProfile(pGlobalData
, hwndDlg
, hSubKey
, szName
))
770 } while (dwResult
== ERROR_SUCCESS
);
772 RegCloseKey(hSubKey
);
774 return (dwNumApps
!= 0);
779 LoadSoundProfiles(PGLOBAL_DATA pGlobalData
, HWND hwndDlg
)
784 if (RegOpenKeyEx(HKEY_CURRENT_USER
,
785 _T("AppEvents\\Schemes"),
788 &hSubKey
) != ERROR_SUCCESS
)
793 dwNumSchemes
= EnumerateSoundProfiles(pGlobalData
, hwndDlg
, hSubKey
);
798 //MessageBox(hwndDlg, _T("importing sound profiles..."), NULL, MB_OK);
799 ImportSoundProfiles(pGlobalData
, hwndDlg
, hSubKey
);
802 RegCloseKey(hSubKey
);
808 LoadSoundFiles(HWND hwndDlg
)
811 WCHAR szPath
[MAX_PATH
];
813 WIN32_FIND_DATAW FileData
;
818 /* Add no sound listview item */
819 if (LoadString(hApplet
, IDS_NO_SOUND
, szList
, _countof(szList
)))
821 szList
[_countof(szList
) - 1] = TEXT('\0');
822 ComboBox_AddString(GetDlgItem(hwndDlg
, IDC_SOUND_LIST
), szList
);
825 /* Load sound files */
826 length
= GetWindowsDirectoryW(szPath
, MAX_PATH
);
827 if (length
== 0 || length
>= MAX_PATH
- 9)
831 if (szPath
[length
-1] != L
'\\')
833 szPath
[length
] = L
'\\';
836 wcscpy(&szPath
[length
], L
"media\\*");
839 hFile
= FindFirstFileW(szPath
, &FileData
);
840 if (hFile
== INVALID_HANDLE_VALUE
)
847 if (FileData
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
850 ptr
= wcsrchr(FileData
.cFileName
, L
'\\');
857 ptr
= FileData
.cFileName
;
859 lResult
= SendDlgItemMessageW(hwndDlg
, IDC_SOUND_LIST
, CB_ADDSTRING
, (WPARAM
)0, (LPARAM
)ptr
);
860 if (lResult
!= CB_ERR
)
862 wcscpy(&szPath
[length
-1], FileData
.cFileName
);
863 SendDlgItemMessageW(hwndDlg
, IDC_SOUND_LIST
, CB_SETITEMDATA
, (WPARAM
)lResult
, (LPARAM
)_wcsdup(szPath
));
865 } while (FindNextFileW(hFile
, &FileData
) != 0);
873 ShowSoundScheme(PGLOBAL_DATA pGlobalData
, HWND hwndDlg
)
876 PSOUND_SCHEME_CONTEXT pScheme
;
878 PLABEL_MAP pLabelMap
;
879 PLABEL_CONTEXT pLabelContext
;
880 HWND hDlgCtrl
, hList
;
881 TVINSERTSTRUCT tvItem
;
884 hDlgCtrl
= GetDlgItem(hwndDlg
, IDC_SOUND_SCHEME
);
885 hList
= GetDlgItem(hwndDlg
, IDC_SCHEME_LIST
);
887 if (pGlobalData
->hSoundsImageList
!= NULL
)
889 TreeView_SetImageList(hList
, pGlobalData
->hSoundsImageList
, TVSIL_NORMAL
);
892 lIndex
= SendMessage(hDlgCtrl
, CB_GETCURSEL
, (WPARAM
)0, (LPARAM
)0);
893 if (lIndex
== CB_ERR
)
898 lIndex
= SendMessage(hDlgCtrl
, CB_GETITEMDATA
, (WPARAM
)lIndex
, (LPARAM
)0);
899 if (lIndex
== CB_ERR
)
903 pScheme
= (PSOUND_SCHEME_CONTEXT
)lIndex
;
905 _tcscpy(pGlobalData
->szDefault
, pScheme
->szName
);
907 pAppMap
= pGlobalData
->pAppMap
;
910 ZeroMemory(&tvItem
, sizeof(tvItem
));
911 tvItem
.hParent
= TVI_ROOT
;
912 tvItem
.hInsertAfter
= TVI_FIRST
;
914 tvItem
.item
.mask
= TVIF_STATE
| TVIF_TEXT
| TVIF_PARAM
| TVIF_IMAGE
| TVIF_SELECTEDIMAGE
;
915 tvItem
.item
.state
= TVIS_EXPANDED
;
916 tvItem
.item
.stateMask
= TVIS_EXPANDED
;
917 tvItem
.item
.pszText
= pAppMap
->szDesc
;
918 tvItem
.item
.iImage
= IMAGE_SOUND_SECTION
;
919 tvItem
.item
.iSelectedImage
= IMAGE_SOUND_SECTION
;
920 tvItem
.item
.lParam
= (LPARAM
)NULL
;
922 hTreeItem
= TreeView_InsertItem(hList
, &tvItem
);
924 pLabelMap
= pAppMap
->LabelMap
;
927 pLabelContext
= FindLabelContext(pGlobalData
, pScheme
, pAppMap
->szName
, pLabelMap
->szName
);
929 ZeroMemory(&tvItem
, sizeof(tvItem
));
930 tvItem
.hParent
= hTreeItem
;
931 tvItem
.hInsertAfter
= TVI_SORT
;
933 tvItem
.item
.mask
= TVIF_STATE
| TVIF_TEXT
| TVIF_PARAM
| TVIF_IMAGE
| TVIF_SELECTEDIMAGE
;
934 tvItem
.item
.state
= TVIS_EXPANDED
;
935 tvItem
.item
.stateMask
= TVIS_EXPANDED
;
936 tvItem
.item
.pszText
= pLabelMap
->szDesc
;
937 if (pLabelContext
->szValue
&& _tcslen(pLabelContext
->szValue
) > 0)
939 tvItem
.item
.iImage
= IMAGE_SOUND_ASSIGNED
;
940 tvItem
.item
.iSelectedImage
= IMAGE_SOUND_ASSIGNED
;
944 tvItem
.item
.iImage
= IMAGE_SOUND_NONE
;
945 tvItem
.item
.iSelectedImage
= IMAGE_SOUND_NONE
;
947 tvItem
.item
.lParam
= (LPARAM
)FindLabelContext(pGlobalData
, pScheme
, pAppMap
->szName
, pLabelMap
->szName
);
949 TreeView_InsertItem(hList
, &tvItem
);
951 pLabelMap
= pLabelMap
->Next
;
953 pAppMap
= pAppMap
->Next
;
960 ApplyChanges(HWND hwndDlg
)
964 PSOUND_SCHEME_CONTEXT pScheme
;
966 PLABEL_CONTEXT pLabelContext
;
969 hDlgCtrl
= GetDlgItem(hwndDlg
, IDC_SOUND_SCHEME
);
971 lIndex
= SendMessage(hDlgCtrl
, CB_GETCURSEL
, (WPARAM
)0, (LPARAM
)0);
972 if (lIndex
== CB_ERR
)
977 lIndex
= SendMessage(hDlgCtrl
, CB_GETITEMDATA
, (WPARAM
)lIndex
, (LPARAM
)0);
978 if (lIndex
== CB_ERR
)
982 pScheme
= (PSOUND_SCHEME_CONTEXT
)lIndex
;
984 if (RegOpenKeyEx(HKEY_CURRENT_USER
,
985 _T("AppEvents\\Schemes"),
988 &hKey
) != ERROR_SUCCESS
)
993 RegSetValueEx(hKey
, NULL
, 0, REG_SZ
, (LPBYTE
)pScheme
->szName
, (_tcslen(pScheme
->szName
) +1) * sizeof(TCHAR
));
996 if (RegOpenKeyEx(HKEY_CURRENT_USER
,
997 _T("AppEvents\\Schemes\\Apps"),
1000 &hKey
) != ERROR_SUCCESS
)
1005 pLabelContext
= pScheme
->LabelContext
;
1007 while (pLabelContext
)
1009 _stprintf(Buffer
, _T("%s\\%s\\.Current"), pLabelContext
->AppMap
->szName
, pLabelContext
->LabelMap
->szName
);
1011 if (RegOpenKeyEx(hKey
, Buffer
, 0, KEY_WRITE
, &hSubKey
) == ERROR_SUCCESS
)
1013 RegSetValueEx(hSubKey
, NULL
, 0, REG_EXPAND_SZ
, (LPBYTE
)pLabelContext
->szValue
, (_tcslen(pLabelContext
->szValue
) +1) * sizeof(TCHAR
));
1014 RegCloseKey(hSubKey
);
1017 pLabelContext
= pLabelContext
->Next
;
1021 SetWindowLongPtr(hwndDlg
, DWLP_MSGRESULT
, (LONG_PTR
)PSNRET_NOERROR
);
1027 InitImageList(UINT StartResource
,
1038 /* Create the toolbar icon image list */
1039 himl
= ImageList_Create(Width
,
1041 ILC_MASK
| ILC_COLOR32
,
1042 EndResource
- StartResource
,
1048 for (i
= StartResource
; i
<= EndResource
&& ret
!= -1; i
++)
1050 hImage
= LoadImageW(hApplet
,
1051 MAKEINTRESOURCEW(i
),
1055 LR_LOADTRANSPARENT
);
1058 ImageList_Destroy(himl
);
1063 if (type
== IMAGE_BITMAP
)
1065 ret
= ImageList_AddMasked(himl
,
1069 else if (type
== IMAGE_ICON
)
1071 ret
= ImageList_AddIcon(himl
,
1075 DeleteObject(hImage
);
1080 ImageList_Destroy(himl
);
1088 /* Sounds property page dialog callback */
1091 SoundsDlgProc(HWND hwndDlg
,
1096 PGLOBAL_DATA pGlobalData
;
1099 WCHAR filename
[MAX_PATH
];
1100 WCHAR szFilter
[256], szTitle
[256];
1104 pGlobalData
= (PGLOBAL_DATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
1110 UINT NumWavOut
= waveOutGetNumDevs();
1112 pGlobalData
= (PGLOBAL_DATA
)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(GLOBAL_DATA
));
1113 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pGlobalData
);
1115 SendMessage(GetDlgItem(hwndDlg
, IDC_PLAY_SOUND
),
1116 BM_SETIMAGE
,(WPARAM
)IMAGE_ICON
,
1117 (LPARAM
)(HANDLE
)LoadIcon(hApplet
, MAKEINTRESOURCE(IDI_PLAY_ICON
)));
1119 pGlobalData
->hSoundsImageList
= InitImageList(IDI_SOUND_SECTION
,
1121 GetSystemMetrics(SM_CXSMICON
),
1122 GetSystemMetrics(SM_CXSMICON
),
1125 LoadEventLabels(pGlobalData
);
1126 LoadSoundProfiles(pGlobalData
, hwndDlg
);
1127 LoadSoundFiles(hwndDlg
);
1128 ShowSoundScheme(pGlobalData
, hwndDlg
);
1132 EnableWindow(GetDlgItem(hwndDlg
, IDC_SOUND_SCHEME
), FALSE
);
1133 EnableWindow(GetDlgItem(hwndDlg
, IDC_SAVEAS_BTN
), FALSE
);
1134 EnableWindow(GetDlgItem(hwndDlg
, IDC_DELETE_BTN
), FALSE
);
1135 EnableWindow(GetDlgItem(hwndDlg
, IDC_SCHEME_LIST
), FALSE
);
1138 if (wParam
== (WPARAM
)GetDlgItem(hwndDlg
, IDC_SOUND_SCHEME
))
1140 SetFocus(GetDlgItem(hwndDlg
, IDC_SOUND_SCHEME
));
1145 switch (LOWORD(wParam
))
1147 case IDC_BROWSE_SOUND
:
1149 ZeroMemory(&ofn
, sizeof(ofn
));
1150 ofn
.lStructSize
= sizeof(ofn
);
1151 ofn
.hwndOwner
= hwndDlg
;
1152 ofn
.lpstrFile
= filename
;
1153 ofn
.lpstrFile
[0] = L
'\0';
1154 ofn
.nMaxFile
= _countof(filename
);
1155 LoadStringW(hApplet
, IDS_WAVE_FILES_FILTER
, szFilter
, _countof(szFilter
));
1156 ofn
.lpstrFilter
= MakeFilter(szFilter
);
1157 ofn
.nFilterIndex
= 0;
1158 LoadStringW(hApplet
, IDS_BROWSE_FOR_SOUND
, szTitle
, _countof(szTitle
));
1159 ofn
.lpstrTitle
= szTitle
;
1160 ofn
.lpstrInitialDir
= NULL
;
1161 ofn
.Flags
= OFN_FILEMUSTEXIST
| OFN_HIDEREADONLY
;
1163 if (GetOpenFileNameW(&ofn
) != FALSE
)
1165 // FIXME search if list already contains that sound
1167 // extract file name
1168 pFileName
= wcsrchr(filename
, L
'\\');
1169 ASSERT(pFileName
!= NULL
);
1173 lResult
= SendDlgItemMessageW(hwndDlg
, IDC_SOUND_LIST
, CB_ADDSTRING
, (WPARAM
)0, (LPARAM
)pFileName
);
1174 if (lResult
!= CB_ERR
)
1176 // add path and select item
1177 SendDlgItemMessageW(hwndDlg
, IDC_SOUND_LIST
, CB_SETITEMDATA
, (WPARAM
)lResult
, (LPARAM
)_wcsdup(filename
));
1178 SendDlgItemMessageW(hwndDlg
, IDC_SOUND_LIST
, CB_SETCURSEL
, (WPARAM
)lResult
, (LPARAM
)0);
1183 case IDC_PLAY_SOUND
:
1186 lIndex
= ComboBox_GetCurSel(GetDlgItem(hwndDlg
, IDC_SOUND_LIST
));
1187 if (lIndex
== CB_ERR
)
1192 lIndex
= ComboBox_GetItemData(GetDlgItem(hwndDlg
, IDC_SOUND_LIST
), lIndex
);
1193 if (lIndex
!= CB_ERR
)
1195 PlaySound((TCHAR
*)lIndex
, NULL
, SND_FILENAME
);
1199 case IDC_SOUND_SCHEME
:
1201 if (HIWORD(wParam
) == CBN_SELENDOK
)
1203 (void)TreeView_DeleteAllItems(GetDlgItem(hwndDlg
, IDC_SCHEME_LIST
));
1204 ShowSoundScheme(pGlobalData
, hwndDlg
);
1205 EnableWindow(GetDlgItem(hwndDlg
, IDC_SOUND_LIST
), FALSE
);
1206 EnableWindow(GetDlgItem(hwndDlg
, IDC_TEXT_SOUND
), FALSE
);
1207 EnableWindow(GetDlgItem(hwndDlg
, IDC_PLAY_SOUND
), FALSE
);
1208 EnableWindow(GetDlgItem(hwndDlg
, IDC_BROWSE_SOUND
), FALSE
);
1209 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
1213 case IDC_SOUND_LIST
:
1215 if (HIWORD(wParam
) == CBN_SELENDOK
)
1217 PLABEL_CONTEXT pLabelContext
;
1222 hItem
= TreeView_GetSelection(GetDlgItem(hwndDlg
, IDC_SCHEME_LIST
));
1228 lIndex
= ComboBox_GetCurSel(GetDlgItem(hwndDlg
, IDC_SOUND_LIST
));
1229 if (lIndex
== CB_ERR
)
1234 ZeroMemory(&item
, sizeof(item
));
1235 item
.mask
= TVIF_PARAM
;
1237 if (TreeView_GetItem(GetDlgItem(hwndDlg
, IDC_SCHEME_LIST
), &item
))
1240 pLabelContext
= (PLABEL_CONTEXT
)item
.lParam
;
1242 lResult
= ComboBox_GetItemData(GetDlgItem(hwndDlg
, IDC_SOUND_LIST
), lIndex
);
1243 if (lResult
== CB_ERR
|| lResult
== 0)
1245 if (lIndex
!= pLabelContext
->szValue
[0])
1246 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
1248 pLabelContext
->szValue
[0] = L
'\0';
1252 if (_tcsicmp(pLabelContext
->szValue
, (TCHAR
*)lResult
) || (lIndex
!= pLabelContext
->szValue
[0]))
1254 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
1256 /// Should store in current member
1258 _tcscpy(pLabelContext
->szValue
, (TCHAR
*)lResult
);
1260 if (_tcslen((TCHAR
*)lResult
) && lIndex
!= 0)
1262 EnableWindow(GetDlgItem(hwndDlg
, IDC_PLAY_SOUND
), TRUE
);
1266 EnableWindow(GetDlgItem(hwndDlg
, IDC_PLAY_SOUND
), FALSE
);
1277 FreeSoundProfiles(hwndDlg
);
1278 FreeAppMap(pGlobalData
);
1279 FreeLabelMap(pGlobalData
);
1280 if (pGlobalData
->hSoundsImageList
)
1281 ImageList_Destroy(pGlobalData
->hSoundsImageList
);
1282 HeapFree(GetProcessHeap(), 0, pGlobalData
);
1287 PLABEL_CONTEXT pLabelContext
;
1290 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
1296 ApplyChanges(hwndDlg
);
1299 case TVN_SELCHANGED
:
1301 LPNMTREEVIEW nm
= (LPNMTREEVIEW
)lParam
;
1302 LRESULT lCount
, lIndex
, lResult
;
1304 pLabelContext
= (PLABEL_CONTEXT
)nm
->itemNew
.lParam
;
1305 if (pLabelContext
== NULL
)
1307 EnableWindow(GetDlgItem(hwndDlg
, IDC_SOUND_LIST
), FALSE
);
1308 EnableWindow(GetDlgItem(hwndDlg
, IDC_TEXT_SOUND
), FALSE
);
1309 EnableWindow(GetDlgItem(hwndDlg
, IDC_BROWSE_SOUND
), FALSE
);
1310 EnableWindow(GetDlgItem(hwndDlg
, IDC_PLAY_SOUND
), FALSE
);
1314 EnableWindow(GetDlgItem(hwndDlg
, IDC_SOUND_LIST
), TRUE
);
1315 EnableWindow(GetDlgItem(hwndDlg
, IDC_TEXT_SOUND
), TRUE
);
1316 EnableWindow(GetDlgItem(hwndDlg
, IDC_BROWSE_SOUND
), TRUE
);
1318 if (_tcslen(pLabelContext
->szValue
) == 0)
1320 lIndex
= ComboBox_SetCurSel(GetDlgItem(hwndDlg
, IDC_SOUND_LIST
), 0);
1321 EnableWindow(GetDlgItem(hwndDlg
, IDC_PLAY_SOUND
), FALSE
);
1325 EnableWindow(GetDlgItem(hwndDlg
, IDC_PLAY_SOUND
), TRUE
);
1327 lCount
= ComboBox_GetCount(GetDlgItem(hwndDlg
, IDC_SOUND_LIST
));
1328 for (lIndex
= 0; lIndex
< lCount
; lIndex
++)
1330 lResult
= ComboBox_GetItemData(GetDlgItem(hwndDlg
, IDC_SOUND_LIST
), lIndex
);
1331 if (lResult
== CB_ERR
|| lResult
== 0)
1334 if (!_tcscmp((TCHAR
*)lResult
, pLabelContext
->szValue
))
1336 ComboBox_SetCurSel(GetDlgItem(hwndDlg
, IDC_SOUND_LIST
), lIndex
);
1341 ptr
= _tcsrchr(pLabelContext
->szValue
, _T('\\'));
1348 ptr
= pLabelContext
->szValue
;
1351 lIndex
= ComboBox_AddString(GetDlgItem(hwndDlg
, IDC_SOUND_LIST
), ptr
);
1352 if (lIndex
!= CB_ERR
)
1354 ComboBox_SetItemData(GetDlgItem(hwndDlg
, IDC_SOUND_LIST
), lIndex
, _tcsdup(pLabelContext
->szValue
));
1355 ComboBox_SetCurSel(GetDlgItem(hwndDlg
, IDC_SOUND_LIST
), lIndex
);