void CAnnivEditCtrl::SetZodiacAndAge(MAnnivDate *mt) { if (PtrIsValid(mt)) { int age; MZodiac zod; zod = mt->Zodiac(); if (zod.pszName != NULL) { ShowWindow(GetDlgItem(_hwndDlg, TEXT_ZODIAC), SW_SHOW); SetDlgItemText(_hwndDlg, TEXT_ZODIAC, TranslateTS(zod.pszName)); SendDlgItemMessage(_hwndDlg, IDC_ZODIAC, STM_SETIMAGE, IMAGE_ICON, (LPARAM)zod.hIcon); } else { ShowWindow(GetDlgItem(_hwndDlg, IDC_ZODIAC), SW_HIDE); ShowWindow(GetDlgItem(_hwndDlg, TEXT_ZODIAC), SW_HIDE); } if ((age = mt->Age()) > 0) { SetDlgItemInt(_hwndDlg, EDIT_AGE, age , FALSE); } } }
/** * name: ProfileList_AddNewItem * desc: Ask's user for a type and adds new item to the list view * param: pList - pointer to the listview's data structure * pszList - database settings string, that identifies this category * * return: TRUE or FALSE **/ static BOOLEAN ProfileList_AddNewItem(HWND hDlg, LPLISTCTRL pList, const PROFILEENTRY *pEntry) { LPLCITEM pItem; LVITEM lvi; HANDLE hContact; if (PtrIsValid(pList) && (pItem = (LPLCITEM)mir_alloc(sizeof(LCITEM)))) { PSGetContact(hDlg, hContact); pItem->nType = CTRL_LIST_ITEM; pItem->wFlags = hContact ? CTRLF_HASCUSTOM : 0; pItem->iListItem = 0; pItem->pszText[0] = NULL; pItem->pszText[1] = NULL; // get category list pEntry->GetList((WPARAM)&pItem->idstrListCount, (LPARAM)&pItem->idstrList); lvi.mask = LVIF_PARAM|LVIF_STATE; lvi.stateMask = 0xFFFFFFFF; lvi.state = LVIS_FOCUSED|LVIS_SELECTED; lvi.iItem = ProfileList_GetInsertIndex(pList->hList, pEntry->szGroup); lvi.iSubItem = 0; lvi.lParam = (LPARAM)pItem; if ((lvi.iItem = ListView_InsertItem(pList->hList, &lvi)) >= 0) { ProfileList_BeginLabelEdit(pList, lvi.iItem, 0); return TRUE; } mir_free(pItem); MsgErr(hDlg, LPGENT("Sorry, but there is a problem with adding a new item of type \"%s\""), pEntry->szGroup); } return FALSE; }
// Default dialog procedure, which handles common functions INT_PTR CALLBACK PSPBaseProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { CCtrlList *pCtrlList; pCtrlList = CCtrlList::GetObj(hDlg); if (PtrIsValid(pCtrlList)) { switch (uMsg) { case WM_INITDIALOG: 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; // Set text color of edit boxes according to the source of information they display. case WM_CTLCOLOREDIT: return pCtrlList->OnSetTextColour((HWND)lParam, (HDC)wParam); case WM_NOTIFY: switch (((LPNMHDR)lParam)->idFrom) { case 0: MCONTACT hContact = (MCONTACT)((LPPSHNOTIFY)lParam)->lParam; LPSTR pszProto; switch (((LPNMHDR)lParam)->code) { case PSN_RESET: pCtrlList->OnReset(); break; case PSN_INFOCHANGED: if (PSGetBaseProto(hDlg, pszProto) && *pszProto) { BOOL bChanged = (GetWindowLongPtr(hDlg, DWLP_MSGRESULT)&PSP_CHANGED) | pCtrlList->OnInfoChanged(hContact, pszProto); SetWindowLongPtr(hDlg, DWLP_MSGRESULT, bChanged ? PSP_CHANGED : 0); } break; case PSN_APPLY: if (PSGetBaseProto(hDlg, pszProto) && *pszProto) pCtrlList->OnApply(hContact, pszProto); break; } break; } break; case WM_COMMAND: if (!PspIsLocked(hDlg)) pCtrlList->OnChangedByUser(LOWORD(wParam), HIWORD(wParam)); break; case WM_DESTROY: // destroy all control objects and the list pCtrlList->Release(); } } return 0; }
/** * name: ProfileList_EndLabelEdit * desc: destroys the edit control and saves the text to the list control if desired * param: hList - handle to listview control * bSave - tells, whether to save changes (TRUE) or not (FALSE) * return: returns 0 on success or nonzero **/ static INT ProfileList_EndLabelEdit(LPLISTCTRL pList, BOOLEAN bSave) { HWND hEdit; // check if labeledit is enabled if (!PtrIsValid(pList) || !pList->hList || !pList->labelEdit.hEdit) return 1; // set hEdit NULL to indicate the endlabeledit call and prevent other calls hEdit = pList->labelEdit.hEdit; pList->labelEdit.hEdit = NULL; if (bSave != FALSE && pList->labelEdit.pItem) { WORD ccText; LPTSTR szEdit = NULL; BOOLEAN bChanged = FALSE; // an list element was selected if (pList->labelEdit.iSubItem && pList->labelEdit.dropDown.iItem != pList->labelEdit.pItem->iListItem && pList->labelEdit.dropDown.iItem >= 0 && pList->labelEdit.dropDown.iItem < pList->labelEdit.pItem->idstrListCount) { pList->labelEdit.pItem->iListItem = pList->labelEdit.dropDown.iItem; if (pList->labelEdit.pItem->pszText[0]) { mir_free(pList->labelEdit.pItem->pszText[0]); pList->labelEdit.pItem->pszText[0] = NULL; } bChanged = TRUE; } // value was edited else { if ((ccText = GetWindowTextLength(hEdit)) > 0 && (szEdit = (LPTSTR)mir_alloc((ccText + 2) * sizeof(TCHAR)))) { GetWindowText(hEdit, szEdit, ccText + 1); szEdit[ccText + 1] = 0; if (!pList->labelEdit.pItem->pszText[pList->labelEdit.iSubItem]) { pList->labelEdit.pItem->pszText[pList->labelEdit.iSubItem] = szEdit; bChanged = TRUE; } else if (_tcscmp(pList->labelEdit.pItem->pszText[pList->labelEdit.iSubItem], szEdit)) { mir_free(pList->labelEdit.pItem->pszText[pList->labelEdit.iSubItem]); pList->labelEdit.pItem->pszText[pList->labelEdit.iSubItem] = szEdit; bChanged = TRUE; } else mir_free(szEdit); } } if (bChanged) { pList->labelEdit.pItem->wFlags |= CTRLF_CHANGED; pList->wFlags |= CTRLF_CHANGED; SendMessage(GetParent(GetParent(pList->hList)), PSM_CHANGED, 0, 0); } } if (pList->labelEdit.hBtn) DestroyWindow(pList->labelEdit.hBtn); if (pList->labelEdit.dropDown.hDrop) DestroyWindow(pList->labelEdit.dropDown.hDrop); DestroyWindow(hEdit); ListView_RedrawItems(pList->hList, pList->labelEdit.iItem, pList->labelEdit.iItem); ZeroMemory(&pList->labelEdit, sizeof(pList->labelEdit)); SetFocus(pList->hList); return 0; }
INT_PTR CALLBACK Ctrl_SetTextColour(HWND hCtrl, HDC hdc) { if (hCtrl && DB::Setting::GetByte(SET_PROPSHEET_SHOWCOLOURS, 1)) { LPCTRL pCtrl = (LPCTRL)GetUserData(hCtrl); if (PtrIsValid(pCtrl)) return Ctrl_SetTextColour(hdc, pCtrl->wFlags); } return FALSE; }
VOID CCtrlList::OnApply(HANDLE hContact, LPCSTR pszProto) { INT_PTR i; for (i = 0; i < count; i++) { if (PtrIsValid(items[i])) { items[i]->OnApply(hContact, pszProto); } } }
INT_PTR CCtrlList::OnSetTextColour(HWND hCtrl, HDC hdc) { if (IsWindow(hCtrl) && myGlobals.ShowPropsheetColours) { CBaseCtrl* pCtrl = CBaseCtrl::GetObj(hCtrl); if (PtrIsValid(pCtrl) && (pCtrl->_cbSize = sizeof(CBaseCtrl))) { return pCtrl->OnSetTextColour(hdc); } } return FALSE; }
/** * This method returns the data structure accociated with a list item. * * @param iItem - index of the desired item * * @return pointer to the data strucutre on success or NULL otherwise. **/ CItemData *ItemData(int iItem) { if (_hList && iItem >= 0 && iItem < _numRows) { LVITEM lvi; lvi.mask = LVIF_PARAM; lvi.iItem = iItem; lvi.iSubItem = 0; if (ListView_GetItem(_hList, &lvi) && PtrIsValid(lvi.lParam)) return (CItemData *)lvi.lParam; } return NULL; }
/** * name: ProfileList_DeleteItem * desc: delete an item from the listview * param: hList - handle to listview control * iItem - item index * * return: nothing **/ static VOID ProfileList_DeleteItem(HWND hList, INT iItem) { LPLCITEM pItem = ProfileList_GetItemData(hList, iItem); if (PtrIsValid(pItem)) { if (pItem->pszText[0]) mir_free(pItem->pszText[0]); if (pItem->pszText[1]) mir_free(pItem->pszText[1]); mir_free(pItem); } ListView_DeleteItem(hList, iItem); }
/** * Adds a string and associated item data to a combobox. * * @param pszText - the text to add to the combobox * @param lParam - item data to accociate with the new item * * @return zero-based index to new item or CB_ERR on failure **/ INT_PTR CCombo::AddItem(LPCTSTR pszText, LPARAM lParam) { INT_PTR added = ComboBox_AddString(_hwnd, pszText); if (SUCCEEDED(added)) { if (PtrIsValid(lParam) && FAILED(ComboBox_SetItemData(_hwnd, added, lParam))) { ComboBox_DeleteString(_hwnd, added); added = CB_ERR; } } return added; }
BOOL CCtrlList::OnInfoChanged(HANDLE hContact, LPCSTR pszProto) { BOOL bChanged = 0; INT_PTR i; for (i = 0; i < count; i++) { if (PtrIsValid(items[i])) { bChanged |= items[i]->OnInfoChanged(hContact, pszProto); } } return bChanged; }
/** * This method searches for an item which matches the given nID. * * @param nID - the id of the desired object. * * @retval CB_ERR - item not found * @retval 0...n - index of the combobox item **/ int CCombo::Find(int nID) const { int i; LPIDSTRLIST pd; for (i = ComboBox_GetCount(_hwnd) - 1; i >= 0; i--) { pd = (LPIDSTRLIST)ComboBox_GetItemData(_hwnd, i); if (PtrIsValid(pd) && (pd->nID == nID)) { break; } } return i; }
VOID CCtrlList::OnChangedByUser(WORD idCtrl, WORD wChangedMsg) { // prefilter messages to avoid unessesary search operations switch (wChangedMsg) { case EN_UPDATE: case EN_CHANGE: case CBN_SELCHANGE: { CBaseCtrl *pResult = CBaseCtrl::GetObj(_hOwnerDlg, idCtrl); if (PtrIsValid(pResult) && (pResult->_cbSize == sizeof(CBaseCtrl))) { pResult->OnChangedByUser(wChangedMsg); } } } }
/** * This is the service function for external plugins to use the nice messagebox * * @param wParam - MCONTACT hContact which can display an avatar for popups * @param lParam - MSGBOX structure holding parameters * * @return The function returns the ID of the clicked button (IDOK, IDCANCEL, ...) * or -1 on error. **/ INT_PTR MsgBoxService(WPARAM, LPARAM lParam) { LPMSGBOX pMsgBox = (LPMSGBOX)lParam; // check input if (PtrIsValid(pMsgBox) && pMsgBox->cbSize == sizeof(MSGBOX)) { // Shall the MessageBox displayed as popup? if (!(pMsgBox->uType & (MB_INFOBAR | MB_NOPOPUP)) // message box can be a popup? && ServiceExists(MS_POPUP_ADDPOPUPT) // popups exist? && myGlobals.PopupActionsExist == 1 // popup support ext stuct? && (db_get_dw(NULL, "Popup", "Actions", 0) & 1) // popup++ actions on? && db_get_b(NULL, MODNAME, SET_POPUPMSGBOX, DEFVAL_POPUPMSGBOX)) // user likes popups? return DialogBoxParam(ghInst, MAKEINTRESOURCE(IDD_MSGBOXDUMMI), pMsgBox->hParent, MsgBoxPop, lParam); return DialogBoxParam(ghInst, MAKEINTRESOURCE(IDD_MSGBOX), pMsgBox->hParent, MsgBoxProc, lParam); } return -1; }
/** * This method writes the combobox's item as the contact's timezone. * * @param hContact - HANDLE of the contact whose timezone to select * @param pszProto - the contact's protocol (not used by new core tz interface) * * @return nothing **/ void CTzCombo::OnApply(HANDLE hContact, LPCSTR pszProto) { if (_Flags.B.hasChanged) { const char* pszModule = hContact ? USERINFO : pszProto; if (_Flags.B.hasCustom || !hContact) { //use new core tz interface if (tmi.storeListResults) { tmi.storeListResults(hContact, _hwnd, TZF_PLF_CB); if (!hContact) { _Flags.B.hasCustom = 0; _Flags.B.hasProto = 1; } _Flags.B.hasChanged = 0; } //fallback use old UIEX method else { const CTimeZone* pTimeZone = (CTimeZone*)ComboBox_GetItemData(_hwnd, _curSel); if (PtrIsValid(pTimeZone)) { db_set_ts(hContact, USERINFO, SET_CONTACT_TIMEZONENAME, pTimeZone->ptszName); db_set_b(hContact, pszModule, SET_CONTACT_TIMEZONE, pTimeZone->ToMirandaTimezone()); if (!hContact) { _Flags.B.hasCustom = 0; _Flags.B.hasProto = 1; } _Flags.B.hasChanged = 0; } } } if (_Flags.B.hasChanged) { db_unset(hContact, USERINFO, SET_CONTACT_TIMEZONENAME); db_unset(hContact, USERINFO, SET_CONTACT_TIMEZONEINDEX); db_unset(hContact, pszModule, SET_CONTACT_TIMEZONE); _Flags.B.hasChanged = 0; OnInfoChanged(hContact, pszProto); } InvalidateRect(_hwnd, NULL, TRUE); } }
/** * name: ProfileList_Clear * desc: delete all list items and their data * **/ static VOID ProfileList_Clear(HWND hList) { LVITEM lvi; lvi.iItem = 0; lvi.iSubItem = 0; lvi.mask = LVIF_PARAM; while (ListView_GetItem(hList, &lvi)) { if (PtrIsValid(lvi.lParam)) { if (((LPLCITEM)lvi.lParam)->pszText[0]) mir_free(((LPLCITEM)lvi.lParam)->pszText[0]); if (((LPLCITEM)lvi.lParam)->pszText[1]) mir_free(((LPLCITEM)lvi.lParam)->pszText[1]); mir_free((LPVOID)lvi.lParam); } lvi.iItem++; } ListView_DeleteAllItems(hList); }
/** * This method fills @szTime with the current time * according to the combobox's selected timezone. * * @param szTime - string to fill with the current time * @param cchTime - number of characters the string can take * * @return nothing **/ void CTzCombo::GetTime(LPTSTR szTime, WORD cchTime) { //use new core tz interface if (tmi.printDateTime) { tmi.printDateTime((HANDLE)ComboBox_GetItemData(_hwnd, _curSel), _T("t"), szTime, cchTime, 0); } //fallback use old UIEX method else { const CTimeZone *pTimeZone = (CTimeZone*)ComboBox_GetItemData(_hwnd, _curSel); if (PtrIsValid(pTimeZone)) { MTime now; TIME_ZONE_INFORMATION tzi = *pTimeZone; now.GetTimeUTC(); now.UTCToTzSpecificLocal(&tzi); now.TimeFormat(szTime, cchTime); } else mir_tcscpy(szTime, _T("--:--")); } }
/** * name: ProfileList_LabelEditProc * desc: procedure to catch messages for an edit control for my own combobox * param: hwnd - handle to the listview control's window * msg - message sent to the control * wParam - message specific parameter * lParam - message specific parameter * return: message specific **/ static INT_PTR CALLBACK ProfileList_LabelEditProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { LPLISTCTRL pList; switch (msg) { case WM_KEYDOWN: switch (wParam) { case VK_ESCAPE: if (PtrIsValid(pList = (LPLISTCTRL)GetUserData(hwnd))) ProfileList_EndLabelEdit(pList, FALSE); return 0; case VK_F3: if (PtrIsValid(pList = (LPLISTCTRL)GetUserData(hwnd)) && pList->labelEdit.hBtn) SendMessage(pList->hList, WM_COMMAND, MAKEWPARAM(BTN_EDIT, BN_CLICKED), (LPARAM)pList->labelEdit.hBtn); return 0; case VK_RETURN: { BOOLEAN bEditNext; INT iItem; if (GetWindowLongPtr(hwnd, GWL_STYLE) & ES_WANTRETURN && !(GetKeyState(VK_CONTROL) & 0x8000)) break; if (PtrIsValid(pList = (LPLISTCTRL)GetUserData(hwnd))) { bEditNext = !pList->labelEdit.iSubItem && !ProfileList_GetItemText(pList->hList, pList->labelEdit.iItem, 1, NULL, NULL); iItem = pList->labelEdit.iItem; ProfileList_EndLabelEdit(pList->hList, TRUE); if (bEditNext) ProfileList_BeginLabelEdit(pList->hList, pList->labelEdit.iItem, 1); } return 0; } case VK_TAB: if (PtrIsValid(pList = (LPLISTCTRL)GetUserData(hwnd))) { LVITEM lvi; lvi.mask = LVIF_STATE; lvi.stateMask = LVIS_FOCUSED|LVIS_SELECTED; lvi.iItem = pList->labelEdit.iItem; if (wParam == VK_TAB && !pList->labelEdit.iSubItem) { lvi.iSubItem = 1; lvi.state = LVIS_FOCUSED|LVIS_SELECTED; ProfileList_EndLabelEdit(pList->hList, TRUE); } else { UINT iSubItem = (wParam == VK_TAB) ? 0 : pList->labelEdit.iSubItem; lvi.iSubItem = 0; lvi.state = 0; ProfileList_EndLabelEdit(pList, TRUE); // unselect current list item if (!ListView_SetItem(pList->hList, &lvi)) return 0; // search for next valid list item (skip deviders) lvi.iSubItem = iSubItem; lvi.mask = LVIF_PARAM; do { if (wParam == VK_UP) lvi.iItem--; else lvi.iItem++; if (lvi.iItem == -1 || !ListView_GetItem(pList->hList, &lvi)) { return 0; } } while (!lvi.lParam); // select new list item lvi.mask = LVIF_STATE; lvi.state = LVIS_FOCUSED|LVIS_SELECTED; if (!ListView_SetItem(pList->hList, &lvi)){ return 0; } } ProfileList_BeginLabelEdit(pList->hList, lvi.iItem, lvi.iSubItem); return 0; } return 1; } break; case WM_GETDLGCODE: return DLGC_WANTALLKEYS | CallWindowProc(OldEditProc, hwnd, msg, wParam, lParam); case WM_KILLFOCUS: { HWND hwndFocus = GetFocus(); if (PtrIsValid(pList = (LPLISTCTRL)GetUserData(hwnd)) && hwndFocus != pList->labelEdit.dropDown.hDrop && hwndFocus != pList->labelEdit.hEdit && hwndFocus != pList->labelEdit.hBtn) ProfileList_EndLabelEdit(pList, hwndFocus == pList->hList); return 0; } } return CallWindowProc(OldEditProc, hwnd, msg, wParam, lParam); }
/** * name: ProfileList_DropdownProc * desc: procedure to catch messages for a listbox control for my own combobox * param: hwnd - handle to the listview control's window * msg - message sent to the control * wParam - message specific parameter * lParam - message specific parameter * return: message specific **/ static INT_PTR CALLBACK ProfileList_DropdownProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { LPLISTCTRL pList; switch (msg) { case WM_KEYDOWN: switch (wParam) { case VK_ESCAPE: SetFocus(GetParent(hwnd)); return 0; case VK_RETURN: case VK_F4: { LPIDSTRLIST pItem; if (!PtrIsValid(pList = (LPLISTCTRL)GetUserData(hwnd))) return CB_ERR; pList->labelEdit.dropDown.iItem = ListBox_GetCurSel(hwnd); if (pList->labelEdit.dropDown.iItem >= 0 && PtrIsValid(pItem = (LPIDSTRLIST)ListBox_GetItemData(hwnd, pList->labelEdit.dropDown.iItem))) SetWindowText(pList->labelEdit.hEdit, pItem->ptszTranslated); else pList->labelEdit.dropDown.iItem = -1; SetFocus(pList->labelEdit.hEdit); return 0; } } break; case WM_LBUTTONUP: { POINT pt; LPIDSTRLIST pItem; if (!PtrIsValid(pList = (LPLISTCTRL)GetUserData(hwnd))) return CB_ERR; CallWindowProc(OldDropdownProc, hwnd, msg, wParam, lParam); pt.x = (short)LOWORD(lParam); pt.y = (short)HIWORD(lParam); ClientToScreen(hwnd, &pt); if (SendMessage(hwnd, WM_NCHITTEST, 0, MAKELPARAM(pt.x, pt.y)) == HTVSCROLL) return CB_ERR; pList->labelEdit.dropDown.iItem = SendMessage(hwnd, LB_GETCURSEL, 0, 0); if (pList->labelEdit.dropDown.iItem >= 0 && PtrIsValid(pItem = (LPIDSTRLIST)ListBox_GetItemData(hwnd, pList->labelEdit.dropDown.iItem))) { SetWindowText(pList->labelEdit.hEdit, pItem->ptszTranslated); } else pList->labelEdit.dropDown.iItem = -1; ProfileList_EndLabelEdit(pList->hList, TRUE); return 0; } case WM_KILLFOCUS: if (PtrIsValid(pList = (LPLISTCTRL)GetUserData(hwnd))) { if (GetFocus() == pList->labelEdit.hEdit) { ShowWindow(hwnd, SW_HIDE); return 0; } ProfileList_EndLabelEdit(pList, FALSE); } return 0; } return CallWindowProc(OldDropdownProc, hwnd, msg, wParam, lParam); }
/** * name: CtrlContactWndProc * desc: window procedure for the extended combobox class * param: hwnd - handle to a extended combobox window * msg - message to handle * wParam - message specific * lParam - message specific * return: message specific **/ static LRESULT CALLBACK CtrlContactWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { LPCBEX cbex = (LPCBEX)GetWindowLongPtr(hwnd, 0); switch (msg) { /** * name: WM_NCCREATE * desc: is called to initiate the window creation * param: wParam - not used * lParam - pointer to a CREATESTRUCT * * return: FALSE on error, TRUE if initialisation was ok **/ case WM_NCCREATE: { LPCREATESTRUCT cs = (LPCREATESTRUCT)lParam; if (!(cbex = (LPCBEX)mir_calloc(1*sizeof(CBEX)))) return FALSE; SetWindowLongPtr(hwnd, 0, (LONG_PTR)cbex); cbex->bLocked = 1; cbex->hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT); cbex->hInstance = cs->hInstance; cbex->iSelectedItem = -1; cbex->rect.left = cs->x; cbex->rect.top = cs->y; cbex->rect.right = cs->x + cs->cx; cbex->rect.bottom = cs->y + cs->cy; return TRUE; } /** * name: WM_NCCREATE * desc: is called to create all subitems * param: wParam - not used * lParam - not used * * return: FALSE on error, TRUE if initialisation was ok **/ case WM_CREATE: { WORD wHeight = (WORD)(cbex->rect.bottom - cbex->rect.top); WORD wWidth = 130; WORD x = 0; if (!(cbex->hBtnEdit = CreateWindowEx(WS_EX_NOPARENTNOTIFY, UINFOBUTTONCLASS, _T("none"), WS_VISIBLE|WS_CHILD|WS_TABSTOP, 0, 0, wWidth, wHeight, hwnd, NULL, cbex->hInstance, NULL))) { cbex->bLocked = 0; return FALSE; } x += wWidth + 2; wWidth = wHeight; if (!(cbex->hBtnMenu = CreateWindowEx(WS_EX_NOPARENTNOTIFY, UINFOBUTTONCLASS, NULL, WS_VISIBLE|WS_CHILD|WS_TABSTOP|MBS_PUSHBUTTON|MBS_DOWNARROW, x, 0, wWidth, wHeight, hwnd, NULL, cbex->hInstance, NULL))) { DestroyWindow(cbex->hBtnEdit); cbex->bLocked = 0; return FALSE; } x += wWidth + 2; wWidth = (WORD)(cbex->rect.right - cbex->rect.left - x - (2 * (wHeight + 2))); if (!(cbex->hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, _T("Edit"), NULL, WS_VISIBLE|WS_CHILD|WS_TABSTOP|ES_AUTOHSCROLL, x, 1, wWidth, wHeight - 2, hwnd, NULL, cbex->hInstance, NULL))) { DestroyWindow(cbex->hBtnEdit); DestroyWindow(cbex->hBtnMenu); cbex->bLocked = 0; return FALSE; } x += wWidth + 2; wWidth = wHeight; if (!(cbex->hBtnAdd = CreateWindowEx(WS_EX_NOPARENTNOTIFY, UINFOBUTTONCLASS, NULL, WS_VISIBLE|WS_CHILD|WS_TABSTOP|MBS_FLAT, x, 0, wWidth, wHeight, hwnd, NULL, cbex->hInstance, NULL))) { DestroyWindow(cbex->hBtnEdit); DestroyWindow(cbex->hBtnMenu); DestroyWindow(cbex->hEdit); cbex->bLocked = 0; return FALSE; } x += wWidth + 2; if (!(cbex->hBtnDel = CreateWindowEx(WS_EX_NOPARENTNOTIFY, UINFOBUTTONCLASS, NULL, WS_VISIBLE|WS_CHILD|WS_TABSTOP|MBS_FLAT, x, 0, wWidth, wHeight, hwnd, NULL, cbex->hInstance, NULL))) { DestroyWindow(cbex->hBtnEdit); DestroyWindow(cbex->hBtnMenu); DestroyWindow(cbex->hEdit); DestroyWindow(cbex->hBtnAdd); cbex->bLocked = 0; return FALSE; } // set ids SetWindowLongPtr(cbex->hBtnEdit, GWLP_ID, BTN_EDIT); SetWindowLongPtr(cbex->hBtnMenu, GWLP_ID, BTN_MENU); SetWindowLongPtr(cbex->hEdit, GWLP_ID, EDIT_VALUE); SetWindowLongPtr(cbex->hBtnAdd, GWLP_ID, BTN_ADD); SetWindowLongPtr(cbex->hBtnDel, GWLP_ID, BTN_DEL); // set fonts & maximum edit control charachters SendMessage(cbex->hEdit, WM_SETFONT, (WPARAM)cbex->hFont, NULL); SendMessage(cbex->hEdit, EM_LIMITTEXT, (WPARAM)MAXDATASIZE, NULL); // add tooltips SendMessage(cbex->hBtnMenu, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Choose the item to display"), MBBF_TCHAR); SendMessage(cbex->hBtnEdit, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Edit the currently displayed item"), MBBF_TCHAR); SendMessage(cbex->hBtnAdd, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Add a new custom item"), MBBF_TCHAR); SendMessage(cbex->hBtnDel, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Delete the selected item"), MBBF_TCHAR); // reload icons CtrlContactWndProc(hwnd, WM_SETICON, NULL, NULL); cbex->bLocked = 0; return TRUE; } /** * name: WM_DESTROY * desc: default destroy message, so clear up memory * param: wParam - not used * lParam - not used * return: return value of DefWindowProc **/ case WM_DESTROY: CtrlContactWndProc(hwnd, CBEXM_DELALLITEMS, NULL, NULL); DestroyWindow(cbex->hBtnEdit); DestroyWindow(cbex->hBtnMenu); DestroyWindow(cbex->hBtnAdd); DestroyWindow(cbex->hBtnDel); DestroyWindow(cbex->hEdit); MIR_FREE(cbex); break; /** * name: WM_CTLCOLOREDIT * desc: is called on a paint message for a dialog item to determine its colour scheme * param: wParam - pointer to a HDC * lParam - pointer to a HWND * return: a brush **/ case WM_CTLCOLOREDIT: if (!db_get_b(NULL, MODNAME, SET_PROPSHEET_SHOWCOLOURS, 1) || (HWND)lParam != cbex->hEdit || !cbex->pItems || cbex->iSelectedItem < 0) break; return Ctrl_SetTextColour((HDC)wParam, cbex->pItems[cbex->iSelectedItem].wFlags); case WM_CTLCOLORSTATIC: if ((HWND)lParam == cbex->hEdit) return (INT_PTR)GetSysColor(COLOR_WINDOW); return FALSE; /** * name: WM_SETICON * desc: updates the icons of this control * param: wParam - not used * lParam - not used * return: always 0 **/ case WM_SETICON: { HICON hIcon = IcoLib_GetIcon(ICO_BTN_ADD); SendMessage(cbex->hBtnAdd, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); SetWindowText(cbex->hBtnAdd, (hIcon ? _T("") : _T("+"))); hIcon = IcoLib_GetIcon(ICO_BTN_DELETE); SendMessage(cbex->hBtnDel, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); SetWindowText(cbex->hBtnDel, (hIcon ? _T("") : _T("-"))); if (cbex->pItems && cbex->numItems > 0) { for (int i = 0; i < cbex->numItems; i++) cbex->pItems[i].hIcon = IcoLib_GetIcon(cbex->pItems[i].pszIcon); if (cbex->iSelectedItem >= 0 && cbex->iSelectedItem < cbex->numItems) SendMessage(cbex->hBtnEdit, BM_SETIMAGE, IMAGE_ICON, (LPARAM)cbex->pItems[cbex->iSelectedItem].hIcon); } return 0; } case WM_COMMAND: switch (LOWORD(wParam)) { /** * name: BTN_MENU * desc: the button to dropdown the list to show all items is pressed **/ case BTN_MENU: if (HIWORD(wParam) == BN_CLICKED) { POINT pt = { 0, 0 }; RECT rc; int i, nItems; HMENU hMenu; if (!(hMenu = CreatePopupMenu())) return 0; SetFocus((HWND)lParam); MENUITEMINFO mii = { 0 }; mii.cbSize = sizeof(mii); mii.fMask = MIIM_ID|MIIM_STRING|MIIM_FTYPE|MIIM_STATE; mii.fType = MFT_STRING; // insert the items for (i = nItems = 0; i < cbex->numItems; i++) { if ((cbex->pItems[i].wFlags & CBEXIF_DELETED) || *cbex->pItems[i].szCat == 0) continue; mii.fState = (cbex->pItems[i].pszVal && *cbex->pItems[i].pszVal) ? MFS_CHECKED : MFS_UNCHECKED; mii.wID = CBEXM_MENIITEMFIRST + i; mii.dwTypeData = cbex->pItems[i].szCat; if (!InsertMenuItem(hMenu, i, TRUE, &mii)) { DestroyMenu(hMenu); return 0; } nItems++; } // add separator between default and custom items if (nItems > 3) { mii.fMask = MIIM_FTYPE; mii.fType = MFT_SEPARATOR; mii.wID = 0; mii.dwItemData = 0; InsertMenuItem(hMenu, 3, TRUE, &mii); } ClientToScreen((HWND)lParam, &pt); GetClientRect((HWND)lParam, &rc); i = TrackPopupMenuEx(hMenu, TPM_RIGHTALIGN|TPM_RETURNCMD, pt.x + rc.right, pt.y + rc.bottom, hwnd, NULL); SendMessage(cbex->hBtnMenu, BM_SETCHECK, NULL, NULL); if (i >= CBEXM_MENIITEMFIRST && i < CBEXM_MENIITEMFIRST + cbex->numItems) { CtrlContactWndProc(hwnd, CBEXM_SETCURSEL, (WPARAM)i - CBEXM_MENIITEMFIRST, NULL); } DestroyMenu(hMenu); return 0; } break; /** * name: BTN_ADD * desc: the button to add a new entry is pressed **/ case BTN_ADD: if (HIWORD(wParam) == BN_CLICKED) { DLGPROC dlgProc; WORD dlgID; TCHAR szCat[MAX_CAT] = { 0 }; TCHAR szVal[MAXDATASIZE] = { 0 }; CBEXITEM cbi; HWND hDlgDetails; SetFocus((HWND)lParam); if (!(hDlgDetails = GetParent(GetParent(hwnd)))) return 1; if (SendMessage(hDlgDetails, PSM_ISLOCKED, NULL, NULL)) return 0; switch (GetWindowLongPtr(hwnd, GWLP_ID)) { case EDIT_PHONE: dlgID = IDD_ADDPHONE; dlgProc = DlgProc_Phone; cbi.pszIcon = ICO_BTN_CUSTOMPHONE; break; case EDIT_EMAIL: dlgID = IDD_ADDEMAIL; dlgProc = DlgProc_EMail; cbi.pszIcon = ICO_BTN_EMAIL; break; default: return 1; } cbi.iItem = -1; cbi.wMask = CBEXIM_CAT|CBEXIM_VAL|CBEXIM_FLAGS|CBEXIM_ICONTEXT; cbi.pszCat = szCat; cbi.pszVal = szVal; cbi.ccCat = MAX_CAT; cbi.ccVal = MAXDATASIZE; cbi.wFlags = 0; cbi.dwID = 0; if (DialogBoxParam(ghInst, MAKEINTRESOURCE(dlgID), GetParent(hwnd), dlgProc, (LPARAM)&cbi) == IDOK) { MCONTACT hContact = NULL; SendMessage(hDlgDetails, PSM_GETCONTACT, NULL, (LPARAM)&hContact); if (hContact) cbi.wFlags |= CTRLF_HASCUSTOM; cbi.wFlags |= CTRLF_CHANGED; if (SendMessage(hwnd, CBEXM_ADDITEM, NULL, (LPARAM)&cbi) > CB_ERR) { SendMessage(hDlgDetails, PSM_CHANGED, NULL, NULL); cbex->bIsChanged = TRUE; SendMessage(hwnd, CBEXM_SETCURSEL, cbex->numItems - 1, NULL); } } return 0; } break; /** * name: BTN_EDIT * desc: the button to edit an existing entry is pressed **/ case BTN_EDIT: if (HIWORD(wParam) == BN_CLICKED) { DLGPROC dlgProc; WORD dlgID; TCHAR szCat[MAX_CAT] = { 0 }; TCHAR szVal[MAXDATASIZE] = { 0 }; CBEXITEM cbi; HWND hDlgDetails; SetFocus((HWND)lParam); if (!(hDlgDetails = GetParent(GetParent(hwnd)))) return 1; if (SendMessage(hDlgDetails, PSM_ISLOCKED, NULL, NULL)) return 0; if (!cbex->pItems || cbex->iSelectedItem == -1) return 0; switch (GetWindowLongPtr(hwnd, GWLP_ID)) { case EDIT_PHONE: dlgID = IDD_ADDPHONE; dlgProc = DlgProc_Phone; break; case EDIT_EMAIL: dlgID = IDD_ADDEMAIL; dlgProc = DlgProc_EMail; break; default: return 1; } cbi.iItem = cbex->iSelectedItem; cbi.dwID = 0; cbi.wMask = CBEXIM_CAT|CBEXIM_VAL|CBEXIM_FLAGS; cbi.pszCat = szCat; cbi.pszVal = szVal; cbi.ccCat = MAX_CAT; cbi.ccVal = MAXDATASIZE; if (!CtrlContactWndProc(hwnd, CBEXM_GETITEM, NULL, (LPARAM)&cbi)) { MsgErr(hwnd, LPGENT("CRITICAL: Unable to edit current entry!\nThis should not happen!")); return 1; } if (DialogBoxParam(ghInst, MAKEINTRESOURCE(dlgID), GetParent(hwnd), dlgProc, (LPARAM)&cbi) == IDOK) { MCONTACT hContact; SendMessage(hDlgDetails, PSM_GETCONTACT, NULL, (LPARAM)&hContact); if (hContact) cbi.wFlags |= CTRLF_HASCUSTOM; cbi.wFlags |= CTRLF_CHANGED; SendMessage(hwnd, CBEXM_SETITEM, NULL, (LPARAM)&cbi); SendMessage(hDlgDetails, PSM_CHANGED, NULL, NULL); cbex->bIsChanged = TRUE; } return 0; } break; /** * name: BTN_DEL * desc: the button to delete an existing entry is pressed **/ case BTN_DEL: if (HIWORD(wParam) == BN_CLICKED) { HWND hDlgDetails; MSGBOX mBox; TCHAR szMsg[MAXDATASIZE]; SetFocus((HWND)lParam); if (!(hDlgDetails = GetParent(GetParent(hwnd))) || SendMessage(hDlgDetails, PSM_ISLOCKED, NULL, NULL) || !cbex->pItems || cbex->iSelectedItem < 0 || cbex->iSelectedItem >= cbex->numItems || FAILED(mir_sntprintf(szMsg, TranslateT("Do you really want to delete the current selected item?\n\t%s\n\t%s"), cbex->pItems[cbex->iSelectedItem].szCat, cbex->pItems[cbex->iSelectedItem].pszVal)) ) { return 1; } mBox.cbSize = sizeof(MSGBOX); mBox.hParent = hDlgDetails; mBox.hiLogo = IcoLib_GetIcon(ICO_DLG_PHONE); mBox.uType = MB_YESNO|MB_ICON_QUESTION|MB_NOPOPUP; mBox.ptszTitle = TranslateT("Delete"); mBox.ptszMsg = szMsg; if (IDYES == MsgBoxService(NULL, (LPARAM)&mBox)) { // clear value for standard entry if (cbex->pItems[cbex->iSelectedItem].wFlags & CBEXIF_CATREADONLY) { MIR_FREE(cbex->pItems[cbex->iSelectedItem].pszVal); SetWindowText(cbex->hEdit, _T("")); cbex->pItems[cbex->iSelectedItem].wFlags &= ~CBEXIF_SMS; cbex->pItems[cbex->iSelectedItem].wFlags |= CTRLF_CHANGED; } // clear values for customized database entry else if (cbex->pItems[cbex->iSelectedItem].dwID != 0) { MIR_FREE(cbex->pItems[cbex->iSelectedItem].pszVal); *cbex->pItems[cbex->iSelectedItem].szCat = 0; cbex->pItems[cbex->iSelectedItem].wFlags |= CTRLF_CHANGED|CBEXIF_DELETED; CtrlContactWndProc(hwnd, CBEXM_SETCURSEL, cbex->iSelectedItem - 1, FALSE); } // delete default entry else CtrlContactWndProc(hwnd, CBEXM_DELITEM, NULL, cbex->iSelectedItem); SendMessage(hDlgDetails, PSM_CHANGED, NULL, NULL); cbex->bIsChanged = TRUE; } return 0; } break; /** * name: EDIT_VALUE * desc: the edit control wants us to act **/ case EDIT_VALUE: switch (HIWORD(wParam)) { case EN_UPDATE: { TCHAR szVal[MAXDATASIZE] = { 0 }; int ccVal; MCONTACT hContact; HWND hDlgDetails = GetParent(GetParent(hwnd)); EnableWindow(cbex->hBtnDel, GetWindowTextLength(cbex->hEdit) > 0); if (SendMessage(hDlgDetails, PSM_ISLOCKED, NULL, NULL) || cbex->bLocked || !cbex->pItems || cbex->iSelectedItem < 0 || cbex->iSelectedItem >= cbex->numItems) return 1; // get the edit control's text value and check it for syntax switch (GetWindowLongPtr(hwnd, GWLP_ID)) { case EDIT_PHONE: { int errorPos; TCHAR szEdit[MAXDATASIZE]; if (ccVal = GetWindowText(cbex->hEdit, szEdit, _countof(szEdit))) { if (!(ccVal = CheckPhoneSyntax(szEdit, szVal, MAXDATASIZE, errorPos)) || errorPos > -1) { SetWindowText(cbex->hEdit, szVal); SendMessage(cbex->hEdit, EM_SETSEL, errorPos, errorPos); } } break; } case EDIT_EMAIL: ccVal = GetWindowText(cbex->hEdit, szVal, _countof(szVal)); break; default: ccVal = GetWindowText(cbex->hEdit, szVal, _countof(szVal)); break; } SendMessage(hDlgDetails, PSM_GETCONTACT, NULL, (LPARAM)&hContact); if ((cbex->pItems[cbex->iSelectedItem].wFlags & CTRLF_CHANGED) && !(hContact && (cbex->pItems[cbex->iSelectedItem].wFlags & CTRLF_HASCUSTOM))) return 0; if (*szVal == 0 || !cbex->pItems[cbex->iSelectedItem].pszVal || mir_tstrcmp(szVal, cbex->pItems[cbex->iSelectedItem].pszVal)) { cbex->pItems[cbex->iSelectedItem].wFlags |= CTRLF_CHANGED; cbex->pItems[cbex->iSelectedItem].wFlags |= (hContact ? CTRLF_HASCUSTOM : CTRLF_HASPROTO); cbex->bIsChanged = TRUE; InvalidateRect((HWND)lParam, NULL, TRUE); SendMessage(hDlgDetails, PSM_CHANGED, NULL, NULL); } return 0; } case EN_KILLFOCUS: { int ccText; if (!cbex->pItems || cbex->iSelectedItem < 0 || cbex->iSelectedItem >= cbex->numItems) return 1; if (!(cbex->pItems[cbex->iSelectedItem].wFlags & CTRLF_CHANGED)) return 0; if ((ccText = GetWindowTextLength(cbex->hEdit)) <= 0) { if (cbex->pItems[cbex->iSelectedItem].wFlags & CBEXIF_CATREADONLY) { MIR_FREE(cbex->pItems[cbex->iSelectedItem].pszVal); SetWindowText(cbex->hEdit, _T("")); cbex->pItems[cbex->iSelectedItem].wFlags &= ~CBEXIF_SMS; } else CtrlContactWndProc(hwnd, CBEXM_DELITEM, NULL, cbex->iSelectedItem); SendMessage(GetParent(GetParent(hwnd)), PSM_CHANGED, NULL, NULL); cbex->bIsChanged = TRUE; } else if (cbex->pItems[cbex->iSelectedItem].pszVal = (LPTSTR)mir_realloc(cbex->pItems[cbex->iSelectedItem].pszVal, (ccText + 2) * sizeof(TCHAR))) { cbex->pItems[cbex->iSelectedItem].pszVal[ccText + 1] = 0; GetWindowText(cbex->hEdit, cbex->pItems[cbex->iSelectedItem].pszVal, ccText + 1); } return 0; } } break; } break; /** * name: CBEXM_ADDITEM * desc: add a item to the control * param: wParam - not used * lParam - (LPCBEXITEM)&item * return: CB_ERR on failure, new item index if successful **/ case CBEXM_ADDITEM: { LPCBEXITEM pItem = (LPCBEXITEM)lParam; if (!pItem) return FALSE; // if an item with the id of pItem exists, change it instead of adding a new one // but only if it has not been changed by the user yet. if ((pItem->wMask & CBEXIM_ID) && cbex->pItems && pItem->dwID != 0) { int iIndex; for (iIndex = 0; iIndex < cbex->numItems; iIndex++) { if (cbex->pItems[iIndex].dwID == pItem->dwID) { pItem->iItem = iIndex; if (cbex->pItems[iIndex].wFlags & CTRLF_CHANGED) pItem->wFlags |= CTRLF_CHANGED; else CtrlContactWndProc(hwnd, CBEXM_SETITEM, 0, lParam); return iIndex; } } } // add a new item to the combobox if (!(cbex->pItems = (LPCBEXITEMINTERN)mir_realloc(cbex->pItems, (cbex->numItems + 1) * sizeof(CBEXITEMINTERN)))) { cbex->numItems = 0; return CB_ERR; } // set the ID cbex->pItems[cbex->numItems].dwID = (pItem->wMask & CBEXIM_ID) ? pItem->dwID : 0; // set category string if (!pItem->pszCat || !pItem->pszCat[0] || !mir_tstrncpy(cbex->pItems[cbex->numItems].szCat, pItem->pszCat, MAX_CAT)) { mir_sntprintf(cbex->pItems[cbex->numItems].szCat, _T("%s %d"), TranslateT("Other"), ++cbex->numOther); } // set value string if ((pItem->wMask & CBEXIM_VAL) && pItem->pszVal && pItem->pszVal[0]) cbex->pItems[cbex->numItems].pszVal = mir_tstrdup(pItem->pszVal); else cbex->pItems[cbex->numItems].pszVal = NULL; // set icon if ((pItem->wMask & CBEXIM_ICONTEXT) && pItem->pszIcon) { cbex->pItems[cbex->numItems].pszIcon = pItem->pszIcon; cbex->pItems[cbex->numItems].hIcon = IcoLib_GetIcon(pItem->pszIcon); } // set flags cbex->pItems[cbex->numItems].wFlags = (pItem->wMask & CBEXIM_CAT) ? pItem->wFlags : 0; cbex->numItems++; return cbex->numItems; } /** * name: CBEXM_SETITEM * desc: Set an item's information of the control. * If iItem member of CBEXITEM is -1, the currently selected item is changed. * param: wParam - not used * lParam - (LPCBEXITEM)&item * return: CB_ERR on failure, new item index if successful **/ case CBEXM_SETITEM: { LPCBEXITEM pItem = (LPCBEXITEM)lParam; if (!PtrIsValid(pItem) || !pItem->wMask || !PtrIsValid(cbex->pItems)) return FALSE; if (pItem->iItem == -1) pItem->iItem = cbex->iSelectedItem; if (pItem->iItem < 0 || pItem->iItem >= cbex->numItems) return FALSE; // set new category string if (pItem->wMask & CBEXIM_CAT) { // set category string if (!pItem->pszCat || !pItem->pszCat[0] || !mir_tstrncpy(cbex->pItems[pItem->iItem].szCat, pItem->pszCat, _countof(cbex->pItems[pItem->iItem].szCat))) mir_sntprintf(cbex->pItems[pItem->iItem].szCat, _T("%s %d"), TranslateT("Other"), ++cbex->numOther); if (pItem->iItem == cbex->iSelectedItem) SetWindowText(cbex->hBtnEdit, cbex->pItems[pItem->iItem].szCat); } // set new value if (pItem->wMask & CBEXIM_VAL) { MIR_FREE(cbex->pItems[pItem->iItem].pszVal); if (pItem->pszVal && pItem->pszVal[0]) cbex->pItems[pItem->iItem].pszVal = mir_tstrdup(pItem->pszVal); if (pItem->iItem == cbex->iSelectedItem) SetWindowText(cbex->hEdit, cbex->pItems[pItem->iItem].pszVal ? cbex->pItems[pItem->iItem].pszVal : _T("")); } // set icon if ((pItem->wMask & CBEXIM_ICONTEXT) && pItem->pszIcon) { cbex->pItems[pItem->iItem].pszIcon = pItem->pszIcon; cbex->pItems[pItem->iItem].hIcon = IcoLib_GetIcon(pItem->pszIcon); if (pItem->iItem == cbex->iSelectedItem) SendMessage(cbex->hBtnEdit, BM_SETIMAGE, IMAGE_ICON, (LPARAM)cbex->pItems[pItem->iItem].hIcon); } if (pItem->wMask & CBEXIM_FLAGS) { cbex->pItems[pItem->iItem].wFlags = pItem->wFlags; CtrlContactWndProc(hwnd, CBEXM_ENABLEITEM, NULL, NULL); } return TRUE; } /** * name: CBEXM_GETITEM * desc: Get an item from the control. * If iItem member of CBEXITEM is -1, the currently selected item is returned. * param: wParam - not used * lParam - (LPCBEXITEM)&item * return: CB_ERR on failure, new item index if successful **/ case CBEXM_GETITEM: { LPCBEXITEM pItem = (LPCBEXITEM)lParam; if (!pItem || !cbex->pItems) return FALSE; // try to find item by id if ((pItem->wMask & CBEXIM_ID) && pItem->dwID != 0) { int i; for (i = 0; i < cbex->numItems; i++) { if (cbex->pItems[i].dwID == pItem->dwID) break; } pItem->iItem = i; } else if (pItem->iItem == -1) pItem->iItem = cbex->iSelectedItem; if (pItem->iItem < 0 || pItem->iItem >= cbex->numItems) return FALSE; // return only currently selected itemindex if (!pItem->wMask) return TRUE; // return the unique id if (pItem->wMask & CBEXIM_ID) pItem->dwID = cbex->pItems[pItem->iItem].dwID; // return category string if ((pItem->wMask & CBEXIM_CAT) && pItem->pszCat) { if (*cbex->pItems[pItem->iItem].szCat != 0) mir_tstrncpy(pItem->pszCat, cbex->pItems[pItem->iItem].szCat, pItem->ccCat - 1); else *pItem->pszCat = 0; } // return value string if ((pItem->wMask & CBEXIM_VAL) && pItem->pszVal) { if (cbex->pItems[pItem->iItem].pszVal) mir_tstrncpy(pItem->pszVal, cbex->pItems[pItem->iItem].pszVal, pItem->ccVal - 1); else *pItem->pszVal = 0; } // return the icon if (pItem->wMask & CBEXIM_ICONTEXT) pItem->pszIcon = cbex->pItems[pItem->iItem].pszIcon; // return the flags if (pItem->wMask & CBEXIM_FLAGS) pItem->wFlags = cbex->pItems[pItem->iItem].wFlags; return TRUE; } /** * name: CBEXM_DELITEM * desc: delete an item from the control * param: wParam - not used * lParam - item index * return: CB_ERR on failure, new item index if successful **/ case CBEXM_DELITEM: { if (!cbex->pItems || (int)lParam < 0 || (int)lParam >= cbex->numItems || (cbex->pItems[lParam].wFlags & CBEXIF_CATREADONLY)) return FALSE; MIR_FREE(cbex->pItems[(int)lParam].pszVal); memmove(cbex->pItems + (int)lParam, cbex->pItems + (int)lParam + 1, (cbex->numItems - (int)lParam - 1) * sizeof(CBEXITEMINTERN)); cbex->numItems--; memset((cbex->pItems + cbex->numItems), 0, sizeof(CBEXITEMINTERN)); CtrlContactWndProc(hwnd, CBEXM_SETCURSEL, lParam - 1, FALSE); return TRUE; } /** * name: CBEXM_DELITEM * desc: delete an item from the control * param: wParam - not used * lParam - item index * return: CB_ERR on failure, new item index if successful **/ case CBEXM_DELALLITEMS: { int i; if (PtrIsValid(cbex)) { if (PtrIsValid(cbex->pItems)) { for (i = 0; i < cbex->numItems; i++) { MIR_FREE(cbex->pItems[i].pszVal); } MIR_FREE(cbex->pItems); cbex->pItems = NULL; } cbex->numItems = 0; cbex->iSelectedItem = -1; SetWindowText(cbex->hEdit, _T("")); SetWindowText(cbex->hBtnEdit, _T("")); SendMessage(cbex->hBtnEdit, WM_SETICON, NULL, NULL); } return TRUE; } /** * name: CBEXM_ENABLEITEM * desc: enables or disables the current item * param: wParam - not used * lParam - not used * return: always 0 **/ case CBEXM_ENABLEITEM: if (cbex->iSelectedItem >= 0 && cbex->iSelectedItem < cbex->numItems) { MCONTACT hContact; BYTE bEnabled; PSGetContact(GetParent(hwnd), hContact); bEnabled = !hContact || (cbex->pItems[cbex->iSelectedItem].wFlags & CTRLF_HASCUSTOM) || !(cbex->pItems[cbex->iSelectedItem].wFlags & (CTRLF_HASPROTO|CTRLF_HASMETA)) || !db_get_b(NULL, MODNAME, SET_PROPSHEET_PCBIREADONLY, 0); EnableWindow(cbex->hBtnEdit, bEnabled); EnableWindow(cbex->hBtnDel, bEnabled && GetWindowTextLength(cbex->hEdit) > 0); EnableWindow(cbex->hEdit, bEnabled); } break; /** * name: CBEXM_ISCHANGED * desc: returns whether the control contains changed values or not * param: wParam - not used * lParam - not used * return: TRUE if control was changed, FALSE if nothing was edited **/ case CBEXM_ISCHANGED: return cbex->bIsChanged; /** * name: CBEXM_RESETCHANGED * desc: resets changed flag to FALSE * param: wParam - not used * lParam - not used * return: always FALSE **/ case CBEXM_RESETCHANGED: cbex->bIsChanged = 0; return 0; /** * name: CBEXM_SETCURSEL * desc: selects a certain item * param: wParam - index of the item to select * lParam - (BYTE)bValid - if TRUE, the next item with a value is selected * return: always FALSE **/ case CBEXM_SETCURSEL: { int i; if (!cbex->pItems) return 1; if ((int)wParam < 0 || (int)wParam >= cbex->numItems) wParam = max(cbex->iSelectedItem, 0); cbex->bLocked = 1; if ((BYTE)lParam == TRUE) { i = (int)wParam; cbex->iSelectedItem = (int)wParam; while (i < cbex->numItems) { if (cbex->pItems[i].pszVal && *cbex->pItems[i].pszVal) { cbex->iSelectedItem = i; break; } i++; } } else { // search for the next none deleted item for (i = (int)wParam; i < cbex->numItems && *cbex->pItems[i].szCat == 0; i++); if (i == cbex->numItems && (int)wParam > 0) { for (i = 0; i < (int)wParam && *cbex->pItems[i].szCat == 0; i++); cbex->iSelectedItem = i == (int)wParam ? 0 : i; } else cbex->iSelectedItem = i; } SetWindowText(cbex->hBtnEdit, cbex->pItems[cbex->iSelectedItem].szCat); SetWindowText(cbex->hEdit, cbex->pItems[cbex->iSelectedItem].pszVal ? cbex->pItems[cbex->iSelectedItem].pszVal : _T("")); SendMessage(cbex->hBtnEdit, BM_SETIMAGE, IMAGE_ICON, (LPARAM)cbex->pItems[cbex->iSelectedItem].hIcon); CtrlContactWndProc(hwnd, CBEXM_ENABLEITEM, NULL, NULL); cbex->bLocked = 0; return 0; } case CBEXM_SORT: if (cbex->numItems > 4) { qsort(cbex->pItems + 3, cbex->numItems - 3, sizeof(CBEXITEMINTERN), compareProc); } return 0; case WM_ERASEBKGND: return 1; case WM_SETFOCUS: SetFocus(cbex->hEdit); SendMessage(cbex->hEdit, EM_SETSEL, 0, (LPARAM)-1); return 0; } return DefWindowProc(hwnd, msg, wParam, lParam); }
/** * name: ProfileList_BeginLabelEdit * desc: create an edit control to edit the label of the selected item * param: pList - handle to listview control's info structure * iItem - item index * iSubItem - subitem (column) index * return: handle to the edit control **/ static HWND ProfileList_BeginLabelEdit(LPLISTCTRL pList, INT iItem, INT iSubItem) { LVITEM lvi; LPLCITEM pItem; HANDLE hContact; RECT rcList; if (!PtrIsValid(pList)) return NULL; if (pList->labelEdit.hEdit) ProfileList_EndLabelEdit(pList, FALSE); lvi.mask = LVIF_PARAM|LVIF_STATE; lvi.stateMask = 0xFFFFFFFF; lvi.iItem = iItem; lvi.iSubItem = iSubItem; if (!ListView_GetItem(pList->hList, &lvi)) return NULL; pItem = (LPLCITEM)lvi.lParam; PSGetContact(GetParent(pList->hList), hContact); // do not edit deviders or protocol based contact information if (!(lvi.state & LVIS_SELECTED) || !PtrIsValid(pItem) || (hContact && (pItem->wFlags & CTRLF_HASPROTO))) return NULL; ListView_EnsureVisible(pList->hList, iItem, FALSE); ListView_GetSubItemRect(pList->hList, iItem, iSubItem, LVIR_BOUNDS, &pList->labelEdit.rcCombo); if (lvi.iSubItem == 0) { RECT rc2; ListView_GetSubItemRect(pList->hList, iItem, 1, LVIR_BOUNDS, &rc2); pList->labelEdit.rcCombo.right = rc2.left; } GetClientRect(pList->hList, &rcList); pList->labelEdit.rcCombo.right = min(pList->labelEdit.rcCombo.right, rcList.right); pList->labelEdit.rcCombo.left = max(pList->labelEdit.rcCombo.left, rcList.left); InflateRect(&pList->labelEdit.rcCombo, -1, -1); // create the button control for the combobox if (!iSubItem && pItem->idstrList) { pList->labelEdit.hBtn = CreateWindowEx(WS_EX_NOPARENTNOTIFY, UINFOBUTTONCLASS, NULL, WS_VISIBLE|WS_CHILD|MBS_DOWNARROW, pList->labelEdit.rcCombo.right - (pList->labelEdit.rcCombo.bottom - pList->labelEdit.rcCombo.top), pList->labelEdit.rcCombo.top, pList->labelEdit.rcCombo.bottom - pList->labelEdit.rcCombo.top, pList->labelEdit.rcCombo.bottom - pList->labelEdit.rcCombo.top, pList->hList, NULL, ghInst, NULL); if (pList->labelEdit.hBtn) { SetWindowLongPtr(pList->labelEdit.hBtn, GWLP_ID, BTN_EDIT); pList->labelEdit.rcCombo.right -= pList->labelEdit.rcCombo.bottom - pList->labelEdit.rcCombo.top; } } else { pList->labelEdit.rcCombo.bottom = 3 * pList->labelEdit.rcCombo.bottom - 2 * pList->labelEdit.rcCombo.top; if (rcList.bottom < pList->labelEdit.rcCombo.bottom) { OffsetRect(&pList->labelEdit.rcCombo, 0, rcList.bottom - pList->labelEdit.rcCombo.bottom - 2); } } // create the edit control pList->labelEdit.hEdit = CreateWindowEx(WS_EX_NOPARENTNOTIFY|WS_EX_CLIENTEDGE, _T("EDIT"), (!iSubItem && pItem->idstrList && pItem->iListItem > 0 && pItem->iListItem < pItem->idstrListCount) ? pItem->idstrList[pItem->iListItem].ptszTranslated : (iSubItem >= 0 && iSubItem < 2 && pItem->pszText[iSubItem] && *pItem->pszText[iSubItem]) ? pItem->pszText[iSubItem] : _T(""), WS_VISIBLE|WS_CHILD|(iSubItem ? (WS_VSCROLL|ES_MULTILINE|ES_AUTOVSCROLL) : ES_AUTOHSCROLL), pList->labelEdit.rcCombo.left, pList->labelEdit.rcCombo.top, pList->labelEdit.rcCombo.right - pList->labelEdit.rcCombo.left, pList->labelEdit.rcCombo.bottom - pList->labelEdit.rcCombo.top, pList->hList, NULL, ghInst, NULL); if (!pList->labelEdit.hEdit) return NULL; SendMessage(pList->labelEdit.hEdit, WM_SETFONT, (WPARAM)(pList->hFont), 0); SendMessage(pList->labelEdit.hEdit, EM_SETSEL, 0, (LPARAM)-1); SetUserData(pList->labelEdit.hEdit, pList); pList->labelEdit.dropDown.iItem = pItem->iListItem; pList->labelEdit.iItem = iItem; pList->labelEdit.iSubItem = iSubItem; pList->labelEdit.iTopIndex = ListView_GetTopIndex(pList->hList); pList->labelEdit.pItem = pItem; SetFocus(pList->labelEdit.hEdit); OldEditProc = (WNDPROC)SetWindowLongPtr(pList->labelEdit.hEdit, GWLP_WNDPROC, (LONG_PTR)ProfileList_LabelEditProc); return pList->labelEdit.hEdit; }
/** * Dialog procedure for the about/nodes information propertysheetpage * * @param hDlg - handle to the dialog window * @param uMsg - the message to handle * @param wParam - parameter * @param lParam - parameter * * @return different values **/ INT_PTR CALLBACK PSPProcEdit(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam, const CHAR *pszSetting) { switch (uMsg) { case WM_INITDIALOG: { CCtrlList *pCtrlList = CCtrlList::CreateObj(hDlg); if (pCtrlList) { HFONT hBoldFont; PSGetBoldFont(hDlg, hBoldFont); SendDlgItemMessage(hDlg, IDC_PAGETITLE, WM_SETFONT, (WPARAM)hBoldFont, 0); if (!mir_strcmp(pszSetting, SET_CONTACT_MYNOTES)) SetDlgItemText(hDlg, IDC_PAGETITLE, LPGENT("My notes:")); else SetDlgItemText(hDlg, IDC_PAGETITLE, LPGENT("About:")); TranslateDialogDefault(hDlg); pCtrlList->insert(CEditCtrl::CreateObj(hDlg, EDIT_ABOUT, pszSetting, DBVT_TCHAR)); // remove static edge in aero mode if (IsAeroMode()) SetWindowLongPtr(GetDlgItem(hDlg, EDIT_ABOUT), GWL_EXSTYLE, GetWindowLongPtr(GetDlgItem(hDlg, EDIT_ABOUT), GWL_EXSTYLE) & ~WS_EX_STATICEDGE); SendDlgItemMessage(hDlg, EDIT_ABOUT, EM_SETEVENTMASK, 0, /*ENM_KEYEVENTS | */ENM_LINK | ENM_CHANGE); SendDlgItemMessage(hDlg, EDIT_ABOUT, EM_AUTOURLDETECT, TRUE, NULL); if (!lParam) SendDlgItemMessage(hDlg, EDIT_ABOUT, EM_LIMITTEXT, 1024, NULL); } } break; case WM_NOTIFY: { switch (((LPNMHDR)lParam)->idFrom) { // notification handler for richedit control case EDIT_ABOUT: { switch (((LPNMHDR)lParam)->code) { // notification handler for a link within the richedit control case EN_LINK: return CEditCtrl::GetObj(((LPNMHDR)lParam)->hwndFrom)->LinkNotificationHandler((ENLINK *)lParam); } } return FALSE; } } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case EDIT_ABOUT: { if (HIWORD(wParam) == EN_CHANGE) { CBaseCtrl *pResult; pResult = CBaseCtrl::GetObj((HWND)lParam); if (PtrIsValid(pResult) && (pResult->_cbSize == sizeof(CBaseCtrl))) pResult->OnChangedByUser(HIWORD(wParam)); } } } } return FALSE; } return PSPBaseProc(hDlg, 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; }
/** * name: DlgProcPspAbout() * desc: dialog procedure * * return: 0 or 1 **/ INT_PTR CALLBACK PSPProcContactProfile(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { HWND hList = GetDlgItem(hDlg, LIST_PROFILE); LPLISTCTRL pList; switch (uMsg) { case WM_INITDIALOG: { LVCOLUMN lvc; RECT rc; LOGFONT lf; HFONT hFont; TOOLINFO ti; if (!hList || !(pList = (LPLISTCTRL)mir_alloc(sizeof(LISTCTRL)))) return FALSE; ZeroMemory(pList, sizeof(LISTCTRL)); TranslateDialogDefault(hDlg); Ctrl_InitTextColours(); // init info structure pList->hList = hList; pList->nType = CTRL_LIST_PROFILE; ZeroMemory(&pList->labelEdit, sizeof(pList->labelEdit)); SetUserData(hList, pList); // set new window procedure OldListViewProc = (WNDPROC)SetWindowLongPtr(hList, GWLP_WNDPROC, (LONG_PTR)&ProfileList_SubclassProc); // remove static edge in aero mode if (IsAeroMode()) SetWindowLongPtr(hList, GWL_EXSTYLE, GetWindowLongPtr(hList, GWL_EXSTYLE)&~WS_EX_STATICEDGE); // insert columns into the listboxes ListView_SetExtendedListViewStyle(hList, LVS_EX_FULLROWSELECT); PSGetBoldFont(hDlg, hFont); SendDlgItemMessage(hDlg, IDC_PAGETITLE, WM_SETFONT, (WPARAM)hFont, 0); // set listfont pList->hFont = (HFONT)SendMessage(hList, WM_GETFONT, 0, 0); pList->wFlags |= LVF_EDITLABEL; GetObject(pList->hFont, sizeof(lf), &lf); lf.lfHeight -= 6; hFont = CreateFontIndirect(&lf); SendMessage(hList, WM_SETFONT, (WPARAM)hFont, 0); GetClientRect(hList, &rc); rc.right -= GetSystemMetrics(SM_CXVSCROLL); // initiate the tooltips pList->hTip = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, NULL, WS_POPUP|TTS_BALLOON|TTS_NOPREFIX|TTS_ALWAYSTIP, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hList, NULL, ghInst, NULL); if (pList->hTip) { SetWindowPos(pList->hTip, HWND_TOPMOST, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); ZeroMemory(&ti, sizeof(TOOLINFO)); ti.cbSize = sizeof(TOOLINFO); ti.uFlags = TTF_IDISHWND|TTF_SUBCLASS|TTF_TRANSPARENT; ti.hinst = ghInst; ti.hwnd = hList; ti.uId = (UINT_PTR)hList; SendMessage(pList->hTip, TTM_ADDTOOL, NULL, (LPARAM)&ti); SendMessage(pList->hTip, TTM_ACTIVATE, FALSE, (LPARAM)&ti); } // insert columns into the listboxes lvc.mask = LVCF_WIDTH; lvc.cx = rc.right / 8 * 3; ListView_InsertColumn(hList, 0, &lvc); lvc.cx = rc.right / 8 * 5; ListView_InsertColumn(hList, 1, &lvc); return TRUE; } case WM_CTLCOLORSTATIC: case WM_CTLCOLORDLG: if (IsAeroMode()) return (INT_PTR)GetStockBrush(WHITE_BRUSH); break; case WM_NOTIFY: switch (((LPNMHDR)lParam)->idFrom) { case 0: { HANDLE hContact = (HANDLE)((LPPSHNOTIFY)lParam)->lParam; LPCSTR pszProto; if (!PtrIsValid(pList = (LPLISTCTRL)GetUserData(hList))) break; switch (((LPNMHDR)lParam)->code) { // some account data may have changed so reread database case PSN_INFOCHANGED: { BYTE msgResult = 0; LPIDSTRLIST idList; UINT nList; BYTE i; INT iItem = 0, iGrp = 0, numProtoItems, numUserItems; if (!(pList->wFlags & CTRLF_CHANGED) && PSGetBaseProto(hDlg, pszProto) && *pszProto != 0) { ProfileList_Clear(hList); // insert the past information for (i = 0; i < 3; i++) { pFmt[i].GetList((WPARAM)&nList, (LPARAM)&idList); if ((numProtoItems = ProfileList_AddItemlistFromDB(pList, iItem, idList, nList, hContact, pszProto, pFmt[i].szCatFmt, pFmt[i].szValFmt, CTRLF_HASPROTO)) < 0) return FALSE; // scan all basic protocols for the subcontacts if (DB::Module::IsMetaAndScan(pszProto)) { INT iDefault = CallService(MS_MC_GETDEFAULTCONTACTNUM, (WPARAM)hContact, NULL); HANDLE hSubContact, hDefContact; LPCSTR pszSubBaseProto; INT j, numSubs; if ((hDefContact = (HANDLE)CallService(MS_MC_GETSUBCONTACT, (WPARAM)hContact, iDefault)) && (pszSubBaseProto = DB::Contact::Proto(hDefContact))) { if ((numProtoItems += ProfileList_AddItemlistFromDB(pList, iItem, idList, nList, hDefContact, pszSubBaseProto, pFmt[i].szCatFmt, pFmt[i].szValFmt, CTRLF_HASMETA|CTRLF_HASPROTO)) < 0) return FALSE; // copy the missing settings from the other subcontacts numSubs = CallService(MS_MC_GETNUMCONTACTS, (WPARAM)hContact, NULL); for (j = 0; j < numSubs; j++) { if (j == iDefault) continue; if (!(hSubContact = (HANDLE)CallService(MS_MC_GETSUBCONTACT, (WPARAM)hContact, j))) continue; if (!(pszSubBaseProto = DB::Contact::Proto(hSubContact))) continue; if ((numProtoItems += ProfileList_AddItemlistFromDB(pList, iItem, idList, nList, hSubContact, pszSubBaseProto, pFmt[i].szCatFmt, pFmt[i].szValFmt, CTRLF_HASMETA|CTRLF_HASPROTO)) < 0) return FALSE; //if ((numUserItems += ProfileList_AddItemlistFromDB(pList, iItem, idList, nList, hSubContact, USERINFO, pFmt[i].szCatFmt, pFmt[i].szValFmt, CTRLF_HASMETA|CTRLF_HASPROTO)) < 0) // return FALSE; } } } if ((numUserItems = ProfileList_AddItemlistFromDB(pList, iItem, idList, nList, hContact, USERINFO, pFmt[i].szCatFmt, pFmt[i].szValFmt, CTRLF_HASCUSTOM)) < 0) return FALSE; if (numUserItems || numProtoItems) { msgResult = PSP_CHANGED; ProfileList_AddGroup(hList, pFmt[i].szGroup, iGrp); iGrp = ++iItem; } } } SetWindowLongPtr(hDlg, DWLP_MSGRESULT, msgResult); break; } // user swiches to another propertysheetpage case PSN_KILLACTIVE: ProfileList_EndLabelEdit(hList, TRUE); break; // user selected to apply settings to the database case PSN_APPLY: if (pList->wFlags & CTRLF_CHANGED) { BYTE iFmt = -1; INT iItem; LVITEM lvi; TCHAR szGroup[MAX_PATH]; CHAR pszSetting[MAXSETTING]; LPLCITEM pItem; LPSTR pszModule = USERINFO; if (!hContact) PSGetBaseProto(hDlg, pszModule); *szGroup = 0; lvi.mask = LVIF_TEXT|LVIF_PARAM; lvi.pszText = szGroup; lvi.cchTextMax = MAX_PATH; for (iItem = lvi.iItem = lvi.iSubItem = 0; ListView_GetItem(hList, &lvi); lvi.iItem++) { if (!PtrIsValid(pItem = (LPLCITEM)lvi.lParam)) { // delete reluctant items if (iFmt >= 0 && iFmt < SIZEOF(pFmt)) { DB::Setting::DeleteArray(hContact, pszModule, pFmt[iFmt].szCatFmt, iItem); DB::Setting::DeleteArray(hContact, pszModule, pFmt[iFmt].szValFmt, iItem); } // find information about the group for (iFmt = 0; iFmt < SIZEOF(pFmt); iFmt++) { if (!_tcscmp(szGroup, pFmt[iFmt].szGroup)) { break; } } // indicate, no group was found. should not happen!! if (iFmt == SIZEOF(pFmt)) { *szGroup = 0; iFmt = -1; } iItem = 0; } else if (iFmt >= 0 && iFmt < SIZEOF(pFmt)) { // save value if (!pItem->pszText[1] || !*pItem->pszText[1]) continue; if (!(pItem->wFlags & (CTRLF_HASPROTO|CTRLF_HASMETA))) { mir_snprintf(pszSetting, MAXSETTING, pFmt[iFmt].szValFmt, iItem); DB::Setting::WriteTString(hContact, pszModule, pszSetting, pItem->pszText[1]); // save category mir_snprintf(pszSetting, MAXSETTING, pFmt[iFmt].szCatFmt, iItem); if (pItem->idstrList && pItem->iListItem > 0 && pItem->iListItem < pItem->idstrListCount) DB::Setting::WriteAString(hContact, pszModule, pszSetting, (LPSTR)pItem->idstrList[pItem->iListItem].pszText); else if (pItem->pszText[0] && *pItem->pszText[0]) DB::Setting::WriteTString(hContact, pszModule, pszSetting, (LPTSTR)pItem->pszText[0]); else DB::Setting::Delete(hContact, pszModule, pszSetting); // redraw the item if required if (pItem->wFlags & CTRLF_CHANGED) { pItem->wFlags &= ~CTRLF_CHANGED; ListView_RedrawItems(hList, lvi.iItem, lvi.iItem); } iItem++; } } } // delete reluctant items if (iFmt >= 0 && iFmt < SIZEOF(pFmt)) { DB::Setting::DeleteArray(hContact, pszModule, pFmt[iFmt].szCatFmt, iItem); DB::Setting::DeleteArray(hContact, pszModule, pFmt[iFmt].szValFmt, iItem); } pList->wFlags &= ~CTRLF_CHANGED; } break; } break; } // // handle notification messages from the list control // case LIST_PROFILE: { LPLISTCTRL pList = (LPLISTCTRL)GetUserData(((LPNMHDR)lParam)->hwndFrom); switch (((LPNMHDR)lParam)->code) { case NM_RCLICK: { HMENU hMenu = CreatePopupMenu(); MENUITEMINFO mii; HANDLE hContact; LVHITTESTINFO hi; LPLCITEM pItem; POINT pt; if (!hMenu) return 1; PSGetContact(hDlg, hContact); GetCursorPos(&pt); hi.pt = pt; ScreenToClient(((LPNMHDR)lParam)->hwndFrom, &hi.pt); ListView_SubItemHitTest(((LPNMHDR)lParam)->hwndFrom, &hi); pItem = ProfileList_GetItemData(((LPNMHDR)lParam)->hwndFrom, hi.iItem); // insert menuitems ZeroMemory(&mii, sizeof(MENUITEMINFO)); mii.cbSize = sizeof(MENUITEMINFO); mii.fMask = MIIM_ID|MIIM_STRING; // insert "Add" Menuitem mii.wID = BTN_ADD_intEREST; mii.dwTypeData = TranslateT("Add Interest"); InsertMenuItem(hMenu, 0, TRUE, &mii); mii.wID = BTN_ADD_AFFLIATION; mii.dwTypeData = TranslateT("Add Affliation"); InsertMenuItem(hMenu, 1, TRUE, &mii); mii.wID = BTN_ADD_PAST; mii.dwTypeData = TranslateT("Add Past"); InsertMenuItem(hMenu, 2, TRUE, &mii); if (hi.iItem != -1 && PtrIsValid(pItem) && !(hContact && (pItem->wFlags & CTRLF_HASPROTO))) { // insert separator mii.fMask = MIIM_FTYPE; mii.fType = MFT_SEPARATOR; InsertMenuItem(hMenu, 3, TRUE, &mii); // insert "Delete" Menuitem mii.fMask = MIIM_ID|MIIM_STRING; mii.wID = BTN_EDIT_CAT; mii.dwTypeData = TranslateT("Edit Category"); InsertMenuItem(hMenu, 4, TRUE, &mii); mii.wID = BTN_EDIT_VAL; mii.dwTypeData = TranslateT("Edit Value"); InsertMenuItem(hMenu, 5, TRUE, &mii); mii.fMask = MIIM_FTYPE; mii.fType = MFT_SEPARATOR; InsertMenuItem(hMenu, 6, TRUE, &mii); // insert "Delete" Menuitem mii.fMask = MIIM_ID|MIIM_STRING; mii.wID = BTN_DEL; mii.dwTypeData = TranslateT("Delete"); InsertMenuItem(hMenu, 7, TRUE, &mii); } TrackPopupMenu(hMenu, 0, pt.x, pt.y, 0, hDlg, 0); DestroyMenu(hMenu); return 0; } /*case LVN_BEGINSCROLL: SetFocus(((LPNMHDR)lParam)->hwndFrom); break; */ case LVN_GETDISPINFO: if (pList->labelEdit.iTopIndex != ListView_GetTopIndex(hList)) ProfileList_EndLabelEdit(((LPNMHDR)lParam)->hwndFrom, FALSE); break; case NM_CUSTOMDRAW: { LPNMLVCUSTOMDRAW cd = (LPNMLVCUSTOMDRAW)lParam; LPLCITEM pItem = (LPLCITEM)cd->nmcd.lItemlParam; RECT rc; switch (cd->nmcd.dwDrawStage) { case CDDS_PREPAINT: SetWindowLongPtr(hDlg, DWLP_MSGRESULT, CDRF_NOTIFYITEMDRAW); return TRUE; case CDDS_ITEMPREPAINT: ListView_GetItemRect(cd->nmcd.hdr.hwndFrom, cd->nmcd.dwItemSpec, &rc, LVIR_BOUNDS); if (!PtrIsValid(pItem)) { HFONT hBold, hFont; TCHAR szText[MAX_PATH]; PSGetBoldFont(hDlg, hBold); hFont = (HFONT)SelectObject(cd->nmcd.hdc, hBold); SetTextColor(cd->nmcd.hdc, GetSysColor(COLOR_3DSHADOW)); ProfileList_GetItemText(cd->nmcd.hdr.hwndFrom, cd->nmcd.dwItemSpec, 0, szText, MAX_PATH); rc.left += 6; DrawText(cd->nmcd.hdc, TranslateTS(szText), -1, &rc, DT_NOCLIP|DT_NOPREFIX|DT_SINGLELINE|DT_VCENTER); rc.bottom -= 2; rc.top = rc.bottom - 1; rc.left -= 6; DrawEdge(cd->nmcd.hdc, &rc, BDR_SUNKENOUTER, BF_RECT); SelectObject(cd->nmcd.hdc, hFont); SetWindowLongPtr(hDlg, DWLP_MSGRESULT, CDRF_SKIPDEFAULT); return TRUE; } // draw selected item if ((cd->nmcd.uItemState & CDIS_SELECTED) || (pList->labelEdit.iItem == cd->nmcd.dwItemSpec)) { SetTextColor(cd->nmcd.hdc, GetSysColor(COLOR_HIGHLIGHTTEXT)); FillRect(cd->nmcd.hdc, &rc, GetSysColorBrush(COLOR_HIGHLIGHT)); } // draw background of unselected item else { SetTextColor(cd->nmcd.hdc, (pItem->wFlags & CTRLF_CHANGED) ? clrChanged : (pItem->wFlags & CTRLF_HASMETA) ? clrMeta : ((pItem->wFlags & (CTRLF_HASCUSTOM)) && (pItem->wFlags & CTRLF_HASPROTO)) ? clrBoth : (pItem->wFlags & CTRLF_HASCUSTOM) ? clrCustom : clrNormal); FillRect(cd->nmcd.hdc, &rc, GetSysColorBrush(COLOR_WINDOW)); } SetWindowLongPtr(hDlg, DWLP_MSGRESULT, CDRF_NEWFONT|CDRF_NOTIFYSUBITEMDRAW); return TRUE; case CDDS_SUBITEM|CDDS_ITEMPREPAINT: { HFONT hoFont = (HFONT)SelectObject(cd->nmcd.hdc, pList->hFont); ListView_GetSubItemRect(cd->nmcd.hdr.hwndFrom, cd->nmcd.dwItemSpec, cd->iSubItem, LVIR_BOUNDS, &rc); if (cd->iSubItem == 0) { RECT rc2; ListView_GetSubItemRect(cd->nmcd.hdr.hwndFrom, cd->nmcd.dwItemSpec, 1, LVIR_BOUNDS, &rc2); rc.right = rc2.left; } rc.left += 3; DrawText(cd->nmcd.hdc, pItem->pszText[cd->iSubItem] ? pItem->pszText[cd->iSubItem] : (cd->iSubItem == 0 && pItem->idstrList && pItem->iListItem > 0 && pItem->iListItem < pItem->idstrListCount) ? pItem->idstrList[pItem->iListItem].ptszTranslated : TranslateT("<empty>"), -1, &rc, DT_END_ELLIPSIS|DT_NOCLIP|DT_NOPREFIX|DT_SINGLELINE|DT_VCENTER); SetWindowLongPtr(hDlg, DWLP_MSGRESULT, CDRF_SKIPDEFAULT); return TRUE; } } /* switch (cd->nmcd.dwDrawStage) */ break; } /* case NM_CUSTOMDRAW: */ } /* (((LPNMHDR)lParam)->code) */ break; } } break; /* case WM_NOTIFY: */ case WM_COMMAND: { switch (LOWORD(wParam)) { case BTN_ADD_intEREST: return ProfileList_AddNewItem(hDlg, (LPLISTCTRL)GetUserData(hList), &pFmt[2]); case BTN_ADD_AFFLIATION: return ProfileList_AddNewItem(hDlg, (LPLISTCTRL)GetUserData(hList), &pFmt[1]); case BTN_ADD_PAST: return ProfileList_AddNewItem(hDlg, (LPLISTCTRL)GetUserData(hList), &pFmt[0]); case BTN_EDIT_CAT: ProfileList_BeginLabelEdit(hList, ListView_GetSelectionMark(hList), 0); break; case BTN_EDIT_VAL: ProfileList_BeginLabelEdit(hList, ListView_GetSelectionMark(hList), 1); break; case BTN_DEL: if (IDYES == MsgBox(hDlg, MB_YESNO|MB_ICON_QUESTION, LPGENT("Question"), LPGENT("Delete an entry"), LPGENT("Do you really want to delete this entry?"))) { INT iItem = ListView_GetSelectionMark(hList); LPLISTCTRL pList = (LPLISTCTRL)GetUserData(hList); ProfileList_DeleteItem(hList, iItem); if (PtrIsValid(pList)) pList->wFlags |= CTRLF_CHANGED; SendMessage(GetParent(hDlg), PSM_CHANGED, NULL, NULL); // check if to delete any devider if (!ProfileList_GetItemData(hList, iItem--) && !ProfileList_GetItemData(hList, iItem)) ListView_DeleteItem(hList, iItem); } break; } break; } } return FALSE; }
/** * Dialog procedure for the anniversary add/edit dialog * * @param hDlg - handle to the dialog window * @param uMsg - the message to handle * @param wParam - parameter * @param lParam - parameter * * @return different values **/ static INT_PTR CALLBACK DlgProc_AnniversaryEditor(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { MAnnivDate *pDlgEditAnniv = (MAnnivDate *)GetUserData(hDlg); switch (uMsg) { case WM_INITDIALOG: pDlgEditAnniv = (MAnnivDate *)lParam; if (!PtrIsValid(pDlgEditAnniv)) break; SetUserData(hDlg, lParam); // set icons if (db_get_b(NULL, MODNAME, SET_ICONS_BUTTONS, 1)) { SendDlgItemMessage(hDlg, IDOK, BM_SETIMAGE, IMAGE_ICON, (LPARAM)IcoLib_GetIcon(ICO_BTN_OK)); SendDlgItemMessage(hDlg, IDCANCEL, BM_SETIMAGE, IMAGE_ICON, (LPARAM)IcoLib_GetIcon(ICO_BTN_CANCEL)); } SendDlgItemMessage(hDlg, IDC_HEADERBAR, WM_SETICON, 0, (LPARAM)IcoLib_GetIcon(ICO_DLG_ANNIVERSARY, TRUE)); // translate controls SendDlgItemMessage(hDlg, IDOK, BUTTONTRANSLATE, NULL, NULL); SendDlgItemMessage(hDlg, IDCANCEL, BUTTONTRANSLATE, NULL, NULL); TranslateDialogDefault(hDlg); // init controls EnableWindow(GetDlgItem(hDlg, EDIT_CATEGORY), pDlgEditAnniv->Id() != ANID_BIRTHDAY); SetDlgItemText(hDlg, EDIT_CATEGORY, pDlgEditAnniv->Description()); return TRUE; case WM_CTLCOLORSTATIC: SetBkColor((HDC)wParam, RGB(255, 255, 255)); return (INT_PTR)GetStockObject(WHITE_BRUSH); case WM_COMMAND: switch (LOWORD(wParam)) { case EDIT_CATEGORY: if (HIWORD(wParam) == EN_UPDATE) EnableWindow(GetDlgItem(hDlg, IDOK), GetWindowTextLength((HWND)lParam) > 0); break; case IDOK: { // read new description HWND hEdit = GetDlgItem(hDlg, EDIT_CATEGORY); int len = Edit_GetTextLength(hEdit); LPTSTR pszText; if (len == 0 || (pszText = (LPTSTR)_alloca((len + 1) * sizeof(TCHAR))) == NULL || !Edit_GetText(hEdit, pszText, len + 1)) { MsgErr(hDlg, LPGENT("Please enter a valid description first!")); break; } if (mir_tstrcmpi(pszText, pDlgEditAnniv->Description())) { pDlgEditAnniv->Description(pszText); pDlgEditAnniv->SetFlags(MAnnivDate::MADF_HASCUSTOM | MAnnivDate::MADF_CHANGED); } } // fall through case IDCANCEL: return EndDialog(hDlg, LOWORD(wParam)); } } return FALSE; }
INT_PTR CALLBACK PSPProcAnniversary(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { CAnnivEditCtrl *pDateCtrl = CAnnivEditCtrl::GetObj(hDlg, EDIT_ANNIVERSARY_DATE); switch (uMsg) { case WM_INITDIALOG: { CCtrlList *pCtrlList = CCtrlList::CreateObj(hDlg); if (pCtrlList) { HFONT hBoldFont; PSGetBoldFont(hDlg, hBoldFont); SendDlgItemMessage(hDlg, IDC_PAGETITLE, WM_SETFONT, (WPARAM)hBoldFont, 0); TranslateDialogDefault(hDlg); pCtrlList->insert(CEditCtrl::CreateObj(hDlg, EDIT_AGE, SET_CONTACT_AGE, DBVT_BYTE)); pCtrlList->insert(CAnnivEditCtrl::CreateObj(hDlg, EDIT_ANNIVERSARY_DATE, NULL)); // hContact == NULL or reminder disabled CAnnivEditCtrl::GetObj(hDlg, EDIT_ANNIVERSARY_DATE)->EnableReminderCtrl(lParam != NULL); SendDlgItemMessage(hDlg, EDIT_AGE, EM_LIMITTEXT, 3, 0); SendDlgItemMessage(hDlg, SPIN_AGE, UDM_SETRANGE32, 0, 200); } } break; case WM_NOTIFY: switch (((LPNMHDR)lParam)->idFrom) { case 0: switch (((LPNMHDR)lParam)->code) { case PSN_ICONCHANGED: { const ICONCTRL idIcon[] = { { ICO_COMMON_BIRTHDAY, STM_SETIMAGE, ICO_BIRTHDAY }, { ICO_BTN_ADD, BM_SETIMAGE, BTN_ADD }, { ICO_BTN_DELETE, BM_SETIMAGE, BTN_DELETE } }; IcoLib_SetCtrlIcons(hDlg, idIcon, _countof(idIcon)); } return FALSE; } break; /* case 0 */ case EDIT_ANNIVERSARY_DATE: if (!PspIsLocked(hDlg) && PtrIsValid(pDateCtrl)) { LPNMHDR lpNmhdr = (LPNMHDR)lParam; switch (lpNmhdr->code) { case DTN_DATETIMECHANGE: pDateCtrl->OnDateChanged((LPNMDATETIMECHANGE)lParam); break; case DTN_DROPDOWN: HWND hMonthCal = DateTime_GetMonthCal(lpNmhdr->hwndFrom); SetWindowLongPtr(hMonthCal, GWL_STYLE, GetWindowLongPtr(hMonthCal, GWL_STYLE) | MCS_WEEKNUMBERS); InvalidateRect(hMonthCal, NULL, TRUE); } } return FALSE; } break; case WM_COMMAND: switch (LOWORD(wParam)) { case EDIT_REMIND: if (!PspIsLocked(hDlg) && HIWORD(wParam) == EN_UPDATE) if (PtrIsValid(pDateCtrl)) pDateCtrl->OnRemindEditChanged(); return FALSE; /** * name: BTN_MENU * desc: the button to dropdown the list to show all items is pressed **/ case BTN_MENU: if (HIWORD(wParam) == BN_CLICKED) { if (PtrIsValid(pDateCtrl)) pDateCtrl->OnMenuPopup(); } return FALSE; /** * name: BTN_ADD * desc: creates a new dialog to add a new anniversary **/ case BTN_ADD: if (HIWORD(wParam) == BN_CLICKED && PtrIsValid(pDateCtrl)) { MAnnivDate Date; if (IDOK == DialogBoxParam(ghInst, MAKEINTRESOURCE(IDD_ANNIVERSARY_EDITOR), hDlg, DlgProc_AnniversaryEditor, (LPARAM)&Date)) { SendMessage(GetParent(hDlg), PSM_CHANGED, NULL, NULL); if (!pDateCtrl->AddDate(Date)) pDateCtrl->SetCurSel(pDateCtrl->NumDates() - 1); } } return FALSE; /** * name: BTN_EDIT * desc: edit the currently selected anniversary **/ case BTN_EDIT: if (HIWORD(wParam) == BN_CLICKED && PtrIsValid(pDateCtrl)) { MAnnivDate *pDate = pDateCtrl->Current(); if (!pDate) MsgErr(hDlg, LPGENT("No valid date selected for editing!")); else if ( IDOK == DialogBoxParam(ghInst, MAKEINTRESOURCE(IDD_ANNIVERSARY_EDITOR), hDlg, DlgProc_AnniversaryEditor, (LPARAM)pDate) && (pDate->Flags() & (MAnnivDate::MADF_CHANGED | MAnnivDate::MADF_REMINDER_CHANGED))) { SendMessage(GetParent(hDlg), PSM_CHANGED, NULL, NULL); pDateCtrl->SetCurSel(pDateCtrl->CurrentIndex()); } } return FALSE; /** * name: BTN_DELETE * desc: user wants to delete an anniversary **/ case BTN_DELETE: if (HIWORD(wParam) == BN_CLICKED && PtrIsValid(pDateCtrl)) { MAnnivDate *pCurrent = pDateCtrl->Current(); if (pCurrent) { int rc = MsgBox(hDlg, MB_YESNO | MB_ICON_QUESTION | MB_NOPOPUP, LPGENT("Delete"), NULL, LPGENT("Do you really want to delete the %s?"), pCurrent->Description()); if (rc == IDYES) pDateCtrl->DeleteDate(pDateCtrl->CurrentIndex()); } } return FALSE; /** * name: CHECK_REMIND * desc: state of reminder checkbox is changed **/ case RADIO_REMIND1: case RADIO_REMIND2: case RADIO_REMIND3: CAnnivEditCtrl *pDateCtrl = CAnnivEditCtrl::GetObj(hDlg, EDIT_ANNIVERSARY_DATE); if (PtrIsValid(pDateCtrl) && HIWORD(wParam) == BN_CLICKED) pDateCtrl->OnReminderChecked(); return FALSE; } /* switch (LOWORD(wParam)) */ break; } return PSPBaseProc(hDlg, uMsg, wParam, lParam); }
/** * name: ListSubclassProc * desc: procedure to catch messages for a listview control, to handle tooltips * param: hwnd - handle to the listview control's window * msg - message sent to the control * wParam - message specific parameter * lParam - message specific parameter * return: message specific **/ static INT_PTR CALLBACK ProfileList_SubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { LPLISTCTRL pList; switch (msg) { case WM_KEYDOWN: { INT nCurSel, newSel; LVITEM lvi; switch (wParam) { case VK_F2: nCurSel = ListView_GetSelectionMark(hwnd); if (nCurSel == -1) break; ProfileList_BeginLabelEdit(hwnd, nCurSel, 0); return 0; case VK_F3: nCurSel = ListView_GetSelectionMark(hwnd); if (nCurSel == -1) break; ProfileList_BeginLabelEdit(hwnd, nCurSel, 1); return 0; case VK_UP: case VK_DOWN: lvi.iItem = nCurSel = ListView_GetSelectionMark(hwnd); lvi.iSubItem = 0; // find next valid item to select lvi.mask = LVIF_PARAM; do { if (wParam == VK_UP) lvi.iItem--; else lvi.iItem++; if (lvi.iItem == -1 || !ListView_GetItem(hwnd, &lvi)) { return 0; } } while (!lvi.lParam); ListView_EnsureVisible(hwnd, lvi.iItem, FALSE); newSel = lvi.iItem; lvi.iItem = nCurSel; lvi.mask = LVIF_STATE; lvi.stateMask = LVIS_FOCUSED|LVIS_SELECTED; lvi.state = 0; ListView_SetItem(hwnd, &lvi); lvi.iItem = newSel; lvi.state = LVIS_FOCUSED|LVIS_SELECTED; ListView_SetItem(hwnd, &lvi); ListView_SetSelectionMark(hwnd, lvi.iItem); return 0; } break; } case WM_MOUSEMOVE: if (PtrIsValid(pList = (LPLISTCTRL)GetUserData(hwnd))) { HDC hDC; RECT rchWnd, rcItem; SIZE textSize; LVHITTESTINFO hi; TOOLINFO ti; BOOLEAN bReposition; LPLCITEM pItem; hi.pt.x = GET_X_LPARAM(lParam); hi.pt.y = GET_Y_LPARAM(lParam); ListView_SubItemHitTest(hwnd, &hi); // show tip only if pointer is over an item if (pList->iHotItem != hi.iItem || pList->iHotSubItem != hi.iSubItem) { bReposition = pList->iHotItem != -1 || pList->iHotSubItem != -1; pList->iHotItem = hi.iItem; pList->iHotSubItem = hi.iSubItem; if ((hi.flags & LVHT_ONITEMLABEL) && PtrIsValid(pItem = ProfileList_GetItemData(hwnd, hi.iItem))) { GetWindowRect(hwnd, &rchWnd); ListView_GetSubItemRect(hwnd, hi.iItem, hi.iSubItem, LVIR_BOUNDS, &rcItem); // calculate size of text on the screen if ((hDC = GetDC(GetParent(hwnd)))) { SelectObject(hDC, (HFONT)SendMessage(GetParent(hwnd), WM_GETFONT, NULL, NULL)); GetTextExtentPoint32(hDC, pItem->pszText[hi.iSubItem], lstrlen(pItem->pszText[hi.iSubItem]), &textSize); ReleaseDC(GetParent(hwnd), hDC); } // show tip only for text that is larger than te listview can display if (textSize.cx > rchWnd.right - rchWnd.left || textSize.cx > rcItem.right - rcItem.left) { ZeroMemory(&ti, sizeof(TOOLINFO)); ti.cbSize = sizeof(TOOLINFO); ti.uFlags = TTF_IDISHWND|TTF_SUBCLASS|TTF_TRANSPARENT; ti.hinst = ghInst; ti.hwnd = hwnd; ti.uId = (UINT_PTR)hwnd; ti.lpszText = pItem->pszText[hi.iSubItem]; ti.rect = rcItem; SendMessage(pList->hTip, TTM_SETMAXTIPWIDTH, 0, 300); SendMessage(pList->hTip, TTM_SETTOOLINFO, NULL, (LPARAM)&ti); if (pList->iHotSubItem > 0) { SendMessage(pList->hTip, TTM_SETTITLE, 1, (LPARAM) ((pItem->idstrList && pItem->iListItem > 0 && pItem->iListItem < pItem->idstrListCount) ? pItem->idstrList[pItem->iListItem].ptszTranslated : (pItem->pszText[0] && *pItem->pszText[0]) ? pItem->pszText[0] : TranslateT("<empty>")) ); InvalidateRect(pList->hTip, NULL, TRUE); } else SendMessage(pList->hTip, TTM_SETTITLE, 0, (LPARAM)""); SendMessage(pList->hTip, TTM_ACTIVATE, TRUE, (LPARAM)&ti); pList->ptTip.x = rchWnd.left + GET_X_LPARAM(lParam) - 16; pList->ptTip.y = rchWnd.top + rcItem.top; // no TTN_SHOW is called if bReposition is TRUE, so repose here! if (bReposition) { RECT rcTip; GetClientRect(pList->hTip, &rcTip); SetWindowPos(pList->hTip, hwnd, pList->ptTip.x, pList->ptTip.y - rcTip.bottom, 0, 0, SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE); } pList->wFlags |= LIF_TIPVISIBLE; return 0; } } if (pList->wFlags & LIF_TIPVISIBLE) { SendMessage(pList->hTip, TTM_ACTIVATE, FALSE, (LPARAM)&ti); pList->wFlags &= ~LIF_TIPVISIBLE; } } } return 0; // begin label edit case WM_LBUTTONDBLCLK: { LVHITTESTINFO hi; hi.pt.x = GET_X_LPARAM(lParam); hi.pt.y = GET_Y_LPARAM(lParam); if (ListView_SubItemHitTest(hwnd, &hi)) { ProfileList_BeginLabelEdit(hwnd, hi.iItem, hi.iSubItem); } return TRUE; } case WM_NOTIFY: if (!PtrIsValid(pList = (LPLISTCTRL)GetUserData(hwnd))) break; // ensure position of tooltip is on the topline of the item if (((LPNMHDR)lParam)->hwndFrom == pList->hTip) { RECT rcTip; GetClientRect(pList->hTip, &rcTip); switch (((LPNMHDR)lParam)->code) { case TTN_SHOW: SetWindowPos(pList->hTip, hwnd, pList->ptTip.x, pList->ptTip.y - rcTip.bottom, 0, 0, SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE); return TRUE; } } break; case WM_COMMAND: { switch (LOWORD(wParam)) { // show dropdown menu for category list case BTN_EDIT: { INT i; TCHAR szEdit[MAX_PATH]; if (!PtrIsValid(pList = (LPLISTCTRL)GetUserData(hwnd))) break; GetWindowText(pList->labelEdit.hEdit, szEdit, MAX_PATH); // need to create the dropdown list? if (pList->labelEdit.dropDown.hDrop == NULL) { const INT listHeight = 120; RECT rc, rcList; INT add; // dropdown rect GetClientRect(pList->hList, &rcList); rc.left = pList->labelEdit.rcCombo.left; rc.right = pList->labelEdit.rcCombo.right + pList->labelEdit.rcCombo.bottom - pList->labelEdit.rcCombo.top; if (rcList.bottom < pList->labelEdit.rcCombo.bottom + listHeight) { rc.bottom = pList->labelEdit.rcCombo.bottom - 7; // don't ask me why! rc.top = rc.bottom - listHeight; } else { rc.top = pList->labelEdit.rcCombo.bottom; rc.bottom = rc.top + listHeight; } pList->labelEdit.dropDown.hDrop = CreateWindowEx(0, _T("LISTBOX"), NULL, WS_CHILD|WS_BORDER|WS_VSCROLL|LBS_COMBOBOX|LBS_HASSTRINGS, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, hwnd, NULL, ghInst, NULL); if (!pList->labelEdit.dropDown.hDrop) return FALSE; SetUserData(pList->labelEdit.dropDown.hDrop, pList); OldDropdownProc = (WNDPROC)SetWindowLongPtr(pList->labelEdit.dropDown.hDrop, GWLP_WNDPROC, (LONG_PTR)ProfileList_DropdownProc); SetWindowLongPtr(pList->labelEdit.dropDown.hDrop, GWLP_ID, LIST_DROPDOWN); SendMessage(pList->labelEdit.dropDown.hDrop, WM_SETFONT, (WPARAM)SendMessage(GetParent(pList->hList), WM_GETFONT, 0, 0), 0); // add items for (i = 0; i < pList->labelEdit.pItem->idstrListCount; i++) { add = ListBox_AddString(pList->labelEdit.dropDown.hDrop, pList->labelEdit.pItem->idstrList[i].ptszTranslated); ListBox_SetItemData(pList->labelEdit.dropDown.hDrop, add, pList->labelEdit.pItem->idstrList + i); if (!_tcscmp(szEdit, pList->labelEdit.pItem->idstrList[i].ptszTranslated)) ListBox_SetCurSel(pList->labelEdit.dropDown.hDrop, add); } } else { LPIDSTRLIST lpidList; i = 0; while (PtrIsValid(lpidList = (LPIDSTRLIST)ListBox_GetItemData(pList->labelEdit.dropDown.hDrop, i))) { if (!_tcscmp(szEdit, lpidList->ptszTranslated)) { ListBox_SetCurSel(pList->labelEdit.dropDown.hDrop, i); break; } i++; } if (i == pList->labelEdit.pItem->idstrListCount) ListBox_SetCurSel(pList->labelEdit.dropDown.hDrop, -1); } if (IsWindowVisible(pList->labelEdit.dropDown.hDrop)) { SetFocus(pList->labelEdit.hEdit); } else { ShowWindow(pList->labelEdit.dropDown.hDrop, SW_SHOW); //SetFocus(pList->labelEdit.dropDown.hDrop); } break; } } break; } case WM_MOUSEWHEEL: case WM_VSCROLL: case WM_HSCROLL: { if (PtrIsValid(pList = (LPLISTCTRL)GetUserData(hwnd))) ProfileList_EndLabelEdit(pList, FALSE); break; } case WM_KILLFOCUS: { HWND hwndFocus = GetFocus(); if (PtrIsValid(pList = (LPLISTCTRL)GetUserData(hwnd)) && pList->labelEdit.hEdit != hwndFocus && pList->labelEdit.dropDown.hDrop != hwndFocus && pList->labelEdit.hBtn != hwndFocus) ProfileList_EndLabelEdit(pList, FALSE); break; } case WM_DESTROY: if (PtrIsValid(pList = (LPLISTCTRL)GetUserData(hwnd))) { HFONT hFont; ProfileList_EndLabelEdit(pList, FALSE); ProfileList_Clear(hwnd); if (PtrIsValid(hFont = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0)) && hFont != pList->hFont) DeleteObject(hFont); DestroyWindow(pList->hTip); mir_free(pList); } break; } return CallWindowProc(OldListViewProc, hwnd, msg, wParam, lParam); }
/** * name: DlgProc_EditEMail() * desc: dialog procedure * * return: 0 or 1 **/ static INT_PTR CALLBACK DlgProc_EMail(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { LPCBEXITEM cbi = (LPCBEXITEM)GetUserData(hDlg); switch (msg) { case WM_INITDIALOG: cbi = (LPCBEXITEM)lParam; if (!cbi) return FALSE; SetUserData(hDlg, lParam); SendDlgItemMessage(hDlg, IDC_HEADERBAR, WM_SETICON, 0, (LPARAM)IcoLib_GetIcon(ICO_DLG_EMAIL, TRUE)); if (db_get_b(NULL, MODNAME, SET_ICONS_BUTTONS, 1)) { SendDlgItemMessage(hDlg, IDOK, BM_SETIMAGE, IMAGE_ICON, (LPARAM)IcoLib_GetIcon(ICO_BTN_OK)); SendDlgItemMessage(hDlg, IDCANCEL, BM_SETIMAGE, IMAGE_ICON, (LPARAM)IcoLib_GetIcon(ICO_BTN_CANCEL)); } if (*cbi->pszVal) SetWindowText(hDlg, LPGENT("Edit e-mail")); TranslateDialogDefault(hDlg); SendDlgItemMessage(hDlg, EDIT_CATEGORY, EM_LIMITTEXT, cbi->ccCat - 1, 0); SendDlgItemMessage(hDlg, EDIT_EMAIL, EM_LIMITTEXT, cbi->ccVal - 1, 0); SetDlgItemText(hDlg, EDIT_CATEGORY, cbi->pszCat); SetDlgItemText(hDlg, EDIT_EMAIL, cbi->pszVal); EnableWindow(GetDlgItem(hDlg, EDIT_CATEGORY), !(cbi->wFlags & CBEXIF_CATREADONLY)); EnableWindow(GetDlgItem(hDlg, IDOK), *cbi->pszVal); // translate Userinfo buttons { TCHAR szButton[MAX_PATH]; HWND hBtn = GetDlgItem(hDlg, IDOK); GetWindowText(hBtn, szButton, _countof(szButton)); SetWindowText(hBtn, TranslateTS(szButton)); hBtn = GetDlgItem(hDlg, IDCANCEL); GetWindowText(hBtn, szButton, _countof(szButton)); SetWindowText(hBtn, TranslateTS(szButton)); } return TRUE; case WM_CTLCOLORSTATIC: SetBkColor((HDC)wParam, RGB(255, 255, 255)); return (INT_PTR)GetStockObject(WHITE_BRUSH); case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: { if (HIWORD(wParam) == BN_CLICKED) { if (cbi->pszVal && cbi->ccVal > 0) GetDlgItemText(hDlg, EDIT_EMAIL, cbi->pszVal, cbi->ccVal); if (cbi->pszCat && cbi->ccCat > 0) GetDlgItemText(hDlg, EDIT_CATEGORY, cbi->pszCat, cbi->ccCat); } break; } case IDCANCEL: { if (HIWORD(wParam) == BN_CLICKED) EndDialog(hDlg, LOWORD(wParam)); break; } case EDIT_EMAIL: if (HIWORD(wParam) == EN_UPDATE) { TCHAR szText[MAXDATASIZE]; LPTSTR pszAdd, pszDot; if (PtrIsValid(cbi)) { GetWindowText((HWND)lParam, szText, _countof(szText)); EnableWindow(GetDlgItem(hDlg, IDOK), ((pszAdd = _tcschr(szText, '@')) && *(pszAdd + 1) != '.' && (pszDot = _tcschr(pszAdd, '.')) && *(pszDot + 1) && mir_tstrcmp(szText, cbi->pszVal))); } } break; } break; } return FALSE; }
/** * name: OnAddPage * class: CPsTreeItem * desc: inits the treeitem's attributes * params: pPsh - pointer to the property page's header structure * odp - OPTIONSDIALOGPAGE structure with the information about the page to add * return: 0 on success, 1 on failure **/ int CPsTreeItem::Create(CPsHdr* pPsh, OPTIONSDIALOGPAGE *odp) { int err; TCHAR szTitle[ MAXSETTING ]; // check parameter if (pPsh && pPsh->_dwSize == sizeof(CPsHdr) && odp && PtrIsValid(odp->hInstance)) { // instance value _hInst = odp->hInstance; _dwFlags = odp->flags; _initParam = odp->dwInitParam; // init page owning contact _hContact = pPsh->_hContact; _pszProto = mir_strdup(pPsh->_pszProto); // global settings prefix for current contact (is dialog owning contact's protocol by default) _pszPrefix = (pPsh->_pszPrefix) ? pPsh->_pszPrefix : "Owner"; if (pPsh->_dwFlags & PSF_PROTOPAGESONLY) { if (_dwFlags & ODPF_USERINFOTAB) mir_sntprintf(szTitle, _T("%s %d\\%s"), odp->ptszTitle, pPsh->_nSubContact+1, odp->ptszTab); else mir_sntprintf(szTitle, _T("%s %d"), odp->ptszTitle, pPsh->_nSubContact+1); } else { if (_dwFlags & ODPF_USERINFOTAB) mir_sntprintf(szTitle, _T("%s\\%s"), odp->ptszTitle, odp->ptszTab); else mir_tstrcpy(szTitle, odp->ptszTitle); } // set the unique utf8 encoded name for the item if (err = Name(szTitle, (_dwFlags & ODPF_UNICODE) == ODPF_UNICODE)) MsgErr(NULL, LPGENT("Creating unique name for a page failed with %d and error code %d"), err, GetLastError()); // read label from database or create it else if (err = ItemLabel(TRUE)) MsgErr(NULL, LPGENT("Creating the label for a page failed with %d and error code %d"), err, GetLastError()); else { // load icon for the item Icon(pPsh->_hImages, odp, (pPsh->_dwFlags & PSTVF_INITICONS) == PSTVF_INITICONS); // the rest is not needed if only icons are loaded if (pPsh->_dwFlags & PSTVF_INITICONS) return 0; // load custom order if (!(pPsh->_dwFlags & PSTVF_SORTTREE)) { _iPosition = (int)db_get_b(NULL, MODNAME, PropertyKey(SET_ITEM_POS), odp->position); if ((_iPosition < 0) && (_iPosition > 0x800000A)) _iPosition = 0; } // read visibility state _bState = db_get_b(NULL, MODNAME, PropertyKey(SET_ITEM_STATE), DBTVIS_EXPANDED); // error for no longer supported dialog template type if (((UINT_PTR)odp->pszTemplate & 0xFFFF0000)) MsgErr(NULL, LPGENT("The dialog template type is no longer supported")); else { // fetch dialog resource id _idDlg = (INT_PTR)odp->pszTemplate; // dialog procedure _pfnDlgProc = odp->pfnDlgProc; // is dummy item? if (!_idDlg && !_pfnDlgProc) return 0; if (_idDlg && _pfnDlgProc) { // lock the property pages dialog resource _pTemplate = (DLGTEMPLATE*)LockResource(LoadResource(_hInst, FindResource(_hInst, (LPCTSTR)(UINT_PTR)_idDlg, RT_DIALOG))); if (_pTemplate) return 0; } } } } return 1; }
/** * This is the message procedure for my nice looking message box * * @param hDlg - window handle * @param uMsg - message to handle * @param wParam - message specific parameter * @param lParam - message specific parameter * * @return TRUE, FALSE, IDOK, IDYES, IDALL, IDNO or IDCANCEL **/ static INT_PTR CALLBACK MsgBoxProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { static int retOk = IDOK; static int retAll = IDALL; static int retNon = IDNONE; static int retCancel = IDCANCEL; switch (uMsg) { case WM_INITDIALOG: { LPMSGBOX pMsgBox = (LPMSGBOX)lParam; if (PtrIsValid(pMsgBox)) { int icoWidth = 0; int InfoBarHeight = 0; HFONT hNormalFont; hNormalFont = (HFONT)SendDlgItemMessage(hDlg, TXT_NAME, WM_GETFONT, 0, 0); if (pMsgBox->uType & MB_INFOBAR) { LOGFONT lf; // set bold font for name in description area GetObject(hNormalFont, sizeof(lf), &lf); lf.lfWeight = FW_BOLD; hNormalFont = CreateFontIndirect(&lf); // set infobar's textfont SendDlgItemMessage(hDlg, TXT_NAME, WM_SETFONT, (WPARAM)hNormalFont, 0); // set infobar's logo icon SendDlgItemMessage(hDlg, ICO_DLGLOGO, STM_SETIMAGE, IMAGE_ICON, (pMsgBox->hiLogo ? (LPARAM)pMsgBox->hiLogo : (LPARAM)IcoLib_GetIcon(ICO_DLG_DETAILS,TRUE))); // enable headerbar ShowWindow(GetDlgItem(hDlg, TXT_NAME), SW_SHOW); ShowWindow(GetDlgItem(hDlg, ICO_DLGLOGO), SW_SHOW); } else { RECT rc; GetClientRect(GetDlgItem(hDlg, TXT_NAME), &rc); InfoBarHeight = rc.bottom; if (pMsgBox->hiLogo) SendMessage(hDlg, WM_SETICON, ICON_BIG, (LPARAM)pMsgBox->hiLogo); } // draw the desired status icon HICON hIcon = MsgLoadIcon(pMsgBox); if (hIcon) SendDlgItemMessage(hDlg, ICO_MSGDLG, STM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); else { RECT ws; GetWindowRect(GetDlgItem(hDlg, ICO_MSGDLG), &ws); icoWidth = ws.right - ws.left; ShowWindow(GetDlgItem(hDlg, ICO_MSGDLG), SW_HIDE); } // resize the messagebox and reorganize the buttons if (HDC hDC = GetDC(hDlg)) { POINT mpt = { 0, 0 }; RECT ws = { 0, 0, 0, 0 }; int txtWidth=0, txtHeight=0, needX, needY; RECT rcDlg; SIZE ts; LPTSTR h, rs; SelectObject(hDC, hNormalFont); // get message text width and height if(pMsgBox->ptszMsg) for (rs=h=pMsgBox->ptszMsg; ; ++h) { if (*h=='\n' || !*h) { GetTextExtentPoint32(hDC, rs, h-rs, &ts); if (ts.cx > txtWidth) txtWidth = ts.cx; txtHeight += ts.cy; if (!*h) break; rs = h+1; } } // increase width if info text requires more if((pMsgBox->uType&MB_INFOBAR) && pMsgBox->ptszInfoText && *pMsgBox->ptszInfoText){ //int multiline = 0; RECT rcico; GetClientRect(GetDlgItem(hDlg,ICO_DLGLOGO), &rcico); rcico.right = rcico.right*100/66; // padding for(rs=h=pMsgBox->ptszInfoText; ; ++h) { if (*h=='\n' || !*h) { GetTextExtentPoint32(hDC, rs, h-rs, &ts); ts.cx += rcico.right; if (ts.cx > txtWidth) txtWidth = ts.cx; if (!*h) break; rs = h+1; //++multiline; } } /* used by SendSS, disabled for UserInfoEx for now if(!multiline) SetWindowLongPtr(GetDlgItem(hDlg,TXT_NAME), GWL_STYLE, GetWindowLongPtr(GetDlgItem(hDlg,TXT_NAME), GWL_STYLE)|SS_CENTERIMAGE); */ } ReleaseDC(hDlg, hDC); // calc new dialog size GetWindowRect(hDlg, &rcDlg); GetWindowRect(GetDlgItem(hDlg, TXT_MESSAGE), &ws); needX = txtWidth - (ws.right - ws.left) - icoWidth; needY = max(0, txtHeight - (ws.bottom - ws.top) + 5); rcDlg.left -= needX/2; rcDlg.right += needX/2; rcDlg.top -= (needY-InfoBarHeight)/2; rcDlg.bottom += (needY-InfoBarHeight)/2; // resize dialog window MoveWindow(hDlg, rcDlg.left, rcDlg.top, rcDlg.right - rcDlg.left, rcDlg.bottom - rcDlg.top, FALSE); ClientToScreen(hDlg, &mpt); MoveCtrl(hDlg, STATIC_WHITERECT, -mpt.x, -mpt.y, needX, needY - InfoBarHeight); MoveCtrl(hDlg, TXT_NAME, -mpt.x, -mpt.y, needX, 0); MoveCtrl(hDlg, ICO_DLGLOGO, -mpt.x + needX, -mpt.y, 0, 0); MoveCtrl(hDlg, ICO_MSGDLG, -mpt.x, -mpt.y - InfoBarHeight, 0, 0); MoveCtrl(hDlg, TXT_MESSAGE, -mpt.x - icoWidth, -mpt.y - InfoBarHeight, needX, needY); MoveCtrl(hDlg, STATIC_LINE2, -mpt.x, -mpt.y + needY - InfoBarHeight, needX, 0); // // Do pushbutton positioning // RECT rcOk, rcAll, rcNone, rcCancel; // get button rectangles GetWindowRect(GetDlgItem(hDlg, IDOK), &rcOk); OffsetRect(&rcOk, -mpt.x, -mpt.y + needY - InfoBarHeight); GetWindowRect(GetDlgItem(hDlg, IDALL), &rcAll); OffsetRect(&rcAll, -mpt.x, -mpt.y + needY - InfoBarHeight); GetWindowRect(GetDlgItem(hDlg, IDNONE), &rcNone); OffsetRect(&rcNone, -mpt.x, -mpt.y + needY - InfoBarHeight); GetWindowRect(GetDlgItem(hDlg, IDCANCEL), &rcCancel); OffsetRect(&rcCancel, -mpt.x, -mpt.y + needY - InfoBarHeight); LONG okWidth = rcOk.right - rcOk.left; LONG allWidth = rcAll.right - rcAll.left; LONG noneWidth = rcNone.right - rcNone.left; LONG caWidth = rcCancel.right - rcCancel.left; LONG dlgMid = (rcDlg.right - rcDlg.left) / 2; // load button configuration switch (MB_TYPE(pMsgBox->uType)) { case MB_OK: rcOk.left = dlgMid - (okWidth / 2); rcOk.right = rcOk.left + okWidth; ShowWindow(GetDlgItem(hDlg, IDOK), SW_SHOW); break; case MB_OKCANCEL: retOk = IDRETRY; SetDlgItemText(hDlg, IDOK, LPGENT("OK")); retCancel = IDCANCEL; SetDlgItemText(hDlg, IDCANCEL, LPGENT("Cancel")); rcOk.left = dlgMid - okWidth - 10; rcOk.right = rcOk.left + okWidth; rcCancel.left = dlgMid + 10; rcCancel.right = rcCancel.left + caWidth; ShowWindow(GetDlgItem(hDlg, IDOK), SW_SHOW); ShowWindow(GetDlgItem(hDlg, IDCANCEL), SW_SHOW); break; case MB_RETRYCANCEL: retOk = IDRETRY; SetDlgItemText(hDlg, IDOK, LPGENT("Retry")); retCancel = IDCANCEL; SetDlgItemText(hDlg, IDCANCEL, LPGENT("Cancel")); rcOk.left = dlgMid - okWidth - 10; rcOk.right = rcOk.left + okWidth; rcCancel.left = dlgMid + 10; rcCancel.right = rcCancel.left + caWidth; ShowWindow(GetDlgItem(hDlg, IDOK), SW_SHOW); ShowWindow(GetDlgItem(hDlg, IDCANCEL), SW_SHOW); break; case MB_YESNO: retOk = IDYES; SetDlgItemText(hDlg, IDOK, LPGENT("Yes")); retCancel = IDNO; SetDlgItemText(hDlg, IDCANCEL, LPGENT("No")); rcOk.left = dlgMid - okWidth - 10; rcOk.right = rcOk.left + okWidth; rcCancel.left = dlgMid + 10; rcCancel.right = rcCancel.left + caWidth; ShowWindow(GetDlgItem(hDlg, IDOK), SW_SHOW); ShowWindow(GetDlgItem(hDlg, IDCANCEL), SW_SHOW); break; case MB_ABORTRETRYIGNORE: retOk = IDABORT; SetDlgItemText(hDlg, IDOK, LPGENT("Abort")); retAll = IDABORT; SetDlgItemText(hDlg, IDALL, LPGENT("Retry")); retCancel = IDCANCEL; SetDlgItemText(hDlg, IDCANCEL, LPGENT("Ignore")); rcAll.left = dlgMid - (allWidth / 2); rcAll.right = rcAll.left + allWidth; rcOk.left = rcAll.left - okWidth - 5; rcOk.right = rcOk.left + okWidth; rcCancel.left = rcAll.right + 5; rcCancel.right = rcCancel.left + caWidth; ShowWindow(GetDlgItem(hDlg, IDOK), SW_SHOW); ShowWindow(GetDlgItem(hDlg, IDALL), SW_SHOW); ShowWindow(GetDlgItem(hDlg, IDCANCEL), SW_SHOW); break; case MB_YESNOCANCEL: retOk = IDYES; SetDlgItemText(hDlg, IDOK, LPGENT("Yes")); retAll = IDNO; SetDlgItemText(hDlg, IDALL, LPGENT("No")); retCancel = IDCANCEL; SetDlgItemText(hDlg, IDCANCEL, LPGENT("Cancel")); rcAll.left = dlgMid - (allWidth / 2); rcAll.right = rcAll.left + allWidth; rcOk.left = rcAll.left - okWidth - 5; rcOk.right = rcOk.left + okWidth; rcCancel.left = rcAll.right + 5; rcCancel.right = rcCancel.left + caWidth; ShowWindow(GetDlgItem(hDlg, IDOK), SW_SHOW); ShowWindow(GetDlgItem(hDlg, IDALL), SW_SHOW); ShowWindow(GetDlgItem(hDlg, IDCANCEL), SW_SHOW); break; case MB_YESALLNO: retOk = IDYES; SetDlgItemText(hDlg, IDOK, LPGENT("Yes")); retAll = IDALL; SetDlgItemText(hDlg, IDALL, LPGENT("All")); //retNon = IDNONE; SetDlgItemText(hDlg, IDNONE, LPGENT("None")); retCancel = IDNO; SetDlgItemText(hDlg, IDCANCEL, LPGENT("No")); rcCancel.right = rcDlg.right - rcDlg.left - 10; rcCancel.left = rcCancel.right - caWidth; rcNone.right = rcCancel.left - 5; rcNone.left = rcNone.right - noneWidth; rcAll.right = rcNone.left - 5; rcAll.left = rcAll.right - allWidth; rcOk.right = rcAll.left - 5; rcOk.left = rcOk.right - okWidth; // show buttons ShowWindow(GetDlgItem(hDlg, IDOK), SW_SHOW); ShowWindow(GetDlgItem(hDlg, IDALL), SW_SHOW); ShowWindow(GetDlgItem(hDlg, IDNONE), SW_SHOW); ShowWindow(GetDlgItem(hDlg, IDCANCEL), SW_SHOW); break; default: rcOk.left = dlgMid - (okWidth / 2); rcOk.right = rcOk.left + okWidth; } MoveWindow(GetDlgItem(hDlg, IDOK), rcOk.left, rcOk.top, rcOk.right - rcOk.left, rcOk.bottom - rcOk.top, FALSE); MoveWindow(GetDlgItem(hDlg, IDALL), rcAll.left, rcAll.top, rcAll.right - rcAll.left, rcAll.bottom - rcAll.top, FALSE); MoveWindow(GetDlgItem(hDlg, IDNONE), rcNone.left, rcNone.top, rcNone.right - rcNone.left, rcNone.bottom - rcNone.top, FALSE); MoveWindow(GetDlgItem(hDlg, IDCANCEL), rcCancel.left, rcCancel.top, rcCancel.right - rcCancel.left, rcCancel.bottom - rcCancel.top, FALSE); } // set text's SetWindowText(hDlg, pMsgBox->ptszTitle); SetDlgItemText(hDlg, TXT_NAME, pMsgBox->ptszInfoText); SetDlgItemText(hDlg, TXT_MESSAGE, pMsgBox->ptszMsg); TranslateDialogDefault(hDlg); return TRUE; } } break; case WM_CTLCOLORSTATIC: switch (GetWindowLongPtr((HWND)lParam, GWLP_ID)) { case STATIC_WHITERECT: case ICO_DLGLOGO: case ICO_MSGDLG: case TXT_MESSAGE: case TXT_NAME: SetTextColor((HDC)wParam, GetSysColor(COLOR_WINDOWTEXT)); return GetSysColor(COLOR_WINDOW); } break; case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: EndDialog(hDlg, retOk); break; case IDCANCEL: EndDialog(hDlg, retCancel); break; case IDALL: EndDialog(hDlg, retAll); break; case IDNONE: EndDialog(hDlg, retNon); } break; case WM_DESTROY: DeleteObject((HFONT)SendDlgItemMessage(hDlg, TXT_NAME, WM_GETFONT, 0, 0)); break; } return FALSE; }