Beispiel #1
0
int cliCompareContacts(const ClcContact *contact1, const ClcContact *contact2)
{
	ClcCacheEntry *c1 = contact1->pce, *c2 = contact2->pce;

	for (int i = 0; i < _countof(g_CluiData.bSortByOrder); i++) {
		BYTE &by = g_CluiData.bSortByOrder[i];

		if (by == SORTBY_STATUS) { //status
			int ordera = GetStatusModeOrdering(c1->getStatus());
			int orderb = GetStatusModeOrdering(c2->getStatus());
			if (ordera == orderb)
				continue;
			return ordera - orderb;
		}

		// one is offline: offline goes below online
		if (!g_CluiData.fSortNoOfflineBottom) {
			int statusa = c1->getStatus();
			int statusb = c2->getStatus();
			if ((statusa == ID_STATUS_OFFLINE) != (statusb == ID_STATUS_OFFLINE))
				return 2 * (statusa == ID_STATUS_OFFLINE) - 1;
		}

		int r = 0;

		switch (by) {
		case SORTBY_NAME: // name
			r = mir_wstrcmpi(contact1->szText, contact2->szText);
			break;

		case SORTBY_NAME_LOCALE: // name
			if (LocaleId == -1)
				LocaleId = Langpack_GetDefaultLocale();
			r = CompareString(LocaleId, NORM_IGNORECASE, SAFETSTRING(contact1->szText), -1, SAFETSTRING(contact2->szText), -1) - 2;
			break;

		case SORTBY_LASTMSG: // last message
			r = (int)CompareContacts2_getLMTime(contact2->hContact) - (int)CompareContacts2_getLMTime(contact1->hContact);
			break;

		case SORTBY_PROTO:
			if (contact1->proto == nullptr || contact2->proto == nullptr)
				continue;
			r = GetProtoIndex(contact1->proto) - GetProtoIndex(contact2->proto);
			break;

		case SORTBY_RATE:
			r = contact2->bContactRate - contact1->bContactRate; // reverse order 
			break;

		default: // should never happen
			continue;
		}

		if (r != 0)
			return r;
	}
	return 0;
}
Beispiel #2
0
int CompareContacts2(const ClcContact *contact1, const ClcContact *contact2, int by)
{
	TCHAR *namea, *nameb;
	int statusa, statusb;
	char *szProto1, *szProto2;

	if ((INT_PTR)contact1 < 100 || (INT_PTR)contact2 < 100) return 0;

	MCONTACT a = contact1->hContact;
	MCONTACT b = contact2->hContact;

	namea = (TCHAR *)contact1->szText;
	statusa = GetContactCachedStatus(contact1->hContact);
	szProto1 = contact1->proto;

	nameb = (TCHAR *)contact2->szText;
	statusb = GetContactCachedStatus(contact2->hContact);
	szProto2 = contact2->proto;

	if (by == SORTBY_STATUS) { //status
		int ordera, orderb;
		ordera = GetStatusModeOrdering(statusa);
		orderb = GetStatusModeOrdering(statusb);
		return (ordera != orderb) ? ordera - orderb : 0;
	}

	//one is offline: offline goes below online
	if (g_CluiData.fSortNoOfflineBottom == 0 && (statusa == ID_STATUS_OFFLINE) != (statusb == ID_STATUS_OFFLINE))
		return 2 * (statusa == ID_STATUS_OFFLINE) - 1;

	if (by == SORTBY_NAME) //name
		return mir_tstrcmpi(namea, nameb);

	if (by == SORTBY_NAME_LOCALE) {
		//name
		static int LocaleId = -1;
		if (LocaleId == -1) LocaleId = Langpack_GetDefaultLocale();
		return (CompareString(LocaleId, NORM_IGNORECASE, SAFETSTRING(namea), -1, SAFETSTRING(nameb), -1)) - 2;
	}
	if (by == SORTBY_LASTMSG) {
		//last message
		DWORD ta = CompareContacts2_getLMTime(a);
		DWORD tb = CompareContacts2_getLMTime(b);
		return tb - ta;
	}
	if (by == SORTBY_PROTO) {
		int rc = GetProtoIndex(szProto1) - GetProtoIndex(szProto2);
		if (rc != 0 && (szProto1 != NULL && szProto2 != NULL))
			return rc;
	}
	else if (by == SORTBY_RATE)
		return contact2->bContactRate - contact1->bContactRate;
	// else :o)
	return 0;
}
Beispiel #3
0
extern "C" int __declspec(dllexport) Load(void)
{
	hMsftedit = LoadLibrary(_T("Msftedit.dll"));
	if (hMsftedit == NULL)
		return 1;

	clsdates = db_get_b(NULL, PluginName, "ClassicDates", 1) != 0;
	dtsubfldr = db_get_b(NULL, PluginName, "SubFolders", 1) != 0;
	catchcrashes = db_get_b(NULL, PluginName, "CatchCrashes", 1) != 0;

	mir_getLP(&pluginInfoEx);

	profname = Utils_ReplaceVarsT(_T("%miranda_profilename%.dat"));
	profpath = Utils_ReplaceVarsT(_T("%miranda_userdata%"));
	if (catchcrashes && !needrestart)
		mir_sntprintf(CrashLogFolder, TEXT("%s\\CrashLog"), profpath);
	_tcsncpy_s(VersionInfoFolder, profpath, _TRUNCATE);


	HookEvent(ME_SYSTEM_MODULESLOADED, ModulesLoaded);
	HookEvent(ME_OPT_INITIALISE, OptionsInit);
	HookEvent(ME_SYSTEM_PRESHUTDOWN, PreShutdown);

	packlcid = (LCID)Langpack_GetDefaultLocale();

	InitIcons();

	if (catchcrashes && !needrestart)
		InitExceptionHandler();

	CreateServiceFunction(MS_CRASHDUMPER_STORETOFILE, StoreVersionInfoToFile);
	CreateServiceFunction(MS_CRASHDUMPER_STORETOCLIP, StoreVersionInfoToClipboard);
	CreateServiceFunction(MS_CRASHDUMPER_VIEWINFO, ViewVersionInfo);
	CreateServiceFunction(MS_CRASHDUMPER_GETINFO, GetVersionInfo);
	CreateServiceFunction(MS_CRASHDUMPER_UPLOAD, UploadVersionInfo);
	CreateServiceFunction(MS_CRASHDUMPER_URL, OpenUrl);
	CreateServiceFunction(MS_SERVICEMODE_LAUNCH, ServiceModeLaunch);
	CreateServiceFunction(MS_CRASHDUMPER_URLTOCLIP, CopyLinkToClipboard);
	return 0;
}
Beispiel #4
0
static void DisplayPackInfo(HWND hwndDlg, const LANGPACK_INFO *pack)
{
	/* locale string */
	if (!(pack->flags & LPF_NOLOCALE)) {
		TCHAR szLocaleName[256], szLanguageName[128], szContryName[128];

		if (!GetLocaleInfo(pack->Locale, WINVER >= _WIN32_WINNT_WIN7 ? LOCALE_SENGLISHLANGUAGENAME : LOCALE_SENGLANGUAGE, szLanguageName, _countof(szLanguageName)))
			szLanguageName[0] = _T('\0');
		if (!GetLocaleInfo(pack->Locale, WINVER >= _WIN32_WINNT_WIN7 ? LOCALE_SENGLISHCOUNTRYNAME : LOCALE_SENGCOUNTRY, szContryName, _countof(szContryName)))
			szContryName[0] = _T('\0');
		
		/* add some note if its incompatible */
		if (szLanguageName[0] && szContryName[0]) {
			mir_sntprintf(szLocaleName, _T("%s (%s)"), TranslateTS(szLanguageName), TranslateTS(szContryName));
			if (!IsValidLocale(pack->Locale, LCID_INSTALLED)) {
				TCHAR *pszIncompat;
				pszIncompat = TranslateT("(incompatible)");
				szLocaleName[_countof(szLocaleName) - mir_tstrlen(pszIncompat) - 1] = 0;
				mir_tstrcat(mir_tstrcat(szLocaleName, _T(" ")), pszIncompat);
			}
			SetDlgItemText(hwndDlg, IDC_LANGLOCALE, szLocaleName);
		}
		else SetDlgItemText(hwndDlg, IDC_LANGLOCALE, TranslateT("Unknown"));
	}
	else SetDlgItemText(hwndDlg, IDC_LANGLOCALE, TranslateT("Unknown"));
	
	/* file date */
	SYSTEMTIME stFileDate;
	TCHAR szDate[128]; szDate[0] = 0;
	if (FileTimeToSystemTime(&pack->ftFileDate, &stFileDate))
		GetDateFormat(Langpack_GetDefaultLocale(), DATE_SHORTDATE, &stFileDate, NULL, szDate, _countof(szDate));
	SetDlgItemText(hwndDlg, IDC_LANGDATE, szDate);
	
	/* general */
	SetDlgItemText_CP(hwndDlg, IDC_LANGMODUSING, pack->szLastModifiedUsing);
	SetDlgItemText_CP(hwndDlg, IDC_LANGAUTHORS, pack->szAuthors);
	SetDlgItemText_CP(hwndDlg, IDC_LANGEMAIL, pack->szAuthorEmail);
	SetDlgItemText(hwndDlg, IDC_LANGINFOFRAME, TranslateTS(pack->tszLanguage));
}
Beispiel #5
0
static void DialogCacheSaveThread(void *unused)
{
	int success = 0;

	// TODO: port the following code to write to the helppack file instead
	// (netlib code already removed)
	/*
	{	WCHAR *szDecoded;
	char *szEncoded=mir_strdup(dialogCache[i].control[j].szText);
	if (mir_utf8decode(szEncoded, &szDecoded)) {
		[...]
		mir_free(szDecoded)
	}
	mir_free(szEncoded); // does NULL check
	}


	int i, j;
	struct ResizableCharBuffer data={0}, dlgId={0};

	for (i = 0; i < dialogCacheCount; i++) {
		if(!dialogCache[i].changes) continue;

		AppendToCharBuffer(&data, "t <dialog id=\"%s\" module=\"%s\">\r\n", dialogCache[i].szId, dialogCache[i].szModule);
		for (j = 0; j < dialogCache[i].controlCount; j++) {
			AppendToCharBuffer(&data, "<control id=%d type=%d>\r\n", dialogCache[i].control[j].id, dialogCache[i].control[j].type);
			if (dialogCache[i].control[j].szTitle)
				AppendToCharBuffer(&data, "<title>%s</title>\r\n", dialogCache[i].control[j].szTitle);
			if (dialogCache[i].control[j].szText)
				AppendToCharBuffer(&data, "<text>%s</text>\r\n", dialogCache[i].control[j].szText);
			AppendToCharBuffer(&data, "</control>\r\n");
		}
		AppendToCharBuffer(&data, "</dialog>");
	}

	if(success) {
		dialogCache[i].changes = 0;
		dialogCache[i].timeLoaded = GetTickCount();
	}
	*/
	MessageBoxEx(NULL, success ? TranslateT("Help saving complete.") : TranslateT("Help saving failed!"), TranslateT("Help editor"), (success ? MB_ICONINFORMATION : MB_ICONERROR) | MB_OK | MB_SETFOREGROUND | MB_TOPMOST | MB_TASKMODAL, LANGIDFROMLCID(Langpack_GetDefaultLocale()));
}
Beispiel #6
0
static INT_PTR srvGetDefaultLocale(WPARAM, LPARAM)
{
	return Langpack_GetDefaultLocale();
}
Beispiel #7
0
static INT_PTR CALLBACK SettingsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg) {
	case WM_INITDIALOG:
		TranslateDialogDefault(hwndDlg);
		{
			hwndSettingsDlg = hwndDlg;
			LCID locale = Langpack_GetDefaultLocale();
			SendDlgItemMessage(hwndDlg, IDC_ICON_HEADER, STM_SETIMAGE, IMAGE_ICON, (LPARAM)IcoLib_GetIcon("AutoShutdown_Header"));
			{
				HFONT hBoldFont;
				LOGFONT lf;
				if (GetObject((HFONT)SendDlgItemMessage(hwndDlg, IDC_TEXT_HEADER, WM_GETFONT, 0, 0), sizeof(lf), &lf)) {
					lf.lfWeight = FW_BOLD;
					hBoldFont = CreateFontIndirect(&lf);
				}
				else hBoldFont = NULL;
				SendDlgItemMessage(hwndDlg, IDC_TEXT_HEADER, WM_SETFONT, (WPARAM)hBoldFont, FALSE);
			}
			/* read-in watcher flags */
			{
				WORD watcherType = db_get_w(NULL, "AutoShutdown", "WatcherFlags", SETTING_WATCHERFLAGS_DEFAULT);
				CheckRadioButton(hwndDlg, IDC_RADIO_STTIME, IDC_RADIO_STCOUNTDOWN, (watcherType&SDWTF_ST_TIME) ? IDC_RADIO_STTIME : IDC_RADIO_STCOUNTDOWN);
				CheckDlgButton(hwndDlg, IDC_CHECK_SPECIFICTIME, (watcherType&SDWTF_SPECIFICTIME) != 0 ? BST_CHECKED : BST_UNCHECKED);
				CheckDlgButton(hwndDlg, IDC_CHECK_MESSAGE, (watcherType&SDWTF_MESSAGE) != 0 ? BST_CHECKED : BST_UNCHECKED);
				CheckDlgButton(hwndDlg, IDC_CHECK_FILETRANSFER, (watcherType&SDWTF_FILETRANSFER) != 0 ? BST_CHECKED : BST_UNCHECKED);
				CheckDlgButton(hwndDlg, IDC_CHECK_IDLE, (watcherType&SDWTF_IDLE) != 0 ? BST_CHECKED : BST_UNCHECKED);
				CheckDlgButton(hwndDlg, IDC_CHECK_STATUS, (watcherType&SDWTF_STATUS) != 0 ? BST_CHECKED : BST_UNCHECKED);
				CheckDlgButton(hwndDlg, IDC_CHECK_CPUUSAGE, (watcherType&SDWTF_CPUUSAGE) != 0 ? BST_CHECKED : BST_UNCHECKED);
			}
			/* read-in countdown val */
			{
				SYSTEMTIME st;
				if (!TimeStampToSystemTime((time_t)db_get_dw(NULL, "AutoShutdown", "TimeStamp", SETTING_TIMESTAMP_DEFAULT), &st))
					GetLocalTime(&st);
				DateTime_SetSystemtime(GetDlgItem(hwndDlg, IDC_TIME_TIMESTAMP), GDT_VALID, &st);
				DateTime_SetSystemtime(GetDlgItem(hwndDlg, IDC_DATE_TIMESTAMP), GDT_VALID, &st);
				SendMessage(hwndDlg, M_CHECK_DATETIME, 0, 0);
			}
			{
				DWORD setting = db_get_dw(NULL, "AutoShutdown", "Countdown", SETTING_COUNTDOWN_DEFAULT);
				if (setting < 1) setting = SETTING_COUNTDOWN_DEFAULT;
				SendDlgItemMessage(hwndDlg, IDC_SPIN_COUNTDOWN, UDM_SETRANGE, 0, MAKELPARAM(UD_MAXVAL, 1));
				SendDlgItemMessage(hwndDlg, IDC_EDIT_COUNTDOWN, EM_SETLIMITTEXT, (WPARAM)10, 0);
				SendDlgItemMessage(hwndDlg, IDC_SPIN_COUNTDOWN, UDM_SETPOS, 0, MAKELPARAM(setting, 0));
				SetDlgItemInt(hwndDlg, IDC_EDIT_COUNTDOWN, setting, FALSE);
			}
			{
				HWND hwndCombo = GetDlgItem(hwndDlg, IDC_COMBO_COUNTDOWNUNIT);
				DWORD lastUnit = db_get_dw(NULL, "AutoShutdown", "CountdownUnit", SETTING_COUNTDOWNUNIT_DEFAULT);
				SendMessage(hwndCombo, CB_SETLOCALE, (WPARAM)locale, 0); /* sort order */
				SendMessage(hwndCombo, CB_INITSTORAGE, _countof(unitNames), _countof(unitNames) * 16); /* approx. */
				for (int i = 0; i < _countof(unitNames); ++i) {
					int index = SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM)TranslateTS(unitNames[i]));
					if (index != LB_ERR) {
						SendMessage(hwndCombo, CB_SETITEMDATA, index, (LPARAM)unitValues[i]);
						if (i == 0 || unitValues[i] == lastUnit) SendMessage(hwndCombo, CB_SETCURSEL, index, 0);
					}
				}
			}
			{
				DBVARIANT dbv;
				if (!db_get_ts(NULL, "AutoShutdown", "Message", &dbv)) {
					SetDlgItemText(hwndDlg, IDC_EDIT_MESSAGE, dbv.ptszVal);
					mir_free(dbv.ptszVal);
				}
			}
			/* cpuusage threshold */
			{
				BYTE setting = DBGetContactSettingRangedByte(NULL, "AutoShutdown", "CpuUsageThreshold", SETTING_CPUUSAGETHRESHOLD_DEFAULT, 1, 100);
				SendDlgItemMessage(hwndDlg, IDC_SPIN_CPUUSAGE, UDM_SETRANGE, 0, MAKELPARAM(100, 1));
				SendDlgItemMessage(hwndDlg, IDC_EDIT_CPUUSAGE, EM_SETLIMITTEXT, (WPARAM)3, 0);
				SendDlgItemMessage(hwndDlg, IDC_SPIN_CPUUSAGE, UDM_SETPOS, 0, MAKELPARAM(setting, 0));
				SetDlgItemInt(hwndDlg, IDC_EDIT_CPUUSAGE, setting, FALSE);
			}
			/* shutdown types */
			{
				HWND hwndCombo = GetDlgItem(hwndDlg, IDC_COMBO_SHUTDOWNTYPE);
				BYTE lastShutdownType = db_get_b(NULL, "AutoShutdown", "ShutdownType", SETTING_SHUTDOWNTYPE_DEFAULT);
				SendMessage(hwndCombo, CB_SETLOCALE, (WPARAM)locale, 0); /* sort order */
				SendMessage(hwndCombo, CB_SETEXTENDEDUI, TRUE, 0);
				SendMessage(hwndCombo, CB_INITSTORAGE, SDSDT_MAX, SDSDT_MAX * 32);
				for (BYTE shutdownType = 1; shutdownType <= SDSDT_MAX; ++shutdownType)
					if (ServiceIsTypeEnabled(shutdownType, 0)) {
						TCHAR *pszText = (TCHAR*)ServiceGetTypeDescription(shutdownType, GSTDF_TCHAR); /* never fails */
						int index = SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM)pszText);
						if (index != LB_ERR) {
							SendMessage(hwndCombo, CB_SETITEMDATA, index, (LPARAM)shutdownType);
							if (shutdownType == 1 || shutdownType == lastShutdownType) SendMessage(hwndCombo, CB_SETCURSEL, (WPARAM)index, 0);
						}
					}
				SendMessage(hwndDlg, M_UPDATE_SHUTDOWNDESC, 0, (LPARAM)hwndCombo);
			}
			/* check if proto is installed that supports instant messages and check if a message dialog plugin is installed */
			if (!AnyProtoHasCaps(PF1_IMRECV) || !ServiceExists(MS_MSG_SENDMESSAGE)) { /* no srmessage present? */
				CheckDlgButton(hwndDlg, IDC_CHECK_MESSAGE, BST_UNCHECKED);
				EnableWindow(GetDlgItem(hwndDlg, IDC_CHECK_MESSAGE), FALSE);
				EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT_MESSAGE), FALSE);
			}
			/* check if proto is installed that supports file transfers and check if a file transfer dialog is available */
			if (!AnyProtoHasCaps(PF1_FILESEND) && !AnyProtoHasCaps(PF1_FILERECV)) {  /* no srfile present? */
				CheckDlgButton(hwndDlg, IDC_CHECK_FILETRANSFER, BST_UNCHECKED);
				EnableWindow(GetDlgItem(hwndDlg, IDC_CHECK_FILETRANSFER), FALSE);
			}
			/* check if cpu usage can be detected */
			if (!PollCpuUsage(DisplayCpuUsageProc, (LPARAM)GetDlgItem(hwndDlg, IDC_TEXT_CURRENTCPU), 1800)) {
				CheckDlgButton(hwndDlg, IDC_CHECK_CPUUSAGE, BST_UNCHECKED);
				EnableWindow(GetDlgItem(hwndDlg, IDC_CHECK_CPUUSAGE), FALSE);
			}
		}
		SendMessage(hwndDlg, M_ENABLE_SUBCTLS, 0, 0);
		Utils_RestoreWindowPositionNoSize(hwndDlg, NULL, "AutoShutdown", "SettingsDlg_");
		return TRUE; /* default focus */

	case WM_DESTROY:
		Utils_SaveWindowPosition(hwndDlg, NULL, "AutoShutdown", "SettingsDlg_");
		{
			HFONT hFont = (HFONT)SendDlgItemMessage(hwndDlg, IDC_TEXT_HEADER, WM_GETFONT, 0, 0);
			SendDlgItemMessage(hwndDlg, IDC_TEXT_HEADER, WM_SETFONT, 0, FALSE); /* no return value */
			if (hFont != NULL)
				DeleteObject(hFont);
			hwndSettingsDlg = NULL;
		}
		return TRUE;

	case WM_CTLCOLORSTATIC:
		switch (GetDlgCtrlID((HWND)lParam)) {
		case IDC_ICON_HEADER:
			SetBkMode((HDC)wParam, TRANSPARENT);

		case IDC_RECT_HEADER:
			/* need to set COLOR_WINDOW manually for Win9x */
			SetBkColor((HDC)wParam, GetSysColor(COLOR_WINDOW));
			return (INT_PTR)GetSysColorBrush(COLOR_WINDOW);

		case IDC_TEXT_HEADER:
		case IDC_TEXT_HEADERDESC:
			SetBkMode((HDC)wParam, TRANSPARENT);
			return (INT_PTR)GetStockObject(NULL_BRUSH);
		}
		break;

	case M_ENABLE_SUBCTLS:
		{
			BOOL checked = IsDlgButtonChecked(hwndDlg, IDC_CHECK_MESSAGE) != 0;
			EnableDlgItem(hwndDlg, IDC_EDIT_MESSAGE, checked);
			checked = IsDlgButtonChecked(hwndDlg, IDC_CHECK_SPECIFICTIME) != 0;
			EnableDlgItem(hwndDlg, IDC_RADIO_STTIME, checked);
			EnableDlgItem(hwndDlg, IDC_RADIO_STCOUNTDOWN, checked);
			checked = (IsDlgButtonChecked(hwndDlg, IDC_CHECK_SPECIFICTIME) && IsDlgButtonChecked(hwndDlg, IDC_RADIO_STTIME));
			EnableDlgItem(hwndDlg, IDC_TIME_TIMESTAMP, checked);
			EnableDlgItem(hwndDlg, IDC_DATE_TIMESTAMP, checked);
			checked = (IsDlgButtonChecked(hwndDlg, IDC_CHECK_SPECIFICTIME) && IsDlgButtonChecked(hwndDlg, IDC_RADIO_STCOUNTDOWN));
			EnableDlgItem(hwndDlg, IDC_EDIT_COUNTDOWN, checked);
			EnableDlgItem(hwndDlg, IDC_SPIN_COUNTDOWN, checked);
			EnableDlgItem(hwndDlg, IDC_COMBO_COUNTDOWNUNIT, checked);
			checked = IsDlgButtonChecked(hwndDlg, IDC_CHECK_IDLE) != 0;
			EnableDlgItem(hwndDlg, IDC_URL_IDLE, checked);
			checked = IsDlgButtonChecked(hwndDlg, IDC_CHECK_CPUUSAGE) != 0;
			EnableDlgItem(hwndDlg, IDC_EDIT_CPUUSAGE, checked);
			EnableDlgItem(hwndDlg, IDC_SPIN_CPUUSAGE, checked);
			EnableDlgItem(hwndDlg, IDC_TEXT_PERCENT, checked);
			EnableDlgItem(hwndDlg, IDC_TEXT_CURRENTCPU, checked);
			checked = (IsDlgButtonChecked(hwndDlg, IDC_CHECK_SPECIFICTIME) || IsDlgButtonChecked(hwndDlg, IDC_CHECK_MESSAGE) ||
				IsDlgButtonChecked(hwndDlg, IDC_CHECK_IDLE) || IsDlgButtonChecked(hwndDlg, IDC_CHECK_STATUS) ||
				IsDlgButtonChecked(hwndDlg, IDC_CHECK_FILETRANSFER) || IsDlgButtonChecked(hwndDlg, IDC_CHECK_CPUUSAGE));
			EnableDlgItem(hwndDlg, IDOK, checked);
		}
		return TRUE;

	case M_UPDATE_SHUTDOWNDESC: /* lParam=(LPARAM)(HWND)hwndCombo */
		{
			BYTE shutdownType = (BYTE)SendMessage((HWND)lParam, CB_GETITEMDATA, SendMessage((HWND)lParam, CB_GETCURSEL, 0, 0), 0);
			SetDlgItemText(hwndDlg, IDC_TEXT_SHUTDOWNTYPE, (TCHAR*)ServiceGetTypeDescription(shutdownType, GSTDF_LONGDESC | GSTDF_TCHAR));
		}
		return TRUE;

	case WM_TIMECHANGE: /* system time changed */
		SendMessage(hwndDlg, M_CHECK_DATETIME, 0, 0);
		return TRUE;

	case M_CHECK_DATETIME:
		{
			SYSTEMTIME st, stBuf;
			time_t timestamp;
			DateTime_GetSystemtime(GetDlgItem(hwndDlg, IDC_DATE_TIMESTAMP), &stBuf);
			DateTime_GetSystemtime(GetDlgItem(hwndDlg, IDC_TIME_TIMESTAMP), &st);
			st.wDay = stBuf.wDay;
			st.wDayOfWeek = stBuf.wDayOfWeek;
			st.wMonth = stBuf.wMonth;
			st.wYear = stBuf.wYear;
			GetLocalTime(&stBuf);
			if (SystemTimeToTimeStamp(&st, &timestamp)) {
				/* set to current date if earlier */
				if (timestamp < time(NULL)) {
					st.wDay = stBuf.wDay;
					st.wDayOfWeek = stBuf.wDayOfWeek;
					st.wMonth = stBuf.wMonth;
					st.wYear = stBuf.wYear;
					if (SystemTimeToTimeStamp(&st, &timestamp)) {
						/* step one day up if still earlier */
						if (timestamp < time(NULL)) {
							timestamp += 24 * 60 * 60;
							TimeStampToSystemTime(timestamp, &st);
						}
					}
				}
			}
			DateTime_SetRange(GetDlgItem(hwndDlg, IDC_DATE_TIMESTAMP), GDTR_MIN, &stBuf);
			DateTime_SetRange(GetDlgItem(hwndDlg, IDC_TIME_TIMESTAMP), GDTR_MIN, &stBuf);
			DateTime_SetSystemtime(GetDlgItem(hwndDlg, IDC_DATE_TIMESTAMP), GDT_VALID, &st);
			DateTime_SetSystemtime(GetDlgItem(hwndDlg, IDC_TIME_TIMESTAMP), GDT_VALID, &st);
		}
		return TRUE;

	case WM_NOTIFY:
		switch (((NMHDR*)lParam)->idFrom) {
		case IDC_TIME_TIMESTAMP:
		case IDC_DATE_TIMESTAMP:
			switch (((NMHDR*)lParam)->code) {
			case DTN_CLOSEUP:
			case NM_KILLFOCUS:
				PostMessage(hwndDlg, M_CHECK_DATETIME, 0, 0);
				return TRUE;
			}
		}
		break;

	case WM_COMMAND:
		switch (LOWORD(wParam)) {
		case IDC_CHECK_MESSAGE:
		case IDC_CHECK_FILETRANSFER:
		case IDC_CHECK_IDLE:
		case IDC_CHECK_CPUUSAGE:
		case IDC_CHECK_STATUS:
		case IDC_CHECK_SPECIFICTIME:
		case IDC_RADIO_STTIME:
		case IDC_RADIO_STCOUNTDOWN:
			SendMessage(hwndDlg, M_ENABLE_SUBCTLS, 0, 0);
			return TRUE;

		case IDC_EDIT_COUNTDOWN:
			if (HIWORD(wParam) == EN_KILLFOCUS) {
				if ((int)GetDlgItemInt(hwndDlg, IDC_EDIT_COUNTDOWN, NULL, TRUE) < 1) {
					SendDlgItemMessage(hwndDlg, IDC_SPIN_COUNTDOWN, UDM_SETPOS, 0, MAKELPARAM(1, 0));
					SetDlgItemInt(hwndDlg, IDC_EDIT_COUNTDOWN, 1, FALSE);
				}
				return TRUE;
			}
			break;

		case IDC_EDIT_CPUUSAGE:
			if (HIWORD(wParam) == EN_KILLFOCUS) {
				WORD val = (WORD)GetDlgItemInt(hwndDlg, IDC_EDIT_CPUUSAGE, NULL, FALSE);
				if (val < 1) val = 1;
				else if (val>100) val = 100;
				SendDlgItemMessage(hwndDlg, IDC_SPIN_CPUUSAGE, UDM_SETPOS, 0, MAKELPARAM(val, 0));
				SetDlgItemInt(hwndDlg, IDC_EDIT_CPUUSAGE, val, FALSE);
				return TRUE;
			}
			break;

		case IDC_URL_IDLE:
			{
				OPENOPTIONSDIALOG ood;
				ood.cbSize = sizeof(ood);
				ood.pszGroup = "Status"; /* autotranslated */
				ood.pszPage = "Idle"; /* autotranslated */
				ood.pszTab = NULL;
				Options_Open(&ood);
				return TRUE;
			}

		case IDC_COMBO_SHUTDOWNTYPE:
			if (HIWORD(wParam) == CBN_SELCHANGE)
				SendMessage(hwndDlg, M_UPDATE_SHUTDOWNDESC, 0, lParam);
			return TRUE;

		case IDOK: /* save settings and start watcher */
			ShowWindow(hwndDlg, SW_HIDE);
			/* message text */
			{
				HWND hwndEdit = GetDlgItem(hwndDlg, IDC_EDIT_MESSAGE);
				int len = GetWindowTextLength(hwndEdit) + 1;
				TCHAR *pszText = (TCHAR*)mir_alloc(len*sizeof(TCHAR));
				if (pszText != NULL && GetWindowText(hwndEdit, pszText, len + 1)) {
					TrimString(pszText);
					db_set_ts(NULL, "AutoShutdown", "Message", pszText);
				}
				mir_free(pszText); /* does NULL check */
			}
			/* timestamp */
			{
				SYSTEMTIME st;
				time_t timestamp;
				DateTime_GetSystemtime(GetDlgItem(hwndDlg, IDC_TIME_TIMESTAMP), &st); /* time gets synchronized */
				if (!SystemTimeToTimeStamp(&st, &timestamp))
					timestamp = time(NULL);
				db_set_dw(NULL, "AutoShutdown", "TimeStamp", (DWORD)timestamp);
			}
			/* shutdown type */
			{
				int index = SendDlgItemMessage(hwndDlg, IDC_COMBO_SHUTDOWNTYPE, CB_GETCURSEL, 0, 0);
				if (index != LB_ERR)
					db_set_b(NULL, "AutoShutdown", "ShutdownType", (BYTE)SendDlgItemMessage(hwndDlg, IDC_COMBO_SHUTDOWNTYPE, CB_GETITEMDATA, (WPARAM)index, 0));
				index = SendDlgItemMessage(hwndDlg, IDC_COMBO_COUNTDOWNUNIT, CB_GETCURSEL, 0, 0);
				if (index != LB_ERR)
					db_set_dw(NULL, "AutoShutdown", "CountdownUnit", (DWORD)SendDlgItemMessage(hwndDlg, IDC_COMBO_COUNTDOWNUNIT, CB_GETITEMDATA, (WPARAM)index, 0));
				db_set_dw(NULL, "AutoShutdown", "Countdown", (DWORD)GetDlgItemInt(hwndDlg, IDC_EDIT_COUNTDOWN, NULL, FALSE));
				db_set_b(NULL, "AutoShutdown", "CpuUsageThreshold", (BYTE)GetDlgItemInt(hwndDlg, IDC_EDIT_CPUUSAGE, NULL, FALSE));
			}
			/* watcher type */
			{
				WORD watcherType = (WORD)(IsDlgButtonChecked(hwndDlg, IDC_RADIO_STTIME) ? SDWTF_ST_TIME : SDWTF_ST_COUNTDOWN);
				if (IsDlgButtonChecked(hwndDlg, IDC_CHECK_SPECIFICTIME)) watcherType |= SDWTF_SPECIFICTIME;
				if (IsDlgButtonChecked(hwndDlg, IDC_CHECK_MESSAGE)) watcherType |= SDWTF_MESSAGE;
				if (IsDlgButtonChecked(hwndDlg, IDC_CHECK_FILETRANSFER)) watcherType |= SDWTF_FILETRANSFER;
				if (IsDlgButtonChecked(hwndDlg, IDC_CHECK_IDLE)) watcherType |= SDWTF_IDLE;
				if (IsDlgButtonChecked(hwndDlg, IDC_CHECK_STATUS)) watcherType |= SDWTF_STATUS;
				if (IsDlgButtonChecked(hwndDlg, IDC_CHECK_CPUUSAGE)) watcherType |= SDWTF_CPUUSAGE;
				db_set_w(NULL, "AutoShutdown", "WatcherFlags", watcherType);
				ServiceStartWatcher(0, watcherType);
			}
			DestroyWindow(hwndDlg);
			return TRUE;
			// fall through 

		case IDCANCEL: /* WM_CLOSE */
			DestroyWindow(hwndDlg);
			SetShutdownToolbarButton(false);
			SetShutdownMenuItem(false);
			return TRUE;
		}
		break;
	}
	return FALSE;
}