/* =============================================================================== NewStatusNotify plugin This plugin notifies you when a contact changes his/hers status with a PopUp. You can customize its look (style of popup, font, text...) and behaviour (the position in the screen, the time to live, the action on a mouse click). File name: "indiv_sounds.c" This file contains the code for individual sound support. Written by: Hrk (Luca Santarelli) (2002-2004), Vasilich (2005-2008) Miranda IM can be found here: http://miranda-im.org/ =============================================================================== */ #include "newstatusnotify.h" #define NICK_COLUMN 140 #define STATUS_COLUMN 110 extern const char* ModuleName; extern aStatus StatusesList[]; extern void Log(char*); extern MYOPTIONS MyOptions; extern HINSTANCE hInst; static void ResetListOptions(HWND); //Declarations BOOL CALLBACK DlgProcSoundOpts(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK DlgProcSoundUIPage(HWND, UINT, WPARAM, LPARAM); int UserInfoInitialise(WPARAM, LPARAM); static BOOL RemoveSoundFromList(HWND); static BOOL SelectSound(HWND); static BOOL PreviewSound(HWND, int); HIMAGELIST GetStatusIconsImgList(char*); //NewKindOfOptionsPage static void ResetListOptions(HWND); HWND hCListClone = NULL; //Definitions static BOOL PreviewSound(HWND hList, int status) { int iSel = ListView_GetSelectionMark(hList); if ( iSel > -1 ) { TCHAR str[MAX_PATH] = { 0 }; //Let's read the file name: ListView_GetItemText(hList, ListView_GetNextItem(hList, -1, LVNI_SELECTED), 1, str, sizeof(str)); //If the string is "(default sound)", we want to hear the default sound indeed ;-) if (lstrcmp(str, TranslateT("(default sound)")) == 0) { if (status==1) SkinPlaySound("UserFromOffline"); else SkinPlaySound(StatusesList[Index(status)].lpzSkinSoundName); } else { //We have a configured sound. // char szSoundFile[MAX_PATH] = { 0 }; TCHAR tszTranslatedSoundFile[MAX_PATH] = { 0 }; /*#ifdef UNICODE WideCharToMultiByte(CP_ACP,0,str,-1,szSoundFile,MAX_PATH,0,0); CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)szSoundFile, (LPARAM)tszTranslatedSoundFile); #else CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)str, (LPARAM)tszTranslatedSoundFile); #endif */ CallService(MS_UTILS_PATHTOABSOLUTET, (WPARAM)str, (LPARAM)tszTranslatedSoundFile); #ifdef MS_SKIN_PLAYSOUNDEX if (ServiceExists(MS_SKIN_PLAYSOUNDEX)) { SkinPlaySoundEx(tszTranslatedSoundFile); } else #endif #ifdef RegIndivSounds SkinPlaySound(tszTranslatedSoundFile); #else { if (MyOptions.AvoidClipping) PlaySound(tszTranslatedSoundFile, NULL, SND_ASYNC | SND_FILENAME | SND_NOSTOP); else PlaySound(tszTranslatedSoundFile, NULL, SND_ASYNC | SND_FILENAME); } #endif } } return TRUE; } //Returns TRUE on sound change, FALSE on error. static BOOL RemoveSoundFromList(HWND hList) { int iSel = ListView_GetNextItem(hList, -1, LVNI_SELECTED); if (iSel > -1) { LVITEM lvitem = { 0 }; TCHAR str[MAX_PATH] = { 0 }; lvitem.mask = LVIF_PARAM; lvitem.iItem = iSel; ListView_GetItemText(hList,iSel,1,str,sizeof(str)); if (lstrcmp(str, TranslateT("(default sound)"))==0) return FALSE; else { //We cycle on the selected items. iSel = -1; while ((iSel = ListView_GetNextItem(hList, iSel, LVNI_SELECTED)) != -1) //ListView_SetItemText(hList, iSel, 1, Translate("(default sound)")); { LV_ITEM _ms_lvi; _ms_lvi.iSubItem = 1; _ms_lvi.pszText = TranslateT("(default sound)"); SNDMSG(hList, LVM_SETITEMTEXT, (WPARAM)iSel, (LPARAM)(LV_ITEM *)&_ms_lvi); } return TRUE; } } else //There is no contact selected. return FALSE; } //Returns TRUE on sound change, FALSE on error. static BOOL SelectSound(HWND hwndDlg) { TCHAR str[MAX_PATH] = { 0 }; OPENFILENAME ofn = { 0 }; HWND hList = GetDlgItem(hwndDlg, IDC_INDSNDLIST); int iSel = ListView_GetNextItem(hList, -1, LVNI_SELECTED); if (iSel <= -1) return FALSE; ListView_GetItemText(hList,ListView_GetNextItem(hList,-1,LVNI_SELECTED),1,str,sizeof(str)); ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = GetParent(hwndDlg); ofn.hInstance = NULL; ofn.lpstrFilter = _T("Wave Files (*.wav)\0*.WAV\0All Files (*)\0*\0"); ofn.lpstrFile = str; ofn.Flags = OFN_FILEMUSTEXIST; ofn.nMaxFile = sizeof(str); ofn.nMaxFileTitle = MAX_PATH; ofn.lpstrDefExt = _T("wav"); if(!GetOpenFileName(&ofn)) return FALSE; //Now let's change the text in the listview. We cycle on the selected items (so that people may choose more than one status) iSel = -1; while ((iSel = ListView_GetNextItem(hList, iSel, LVNI_SELECTED)) != -1) { ListView_SetItemText(hList, iSel,1,str); } return TRUE; } HIMAGELIST GetStatusIconsImgList(char * lpzProto) { HIMAGELIST hList = NULL; hList = ImageList_Create(GetSystemMetrics(SM_CXSMICON), //cx GetSystemMetrics(SM_CYSMICON), //cy ((LOBYTE(LOWORD(GetVersion()))>=5 && LOWORD(GetVersion())!=5)?ILC_COLOR32:ILC_COLOR16)|ILC_MASK, //flags 10, //cInitial: the number of initial images: the statuses are 10! 0); //cGrow: we'll not add any other icon to the list. if (hList != NULL && lpzProto != NULL) { //The list was made, add the icons to it. int i = 0; for (i = ID_STATUS_MIN; i <= ID_STATUS_MAX; i++) { ImageList_AddIcon(hList, LoadSkinnedProtoIcon(lpzProto, StatusesList[Index(i)].ID)); } } return hList; } //========== Individual Sounds: UserInfo page ========== BOOL CALLBACK DlgProcSoundUIPage(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static HANDLE hContact = NULL; switch (msg) { case WM_INITDIALOG: { LV_COLUMN lvc = { 0 }; HWND hList = GetDlgItem(hwndDlg, IDC_INDSNDLIST); RECT aRect = { 0 }; int i; char* lpzProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)lParam,0); //Let's get an image list with the status icons. HIMAGELIST hImgList = GetStatusIconsImgList(lpzProto); hContact = (HANDLE)lParam; ListView_SetImageList(hList, hImgList, LVSIL_SMALL); ImageList_AddIcon(hImgList, LoadSkinnedIcon(SKINICON_OTHER_USERONLINE)); // icon for UserFromOffline sound GetClientRect(hList, &aRect); lvc.mask = LVCF_WIDTH | LVCF_TEXT; ListView_SetExtendedListViewStyleEx(hList, LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP, LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP); lvc.cx = STATUS_COLUMN; lvc.pszText = TranslateT("Status"); SNDMSG((hList), LVM_INSERTCOLUMN, 0, (LPARAM)(const LV_COLUMN *)(&lvc)); lvc.cx = aRect.right - STATUS_COLUMN - GetSystemMetrics(SM_CXVSCROLL); lvc.pszText = TranslateT("Sound for the status"); SNDMSG((hList), LVM_INSERTCOLUMN, 1, (LPARAM)(const LV_COLUMN *)(&lvc)); if ( lpzProto!=NULL) { // -----------------------------------------------------------------add all status sounds for (i = ID_STATUS_MAX; i >= ID_STATUS_MIN; i--) { int Pflags2 = CallProtoService(lpzProto,PS_GETCAPS,PFLAGNUM_2,0); if (Pflags2 == 0) Pflags2 = PF2_ONLINE|PF2_INVISIBLE|PF2_SHORTAWAY|PF2_LONGAWAY|PF2_LIGHTDND|PF2_HEAVYDND|PF2_FREECHAT|PF2_OUTTOLUNCH|PF2_ONTHEPHONE; if ((Proto_Status2Flag(i) != 0 && Pflags2&Proto_Status2Flag(i)) || i == ID_STATUS_OFFLINE) { //Offline has not a PF value, so we workaround it :/ LV_ITEM _ms_lvi; LV_ITEM lvi = { 0 }; DBVARIANT dbv = { 0 }; lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE; lvi.iItem = 0; lvi.iSubItem = 0; lvi.iImage = Index(i); //We've already associated an image list to the listview. lvi.lParam = (LPARAM)i; lvi.pszText = TranslateTS(StatusesList[Index(i)].lpzStandardText); //lvi.iItem = ListView_InsertItem(GetDlgItem(hwndDlg, IDC_INDSNDLIST),&lvi); lvi.iItem = SNDMSG(GetDlgItem(hwndDlg, IDC_INDSNDLIST), LVM_INSERTITEM, 0, (LPARAM)(const LV_ITEM *)(&lvi)); if (DBGetContactSettingTString(hContact, ModuleName, StatusesList[Index(i)].lpzSkinSoundName, &dbv) == DB_READ_SUCCESS) { lvi.pszText = dbv.ptszVal; DBFreeVariant(&dbv); } else lvi.pszText = TranslateT("(default sound)"); _ms_lvi.iSubItem = 1; _ms_lvi.pszText = lvi.pszText; SNDMSG((GetDlgItem(hwndDlg, IDC_INDSNDLIST)), LVM_SETITEMTEXT, (WPARAM)lvi.iItem, (LPARAM)(LV_ITEM *)&_ms_lvi); } } // ---------------- add "user from offline" sound settting { LV_ITEM _ms_lvi; LV_ITEM lvi = { 0 }; DBVARIANT dbv = { 0 }; lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE; lvi.iItem = 0; lvi.iSubItem = 0; lvi.iImage = Index(ID_STATUS_MAX)+1; // additional icon lvi.lParam = (LPARAM)1; lvi.pszText = TranslateT("From offline"); lvi.iItem = SNDMSG(GetDlgItem(hwndDlg, IDC_INDSNDLIST), LVM_INSERTITEM, 0, (LPARAM)(const LV_ITEM *)(&lvi)); if (DBGetContactSettingTString(hContact, ModuleName, "UserFromOffline", &dbv) == DB_READ_SUCCESS) { lvi.pszText = dbv.ptszVal; DBFreeVariant(&dbv); } else lvi.pszText = TranslateT("(default sound)"); //ListView_SetItemText(GetDlgItem(hwndDlg, IDC_INDSNDLIST),lvi.iItem,1,lvi.pszText); _ms_lvi.iSubItem = 1; _ms_lvi.pszText = lvi.pszText; SNDMSG((GetDlgItem(hwndDlg, IDC_INDSNDLIST)), LVM_SETITEMTEXT, (WPARAM)lvi.iItem, (LPARAM)(LV_ITEM *)&_ms_lvi); } //------------------------------------------end "fromoffline"--- } { //checkboxes for contact to disable popups and sounds BYTE EnableSounds = DBGetContactSettingByte(hContact,ModuleName,"EnableSounds",1); BYTE EnablePopups = DBGetContactSettingByte(hContact,ModuleName,"EnablePopups",1); CheckDlgButton(hwndDlg, IDC_CHECK_NOTIFYSOUNDS, EnableSounds?BST_CHECKED:BST_UNCHECKED); CheckDlgButton(hwndDlg, IDC_CHECK_NOTIFYPOPUPS, EnablePopups?BST_CHECKED:BST_UNCHECKED); } if (MyOptions.UseIndSnd) // if individual sounds are used, then activate all controls { ShowWindow(GetDlgItem(hwndDlg, IDC_INDSNDLIST), SW_SHOW); ShowWindow(GetDlgItem(hwndDlg,IDC_TEXT_ENABLE_IS), SW_HIDE); ShowWindow(GetDlgItem(hwndDlg, IDC_CHANGE), SW_SHOW); ShowWindow(GetDlgItem(hwndDlg, IDC_PREVIEW), SW_SHOW); ShowWindow(GetDlgItem(hwndDlg, IDC_DELETE), SW_SHOW); } else { ShowWindow(GetDlgItem(hwndDlg, IDC_INDSNDLIST), SW_HIDE); ShowWindow(GetDlgItem(hwndDlg,IDC_TEXT_ENABLE_IS), SW_SHOW); ShowWindow(GetDlgItem(hwndDlg, IDC_CHANGE), SW_HIDE); ShowWindow(GetDlgItem(hwndDlg, IDC_PREVIEW), SW_HIDE); ShowWindow(GetDlgItem(hwndDlg, IDC_DELETE), SW_HIDE); } TranslateDialogDefault(hwndDlg); return TRUE; //End of WM_INITDIALOG } case WM_COMMAND: { //Who sent us a WM_COMMAND? switch (LOWORD(wParam)) { case IDC_PREVIEW: { //We want to hear the sound. HWND hList = GetDlgItem(hwndDlg, IDC_INDSNDLIST); int nSel = ListView_GetSelectionMark(hList); if ( nSel > -1 ) { //There's something selected. LVITEM lvitem = { 0 }; lvitem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE; lvitem.iItem = ListView_GetNextItem(hList,-1,LVNI_SELECTED); ListView_GetItem(hList, &lvitem); PreviewSound(hList, lvitem.lParam); } break; } //End of IDC_PREVIEW case IDC_CHANGE: if (SelectSound(hwndDlg) == TRUE) SendMessage(GetParent(hwndDlg), PSM_CHANGED,0,0); break; case IDC_DELETE: if (RemoveSoundFromList(GetDlgItem(hwndDlg, IDC_INDSNDLIST))==TRUE) SendMessage(GetParent(hwndDlg), PSM_CHANGED,0,0); break; case IDC_CHECK_NOTIFYSOUNDS: if (IsDlgButtonChecked(hwndDlg, IDC_CHECK_NOTIFYSOUNDS)) DBDeleteContactSetting(hContact,ModuleName,"EnableSounds"); else DBWriteContactSettingByte(hContact,ModuleName,"EnableSounds",0); break; case IDC_CHECK_NOTIFYPOPUPS: if (IsDlgButtonChecked(hwndDlg, IDC_CHECK_NOTIFYPOPUPS)) DBDeleteContactSetting(hContact,ModuleName,"EnablePopups"); else DBWriteContactSettingByte(hContact,ModuleName,"EnablePopups",0); break; default: break; } //End of SWITCH on WM_COMMAND break; //End of WM_COMMAND } case WM_NOTIFY: switch(((LPNMHDR)lParam)->idFrom) { case 0: switch (((LPNMHDR)lParam)->code) { case PSN_APPLY: { //We have to write to the DB: let's find out what. TCHAR str[MAX_PATH] = { 0 }; HWND hList = GetDlgItem(hwndDlg, IDC_INDSNDLIST); LVITEM lvitem = { 0 }; lvitem.mask = LVIF_PARAM; //Cycle through the list reading the text associated to each status. for(lvitem.iItem = ListView_GetItemCount(hList)-1; lvitem.iItem>=0; lvitem.iItem--) { ListView_GetItem(hList,&lvitem); ListView_GetItemText(hList,lvitem.iItem,1,str,sizeof(str)); //If the filename is "(default sound)", delete the setting from the DB, else write the new setting. if (lstrcmp(str, TranslateT("(default sound)"))==0) { if (lvitem.lParam==1) DBDeleteContactSetting((HANDLE)hContact,ModuleName, "UserFromOffline"); else DBDeleteContactSetting((HANDLE)hContact,ModuleName, StatusesList[Index(lvitem.lParam)].lpzSkinSoundName); } else { TCHAR szTranslatedPath[MAX_PATH] = { 0 }; /*#ifdef UNICODE char cPath[MAX_PATH] = {0}; WideCharToMultiByte(CP_ACP,0,str,-1,cPath,MAX_PATH,0,0); CallService(MS_UTILS_PATHTORELATIVE, (WPARAM)cPath, (LPARAM)szTranslatedPath); #else CallService(MS_UTILS_PATHTORELATIVE, (WPARAM)str, (LPARAM)szTranslatedPath); #endif */ CallService(MS_UTILS_PATHTORELATIVET, (WPARAM)str, (LPARAM)szTranslatedPath); if (lvitem.lParam==1) DBWriteContactSettingTString((HANDLE)hContact,ModuleName, "UserFromOffline",szTranslatedPath); else DBWriteContactSettingTString((HANDLE)hContact,ModuleName, StatusesList[Index(lvitem.lParam)].lpzSkinSoundName, szTranslatedPath); } } //End of for, we have written every setting. return TRUE; } } } //Various actions. { LPNMHDR pParam = (LPNMHDR)lParam; if (pParam == NULL) return TRUE; switch ((int)wParam) { case IDC_INDSNDLIST: { switch (pParam->code) { case NM_DBLCLK: { if (SelectSound(hwndDlg) == TRUE) SendMessage(GetParent(hwndDlg), PSM_CHANGED,0,0); return TRUE; } case LVN_KEYDOWN: { LPNMLVKEYDOWN pnkd = (LPNMLVKEYDOWN)lParam; if (pnkd->wVKey == VK_DELETE) RemoveSoundFromList(GetDlgItem(hwndDlg, IDC_INDSNDLIST)); break; } //End of KEYDOWN } } //End of IDC_INDSNDLIST } //end int wParam break ; } //End of WM_NOTIFY default: break; } return FALSE; } //========== UserInfo page : Initialization ========== int UserInfoInitialise(WPARAM wParam, LPARAM lParam) { { //Individual Sounds UserInfo details page OPTIONSDIALOGPAGE odp = { 0 }; if((HANDLE)lParam == NULL) return 0; odp.cbSize = sizeof(odp); odp.position = 100000000; odp.hInstance = hInst; odp.pszTemplate = MAKEINTRESOURCEA(IDD_INFO_SOUNDS); odp.pszTitle = _strdup(NAME_OF_UIPAGE); odp.pfnDlgProc = DlgProcSoundUIPage; CallService(MS_USERINFO_ADDPAGE,wParam,(LPARAM)&odp); } return 0; } static void ResetListOptions(HWND hwndList) { int i; SendMessage(hwndList,CLM_SETBKBITMAP,0,(LPARAM)(HBITMAP)NULL); SendMessage(hwndList,CLM_SETBKCOLOR,GetSysColor(COLOR_WINDOW),0); SendMessage(hwndList,CLM_SETGREYOUTFLAGS,0,0); SendMessage(hwndList,CLM_SETLEFTMARGIN,4,0); SendMessage(hwndList,CLM_SETINDENT,10,0); for(i=0;i<=FONTID_MAX;i++) SendMessage(hwndList,CLM_SETTEXTCOLOR,i,GetSysColor(COLOR_WINDOWTEXT)); SetWindowLong(hwndList,GWL_STYLE,GetWindowLong(hwndList,GWL_STYLE)|CLS_SHOWHIDDEN); } static void SetAllContactIcons(HWND hwndList) { HANDLE hContact,hItem; char *szProto; DWORD flags; BYTE EnableSounds, EnablePopups; hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0); do { hItem=(HANDLE)SendMessage(hwndList,CLM_FINDCONTACT,(WPARAM)hContact,0); if(hItem) { szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)hContact,0); if (szProto == NULL) { flags = 0; EnableSounds =EnablePopups = 0;} else { flags = CallProtoService(szProto,PS_GETCAPS,PFLAGNUM_1,0); //Status flags EnableSounds = DBGetContactSettingByte(hContact,ModuleName,"EnableSounds",1); EnablePopups = DBGetContactSettingByte(hContact,ModuleName,"EnablePopups",1); } //if(PF1_INDIVSTATUS) { if(SendMessage(hwndList,CLM_GETEXTRAIMAGE,(WPARAM)hItem,MAKELPARAM(0,0))==0xFF) SendMessage(hwndList,CLM_SETEXTRAIMAGE,(WPARAM)hItem,MAKELPARAM(0,EnableSounds==TRUE?1:0)); if(SendMessage(hwndList,CLM_GETEXTRAIMAGE,(WPARAM)hItem,MAKELPARAM(1,0))==0xFF) SendMessage(hwndList,CLM_SETEXTRAIMAGE,(WPARAM)hItem,MAKELPARAM(1,EnablePopups==TRUE?2:0)); } } } while(hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0)); } static void SetListGroupIcons(HWND hwndList,HANDLE hFirstItem,HANDLE hParentItem,int *groupChildCount) { int typeOfFirst; int iconOn[2]={1,1}; int childCount[2]={0,0},i; int iImage; HANDLE hItem,hChildItem; typeOfFirst=SendMessage(hwndList,CLM_GETITEMTYPE,(WPARAM)hFirstItem,0); //check groups if(typeOfFirst==CLCIT_GROUP) hItem=hFirstItem; else hItem=(HANDLE)SendMessage(hwndList,CLM_GETNEXTITEM,CLGN_NEXTGROUP,(LPARAM)hFirstItem); while(hItem) { hChildItem=(HANDLE)SendMessage(hwndList,CLM_GETNEXTITEM,CLGN_CHILD,(LPARAM)hItem); if(hChildItem) SetListGroupIcons(hwndList,hChildItem,hItem,childCount); for( i=0; i < SIZEOF(iconOn); i++) if(iconOn[i] && SendMessage(hwndList,CLM_GETEXTRAIMAGE,(WPARAM)hItem,i)==0) iconOn[i]=0; hItem=(HANDLE)SendMessage(hwndList,CLM_GETNEXTITEM,CLGN_NEXTGROUP,(LPARAM)hItem); } //check contacts if(typeOfFirst==CLCIT_CONTACT) hItem=hFirstItem; else hItem=(HANDLE)SendMessage(hwndList,CLM_GETNEXTITEM,CLGN_NEXTCONTACT,(LPARAM)hFirstItem); while(hItem) { for ( i=0; i < SIZEOF(iconOn); i++) { iImage=SendMessage(hwndList,CLM_GETEXTRAIMAGE,(WPARAM)hItem,i); if(iconOn[i] && iImage==0) iconOn[i]=0; if(iImage!=0xFF) childCount[i]++; } hItem=(HANDLE)SendMessage(hwndList,CLM_GETNEXTITEM,CLGN_NEXTCONTACT,(LPARAM)hItem); } //set icons for( i=0; i < SIZEOF(iconOn); i++) { SendMessage(hwndList,CLM_SETEXTRAIMAGE,(WPARAM)hParentItem,MAKELPARAM(i,childCount[i]?(iconOn[i]?i+1:0):0xFF)); if(groupChildCount) groupChildCount[i]+=childCount[i]; } } static void SetAllChildIcons(HWND hwndList,HANDLE hFirstItem,int iColumn,int iImage) { int typeOfFirst,iOldIcon; HANDLE hItem,hChildItem; typeOfFirst=SendMessage(hwndList,CLM_GETITEMTYPE,(WPARAM)hFirstItem,0); //check groups if(typeOfFirst==CLCIT_GROUP) hItem=hFirstItem; else hItem=(HANDLE)SendMessage(hwndList,CLM_GETNEXTITEM,CLGN_NEXTGROUP,(LPARAM)hFirstItem); while(hItem) { hChildItem=(HANDLE)SendMessage(hwndList,CLM_GETNEXTITEM,CLGN_CHILD,(LPARAM)hItem); if(hChildItem) SetAllChildIcons(hwndList,hChildItem,iColumn,iImage); hItem=(HANDLE)SendMessage(hwndList,CLM_GETNEXTITEM,CLGN_NEXTGROUP,(LPARAM)hItem); } //check contacts if(typeOfFirst==CLCIT_CONTACT) hItem=hFirstItem; else hItem=(HANDLE)SendMessage(hwndList,CLM_GETNEXTITEM,CLGN_NEXTCONTACT,(LPARAM)hFirstItem); while(hItem) { iOldIcon=SendMessage(hwndList,CLM_GETEXTRAIMAGE,(WPARAM)hItem,iColumn); if(iOldIcon!=0xFF && iOldIcon!=iImage) SendMessage(hwndList,CLM_SETEXTRAIMAGE,(WPARAM)hItem,MAKELPARAM(iColumn,iImage)); hItem=(HANDLE)SendMessage(hwndList,CLM_GETNEXTITEM,CLGN_NEXTCONTACT,(LPARAM)hItem); } } BOOL CALLBACK DlgProcSoundOpts2(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { static HICON hSoundIcon,hPopupIcon; static HANDLE hItemAll; HANDLE hList = GetDlgItem(hWnd, IDC_INDSNDLIST); hCListClone=(HWND)hList; //{char str[100];wsprintf (str, L"msg value is %#x", msg);MessageBox(NULL,str,L"soundopts2",0);} //printf("msg = %#x", msg); switch (msg) { case WM_INITDIALOG: { TranslateDialogDefault(hWnd); { HIMAGELIST hImageList; hImageList=ImageList_Create(GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),(IsWinVerXPPlus()?ILC_COLOR32:ILC_COLOR16)|ILC_MASK,3,3); ImageList_AddIcon(hImageList,(LoadSkinnedIcon(SKINICON_OTHER_SMALLDOT))); ImageList_AddIcon(hImageList,LoadIcon(hInst,MAKEINTRESOURCE(IDI_SOUND))); ImageList_AddIcon(hImageList,LoadIcon(hInst,MAKEINTRESOURCE(IDI_POPUP))); SendDlgItemMessage(hWnd,IDC_INDSNDLIST,CLM_SETEXTRAIMAGELIST,0,(LPARAM)hImageList); hSoundIcon=ImageList_GetIcon(hImageList,1,ILD_NORMAL); SendDlgItemMessage(hWnd,IDC_SOUNDICON,STM_SETICON,(WPARAM)hSoundIcon,0); hPopupIcon=ImageList_GetIcon(hImageList,2,ILD_NORMAL); SendDlgItemMessage(hWnd,IDC_POPUPICON,STM_SETICON,(WPARAM)hPopupIcon,0); } ResetListOptions((HWND)hList); SendDlgItemMessage(hWnd,IDC_INDSNDLIST,CLM_SETEXTRACOLUMNS,2,0); { CLCINFOITEM cii={0}; cii.cbSize=sizeof(cii); cii.flags=CLCIIF_GROUPFONT; cii.pszText=TranslateT("** All contacts **"); hItemAll=(HANDLE)SendDlgItemMessage(hWnd,IDC_INDSNDLIST,CLM_ADDINFOITEM,0,(LPARAM)&cii); } SetAllContactIcons((HWND)hList); SetListGroupIcons((HWND)hList,(HANDLE)SendDlgItemMessage(hWnd,IDC_INDSNDLIST,CLM_GETNEXTITEM,CLGN_ROOT,0),hItemAll,NULL); return TRUE; } case WM_SETFOCUS: SetFocus((HWND)hList); break; case WM_NOTIFY: /* {wchar_t str[100]; wsprintf(str, L"wm notify value %#x", ((LPNMHDR)lParam)->idFrom); MessageBox(NULL,str,L"NSN 123456789",0); } */ switch(((LPNMHDR)lParam)->idFrom) { case IDC_INDSNDLIST: switch (((LPNMHDR)lParam)->code) { case CLN_NEWCONTACT: case CLN_LISTREBUILT: SetAllContactIcons((HWND)hList); //fall through case CLN_CONTACTMOVED: SetListGroupIcons((HWND)hList,(HANDLE)SendMessage((HWND)hList,CLM_GETNEXTITEM,CLGN_ROOT,0),hItemAll,NULL); break; case CLN_OPTIONSCHANGED: ResetListOptions((HWND)hList); break; case NM_CLICK: { HANDLE hItem; NMCLISTCONTROL *nm=(NMCLISTCONTROL*)lParam; DWORD hitFlags; int iImage; int itemType; // Make sure we have an extra column if(nm->iColumn==-1) break; // Find clicked item hItem=(HANDLE)SendMessage((HWND)hList,CLM_HITTEST,(WPARAM)&hitFlags,MAKELPARAM(nm->pt.x,nm->pt.y)); // Nothing was clicked if(hItem==NULL) break; // It was not a sound or popup icon if(!(hitFlags&CLCHT_ONITEMEXTRA)) break; itemType=SendMessage((HWND)hList,CLM_GETITEMTYPE,(WPARAM)hItem,0); // Get image in clicked column (0=none, 1=sound, 2=popup) iImage=SendMessage((HWND)hList,CLM_GETEXTRAIMAGE,(WPARAM)hItem,MAKELPARAM(nm->iColumn,0)); if(iImage==0) iImage=nm->iColumn+1; else if(iImage==1 || iImage==2) iImage=0; // Get item type (contact, group, etc...) // Update list if(itemType==CLCIT_CONTACT) { SendMessage((HWND)hList,CLM_SETEXTRAIMAGE,(WPARAM)hItem,MAKELPARAM(nm->iColumn,iImage)); } else if(itemType==CLCIT_INFO) //must be 'all contacts' { SetAllChildIcons((HWND)hList,hItem,nm->iColumn,iImage); } else if(itemType==CLCIT_GROUP) { hItem=(HANDLE)SendMessage((HWND)hList,CLM_GETNEXTITEM,CLGN_CHILD,(LPARAM)hItem); if(hItem) { SetAllChildIcons((HWND)hList,hItem,nm->iColumn,iImage); } } // Update the all/none icons SetListGroupIcons((HWND)hList,(HANDLE)SendMessage((HWND)hList,CLM_GETNEXTITEM,CLGN_ROOT,0),hItemAll,NULL); // Activate Apply button SendMessage(GetParent(hWnd), PSM_CHANGED, 0, 0); break; } } break; case 0: switch (((LPNMHDR)lParam)->code) { case PSN_APPLY: { HANDLE hContact,hItem; int iImage; hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0); do { hItem=(HANDLE)SendMessage((HWND)hList,CLM_FINDCONTACT,(WPARAM)hContact,0); if(hItem) { iImage=SendMessage((HWND)hList,CLM_GETEXTRAIMAGE,(WPARAM)hItem,MAKELPARAM(0,0)); if(iImage==1) DBDeleteContactSetting(hContact,ModuleName,"EnableSounds"); else DBWriteContactSettingByte(hContact,ModuleName,"EnableSounds",0); iImage=SendMessage((HWND)hList,CLM_GETEXTRAIMAGE,(WPARAM)hItem,MAKELPARAM(1,0)); if(iImage==2) DBDeleteContactSetting(hContact,ModuleName,"EnablePopups"); else DBWriteContactSettingByte(hContact,ModuleName,"EnablePopups",0); } } while(hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0)); return TRUE; } } break; } break; case WM_DESTROY: { HIMAGELIST hIml = (HIMAGELIST)SendMessage((HWND)hList,CLM_GETEXTRAIMAGELIST,0,0); DestroyIcon(hSoundIcon); DestroyIcon(hPopupIcon); ImageList_Destroy(hIml); break; } default: break; } return FALSE; }