/* Sessions Management plugin for Miranda IM Copyright (C) 2007-2008 Danil Mozhar This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "stdafx.h" HICON hIcon; HICON hMarked, hNotMarked; HWND hComboBox = nullptr; HWND hComboBoxEdit = nullptr; HWND hOpClistControl = nullptr; CSession *pSession = nullptr; BOOL bSesssionNameChanged = 0; BOOL bChecked = FALSE; static LRESULT CALLBACK ComboBoxSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_ERASEBKGND: return TRUE; case EM_SETSEL: if (!hOpClistControl) return HideCaret(hwnd); break; case WM_GETDLGCODE: if (!hOpClistControl) return DLGC_WANTARROWS; break; case WM_SETCURSOR: if (!hOpClistControl) { SetCursor(LoadCursor(nullptr, IDC_ARROW)); return TRUE; } break; case WM_LBUTTONDOWN: if (hOpClistControl) break; HideCaret(hwnd); case WM_LBUTTONDBLCLK: case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK: SendMessage(hComboBox, CB_SHOWDROPDOWN, 1, 0); return TRUE; case WM_NCLBUTTONDBLCLK: case WM_NCLBUTTONDOWN: if (!bChecked) { pSession->bIsFavorite = true; hIcon = hMarked; bChecked = TRUE; RedrawWindow(hwnd, nullptr, nullptr, RDW_INVALIDATE | RDW_UPDATENOW | RDW_FRAME); } else { pSession->bIsFavorite = false; hIcon = hNotMarked; bChecked = FALSE; RedrawWindow(hwnd, nullptr, nullptr, RDW_INVALIDATE | RDW_UPDATENOW | RDW_FRAME); } pSession->save(); break; case WM_MOUSEMOVE: if (hOpClistControl) break; case WM_NCMOUSEMOVE: return TRUE; case WM_NCPAINT: RECT rc; GetClientRect(hwnd, &rc); rc.left = rc.right; rc.right = rc.left + 16; { HDC hdc = GetDC(hwnd); FillRect(hdc, &rc, (HBRUSH)GetSysColor(COLOR_WINDOW)); DrawIconEx(hdc, rc.left, 0, hIcon, 16, 16, 0, nullptr, DI_NORMAL); ReleaseDC(hwnd, hdc); } break; case WM_NCCALCSIZE: { NCCALCSIZE_PARAMS *ncsParam = (NCCALCSIZE_PARAMS*)lParam; ncsParam->rgrc[0].right -= 16; } break; case WM_NCHITTEST: LRESULT lr = mir_callNextSubclass(hwnd, ComboBoxSubclassProc, msg, wParam, lParam); if (lr == HTNOWHERE) lr = HTOBJECT; return lr; } return mir_callNextSubclass(hwnd, ComboBoxSubclassProc, msg, wParam, lParam); } class COptionsDlg : public CDlgBase { // returns number of contacts in a session int LoadSessionContacts() { memset(session_list_t, 0, sizeof(session_list_t)); int i = 0; for (auto &cc : pSession->contacts) m_opclist.AddString(Clist_GetContactDisplayName(session_list_t[i++] = cc)); return i; } CCtrlClc m_clist; CCtrlCombo m_list; CCtrlListBox m_opclist; CCtrlCheck chkStartDialog, chkLoadLast, chkLast, chkNothing; CCtrlCheck chkExitAsk, chkExitSave, chkExitNothing; CCtrlButton btnSave, btnEdit, btnDel; MCONTACT session_list_t[255]; public: COptionsDlg() : CDlgBase(g_plugin, IDD_OPTIONS), m_list(this, IDC_LIST), m_clist(this, IDC_EMCLIST), m_opclist(this, IDC_OPCLIST), btnDel(this, IDC_DEL), btnEdit(this, IDC_EDIT), btnSave(this, IDC_SAVE), chkLast(this, IDC_CHECKLAST), chkExitAsk(this, IDC_REXASK), chkNothing(this, IDC_RNOTHING), chkExitSave(this, IDC_REXSAVE), chkLoadLast(this, IDC_RLOADLAST), chkExitNothing(this, IDC_REXDSAVE), chkStartDialog(this, IDC_STARTDIALOG) { btnDel.OnClick = Callback(this, &COptionsDlg::onClick_Del); btnEdit.OnClick = Callback(this, &COptionsDlg::onClick_Edit); btnSave.OnClick = Callback(this, &COptionsDlg::onClick_Save); chkNothing.OnChange = Callback(this, &COptionsDlg::onChange_Nothing); chkLoadLast.OnChange = Callback(this, &COptionsDlg::onChange_LoadLast); chkStartDialog.OnChange = Callback(this, &COptionsDlg::onChange_StartDialog); chkExitAsk.OnChange = Callback(this, &COptionsDlg::onChange_ExAsk); chkExitSave.OnChange = Callback(this, &COptionsDlg::onChange_ExSave); chkExitNothing.OnChange = Callback(this, &COptionsDlg::onChange_ExNothing); m_list.OnChange = Callback(this, &COptionsDlg::onEditChange_List); m_list.OnSelChanged = Callback(this, &COptionsDlg::onSelChange_List); m_clist.OnCheckChanged = Callback(this, &COptionsDlg::onCheckChanged_Clist); memset(session_list_t, 0, sizeof(session_list_t)); } bool OnInitDialog() override { COMBOBOXINFO cbi = { 0 }; cbi.cbSize = sizeof(cbi); pSession = nullptr; hMarked = g_plugin.getIcon(IDD_SESSION_CHECKED); hNotMarked = g_plugin.getIcon(IDD_SESSION_UNCHECKED); SetWindowLongPtr(m_clist.GetHwnd(), GWL_STYLE, GetWindowLongPtr(m_clist.GetHwnd(), GWL_STYLE) | CLS_CHECKBOXES | CLS_HIDEEMPTYGROUPS | CLS_USEGROUPS | CLS_GREYALTERNATE | CLS_GROUPCHECKBOXES); m_clist.SetExStyle(CLS_EX_DISABLEDRAGDROP | CLS_EX_TRACKSELECT); m_clist.AutoRebuild(); SetDlgItemInt(m_hwnd, IDC_TRACK, g_ses_limit = g_plugin.getByte("TrackCount", 10), FALSE); SendDlgItemMessage(m_hwnd, IDC_SPIN1, UDM_SETRANGE, 0, MAKELONG(10, 1)); SendDlgItemMessage(m_hwnd, IDC_SPIN1, UDM_SETPOS, 0, GetDlgItemInt(m_hwnd, IDC_TRACK, nullptr, FALSE)); m_opclist.ResetContent(); SetDlgItemInt(m_hwnd, IDC_STARTDELAY, g_plugin.getWord("StartupModeDelay", 1500), FALSE); int startupmode = g_plugin.getByte("StartupMode", 3); int exitmode = g_plugin.getByte("ShutdownMode", 2); g_bExclHidden = g_plugin.getByte("ExclHidden", 0) != 0; g_bWarnOnHidden = g_plugin.getByte("WarnOnHidden", 0) != 0; g_bOtherWarnings = g_plugin.getByte("OtherWarnings", 1) != 0; g_bCrashRecovery = g_plugin.getByte("CrashRecovery", 0) != 0; CheckDlgButton(m_hwnd, IDC_EXCLHIDDEN, g_bExclHidden ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(m_hwnd, IDC_LASTHIDDENWARN, g_bWarnOnHidden ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(m_hwnd, IDC_WARNINGS, g_bOtherWarnings ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(m_hwnd, IDC_CRASHRECOVERY, g_bCrashRecovery ? BST_CHECKED : BST_UNCHECKED); if (startupmode == 1) chkStartDialog.SetState(true); else if (startupmode == 3) { chkStartDialog.SetState(true); chkLast.SetState(true); } else if (startupmode == 2) chkLoadLast.SetState(true); else if (startupmode == 0) chkNothing.SetState(true); if (exitmode == 0) chkExitNothing.SetState(true); else if (exitmode == 1) chkExitAsk.SetState(true); else if (exitmode == 2) chkExitSave.SetState(true); LoadSessionToCombobox(m_list, true); if (m_list.GetCount()) { btnEdit.Enable(); m_list.SetCurSel(0); pSession = (CSession *)m_list.GetItemData(0); if (!LoadSessionContacts()) btnDel.Disable(); } GetComboBoxInfo(m_list.GetHwnd(), &cbi); mir_subclassWindow(cbi.hwndItem, ComboBoxSubclassProc); hComboBoxEdit = cbi.hwndItem; hComboBox = cbi.hwndCombo; SetWindowPos(hComboBoxEdit, nullptr, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); return true; } bool OnApply() override { int iDelay = GetDlgItemInt(m_hwnd, IDC_STARTDELAY, nullptr, FALSE); g_plugin.setWord("StartupModeDelay", (WORD)iDelay); g_plugin.setByte("TrackCount", (BYTE)(g_ses_limit = GetDlgItemInt(m_hwnd, IDC_TRACK, nullptr, FALSE))); if (chkExitSave.IsChecked()) g_plugin.setByte("ShutdownMode", 2); else if (IsDlgButtonChecked(m_hwnd, IDC_REXDSAVE)) g_plugin.setByte("ShutdownMode", 0); else if (chkExitAsk.IsChecked()) g_plugin.setByte("ShutdownMode", 1); if (chkStartDialog.IsChecked()) { if (chkLast.IsChecked()) g_plugin.setByte("StartupMode", 1); else g_plugin.setByte("StartupMode", 3); } else if (chkLoadLast.IsChecked()) g_plugin.setByte("StartupMode", 2); else if (chkNothing.IsChecked()) g_plugin.setByte("StartupMode", 0); g_plugin.setByte("ExclHidden", (BYTE)(IsDlgButtonChecked(m_hwnd, IDC_EXCLHIDDEN) ? (g_bExclHidden = 1) : (g_bExclHidden = 0))); g_plugin.setByte("WarnOnHidden", (BYTE)(IsDlgButtonChecked(m_hwnd, IDC_LASTHIDDENWARN) ? (g_bWarnOnHidden = 1) : (g_bWarnOnHidden = 0))); g_plugin.setByte("OtherWarnings", (BYTE)(IsDlgButtonChecked(m_hwnd, IDC_WARNINGS) ? (g_bOtherWarnings = 1) : (g_bOtherWarnings = 0))); g_plugin.setByte("CrashRecovery", (BYTE)(IsDlgButtonChecked(m_hwnd, IDC_CRASHRECOVERY) ? (g_bCrashRecovery = 1) : (g_bCrashRecovery = 0))); return true; } INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) override { switch (msg) { case WM_CTLCOLORLISTBOX: switch (GetDlgCtrlID((HWND)lParam)) { case IDC_OPCLIST: SetBkMode((HDC)wParam, TRANSPARENT); return (INT_PTR)CreateSolidBrush(GetSysColor(COLOR_3DFACE)); } break; case WM_NOTIFY: if (LOWORD(wParam) == IDC_LIST && !hOpClistControl) { if (HIWORD(wParam) == CBN_DROPDOWN) { SendMessage(hComboBoxEdit, EM_SETSEL, 0, 0); SendMessage(hComboBoxEdit, EM_SCROLLCARET, 0, 0); SendMessage(hComboBoxEdit, WM_KILLFOCUS, 0, 0); } else SendMessage(hComboBoxEdit, EM_SCROLLCARET, 0, 0); HideCaret(hComboBoxEdit); } } return CDlgBase::DlgProc(msg, wParam, lParam); } void onCheckChanged_Clist(CCtrlClc::TEventInfo*) { btnSave.Enable(); } void onEditChange_List(CCtrlCombo *) { btnSave.Enable(); bSesssionNameChanged = TRUE; } void onSelChange_List(CCtrlCombo *) { int index = m_list.GetCurSel(); if (index == CB_ERR) return; pSession = (CSession*)m_list.GetItemData(index); m_opclist.ResetContent(); if (pSession->bIsFavorite) { hIcon = hMarked; bChecked = TRUE; RedrawWindow(hComboBoxEdit, nullptr, nullptr, RDW_INVALIDATE | RDW_NOCHILDREN | RDW_UPDATENOW | RDW_FRAME); } else { hIcon = hNotMarked; bChecked = FALSE; RedrawWindow(hComboBoxEdit, nullptr, nullptr, RDW_INVALIDATE | RDW_NOCHILDREN | RDW_UPDATENOW | RDW_FRAME); } LoadSessionContacts(); if (!hOpClistControl) btnDel.Enable(); else { for (auto &hContact : Contacts()) SendMessage(hOpClistControl, CLM_SETCHECKMARK, hContact, 0); for (int i = 0; session_list_t[i] > 0; i++) { MCONTACT hContact = (MCONTACT)SendMessage(hOpClistControl, CLM_FINDCONTACT, (WPARAM)session_list_t[i], 0); SendMessage(hOpClistControl, CLM_SETCHECKMARK, hContact, 1); } btnSave.Disable(); } } void onClick_Edit(CCtrlButton *) { if (!hOpClistControl) { m_opclist.Hide(); m_clist.Show(); btnDel.Disable(); btnEdit.SetText(TranslateT("View")); hOpClistControl = m_clist.GetHwnd(); for (int i = 0; session_list_t[i] > 0; i++) m_clist.SetCheck(m_clist.FindContact(session_list_t[i]), true); } else { m_clist.Hide(); m_opclist.Show(); btnDel.Enable(); btnSave.Disable(); btnEdit.SetText(TranslateT("Edit")); hOpClistControl = nullptr; } } void onClick_Save(CCtrlButton *) { for (auto &hContact : Contacts()) { BYTE res = m_clist.GetCheck(m_clist.FindContact(hContact)); if (res) { // !!!!!!!!!!!!!!!!!!! } } if (bSesssionNameChanged) { if (GetWindowTextLength(hComboBoxEdit)) { wchar_t szUserSessionName[MAX_PATH] = { '\0' }; GetWindowText(hComboBoxEdit, szUserSessionName, _countof(szUserSessionName)); pSession->wszName = szUserSessionName; pSession->save(); m_list.ResetContent(); LoadSessionToCombobox(m_list, true); } bSesssionNameChanged = FALSE; } btnSave.Disable(); } void onClick_Del(CCtrlButton *) { pSession->remove(); m_opclist.ResetContent(); m_list.ResetContent(); LoadSessionToCombobox(m_list, true); if (m_list.GetCount()) { btnEdit.Enable(); m_list.SetCurSel(0); if (!LoadSessionContacts()) btnDel.Disable(); } else { pSession = nullptr; btnEdit.Disable(); btnDel.Disable(); } } void onChange_StartDialog(CCtrlCheck *pCheck) { if (!pCheck->IsChecked()) return; EnableWindow(GetDlgItem(m_hwnd, IDC_STARTDELAY), TRUE); EnableWindow(GetDlgItem(m_hwnd, IDC_STATICOP), TRUE); EnableWindow(GetDlgItem(m_hwnd, IDC_STATICMS), TRUE); chkLast.Enable(); } void onChange_LoadLast(CCtrlCheck *pCheck) { if (!pCheck->IsChecked()) return; EnableWindow(GetDlgItem(m_hwnd, IDC_STARTDELAY), TRUE); EnableWindow(GetDlgItem(m_hwnd, IDC_STATICOP), TRUE); EnableWindow(GetDlgItem(m_hwnd, IDC_STATICMS), TRUE); chkLast.Disable(); } void onChange_Nothing(CCtrlCheck *pCheck) { if (!pCheck->IsChecked()) return; EnableWindow(GetDlgItem(m_hwnd, IDC_STARTDELAY), FALSE); EnableWindow(GetDlgItem(m_hwnd, IDC_STATICOP), FALSE); EnableWindow(GetDlgItem(m_hwnd, IDC_STATICMS), FALSE); chkLast.Disable(); } void onChange_ExSave(CCtrlCheck *pCheck) { if (!pCheck->IsChecked()) return; EnableWindow(GetDlgItem(m_hwnd, IDC_EXSTATIC1), TRUE); EnableWindow(GetDlgItem(m_hwnd, IDC_EXSTATIC2), TRUE); EnableWindow(GetDlgItem(m_hwnd, IDC_TRACK), TRUE); EnableWindow(GetDlgItem(m_hwnd, IDC_SPIN1), TRUE); } void onChange_ExNothing(CCtrlCheck *pCheck) { if (!pCheck->IsChecked()) return; EnableWindow(GetDlgItem(m_hwnd, IDC_EXSTATIC1), FALSE); EnableWindow(GetDlgItem(m_hwnd, IDC_EXSTATIC2), FALSE); EnableWindow(GetDlgItem(m_hwnd, IDC_TRACK), FALSE); EnableWindow(GetDlgItem(m_hwnd, IDC_SPIN1), FALSE); } void onChange_ExAsk(CCtrlCheck *pCheck) { if (!pCheck->IsChecked()) return; EnableWindow(GetDlgItem(m_hwnd, IDC_EXSTATIC1), TRUE); EnableWindow(GetDlgItem(m_hwnd, IDC_EXSTATIC2), TRUE); EnableWindow(GetDlgItem(m_hwnd, IDC_TRACK), TRUE); EnableWindow(GetDlgItem(m_hwnd, IDC_SPIN1), TRUE); } }; int OptionsInit(WPARAM wparam, LPARAM) { OPTIONSDIALOGPAGE odp = {}; odp.szGroup.a = LPGEN("Message sessions"); odp.szTitle.a = MODULENAME; odp.flags = ODPF_BOLDGROUPS; odp.position = 955000000; odp.pDialog = new COptionsDlg(); g_plugin.addOptions(wparam, &odp); return 0; }