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;
}
Exemple #3
0
// 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;
}
Exemple #5
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;
}
Exemple #6
0
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);
		}
	}
}
Exemple #7
0
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;
}
Exemple #11
0
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;
}
Exemple #13
0
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);
			}
		}
	}
}
Exemple #14
0
/**
* 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);
	}
}
Exemple #16
0
/**
 * 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("--:--"));
	}
}
Exemple #18
0
/**
 * 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);
}
Exemple #19
0
/**
 * 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);
}
Exemple #20
0
/**
 * 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);
}
Exemple #21
0
/**
 * 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;
}
Exemple #22
0
/**
 * 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;
	}
Exemple #24
0
/**
 * 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);
}
Exemple #27
0
/**
 * 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);
}
Exemple #28
0
/**
 * 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;
}
Exemple #29
0
/**
 * 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;
}
Exemple #30
0
/**
 * 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;
}