//------------------------------------------------------------------------------------------- void __cdecl MyCallbackProc(long Mode, long IntVal, double DblVal) { switch (Mode) { case cmiWavelength1: // new wavelength has been calculated dblLambda = DblVal; DlgProc(0, From_CALLBACK, 0, 0); break; case cmiVersion: // WLM has started and publishes version information iVersion = IntVal; DlgProc(0, From_CALLBACK, 0, 0); break; case cmiDLLDetach: // WLM has exited RemoveCallback(); break; } }
static LONG_PTR WINAPI DlgProc(HANDLE hDlg,int Msg,int Param1,LONG_PTR Param2) { static TCHAR Filter[MAX_PATH]; static TCHAR spFilter[MAX_PATH]; static FarListTitles ListTitle; switch(Msg) { case DN_RESIZECONSOLE: { Info.SendDlgMessage(hDlg,DM_ENABLEREDRAW,FALSE,0); ResizeDialog(hDlg); Info.SendDlgMessage(hDlg,DM_ENABLEREDRAW,TRUE,0); } return TRUE; case DMU_UPDATE: { int OldPos = static_cast<int>(Info.SendDlgMessage(hDlg,DM_LISTGETCURPOS,LIST_BOX,0)); if (Param1) UpDateInfo(); ListSize = 0; int NewPos = -1; if (OldPos >= 0 && OldPos < nCount) { if (!*Filter || strstri(p[OldPos].Keys[DisplayName],Filter)) //без учета регистра в OEM кодировке NewPos = OldPos; } for (int i = 0; i < nCount; i++) { const TCHAR* DispName = p[i].Keys[DisplayName], *Find; if (*Filter) Find = strstri(DispName,Filter); else Find = DispName; if (Find != nullptr) //без учета регистра в OEM кодировке { FLI[i].Flags &= ~LIF_HIDDEN; if (Param2 && (i == OldPos)) { if (FLI[i].Flags & LIF_CHECKED) { FLI[i].Flags &= ~LIF_CHECKED; } else { FLI[i].Flags |= LIF_CHECKED; } } //без учета регистра - а кодировка ANSI if (NewPos == -1 && Find == DispName) NewPos = i; ListSize++; } else FLI[i].Flags |= LIF_HIDDEN; } if (Param1 == 0 && Param2) { // Снятие или установка пометки (Ins) if (Param2 == 1) { for (int i = (OldPos+1); i < nCount; i++) { if (!(FLI[i].Flags & LIF_HIDDEN)) { OldPos = i; break; } } NewPos = OldPos; } // Снятие или установка пометки (RClick) else if (Param2 == 2) { NewPos = OldPos; } } else if (NewPos == -1) { NewPos = OldPos; } Info.SendDlgMessage(hDlg,DM_ENABLEREDRAW,FALSE,0); Info.SendDlgMessage(hDlg,DM_LISTSET,LIST_BOX,reinterpret_cast<LONG_PTR>(&FL)); StringCchPrintf(spFilter,ARRAYSIZE(spFilter), GetMsg(MFilter),Filter,ListSize,nCount); ListTitle.Title = spFilter; ListTitle.TitleLen = lstrlen(spFilter); Info.SendDlgMessage(hDlg,DM_LISTSETTITLES,LIST_BOX,reinterpret_cast<LONG_PTR>(&ListTitle)); ResizeDialog(hDlg); struct FarListPos FLP; FLP.SelectPos = NewPos; FLP.TopPos = -1; Info.SendDlgMessage(hDlg,DM_LISTSETCURPOS,LIST_BOX,reinterpret_cast<LONG_PTR>(&FLP)); Info.SendDlgMessage(hDlg,DM_ENABLEREDRAW,TRUE,0); } break; case DN_INITDIALOG: { StringCchCopy(Filter,ARRAYSIZE(Filter),_T("")); ListTitle.Bottom = const_cast<TCHAR*>(GetMsg(MBottomLine)); ListTitle.BottomLen = lstrlen(GetMsg(MBottomLine)); //подстраиваемся под размеры консоли Info.SendDlgMessage(hDlg,DM_ENABLEREDRAW,FALSE,0); ResizeDialog(hDlg); Info.SendDlgMessage(hDlg,DM_ENABLEREDRAW,TRUE,0); //заполняем диалог Info.SendDlgMessage(hDlg,DMU_UPDATE,1,0); } break; case DN_MOUSECLICK: { if (Param1 == LIST_BOX) { MOUSE_EVENT_RECORD *mer = (MOUSE_EVENT_RECORD *)Param2; if (mer->dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED) { // find list on-screen coords (excluding frame and border) SMALL_RECT list_rect; Info.SendDlgMessage(hDlg, DM_GETDLGRECT, 0, reinterpret_cast<LONG_PTR>(&list_rect)); list_rect.Left += 2; list_rect.Top += 1; list_rect.Right -= 2; list_rect.Bottom -= 1; if ((mer->dwEventFlags == 0) && (mer->dwMousePosition.X > list_rect.Left) && (mer->dwMousePosition.X < list_rect.Right) && (mer->dwMousePosition.Y > list_rect.Top) && (mer->dwMousePosition.Y < list_rect.Bottom)) { DlgProc(hDlg, DN_KEY, LIST_BOX, KEY_ENTER); return TRUE; } // pass message to scrollbar if needed if ((mer->dwMousePosition.X == list_rect.Right) && (mer->dwMousePosition.Y > list_rect.Top) && (mer->dwMousePosition.Y < list_rect.Bottom)) return FALSE; return TRUE; } else if (mer->dwButtonState == RIGHTMOST_BUTTON_PRESSED) { Info.SendDlgMessage(hDlg,DMU_UPDATE,0,2); return TRUE; } } } break; case DN_KEY: switch (Param2) { case KEY_F8: { if (ListSize) { TCHAR DlgText[MAX_PATH + 200]; StringCchPrintf(DlgText, ARRAYSIZE(DlgText), GetMsg(MConfirm), p[Info.SendDlgMessage(hDlg,DM_LISTGETCURPOS,LIST_BOX,NULL)].Keys[DisplayName]); if (EMessage((const TCHAR * const *) DlgText, 0, 2) == 0) { if (!DeleteEntry(static_cast<int>(Info.SendDlgMessage(hDlg,DM_LISTGETCURPOS,LIST_BOX,NULL)))) DrawMessage(FMSG_WARNING, 1, "%s",GetMsg(MPlugIn),GetMsg(MDelRegErr),GetMsg(MBtnOk),NULL); Info.SendDlgMessage(hDlg,DMU_UPDATE,1,0); } } } return TRUE; case (KEY_F9|KEY_SHIFT|KEY_ALT): case (KEY_F9): { Configure(0); } return TRUE; case KEY_CTRLR: { Info.SendDlgMessage(hDlg,DMU_UPDATE,1,0); } return TRUE; case KEY_INS: { Info.SendDlgMessage(hDlg,DMU_UPDATE,0,1); } return TRUE; case KEY_ENTER: case KEY_SHIFTENTER: { if (ListSize) { int liChanged = 0; int liSelected = 0, liFirst = -1; for (int i = 0; i < nCount; i++) { if (FLI[i].Flags & LIF_CHECKED) { if (liFirst == -1) liFirst = i; liSelected++; } } if (liSelected <= 1) { int liAction = (Param2 == KEY_ENTER) ? Opt.EnterAction : Opt.ShiftEnterAction; int pos = (liFirst == -1) ? static_cast<int>(Info.SendDlgMessage(hDlg,DM_LISTGETCURPOS,LIST_BOX,NULL)) : liFirst; liChanged = ExecuteEntry(pos, liAction, (Opt.RunLowPriority!=0)); } else { int liAction = (Param2 == KEY_ENTER) ? Opt.EnterAction : Opt.ShiftEnterAction; bool LowPriority = (Opt.RunLowPriority!=0); // Обязательно ожидание - два инсталлятора сразу недопускаются if (liAction == Action_Menu) { if (EntryMenu(0, liAction, LowPriority, liSelected) < 0) return TRUE; } else if (liAction == Action_Uninstall) liAction = Action_UninstallWait; else if (liAction == Action_Modify) liAction = Action_ModifyWait; else if (liAction == Action_Repair) liAction = Action_RepairWait; for (int pos = 0; pos < nCount; pos++) { if (!(FLI[pos].Flags & LIF_CHECKED)) continue; struct FarListPos FLP; FLP.SelectPos = pos; FLP.TopPos = -1; Info.SendDlgMessage(hDlg,DM_LISTSETCURPOS,LIST_BOX,reinterpret_cast<LONG_PTR>(&FLP)); int li = ExecuteEntry(pos, liAction, LowPriority); if (li == -1) break; // отмена if (li == 1) liChanged = 1; } } if (liChanged == 1) { Info.SendDlgMessage(hDlg,DMU_UPDATE,1,0); } } } return TRUE; case KEY_SHIFTINS: case KEY_CTRLV: { TCHAR * bufP = FSF.PasteFromClipboard(); static TCHAR bufData[MAX_PATH]; if (bufP) { StringCchCopy(bufData,ARRAYSIZE(bufData),bufP); FSF.DeleteBuffer(bufP); unQuote(bufData); FSF.LStrlwr(bufData); for (int i = lstrlen(bufData); i >= 1; i--) for (int j = 0; j < nCount; j++) if (strnstri(p[j].Keys[DisplayName],bufData,i)) { lstrcpyn(Filter,bufData,i+1); Info.SendDlgMessage(hDlg,DMU_UPDATE,0,0); return TRUE; } } } return TRUE; case KEY_DEL: { if (lstrlen(Filter) > 0) { StringCchCopy(Filter,ARRAYSIZE(Filter),_T("")); Info.SendDlgMessage(hDlg,DMU_UPDATE,0,0); } } return TRUE; case KEY_F3: case KEY_F4: { if (ListSize) { DisplayEntry(static_cast<int>(Info.SendDlgMessage(hDlg,DM_LISTGETCURPOS,LIST_BOX,NULL))); Info.SendDlgMessage(hDlg,DM_REDRAW,NULL,NULL); } } return TRUE; case KEY_F2: { Opt.SortByDate = !Opt.SortByDate; Info.SendDlgMessage(hDlg,DMU_UPDATE,1,0); } return TRUE; case KEY_BS: { if (lstrlen(Filter)) { Filter[lstrlen(Filter)-1] = '\0'; Info.SendDlgMessage(hDlg,DMU_UPDATE,0,0); } } return TRUE; default: { if (Param2 >= KEY_SPACE && Param2 < KEY_FKEY_BEGIN) { struct FarListInfo ListInfo; Info.SendDlgMessage(hDlg,DM_LISTINFO,LIST_BOX,reinterpret_cast<LONG_PTR>(&ListInfo)); if ((lstrlen(Filter) < sizeof(Filter)) && ListInfo.ItemsNumber) { int filterL = lstrlen(Filter); Filter[filterL] = FSF.LLower(static_cast<unsigned>(Param2)); Filter[filterL+1] = '\0'; Info.SendDlgMessage(hDlg,DMU_UPDATE,0,0); return TRUE; } } } } return FALSE; case DN_CTLCOLORDIALOG: return Info.AdvControl(Info.ModuleNumber,ACTL_GETCOLOR,(void *)COL_MENUTEXT); case DN_CTLCOLORDLGLIST: if (Param1 == LIST_BOX) { FarListColors *Colors = (FarListColors *)Param2; int ColorIndex[] = { COL_MENUBOX, COL_MENUBOX, COL_MENUTITLE, COL_MENUTEXT, COL_MENUHIGHLIGHT, COL_MENUBOX, COL_MENUSELECTEDTEXT, COL_MENUSELECTEDHIGHLIGHT, COL_MENUSCROLLBAR, COL_MENUDISABLEDTEXT, COL_MENUARROWS, COL_MENUARROWSSELECTED, COL_MENUARROWSDISABLED }; int Count = ARRAYSIZE(ColorIndex); if (Count > Colors->ColorCount) Count = Colors->ColorCount; for (int i = 0; i < Count; i++) Colors->Colors[i] = static_cast<BYTE>(Info.AdvControl(Info.ModuleNumber, ACTL_GETCOLOR, reinterpret_cast<void *>(ColorIndex[i]))); return TRUE; } break; } return Info.DefDlgProc(hDlg,Msg,Param1,Param2); }
/*! @param hwndDlg ダイアログボックスのWindow Handle @param uMsg メッセージ @param wParam パラメータ1 @param lParam パラメータ2 */ INT_PTR CALLBACK CPropBackup::DlgProc_page( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam ) { return DlgProc( reinterpret_cast<pDispatchPage>(&CPropBackup::DispatchEvent), hwndDlg, uMsg, wParam, lParam ); }
/** * This static method is the window procedure for the dialog. * * @param hDlg - handle of the dialog window * @param uMsg - message to handle * @param wParam - message dependend parameter * @param lParam - message dependend parameter * * @return depends on message **/ static INT_PTR CALLBACK DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { CAnnivList *pDlg = (CAnnivList *)GetUserData(hDlg); switch (uMsg) { case WM_INITDIALOG: { HWND hCtrl; HICON hIcon; RECT rc; // link the class to the window handle pDlg = (CAnnivList *)lParam; if (!pDlg) break; SetUserData(hDlg, lParam); pDlg->_hDlg = hDlg; // init pointer listview control pDlg->_hList = GetDlgItem(hDlg, EDIT_ANNIVERSARY_DATE); if (!pDlg->_hList) break; // set icons hIcon = IcoLib_GetIcon(ICO_DLG_ANNIVERSARY); SendDlgItemMessage(hDlg, IDC_HEADERBAR, WM_SETICON, 0, (LPARAM)hIcon); SendMessage(hDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon); // insert columns into the listboxes ListView_SetExtendedListViewStyle(pDlg->_hList, LVS_EX_FULLROWSELECT); // add columns if (pDlg->AddColumn(CAnnivList::COLUMN_ETA, LPGENT("ETA"), 40) || pDlg->AddColumn(CAnnivList::COLUMN_CONTACT, LPGENT("Contact"), 160) || pDlg->AddColumn(CAnnivList::COLUMN_PROTO, LPGENT("Proto"), 50) || pDlg->AddColumn(CAnnivList::COLUMN_AGE, LPGENT("Age/Nr."), 40) || pDlg->AddColumn(CAnnivList::COLUMN_DESC, LPGENT("Anniversary"), 100) || pDlg->AddColumn(CAnnivList::COLUMN_DATE, LPGENT("Date"), 80)) break; TranslateDialogDefault(hDlg); // save minimal size GetWindowRect(hDlg, &rc); pDlg->_sizeMin.cx = rc.right - rc.left; pDlg->_sizeMin.cy = rc.bottom - rc.top; // restore position and size Utils_RestoreWindowPosition(hDlg, NULL, MODNAME, "AnnivDlg_"); //save win pos GetWindowRect(hDlg, &pDlg->_rcWin); // add filter strings if (hCtrl = GetDlgItem(hDlg, COMBO_VIEW)) { ComboBox_AddString(hCtrl, TranslateT("All contacts")); ComboBox_AddString(hCtrl, TranslateT("Birthdays only")); ComboBox_AddString(hCtrl, TranslateT("Anniversaries only")); ComboBox_AddString(hCtrl, TranslateT("Disabled reminder")); ComboBox_SetCurSel(hCtrl, pDlg->_filter.bFilterIndex); } // init reminder groups pDlg->_bRemindEnable = db_get_b(NULL, MODNAME, SET_REMIND_ENABLED, DEFVAL_REMIND_ENABLED) != REMIND_OFF; if (hCtrl = GetDlgItem(hDlg, CHECK_REMIND)) { Button_SetCheck(hCtrl, pDlg->_bRemindEnable ? BST_INDETERMINATE : BST_UNCHECKED); EnableWindow(hCtrl, pDlg->_bRemindEnable); } CheckDlgButton(hDlg, CHECK_POPUP, db_get_b(NULL, MODNAME, SET_ANNIVLIST_POPUP, FALSE) ? BST_CHECKED : BST_UNCHECKED); // set number of days to show contact in advance SetDlgItemInt(hDlg, EDIT_DAYS, pDlg->_filter.wDaysBefore, FALSE); if (hCtrl = GetDlgItem(hDlg, CHECK_DAYS)) { Button_SetCheck(hCtrl, db_get_b(NULL, MODNAME, SET_ANNIVLIST_FILTER_DAYSENABLED, FALSE)); DlgProc(hDlg, WM_COMMAND, MAKEWPARAM(CHECK_DAYS, BN_CLICKED), (LPARAM)hCtrl); } pDlg->_wmINIT = false; } return TRUE; // set propertysheet page's background white in aero mode case WM_CTLCOLORSTATIC: case WM_CTLCOLORDLG: if (IsAeroMode()) return (INT_PTR)GetStockBrush(WHITE_BRUSH); break; case WM_NOTIFY: switch (((LPNMHDR)lParam)->idFrom) { case EDIT_ANNIVERSARY_DATE: switch (((LPNMHDR)lParam)->code) { // handle changed selection case LVN_ITEMCHANGED: { CItemData *pid; HWND hCheck; pDlg->_curSel = ((LPNMLISTVIEW)lParam)->iItem; pid = pDlg->ItemData(pDlg->_curSel); if (pid && pDlg->_bRemindEnable && (hCheck = GetDlgItem(hDlg, CHECK_REMIND))) { SetDlgItemInt(hDlg, EDIT_REMIND, pid->_wDaysBefore, FALSE); Button_SetCheck(hCheck, pid->_wReminderState); DlgProc(hDlg, WM_COMMAND, MAKEWPARAM(CHECK_REMIND, BN_CLICKED), (LPARAM)hCheck); } } break; // resort the list case LVN_COLUMNCLICK: { LPNMLISTVIEW pnmv = (LPNMLISTVIEW)lParam; if (pDlg->_sortHeader == pnmv->iSubItem) pDlg->_sortOrder *= -1; else { pDlg->_sortOrder = 1; pDlg->_sortHeader = pnmv->iSubItem; } ListView_SortItemsEx(pDlg->_hList, (CMPPROC)cmpProc, pDlg); } break; // show contact menu case NM_RCLICK: { CItemData *pid = pDlg->ItemData(pDlg->_curSel); if (pid) { HMENU hPopup = Menu_BuildContactMenu(pid->_hContact); if (hPopup) { POINT pt; GetCursorPos(&pt); TrackPopupMenu(hPopup, TPM_TOPALIGN | TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, 0, hDlg, NULL); DestroyMenu(hPopup); } } } break; // handle double click on contact: show message dialog case NM_DBLCLK: { CItemData *pid = pDlg->ItemData(((LPNMITEMACTIVATE)lParam)->iItem); if (pid) CallService(MS_MSG_SENDMESSAGE,(WPARAM)pid->_hContact, NULL); } } } break; case WM_COMMAND: if (PtrIsValid(pDlg)) { CItemData* pid = pDlg->ItemData(pDlg->_curSel); // process contact menu command if (pid && CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam), MPCF_CONTACTMENU), (LPARAM)pid->_hContact)) break; switch (LOWORD(wParam)) { // enable/disable reminder checkbox is clicked case CHECK_REMIND: if (pDlg->_bRemindEnable && HIWORD(wParam) == BN_CLICKED) { BYTE checkState = Button_GetCheck((HWND)lParam); EnableWindow(GetDlgItem(hDlg, EDIT_REMIND), checkState == BST_CHECKED); EnableWindow(GetDlgItem(hDlg, SPIN_REMIND), checkState == BST_CHECKED); if (pid && pid->_wReminderState != checkState) pid->_wReminderState = checkState; } break; // number of days to remind in advance is edited case EDIT_REMIND: if (pid && pDlg->_bRemindEnable && HIWORD(wParam) == EN_CHANGE) { WORD wDaysBefore = GetDlgItemInt(hDlg, LOWORD(wParam), NULL, FALSE); if (pid->_wReminderState == BST_CHECKED && pid->_wDaysBefore != wDaysBefore) { pid->_wDaysBefore = wDaysBefore; } } break; // the filter to display only contacts which have an anniversary in a certain // period of time is enabled/disabled case CHECK_DAYS: if (HIWORD(wParam) == BN_CLICKED) { BYTE isChecked = Button_GetCheck((HWND)lParam); EnableWindow(GetDlgItem(hDlg, EDIT_DAYS), isChecked); EnableWindow(GetDlgItem(hDlg, TXT_DAYS), isChecked); pDlg->_filter.wDaysBefore = isChecked ? GetDlgItemInt(hDlg, EDIT_DAYS, NULL, FALSE) : (WORD)-1; pDlg->RebuildList(); } break; // the number of days a contact must have an anniversary in advance to be displayed is edited case EDIT_DAYS: if (HIWORD(wParam) == EN_CHANGE) { WORD wNewDays = GetDlgItemInt(hDlg, LOWORD(wParam), NULL, FALSE); if (wNewDays != pDlg->_filter.wDaysBefore) { pDlg->_filter.wDaysBefore = wNewDays; pDlg->RebuildList(); } } break; // the filter selection of the filter combobox has changed case COMBO_VIEW: if (HIWORD(wParam) == CBN_SELCHANGE) { pDlg->_filter.bFilterIndex = ComboBox_GetCurSel((HWND)lParam); pDlg->RebuildList(); } } } break; case WM_DRAWITEM: return Menu_DrawItem((LPDRAWITEMSTRUCT)lParam); case WM_MEASUREITEM: return Menu_MeasureItem((LPMEASUREITEMSTRUCT)lParam); case WM_WINDOWPOSCHANGING: if (PtrIsValid(pDlg)) { WINDOWPOS *wndPos = (WINDOWPOS *)lParam; if (!pDlg->_wmINIT && (wndPos->cx != 0 || wndPos->cy != 0)) { //win pos change if ((wndPos->cx == pDlg->_rcWin.right - pDlg->_rcWin.left) && (wndPos->cy == pDlg->_rcWin.bottom - pDlg->_rcWin.top)) //win pos change (store new pos) GetWindowRect(hDlg, &pDlg->_rcWin); //win size change else { // l change if ((wndPos->cx < pDlg->_sizeMin.cx) && (wndPos->x > pDlg->_rcWin.left)) { wndPos->x = wndPos->x + wndPos->cx - pDlg->_sizeMin.cx; wndPos->cx = pDlg->_sizeMin.cx; } // r change else if (wndPos->cx < pDlg->_sizeMin.cx) wndPos->cx = pDlg->_sizeMin.cx; // t change if ((wndPos->cy < pDlg->_sizeMin.cy) && (wndPos->y > pDlg->_rcWin.top)) { wndPos->y = wndPos->y + wndPos->cy - pDlg->_sizeMin.cy; wndPos->cy = pDlg->_sizeMin.cy; } // b change else if (wndPos->cy < pDlg->_sizeMin.cy) wndPos->cy = pDlg->_sizeMin.cy; pDlg->_rcWin.left = wndPos->x; pDlg->_rcWin.right = wndPos->x + wndPos->cx; pDlg->_rcWin.top = wndPos->y; pDlg->_rcWin.bottom = wndPos->y + wndPos->cy; } } CAnchor anchor(wndPos, pDlg->_sizeMin); int anchorPos = CAnchor::ANCHOR_LEFT | CAnchor::ANCHOR_RIGHT | CAnchor::ANCHOR_TOP; anchor.MoveCtrl(IDC_HEADERBAR, anchorPos); anchor.MoveCtrl(GROUP_STATS, anchorPos); // birthday list anchor.MoveCtrl(EDIT_ANNIVERSARY_DATE, CAnchor::ANCHOR_ALL); anchorPos = CAnchor::ANCHOR_RIGHT | CAnchor::ANCHOR_BOTTOM; // filter group anchor.MoveCtrl(GROUP_FILTER, anchorPos); anchor.MoveCtrl(COMBO_VIEW, anchorPos); anchor.MoveCtrl(CHECK_DAYS, anchorPos); anchor.MoveCtrl(EDIT_DAYS, anchorPos); anchor.MoveCtrl(TXT_DAYS, anchorPos); // filter group anchor.MoveCtrl(GROUP_REMINDER, anchorPos); anchor.MoveCtrl(CHECK_REMIND, anchorPos); anchor.MoveCtrl(EDIT_REMIND, anchorPos); anchor.MoveCtrl(SPIN_REMIND, anchorPos); anchor.MoveCtrl(TXT_REMIND6, anchorPos); anchor.MoveCtrl(CHECK_POPUP, anchorPos); } break; // This message is sent if eighter the user clicked on the close button or // Miranda fires the ME_SYSTEM_SHUTDOWN event. case WM_CLOSE: DestroyWindow(hDlg); break; // If the anniversary list is destroyed somehow, the data class must be deleted, too. case WM_DESTROY: if (PtrIsValid(pDlg)) { SetUserData(hDlg, NULL); delete pDlg; } break; } return FALSE; }