Beispiel #1
0
int CVkProto::OnChatEvent(WPARAM, LPARAM lParam)
{
	GCHOOK *gch = (GCHOOK*)lParam;
	if (gch == NULL)
		return 0;

	if (lstrcmpiA(gch->pDest->pszModule, m_szModuleName))
		return 0;

	CVkChatInfo *cc = GetChatById(gch->pDest->ptszID);
	if (cc == NULL)
		return 0;

	switch (gch->pDest->iType) {
	case GC_USER_MESSAGE:
		if (m_bOnline && lstrlen(gch->ptszText) > 0) {
			TCHAR *buf = NEWTSTR_ALLOCA(gch->ptszText);
			rtrimt(buf);
			UnEscapeChatTags(buf);
			
			Push(new AsyncHttpRequest(this, REQUEST_GET, "/method/messages.send.json", true, &CVkProto::OnSendChatMsg)
				<< INT_PARAM("type", 1) << INT_PARAM("chat_id", cc->m_chatid) << TCHAR_PARAM("message", buf));
		}

	case GC_USER_LOGMENU:
		LogMenuHook(cc, gch);
		break;

	case GC_USER_NICKLISTMENU:
		NickMenuHook(cc, gch);
		break;
	}
	return 0;
}
Beispiel #2
0
void CMsnProto::displayEmailCount(MCONTACT hContact)
{
	if (!emailEnabled || getByte("DisableHotmailCL", 0)) return;

	TCHAR* name = GetContactNameT(hContact);
	if (name == NULL) return;

	TCHAR* ch = name - 1;
	do {
		ch = _tcschr(ch + 1, '[');
	} while (ch && !_istdigit(ch[1]));
	if (ch) *ch = 0;
	rtrimt(name);

	TCHAR szNick[128];
	mir_sntprintf(szNick, getByte("DisableHotmailJunk", 0) ? _T("%s [%d]") : _T("%s [%d][%d]"), name, mUnreadMessages, mUnreadJunkEmails);

	nickChg = true;
	setTString(hContact, "Nick", szNick);
	nickChg = false;
}
Beispiel #3
0
int CMsnProto::MSN_GCEventHook(WPARAM, LPARAM lParam)
{
	GCHOOK *gch = (GCHOOK*)lParam;
	if (!gch)
		return 1;

	if (_stricmp(gch->pDest->pszModule, m_szModuleName)) return 0;

	switch (gch->pDest->iType) {
	case GC_SESSION_TERMINATE:
		{
			GCThreadData* thread = MSN_GetThreadByChatId(gch->pDest->ptszID);
			if (thread != NULL) {
				m_arGCThreads.remove(thread);
				for (int i = 0; i < thread->mJoinedContacts.getCount(); i++)
					delete thread->mJoinedContacts[i];
				delete thread;
			}
		}
		break;

	case GC_USER_MESSAGE:
		if (gch->ptszText && gch->ptszText[0]) {
			GCThreadData* thread = MSN_GetThreadByChatId(gch->pDest->ptszID);
			if (thread) {
				TCHAR* pszMsg = UnEscapeChatTags(NEWTSTR_ALLOCA(gch->ptszText));
				rtrimt(pszMsg); // remove the ending linebreak
				msnNsThread->sendMessage('N', thread->szEmail, thread->netId, UTF8(pszMsg), 0);

				DBVARIANT dbv;
				int bError = getTString("Nick", &dbv);

				GCDEST gcd = { m_szModuleName, gch->pDest->ptszID, GC_EVENT_MESSAGE };
				GCEVENT gce = { sizeof(gce), &gcd };
				gce.dwFlags = GCEF_ADDTOLOG;
				gce.ptszNick = bError ? _T("") : dbv.ptszVal;
				gce.ptszUID = mir_a2t(MyOptions.szEmail);
				gce.time = time(NULL);
				gce.ptszText = gch->ptszText;
				gce.bIsMe = TRUE;
				CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gce);

				mir_free((void*)gce.ptszUID);
				if (!bError)
					db_free(&dbv);
			}
		}
		break;

	case GC_USER_CHANMGR:
		DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_CHATROOM_INVITE), NULL, DlgInviteToChat,
			LPARAM(new InviteChatParam(gch->pDest->ptszID, NULL, this)));
		break;

	case GC_USER_PRIVMESS:
		{
			char *email = mir_t2a(gch->ptszUID);
			MCONTACT hContact = MSN_HContactFromEmail(email);
			CallService(MS_MSG_SENDMESSAGE, hContact, 0);
			mir_free(email);
		}
		break;

	case GC_USER_LOGMENU:
		switch (gch->dwData) {
		case 10:
			DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_CHATROOM_INVITE), NULL, DlgInviteToChat,
				LPARAM(new InviteChatParam(gch->pDest->ptszID, NULL, this)));
			break;

		case 20:
			MSN_KillChatSession(gch->pDest->ptszID);
			break;
		}
		break;

	case GC_USER_NICKLISTMENU:
		MCONTACT hContact = MSN_HContactFromEmail(_T2A(gch->ptszUID));

		switch (gch->dwData) {
		case 10:
			CallService(MS_USERINFO_SHOWDIALOG, hContact, 0);
			break;

		case 20:
			CallService(MS_HISTORY_SHOWCONTACTHISTORY, hContact, 0);
			break;

		case 30:
			MSN_Kickuser(gch);
			break;

		case 110:
			MSN_KillChatSession(gch->pDest->ptszID);
			break;

		case 40:
			const TCHAR *pszRole = MSN_GCGetRole(MSN_GetThreadByChatId(gch->pDest->ptszID), _T2A(gch->ptszUID));
			MSN_Promoteuser(gch, (pszRole && !mir_tstrcmp(pszRole, _T("admin"))) ? "user" : "admin");
			break;
		}
		break;
	}

	return 0;
}
Beispiel #4
0
	void list_OnGetTip(CCtrlListView::TEventInfo *evt)
	{
		if (auto pTip = evt->nmlvit) {
			TCHAR profilename[MAX_PATH], tszFullPath[MAX_PATH];
			struct _stat statbuf;
			m_profileList.GetItemText(pTip->iItem, 0, profilename, _countof(profilename));
			mir_sntprintf(tszFullPath, _countof(tszFullPath), _T("%s\\%s\\%s.dat"), m_pd->ptszProfileDir, profilename, profilename);
			_tstat(tszFullPath, &statbuf);
			mir_sntprintf(pTip->pszText, pTip->cchTextMax, _T("%s\n%s: %s\n%s: %s"), tszFullPath, TranslateT("Created"), rtrimt(NEWTSTR_ALLOCA(_tctime(&statbuf.st_ctime))), TranslateT("Modified"), rtrimt(NEWTSTR_ALLOCA(_tctime(&statbuf.st_mtime))));
		}
	}
