Exemple #1
0
// temporary read the current option to memory
// but does not write to the database
void ReadPopupOpt(HWND hdlg) 
{
	TCHAR text[MAX_TEXT_SIZE];
	int num;
	TCHAR str[512];

	// popup colour
	opt.TextColour = SendDlgItemMessage(hdlg,IDC_TEXTCOLOUR,CPM_GETCOLOUR,0,0);
	opt.BGColour = SendDlgItemMessage(hdlg,IDC_BGCOLOUR,CPM_GETCOLOUR,0,0);

	// get delay time
	GetDlgItemText(hdlg, IDC_DELAY, str, sizeof(str));
	num = _ttoi(str);
	opt.pDelay = num;

	// other options
	opt.UseWinColors = (BYTE)IsDlgButtonChecked(hdlg, IDC_USEWINCOLORS);
	opt.UsePopup = (BYTE)IsDlgButtonChecked(hdlg, IDC_E);
	opt.UpdatePopup = (BYTE)IsDlgButtonChecked(hdlg, IDC_POP1);
	opt.AlertPopup = (BYTE)IsDlgButtonChecked(hdlg, IDC_POP2);
	opt.PopupOnChange = (BYTE)IsDlgButtonChecked(hdlg, IDC_CH);
	opt.ShowWarnings = (BYTE)IsDlgButtonChecked(hdlg, IDC_W);

	// popup texts
	wfree(&opt.pText);
	wfree(&opt.pTitle);
	GetDlgItemText(hdlg, IDC_PText, text, MAX_TEXT_SIZE);
	wSetData(&opt.pText, text);
	GetDlgItemText(hdlg, IDC_PTitle, text, MAX_TEXT_SIZE);
	wSetData(&opt.pTitle, text);
}
Exemple #2
0
// set a string to default
// in = string to determine which field to set default "CBNEHXPp"
void SetTextDefault(const char* in)
{
	TCHAR str[MAX_TEXT_SIZE];

	if (strchr(in, 'C') != NULL) {
		_tcsncpy(str, C_DEFAULT, MAX_TEXT_SIZE - 1);
		wSetData(&opt.cText, str);
	}
	if (strchr(in, 'b') != NULL) {
		_tcsncpy(str, b_DEFAULT, MAX_TEXT_SIZE - 1);
		wSetData(&opt.bTitle, str);
	}
	if (strchr(in, 'B') != NULL) {
		_tcsncpy(str, B_DEFAULT, MAX_TEXT_SIZE - 1);
		wSetData(&opt.bText, str);
	}
	if (strchr(in, 'N') != NULL) {
		_tcsncpy(str, N_DEFAULT, MAX_TEXT_SIZE - 1);
		wSetData(&opt.nText, str);
	}
	if (strchr(in, 'E') != NULL) {
		_tcsncpy(str, E_DEFAULT, MAX_TEXT_SIZE - 1);
		wSetData(&opt.eText, str);
	}
	if (strchr(in, 'H') != NULL) {
		_tcsncpy(str, H_DEFAULT, MAX_TEXT_SIZE - 1);
		wSetData(&opt.hText, str);
	}
	if (strchr(in, 'X') != NULL) {
		_tcsncpy(str, X_DEFAULT, MAX_TEXT_SIZE - 1);
		wSetData(&opt.xText, str);
	}
	if (strchr(in, 'P') != NULL) {
		_tcsncpy(str, P_DEFAULT, MAX_TEXT_SIZE - 1);
		wSetData(&opt.pTitle, str);
	}
	if (strchr(in, 'p') != NULL) {
		_tcsncpy(str, p_DEFAULT, MAX_TEXT_SIZE - 1);
		wSetData(&opt.pText, str);
	}
	if (strchr(in, 'S') != NULL) {
		_tcsncpy(str, s_DEFAULT, MAX_TEXT_SIZE - 1);
		wSetData(&opt.sText, str);
	}
}
Exemple #3
0
// add a new update item into the current list
void WICondListAdd(char *str, WICONDLIST *List)
{
	WICONDITEM *newItem = (WICONDITEM*)mir_alloc(sizeof(WICONDITEM));
	wSetData(&newItem->Item, str);
	CharLowerBuff(newItem->Item, (DWORD)mir_tstrlen(newItem->Item));
	newItem->Next = NULL;
	if (List->Tail == NULL)	List->Head = newItem;
	else List->Tail->Next = newItem;
	List->Tail = newItem;
}
Exemple #4
0
// load the station data from a file
// pszFile = the file name + path for the ini file to be loaded
// pszShortFile = the file name of the ini file, but not including the path
// Data = the struct to load the ini content to, and return to previous function
static void LoadStationData(TCHAR *pszFile, TCHAR *pszShortFile, WIDATA *Data)
{
	WIDATAITEM DataItem;
	char *Group, *Temp;
	char *ValName, *Value;

	static const char *statusStr[10] =
	{
		"LIGHTNING",
		"FOG",
		"SNOW SHOWER",
		"SNOW",
		"RAIN SHOWER",
		"RAIN",
		"PARTLY CLOUDY",
		"CLOUDY",
		"SUNNY",
		"N/A"
	};

	// clean up old stuff
	memset(Data, 0, sizeof(*Data));
	Data->Enabled = FALSE;

	// open the ini file
	FILE *pfile = _tfsopen(pszFile, _T("rt"), _SH_DENYWR);
	if (pfile != NULL) {
		char Line[4096];
		fgets(Line, _countof(Line), pfile);
		TrimString(Line);

		// make sure it is a valid weather protocol ini file
		if (!mir_strcmp(Line, "[Weather 0.3.x Update Data]"))
			Data->InternalVer = 1;
		else if (!mir_strcmp(Line, "[Weather 0.3.x Update Data 1.1]"))
			Data->InternalVer = 2;
		else if (!mir_strcmp(Line, "[Weather 0.3.x Update Data 1.1a]"))
			Data->InternalVer = 3;
		else if (!mir_strcmp(Line, "[Weather 0.3.x Update Data 1.2]"))
			Data->InternalVer = 4;
		else if (!mir_strcmp(Line, "[Weather 0.3.x Update Data 1.3]"))
			Data->InternalVer = 5;
		else if (!mir_strcmp(Line, "[Weather 0.3.x Update Data 1.4]"))
			Data->InternalVer = 6;
		else if (!mir_strcmp(Line, "[Weather 0.3.x Update Data 1.5]"))
			Data->InternalVer = 7;
		else {
			TCHAR str[4096];
			mir_sntprintf(str, TranslateT("Invalid ini format for: %s"), pszFile);
			MessageBox(NULL, str, TranslateT("Weather Protocol"), MB_OK | MB_ICONERROR);
			fclose(pfile);
			return;
		}

		// initialize all data fields
		Group = "";

		Data->DisplayName = _T("");
		Data->InternalName = _T("");
		Data->Description = _T("");
		Data->Author = _T("");
		Data->Version = _T("");
		Data->DefaultURL = "";
		Data->DefaultMap = _T("");
		Data->UpdateURL = "";
		Data->UpdateURL2 = "";
		Data->UpdateURL3 = "";
		Data->UpdateURL4 = "";
		Data->Cookie = "";
		Data->UserAgent = "";
		Data->IDSearch.SearchURL = "";
		Data->IDSearch.NotFoundStr = _T("");
		Data->NameSearch.SearchURL = "";
		Data->NameSearch.NotFoundStr = _T("");
		Data->NameSearch.SingleStr = _T("");
		Data->NameSearch.Single.First = _T("");
		Data->NameSearch.Multiple.First = _T("");
		Data->IDSearch.Available = FALSE;
		Data->NameSearch.Single.Available = FALSE;
		Data->NameSearch.Multiple.Available = FALSE;
		wSetData(&Data->FileName, pszFile);
		wSetData(&Data->ShortFileName, pszShortFile);

		ResetDataItem(&Data->IDSearch.Name, _T("ID Search - Station Name"));
		ResetDataItem(&Data->NameSearch.Single.Name, _T("Name Search Single Result - Station Name"));
		ResetDataItem(&Data->NameSearch.Single.ID, _T("Name Search Single Result - Station ID"));
		ResetDataItem(&Data->NameSearch.Multiple.Name, _T("Name Search Multiple Result - Station Name"));
		ResetDataItem(&Data->NameSearch.Multiple.ID, _T("Name Search Multiple Result - Station ID"));

		DataItem.Name = _T("");
		DataItem.Start = _T("");
		DataItem.End = _T("");
		DataItem.Unit = _T("");
		DataItem.Url = "";
		DataItem.Break = _T("");
		DataItem.Type = 0;

		Temp = "";

		// initialize the linked list for update items
		Data->UpdateDataCount = 0;
		Data->MemUsed = sizeof(WIDATA) + sizeof(WIDATALIST) + (mir_tstrlen(pszShortFile) + mir_tstrlen(pszFile) + 20)*sizeof(TCHAR);
		Data->UpdateData = NULL;
		Data->UpdateDataTail = NULL;

		// initialize the icon assignment list
		for (int i = 0; i < 10; i++)
			WICondListInit(&Data->CondList[i]);

		while (!feof(pfile)) {
			// determine current tag

			if (fgets(Line, _countof(Line), pfile) == NULL)
				break;
			TrimString(Line);

			// if the line is a group header/footer
			if (Line[0] == '[') {
				char *chop = strchr(Line + 1, ']');
				if (chop == NULL)
					continue;

				if (Line[1] != '/') {	// if it is not a footer (for old ini)
					// save the group name
					Temp = (char *)mir_alloc(mir_strlen(Line) + 10);
					strncpy(Temp, Line + 1, chop - Line - 1);
					Temp[chop - Line - 1] = 0;
					wfree(&Group);
					wSetData(&Group, Temp);
					// see if it is a update item, if it is, add a new item to the linked list
					//					if (_stricmp(Group, "HEADER") && _stricmp(Group, "DEFAULT") && _stricmp(Group, "ID SEARCH") && 
					//					strcmpi(Group, "NAME SEARCH"))
					//						wSetData(&DataItem.Name, Group);
					if (_stricmp(Group, "HEADER") && _stricmp(Group, "DEFAULT") && _stricmp(Group, "ID SEARCH") &&
						_stricmp(Group, "NAME SEARCH") && _stricmp(Group, "ICONS")) {
						wSetData(&DataItem.Name, Temp);
						DataItem.Type = WID_NORMAL;
						WIItemListAdd(&DataItem, Data);
						Data->UpdateDataCount++;
					}
					mir_free(Temp);
				}
				else {
					wfree(&Group);
					wSetData(&Group, "");
				}
			}
			// ignore comments and all lines without an '='
			Value = strstr(Line, "=");
			if (Value == NULL)	continue;

			// get the string before '=' (ValName) and after '=' (Value)
			ValName = (char *)mir_alloc(mir_strlen(Line) + 1);
			strncpy(ValName, Line, Value - Line);
			ValName[Value - Line] = 0;
			Value++;
			ConvertBackslashes(Value);
			// store the value for each string
			if (!_stricmp(Group, "HEADER")) {
				if (!_stricmp(ValName, "NAME"))						wSetData(&Data->DisplayName, Value);
				else if (!_stricmp(ValName, "INTERNAL NAME"))	wSetData(&Data->InternalName, Value);
				else if (!_stricmp(ValName, "DESCRIPTION"))		wSetData(&Data->Description, Value);
				else if (!_stricmp(ValName, "AUTHOR")) 			wSetData(&Data->Author, Value);
				else if (!_stricmp(ValName, "VERSION")) 			wSetData(&Data->Version, Value);
			}
			else if (!_stricmp(Group, "DEFAULT")) {
				if (!_stricmp(ValName, "DEFAULT URL"))				wSetData(&Data->DefaultURL, Value);
				else if (!_stricmp(ValName, "DEFAULT MAP"))		wSetData(&Data->DefaultMap, Value);
				else if (!_stricmp(ValName, "UPDATE URL"))		wSetData(&Data->UpdateURL, Value);
				else if (!_stricmp(ValName, "UPDATE URL2"))		wSetData(&Data->UpdateURL2, Value);
				else if (!_stricmp(ValName, "UPDATE URL3"))		wSetData(&Data->UpdateURL3, Value);
				else if (!_stricmp(ValName, "UPDATE URL4"))		wSetData(&Data->UpdateURL4, Value);
				else if (!_stricmp(ValName, "COOKIE"))				wSetData(&Data->Cookie, Value);
				else if (!_stricmp(ValName, "USERAGENT"))			wSetData(&Data->UserAgent, Value);
			}
			else if (!_stricmp(Group, "ID SEARCH")) {
				if (!_stricmp(ValName, "AVAILABLE")) {
					if (!_stricmp(Value, "TRUE"))				Data->IDSearch.Available = TRUE;
					else										Data->IDSearch.Available = FALSE;
				}
				else if (!_stricmp(ValName, "SEARCH URL"))		wSetData(&Data->IDSearch.SearchURL, Value);
				else if (!_stricmp(ValName, "NOT FOUND STR"))	wSetData(&Data->IDSearch.NotFoundStr, Value);
				else if (!_stricmp(ValName, "NAME START")) 		wSetData(&Data->IDSearch.Name.Start, Value);
				else if (!_stricmp(ValName, "NAME END")) 		wSetData(&Data->IDSearch.Name.End, Value);
			}
			else if (!_stricmp(Group, "NAME SEARCH")) {
				if (!_stricmp(ValName, "SINGLE RESULT")) {
					if (!_stricmp(Value, "TRUE"))				Data->NameSearch.Single.Available = TRUE;
					else										Data->NameSearch.Single.Available = FALSE;
				}
				else if (!_stricmp(ValName, "MULTIPLE RESULT")) {
					if (!_stricmp(Value, "TRUE"))				Data->NameSearch.Multiple.Available = TRUE;
					else										Data->NameSearch.Multiple.Available = FALSE;
				}
				else if (!_stricmp(ValName, "SEARCH URL"))		wSetData(&Data->NameSearch.SearchURL, Value);
				else if (!_stricmp(ValName, "NOT FOUND STR"))	wSetData(&Data->NameSearch.NotFoundStr, Value);
				else if (!_stricmp(ValName, "SINGLE RESULT STR")) wSetData(&Data->NameSearch.SingleStr, Value);
				else if (!_stricmp(ValName, "SINGLE FIRST"))	wSetData(&Data->NameSearch.Single.First, Value);
				else if (!_stricmp(ValName, "SINGLE NAME START"))wSetData(&Data->NameSearch.Single.Name.Start, Value);
				else if (!_stricmp(ValName, "SINGLE NAME END")) wSetData(&Data->NameSearch.Single.Name.End, Value);
				else if (!_stricmp(ValName, "SINGLE ID START"))	wSetData(&Data->NameSearch.Single.ID.Start, Value);
				else if (!_stricmp(ValName, "SINGLE ID END")) 	wSetData(&Data->NameSearch.Single.ID.End, Value);
				else if (!_stricmp(ValName, "MULT FIRST"))		wSetData(&Data->NameSearch.Multiple.First, Value);
				else if (!_stricmp(ValName, "MULT NAME START"))	wSetData(&Data->NameSearch.Multiple.Name.Start, Value);
				else if (!_stricmp(ValName, "MULT NAME END")) 	wSetData(&Data->NameSearch.Multiple.Name.End, Value);
				else if (!_stricmp(ValName, "MULT ID START"))	wSetData(&Data->NameSearch.Multiple.ID.Start, Value);
				else if (!_stricmp(ValName, "MULT ID END")) 	wSetData(&Data->NameSearch.Multiple.ID.End, Value);
			}
			else if (!_stricmp(Group, "ICONS")) {
				for (int i = 0; i < 10; i++) {
					if (!_stricmp(ValName, statusStr[i])) {
						WICondListAdd(Value, &Data->CondList[i]);
						break;
					}
				}
			}
			else if (Data->UpdateDataCount != 0) {
				if (!_stricmp(ValName, "START")) 			wSetData(&Data->UpdateDataTail->Item.Start, Value);
				else if (!_stricmp(ValName, "SOURCE"))		wSetData(&Data->UpdateDataTail->Item.Start, Value);
				else if (!_stricmp(ValName, "END")) 		wSetData(&Data->UpdateDataTail->Item.End, Value);
				else if (!_stricmp(ValName, "UNIT")) 		wSetData(&Data->UpdateDataTail->Item.Unit, Value);
				else if (!_stricmp(ValName, "URL")) 		wSetData(&Data->UpdateDataTail->Item.Url, Value);
				else if (!_stricmp(ValName, "HIDDEN")) {
					if (!_stricmp(Value, "TRUE")) {
						TCHAR *nm = Data->UpdateDataTail->Item.Name;
						size_t len = mir_tstrlen(nm) + 1;

						Data->UpdateDataTail->Item.Name = nm = (TCHAR*)mir_realloc(nm, sizeof(TCHAR)*(len + 3));
						memmove(nm + 1, nm, len*sizeof(TCHAR));
						*nm = '#';
					}
				}
				else if (!_stricmp(ValName, "SET DATA")) {
					Data->UpdateDataTail->Item.Type = WID_SET;
					wSetData(&Data->UpdateDataTail->Item.End, Value);
				}
				else if (!_stricmp(ValName, "BREAK DATA")) {
					Data->UpdateDataTail->Item.Type = WID_BREAK;
					wSetData(&Data->UpdateDataTail->Item.Break, Value);
				}
			}
			// recalculate memory used
			Data->MemUsed += (mir_strlen(Value) + 10);
			wfree(&ValName);
		}
		// calcualate memory used for the ini and close the file
		Data->MemUsed += sizeof(WIDATAITEMLIST)*Data->UpdateDataCount;
		Data->Enabled = TRUE;	// enable the service
		fclose(pfile);
		wfree(&Group);
	}
}
Exemple #5
0
// load options from database + set default if the setting does not exist
void LoadOptions(void)
{
	memset(&opt, 0, sizeof(opt));

	// main options
	opt.StartupUpdate = db_get_b(NULL, WEATHERPROTONAME, "StartupUpdate", true);
	opt.AutoUpdate = db_get_b(NULL, WEATHERPROTONAME, "AutoUpdate", true);
	opt.UpdateTime = db_get_w(NULL, WEATHERPROTONAME, "UpdateTime", 30);
	opt.NoProtoCondition = db_get_b(NULL, WEATHERPROTONAME, "NoStatus", true);
	opt.UpdateOnlyConditionChanged = db_get_b(NULL, WEATHERPROTONAME, "CondChangeAsUpdate", true);
	opt.RemoveOldData = db_get_b(NULL, WEATHERPROTONAME, "RemoveOld", false);
	opt.MakeItalic = db_get_b(NULL, WEATHERPROTONAME, "MakeItalic", true);
	opt.AvatarSize = db_get_b(NULL, WEATHERPROTONAME, "AvatarSize", 128);

	// units
	opt.tUnit = db_get_w(NULL, WEATHERPROTONAME, "tUnit", 1);
	opt.wUnit = db_get_w(NULL, WEATHERPROTONAME, "wUnit", 2);
	opt.vUnit = db_get_w(NULL, WEATHERPROTONAME, "vUnit", 1);
	opt.pUnit = db_get_w(NULL, WEATHERPROTONAME, "pUnit", 4);
	opt.dUnit = db_get_w(NULL, WEATHERPROTONAME, "dUnit", 1);
	opt.eUnit = db_get_w(NULL, WEATHERPROTONAME, "eUnit", 2);

	ptrT szValue(db_get_tsa(NULL, WEATHERPROTONAME, "DegreeSign"));
	_tcsncpy_s(opt.DegreeSign, (szValue == NULL) ? _T("") : szValue, _TRUNCATE);

	opt.DoNotAppendUnit = db_get_b(NULL, WEATHERPROTONAME, "DoNotAppendUnit", 0);
	opt.NoFrac = db_get_b(NULL, WEATHERPROTONAME, "NoFractions", 0);

	// texts
	if (szValue = db_get_tsa(NULL, WEATHERPROTONAME, "DisplayText"))
		wSetData(&opt.cText, TranslateTS(szValue));
	else
		SetTextDefault("C");

	if (szValue = db_get_tsa(NULL, WEATHERPROTONAME, "BriefTextTitle"))
		wSetData(&opt.bTitle, TranslateTS(szValue));
	else
		SetTextDefault("b");

	if (szValue = db_get_tsa(NULL, WEATHERPROTONAME, "BriefText"))
		wSetData(&opt.bText, TranslateTS(szValue));
	else
		SetTextDefault("B");

	if (szValue = db_get_tsa(NULL, WEATHERPROTONAME, "NoteText"))
		wSetData(&opt.nText, TranslateTS(szValue));
	else
		SetTextDefault("N");

	if (szValue = db_get_tsa(NULL, WEATHERPROTONAME, "ExtText"))
		wSetData(&opt.eText, TranslateTS(szValue));
	else
		SetTextDefault("E");

	if (szValue = db_get_tsa(NULL, WEATHERPROTONAME, "HistoryText"))
		wSetData(&opt.hText, TranslateTS(szValue));
	else
		SetTextDefault("H");

	if (szValue = db_get_tsa(NULL, WEATHERPROTONAME, "ExtraText"))
		wSetData(&opt.xText, TranslateTS(szValue));
	else
		SetTextDefault("X");

	if (szValue = db_get_tsa(NULL, WEATHERPROTONAME, "StatusText"))
		wSetData(&opt.sText, TranslateTS(szValue));
	else
		SetTextDefault("S");

	// advanced
	opt.DisCondIcon = db_get_b(NULL, WEATHERPROTONAME, "DisableConditionIcon", false);
	// popup options
	opt.UsePopup = db_get_b(NULL, WEATHERPROTONAME, "UsePopUp", true);
	opt.UpdatePopup = db_get_b(NULL, WEATHERPROTONAME, "UpdatePopup", true);
	opt.AlertPopup = db_get_b(NULL, WEATHERPROTONAME, "AlertPopup", true);
	opt.PopupOnChange = db_get_b(NULL, WEATHERPROTONAME, "PopUpOnChange", true);
	opt.ShowWarnings = db_get_b(NULL, WEATHERPROTONAME, "ShowWarnings", true);
	// popup colors
	opt.BGColour = db_get_dw(NULL, WEATHERPROTONAME, "BackgroundColour", GetSysColor(COLOR_BTNFACE));
	opt.TextColour = db_get_dw(NULL, WEATHERPROTONAME, "TextColour", GetSysColor(COLOR_WINDOWTEXT));
	opt.UseWinColors = (BOOL)db_get_b(NULL, WEATHERPROTONAME, "UseWinColors", false);
	// popup actions
	opt.LeftClickAction = db_get_dw(NULL, WEATHERPROTONAME, "LeftClickAction", IDM_M2);
	opt.RightClickAction = db_get_dw(NULL, WEATHERPROTONAME, "RightClickAction", IDM_M1);
	// popup delay
	opt.pDelay = db_get_dw(NULL, WEATHERPROTONAME, "PopupDelay", 0);
	// popup texts
	if (szValue = db_get_tsa(NULL, WEATHERPROTONAME, "PopupTitle"))
		wSetData(&opt.pTitle, szValue);
	else
		SetTextDefault("P");

	if (szValue = db_get_tsa(NULL, WEATHERPROTONAME, "PopupText"))
		wSetData(&opt.pText, szValue);
	else
		SetTextDefault("p");

	// misc
	if (szValue = db_get_tsa(NULL, WEATHERPROTONAME, "Default"))
		_tcsncpy_s(opt.Default, szValue, _TRUNCATE);
	else
		opt.Default[0] = 0;
}
Exemple #6
0
INT_PTR CALLBACK DlgProcText(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
	RECT rc, pos;
	HWND button;
	HMENU hMenu, hMenu1;
	TCHAR str[4096];
	switch (msg) {
	case WM_INITDIALOG:
		opt_startup = TRUE;
		// set windows position, make it top-most
		GetWindowRect(hdlg, &rc);
		SetWindowPos(hdlg, HWND_TOPMOST, rc.left, rc.top, 0, 0, SWP_NOSIZE);
		TranslateDialogDefault(hdlg);
		// generate the display text for variable list
		_tcsncpy(str, VAR_LIST_OPT, _countof(str) - 1);
		SetDlgItemText(hdlg, IDC_VARLIST, str);

		// make the more variable and other buttons flat
		SendDlgItemMessage(hdlg, IDC_MORE, BUTTONSETASFLATBTN, TRUE, 0);
		SendDlgItemMessage(hdlg, IDC_TM1, BUTTONSETASFLATBTN, TRUE, 0);
		SendDlgItemMessage(hdlg, IDC_TM2, BUTTONSETASFLATBTN, TRUE, 0);
		SendDlgItemMessage(hdlg, IDC_TM3, BUTTONSETASFLATBTN, TRUE, 0);
		SendDlgItemMessage(hdlg, IDC_TM4, BUTTONSETASFLATBTN, TRUE, 0);
		SendDlgItemMessage(hdlg, IDC_TM5, BUTTONSETASFLATBTN, TRUE, 0);
		SendDlgItemMessage(hdlg, IDC_TM6, BUTTONSETASFLATBTN, TRUE, 0);
		SendDlgItemMessage(hdlg, IDC_TM7, BUTTONSETASFLATBTN, TRUE, 0);
		SendDlgItemMessage(hdlg, IDC_TM8, BUTTONSETASFLATBTN, TRUE, 0);
		SendDlgItemMessage(hdlg, IDC_RESET, BUTTONSETASFLATBTN, TRUE, 0);
		// load the settings
		LoadTextSettings(hdlg);
		opt_startup = FALSE;
		return TRUE;

	case WM_COMMAND:
		if (opt_startup)	return TRUE;
		switch (LOWORD(wParam)) {
		case IDC_CTEXT:
		case IDC_BTITLE:
		case IDC_BTEXT:
		case IDC_NTEXT:
		case IDC_XTEXT:
		case IDC_ETEXT:
		case IDC_HTEXT:
		case IDC_BTITLE2:
			if (HIWORD(wParam) == EN_CHANGE)
				SendMessage(GetParent(hdlg), PSM_CHANGED, 0, 0);
			break;

		case IDC_MORE:
			// display custom variables list
			MoreVarList();
			break;

		case IDC_TM1:
		case IDC_TM2:
		case IDC_TM3:
		case IDC_TM4:
		case IDC_TM5:
		case IDC_TM6:
		case IDC_TM7:
		case IDC_TM8:
			// display the menu
			button = GetDlgItem(hdlg, LOWORD(wParam));
			GetWindowRect(button, &pos);
			hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_TMMENU));
			hMenu1 = GetSubMenu(hMenu, 0);
			TranslateMenu(hMenu1);
			switch (TrackPopupMenu(hMenu1, TPM_LEFTBUTTON | TPM_RETURNCMD, pos.left, pos.bottom, 0, hdlg, NULL)) {
			case ID_MPREVIEW:
				{
					// show the preview in a message box, using the weather data from the default station
					WEATHERINFO winfo = LoadWeatherInfo(opt.DefStn);
					GetDisplay(&winfo, *var[LOWORD(wParam) - IDC_TM1], str);
					MessageBox(NULL, str, TranslateT("Weather Protocol Text Preview"), MB_OK | MB_TOPMOST);
					break;
				}
			case ID_MRESET:
				unsigned varo = LOWORD(wParam) - IDC_TM1;
				// remove the old setting from db and free memory
				TCHAR* vartmp = *var[varo];
				wfree(&vartmp);
				SetTextDefault(varname[varo]);
				SetDlgItemText(hdlg, cname[varo], *var[varo]);
				break;
			}
			DestroyMenu(hMenu);
			break;

		case IDC_RESET:
			// left click action selection menu
			button = GetDlgItem(hdlg, IDC_RESET);
			GetWindowRect(button, &pos);
			hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_TMENU));
			hMenu1 = GetSubMenu(hMenu, 0);
			TranslateMenu(hMenu1);
			switch (TrackPopupMenu(hMenu1, TPM_LEFTBUTTON | TPM_RETURNCMD, pos.left, pos.bottom, 0, hdlg, NULL)) {
			case ID_T1:
				// reset to the strings in memory, discard all changes
				LoadTextSettings(hdlg);
				break;

			case ID_T2:
				// reset to the default setting
				FreeTextVar();
				SetTextDefault("CbBENHX");
				LoadTextSettings(hdlg);
				break;
			}
			DestroyMenu(hMenu);
			break;
		}
		return TRUE;
	case WM_NOTIFY:
		switch (((LPNMHDR)lParam)->code) {
		case PSN_APPLY:
			// save the option
			TCHAR textstr[MAX_TEXT_SIZE];
			// free memory for old settings
			FreeTextVar();
			// save new settings to memory
			GetDlgItemText(hdlg, IDC_CTEXT, textstr, _countof(textstr));
			wSetData(&opt.cText, textstr);
			GetDlgItemText(hdlg, IDC_BTEXT, textstr, _countof(textstr));
			wSetData(&opt.bText, textstr);
			GetDlgItemText(hdlg, IDC_BTITLE, textstr, _countof(textstr));
			wSetData(&opt.bTitle, textstr);
			GetDlgItemText(hdlg, IDC_ETEXT, textstr, _countof(textstr));
			wSetData(&opt.eText, textstr);
			GetDlgItemText(hdlg, IDC_NTEXT, textstr, _countof(textstr));
			wSetData(&opt.nText, textstr);
			GetDlgItemText(hdlg, IDC_HTEXT, textstr, _countof(textstr));
			wSetData(&opt.hText, textstr);
			GetDlgItemText(hdlg, IDC_XTEXT, textstr, _countof(textstr));
			wSetData(&opt.xText, textstr);
			GetDlgItemText(hdlg, IDC_BTITLE2, textstr, _countof(textstr));
			wSetData(&opt.sText, textstr);
			SaveOptions();
			UpdateAllInfo(0, 0);
			break;
		}
		break;
	}
	return FALSE;
}