INT_PTR CALLBACK AddContactDlgProc(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam)
{
	AddDialogParam *acs = (AddDialogParam*)GetWindowLongPtr(hdlg, GWLP_USERDATA);

	switch (msg) {
	case WM_INITDIALOG:
		acs = new AddDialogParam();
		acs->handleType = HANDLE_SEARCHRESULT;
		SetWindowLongPtr(hdlg, GWLP_USERDATA, (LONG_PTR)acs);

		Utils_RestoreWindowPositionNoSize(hdlg, NULL, "AddContact", "");
		TranslateDialogDefault(hdlg);
		SendMessage(hdlg, WM_SETICON, ICON_BIG, (LPARAM)Skin_GetIcon(ICON_ADD,1));
		SendMessage(hdlg, WM_SETICON, ICON_SMALL, (LPARAM)Skin_GetIcon(ICON_ADD));
		HookEventMessage(ME_SKIN2_ICONSCHANGED, hdlg, DM_ADDCONTACT_CHANGEICONS);
		HookEventMessage(ME_PROTO_ACCLISTCHANGED, hdlg, DM_ADDCONTACT_CHANGEACCLIST);
		{
			TCHAR *szGroup;
			for (int i = 1; (szGroup = pcli->pfnGetGroupName(i, NULL)) != NULL; i++) {
				int id = SendDlgItemMessage(hdlg, IDC_GROUP, CB_ADDSTRING, 0, (LPARAM)szGroup);
				SendDlgItemMessage(hdlg, IDC_GROUP, CB_SETITEMDATA, (WPARAM)id, (LPARAM)i);
			}
		}
		SendDlgItemMessage(hdlg, IDC_GROUP, CB_INSERTSTRING, 0, (LPARAM)TranslateT("None"));
		SendDlgItemMessage(hdlg, IDC_GROUP, CB_SETCURSEL, 0, 0);
		{
			ptrA szProto(db_get_sa(NULL, "AddContact", "LastProto"));
			if (szProto)
				acs->proto = szProto;
		}
		if (AddContactDlgAccounts(hdlg, acs)) {
			// By default check these checkboxes
			CheckDlgButton(hdlg, IDC_ADDED, BST_CHECKED);
			CheckDlgButton(hdlg, IDC_AUTH, BST_CHECKED);
			AddContactDlgOpts(hdlg, acs->proto);
			EnableWindow(GetDlgItem(hdlg, IDOK), FALSE);
		}
		break;

	case WM_COMMAND:
		switch (LOWORD(wparam)) {
		case IDC_USERID:
			if (HIWORD(wparam) == EN_CHANGE) {
				TCHAR szUserId[256];
				if (GetDlgItemText(hdlg, IDC_USERID, szUserId, SIZEOF(szUserId))) {
					if (!IsWindowEnabled(GetDlgItem(hdlg, IDOK)))
						EnableWindow(GetDlgItem(hdlg, IDOK), TRUE);
				}
				else if (IsWindowEnabled(GetDlgItem(hdlg, IDOK)))
					EnableWindow(GetDlgItem(hdlg, IDOK), FALSE);
			}
			break;

		case IDC_PROTO:
			if (HIWORD(wparam) == CBN_SELCHANGE || HIWORD(wparam) == CBN_SELENDOK) {
				acs->proto = (char*)SendDlgItemMessage(hdlg, IDC_PROTO, CB_GETITEMDATA, (WPARAM)SendDlgItemMessage(hdlg, IDC_PROTO, CB_GETCURSEL, 0, 0), 0);
				// TODO remember last setting for each proto?
				AddContactDlgOpts(hdlg, acs->proto);
			}
			break;

		case IDC_ADDTEMP:
			AddContactDlgOpts(hdlg, acs->proto, TRUE);
			break;

		case IDC_AUTH:
			{
				DWORD flags = CallProtoService(acs->proto, PS_GETCAPS, PFLAGNUM_4, 0);
				if (flags & PF4_NOCUSTOMAUTH) {
					EnableWindow(GetDlgItem(hdlg, IDC_AUTHREQ), FALSE);
					EnableWindow(GetDlgItem(hdlg, IDC_AUTHGB), FALSE);
				}
				else {
					EnableWindow(GetDlgItem(hdlg, IDC_AUTHREQ), IsDlgButtonChecked(hdlg, IDC_AUTH));
					EnableWindow(GetDlgItem(hdlg, IDC_AUTHGB), IsDlgButtonChecked(hdlg, IDC_AUTH));
				}
			}
			break;

		case IDOK:
			{
				TCHAR szUserId[256];
				GetDlgItemText(hdlg, IDC_USERID, szUserId, SIZEOF(szUserId));

				if (*rtrimt(szUserId) == 0 ||
					(strstr(acs->proto, "GG") && _tcstoul(szUserId, NULL, 10) > INT_MAX) || // Gadu-Gadu protocol
					((CallProtoService(acs->proto, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_NUMERICUSERID) && !_tcstoul(szUserId, NULL, 10)))
				{
					MessageBox(NULL,
						TranslateT("The contact cannot be added to your contact list. Please make sure the contact ID is entered correctly."),
						TranslateT("Add contact"), MB_OK | MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST);
					break;
				}

				PROTOSEARCHRESULT *psr;
				if (strstr(acs->proto, "TLEN")) { // Tlen protocol
					if (_tcschr(szUserId, '@') == NULL) {
						MessageBox(NULL,
							TranslateT("The contact cannot be added to your contact list. Please make sure the contact ID is entered correctly."),
							TranslateT("Add contact"), MB_OK | MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST);
						break;
					}
					psr = (PROTOSEARCHRESULT*)mir_calloc(sizeof(TLEN_SEARCH_RESULT));
					psr->cbSize = sizeof(TLEN_SEARCH_RESULT);
					mir_snprintf(((TLEN_SEARCH_RESULT*)psr)->jid, SIZEOF(((TLEN_SEARCH_RESULT*)psr)->jid), "%S", szUserId);
				}
				else {
					psr = (PROTOSEARCHRESULT*)mir_calloc(sizeof(PROTOSEARCHRESULT));
					psr->cbSize = sizeof(PROTOSEARCHRESULT);
				}

				psr->flags = PSR_TCHAR;
				psr->id = mir_tstrdup(szUserId);
				acs->psr = psr;

				HANDLE hContact = (HANDLE)CallProtoService(acs->proto, PS_ADDTOLIST, IsDlgButtonChecked(hdlg, IDC_ADDTEMP) ? PALF_TEMPORARY : 0, (LPARAM)acs->psr);
				if (hContact == NULL) {
					MessageBox(NULL,
						TranslateT("The contact cannot be added to your contact list. If you are not logged into the selected account, please try to do so. Also, make sure the contact ID is entered correctly."),
						TranslateT("Add contact"), MB_OK | MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST);
					break;
				}

				TCHAR szHandle[256];
				if (GetDlgItemText(hdlg, IDC_MYHANDLE, szHandle, SIZEOF(szHandle)))
					db_set_ts(hContact, "CList", "MyHandle", szHandle);

				int item = SendDlgItemMessage(hdlg, IDC_GROUP, CB_GETCURSEL, 0, 0);
				if (item > 0) {
					item = SendDlgItemMessage(hdlg, IDC_GROUP, CB_GETITEMDATA, item, 0);
					CallService(MS_CLIST_CONTACTCHANGEGROUP, (WPARAM)hContact, item);
				}

				if (!IsDlgButtonChecked(hdlg, IDC_ADDTEMP)) {
					db_unset(hContact, "CList", "NotOnList");

					if (IsDlgButtonChecked(hdlg, IDC_ADDED))
						CallContactService(hContact, PSS_ADDED, 0, 0);

					if (IsDlgButtonChecked(hdlg, IDC_AUTH)) {
						DWORD flags = CallProtoService(acs->proto, PS_GETCAPS, PFLAGNUM_4, 0);
						if (flags & PF4_NOCUSTOMAUTH)
							CallContactService(hContact, PSS_AUTHREQUESTT, 0, 0);
						else {
							TCHAR szReason[512];
							GetDlgItemText(hdlg, IDC_AUTHREQ, szReason, SIZEOF(szReason));
							CallContactService(hContact, PSS_AUTHREQUESTT, 0, (LPARAM)szReason);
						}
					}
				}

				if (GetAsyncKeyState(VK_CONTROL))
					CallService(MS_MSG_SENDMESSAGE, (WPARAM)hContact, (LPARAM)(const char*)NULL);
			}
			// fall through
		case IDCANCEL:
			if (GetParent(hdlg) == NULL)
				DestroyWindow(hdlg);
			else
				EndDialog(hdlg, 0);
		}
		break;

	case WM_CLOSE:
		/* if there is no parent for the dialog, its a modeless dialog and can't be killed using EndDialog() */
		if (GetParent(hdlg) == NULL)
			DestroyWindow(hdlg);
		else
			EndDialog(hdlg, 0);
		break;

	case DM_ADDCONTACT_CHANGEICONS:
		Skin_ReleaseIcon((HICON)SendMessage(hdlg, WM_SETICON, ICON_BIG, (LPARAM)Skin_GetIcon(ICON_ADD, 1)));
		Skin_ReleaseIcon((HICON)SendMessage(hdlg, WM_SETICON, ICON_SMALL, (LPARAM)Skin_GetIcon(ICON_ADD)));
		break;

	case DM_ADDCONTACT_CHANGEACCLIST:
		AddContactDlgAccounts(hdlg, acs);
		break;

	case WM_DESTROY:
		hAddDlg = NULL;
		Skin_ReleaseIcon((HICON)SendMessage(hdlg, WM_SETICON, ICON_BIG, 0));
		Skin_ReleaseIcon((HICON)SendMessage(hdlg, WM_SETICON, ICON_SMALL, 0));
		ImageList_Destroy((HIMAGELIST)SendDlgItemMessage(hdlg, IDC_PROTO, CBEM_GETIMAGELIST, 0, 0));
		if (acs) {
			db_set_s(NULL, "AddContact", "LastProto", acs->proto);
			if (acs->psr) {
				mir_free(acs->psr->nick);
				mir_free(acs->psr->firstName);
				mir_free(acs->psr->lastName);
				mir_free(acs->psr->email);
				mir_free(acs->psr);
			}
			delete acs;
		}
		Utils_SaveWindowPosition(hdlg, NULL, "AddContact", "");
		break;
	}

	return FALSE;
}
static INT_PTR CALLBACK DlgProfileSelect(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
	DlgProfData *dat = (struct DlgProfData *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
	HWND hwndList = GetDlgItem(hwndDlg, IDC_PROFILELIST);

	switch (msg) {
	case WM_INITDIALOG:
		TranslateDialogDefault(hwndDlg);
		EnsureCheckerLoaded(true);
		{
			dat = (DlgProfData*)lParam;
			SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)dat);

			// set columns
			LVCOLUMN col;
			col.mask = LVCF_TEXT | LVCF_WIDTH;
			col.pszText = TranslateT("Profile");
			col.cx = 100;
			ListView_InsertColumn(hwndList, 0, &col);

			col.pszText = TranslateT("Driver");
			col.cx = 150 - GetSystemMetrics(SM_CXVSCROLL);
			ListView_InsertColumn(hwndList, 1, &col);

			col.pszText = TranslateT("Size");
			col.cx = 60;
			ListView_InsertColumn(hwndList, 2, &col);

			// icons
			HIMAGELIST hImgList = ImageList_Create(16, 16, ILC_MASK | ILC_COLOR32, 2, 1);
			ImageList_AddIcon_NotShared(hImgList, MAKEINTRESOURCE(IDI_USERDETAILS));
			ImageList_AddIcon_NotShared(hImgList, MAKEINTRESOURCE(IDI_DELETE));

			// LV will destroy the image list
			SetWindowLongPtr(hwndList, GWL_STYLE, GetWindowLongPtr(hwndList, GWL_STYLE) | LVS_SORTASCENDING);
			ListView_SetImageList(hwndList, hImgList, LVSIL_SMALL);
			ListView_SetExtendedListViewStyle(hwndList,
				ListView_GetExtendedListViewStyle(hwndList) | LVS_EX_DOUBLEBUFFER | LVS_EX_INFOTIP | LVS_EX_LABELTIP | LVS_EX_FULLROWSELECT);

			// find all the profiles
			ProfileEnumData ped = { hwndDlg, dat->pd->szProfile };
			findProfiles(dat->pd->szProfileDir, EnumProfilesForList, (LPARAM)&ped);
			PostMessage(hwndDlg, WM_FOCUSTEXTBOX, 0, 0);

			dat->hFileNotify = FindFirstChangeNotification(dat->pd->szProfileDir, TRUE, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE);
			if (dat->hFileNotify != INVALID_HANDLE_VALUE)
				SetTimer(hwndDlg, 0, 1200, NULL);
			return TRUE;
		}

	case WM_DESTROY:
		KillTimer(hwndDlg, 0);
		FindCloseChangeNotification(dat->hFileNotify);
		break;

	case WM_TIMER:
		if (WaitForSingleObject(dat->hFileNotify, 0) == WAIT_OBJECT_0) {
			ListView_DeleteAllItems(hwndList);
			ProfileEnumData ped = { hwndDlg, dat->pd->szProfile };
			findProfiles(dat->pd->szProfileDir, EnumProfilesForList, (LPARAM)&ped);
			FindNextChangeNotification(dat->hFileNotify);
		}
		break;

	case WM_FOCUSTEXTBOX:
		SetFocus(hwndList);
		if (dat->pd->szProfile[0] == 0 || ListView_GetSelectedCount(hwndList) == 0)
			ListView_SetItemState(hwndList, 0, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
		break;

	case WM_SHOWWINDOW:
		if (wParam) {
			SetWindowText(dat->hwndOK, TranslateT("&Run"));
			EnableWindow(dat->hwndSM, TRUE);
			EnableWindow(dat->hwndOK, ListView_GetSelectedCount(hwndList) == 1);
		}
		break;

	case WM_CONTEXTMENU:
		{
			LVHITTESTINFO lvht = { 0 };
			lvht.pt.x = GET_X_LPARAM(lParam);
			lvht.pt.y = GET_Y_LPARAM(lParam);
			ScreenToClient(hwndList, &lvht.pt);

			if (ListView_HitTest(hwndList, &lvht) < 0) {
				if (lParam != -1)
					break;

				lvht.iItem = ListView_GetSelectionMark(hwndList);
				RECT rc = { 0 };
				if (!ListView_GetItemRect(hwndList, lvht.iItem, &rc, LVIR_LABEL))
					break;
				
				lvht.pt.x = rc.left;
				lvht.pt.y = rc.bottom;
				ClientToScreen(hwndList, &lvht.pt);
			}
			else {
				lvht.pt.x = GET_X_LPARAM(lParam);
				lvht.pt.y = GET_Y_LPARAM(lParam);
			}

			HMENU hMenu = CreatePopupMenu();
			AppendMenu(hMenu, MF_STRING, 1, TranslateT("Run"));
			AppendMenu(hMenu, MF_SEPARATOR, 0, NULL);
			if (ServiceExists(MS_DB_CHECKPROFILE)) {
				AppendMenu(hMenu, MF_STRING, 2, TranslateT("Check database"));
				AppendMenu(hMenu, MF_SEPARATOR, 0, NULL);
			}
			AppendMenu(hMenu, MF_STRING, 3, TranslateT("Delete"));
			int index = TrackPopupMenu(hMenu, TPM_RETURNCMD, lvht.pt.x, lvht.pt.y, 0, hwndDlg, NULL);
			switch (index) {
			case 1:
				SendMessage(GetParent(hwndDlg), WM_COMMAND, IDOK, 0);
				break;

			case 2:
				CheckProfile(hwndList, lvht.iItem, dat);
				break;

			case 3:
				DeleteProfile(hwndList, lvht.iItem, dat);
				break;
			}
			DestroyMenu(hMenu);
		}
		break;

	case WM_NOTIFY:
		LPNMHDR hdr = (LPNMHDR)lParam;
		if (hdr && hdr->code == PSN_INFOCHANGED)
			break;

		if (hdr && hdr->idFrom == IDC_PROFILELIST) {
			switch (hdr->code) {
			case LVN_ITEMCHANGED:
				EnableWindow(dat->hwndOK, ListView_GetSelectedCount(hwndList) == 1);

			case NM_DBLCLK:
				if (dat != NULL) {
					TCHAR profile[MAX_PATH];
					LVITEM item = { 0 };
					item.mask = LVIF_TEXT;
					item.iItem = ListView_GetNextItem(hwndList, -1, LVNI_SELECTED | LVNI_ALL);
					item.pszText = profile;
					item.cchTextMax = SIZEOF(profile);

					if (ListView_GetItem(hwndList, &item)) {
						// profile is placed in "profile_name" subfolder
						TCHAR tmpPath[MAX_PATH];
						mir_sntprintf(tmpPath, SIZEOF(tmpPath), _T("%s\\%s.dat"), dat->pd->szProfileDir, profile);
						HANDLE hFile = CreateFile(tmpPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
						if (hFile == INVALID_HANDLE_VALUE)
							mir_sntprintf(dat->pd->szProfile, MAX_PATH, _T("%s\\%s\\%s.dat"), dat->pd->szProfileDir, profile, profile);
						else
							_tcscpy(dat->pd->szProfile, tmpPath);
						CloseHandle(hFile);
						if (hdr->code == NM_DBLCLK) EndDialog(GetParent(hwndDlg), 1);
					}
				}
				return TRUE;

			case LVN_KEYDOWN:
				if (((LPNMLVKEYDOWN)lParam)->wVKey == VK_DELETE)
					DeleteProfile(hwndList, ListView_GetNextItem(hwndList, -1, LVNI_SELECTED | LVNI_ALL), dat);
				break;

			case LVN_GETINFOTIP:
				NMLVGETINFOTIP *pInfoTip = (NMLVGETINFOTIP *)lParam;
				if (pInfoTip != NULL) {
					TCHAR profilename[MAX_PATH], fullpath[MAX_PATH];
					struct _stat statbuf;
					ListView_GetItemText(hwndList, pInfoTip->iItem, 0, profilename, MAX_PATH);
					mir_sntprintf(fullpath, SIZEOF(fullpath), _T("%s\\%s\\%s.dat"), dat->pd->szProfileDir, profilename, profilename);
					_tstat(fullpath, &statbuf);
					mir_sntprintf(pInfoTip->pszText, pInfoTip->cchTextMax, _T("%s\n%s: %s\n%s: %s"), fullpath, TranslateT("Created"), rtrimt(NEWTSTR_ALLOCA(_tctime(&statbuf.st_ctime))), TranslateT("Modified"), rtrimt(NEWTSTR_ALLOCA(_tctime(&statbuf.st_mtime))));
				}
			}
		}
		break;
	}

	return FALSE;
}