INT_PTR CALLBACK SelectContainerDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { HWND hwndMsgDlg = 0; hwndMsgDlg = (HWND) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); switch (msg) { case WM_INITDIALOG: { TCHAR szNewTitle[128]; RECT rc, rcParent; struct TContainerData *pContainer = 0; SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) lParam); hwndMsgDlg = (HWND) lParam; TranslateDialogDefault(hwndDlg); if (lParam) { struct TWindowData *dat = (struct TWindowData *)GetWindowLongPtr((HWND)lParam, GWLP_USERDATA); if (dat) { mir_sntprintf(szNewTitle, safe_sizeof(szNewTitle), CTranslator::get(CTranslator::CNT_SELECT_FOR), dat->cache->getNick()); SetWindowText(hwndDlg, szNewTitle); } } SendMessage(hwndDlg, DM_SC_BUILDLIST, 0, 0); SendDlgItemMessage(hwndDlg, IDC_NEWCONTAINERNAME, EM_LIMITTEXT, (WPARAM)CONTAINER_NAMELEN, 0); SendDlgItemMessage(hwndDlg, IDC_NEWCONTAINER, EM_LIMITTEXT, (WPARAM)CONTAINER_NAMELEN, 0); GetWindowRect(hwndDlg, &rc); GetWindowRect(GetParent(hwndDlg), &rcParent); SetWindowPos(hwndDlg, 0, (rcParent.left + rcParent.right - (rc.right - rc.left)) / 2, (rcParent.top + rcParent.bottom - (rc.bottom - rc.top)) / 2, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW); return TRUE; } case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: { TCHAR szName[CONTAINER_NAMELEN]; LRESULT iItem; if ((iItem = SendDlgItemMessage(hwndDlg, IDC_CNTLIST, LB_GETCURSEL, 0, 0)) != LB_ERR) { SendDlgItemMessage(hwndDlg, IDC_CNTLIST, LB_GETTEXT, (WPARAM) iItem, (LPARAM) szName); if (IsWindow(hwndMsgDlg)) SendMessage(hwndMsgDlg, DM_CONTAINERSELECTED, 0, (LPARAM) szName); } if (IsWindow(hwndDlg)) DestroyWindow(hwndDlg); break; } case IDCANCEL: DestroyWindow(hwndDlg); break; case IDC_DELETECONTAINER: { TCHAR szName[CONTAINER_NAMELEN + 1]; LRESULT iItem; if ((iItem = SendDlgItemMessage(hwndDlg, IDC_CNTLIST, LB_GETCURSEL, 0, 0)) != LB_ERR) { SendDlgItemMessage(hwndDlg, IDC_CNTLIST, LB_GETTEXT, (WPARAM) iItem, (LPARAM) szName); if (!_tcsncmp(szName, _T("default"), CONTAINER_NAMELEN) || !_tcsncmp(szName, CTranslator::get(CTranslator::GEN_DEFAULT_CONTAINER_NAME), CONTAINER_NAMELEN)) MessageBox(hwndDlg, CTranslator::get(CTranslator::CNT_SELECT_DELETEERROR), _T("Error"), MB_OK | MB_ICONERROR); else { int iIndex = SendDlgItemMessage(hwndDlg, IDC_CNTLIST, LB_GETITEMDATA, (WPARAM)iItem, 0); DeleteContainer(iIndex); SendDlgItemMessage(hwndDlg, IDC_CNTLIST, LB_RESETCONTENT, 0, 0); SendMessage(hwndDlg, DM_SC_BUILDLIST, 0, 0); BuildContainerMenu(); } } break; } case IDC_RENAMECONTAINER: { TCHAR szNewName[CONTAINER_NAMELEN], szName[CONTAINER_NAMELEN + 1]; int iLen, iItem; struct TContainerData *pCurrent = pFirstContainer; iLen = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_NEWCONTAINERNAME)); if (iLen) { GetWindowText(GetDlgItem(hwndDlg, IDC_NEWCONTAINERNAME), szNewName, CONTAINER_NAMELEN); if(!_tcsncmp(szNewName, CGlobals::m_default_container_name, CONTAINER_NAMELEN) || !_tcsncmp(szNewName, CTranslator::get(CTranslator::GEN_DEFAULT_CONTAINER_NAME), CONTAINER_NAMELEN)) { MessageBox(hwndDlg, CTranslator::get(CTranslator::CNT_SELECT_RENAMEERROR), _T("Error"), MB_OK | MB_ICONERROR); break; } iItem = SendDlgItemMessage(hwndDlg, IDC_CNTLIST, LB_FINDSTRING, (WPARAM) - 1, (LPARAM) szNewName); if (iItem != LB_ERR) { TCHAR szOldName[CONTAINER_NAMELEN + 1]; SendDlgItemMessage(hwndDlg, IDC_CNTLIST, LB_GETTEXT, (WPARAM) iItem, (LPARAM) szOldName); if (lstrlen(szOldName) == lstrlen(szNewName)) { MessageBox(0, CTranslator::get(CTranslator::CNT_SELECT_INUSE), _T("Error"), MB_OK | MB_ICONERROR); SetFocus(GetDlgItem(hwndDlg, IDC_NEWCONTAINERNAME)); break; } } if ((iItem = SendDlgItemMessage(hwndDlg, IDC_CNTLIST, LB_GETCURSEL, 0, 0)) != LB_ERR) { SendDlgItemMessage(hwndDlg, IDC_CNTLIST, LB_GETTEXT, (WPARAM) iItem, (LPARAM) szName); if (!_tcsncmp(szName, _T("default"), CONTAINER_NAMELEN) || !_tcsncmp(szName, CTranslator::get(CTranslator::GEN_DEFAULT_CONTAINER_NAME), CONTAINER_NAMELEN)) MessageBox(hwndDlg, CTranslator::get(CTranslator::CNT_SELECT_RENAMEERROR), _T("Error"), MB_OK | MB_ICONERROR); else { int iIndex = SendDlgItemMessage(hwndDlg, IDC_CNTLIST, LB_GETITEMDATA, (WPARAM)iItem, 0); RenameContainer(iIndex, szNewName); SendDlgItemMessage(hwndDlg, IDC_CNTLIST, LB_RESETCONTENT, 0, 0); while (pCurrent) { if (!_tcsncmp(pCurrent->szName, szName, CONTAINER_NAMELEN) && lstrlen(pCurrent->szName) == lstrlen(szName)) { _tcsncpy(pCurrent->szName, szNewName, CONTAINER_NAMELEN); SendMessage(pCurrent->hwnd, DM_CONFIGURECONTAINER, 0, 0); } pCurrent = pCurrent->pNextContainer; } SendMessage(hwndDlg, DM_SC_BUILDLIST, 0, 0); BuildContainerMenu(); } } } break; } case IDC_CREATENEW: { int iLen, iItem; TCHAR szNewName[CONTAINER_NAMELEN], szName[CONTAINER_NAMELEN + 1]; iLen = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_NEWCONTAINER)); if (iLen) { GetWindowText(GetDlgItem(hwndDlg, IDC_NEWCONTAINER), szNewName, CONTAINER_NAMELEN); iItem = SendDlgItemMessage(hwndDlg, IDC_CNTLIST, LB_FINDSTRING, (WPARAM) - 1, (LPARAM) szNewName); if (iItem != LB_ERR || !_tcsncmp(szNewName, CGlobals::m_default_container_name, CONTAINER_NAMELEN)) { SendDlgItemMessage(hwndDlg, IDC_CNTLIST, LB_GETTEXT, (WPARAM)iItem, (LPARAM)szName); if (lstrlen(szName) == lstrlen(szNewName) || !_tcsncmp(szNewName, CGlobals::m_default_container_name, CONTAINER_NAMELEN)) { MessageBox(0, CTranslator::get(CTranslator::CNT_SELECT_INUSE), _T("Error"), MB_OK | MB_ICONERROR); SetFocus(GetDlgItem(hwndDlg, IDC_NEWCONTAINER)); break; } } if (IsWindow(hwndMsgDlg)) { SendMessage(hwndMsgDlg, DM_CONTAINERSELECTED, 0, (LPARAM) szNewName); if (IsWindow(hwndDlg)) DestroyWindow(hwndDlg); } } break; } case IDC_CNTLIST: if (HIWORD(wParam) == LBN_DBLCLK) SendMessage(hwndDlg, WM_COMMAND, IDOK, 0); break; } break; /* * fill the list box... */ case DM_SC_BUILDLIST: { DBVARIANT dbv; int iCounter = 0, iItemNew; char *szKey = "TAB_ContainersW"; char szValue[10]; struct TContainerData *pContainer = 0; do { _snprintf(szValue, 8, "%d", iCounter); if (M->GetTString(NULL, szKey, szValue, &dbv)) break; // end of list if (dbv.type == DBVT_ASCIIZ || dbv.type == DBVT_WCHAR) { if (_tcsncmp(dbv.ptszVal, _T("**free**"), CONTAINER_NAMELEN)) { iItemNew = SendDlgItemMessage(hwndDlg, IDC_CNTLIST, LB_ADDSTRING, 0, (LPARAM)(!_tcscmp(dbv.ptszVal, _T("default")) ? CTranslator::get(CTranslator::GEN_DEFAULT_CONTAINER_NAME) : dbv.ptszVal)); if (iItemNew != LB_ERR) SendDlgItemMessage(hwndDlg, IDC_CNTLIST, LB_SETITEMDATA, (WPARAM)iItemNew, (LPARAM)iCounter); } DBFreeVariant(&dbv); } } while (++iCounter); /* * highlight the name of the container to which the message window currently is assigned */ SendMessage(hwndMsgDlg, DM_QUERYCONTAINER, 0, (LPARAM)&pContainer); if (pContainer) { LRESULT iItem; iItem = SendDlgItemMessage(hwndDlg, IDC_CNTLIST, LB_FINDSTRING, (WPARAM) - 1, (LPARAM)(!_tcscmp(pContainer->szName, _T("default")) ? CTranslator::get(CTranslator::GEN_DEFAULT_CONTAINER_NAME) : pContainer->szName)); if (iItem != LB_ERR) SendDlgItemMessage(hwndDlg, IDC_CNTLIST, LB_SETCURSEL, (WPARAM) iItem, 0); } } break; } return FALSE; }
static INT_PTR CALLBACK ReadAwayMsgDlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) { AwayMsgDlgData *dat = (AwayMsgDlgData *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); switch (message) { case WM_INITDIALOG: TranslateDialogDefault(hwndDlg); dat = (AwayMsgDlgData *)mir_alloc(sizeof(AwayMsgDlgData)); SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)dat); dat->hContact = lParam; dat->hSeq = (HANDLE)CallContactService(dat->hContact, PSS_GETAWAYMSG, 0, 0); dat->hAwayMsgEvent = dat->hSeq ? HookEventMessage(ME_PROTO_ACK, hwndDlg, HM_AWAYMSG) : NULL; WindowList_Add(hWindowList, hwndDlg, dat->hContact); { TCHAR str[256], format[128]; TCHAR *contactName = (TCHAR *)pcli->pfnGetContactDisplayName(dat->hContact, 0); char *szProto = GetContactProto(dat->hContact); WORD dwStatus = db_get_w(dat->hContact, szProto, "Status", ID_STATUS_OFFLINE); TCHAR *status = pcli->pfnGetStatusModeDescription(dwStatus, 0); GetWindowText(hwndDlg, format, _countof(format)); mir_sntprintf(str, _countof(str), format, status, contactName); SetWindowText(hwndDlg, str); if (dat->hSeq) { GetDlgItemText(hwndDlg, IDC_RETRIEVING, format, _countof(format)); mir_sntprintf(str, _countof(str), format, status); } else { mir_sntprintf(str, _countof(str), TranslateT("Failed to retrieve %s message."), status); SetDlgItemText(hwndDlg, IDOK, TranslateT("&Close")); } SetDlgItemText(hwndDlg, IDC_RETRIEVING, str); SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)Skin_LoadProtoIcon(szProto, dwStatus)); SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)Skin_LoadProtoIcon(szProto, dwStatus)); EnableWindow(GetDlgItem(hwndDlg, IDC_COPY), FALSE); } Utils_RestoreWindowPosition(hwndDlg, lParam, "SRAway", "AwayMsgDlg"); return TRUE; case HM_AWAYMSG: { ACKDATA *ack = (ACKDATA *)lParam; if (ack->hContact != dat->hContact || ack->type != ACKTYPE_AWAYMSG) break; if (ack->result != ACKRESULT_SUCCESS) break; if (dat->hAwayMsgEvent && ack->hProcess == dat->hSeq) { UnhookEvent(dat->hAwayMsgEvent); dat->hAwayMsgEvent = NULL; } TCHAR *tszMsg = StrNormNewline((TCHAR *)ack->lParam); SetDlgItemText(hwndDlg, IDC_MSG, tszMsg); mir_free(tszMsg); if (ack->lParam && *((char *)ack->lParam) != '\0') EnableWindow(GetDlgItem(hwndDlg, IDC_COPY), TRUE); ShowWindow(GetDlgItem(hwndDlg, IDC_RETRIEVING), SW_HIDE); ShowWindow(GetDlgItem(hwndDlg, IDC_MSG), SW_SHOW); SetDlgItemText(hwndDlg, IDOK, TranslateT("&Close")); break; } case WM_COMMAND: switch (LOWORD(wParam)) { case IDCANCEL: case IDOK: DestroyWindow(hwndDlg); break; case IDC_COPY: if (!OpenClipboard(hwndDlg)) break; if (EmptyClipboard()) { TCHAR msg[1024]; int len = GetDlgItemText(hwndDlg, IDC_MSG, msg, _countof(msg)); if (len) { LPTSTR lptstrCopy; HGLOBAL hglbCopy = GlobalAlloc(GMEM_MOVEABLE, (len + 1) * sizeof(TCHAR)); if (hglbCopy == NULL) { CloseClipboard(); break; } lptstrCopy = (LPTSTR)GlobalLock(hglbCopy); memcpy(lptstrCopy, msg, len * sizeof(TCHAR)); lptstrCopy[len] = (TCHAR)0; GlobalUnlock(hglbCopy); SetClipboardData(CF_UNICODETEXT, hglbCopy); } } CloseClipboard(); break; } break; case WM_CLOSE: DestroyWindow(hwndDlg); break; case WM_DESTROY: if (dat->hAwayMsgEvent) UnhookEvent(dat->hAwayMsgEvent); Utils_SaveWindowPosition(hwndDlg, dat->hContact, "SRAway", "AwayMsgDlg"); WindowList_Remove(hWindowList, hwndDlg); IcoLib_ReleaseIcon((HICON)SendMessage(hwndDlg, WM_SETICON, ICON_BIG, NULL)); IcoLib_ReleaseIcon((HICON)SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, NULL)); mir_free(dat); break; } return FALSE; }
static CMString FormatOutput (const CIrcMessage* pmsg) { CMString sMessage; if ( pmsg->m_bIncoming ) { // Is it an incoming message? if ( pmsg->sCommand == _T("WALLOPS") && pmsg->parameters.getCount() > 0 ) { TCHAR temp[200]; *temp = '\0'; mir_sntprintf(temp, SIZEOF(temp), TranslateT("WallOps from %s: "), pmsg->prefix.sNick.c_str()); sMessage = temp; for ( int i=0; i < (int)pmsg->parameters.getCount(); i++ ) { sMessage += pmsg->parameters[i]; if (i != pmsg->parameters.getCount()-1) sMessage += _T(" "); } goto THE_END; } if ( pmsg->sCommand == _T("INVITE") && pmsg->parameters.getCount() > 1 ) { TCHAR temp[256]; *temp = '\0'; mir_sntprintf(temp, SIZEOF(temp), TranslateT("%s invites you to %s"), pmsg->prefix.sNick.c_str(), pmsg->parameters[1].c_str()); sMessage = temp; for ( int i=2; i < (int)pmsg->parameters.getCount(); i++ ) { sMessage += _T(": ") + pmsg->parameters[i]; if ( i != pmsg->parameters.getCount()-1 ) sMessage += _T(" "); } goto THE_END; } int index = StrToInt( pmsg->sCommand.c_str()); if ( index == 301 && pmsg->parameters.getCount() > 0 ) { TCHAR temp[500]; *temp = '\0'; mir_sntprintf(temp, SIZEOF(temp), TranslateT("%s is away"), pmsg->parameters[1].c_str()); sMessage = temp; for ( int i=2; i < (int)pmsg->parameters.getCount(); i++ ) { sMessage += _T(": ") + pmsg->parameters[i]; if ( i != pmsg->parameters.getCount()-1 ) sMessage += _T(" "); } goto THE_END; } if (( index == 443 || index == 441 ) && pmsg->parameters.getCount() > 3 ) return pmsg->parameters[1] + _T(" ") + pmsg->parameters[3] + _T(": ") + pmsg->parameters[2]; if ( index == 303 ) { // ISON command sMessage = TranslateT("These are online: "); for ( int i=1; i < (int)pmsg->parameters.getCount(); i++ ) { sMessage += pmsg->parameters[i]; if (i != pmsg->parameters.getCount()-1) sMessage += _T(", "); } goto THE_END; } if (( index > 400 || index < 500) && pmsg->parameters.getCount() > 2 && pmsg->sCommand[0] == '4' ) //all error messages return pmsg->parameters[2] + _T(": ") + pmsg->parameters[1]; } else if ( pmsg->sCommand == _T("NOTICE") && pmsg->parameters.getCount() > 1 ) { TCHAR temp[500]; *temp = '\0'; int l = pmsg->parameters[1].GetLength(); if ( l > 3 && pmsg->parameters[1][0] == 1 && pmsg->parameters[1][ l-1 ] == 1 ) { // CTCP reply CMString tempstr = pmsg->parameters[1]; tempstr.Delete(0,1); tempstr.Delete(tempstr.GetLength()-1,1); CMString type = GetWord(tempstr.c_str(), 0); if ( lstrcmpi(type.c_str(), _T("ping")) == 0) mir_sntprintf(temp, SIZEOF(temp), TranslateT("CTCP %s reply sent to %s"), type.c_str(), pmsg->parameters[0].c_str()); else mir_sntprintf(temp, SIZEOF(temp), TranslateT("CTCP %s reply sent to %s: %s"), type.c_str(), pmsg->parameters[0].c_str(), GetWordAddress(tempstr.c_str(), 1)); sMessage = temp; } else { mir_sntprintf(temp, SIZEOF(temp), TranslateT("Notice to %s: "), pmsg->parameters[0].c_str()); sMessage = temp; for ( int i=1; i < (int)pmsg->parameters.getCount(); i++ ) { sMessage += pmsg->parameters[i]; if (i != pmsg->parameters.getCount()-1) sMessage += _T(" "); } } goto THE_END; } // Default Message handler. if ( pmsg->m_bIncoming ) { if ( pmsg->parameters.getCount() < 2 && pmsg->parameters.getCount() > 0 ) return pmsg->sCommand + _T(" : ") + pmsg->parameters[0]; if ( pmsg->parameters.getCount() > 1 ) for ( int i=1; i < (int)pmsg->parameters.getCount(); i++ ) sMessage += pmsg->parameters[i] + _T(" "); } else { if ( pmsg->prefix.sNick.GetLength()) sMessage = pmsg->prefix.sNick + _T(" "); sMessage += pmsg->sCommand + _T(" "); for ( int i=0; i < (int)pmsg->parameters.getCount(); i++ ) sMessage += pmsg->parameters[i] + _T(" "); } THE_END: return sMessage; }
void CMraProto::MraAvatarsThreadProc(LPVOID lpParameter) { MRA_AVATARS_QUEUE *pmraaqAvatarsQueue = (MRA_AVATARS_QUEUE*)lpParameter; MRA_AVATARS_QUEUE_ITEM *pmraaqiAvatarsQueueItem; CMStringA szEmail, szServer; CMStringW wszFileName; BOOL bContinue, bKeepAlive, bUseKeepAliveConn, bFailed, bDownloadNew, bDefaultAvt; BYTE btBuff[BUFF_SIZE_RCV]; DWORD dwResultCode, dwAvatarFormat, dwReceived, dwServerPort, dwErrorCode; size_t dwAvatarSizeServer; FILETIME ftLastModifiedTimeServer, ftLastModifiedTimeLocal; SYSTEMTIME stAvatarLastModifiedTimeLocal; HANDLE m_hConnection = NULL; NETLIBSELECT nls = { 0 }; INTERNET_TIME itAvatarLastModifiedTimeServer; PROTO_AVATAR_INFORMATIONT pai; WCHAR szErrorText[2048]; nls.cbSize = sizeof(nls); pai.cbSize = sizeof(pai); InterlockedIncrement((volatile LONG*)&pmraaqAvatarsQueue->lThreadsRunningCount); while (InterlockedExchangeAdd((volatile LONG*)&pmraaqAvatarsQueue->bIsRunning, 0)) { if (FifoMTItemPop(pmraaqAvatarsQueue, NULL, (LPVOID*)&pmraaqiAvatarsQueueItem) == NO_ERROR) { bFailed = TRUE; bDownloadNew = FALSE; bDefaultAvt = FALSE; if (!DB_GetStringA(NULL, MRA_AVT_SECT_NAME, "Server", szServer)) szServer = MRA_AVT_DEFAULT_SERVER; dwServerPort = db_get_dw(NULL, MRA_AVT_SECT_NAME, "ServerPort", MRA_AVT_DEFAULT_SERVER_PORT); bUseKeepAliveConn = db_get_b(NULL, MRA_AVT_SECT_NAME, "UseKeepAliveConn", MRA_AVT_DEFAULT_USE_KEEPALIVE_CONN); if (mraGetStringA(pmraaqiAvatarsQueueItem->hContact, "e-mail", szEmail)) { szEmail.MakeLower(); int iStart = 0; CMStringA szUser = szEmail.Tokenize("@", iStart); CMStringA szDomain = szEmail.Tokenize("@", iStart); if (!szUser.IsEmpty() && !szDomain.IsEmpty()) { ProtoBroadcastAck(pmraaqiAvatarsQueueItem->hContact, ACKTYPE_AVATAR, ACKRESULT_CONNECTING, NULL, 0); if (m_hConnection == NULL) m_hConnection = MraAvatarsHttpConnect(pmraaqAvatarsQueue->m_hNetlibUser, szServer, dwServerPort); if (m_hConnection) { ProtoBroadcastAck(pmraaqiAvatarsQueueItem->hContact, ACKTYPE_AVATAR, ACKRESULT_CONNECTED, NULL, 0); ProtoBroadcastAck(pmraaqiAvatarsQueueItem->hContact, ACKTYPE_AVATAR, ACKRESULT_SENTREQUEST, NULL, 0); if (!MraAvatarsHttpTransaction(m_hConnection, REQUEST_HEAD, szUser, szDomain, szServer, MAHTRO_AVTMRIM, bUseKeepAliveConn, &dwResultCode, &bKeepAlive, &dwAvatarFormat, &dwAvatarSizeServer, &itAvatarLastModifiedTimeServer)) { switch (dwResultCode) { case 200: if (MraAvatarsGetContactTime(pmraaqiAvatarsQueueItem->hContact, "AvatarLastModifiedTime", &stAvatarLastModifiedTimeLocal)) { SystemTimeToFileTime(&itAvatarLastModifiedTimeServer.stTime, &ftLastModifiedTimeServer); SystemTimeToFileTime(&stAvatarLastModifiedTimeLocal, &ftLastModifiedTimeLocal); if ((*((DWORDLONG*)&ftLastModifiedTimeServer)) != (*((DWORDLONG*)&ftLastModifiedTimeLocal))) {// need check for update bDownloadNew = TRUE; //ProtoBroadcastAck(pmraaqiAvatarsQueueItem->hContact, ACKTYPE_AVATAR, ACKRESULT_STATUS, 0, 0); } else {// avatar is valid if (MraAvatarsGetFileName(pmraaqAvatarsQueue, pmraaqiAvatarsQueueItem->hContact, dwAvatarFormat, wszFileName) == NO_ERROR) { if (IsFileExist(wszFileName)) bFailed = FALSE; else bDownloadNew = TRUE; } } } else // need update bDownloadNew = TRUE; break; case 404:// return def avatar if (MraAvatarsGetFileName((HANDLE)pmraaqAvatarsQueue, NULL, PA_FORMAT_DEFAULT, wszFileName) == NO_ERROR) { if (IsFileExist(wszFileName)) { dwAvatarFormat = ProtoGetAvatarFormat(wszFileName); bFailed = FALSE; } else//loading default avatar bDownloadNew = TRUE; bDefaultAvt = TRUE; } break; default: mir_sntprintf(szErrorText, SIZEOF(szErrorText), TranslateT("Avatars: server return HTTP code: %lu"), dwResultCode); ShowFormattedErrorMessage(szErrorText, NO_ERROR); break; } } if (bUseKeepAliveConn == FALSE || bKeepAlive == FALSE) NETLIB_CLOSEHANDLE(m_hConnection); } if (bDownloadNew) { if (m_hConnection == NULL) m_hConnection = MraAvatarsHttpConnect(pmraaqAvatarsQueue->m_hNetlibUser, szServer, dwServerPort); if (m_hConnection) { ProtoBroadcastAck(pmraaqiAvatarsQueueItem->hContact, ACKTYPE_AVATAR, ACKRESULT_DATA, NULL, 0); if (MraAvatarsHttpTransaction(m_hConnection, REQUEST_GET, szUser, szDomain, szServer, MAHTRO_AVT, bUseKeepAliveConn, &dwResultCode, &bKeepAlive, &dwAvatarFormat, &dwAvatarSizeServer, &itAvatarLastModifiedTimeServer) == NO_ERROR && dwResultCode == 200) { if (bDefaultAvt) dwAvatarFormat = PA_FORMAT_DEFAULT; if (!MraAvatarsGetFileName(pmraaqAvatarsQueue, pmraaqiAvatarsQueueItem->hContact, dwAvatarFormat, wszFileName)) { HANDLE hFile = CreateFile(wszFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile != INVALID_HANDLE_VALUE) { DWORD dwWritten = 0; bContinue = TRUE; nls.dwTimeout = (1000 * db_get_dw(NULL, MRA_AVT_SECT_NAME, "TimeOutReceive", MRA_AVT_DEFAULT_TIMEOUT_RECV)); nls.hReadConns[0] = m_hConnection; while (bContinue) { switch (CallService(MS_NETLIB_SELECT, 0, (LPARAM)&nls)) { case SOCKET_ERROR: case 0:// Time out dwErrorCode = GetLastError(); ShowFormattedErrorMessage(L"Avatars: error on receive file data", dwErrorCode); bContinue = FALSE; break; case 1: dwReceived = Netlib_Recv(m_hConnection, (LPSTR)&btBuff, SIZEOF(btBuff), 0); if (dwReceived == 0 || dwReceived == SOCKET_ERROR) { dwErrorCode = GetLastError(); ShowFormattedErrorMessage(L"Avatars: error on receive file data", dwErrorCode); bContinue = FALSE; } else { if (WriteFile(hFile, (LPVOID)&btBuff, dwReceived, &dwReceived, NULL)) { dwWritten += dwReceived; if (dwWritten >= dwAvatarSizeServer) bContinue = FALSE; } else { dwErrorCode = GetLastError(); ShowFormattedErrorMessage(L"Avatars: cant write file data, error", dwErrorCode); bContinue = FALSE; } } break; } } CloseHandle(hFile); bFailed = FALSE; } else { dwErrorCode = GetLastError(); mir_sntprintf(szErrorText, SIZEOF(szErrorText), TranslateT("Avatars: can't open file %s, error"), wszFileName); ShowFormattedErrorMessage(szErrorText, dwErrorCode); } } } else _CrtDbgBreak(); if (bUseKeepAliveConn == FALSE || bKeepAlive == FALSE) NETLIB_CLOSEHANDLE(m_hConnection); } } } } if (bFailed) { DeleteFile(wszFileName); pai.hContact = pmraaqiAvatarsQueueItem->hContact; pai.format = PA_FORMAT_UNKNOWN; pai.filename[0] = 0; ProtoBroadcastAck(pmraaqiAvatarsQueueItem->hContact, ACKTYPE_AVATAR, ACKRESULT_FAILED, (HANDLE)&pai, 0); } else { pai.hContact = pmraaqiAvatarsQueueItem->hContact; pai.format = dwAvatarFormat; if (db_get_b(NULL, MRA_AVT_SECT_NAME, "ReturnAbsolutePath", MRA_AVT_DEFAULT_RET_ABC_PATH)) lstrcpyn(pai.filename, wszFileName, SIZEOF(pai.filename)); else PathToRelativeT(wszFileName, pai.filename); if (bDefaultAvt) dwAvatarFormat = PA_FORMAT_DEFAULT; SetContactAvatarFormat(pmraaqiAvatarsQueueItem->hContact, dwAvatarFormat); MraAvatarsSetContactTime(pmraaqiAvatarsQueueItem->hContact, "AvatarLastModifiedTime", &itAvatarLastModifiedTimeServer.stTime); // write owner avatar file name to DB if (pmraaqiAvatarsQueueItem->hContact == NULL) // proto avatar CallService(MS_AV_REPORTMYAVATARCHANGED, (WPARAM)m_szModuleName, 0); ProtoBroadcastAck(pmraaqiAvatarsQueueItem->hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, (HANDLE)&pai, 0); } mir_free(pmraaqiAvatarsQueueItem); } else { // waiting until service stop or new task NETLIB_CLOSEHANDLE(m_hConnection); WaitForSingleObjectEx(pmraaqAvatarsQueue->hThreadEvent, MRA_AVT_DEFAULT_QE_CHK_INTERVAL, FALSE); } } InterlockedDecrement((volatile LONG*)&pmraaqAvatarsQueue->lThreadsRunningCount); }
LRESULT CALLBACK NewStatusBarWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_SETCURSOR: { POINT pt; GetCursorPos(&pt); SendMessage(GetParent(hwnd), msg, wParam, lParam); if (pt.x == ptMouse.x && pt.y == ptMouse.y) return 1;//return(TestCursorOnBorders()); ptMouse = pt; if (tooltip_active){ KillTimer(hwnd, TIMERID_HOVER); if (!NotifyEventHooks(hStatusBarHideToolTipEvent, 0, 0)) CallService("mToolTip/HideTip", 0, 0); tooltip_active = FALSE; } KillTimer(hwnd, TIMERID_HOVER); SetTimer(hwnd, TIMERID_HOVER, 750, 0); } break; case WM_NCHITTEST: { LRESULT lr = SendMessage(GetParent(hwnd), WM_NCHITTEST, wParam, lParam); if (lr == HTLEFT || lr == HTRIGHT || lr == HTBOTTOM || lr == HTTOP || lr == HTTOPLEFT || lr == HTTOPRIGHT || lr == HTBOTTOMLEFT || lr == HTBOTTOMRIGHT) return HTTRANSPARENT; } break; case WM_ERASEBKGND: if (cfg::dat.bSkinnedStatusBar) return 1; return mir_callNextSubclass(hwnd, NewStatusBarWndProc, msg, wParam, lParam); case WM_LBUTTONDOWN: case WM_RBUTTONDOWN: KillTimer(hwnd, TIMERID_HOVER); if (!NotifyEventHooks(hStatusBarHideToolTipEvent, 0, 0)) CallService("mToolTip/HideTip", 0, 0); tooltip_active = FALSE; break; case WM_PAINT: if (cfg::shutDown || arStatusItems.getCount() == 0) return 0; if (cfg::dat.bSkinnedStatusBar) { PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd, &ps); HDC hdcMem = CreateCompatibleDC(hdc); RECT rcClient, rcWindow; DRAWITEMSTRUCT dis = {0}; POINT pt; BYTE windowStyle = cfg::getByte("CLUI", "WindowStyle", SETTING_WINDOWSTYLE_DEFAULT); LONG b_offset = cfg::dat.bClipBorder + (windowStyle == SETTING_WINDOWSTYLE_NOBORDER ? 2 : (windowStyle == SETTING_WINDOWSTYLE_THINBORDER ? 1 : 0)); GetClientRect(hwnd, &rcClient); GetWindowRect(hwnd, &rcWindow); pt.x = rcWindow.left; pt.y = rcWindow.top; ScreenToClient(pcli->hwndContactList, &pt); HBITMAP hbmMem = CreateCompatibleBitmap(hdc, rcClient.right, rcClient.bottom); HBITMAP hbmOld = reinterpret_cast<HBITMAP>(SelectObject(hdcMem, hbmMem)); SetBkMode(hdcMem, TRANSPARENT); HFONT hOldFont = reinterpret_cast<HFONT>(SelectObject(hdcMem, GetStockObject(DEFAULT_GUI_FONT))); BitBlt(hdcMem, 0, 0, rcClient.right, rcClient.bottom, cfg::dat.hdcBg, pt.x, pt.y, SRCCOPY); StatusItems_t *item = arStatusItems[ID_EXTBKSTATUSBAR - ID_STATUS_OFFLINE]; if (!item->IGNORED) { RECT rc = rcClient; rc.left += item->MARGIN_LEFT; rc.right -= item->MARGIN_RIGHT; rc.top += item->MARGIN_TOP; rc.bottom -= item->MARGIN_BOTTOM; DrawAlpha(hdcMem, &rc, item->COLOR, item->ALPHA, item->COLOR2, item->COLOR2_TRANSPARENT, item->GRADIENT, item->CORNER, item->BORDERSTYLE, item->imageItem); SetTextColor(hdcMem, item->TEXTCOLOR); } else SetTextColor(hdcMem, GetSysColor(COLOR_BTNTEXT)); dis.hwndItem = hwnd; dis.hDC = hdcMem; dis.CtlType = 0; int nParts = SendMessage(hwnd, SB_GETPARTS, 0, 0); for (int i = 0; i < nParts; i++) { SendMessage(hwnd, SB_GETRECT, i, (LPARAM)&dis.rcItem); OffsetRect(&dis.rcItem, 0, -b_offset); dis.itemData = SendMessage(hwnd, SB_GETTEXTA, i, 0); SendMessage(pcli->hwndContactList, WM_DRAWITEM, 0, (LPARAM)&dis); } BitBlt(hdc, 0, 0, rcClient.right, rcClient.bottom, hdcMem, 0, 0, SRCCOPY); if (hOldFont) SelectObject(hdcMem, hOldFont); SelectObject(hdcMem, hbmOld); DeleteObject(hbmMem); DeleteDC(hdcMem); EndPaint(hwnd, &ps); return 0; } break; case WM_TIMER: if (wParam == TIMERID_HOVER) { POINT pt; KillTimer(hwnd, TIMERID_HOVER); GetCursorPos(&pt); if (pt.x == ptMouse.x && pt.y == ptMouse.y) { ScreenToClient(hwnd, &pt); int nParts = SendMessage(hwnd, SB_GETPARTS, 0, 0); for (int i = 0; i < nParts; i++) { RECT rc; SendMessage(hwnd, SB_GETRECT, i, (LPARAM)&rc); if (PtInRect(&rc,pt)) { ProtocolData *PD = (ProtocolData *)SendMessageA(hwnd, SB_GETTEXTA, i, 0); if (PD == NULL) continue; if (NotifyEventHooks(hStatusBarShowToolTipEvent, (WPARAM)PD->RealName, 0) > 0) // a plugin handled this event tooltip_active = TRUE; else if (cfg::getDword("mToolTip", "ShowStatusTip", 0)) { WORD wStatus = (WORD)CallProtoService(PD->RealName, PS_GETSTATUS, 0, 0); BYTE isLocked = cfg::getByte(PD->RealName, "LockMainStatus", 0); TCHAR szTipText[256]; mir_sntprintf(szTipText, SIZEOF(szTipText), _T("<b>%s</b>: %s%s"), PD->RealName, pcli->pfnGetStatusModeDescription(wStatus, 0), isLocked ? _T(" (LOCKED)") : _T("")); CLCINFOTIP ti = { sizeof(ti) }; ti.isTreeFocused = (GetFocus() == pcli->hwndContactList); CallService("mToolTip/ShowTipW", (WPARAM)szTipText, (LPARAM)&ti); } break; } } } } break; } return mir_callNextSubclass(hwnd, NewStatusBarWndProc, msg, wParam, lParam); }
INT_PTR CALLBACK DlgProcPopupGeneral(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { static bool bDlgInit = false; //some controls send WM_COMMAND before or during WM_INITDIALOG static OPTTREE_OPTION *statusOptions = NULL; static int statusOptionsCount = 0; if (statusOptions) { int index; if (OptTree_ProcessMessage(hwnd, msg, wParam, lParam, &index, IDC_STATUSES, statusOptions, statusOptionsCount)) return TRUE; } switch (msg) { case WM_INITDIALOG: //Seconds of delay CheckDlgButton(hwnd, IDC_INFINITEDELAY, PopupOptions.InfiniteDelay); CheckDlgButton(hwnd, IDC_LEAVEHOVERED, PopupOptions.LeaveHovered); EnableWindow(GetDlgItem(hwnd, IDC_SECONDS), !PopupOptions.InfiniteDelay); EnableWindow(GetDlgItem(hwnd, IDC_SECONDS_STATIC1), !PopupOptions.InfiniteDelay); EnableWindow(GetDlgItem(hwnd, IDC_SECONDS_STATIC2), !PopupOptions.InfiniteDelay); EnableWindow(GetDlgItem(hwnd, IDC_LEAVEHOVERED), !PopupOptions.InfiniteDelay); SetDlgItemInt(hwnd, IDC_SECONDS, PopupOptions.Seconds, FALSE); SendDlgItemMessage(hwnd, IDC_SECONDS_SPIN, UDM_SETRANGE, 0, (LPARAM)MAKELONG(SETTING_LIFETIME_MAX, SETTING_LIFETIME_MIN)); //Dynamic Resize CheckDlgButton(hwnd, IDC_DYNAMICRESIZE, PopupOptions.DynamicResize); SetDlgItemText(hwnd, IDC_USEMAXIMUMWIDTH, PopupOptions.DynamicResize ? LPGENT("Maximum width") : LPGENT("Width")); //Minimum Width CheckDlgButton(hwnd, IDC_USEMINIMUMWIDTH, PopupOptions.UseMinimumWidth); SendDlgItemMessage(hwnd, IDC_MINIMUMWIDTH_SPIN, UDM_SETRANGE, 0, (LPARAM)MAKELONG(SETTING_MAXIMUMWIDTH_MAX, SETTING_MINIMUMWIDTH_MIN)); SetDlgItemInt(hwnd, IDC_MINIMUMWIDTH, PopupOptions.MinimumWidth, FALSE); //Maximum Width PopupOptions.UseMaximumWidth = PopupOptions.DynamicResize ? PopupOptions.UseMaximumWidth : TRUE; CheckDlgButton(hwnd, IDC_USEMAXIMUMWIDTH, PopupOptions.UseMaximumWidth); SendDlgItemMessage(hwnd, IDC_MAXIMUMWIDTH_SPIN, UDM_SETRANGE, 0, (LPARAM)MAKELONG(SETTING_MAXIMUMWIDTH_MAX, SETTING_MINIMUMWIDTH_MIN)); SetDlgItemInt(hwnd, IDC_MAXIMUMWIDTH, PopupOptions.MaximumWidth, FALSE); //And finally let's enable/disable them. EnableWindow(GetDlgItem(hwnd, IDC_USEMINIMUMWIDTH), PopupOptions.DynamicResize); EnableWindow(GetDlgItem(hwnd, IDC_MINIMUMWIDTH), PopupOptions.DynamicResize && PopupOptions.UseMinimumWidth); EnableWindow(GetDlgItem(hwnd, IDC_MINIMUMWIDTH_SPIN), PopupOptions.DynamicResize && PopupOptions.UseMinimumWidth); EnableWindow(GetDlgItem(hwnd, IDC_MAXIMUMWIDTH), PopupOptions.UseMaximumWidth); EnableWindow(GetDlgItem(hwnd, IDC_MAXIMUMWIDTH_SPIN), PopupOptions.UseMaximumWidth); //Position combobox. { HWND hCtrl = GetDlgItem(hwnd, IDC_WHERE); ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("Upper left corner")), POS_UPPERLEFT); ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("Lower left corner")), POS_LOWERLEFT); ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("Lower right corner")), POS_LOWERRIGHT); ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("Upper right corner")), POS_UPPERRIGHT); SendDlgItemMessage(hwnd, IDC_WHERE, CB_SETCURSEL, PopupOptions.Position, 0); } //Configure popup area { HWND hCtrl = GetDlgItem(hwnd, IDC_CUSTOMPOS); SendMessage(hCtrl, BUTTONSETASFLATBTN, TRUE, 0); SendMessage(hCtrl, BUTTONADDTOOLTIP, (WPARAM)_T("Popup area"), BATF_TCHAR); SendMessage(hCtrl, BM_SETIMAGE, IMAGE_ICON, (LPARAM)IcoLib_GetIcon(ICO_OPT_RESIZE, 0)); } //Spreading combobox { HWND hCtrl = GetDlgItem(hwnd, IDC_LAYOUT); ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("Horizontal")), SPREADING_HORIZONTAL); ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("Vertical")), SPREADING_VERTICAL); SendDlgItemMessage(hwnd, IDC_LAYOUT, CB_SETCURSEL, PopupOptions.Spreading, 0); } //miscellaneous CheckDlgButton(hwnd, IDC_REORDERPOPUPS, PopupOptions.ReorderPopups); //Popup enabled CheckDlgButton(hwnd, IDC_POPUPENABLED, PopupOptions.ModuleIsEnabled ? BST_UNCHECKED : BST_CHECKED); CheckDlgButton(hwnd, IDC_DISABLEINFS, PopupOptions.DisableWhenFullscreen); EnableWindow(GetDlgItem(hwnd, IDC_DISABLEINFS), PopupOptions.ModuleIsEnabled); EnableWindow(GetDlgItem(hwnd, IDC_STATUSES), PopupOptions.ModuleIsEnabled); //new status options { int protocolCount = 0; PROTOACCOUNT **protocols; ProtoEnumAccounts(&protocolCount, &protocols); DWORD globalFlags = 0; for (int i = 0; i < protocolCount; ++i) { DWORD protoFlags = CallProtoService(protocols[i]->szModuleName, PS_GETCAPS, PFLAGNUM_2, 0); globalFlags |= protoFlags; statusOptionsCount += CountStatusModes(protoFlags); } statusOptionsCount += CountStatusModes(globalFlags); statusOptions = new OPTTREE_OPTION[statusOptionsCount]; int pos = AddStatusModes(statusOptions, 0, LPGENT("Global Status"), globalFlags); for (int i = 0; i < protocolCount; ++i) { DWORD protoFlags = CallProtoService(protocols[i]->szModuleName, PS_GETCAPS, PFLAGNUM_2, 0); if (!CountStatusModes(protoFlags)) continue; TCHAR prefix[128]; mir_sntprintf(prefix, SIZEOF(prefix), LPGENT("Protocol Status")_T("/%s"), protocols[i]->tszAccountName); pos = AddStatusModes(statusOptions, pos, prefix, protoFlags); } int index; OptTree_ProcessMessage(hwnd, msg, wParam, lParam, &index, IDC_STATUSES, statusOptions, statusOptionsCount); for (int i = 0; i < protocolCount; ++i) { DWORD protoFlags = CallProtoService(protocols[i]->szModuleName, PS_GETCAPS, PFLAGNUM_2, 0); if (!CountStatusModes(protoFlags)) continue; char prefix[128]; mir_snprintf(prefix, sizeof(prefix), "Protocol Status/%s", protocols[i]->szModuleName); TCHAR pszSettingName[256]; mir_sntprintf(pszSettingName, SIZEOF(pszSettingName), LPGENT("Protocol Status")_T("/%s"), protocols[i]->tszAccountName); OptTree_SetOptions(hwnd, IDC_STATUSES, statusOptions, statusOptionsCount, db_get_dw(NULL, MODULNAME, prefix, 0), pszSettingName); } OptTree_SetOptions(hwnd, IDC_STATUSES, statusOptions, statusOptionsCount, db_get_dw(NULL, MODULNAME, "Global Status", 0), LPGENT("Global Status")); } TranslateDialogDefault(hwnd); //do it on end of WM_INITDIALOG bDlgInit = true; return TRUE; case WM_COMMAND: switch (HIWORD(wParam)) { case BN_CLICKED: //Button controls switch (LOWORD(wParam)) { case IDC_INFINITEDELAY: PopupOptions.InfiniteDelay = !PopupOptions.InfiniteDelay; EnableWindow(GetDlgItem(hwnd, IDC_SECONDS), !PopupOptions.InfiniteDelay); EnableWindow(GetDlgItem(hwnd, IDC_SECONDS_STATIC1), !PopupOptions.InfiniteDelay); EnableWindow(GetDlgItem(hwnd, IDC_SECONDS_STATIC2), !PopupOptions.InfiniteDelay); EnableWindow(GetDlgItem(hwnd, IDC_LEAVEHOVERED), !PopupOptions.InfiniteDelay); SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0); break; case IDC_LEAVEHOVERED: PopupOptions.LeaveHovered = !PopupOptions.LeaveHovered; SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0); break; case IDC_DYNAMICRESIZE: PopupOptions.DynamicResize = !PopupOptions.DynamicResize; EnableWindow(GetDlgItem(hwnd, IDC_USEMINIMUMWIDTH), PopupOptions.DynamicResize); EnableWindow(GetDlgItem(hwnd, IDC_MINIMUMWIDTH), PopupOptions.DynamicResize && PopupOptions.UseMinimumWidth); EnableWindow(GetDlgItem(hwnd, IDC_MINIMUMWIDTH_SPIN), PopupOptions.DynamicResize && PopupOptions.UseMinimumWidth); SetDlgItemText(hwnd, IDC_USEMAXIMUMWIDTH, PopupOptions.DynamicResize ? TranslateT("Maximum width") : TranslateT("Width")); if (!PopupOptions.DynamicResize) { PopupOptions.UseMaximumWidth = TRUE; CheckDlgButton(hwnd, IDC_USEMAXIMUMWIDTH, BST_CHECKED); EnableWindow(GetDlgItem(hwnd, IDC_USEMAXIMUMWIDTH), TRUE); EnableWindow(GetDlgItem(hwnd, IDC_MAXIMUMWIDTH), TRUE); EnableWindow(GetDlgItem(hwnd, IDC_MAXIMUMWIDTH_SPIN), TRUE); } SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0); break; case IDC_USEMINIMUMWIDTH: PopupOptions.UseMinimumWidth = !PopupOptions.UseMinimumWidth; EnableWindow(GetDlgItem(hwnd, IDC_MINIMUMWIDTH), PopupOptions.UseMinimumWidth); EnableWindow(GetDlgItem(hwnd, IDC_MINIMUMWIDTH_SPIN), PopupOptions.UseMinimumWidth); SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0); break; case IDC_USEMAXIMUMWIDTH: PopupOptions.UseMaximumWidth = Button_GetCheck((HWND)lParam); if (!PopupOptions.DynamicResize) { //ugly - set always on if DynamicResize = off CheckDlgButton(hwnd, LOWORD(wParam), BST_CHECKED); PopupOptions.UseMaximumWidth = TRUE; } EnableWindow(GetDlgItem(hwnd, IDC_MAXIMUMWIDTH), PopupOptions.UseMaximumWidth); EnableWindow(GetDlgItem(hwnd, IDC_MAXIMUMWIDTH_SPIN), PopupOptions.UseMaximumWidth); SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0); break; case IDC_CUSTOMPOS: { RECT rcButton, rcBox; HWND hwndBox = CreateDialog(hInst, MAKEINTRESOURCE(IDD_POSITION), NULL, PositionBoxDlgProc); GetWindowRect((HWND)lParam, &rcButton); GetWindowRect(hwndBox, &rcBox); MoveWindow(hwndBox, rcButton.right - (rcBox.right - rcBox.left) + 15, rcButton.bottom + 3, rcBox.right - rcBox.left, rcBox.bottom - rcBox.top, FALSE); SetWindowLongPtr(hwndBox, GWL_EXSTYLE, GetWindowLongPtr(hwndBox, GWL_EXSTYLE) | WS_EX_LAYERED); SetLayeredWindowAttributes(hwndBox, NULL, 0, LWA_ALPHA); ShowWindow(hwndBox, SW_SHOW); for (int i = 0; i <= 255; i += 15) { SetLayeredWindowAttributes(hwndBox, NULL, i, LWA_ALPHA); UpdateWindow(hwndBox); Sleep(1); } SetWindowLongPtr(hwndBox, GWL_EXSTYLE, GetWindowLongPtr(hwndBox, GWL_EXSTYLE) & ~WS_EX_LAYERED); ShowWindow(hwndBox, SW_SHOW); SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0); } break; case IDC_REORDERPOPUPS: { PopupOptions.ReorderPopups = !PopupOptions.ReorderPopups; PopupOptions.ReorderPopupsWarning = PopupOptions.ReorderPopups ? db_get_b(NULL, MODULNAME, "ReorderPopupsWarning", TRUE) : TRUE; SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0); } break; case IDC_POPUPENABLED: { int chk = IsDlgButtonChecked(hwnd, IDC_POPUPENABLED); if (PopupOptions.ModuleIsEnabled&&chk || !PopupOptions.ModuleIsEnabled && !chk) svcEnableDisableMenuCommand(0, 0); EnableWindow(GetDlgItem(hwnd, IDC_STATUSES), PopupOptions.ModuleIsEnabled); EnableWindow(GetDlgItem(hwnd, IDC_DISABLEINFS), PopupOptions.ModuleIsEnabled); } break; case IDC_DISABLEINFS: PopupOptions.DisableWhenFullscreen = !PopupOptions.DisableWhenFullscreen; SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0); break; case IDC_PREVIEW: PopupPreview(); break; } break; case CBN_SELCHANGE: //ComboBox controls switch (LOWORD(wParam)) { //lParam = Handle to the control case IDC_WHERE: PopupOptions.Position = ComboBox_GetItemData((HWND)lParam, ComboBox_GetCurSel((HWND)lParam)); SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0); break; case IDC_LAYOUT: PopupOptions.Spreading = ComboBox_GetItemData((HWND)lParam, ComboBox_GetCurSel((HWND)lParam)); SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0); break; } break; case EN_CHANGE: //Edit controls change if (!bDlgInit) break; switch (LOWORD(wParam)) { //lParam = Handle to the control case IDC_SECONDS: { int seconds = GetDlgItemInt(hwnd, LOWORD(wParam), NULL, FALSE); if (seconds >= SETTING_LIFETIME_MIN && seconds <= SETTING_LIFETIME_MAX && seconds != PopupOptions.Seconds) { PopupOptions.Seconds = seconds; SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0); } } break; case IDC_MINIMUMWIDTH: { int temp = GetDlgItemInt(hwnd, IDC_MINIMUMWIDTH, NULL, FALSE); if (temp >= SETTING_MINIMUMWIDTH_MIN && temp <= SETTING_MAXIMUMWIDTH_MAX && temp != PopupOptions.MinimumWidth) { PopupOptions.MinimumWidth = temp; SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0); } } break; case IDC_MAXIMUMWIDTH: { int temp = GetDlgItemInt(hwnd, IDC_MAXIMUMWIDTH, NULL, FALSE); if (temp >= SETTING_MINIMUMWIDTH_MIN && temp <= SETTING_MAXIMUMWIDTH_MAX && temp != PopupOptions.MaximumWidth) { PopupOptions.MaximumWidth = temp; SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0); } } break; }//end switch(idCtrl) break; case EN_KILLFOCUS: //Edit controls lost fokus switch (LOWORD(wParam)) { //lParam = Handle to the control case IDC_SECONDS: { int seconds = GetDlgItemInt(hwnd, LOWORD(wParam), NULL, FALSE); if (seconds > SETTING_LIFETIME_MAX) PopupOptions.Seconds = SETTING_LIFETIME_MAX; else if (seconds < SETTING_LIFETIME_MIN) PopupOptions.Seconds = SETTING_LIFETIME_MIN; if (seconds != PopupOptions.Seconds) { SetDlgItemInt(hwnd, LOWORD(wParam), PopupOptions.Seconds, FALSE); ErrorMSG(SETTING_LIFETIME_MIN, SETTING_LIFETIME_MAX); SetFocus((HWND)lParam); } } break; case IDC_MINIMUMWIDTH: { int temp = GetDlgItemInt(hwnd, LOWORD(wParam), NULL, FALSE); if (temp < SETTING_MINIMUMWIDTH_MIN) PopupOptions.MinimumWidth = SETTING_MINIMUMWIDTH_MIN; else if (temp > SETTING_MAXIMUMWIDTH_MAX) PopupOptions.MinimumWidth = SETTING_MAXIMUMWIDTH_MAX; if (temp != PopupOptions.MinimumWidth) { SetDlgItemInt(hwnd, LOWORD(wParam), PopupOptions.MinimumWidth, FALSE); ErrorMSG(SETTING_MINIMUMWIDTH_MIN, SETTING_MAXIMUMWIDTH_MAX); SetFocus((HWND)lParam); break; } if (temp > PopupOptions.MaximumWidth) { PopupOptions.MaximumWidth = min(temp, SETTING_MAXIMUMWIDTH_MAX); SetDlgItemInt(hwnd, IDC_MAXIMUMWIDTH, PopupOptions.MaximumWidth, FALSE); } } break; case IDC_MAXIMUMWIDTH: { int temp = GetDlgItemInt(hwnd, LOWORD(wParam), NULL, FALSE); if (temp >= SETTING_MAXIMUMWIDTH_MAX) PopupOptions.MaximumWidth = SETTING_MAXIMUMWIDTH_MAX; else if (temp < SETTING_MINIMUMWIDTH_MIN) PopupOptions.MaximumWidth = SETTING_MINIMUMWIDTH_MIN; if (temp != PopupOptions.MaximumWidth) { SetDlgItemInt(hwnd, LOWORD(wParam), PopupOptions.MaximumWidth, FALSE); ErrorMSG(SETTING_MINIMUMWIDTH_MIN, SETTING_MAXIMUMWIDTH_MAX); SetFocus((HWND)lParam); break; } if (temp < PopupOptions.MinimumWidth) { PopupOptions.MinimumWidth = max(temp, SETTING_MINIMUMWIDTH_MIN); SetDlgItemInt(hwnd, IDC_MINIMUMWIDTH, PopupOptions.MinimumWidth, FALSE); } } break; } break; } break; case WM_NOTIFY: switch (((LPNMHDR)lParam)->idFrom) { case 0: switch (((LPNMHDR)lParam)->code) { case PSN_RESET: LoadOption_General(); return TRUE; case PSN_APPLY: //Seconds db_set_b(NULL, MODULNAME, "InfiniteDelay", PopupOptions.InfiniteDelay); db_set_w(NULL, MODULNAME, "Seconds", (WORD)PopupOptions.Seconds); db_set_b(NULL, MODULNAME, "LeaveHovered", PopupOptions.LeaveHovered); //Dynamic Resize db_set_b(NULL, MODULNAME, "DynamicResize", PopupOptions.DynamicResize); db_set_b(NULL, MODULNAME, "UseMinimumWidth", PopupOptions.UseMinimumWidth); db_set_w(NULL, MODULNAME, "MinimumWidth", PopupOptions.MinimumWidth); db_set_b(NULL, MODULNAME, "UseMaximumWidth", PopupOptions.UseMaximumWidth); db_set_w(NULL, MODULNAME, "MaximumWidth", PopupOptions.MaximumWidth); //Position db_set_b(NULL, MODULNAME, "Position", (BYTE)PopupOptions.Position); //Configure popup area db_set_w(NULL, MODULNAME, "gapTop", (WORD)PopupOptions.gapTop); db_set_w(NULL, MODULNAME, "gapBottom", (WORD)PopupOptions.gapBottom); db_set_w(NULL, MODULNAME, "gapLeft", (WORD)PopupOptions.gapLeft); db_set_w(NULL, MODULNAME, "gapRight", (WORD)PopupOptions.gapRight); db_set_w(NULL, MODULNAME, "spacing", (WORD)PopupOptions.spacing); //Spreading db_set_b(NULL, MODULNAME, "Spreading", (BYTE)PopupOptions.Spreading); //miscellaneous Check_ReorderPopups(hwnd); //this save also PopupOptions.ReorderPopups //disable When db_set_b(NULL, MODULNAME, "DisableWhenFullscreen", PopupOptions.DisableWhenFullscreen); //new status options { int protocolCount; PROTOACCOUNT **protocols; ProtoEnumAccounts(&protocolCount, &protocols); for (int i = 0; i < protocolCount; ++i) { char prefix[128]; mir_snprintf(prefix, SIZEOF(prefix), "Protocol Status/%s", protocols[i]->szModuleName); TCHAR pszSettingName[256]; mir_sntprintf(pszSettingName, SIZEOF(pszSettingName), _T("Protocol Status/%s"), protocols[i]->tszAccountName); db_set_dw(NULL, MODULNAME, prefix, OptTree_GetOptions(hwnd, IDC_STATUSES, statusOptions, statusOptionsCount, pszSettingName)); } db_set_dw(NULL, MODULNAME, "Global Status", OptTree_GetOptions(hwnd, IDC_STATUSES, statusOptions, statusOptionsCount, _T("Global Status"))); } return TRUE; } break; case IDC_MINIMUMWIDTH_SPIN: { LPNMUPDOWN lpnmud = (LPNMUPDOWN)lParam; int temp = lpnmud->iPos + lpnmud->iDelta; if (temp > PopupOptions.MaximumWidth) { PopupOptions.MaximumWidth = min(temp, SETTING_MAXIMUMWIDTH_MAX); SetDlgItemInt(hwnd, IDC_MAXIMUMWIDTH, PopupOptions.MaximumWidth, FALSE); } } break; case IDC_MAXIMUMWIDTH_SPIN: { LPNMUPDOWN lpnmud = (LPNMUPDOWN)lParam; int temp = lpnmud->iPos + lpnmud->iDelta; if (temp < PopupOptions.MinimumWidth) { PopupOptions.MinimumWidth = max(temp, SETTING_MINIMUMWIDTH_MIN); SetDlgItemInt(hwnd, IDC_MINIMUMWIDTH, PopupOptions.MinimumWidth, FALSE); } } } break; case WM_DESTROY: if (statusOptions) { for (int i = 0; i < statusOptionsCount; ++i) { mir_free(statusOptions[i].pszOptionName); mir_free(statusOptions[i].pszSettingName); } delete [] statusOptions; statusOptions = NULL; statusOptionsCount = 0; bDlgInit = false; } break; } return FALSE; }
void __fastcall xmlAddAttrID(HXML hXml, int id) { TCHAR text[100]; mir_sntprintf(text, SIZEOF(text), _T(JABBER_IQID) _T("%d"), id); xmlAddAttr(hXml, _T("id"), text); }
int CJabberProto::ByteSendProxyParse( HANDLE hConn, JABBER_BYTE_TRANSFER *jbt, char* buffer, int datalen ) { int num = datalen; switch ( jbt->state ) { case JBT_INIT: // received: // 00-00 ver ( 0x05 ) // 01-01 selected method ( 0=no auth, 0xff=error ) // send: // 00-00 ver ( 0x05 ) // 01-01 cmd ( 1=connect ) // 02-02 reserved ( 0 ) // 03-03 address type ( 3 ) // 04-44 dst.addr ( 41 bytes: 1-byte length, 40-byte SHA1 hash of [sid,srcJID,dstJID] ) // 45-46 dst.port ( 0 ) if ( datalen==2 && buffer[0]==5 && buffer[1]==0 ) { BYTE data[47]; ZeroMemory( data, sizeof( data )); *(( DWORD* )data ) = 0x03000105; data[4] = 40; TCHAR text[256]; TCHAR *szInitiatorJid = JabberPrepareJid(jbt->srcJID); TCHAR *szTargetJid = JabberPrepareJid(jbt->dstJID); mir_sntprintf( text, SIZEOF( text ), _T("%s%s%s"), jbt->sid, szInitiatorJid, szTargetJid ); mir_free(szInitiatorJid); mir_free(szTargetJid); char* szAuthString = mir_utf8encodeT( text ); Log( "Auth: '%s'", szAuthString ); char* szHash = JabberSha1( szAuthString ); strncpy(( char* )( data+5 ), szHash, 40 ); mir_free( szHash ); Netlib_Send( hConn, ( char* )data, 47, 0 ); jbt->state = JBT_CONNECT; mir_free( szAuthString ); } else jbt->state = JBT_SOCKSERR; break; case JBT_CONNECT: // received: // 00-00 ver ( 0x05 ) // 01-01 reply ( 0=success,2=not allowed ) // 02-02 reserved ( 0 ) // 03-03 address type ( 1=IPv4 address,3=host address ) // 04-mm bnd.addr server bound address ( 4-byte IP if IPv4, 1-byte length + n-byte host address string if host address ) // nn-nn+1 bnd.port server bound port if ( datalen>=5 && buffer[0]==5 && buffer[1]==0 && ( buffer[3]==1 || buffer[3]==3 || buffer[3]==0 )) { if ( buffer[3]==1 && datalen>=10 ) num = 10; else if ( buffer[3]==3 && datalen>=buffer[4]+7 ) num = buffer[4] + 7; else if ( buffer[3]==0 && datalen>=6 ) num = 6; else { jbt->state = JBT_SOCKSERR; break; } jbt->state = JBT_SENDING; jbt->hProxyEvent = CreateEvent( NULL, FALSE, FALSE, NULL ); jbt->bStreamActivated = FALSE; int iqId = SerialNext(); TCHAR listJid[256]; mir_sntprintf(listJid, SIZEOF( listJid ), _T("ftproxy_%d"), iqId); JABBER_LIST_ITEM *item = ListAdd( LIST_FTIQID, listJid ); item->jbt = jbt; IqAdd( iqId, IQ_PROC_NONE, &CJabberProto::IqResultStreamActivate ); m_ThreadInfo->send( XmlNodeIq( _T("set"), iqId, jbt->streamhostJID ) << XQUERY( _T(JABBER_FEAT_BYTESTREAMS)) << XATTR( _T("sid"), jbt->sid ) << XCHILD( _T("activate"), jbt->dstJID )); WaitForSingleObject( jbt->hProxyEvent, INFINITE ); CloseHandle( jbt->hProxyEvent ); jbt->hProxyEvent = NULL; ListRemove( LIST_FTIQID, listJid ); if ( jbt->bStreamActivated) jbt->state = (this->*jbt->pfnSend)( hConn, jbt->ft ) ? JBT_DONE : JBT_ERROR; else jbt->state = JBT_ERROR; } else jbt->state = JBT_SOCKSERR; break; } return num; }
int CJabberProto::ByteReceiveParse( HANDLE hConn, JABBER_BYTE_TRANSFER *jbt, char* buffer, int datalen ) { int bytesReceived, num = datalen; switch ( jbt->state ) { case JBT_INIT: // received: // 00-00 ver ( 0x05 ) // 01-01 selected method ( 0=no auth, 0xff=error ) // send: // 00-00 ver ( 0x05 ) // 01-01 cmd ( 1=connect ) // 02-02 reserved ( 0 ) // 03-03 address type ( 3 ) // 04-44 dst.addr ( 41 bytes: 1-byte length, 40-byte SHA1 hash of [sid,srcJID,dstJID] ) // 45-46 dst.port ( 0 ) if ( datalen==2 && buffer[0]==5 && buffer[1]==0 ) { BYTE data[47]; ZeroMemory( data, sizeof( data )); *(( DWORD* )data ) = 0x03000105; data[4] = 40; TCHAR text[JABBER_MAX_JID_LEN*2]; TCHAR *szInitiatorJid = JabberPrepareJid(jbt->srcJID); TCHAR *szTargetJid = JabberPrepareJid(jbt->dstJID); mir_sntprintf( text, SIZEOF( text ), _T("%s%s%s"), jbt->sid, szInitiatorJid, szTargetJid ); mir_free(szInitiatorJid); mir_free(szTargetJid); char* szAuthString = mir_utf8encodeT( text ); Log( "Auth: '%s'", szAuthString ); char* szHash = JabberSha1( szAuthString ); strncpy(( char* )( data+5 ), szHash, 40 ); mir_free( szHash ); Netlib_Send( hConn, ( char* )data, 47, 0 ); jbt->state = JBT_CONNECT; mir_free( szAuthString ); } else jbt->state = JBT_SOCKSERR; break; case JBT_CONNECT: // received: // 00-00 ver ( 0x05 ) // 01-01 reply ( 0=success,2=not allowed ) // 02-02 reserved ( 0 ) // 03-03 address type ( 1=IPv4 address,3=host address ) // 04-mm bnd.addr server bound address ( 4-byte IP if IPv4, 1-byte length + n-byte host address string if host address ) // nn-nn+1 bnd.port server bound port if ( datalen>=5 && buffer[0]==5 && buffer[1]==0 && ( buffer[3]==1 || buffer[3]==3 || buffer[3]==0 )) { if ( buffer[3]==1 && datalen>=10 ) num = 10; else if ( buffer[3]==3 && datalen>=buffer[4]+7 ) num = buffer[4] + 7; else if ( buffer[3]==0 && datalen>=6 ) num = 6; else { jbt->state = JBT_SOCKSERR; break; } jbt->state = JBT_RECVING; m_ThreadInfo->send( XmlNodeIq( _T("result"), jbt->iqId, jbt->srcJID ) << XQUERY( _T(JABBER_FEAT_BYTESTREAMS)) << XCHILD( _T("streamhost-used")) << XATTR( _T("jid"), jbt->streamhostJID )); } else jbt->state = JBT_SOCKSERR; break; case JBT_RECVING: bytesReceived = (this->*jbt->pfnRecv)( hConn, jbt->ft, buffer, datalen ); if ( bytesReceived < 0 ) jbt->state = JBT_ERROR; else if ( bytesReceived == 0 ) jbt->state = JBT_DONE; break; } return num; }
void CJabberProto::ByteSendThread( JABBER_BYTE_TRANSFER *jbt ) { char* localAddr; char* localAddrInternal; struct in_addr in; DBVARIANT dbv; TCHAR szPort[8]; HANDLE hEvent = NULL; TCHAR* proxyJid; CJabberIqInfo* pInfo = NULL; int nIqId = 0; Log( "Thread started: type=bytestream_send" ); BOOL bDirect = m_options.BsDirect; if ( m_options.BsProxyManual ) { proxyJid = NULL; if ( !DBGetContactSettingString( NULL, m_szModuleName, "BsProxyServer", &dbv )) { proxyJid = mir_a2t( dbv.pszVal ); JFreeVariant( &dbv ); } if ( proxyJid ) { jbt->bProxyDiscovered = FALSE; jbt->szProxyHost = NULL; jbt->szProxyPort = NULL; jbt->szProxyJid = NULL; jbt->hProxyEvent = CreateEvent( NULL, FALSE, FALSE, NULL ); pInfo = m_iqManager.AddHandler( &CJabberProto::IqResultProxyDiscovery, JABBER_IQ_TYPE_GET, proxyJid, 0, -1, jbt ); nIqId = pInfo->GetIqId(); XmlNodeIq iq( pInfo ); iq << XQUERY( _T(JABBER_FEAT_BYTESTREAMS)); m_ThreadInfo->send( iq ); WaitForSingleObject( jbt->hProxyEvent, INFINITE ); m_iqManager.ExpireIq ( nIqId ); CloseHandle( jbt->hProxyEvent ); jbt->hProxyEvent = NULL; mir_free( proxyJid ); if ( jbt->state == JBT_ERROR && !bDirect ) { Log( "Bytestream proxy failure" ); MsgPopup( pInfo->GetHContact(), TranslateT("Bytestream Proxy not available"), pInfo->GetReceiver()); jbt->ft->state = FT_DENIED; (this->*jbt->pfnFinal)( FALSE, jbt->ft ); jbt->ft = NULL; delete jbt; return; } } } pInfo = m_iqManager.AddHandler( &CJabberProto::ByteInitiateResult, JABBER_IQ_TYPE_SET, jbt->dstJID, 0, -1, jbt ); nIqId = pInfo->GetIqId(); { XmlNodeIq iq( pInfo ); HXML query = iq << XQUERY( _T(JABBER_FEAT_BYTESTREAMS)) << XATTR( _T("sid"), jbt->sid ); if ( bDirect ) { localAddr = NULL; if ( m_options.BsDirectManual == TRUE ) { if ( !DBGetContactSettingString( NULL, m_szModuleName, "BsDirectAddr", &dbv )) { localAddr = NEWSTR_ALLOCA( dbv.pszVal ); JFreeVariant( &dbv ); } } NETLIBBIND nlb = {0}; nlb.cbSize = sizeof( NETLIBBIND ); nlb.pfnNewConnectionV2 = JabberByteSendConnection; nlb.pExtra = this; nlb.wPort = 0; // Use user-specified incoming port ranges, if available jbt->hConn = ( HANDLE ) JCallService( MS_NETLIB_BINDPORT, ( WPARAM ) m_hNetlibUser, ( LPARAM )&nlb ); if ( jbt->hConn == NULL ) { Log( "Cannot allocate port for bytestream_send thread, thread ended." ); delete jbt; return; } if ( localAddr == NULL ) { in.S_un.S_addr = htonl(nlb.dwExternalIP); localAddr = NEWSTR_ALLOCA( inet_ntoa( in )); } in.S_un.S_addr = htonl(nlb.dwInternalIP); localAddrInternal = NEWSTR_ALLOCA( inet_ntoa( in )); mir_sntprintf( szPort, SIZEOF( szPort ), _T("%d"), nlb.wPort ); JABBER_LIST_ITEM *item = ListAdd( LIST_BYTE, szPort ); item->jbt = jbt; hEvent = CreateEvent( NULL, FALSE, FALSE, NULL ); jbt->hEvent = hEvent; jbt->hSendEvent = CreateEvent( NULL, FALSE, FALSE, NULL ); query << XCHILD( _T("streamhost")) << XATTR( _T("jid"), m_ThreadInfo->fullJID ) << XATTR( _T("host"), _A2T(localAddr)) << XATTRI( _T("port"), nlb.wPort ); if ( strcmp( localAddr, localAddrInternal )) query << XCHILD( _T("streamhost")) << XATTR( _T("jid"), m_ThreadInfo->fullJID ) << XATTR( _T("host"), _A2T(localAddrInternal)) << XATTRI( _T("port"), nlb.wPort ); } if ( jbt->bProxyDiscovered ) query << XCHILD( _T("streamhost")) << XATTR( _T("jid"), jbt->szProxyJid ) << XATTR( _T("host"), jbt->szProxyHost ) << XATTR( _T("port"), jbt->szProxyPort ); jbt->hProxyEvent = CreateEvent( NULL, FALSE, FALSE, NULL ); jbt->szStreamhostUsed = NULL; m_ThreadInfo->send( iq ); } WaitForSingleObject( jbt->hProxyEvent, INFINITE ); m_iqManager.ExpireIq( nIqId ); CloseHandle( jbt->hProxyEvent ); jbt->hProxyEvent = NULL; if ( !jbt->szStreamhostUsed ) { if ( bDirect ) { SetEvent( jbt->hSendEvent ); CloseHandle( jbt->hSendEvent ); CloseHandle( hEvent ); jbt->hEvent = NULL; if ( jbt->hConn != NULL ) Netlib_CloseHandle( jbt->hConn ); jbt->hConn = NULL; ListRemove( LIST_BYTE, szPort ); } (this->*jbt->pfnFinal)(( jbt->state==JBT_DONE )?TRUE:FALSE, jbt->ft ); jbt->ft = NULL; // stupid fix: wait for listening thread exit Sleep( 100 ); delete jbt; return; } if ( jbt->bProxyDiscovered && !_tcscmp( jbt->szProxyJid, jbt->szStreamhostUsed )) { // jabber proxy used if ( bDirect ) { SetEvent( jbt->hSendEvent ); CloseHandle( jbt->hSendEvent ); CloseHandle( hEvent ); jbt->hEvent = NULL; if ( jbt->hConn != NULL ) Netlib_CloseHandle( jbt->hConn ); jbt->hConn = NULL; ListRemove( LIST_BYTE, szPort ); } ByteSendViaProxy( jbt ); } else { SetEvent( jbt->hSendEvent ); WaitForSingleObject( hEvent, INFINITE ); CloseHandle( hEvent ); CloseHandle( jbt->hSendEvent ); jbt->hEvent = NULL; (this->*jbt->pfnFinal)(( jbt->state == JBT_DONE ) ? TRUE : FALSE, jbt->ft ); jbt->ft = NULL; if ( jbt->hConn != NULL ) Netlib_CloseHandle( jbt->hConn ); jbt->hConn = NULL; ListRemove( LIST_BYTE, szPort ); } // stupid fix: wait for listening connection thread exit Sleep( 100 ); delete jbt; Log( "Thread ended: type=bytestream_send" ); }
int CJabberProto::ByteSendParse( HANDLE hConn, JABBER_BYTE_TRANSFER *jbt, char* buffer, int datalen ) { int nMethods; BYTE data[10]; int i; char* str; switch ( jbt->state ) { case JBT_INIT: // received: // 00-00 ver ( 0x05 ) // 01-01 nmethods // 02-xx list of methods ( nmethods bytes ) // send: // 00-00 ver ( 0x05 ) // 01-01 select method ( 0=no auth required ) if ( datalen>=2 && buffer[0]==5 && buffer[1]+2==datalen ) { nMethods = buffer[1]; for ( i=0; i<nMethods && buffer[2+i]!=0; i++ ); if ( i < nMethods ) { data[1] = 0; jbt->state = JBT_CONNECT; } else { data[1] = 0xff; jbt->state = JBT_ERROR; } data[0] = 5; Netlib_Send( hConn, ( char* )data, 2, 0 ); } else jbt->state = JBT_ERROR; break; case JBT_CONNECT: // received: // 00-00 ver ( 0x05 ) // 01-01 cmd ( 1=connect ) // 02-02 reserved ( 0 ) // 03-03 address type ( 3 ) // 04-44 dst.addr ( 41 bytes: 1-byte length, 40-byte SHA1 hash of [sid,srcJID,dstJID] ) // 45-46 dst.port ( 0 ) // send: // 00-00 ver ( 0x05 ) // 01-01 reply ( 0=success,2=not allowed ) // 02-02 reserved ( 0 ) // 03-03 address type ( 1=IPv4 address ) // 04-07 bnd.addr server bound address // 08-09 bnd.port server bound port if ( datalen == 47 && *(( DWORD* )buffer )==0x03000105 && buffer[4]==40 && *(( WORD* )( buffer+45 ))==0 ) { TCHAR text[256]; TCHAR *szInitiatorJid = JabberPrepareJid(jbt->srcJID); TCHAR *szTargetJid = JabberPrepareJid(jbt->dstJID); mir_sntprintf( text, SIZEOF( text ), _T("%s%s%s"), jbt->sid, szInitiatorJid, szTargetJid ); mir_free(szInitiatorJid); mir_free(szTargetJid); char* szAuthString = mir_utf8encodeT( text ); Log( "Auth: '%s'", szAuthString ); if (( str = JabberSha1( szAuthString )) != NULL ) { for ( i=0; i<40 && buffer[i+5]==str[i]; i++ ); mir_free( str ); ZeroMemory( data, 10 ); data[1] = ( i>=20 )?0:2; data[0] = 5; data[3] = 1; Netlib_Send( hConn, ( char* )data, 10, 0 ); // wait stream activation WaitForSingleObject( jbt->hSendEvent, INFINITE ); if ( jbt->state == JBT_ERROR ) break; if ( i>=20 && (this->*jbt->pfnSend)( hConn, jbt->ft )==TRUE ) jbt->state = JBT_DONE; else jbt->state = JBT_ERROR; } mir_free( szAuthString ); } else jbt->state = JBT_ERROR; break; } return datalen; }
void ShowPopup(XSTATUSCHANGE *xsc) { DBVARIANT dbv; char szSetting[64]; POPUPDATAT ppd = {0}; ppd.lchContact = xsc->hContact; switch(xsc->type) { case TYPE_JABBER_MOOD: case TYPE_JABBER_ACTIVITY: mir_snprintf(szSetting, SIZEOF(szSetting), "%s/%s/%s", xsc->szProto, (xsc->type == TYPE_JABBER_MOOD) ? "mood" : "activity", "icon"); if (!db_get_s(xsc->hContact, "AdvStatus", szSetting, &dbv)) { ppd.lchIcon = Skin_GetIcon(dbv.pszVal); db_free(&dbv); } break; case TYPE_ICQ_XSTATUS: { int statusId = db_get_b(xsc->hContact, xsc->szProto, "XStatusId", 0); ppd.lchIcon = (HICON)CallProtoService(xsc->szProto, PS_GETCUSTOMSTATUSICON, statusId, LR_SHARED); } } if (ppd.lchIcon == NULL) ppd.lchIcon = LoadSkinnedProtoIcon(xsc->szProto, db_get_w(xsc->hContact, xsc->szProto, "Status", ID_STATUS_ONLINE)); switch (opt.Colors) { case POPUP_COLOR_OWN: ppd.colorBack = db_get_dw(0, MODULE, "40081bg", COLOR_BG_AVAILDEFAULT); ppd.colorText = db_get_dw(0, MODULE, "40081tx", COLOR_TX_DEFAULT); break; case POPUP_COLOR_WINDOWS: ppd.colorBack = GetSysColor(COLOR_BTNFACE); ppd.colorText = GetSysColor(COLOR_WINDOWTEXT); break; case POPUP_COLOR_POPUP: ppd.colorBack = ppd.colorText = 0; break; } TCHAR *ptszGroup = NULL; TCHAR *ptszNick = (TCHAR *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)xsc->hContact, GSMDF_TCHAR); if (opt.ShowGroup) { //add group name to popup title if (!db_get_ts(xsc->hContact, "CList", "Group", &dbv)) { ptszGroup = NEWTSTR_ALLOCA(dbv.ptszVal); db_free(&dbv); } } if (ptszGroup) mir_sntprintf(ppd.lptzContactName, SIZEOF(ppd.lptzContactName),_T("%s (%s)"), ptszNick, ptszGroup); else _tcsncpy(ppd.lptzContactName, ptszNick, SIZEOF(ppd.lptzContactName)); // cut message if needed if (opt.PTruncateMsg && (opt.PMsgLen > 0) && xsc->stzText && (_tcslen(xsc->stzText) > opt.PMsgLen)) { TCHAR buff[MAX_TEXT_LEN + 3]; _tcsncpy(buff, xsc->stzText, opt.PMsgLen); buff[opt.PMsgLen] = 0; _tcscat(buff, _T("...")); mir_free(xsc->stzText); xsc->stzText = mir_tstrdup(buff); } TCHAR *Template = _T(""); switch (xsc->action) { case NOTIFY_NEW_XSTATUS: Template = templates.PopupNewXstatus; break; case NOTIFY_NEW_MESSAGE: Template = templates.PopupNewMsg; break; case NOTIFY_REMOVE: Template = templates.PopupRemove; break; case NOTIFY_OPENING_ML: Template = templates.LogOpening; break; } TCHAR stzPopupText[2*MAX_TEXT_LEN]; ReplaceVars(xsc, Template, templates.PopupDelimiter, stzPopupText); _tcsncpy(ppd.lptzText, stzPopupText, SIZEOF(ppd.lptzText)); ppd.lptzText[SIZEOF(ppd.lptzText) - 1] = 0; ppd.PluginWindowProc = (WNDPROC)PopupDlgProc; ppd.iSeconds = opt.PopupTimeout; PUAddPopupT(&ppd); }
static void sttFillJidList(HWND hwndDlg) { JABBER_MUC_JIDLIST_INFO *jidListInfo; HXML iqNode, queryNode; const TCHAR* from, *jid, *reason, *nick; LVITEM lvi; HWND hwndList; int count, i; TCHAR *filter = NULL; if (GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_FILTER), GWLP_USERDATA)) { int filterLength = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_FILTER)) + 1; filter = (TCHAR *)_alloca(filterLength * sizeof(TCHAR)); GetDlgItemText(hwndDlg, IDC_FILTER, filter, filterLength); } jidListInfo = ( JABBER_MUC_JIDLIST_INFO * ) GetWindowLongPtr( hwndDlg, GWLP_USERDATA ); if ( !jidListInfo ) return; hwndList = GetDlgItem( hwndDlg, IDC_LIST ); SendMessage(hwndList, WM_SETREDRAW, FALSE, 0); count = ListView_GetItemCount( hwndList ); lvi.mask = LVIF_PARAM; lvi.iSubItem = 0; for ( i=0; i<count; i++ ) { lvi.iItem = i; if ( ListView_GetItem( hwndList, &lvi ) == TRUE ) { if ( lvi.lParam!=( LPARAM )( -1 ) && lvi.lParam!=( LPARAM )( NULL )) { mir_free(( void * ) lvi.lParam ); } } } ListView_DeleteAllItems( hwndList ); // Populate displayed list from iqNode if (( iqNode = jidListInfo->iqNode ) != NULL ) { if (( from = xmlGetAttrValue( iqNode, _T("from"))) != NULL ) { if (( queryNode = xmlGetChild( iqNode , "query" )) != NULL ) { lvi.mask = LVIF_TEXT | LVIF_PARAM; lvi.iSubItem = 0; lvi.iItem = 0; for ( i=0; ; i++ ) { HXML itemNode = xmlGetChild( queryNode ,i); if ( !itemNode ) break; if (( jid = xmlGetAttrValue( itemNode, _T("jid"))) != NULL ) { lvi.pszText = ( TCHAR* )jid; if ( jidListInfo->type == MUC_BANLIST ) { if (( reason = xmlGetText(xmlGetChild( itemNode , "reason" ))) != NULL ) { TCHAR jidreason[ JABBER_MAX_JID_LEN + 256 ]; mir_sntprintf( jidreason, SIZEOF( jidreason ), _T("%s (%s)") , jid, reason ); lvi.pszText = jidreason; } } if ( jidListInfo->type == MUC_VOICELIST || jidListInfo->type == MUC_MODERATORLIST ) { if (( nick = xmlGetAttrValue( itemNode, _T("nick"))) != NULL ) { TCHAR nickjid[ JABBER_MAX_JID_LEN + 256 ]; mir_sntprintf( nickjid, SIZEOF( nickjid ), _T("%s (%s)") , nick, jid ); lvi.pszText = nickjid; } } if (filter && *filter && !JabberStrIStr(lvi.pszText, filter)) continue; lvi.lParam = ( LPARAM )mir_tstrdup( jid ); ListView_InsertItem( hwndList, &lvi ); lvi.iItem++; } } } } } lvi.mask = LVIF_PARAM; lvi.lParam = ( LPARAM )( -1 ); ListView_InsertItem( hwndList, &lvi ); SendMessage(hwndList, WM_SETREDRAW, TRUE, 0); RedrawWindow(hwndList, NULL, NULL, RDW_INVALIDATE); }
static INT_PTR CALLBACK JabberMucJidListDlgProc( HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam ) { JABBER_MUC_JIDLIST_INFO* dat = (JABBER_MUC_JIDLIST_INFO*)GetWindowLongPtr( hwndDlg, GWLP_USERDATA ); switch( msg ) { case WM_INITDIALOG: { LVCOLUMN lvc; RECT rc; HWND hwndList; TranslateDialogDefault( hwndDlg ); hwndList = GetDlgItem( hwndDlg, IDC_LIST ); ListView_SetExtendedListViewStyle(hwndList, LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES); GetClientRect( hwndList, &rc ); //rc.right -= GetSystemMetrics( SM_CXVSCROLL ); lvc.mask = LVCF_WIDTH; lvc.cx = rc.right - 20; ListView_InsertColumn( hwndList, 0, &lvc ); lvc.cx = 20; ListView_InsertColumn( hwndList, 1, &lvc ); SendMessage( hwndDlg, WM_JABBER_REFRESH, 0, lParam ); dat = (JABBER_MUC_JIDLIST_INFO*)lParam; static struct { int idc; char *title; char *icon; bool push; } buttons[] = { {IDC_BTN_FILTERAPPLY, "Apply filter", "sd_filter_apply", false}, {IDC_BTN_FILTERRESET, "Reset filter", "sd_filter_reset", false}, }; for (int i = 0; i < SIZEOF(buttons); ++i) { SendDlgItemMessage(hwndDlg, buttons[i].idc, BM_SETIMAGE, IMAGE_ICON, (LPARAM)dat->ppro->LoadIconEx(buttons[i].icon)); SendDlgItemMessage(hwndDlg, buttons[i].idc, BUTTONSETASFLATBTN, 0, 0); SendDlgItemMessage(hwndDlg, buttons[i].idc, BUTTONADDTOOLTIP, (WPARAM)buttons[i].title, 0); if (buttons[i].push) SendDlgItemMessage(hwndDlg, buttons[i].idc, BUTTONSETASPUSHBTN, 0, 0); } Utils_RestoreWindowPosition(hwndDlg, NULL, dat->ppro->m_szModuleName, "jidListWnd_"); } return TRUE; case WM_SIZE: { UTILRESIZEDIALOG urd = {0}; urd.cbSize = sizeof(urd); urd.hInstance = hInst; urd.hwndDlg = hwndDlg; urd.lpTemplate = MAKEINTRESOURCEA(IDD_JIDLIST); urd.pfnResizer = sttJidListResizer; CallService(MS_UTILS_RESIZEDIALOG, 0, (LPARAM)&urd); RECT listrc; LVCOLUMN lvc; HWND hwndList = GetDlgItem( hwndDlg, IDC_LIST ); GetClientRect( hwndList, &listrc ); lvc.mask = LVCF_WIDTH; //listrc.right -= GetSystemMetrics( SM_CXVSCROLL ); lvc.cx = listrc.right - 20; SendMessage(hwndList, LVM_SETCOLUMN, 0, (LPARAM)&lvc); break; } break; case WM_JABBER_REFRESH: { // lParam is ( JABBER_MUC_JIDLIST_INFO * ) HXML iqNode, queryNode; const TCHAR* from; TCHAR title[256]; // Clear current GWL_USERDATA, if any if ( dat != NULL ) delete dat; // Set new GWL_USERDATA dat = ( JABBER_MUC_JIDLIST_INFO * ) lParam; SetWindowLongPtr( hwndDlg, GWLP_USERDATA, ( LONG_PTR ) dat ); // Populate displayed list from iqNode lstrcpyn( title, TranslateT( "JID List" ), SIZEOF( title )); if (( dat=( JABBER_MUC_JIDLIST_INFO * ) lParam ) != NULL ) { if (( iqNode = dat->iqNode ) != NULL ) { if (( from = xmlGetAttrValue( iqNode, _T("from"))) != NULL ) { dat->roomJid = mir_tstrdup( from ); if (( queryNode = xmlGetChild( iqNode , "query" )) != NULL ) { TCHAR* localFrom = mir_tstrdup( from ); mir_sntprintf( title, SIZEOF( title ), TranslateT("%s, %d items (%s)"), ( dat->type == MUC_VOICELIST ) ? TranslateT( "Voice List" ) : ( dat->type == MUC_MEMBERLIST ) ? TranslateT( "Member List" ) : ( dat->type == MUC_MODERATORLIST ) ? TranslateT( "Moderator List" ) : ( dat->type == MUC_BANLIST ) ? TranslateT( "Ban List" ) : ( dat->type == MUC_ADMINLIST ) ? TranslateT( "Admin List" ) : ( dat->type == MUC_OWNERLIST ) ? TranslateT( "Owner List" ) : TranslateT( "JID List" ), xmlGetChildCount(queryNode), localFrom ); mir_free( localFrom ); } } } } SetWindowText( hwndDlg, title ); SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_FILTER), GWLP_USERDATA, 0); sttFillJidList(hwndDlg); } break; case WM_NOTIFY: if (( ( LPNMHDR )lParam )->idFrom == IDC_LIST ) { switch (( ( LPNMHDR )lParam )->code ) { case NM_CUSTOMDRAW: { NMLVCUSTOMDRAW *nm = ( NMLVCUSTOMDRAW * ) lParam; switch ( nm->nmcd.dwDrawStage ) { case CDDS_PREPAINT: case CDDS_ITEMPREPAINT: SetWindowLongPtr( hwndDlg, DWLP_MSGRESULT, CDRF_NOTIFYSUBITEMDRAW ); return TRUE; case CDDS_SUBITEM|CDDS_ITEMPREPAINT: { RECT rc; HICON hIcon; ListView_GetSubItemRect( nm->nmcd.hdr.hwndFrom, nm->nmcd.dwItemSpec, nm->iSubItem, LVIR_LABEL, &rc ); if ( nm->iSubItem == 1 ) { if( nm->nmcd.lItemlParam == ( LPARAM )( -1 )) hIcon = ( HICON )LoadImage( hInst, MAKEINTRESOURCE( IDI_ADDCONTACT ), IMAGE_ICON, GetSystemMetrics( SM_CXSMICON ), GetSystemMetrics( SM_CYSMICON ), 0 ); else hIcon = ( HICON )LoadImage( hInst, MAKEINTRESOURCE( IDI_DELETE ), IMAGE_ICON, GetSystemMetrics( SM_CXSMICON ), GetSystemMetrics( SM_CYSMICON ), 0 ); DrawIconEx( nm->nmcd.hdc, ( rc.left+rc.right-GetSystemMetrics( SM_CXSMICON ))/2, ( rc.top+rc.bottom-GetSystemMetrics( SM_CYSMICON ))/2,hIcon, GetSystemMetrics( SM_CXSMICON ), GetSystemMetrics( SM_CYSMICON ), 0, GetSysColorBrush(COLOR_WINDOW), DI_NORMAL ); DestroyIcon( hIcon ); SetWindowLongPtr( hwndDlg, DWLP_MSGRESULT, CDRF_SKIPDEFAULT ); return TRUE; } } } } break; case NM_CLICK: { NMLISTVIEW *nm = ( NMLISTVIEW * ) lParam; LVITEM lvi; LVHITTESTINFO hti; TCHAR text[128]; if ( nm->iSubItem < 1 ) break; hti.pt.x = ( short ) LOWORD( GetMessagePos()); hti.pt.y = ( short ) HIWORD( GetMessagePos()); ScreenToClient( nm->hdr.hwndFrom, &hti.pt ); if ( ListView_SubItemHitTest( nm->hdr.hwndFrom, &hti ) == -1 ) break; if ( hti.iSubItem != 1 ) break; lvi.mask = LVIF_PARAM | LVIF_TEXT; lvi.iItem = hti.iItem; lvi.iSubItem = 0; lvi.pszText = text; lvi.cchTextMax = sizeof( text ); ListView_GetItem( nm->hdr.hwndFrom, &lvi ); if ( lvi.lParam == ( LPARAM )( -1 )) { TCHAR szBuffer[ 1024 ]; _tcscpy( szBuffer, dat->type2str()); if ( !dat->ppro->EnterString(szBuffer, SIZEOF(szBuffer), NULL, JES_COMBO, "gcAddNick_")) break; // Trim leading and trailing whitespaces TCHAR *p = szBuffer, *q; for ( p = szBuffer; *p!='\0' && isspace( BYTE( *p )); p++); for ( q = p; *q!='\0' && !isspace( BYTE( *q )); q++); if (*q != '\0') *q = '\0'; if (*p == '\0') break; TCHAR rsn[ 1024 ]; _tcscpy( rsn, dat->type2str()); if ( dat->type == MUC_BANLIST ) { dat->ppro->EnterString(rsn, SIZEOF(rsn), TranslateT("Reason to ban") , JES_COMBO, "gcAddReason_"); if ( szBuffer ) dat->ppro->AddMucListItem( dat, p , rsn); else dat->ppro->AddMucListItem( dat, p ); } else dat->ppro->AddMucListItem( dat, p ); } else { //delete TCHAR msgText[128]; mir_sntprintf( msgText, SIZEOF( msgText ), _T("%s %s?"), TranslateT( "Removing" ), text ); if ( MessageBox( hwndDlg, msgText, dat->type2str(), MB_YESNO|MB_SETFOREGROUND ) == IDYES ) { dat->ppro->DeleteMucListItem( dat, ( TCHAR* )lvi.lParam ); mir_free(( void * )lvi.lParam ); ListView_DeleteItem( nm->hdr.hwndFrom, hti.iItem ); } } } break; } break; } break; case WM_COMMAND: if ((LOWORD(wParam) == IDC_BTN_FILTERAPPLY) || ((LOWORD(wParam) == IDOK) && (GetFocus() == GetDlgItem(hwndDlg, IDC_FILTER)))) { SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_FILTER), GWLP_USERDATA, 1); sttFillJidList(hwndDlg); } else if ((LOWORD(wParam) == IDC_BTN_FILTERRESET) || ((LOWORD(wParam) == IDCANCEL) && (GetFocus() == GetDlgItem(hwndDlg, IDC_FILTER)))) { SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_FILTER), GWLP_USERDATA, 0); sttFillJidList(hwndDlg); } break; /* case WM_SETCURSOR: if ( LOWORD( LPARAM )!= HTCLIENT ) break; if ( GetForegroundWindow() == GetParent( hwndDlg )) { POINT pt; GetCursorPos( &pt ); ScreenToClient( hwndDlg,&pt ); SetFocus( ChildWindowFromPoint( hwndDlg,pt )); //ugly hack because listviews ignore their first click } break; */ case WM_CLOSE: { HWND hwndList; int count, i; LVITEM lvi; // Free lParam of the displayed list items hwndList = GetDlgItem( hwndDlg, IDC_LIST ); count = ListView_GetItemCount( hwndList ); lvi.mask = LVIF_PARAM; lvi.iSubItem = 0; for ( i=0; i<count; i++ ) { lvi.iItem = i; if ( ListView_GetItem( hwndList, &lvi ) == TRUE ) { if ( lvi.lParam!=( LPARAM )( -1 ) && lvi.lParam!=( LPARAM )( NULL )) { mir_free(( void * ) lvi.lParam ); } } } ListView_DeleteAllItems( hwndList ); CJabberProto* ppro = dat->ppro; switch ( dat->type ) { case MUC_VOICELIST: ppro->m_hwndMucVoiceList = NULL; break; case MUC_MEMBERLIST: ppro->m_hwndMucMemberList = NULL; break; case MUC_MODERATORLIST: ppro->m_hwndMucModeratorList = NULL; break; case MUC_BANLIST: ppro->m_hwndMucBanList = NULL; break; case MUC_ADMINLIST: ppro->m_hwndMucAdminList = NULL; break; case MUC_OWNERLIST: ppro->m_hwndMucOwnerList = NULL; break; } DestroyWindow( hwndDlg ); } break; case WM_DESTROY: // Clear GWL_USERDATA if ( dat != NULL ) { Utils_SaveWindowPosition(hwndDlg, NULL, dat->ppro->m_szModuleName, "jidListWnd_"); delete dat; } break; } return FALSE; }
static BOOL dialogListPlugins(WIN32_FIND_DATA *fd, TCHAR *path, WPARAM, LPARAM lParam) { TCHAR buf[MAX_PATH]; mir_sntprintf(buf, _T("%s\\Plugins\\%s"), path, fd->cFileName); HINSTANCE hInst = GetModuleHandle(buf); BASIC_PLUGIN_INFO pi; if (checkAPI(buf, &pi, MIRANDA_VERSION_CORE, CHECKAPI_NONE) == 0) return TRUE; PluginListItemData *dat = (PluginListItemData*)mir_alloc(sizeof(PluginListItemData)); dat->hInst = hInst; dat->flags = pi.pluginInfo->flags; dat->stdPlugin = 0; if (pi.Interfaces) { MUUID *piface = pi.Interfaces; for (int i = 0; !equalUUID(miid_last, piface[i]); i++) { int idx = getDefaultPluginIdx(piface[i]); if (idx != -1) { dat->stdPlugin |= (1 << idx); break; } } } CharLower(fd->cFileName); _tcsncpy_s(dat->fileName, fd->cFileName, _TRUNCATE); HWND hwndList = (HWND)lParam; LVITEM it = { 0 }; // column 1: Checkbox + Enable/disabled icons it.mask = LVIF_PARAM | LVIF_IMAGE; it.iImage = (hInst != NULL) ? 2 : 3; bool bNoCheckbox = (dat->flags & STATIC_PLUGIN) != 0; if (bNoCheckbox || hasMuuid(pi, miid_clist) || hasMuuid(pi, miid_protocol)) it.iImage += 2; it.lParam = (LPARAM)dat; int iRow = ListView_InsertItem(hwndList, &it); if (isPluginOnWhiteList(fd->cFileName)) ListView_SetItemState(hwndList, iRow, bNoCheckbox ? 0x3000 : 0x2000, LVIS_STATEIMAGEMASK); if (iRow != -1) { // column 2: Unicode/ANSI icon + filename it.mask = LVIF_IMAGE | LVIF_TEXT; it.iItem = iRow; it.iSubItem = 1; it.iImage = (dat->flags & UNICODE_AWARE) ? 0 : 1; it.pszText = fd->cFileName; ListView_SetItem(hwndList, &it); dat->author = mir_strdup(pi.pluginInfo->author); dat->authorEmail = mir_strdup(pi.pluginInfo->authorEmail); dat->copyright = mir_strdup(pi.pluginInfo->copyright); dat->description = mir_strdup(pi.pluginInfo->description); dat->homepage = mir_strdup(pi.pluginInfo->homepage); if (pi.pluginInfo->cbSize == sizeof(PLUGININFOEX)) dat->uuid = pi.pluginInfo->uuid; else memset(&dat->uuid, 0, sizeof(dat->uuid)); TCHAR *shortNameT = mir_a2t(pi.pluginInfo->shortName); // column 3: plugin short name if (shortNameT) { ListView_SetItemText(hwndList, iRow, 2, shortNameT); mir_free(shortNameT); } // column4: version number DWORD unused, verInfoSize = GetFileVersionInfoSize(buf, &unused); if (verInfoSize != 0) { UINT blockSize; VS_FIXEDFILEINFO *fi; void *pVerInfo = mir_alloc(verInfoSize); GetFileVersionInfo(buf, 0, verInfoSize, pVerInfo); VerQueryValue(pVerInfo, _T("\\"), (LPVOID*)&fi, &blockSize); mir_sntprintf(buf, _T("%d.%d.%d.%d"), HIWORD(fi->dwProductVersionMS), LOWORD(fi->dwProductVersionMS), HIWORD(fi->dwProductVersionLS), LOWORD(fi->dwProductVersionLS)); mir_free(pVerInfo); } else mir_sntprintf(buf, _T("%d.%d.%d.%d"), HIBYTE(HIWORD(pi.pluginInfo->version)), LOBYTE(HIWORD(pi.pluginInfo->version)), HIBYTE(LOWORD(pi.pluginInfo->version)), LOBYTE(LOWORD(pi.pluginInfo->version))); ListView_SetItemText(hwndList, iRow, 3, buf); arPluginList.insert(dat); } else mir_free(dat); FreeLibrary(pi.hInst); return TRUE; }
void JabberByteSendConnection( HANDLE hConn, DWORD /*dwRemoteIP*/, void* extra ) { CJabberProto* ppro = ( CJabberProto* )extra; SOCKET s; SOCKADDR_IN saddr; int len; WORD localPort; TCHAR szPort[8]; JABBER_BYTE_TRANSFER *jbt; int recvResult, bytesParsed; HANDLE hListen; JABBER_LIST_ITEM *item; char* buffer; int datalen; localPort = 0; if (( s = JCallService( MS_NETLIB_GETSOCKET, ( WPARAM ) hConn, 0 )) != INVALID_SOCKET ) { len = sizeof( saddr ); if ( getsockname( s, ( SOCKADDR * ) &saddr, &len ) != SOCKET_ERROR ) localPort = ntohs( saddr.sin_port ); } if ( localPort == 0 ) { ppro->Log( "bytestream_send_connection unable to determine the local port, connection closed." ); Netlib_CloseHandle( hConn ); return; } mir_sntprintf( szPort, SIZEOF( szPort ), _T("%d"), localPort ); ppro->Log( "bytestream_send_connection incoming connection accepted: local_port=" TCHAR_STR_PARAM, szPort ); if (( item = ppro->ListGetItemPtr( LIST_BYTE, szPort )) == NULL ) { ppro->Log( "No bytestream session is currently active, connection closed." ); Netlib_CloseHandle( hConn ); return; } jbt = item->jbt; if (( buffer = ( char* )mir_alloc( JABBER_NETWORK_BUFFER_SIZE )) == NULL ) { ppro->Log( "bytestream_send cannot allocate network buffer, connection closed." ); jbt->state = JBT_ERROR; Netlib_CloseHandle( hConn ); if ( jbt->hEvent != NULL ) SetEvent( jbt->hEvent ); return; } hListen = jbt->hConn; jbt->hConn = hConn; jbt->state = JBT_INIT; datalen = 0; while ( jbt->state!=JBT_DONE && jbt->state!=JBT_ERROR ) { recvResult = Netlib_Recv( hConn, buffer+datalen, JABBER_NETWORK_BUFFER_SIZE-datalen, 0 ); if ( recvResult <= 0 ) break; datalen += recvResult; bytesParsed = ppro->ByteSendParse( hConn, jbt, buffer, datalen ); if ( bytesParsed < datalen ) memmove( buffer, buffer+bytesParsed, datalen-bytesParsed ); datalen -= bytesParsed; } if ( jbt->hConn ) Netlib_CloseHandle( jbt->hConn ); ppro->Log( "bytestream_send_connection closing connection" ); jbt->hConn = hListen; mir_free( buffer ); if ( jbt->hEvent != NULL ) SetEvent( jbt->hEvent ); }
/* * add a contact to recent or favorites menu * mode = 1, add * mode = 0, only modify it.. * hMenu specifies the menu handle (the menus are identical...) * cares about updating the menu entry. It sets the hIcon (proto status icon) in * dwItemData of the the menu entry, so that the WM_DRAWITEM handler can retrieve it * w/o costly service calls. * * Also, the function does housekeeping on the Recent Sessions menu to enforce the * maximum number of allowed entries (20 at the moment). The oldest (topmost) entry * is deleted, if necessary. */ void TSAPI AddContactToFavorites(MCONTACT hContact, const TCHAR *szNickname, const char *szProto, TCHAR *szStatus, WORD wStatus, HICON hIcon, BOOL mode, HMENU hMenu) { TCHAR szMenuEntry[80]; TCHAR szFinalNick[100]; if (szNickname == NULL) _tcsncpy_s(szFinalNick, pcli->pfnGetContactDisplayName(hContact, 0), _TRUNCATE); else _tcsncpy_s(szFinalNick, szNickname, _TRUNCATE); if (szProto == NULL) szProto = GetContactProto(hContact); if (szProto) { if (wStatus == 0) wStatus = db_get_w(hContact, szProto, "Status", ID_STATUS_OFFLINE); if (szStatus == NULL) szStatus = pcli->pfnGetStatusModeDescription(wStatus, 0); } else return; if (hIcon == 0) hIcon = Skin_LoadProtoIcon(szProto, wStatus); PROTOACCOUNT *acc = Proto_GetAccount(szProto); if (acc && acc->tszAccountName) { MENUITEMINFO mii = { 0 }; mii.cbSize = sizeof(mii); mir_sntprintf(szMenuEntry, _T("%s: %s (%s)"), acc->tszAccountName, szFinalNick, szStatus); if (mode) { if (hMenu == PluginConfig.g_hMenuRecent) { if (CheckMenuItem(hMenu, (UINT_PTR)hContact, MF_BYCOMMAND | MF_UNCHECKED) == 0) { DeleteMenu(hMenu, (UINT_PTR)hContact, MF_BYCOMMAND); goto addnew; // move to the end of the menu... } if (GetMenuItemCount(PluginConfig.g_hMenuRecent) > nen_options.wMaxRecent) { // throw out oldest entry in the recent menu... UINT uid = GetMenuItemID(hMenu, 0); if (uid) { DeleteMenu(hMenu, (UINT_PTR)0, MF_BYPOSITION); db_set_dw((MCONTACT)uid, SRMSGMOD_T, "isRecent", 0); } } addnew: db_set_dw(hContact, SRMSGMOD_T, "isRecent", time(NULL)); AppendMenu(hMenu, MF_BYCOMMAND, (UINT_PTR)hContact, szMenuEntry); } else if (hMenu == PluginConfig.g_hMenuFavorites) { // insert the item sorted... TCHAR szBuffer[142]; int i, c = GetMenuItemCount(PluginConfig.g_hMenuFavorites); MENUITEMINFO mii2 = { 0 }; mii2.fMask = MIIM_STRING; mii2.cbSize = sizeof(mii2); if (c == 0) InsertMenu(PluginConfig.g_hMenuFavorites, 0, MF_BYPOSITION, (UINT_PTR)hContact, szMenuEntry); else { for (i = 0; i <= c; i++) { mii2.cch = 0; mii2.dwTypeData = NULL; GetMenuItemInfo(PluginConfig.g_hMenuFavorites, i, TRUE, &mii2); mii2.cch++; mii2.dwTypeData = szBuffer; GetMenuItemInfo(PluginConfig.g_hMenuFavorites, i, TRUE, &mii2); if (_tcsncmp((TCHAR*)mii2.dwTypeData, szMenuEntry, 140) > 0 || i == c) { InsertMenu(PluginConfig.g_hMenuFavorites, i, MF_BYPOSITION, (UINT_PTR)hContact, szMenuEntry); break; } } } } } mii.fMask = MIIM_BITMAP | MIIM_DATA; if (!mode) { mii.fMask |= MIIM_STRING; mii.dwTypeData = (LPTSTR)szMenuEntry; mii.cch = (int)mir_tstrlen(szMenuEntry) + 1; } mii.hbmpItem = HBMMENU_CALLBACK; mii.dwItemData = (ULONG_PTR)hIcon; SetMenuItemInfo(hMenu, (UINT)hContact, FALSE, &mii); } }
INT_PTR CALLBACK DlgSkinOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_DESTROY: if (hPreviewBitmap) ske_UnloadGlyphImage(hPreviewBitmap); break; case WM_INITDIALOG: TranslateDialogDefault(hwndDlg); SetDlgItemText(hwndDlg, IDC_SKINFOLDERLABEL, SkinsFolder); { HTREEITEM it = FillAvailableSkinList(hwndDlg); HWND wnd = GetDlgItem(hwndDlg, IDC_TREE1); TreeView_SelectItem(wnd, it); } return 0; case WM_COMMAND: switch (LOWORD(wParam)) { case IDC_COLOUR_MENUNORMAL: case IDC_COLOUR_MENUSELECTED: case IDC_COLOUR_FRAMES: case IDC_COLOUR_STATUSBAR: SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); break; case IDC_BUTTON_INFO: { TCHAR Author[255], URL[MAX_PATH], Contact[255], Description[400], text[2000]; SkinListData *sd = NULL; HTREEITEM hti = TreeView_GetSelection(GetDlgItem(hwndDlg, IDC_TREE1)); if (hti == 0) return 0; { TVITEM tvi = { 0 }; tvi.hItem = hti; tvi.mask = TVIF_HANDLE | TVIF_PARAM; TreeView_GetItem(GetDlgItem(hwndDlg, IDC_TREE1), &tvi); sd = (SkinListData*)(tvi.lParam); } if (!sd) return 0; if (sd->File && !_tcschr(sd->File, _T('%'))) { GetPrivateProfileString(_T("Skin_Description_Section"), _T("Author"), TranslateT("( unknown )"), Author, _countof(Author), sd->File); GetPrivateProfileString(_T("Skin_Description_Section"), _T("URL"), _T(""), URL, _countof(URL), sd->File); GetPrivateProfileString(_T("Skin_Description_Section"), _T("Contact"), _T(""), Contact, _countof(Contact), sd->File); GetPrivateProfileString(_T("Skin_Description_Section"), _T("Description"), _T(""), Description, _countof(Description), sd->File); mir_sntprintf(text, TranslateT("%s\n\n%s\n\nAuthor(s):\t %s\nContact:\t %s\nWeb:\t %s\n\nFile:\t %s"), sd->Name, Description, Author, Contact, URL, sd->File); } else { mir_sntprintf(text, TranslateT("%s\n\n%s\n\nAuthor(s): %s\nContact:\t %s\nWeb:\t %s\n\nFile:\t %s"), TranslateT("reVista for Modern v0.5"), TranslateT("This is second default Modern Contact list skin in Vista Aero style"), TranslateT("Angeli-Ka (graphics), FYR (template)"), _T("JID: [email protected]"), _T("fyr.mirandaim.ru"), TranslateT("Inside library")); } MessageBox(hwndDlg, text, TranslateT("Skin information"), MB_OK | MB_ICONINFORMATION); } break; case IDC_BUTTON_APPLY_SKIN: if (HIWORD(wParam) == BN_CLICKED) { SkinListData *sd = NULL; HTREEITEM hti = TreeView_GetSelection(GetDlgItem(hwndDlg, IDC_TREE1)); if (hti == 0) return 0; { TVITEM tvi = { 0 }; tvi.hItem = hti; tvi.mask = TVIF_HANDLE | TVIF_PARAM; TreeView_GetItem(GetDlgItem(hwndDlg, IDC_TREE1), &tvi); sd = (SkinListData*)(tvi.lParam); } if (!sd) return 0; ske_LoadSkinFromIniFile(sd->File, FALSE); ske_LoadSkinFromDB(); pcli->pfnClcBroadcast(INTM_RELOADOPTIONS, 0, 0); Sync(CLUIFrames_OnClistResize_mod, 0, 0); ske_RedrawCompleteWindow(); Sync(CLUIFrames_OnClistResize_mod, 0, 0); { HWND hwnd = pcli->hwndContactList; RECT rc = { 0 }; GetWindowRect(hwnd, &rc); Sync(CLUIFrames_OnMoving, hwnd, &rc); } if (g_hCLUIOptionsWnd) { SendDlgItemMessage(g_hCLUIOptionsWnd, IDC_LEFTMARGINSPIN, UDM_SETPOS, 0, db_get_b(NULL, "CLUI", "LeftClientMargin", SETTING_LEFTCLIENTMARIGN_DEFAULT)); SendDlgItemMessage(g_hCLUIOptionsWnd, IDC_RIGHTMARGINSPIN, UDM_SETPOS, 0, db_get_b(NULL, "CLUI", "RightClientMargin", SETTING_RIGHTCLIENTMARIGN_DEFAULT)); SendDlgItemMessage(g_hCLUIOptionsWnd, IDC_TOPMARGINSPIN, UDM_SETPOS, 0, db_get_b(NULL, "CLUI", "TopClientMargin", SETTING_TOPCLIENTMARIGN_DEFAULT)); SendDlgItemMessage(g_hCLUIOptionsWnd, IDC_BOTTOMMARGINSPIN, UDM_SETPOS, 0, db_get_b(NULL, "CLUI", "BottomClientMargin", SETTING_BOTTOMCLIENTMARIGN_DEFAULT)); } } break; case IDC_BUTTON_RESCAN: if (HIWORD(wParam) == BN_CLICKED) { HTREEITEM it = FillAvailableSkinList(hwndDlg); HWND wnd = GetDlgItem(hwndDlg, IDC_TREE1); TreeView_SelectItem(wnd, it); } } break; case WM_DRAWITEM: if (wParam == IDC_PREVIEW) { //TODO:Draw hPreviewBitmap here int mWidth, mHeight; HBRUSH hbr = CreateSolidBrush(GetSysColor(COLOR_3DFACE)); DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)lParam; mWidth = dis->rcItem.right - dis->rcItem.left; mHeight = dis->rcItem.bottom - dis->rcItem.top; HDC memDC = CreateCompatibleDC(dis->hDC); HBITMAP hbmp = ske_CreateDIB32(mWidth, mHeight); HBITMAP holdbmp = (HBITMAP)SelectObject(memDC, hbmp); RECT workRect = dis->rcItem; OffsetRect(&workRect, -workRect.left, -workRect.top); FillRect(memDC, &workRect, hbr); DeleteObject(hbr); if (hPreviewBitmap) { //variables BITMAP bmp = { 0 }; POINT imgPos = { 0 }; float xScale = 1, yScale = 1; //GetSize GetObject(hPreviewBitmap, sizeof(BITMAP), &bmp); int wWidth = workRect.right - workRect.left; int wHeight = workRect.bottom - workRect.top; if (wWidth < bmp.bmWidth) xScale = (float)wWidth / bmp.bmWidth; if (wHeight < bmp.bmHeight) yScale = (float)wHeight / bmp.bmHeight; xScale = min(xScale, yScale); yScale = xScale; int dWidth = (int)(xScale*bmp.bmWidth); int dHeight = (int)(yScale*bmp.bmHeight); //CalcPosition imgPos.x = workRect.left + ((wWidth - dWidth) >> 1); imgPos.y = workRect.top + ((wHeight - dHeight) >> 1); //DrawImage DrawAvatarImageWithGDIp(memDC, imgPos.x, imgPos.y, dWidth, dHeight, hPreviewBitmap, 0, 0, bmp.bmWidth, bmp.bmHeight, 8, 255); } BitBlt(dis->hDC, dis->rcItem.left, dis->rcItem.top, mWidth, mHeight, memDC, 0, 0, SRCCOPY); SelectObject(memDC, holdbmp); DeleteObject(hbmp); DeleteDC(memDC); } break; case WM_NOTIFY: switch (((LPNMHDR)lParam)->idFrom) { case IDC_TREE1: { NMTREEVIEW * nmtv = (NMTREEVIEW *)lParam; if (nmtv == NULL) return 0; if (nmtv->hdr.code == TVN_SELCHANGED) { SkinListData * sd = NULL; if (hPreviewBitmap) { ske_UnloadGlyphImage(hPreviewBitmap); hPreviewBitmap = NULL; } if (nmtv->itemNew.lParam) { sd = (SkinListData*)nmtv->itemNew.lParam; TCHAR buf[MAX_PATH]; PathToRelativeT(sd->File, buf); SetDlgItemText(hwndDlg, IDC_EDIT_SKIN_FILENAME, buf); TCHAR prfn[MAX_PATH] = { 0 }, imfn[MAX_PATH] = { 0 }, skinfolder[MAX_PATH] = { 0 }; GetPrivateProfileString(_T("Skin_Description_Section"), _T("Preview"), _T(""), imfn, _countof(imfn), sd->File); IniParser::GetSkinFolder(sd->File, skinfolder); mir_sntprintf(prfn, _T("%s\\%s"), skinfolder, imfn); PathToAbsoluteT(prfn, imfn); hPreviewBitmap = ske_LoadGlyphImage(imfn); EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_APPLY_SKIN), TRUE); EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_INFO), TRUE); if (hPreviewBitmap) InvalidateRect(GetDlgItem(hwndDlg, IDC_PREVIEW), NULL, TRUE); else { //prepare text TCHAR Author[255], URL[MAX_PATH], Contact[255], Description[400], text[2000]; SkinListData* sd2 = NULL; HTREEITEM hti = TreeView_GetSelection(GetDlgItem(hwndDlg, IDC_TREE1)); if (hti == 0) return 0; { TVITEM tvi = { 0 }; tvi.hItem = hti; tvi.mask = TVIF_HANDLE | TVIF_PARAM; TreeView_GetItem(GetDlgItem(hwndDlg, IDC_TREE1), &tvi); sd2 = (SkinListData*)(tvi.lParam); } if (!sd2) return 0; if (sd2->File && !_tcschr(sd2->File, _T('%'))) { GetPrivateProfileString(_T("Skin_Description_Section"), _T("Author"), TranslateT("( unknown )"), Author, _countof(Author), sd2->File); GetPrivateProfileString(_T("Skin_Description_Section"), _T("URL"), _T(""), URL, _countof(URL), sd2->File); GetPrivateProfileString(_T("Skin_Description_Section"), _T("Contact"), _T(""), Contact, _countof(Contact), sd2->File); GetPrivateProfileString(_T("Skin_Description_Section"), _T("Description"), _T(""), Description, _countof(Description), sd2->File); mir_sntprintf(text, TranslateT("Preview is not available\n\n%s\n----------------------\n\n%s\n\nAUTHOR(S):\n%s\n\nCONTACT:\n%s\n\nHOMEPAGE:\n%s"), sd2->Name, Description, Author, Contact, URL); } else { mir_sntprintf(text, TranslateT("%s\n\n%s\n\nAUTHORS:\n%s\n\nCONTACT:\n%s\n\nWEB:\n%s\n\n\n"), TranslateT("reVista for Modern v0.5"), TranslateT("This is second default Modern Contact list skin in Vista Aero style"), TranslateT("graphics by Angeli-Ka\ntemplate by FYR"), _T("JID: [email protected]"), _T("fyr.mirandaim.ru")); } ShowWindow(GetDlgItem(hwndDlg, IDC_PREVIEW), SW_HIDE); ShowWindow(GetDlgItem(hwndDlg, IDC_STATIC_INFO), SW_SHOW); SetDlgItemText(hwndDlg, IDC_STATIC_INFO, text); } } else { //no selected SetDlgItemText(hwndDlg, IDC_EDIT_SKIN_FILENAME, TranslateT("Select skin from list")); EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_APPLY_SKIN), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_INFO), FALSE); SetDlgItemText(hwndDlg, IDC_STATIC_INFO, TranslateT("Please select skin to apply")); ShowWindow(GetDlgItem(hwndDlg, IDC_PREVIEW), SW_HIDE); } ShowWindow(GetDlgItem(hwndDlg, IDC_PREVIEW), hPreviewBitmap ? SW_SHOW : SW_HIDE); return 0; } else if (nmtv->hdr.code == TVN_DELETEITEM) { mir_free_and_nil(nmtv->itemOld.lParam); return 0; } } break; case 0: switch (((LPNMHDR)lParam)->code) { case PSN_APPLY: pcli->pfnClcBroadcast(INTM_RELOADOPTIONS, 0, 0); NotifyEventHooks(g_CluiData.hEventBkgrChanged, 0, 0); pcli->pfnClcBroadcast(INTM_INVALIDATE, 0, 0); RedrawWindow(GetParent(pcli->hwndContactTree), NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN); } break; } }
void ErrorMSG(int minValue, int maxValue) { TCHAR str[128]; mir_sntprintf(str, SIZEOF(str), TranslateT("You cannot specify a value lower than %d and higher than %d."), minValue, maxValue); MSGERROR(str); }
void InitMenu() { CLISTMENUITEM menu = {0}; menu.cbSize=sizeof(menu); menu.flags = CMIM_ALL | CMIF_TCHAR | CMIF_ICONFROMICOLIB; // main menu item hServiceMenuOnOff = CreateServiceFunction(MODULE "/MenuOnOff", ServiceMenuOnOff); menu.ptszName = MetaEnabled() ? _T("Disable MetaContacts") : _T("Enable MetaContacts"); menu.pszService = MODULE "/MenuOnOff"; menu.icolibItem = GetIcolibHandle(MetaEnabled() ? I_MENUOFF : I_MENU); hMenuOnOff = (HANDLE)CallService(MS_CLIST_ADDMAINMENUITEM,0,(LPARAM)&menu); // normal and subcontact menu items hServiceMenuConvert = CreateServiceFunction(MODULE "/ContactMenuConvert", ContactMenuConvert); menu.ptszName = _T("Convert to MetaContact"); menu.pszService = MODULE "/ContactMenuConvert"; menu.icolibItem = GetIcolibHandle(I_CONVERT); hMenuConvert = (HANDLE)CallService(MS_CLIST_ADDCONTACTMENUITEM,0,(LPARAM)&menu); hServiceMenuAdd = CreateServiceFunction(MODULE "/ContactMenuAdd", ContactMenuAdd); menu.ptszName = _T("Add to existing MetaContact..."); menu.pszService = MODULE "/ContactMenuAdd"; menu.icolibItem = GetIcolibHandle(I_ADD); hMenuAdd = (HANDLE)CallService(MS_CLIST_ADDCONTACTMENUITEM,0,(LPARAM)&menu); hServiceMenuRemove = CreateServiceFunction(MODULE "/ContactMenuRemove", ContactMenuRemove); menu.ptszName = _T("Remove from MetaContact"); menu.pszService = MODULE "/ContactMenuRemove"; menu.icolibItem = GetIcolibHandle(I_REMOVE); hMenuRemove = (HANDLE)CallService(MS_CLIST_ADDCONTACTMENUITEM,0,(LPARAM)&menu); hServiceMenuDefault = CreateServiceFunction(MODULE "/ContactMenuDefault", ContactMenuDefault); menu.ptszName = _T("Set as MetaContact default"); menu.pszService = MODULE "/ContactMenuDefault"; menu.icolibItem = GetIcolibHandle(I_SETDEFAULT); hMenuDefault = (HANDLE)CallService(MS_CLIST_ADDCONTACTMENUITEM,0,(LPARAM)&menu); // hidden contact menu items...ho hum hServiceContactMenu = CreateServiceFunction("MetaContacts/MenuFunc",Meta_ContactMenuFunc); menu.flags = CMIM_ALL | CMIF_TCHAR | CMIF_HIDDEN; menu.pszContactOwner = MODULE; menu.hIcon = 0; menu.position = -99000; menu.hIcon = 0; TCHAR buff[256]; menu.ptszName = buff; for(int i = 0; i < MAX_SUBCONTACTS; i++) { menu.position--; menu.popupPosition = i; mir_sntprintf(buff, 256, _T("Context%d"), i); menu.pszService= "MetaContacts/MenuFunc"; hMenuContact[i] = (HANDLE)CallService(MS_CLIST_ADDCONTACTMENUITEM,0,(LPARAM)&menu); } // metacontact items menu.flags = CMIM_ALL | CMIF_TCHAR | CMIF_ICONFROMICOLIB; hServiceMenuEdit = CreateServiceFunction(MODULE "/ContactMenuEdit", ContactMenuEdit); menu.ptszName = _T("Edit MetaContact"); menu.pszService = MODULE "/ContactMenuEdit"; menu.icolibItem = GetIcolibHandle(I_EDIT); menu.pszContactOwner = MODULE; hMenuEdit = (HANDLE)CallService(MS_CLIST_ADDCONTACTMENUITEM,0,(LPARAM)&menu); hEventMenuBuild = HookEvent(ME_CLIST_PREBUILDCONTACTMENU, PrebuildContactMenu); // for toptoolbar buttons (backward compatible) hServiceToggle = CreateServiceFunction("MetaContacts/OnOff", ServiceMenuOnOff); }
void __cdecl FindSettings(LPVOID param) { FindInfo* fi = (FindInfo*)param; HWND hwndParent = GetParent(fi->hwnd); ModuleSettingLL ModuleList, SettingList; ModSetLinkLinkItem *module, *setting; MCONTACT hContact; DBVARIANT dbv = { 0 }; int foundCount = 0, replaceCount = 0, deleteCount = 0; DWORD numsearch = 0, numreplace = 0; int NULLContactDone = 0; if (!fi->search || !EnumModules(&ModuleList)) { fi_free(fi); return; } _T2A search(fi->search); _T2A replace(fi->replace); // skip modules and setting names on unicode search or replace if (IsRealUnicode(fi->search) || IsRealUnicode(fi->replace)) { fi->options &= ~(F_SETNAME | F_MODNAME); fi->options |= F_UNICODE; } if (!(fi->options & F_UNICODE) && (fi->options & F_SETVAL)) { char val[16]; numsearch = strtoul(search, NULL, 10); _ultoa(numsearch, val, 10); if (!mir_strcmp(search, val)) { fi->options |= F_NUMSRCH; // replace numeric values only entirely if (replace && (fi->options & F_ENTIRE)) { numreplace = strtoul(replace, NULL, 10); _ultoa(numreplace, val, 10); if (!replace[0] || !mir_strcmp(replace, val)) fi->options |= F_NUMREPL; } } } SendDlgItemMessage(hwndParent, IDC_SBAR, SB_SETTEXT, 0, (LPARAM)TranslateT("Searching...")); hContact = 0; while (GetWindowLongPtr(GetDlgItem(hwndParent, IDC_SEARCH), GWLP_USERDATA)) { if (!hContact) { if (NULLContactDone) break; else { NULLContactDone = 1; hContact = db_find_first(); } } else hContact = db_find_next(hContact); for (module = ModuleList.first; module; module = module->next) { if (IsModuleEmpty(hContact, module->name)) continue; if (fi->options & (F_SETVAL | F_SETNAME)) { if (!EnumSettings(hContact, module->name, &SettingList)) { fi_free(fi); FreeModuleSettingLL(&ModuleList); return; } for (setting = SettingList.first; setting; setting = setting->next) { dbv.type = 0; if (db_get_s(hContact, module->name, setting->name, &dbv, 0)) continue; // check in settings value if (fi->options & F_SETVAL) { TCHAR *value = NULL; switch(dbv.type) { case DBVT_BYTE: case DBVT_WORD: case DBVT_DWORD: if ((fi->options & F_NUMSRCH) && numsearch == getNumericValue(&dbv)) { TCHAR *val = fi->search; int flag = F_SETVAL; if (fi->options & F_NUMREPL) { if (replace[0]) { db_unset(hContact, module->name, setting->name); flag |= F_DELETED; deleteCount++; } else if (setNumericValue(hContact, module->name, setting->name, numreplace, dbv.type)) { val = fi->replace; flag |= F_REPLACED; replaceCount++; } } ItemFound(fi->hwnd, hContact, module->name, setting->name, val, flag); } break; case DBVT_WCHAR: if (!value) value = mir_u2t(dbv.pwszVal); case DBVT_UTF8: if (!value) value = mir_utf8decodeT(dbv.pszVal); case DBVT_ASCIIZ: if (!value) value = mir_a2t(dbv.pszVal); if (FindMatchT(value, fi->search, fi->options)) { foundCount++; ptrT ptr; TCHAR *newValue = value; int flag = F_SETVAL; if (fi->replace) { newValue = (fi->options & F_ENTIRE) ? fi->replace : ptr = multiReplaceT(value, fi->search, fi->replace, fi->options & F_CASE); // !!!! delete or make empty ? if (!newValue[0]) { db_unset(hContact, module->name, setting->name); flag |= F_DELETED; newValue = value; deleteCount++; } else { #ifdef _UNICODE // save as unicode if needed if (dbv.type != DBVT_ASCIIZ || IsRealUnicode(newValue)) db_set_ws(hContact, module->name, setting->name, newValue); else #endif db_set_s(hContact, module->name, setting->name, _T2A(newValue)); flag |= F_REPLACED; replaceCount++; } } ItemFound(fi->hwnd, hContact, module->name, setting->name, newValue, flag); } mir_free(value); break; } // switch } // check in setting name if ((fi->options & F_SETNAME) && FindMatchA(setting->name, search, fi->options)) { foundCount++; ptrA ptr; char *newSetting = setting->name; int flag = F_SETNAME; if (replace) { newSetting = (fi->options & F_ENTIRE) ? replace : ptr = multiReplaceA(setting->name, search, replace, fi->options & F_CASE); if (!newSetting[0]) { db_unset(hContact, module->name, setting->name); flag |= F_DELETED; newSetting = setting->name; deleteCount++; } else { DBVARIANT dbv2; // skip if exist if (!db_get_s(hContact, module->name, newSetting, &dbv2, 0)) db_free(&dbv2); else if (!db_set(hContact, module->name, newSetting, &dbv)) { db_unset(hContact, module->name, setting->name); flag |= F_REPLACED; replaceCount++; } } } ItemFound(fi->hwnd, hContact, module->name, newSetting, NULL, flag); } db_free(&dbv); } // for(setting) FreeModuleSettingLL(&SettingList); } // check in module name if ((fi->options & F_MODNAME) && FindMatchA(module->name, search, fi->options)) { foundCount++; char *newModule = module->name; int flag = F_MODNAME; ptrA ptr; if (replace) { newModule = (fi->options & F_ENTIRE) ? replace : ptr = multiReplaceA(module->name, search, replace, fi->options & F_CASE); if (!newModule[0]) { deleteModule(hContact, module->name, 0); replaceTreeItem(hContact, module->name, NULL); flag |= F_DELETED; newModule = module->name; deleteCount++; } else if (renameModule(hContact, module->name, newModule)) { replaceTreeItem(hContact, module->name, NULL); flag |= F_REPLACED; replaceCount++; } } ItemFound(fi->hwnd, hContact, newModule, 0, 0, flag); } } // for(module) } TCHAR msg[MSG_SIZE]; mir_sntprintf(msg, TranslateT("Finished. Items found: %d / replaced: %d / deleted: %d"), foundCount, replaceCount, deleteCount); SendDlgItemMessage(hwndParent, IDC_SBAR, SB_SETTEXT, 0, (LPARAM)msg); if (fi->replace) { EnableWindow(GetDlgItem(hwndParent, IDC_SEARCH), 1); SetDlgItemText(hwndParent, IDOK, TranslateT("&Replace")); } else { SetDlgItemText(hwndParent, IDC_SEARCH, TranslateT("&Search")); EnableWindow(GetDlgItem(hwndParent, IDOK), 1); } fi_free(fi); FreeModuleSettingLL(&ModuleList); SetWindowLongPtr(GetDlgItem(hwndParent, IDC_SEARCH), GWLP_USERDATA, 0); EnableWindow(GetDlgItem(hwndParent, IDCANCEL), 1); }
int PrebuildContactMenu(WPARAM wParam, LPARAM lParam) { HANDLE hContact = (HANDLE)wParam; CLISTMENUITEM mi = {0}; mi.cbSize = sizeof(CLISTMENUITEM); if(MetaEnabled()) { if(IsSubcontact(hContact)) { mi.flags = CMIM_FLAGS | CMIF_HIDDEN; CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuAdd, (LPARAM)&mi); CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuConvert, (LPARAM)&mi); mi.flags = CMIM_FLAGS; CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuDefault, (LPARAM)&mi); CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuRemove, (LPARAM)&mi); } else if(IsMetacontact(hContact)) { GetCursorPos(&menuMousePoint); mi.flags = CMIM_FLAGS | CMIF_HIDDEN; CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuAdd, (LPARAM)&mi); CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuConvert, (LPARAM)&mi); CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuDefault, (LPARAM)&mi); CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuRemove, (LPARAM)&mi); if(!metaMap.exists(hContact)) { PUShowMessage("No such meta!", SM_WARNING); return 0; } // show subcontact menu items mi.flags = CMIM_FLAGS | CMIM_NAME | CMIM_ICON | CMIF_TCHAR; HIMAGELIST il = (HIMAGELIST)CallService(MS_CLIST_GETICONSIMAGELIST, 0, 0); SubcontactList::Iterator i = metaMap[hContact].start(); int count = 0; TCHAR buff[31]; while(i.has_val()) { // limit names to 30 chars mir_sntprintf(buff, 31, _T("%s"), ContactName(i.val().handle())); mi.ptszName = buff; mi.hIcon = ImageList_GetIcon(il, (int)CallService(MS_CLIST_GETCONTACTICON, (WPARAM)i.val().handle(), 0), 0); CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuContact[count], (LPARAM)&mi); i.next(); count++; } mi.flags = CMIM_FLAGS | CMIF_HIDDEN; for(;count < MAX_SUBCONTACTS; count++) CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuContact[count], (LPARAM)&mi); // show hide nudge menu item // wParam = char *szProto // lParam = BOOL show #define MS_NUDGE_SHOWMENU "NudgeShowMenu" { char serviceFunc[256]; hContact = Meta_GetActive((HANDLE)wParam); mir_snprintf(serviceFunc, 256, "%s/SendNudge", ContactProto(hContact)); CallService(MS_NUDGE_SHOWMENU, (WPARAM)MODULE, (LPARAM)ServiceExists(serviceFunc)); } } else { mi.flags = CMIM_FLAGS; if(metaMap.size()) CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuAdd, (LPARAM)&mi); CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuConvert, (LPARAM)&mi); mi.flags = CMIM_FLAGS | CMIF_HIDDEN; if(!metaMap.size()) CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuAdd, (LPARAM)&mi); CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuRemove, (LPARAM)&mi); CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuDefault, (LPARAM)&mi); } } else { mi.flags = CMIM_FLAGS | CMIF_HIDDEN; CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuAdd, (LPARAM)&mi); CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuConvert, (LPARAM)&mi); CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuDefault, (LPARAM)&mi); CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuRemove, (LPARAM)&mi); } return 0; }
HANDLE FacebookProto::SearchByName(const PROTOCHAR* nick, const PROTOCHAR* firstName, const PROTOCHAR* lastName) { TCHAR arg[200]; mir_sntprintf (arg, SIZEOF(arg), _T("%s %s %s"), nick, firstName, lastName); return SearchByEmail(arg); // Facebook is using one search method for everything (except IDs) }
TCHAR* ParseString(TCHAR *szstring, MCONTACT hcontact) { #define MAXSIZE 1024 static TCHAR sztemp[MAXSIZE + 1]; TCHAR szdbsetting[128]; TCHAR *charPtr; int isetting = 0; DWORD dwsetting = 0; struct in_addr ia; DBVARIANT dbv; sztemp[0] = '\0'; SYSTEMTIME st; if (!isSeen(hcontact, &st)) { mir_tstrcat(sztemp, TranslateT("<never seen>")); return sztemp; } CONTACTINFO ci = { sizeof(CONTACTINFO) }; ci.hContact = hcontact; ci.szProto = hcontact ? GetContactProto(hcontact) : courProtoName; TCHAR *d = sztemp; for (TCHAR *p = szstring; *p; p++) { if (d >= sztemp + MAXSIZE) break; if (*p != '%' && *p != '#') { *d++ = *p; continue; } bool wantempty = *p == '#'; switch (*++p) { case 'Y': if (!st.wYear) goto LBL_noData; d += _stprintf(d, _T("%04i"), st.wYear); //!!!!!!!!!!!! break; case 'y': if (!st.wYear) goto LBL_noData; d += _stprintf(d, _T("%02i"), st.wYear % 100); //!!!!!!!!!!!! break; case 'm': if (!(isetting = st.wMonth)) goto LBL_noData; LBL_2DigNum: d += _stprintf(d, _T("%02i"), isetting); //!!!!!!!!!!!! break; case 'd': if (isetting = st.wDay) goto LBL_2DigNum; else goto LBL_noData; case 'W': isetting = st.wDayOfWeek; if (isetting == -1) { LBL_noData: charPtr = wantempty ? _T("") : TranslateT("<unknown>"); goto LBL_charPtr; } charPtr = TranslateTS(weekdays[isetting]); LBL_charPtr: d += mir_sntprintf(d, MAXSIZE - (d - sztemp), _T("%s"), charPtr); break; case 'w': isetting = st.wDayOfWeek; if (isetting == -1) goto LBL_noData; charPtr = TranslateTS(wdays_short[isetting]); goto LBL_charPtr; case 'E': if (!(isetting = st.wMonth)) goto LBL_noData; charPtr = TranslateTS(monthnames[isetting - 1]); goto LBL_charPtr; case 'e': if (!(isetting = st.wMonth)) goto LBL_noData; charPtr = TranslateTS(mnames_short[isetting - 1]); goto LBL_charPtr; case 'H': if ((isetting = st.wHour) == -1) goto LBL_noData; goto LBL_2DigNum; case 'h': if ((isetting = st.wHour) == -1) goto LBL_noData; if (!isetting) isetting = 12; isetting = isetting - ((isetting > 12) ? 12 : 0); goto LBL_2DigNum; case 'p': if ((isetting = st.wHour) == -1) goto LBL_noData; charPtr = (isetting >= 12) ? _T("PM") : _T("AM"); goto LBL_charPtr; case 'M': if ((isetting = st.wMinute) == -1) goto LBL_noData; goto LBL_2DigNum; case 'S': if ((isetting = st.wHour) == -1) goto LBL_noData; goto LBL_2DigNum; case 'n': charPtr = hcontact ? (TCHAR*)pcli->pfnGetContactDisplayName(hcontact, 0) : (wantempty ? _T("") : _T("---")); goto LBL_charPtr; case 'N': ci.dwFlag = CNF_NICK | CNF_TCHAR; if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM)&ci)) { charPtr = ci.pszVal; goto LBL_charPtr; } goto LBL_noData; case 'G': if (!db_get_ts(hcontact, "CList", "Group", &dbv)) { _tcsncpy(szdbsetting, dbv.ptszVal, _countof(szdbsetting)); db_free(&dbv); charPtr = szdbsetting; goto LBL_charPtr; } break; case 'u': ci.dwFlag = CNF_UNIQUEID | CNF_TCHAR; if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM)&ci)) { switch (ci.type) { case CNFT_BYTE: _ltot(ci.bVal, szdbsetting, 10); break; case CNFT_WORD: _ltot(ci.wVal, szdbsetting, 10); break; case CNFT_DWORD: _ltot(ci.dVal, szdbsetting, 10); break; case CNFT_ASCIIZ: _tcsncpy(szdbsetting, ci.pszVal, _countof(szdbsetting)); break; } } else goto LBL_noData; charPtr = szdbsetting; goto LBL_charPtr; case 's': if (isetting = db_get_w(hcontact, S_MOD, hcontact ? "StatusTriger" : courProtoName, 0)) { _tcsncpy(szdbsetting, pcli->pfnGetStatusModeDescription(isetting | 0x8000, 0), _countof(szdbsetting)); if (!(isetting & 0x8000)) { mir_tstrncat(szdbsetting, _T("/"), _countof(szdbsetting) - mir_tstrlen(szdbsetting)); mir_tstrncat(szdbsetting, TranslateT("Idle"), _countof(szdbsetting) - mir_tstrlen(szdbsetting)); } charPtr = szdbsetting; goto LBL_charPtr; } goto LBL_noData; case 'T': if (db_get_ts(hcontact, "CList", "StatusMsg", &dbv)) goto LBL_noData; d += mir_sntprintf(d, MAXSIZE - (d - sztemp), _T("%s"), dbv.ptszVal); db_free(&dbv); break; case 'o': if (isetting = db_get_w(hcontact, S_MOD, hcontact ? "OldStatus" : courProtoName, 0)) { _tcsncpy(szdbsetting, pcli->pfnGetStatusModeDescription(isetting, 0), _countof(szdbsetting)); if (includeIdle && hcontact && db_get_b(hcontact, S_MOD, "OldIdle", 0)) { mir_tstrncat(szdbsetting, _T("/"), _countof(szdbsetting) - mir_tstrlen(szdbsetting)); mir_tstrncat(szdbsetting, TranslateT("Idle"), _countof(szdbsetting) - mir_tstrlen(szdbsetting)); } charPtr = szdbsetting; goto LBL_charPtr; } goto LBL_noData; case 'i': case 'r': if (isJabber(ci.szProto)) { if (db_get_ts(hcontact, ci.szProto, *p == 'i' ? "Resource" : "System", &dbv)) goto LBL_noData; _tcsncpy(szdbsetting, dbv.ptszVal, _countof(szdbsetting)); db_free(&dbv); charPtr = szdbsetting; } else { dwsetting = db_get_dw(hcontact, ci.szProto, *p == 'i' ? "IP" : "RealIP", 0); if (!dwsetting) goto LBL_noData; ia.S_un.S_addr = htonl(dwsetting); _tcsncpy(szdbsetting, _A2T(inet_ntoa(ia)), _countof(szdbsetting)); charPtr = szdbsetting; } goto LBL_charPtr; case 'P': _tcsncpy(szdbsetting, ci.szProto ? _A2T(ci.szProto) : (wantempty ? _T("") : _T("ProtoUnknown")), _countof(szdbsetting)); charPtr = szdbsetting; goto LBL_charPtr; case 'b': charPtr = _T("\x0D\x0A"); goto LBL_charPtr; case 'C': // Get Client Info if (!db_get_ts(hcontact, ci.szProto, "MirVer", &dbv)) { _tcsncpy(szdbsetting, dbv.ptszVal, _countof(szdbsetting)); db_free(&dbv); } else goto LBL_noData; charPtr = szdbsetting; goto LBL_charPtr; case 't': charPtr = _T("\t"); goto LBL_charPtr; case 'A': { PROTOACCOUNT *pa = Proto_GetAccount(ci.szProto); if (!pa) goto LBL_noData; _tcsncpy(szdbsetting, pa->tszAccountName, _countof(szdbsetting)); charPtr = szdbsetting; goto LBL_charPtr; } default: *d++ = p[-1]; *d++ = *p; } } *d = 0; return sztemp; }
static INT_PTR CALLBACK CopyAwayMsgDlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) { AwayMsgDlgData *dat = (AwayMsgDlgData *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); switch (message) { case WM_INITDIALOG: { TCHAR str[256], format[128]; TCHAR *contactName; TranslateDialogDefault(hwndDlg); dat = (AwayMsgDlgData *)mir_alloc(sizeof(AwayMsgDlgData)); SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)dat); dat->hContact = lParam; dat->hSeq = (HANDLE)CallContactService(dat->hContact, PSS_GETAWAYMSG, 0, 0); dat->hAwayMsgEvent = dat->hSeq ? HookEventMessage(ME_PROTO_ACK, hwndDlg, HM_AWAYMSG) : NULL; WindowList_Add(hWindowList2, hwndDlg, dat->hContact); contactName = (TCHAR *)pcli->pfnGetContactDisplayName(dat->hContact, 0); GetWindowText(hwndDlg, format, _countof(format)); mir_sntprintf(str, _countof(str), format, contactName); SetWindowText(hwndDlg, str); if (!dat->hSeq) DestroyWindow(hwndDlg); return TRUE; } case HM_AWAYMSG: { ACKDATA *ack = (ACKDATA *)lParam; if (ack->hContact != dat->hContact || ack->type != ACKTYPE_AWAYMSG) { DestroyWindow(hwndDlg); break; } if (ack->result != ACKRESULT_SUCCESS) { DestroyWindow(hwndDlg); break; } if (dat->hAwayMsgEvent && ack->hProcess == dat->hSeq) { UnhookEvent(dat->hAwayMsgEvent); dat->hAwayMsgEvent = NULL; } if (!OpenClipboard(hwndDlg)) { DestroyWindow(hwndDlg); break; } if (EmptyClipboard()) { TCHAR msg[1024]; TCHAR *tszMsg = StrNormNewline((TCHAR *)ack->lParam); _tcsncpy_s(msg, tszMsg, _TRUNCATE); mir_free(tszMsg); size_t len = mir_tstrlen(msg); if (len) { LPTSTR lptstrCopy; HGLOBAL hglbCopy = GlobalAlloc(GMEM_MOVEABLE, (len + 1) * sizeof(TCHAR)); if (hglbCopy == NULL) { CloseClipboard(); DestroyWindow(hwndDlg); break; } lptstrCopy = (LPTSTR)GlobalLock(hglbCopy); memcpy(lptstrCopy, msg, len * sizeof(TCHAR)); lptstrCopy[len] = (TCHAR)0; GlobalUnlock(hglbCopy); SetClipboardData(CF_UNICODETEXT, hglbCopy); } } CloseClipboard(); DestroyWindow(hwndDlg); break; } case WM_COMMAND: switch (LOWORD(wParam)) { case IDCANCEL: case IDOK: DestroyWindow(hwndDlg); break; } break; case WM_CLOSE: DestroyWindow(hwndDlg); break; case WM_DESTROY: if (dat->hAwayMsgEvent) UnhookEvent(dat->hAwayMsgEvent); WindowList_Remove(hWindowList2, hwndDlg); mir_free(dat); break; } return FALSE; }
static int AvatarChanged(WPARAM hContact, LPARAM lParam) { if (hContact == NULL) return 0; char *proto = GetContactProto(hContact); if (proto == NULL) return 0; if (mir_strcmp(META_PROTO, proto) == 0) return 0; DBVARIANT dbvOldHash = {0}; bool ret = (db_get_ts(hContact,MODULE_NAME,"AvatarHash",&dbvOldHash) == 0); CONTACTAVATARCHANGEDNOTIFICATION* avatar = (CONTACTAVATARCHANGEDNOTIFICATION*)lParam; if (avatar == NULL) { if (!ret || !mir_tstrcmp(dbvOldHash.ptszVal, _T("-"))) { //avoid duplicate "removed avatar" notifications //do not notify on an empty profile ShowDebugPopup(hContact, TranslateT("AVH Debug"), TranslateT("Removed avatar, no avatar before... skipping")); db_free(&dbvOldHash); return 0; } SkinPlaySound("avatar_removed"); // Is a flash avatar or avs could not load it db_set_ts(hContact, MODULE_NAME, "AvatarHash", _T("-")); if (ContactEnabled(hContact, "AvatarPopups", AVH_DEF_AVPOPUPS) && opts.popup_show_removed) ShowPopup(hContact, NULL, opts.popup_removed); } else { if (ret && !mir_tstrcmp(dbvOldHash.ptszVal, avatar->hash)) { // same avatar hash, skipping ShowDebugPopup(hContact, TranslateT("AVH Debug"), TranslateT("Hashes are the same... skipping")); db_free(&dbvOldHash); return 0; } SkinPlaySound("avatar_changed"); db_set_ts(hContact, "AvatarHistory", "AvatarHash", avatar->hash); TCHAR history_filename[MAX_PATH] = _T(""); if (ContactEnabled(hContact, "LogToDisk", AVH_DEF_LOGTODISK)) { if (!opts.log_store_as_hash) { if (opts.log_per_contact_folders) { GetOldStyleAvatarName(history_filename, hContact); if (CopyImageFile(avatar->filename, history_filename)) ShowPopup(hContact, TranslateT("Avatar History: Unable to save avatar"), history_filename); else ShowDebugPopup(hContact, TranslateT("AVH Debug: File copied successfully"), history_filename); MCONTACT hMetaContact = db_mc_getMeta(hContact); if (hMetaContact && ContactEnabled(hMetaContact, "LogToDisk", AVH_DEF_LOGTOHISTORY)) { TCHAR filename[MAX_PATH] = _T(""); GetOldStyleAvatarName(filename, hMetaContact); if (CopyImageFile(avatar->filename, filename)) ShowPopup(hContact, TranslateT("Avatar History: Unable to save avatar"), filename); else ShowDebugPopup(hContact, TranslateT("AVH Debug: File copied successfully"), filename); } } } else { // See if we already have the avatar TCHAR hash[128]; _tcsncpy_s(hash, avatar->hash, _TRUNCATE); ConvertToFilename(hash, _countof(hash)); TCHAR *file = GetCachedAvatar(proto, hash); if (file != NULL) { mir_tstrncpy(history_filename, file, _countof(history_filename)); mir_free(file); } else { if (opts.log_keep_same_folder) GetHistoryFolder(history_filename); else GetProtocolFolder(history_filename, proto); mir_sntprintf(history_filename, _T("%s\\%s"), history_filename, hash); if (CopyImageFile(avatar->filename, history_filename)) ShowPopup(hContact, TranslateT("Avatar History: Unable to save avatar"), history_filename); else ShowDebugPopup(hContact, TranslateT("AVH Debug: File copied successfully"), history_filename); } if (opts.log_per_contact_folders) { CreateOldStyleShortcut(hContact, history_filename); MCONTACT hMetaContact = db_mc_getMeta(hContact); if (hMetaContact && ContactEnabled(hMetaContact, "LogToDisk", AVH_DEF_LOGTOHISTORY)) CreateOldStyleShortcut(hMetaContact, history_filename); } } } if (ContactEnabled(hContact, "AvatarPopups", AVH_DEF_AVPOPUPS) && opts.popup_show_changed) ShowPopup(hContact, NULL, opts.popup_changed); if (ContactEnabled(hContact, "LogToHistory", AVH_DEF_LOGTOHISTORY)) { TCHAR rel_path[MAX_PATH]; PathToRelativeT(history_filename, rel_path); T2Utf blob(rel_path); DBEVENTINFO dbei = { sizeof(dbei) }; dbei.szModule = GetContactProto(hContact); dbei.flags = DBEF_READ | DBEF_UTF; dbei.timestamp = (DWORD) time(NULL); dbei.eventType = EVENTTYPE_AVATAR_CHANGE; dbei.cbBlob = (DWORD)mir_strlen(blob) + 1; dbei.pBlob = blob; db_event_add(hContact, &dbei); } } return 0; }
static INT_PTR Service_NewChat(WPARAM, LPARAM lParam) { GCSESSION *gcw = (GCSESSION *)lParam; if (gcw == NULL) return GC_NEWSESSION_ERROR; if (gcw->cbSize != sizeof(GCSESSION)) return GC_NEWSESSION_WRONGVER; mir_cslock lck(cs); MODULEINFO *mi = chatApi.MM_FindModule(gcw->pszModule); if (mi == NULL) return GC_NEWSESSION_ERROR; // try to restart a session first SESSION_INFO *si = chatApi.SM_FindSession(gcw->ptszID, gcw->pszModule); if (si != NULL) { chatApi.UM_RemoveAll(&si->pUsers); chatApi.TM_RemoveAll(&si->pStatuses); si->iStatusCount = 0; si->nUsersInNicklist = 0; si->pMe = NULL; if (chatApi.OnReplaceSession) chatApi.OnReplaceSession(si); return 0; } // create a new session and set the defaults if ((si = chatApi.SM_AddSession(gcw->ptszID, gcw->pszModule)) == NULL) return GC_NEWSESSION_ERROR; si->dwItemData = gcw->dwItemData; if (gcw->iType != GCW_SERVER) si->wStatus = ID_STATUS_ONLINE; si->iType = gcw->iType; si->dwFlags = gcw->dwFlags; si->ptszName = mir_tstrdup(gcw->ptszName); si->ptszStatusbarText = mir_tstrdup(gcw->ptszStatusbarText); si->iSplitterX = g_Settings->iSplitterX; si->iSplitterY = g_Settings->iSplitterY; si->iLogFilterFlags = db_get_dw(NULL, CHAT_MODULE, "FilterFlags", 0x03E0); si->bFilterEnabled = db_get_b(NULL, CHAT_MODULE, "FilterEnabled", 0); si->bNicklistEnabled = db_get_b(NULL, CHAT_MODULE, "ShowNicklist", 1); if (mi->bColor) { si->iFG = 4; si->bFGSet = TRUE; } if (mi->bBkgColor) { si->iBG = 2; si->bBGSet = TRUE; } TCHAR szTemp[256]; if (si->iType == GCW_SERVER) mir_sntprintf(szTemp, _T("Server: %s"), si->ptszName); else _tcsncpy_s(szTemp, si->ptszName, _TRUNCATE); si->hContact = chatApi.AddRoom(gcw->pszModule, gcw->ptszID, szTemp, si->iType); db_set_s(si->hContact, si->pszModule, "Topic", ""); db_unset(si->hContact, "CList", "StatusMsg"); if (si->ptszStatusbarText) db_set_ts(si->hContact, si->pszModule, "StatusBar", si->ptszStatusbarText); else db_set_s(si->hContact, si->pszModule, "StatusBar", ""); if (chatApi.OnCreateSession) chatApi.OnCreateSession(si, mi); return 0; }
INT_PTR CALLBACK DlgPluginOpt(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_INITDIALOG: TranslateDialogDefault(hwndDlg); timerID = 0; { HWND hwndList = GetDlgItem(hwndDlg, IDC_PLUGLIST); mir_subclassWindow(hwndList, PluginListWndProc); HIMAGELIST hIml = ImageList_Create(16, 16, ILC_MASK | ILC_COLOR32, 4, 0); ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_UNICODE); ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_ANSI); ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_LOADED); ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_NOTLOADED); ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_LOADEDGRAY); ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_NOTLOADEDGRAY); ListView_SetImageList(hwndList, hIml, LVSIL_SMALL); LVCOLUMN col; col.mask = LVCF_TEXT | LVCF_WIDTH; col.pszText = _T(""); col.cx = 40; ListView_InsertColumn(hwndList, 0, &col); col.pszText = TranslateT("Plugin"); col.cx = 180; ListView_InsertColumn(hwndList, 1, &col); col.pszText = TranslateT("Name"); col.cx = 180;//max = 220; ListView_InsertColumn(hwndList, 2, &col); col.pszText = TranslateT("Version"); col.cx = 75; ListView_InsertColumn(hwndList, 3, &col); ListView_SetExtendedListViewStyleEx(hwndList, 0, LVS_EX_SUBITEMIMAGES | LVS_EX_CHECKBOXES | LVS_EX_LABELTIP | LVS_EX_FULLROWSELECT); // scan the plugin dir for plugins, cos arPluginList.destroy(); szFilter.Empty(); enumPlugins(dialogListPlugins, (WPARAM)hwndDlg, (LPARAM)hwndList); // sort out the headers ListView_SetColumnWidth(hwndList, 1, LVSCW_AUTOSIZE); // dll name int w = ListView_GetColumnWidth(hwndList, 1); if (w > 110) { ListView_SetColumnWidth(hwndList, 1, w = 110); } int max = w < 110 ? 189 + 110 - w : 189; ListView_SetColumnWidth(hwndList, 3, LVSCW_AUTOSIZE); // short name w = ListView_GetColumnWidth(hwndList, 2); if (w > max) ListView_SetColumnWidth(hwndList, 2, max); ListView_SortItems(hwndList, SortPlugins, (LPARAM)hwndDlg); } return TRUE; case WM_NOTIFY: if (lParam) { NMLISTVIEW *hdr = (NMLISTVIEW *)lParam; if (hdr->hdr.code == LVN_ITEMCHANGED && IsWindowVisible(hdr->hdr.hwndFrom)) { if (hdr->uOldState != 0 && (hdr->uNewState == 0x1000 || hdr->uNewState == 0x2000)) { HWND hwndList = GetDlgItem(hwndDlg, IDC_PLUGLIST); LVITEM it; it.mask = LVIF_PARAM | LVIF_STATE; it.iItem = hdr->iItem; if (!ListView_GetItem(hwndList, &it)) break; PluginListItemData *dat = (PluginListItemData*)it.lParam; if (dat->flags & STATIC_PLUGIN) { ListView_SetItemState(hwndList, hdr->iItem, 0x3000, LVIS_STATEIMAGEMASK); return FALSE; } // find all another standard plugins by mask and disable them if ((hdr->uNewState == 0x2000) && dat->stdPlugin != 0) { for (int iRow = 0; iRow != -1; iRow = ListView_GetNextItem(hwndList, iRow, LVNI_ALL)) { if (iRow != hdr->iItem) { // skip the plugin we're standing on LVITEM dt; dt.mask = LVIF_PARAM; dt.iItem = iRow; if (ListView_GetItem(hwndList, &dt)) { PluginListItemData *dat2 = (PluginListItemData*)dt.lParam; if (dat2->stdPlugin & dat->stdPlugin) {// mask differs // the lParam is unset, so when the check is unset the clist block doesnt trigger int iSave = dat2->stdPlugin; dat2->stdPlugin = 0; ListView_SetItemState(hwndList, iRow, 0x1000, LVIS_STATEIMAGEMASK); dat2->stdPlugin = iSave; } } } } } if (bOldMode) ShowWindow(GetDlgItem(hwndDlg, IDC_RESTART), TRUE); // this here only in "ghazan mode" SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); break; } if (hdr->iItem != -1) { int sel = hdr->uNewState & LVIS_SELECTED; HWND hwndList = GetDlgItem(hwndDlg, IDC_PLUGLIST); LVITEM lvi = { 0 }; lvi.mask = LVIF_PARAM; lvi.iItem = hdr->iItem; if (ListView_GetItem(hwndList, &lvi)) { PluginListItemData *dat = (PluginListItemData*)lvi.lParam; TCHAR buf[1024]; ListView_GetItemText(hwndList, hdr->iItem, 2, buf, _countof(buf)); SetDlgItemText(hwndDlg, IDC_PLUGININFOFRAME, sel ? buf : _T("")); ptrT tszAuthor(latin2t(sel ? dat->author : NULL)); SetDlgItemText(hwndDlg, IDC_PLUGINAUTHOR, tszAuthor); ptrT tszEmail(latin2t(sel ? dat->authorEmail : NULL)); SetDlgItemText(hwndDlg, IDC_PLUGINEMAIL, tszEmail); ptrT p(Langpack_PcharToTchar(dat->description)); SetDlgItemText(hwndDlg, IDC_PLUGINLONGINFO, sel ? p : _T("")); ptrT tszCopyright(latin2t(sel ? dat->copyright : NULL)); SetDlgItemText(hwndDlg, IDC_PLUGINCPYR, tszCopyright); ptrT tszUrl(latin2t(sel ? dat->homepage : NULL)); SetDlgItemText(hwndDlg, IDC_PLUGINURL, tszUrl); if (!equalUUID(miid_last, dat->uuid)) { char szUID[128]; uuidToString(dat->uuid, szUID, sizeof(szUID)); SetDlgItemTextA(hwndDlg, IDC_PLUGINPID, sel ? szUID : ""); } else SetDlgItemText(hwndDlg, IDC_PLUGINPID, sel ? TranslateT("<none>") : _T("")); } } } if (hdr->hdr.code == PSN_APPLY) { bool needRestart = false; TCHAR bufRestart[1024]; int bufLen = mir_sntprintf(bufRestart, _T("%s\n"), TranslateT("Miranda NG must be restarted to apply changes for these plugins:")); HWND hwndList = GetDlgItem(hwndDlg, IDC_PLUGLIST); for (int iRow = 0; iRow != -1;) { TCHAR buf[1024]; ListView_GetItemText(hwndList, iRow, 1, buf, _countof(buf)); int iState = ListView_GetItemState(hwndList, iRow, LVIS_STATEIMAGEMASK); SetPluginOnWhiteList(buf, (iState & 0x2000) ? 1 : 0); if (!bOldMode && iState != 0x3000) { LVITEM lvi = { 0 }; lvi.mask = LVIF_IMAGE | LVIF_PARAM; lvi.stateMask = -1; lvi.iItem = iRow; lvi.iSubItem = 0; if (ListView_GetItem(hwndList, &lvi)) { lvi.mask = LVIF_IMAGE; PluginListItemData *dat = (PluginListItemData*)lvi.lParam; if (iState == 0x2000) { // enabling plugin if (lvi.iImage == 3 || lvi.iImage == 5) { if (lvi.iImage == 3 && LoadPluginDynamically(dat)) { lvi.iImage = 2; ListView_SetItem(hwndList, &lvi); } else { bufLen += mir_sntprintf(bufRestart + bufLen, _countof(bufRestart) - bufLen, _T(" - %s\n"), buf); needRestart = true; } } } else { // disabling plugin if (lvi.iImage == 2 || lvi.iImage == 4) { if (lvi.iImage == 2 && UnloadPluginDynamically(dat)) { lvi.iImage = 3; ListView_SetItem(hwndList, &lvi); } else { bufLen += mir_sntprintf(bufRestart + bufLen, _countof(bufRestart) - bufLen, _T(" - %s\n"), buf); needRestart = true; } } } } } iRow = ListView_GetNextItem(hwndList, iRow, LVNI_ALL); } LoadStdPlugins(); ShowWindow(GetDlgItem(hwndDlg, IDC_RESTART), needRestart); if (needRestart) { mir_sntprintf(bufRestart + bufLen, _countof(bufRestart) - bufLen, _T("\n%s"), TranslateT("Do you want to restart it now?")); if (MessageBox(NULL, bufRestart, _T("Miranda NG"), MB_ICONWARNING | MB_YESNO) == IDYES) CallService(MS_SYSTEM_RESTART, 1, 0); } } } break; case WM_COMMAND: if (HIWORD(wParam) == STN_CLICKED) { switch (LOWORD(wParam)) { case IDC_GETMOREPLUGINS: Utils_OpenUrl("http://miranda-ng.org/downloads/"); break; case IDC_PLUGINEMAIL: case IDC_PLUGINURL: char buf[512]; char *p = &buf[7]; mir_strcpy(buf, "mailto:"); if (GetDlgItemTextA(hwndDlg, LOWORD(wParam), p, _countof(buf) - 7)) Utils_OpenUrl(LOWORD(wParam) == IDC_PLUGINEMAIL ? buf : p); break; } } break; case WM_DESTROY: arPluginList.destroy(); RemoveAllItems(GetDlgItem(hwndDlg, IDC_PLUGLIST)); break; } return FALSE; }
BOOL ITunes::FillCache() { HRESULT hr; long lret; CALL( track->get_Album(&ret)); listening_info.ptszAlbum = U2T(ret); CALL( track->get_Artist(&ret)); listening_info.ptszArtist = U2T(ret); CALL( track->get_Name(&ret)); listening_info.ptszTitle = U2T(ret); CALL( track->get_Year(&lret)); if (lret > 0) { listening_info.ptszYear = (TCHAR*) mir_alloc(10 * sizeof(TCHAR)); _itot(lret, listening_info.ptszYear, 10); } CALL( track->get_TrackNumber(&lret)); if (lret > 0) { listening_info.ptszTrack = (TCHAR*) mir_alloc(10 * sizeof(TCHAR)); _itot(lret, listening_info.ptszTrack, 10); } CALL( track->get_Genre(&ret)); listening_info.ptszGenre = U2T(ret); CALL( track->get_Duration(&lret)); if (lret > 0) { listening_info.ptszLength = (TCHAR*) mir_alloc(10 * sizeof(TCHAR)); int s = lret % 60; int m = (lret / 60) % 60; int h = (lret / 60) / 60; if (h > 0) mir_sntprintf(listening_info.ptszLength, 9, _T("%d:%02d:%02d"), h, m, s); else mir_sntprintf(listening_info.ptszLength, 9, _T("%d:%02d"), m, s); } listening_info.ptszType = mir_tstrdup(_T("Music")); if (listening_info.ptszTitle == NULL) { // Get from filename WCHAR *p = wcsrchr(filename, '\\'); if (p != NULL) p++; else p = filename; listening_info.ptszTitle = mir_u2t(p); TCHAR *pt = _tcsrchr(listening_info.ptszTitle, '.'); if (pt != NULL) *p = _T('\0'); } listening_info.ptszPlayer = mir_tstrdup(name); listening_info.cbSize = sizeof(listening_info); listening_info.dwFlags = LTI_TCHAR; return TRUE; }
void CSrmmProxyWindow::OnRenderThumbnail(int width, int height) { HBITMAP hbmp = CreateDwmBitmap(width, height); HDC hdc = CreateCompatibleDC(0); SelectObject(hdc, hbmp); RGBQUAD rgb0, rgb1; rgb0.rgbRed = 0; rgb0.rgbGreen = 0; rgb0.rgbBlue = 0; rgb1.rgbRed = 19; rgb1.rgbGreen = 58; rgb1.rgbBlue = 89; DrawGradient(hdc, 0, 0, width, height, &rgb0, &rgb1); HFONT hfntSave = (HFONT)SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT)); SetTextColor(hdc, RGB(255, 255, 255)); SetBkMode(hdc, TRANSPARENT); RECT rc; SIZE sz; SetRect(&rc, 5, 5, width-10, height-10); int avatarWidth = 0; int avatarHeight = 0; if (true) { AVATARCACHEENTRY *ace = (AVATARCACHEENTRY *)CallService(MS_AV_GETAVATARBITMAP, (WPARAM)m_hContact, 0); if (ace && (ace != (AVATARCACHEENTRY *)CALLSERVICE_NOTFOUND)) { if (ace->bmWidth < width / 4) { avatarWidth = ace->bmWidth; avatarHeight = ace->bmHeight; } else { avatarWidth = width / 4; avatarHeight = avatarWidth * ace->bmHeight / ace->bmWidth; } AVATARDRAWREQUEST avdr = {0}; avdr.cbSize = sizeof(avdr); avdr.hContact = m_hContact; avdr.hTargetDC = hdc; avdr.rcDraw = rc; avdr.rcDraw.bottom = avdr.rcDraw.top + avatarHeight; avdr.rcDraw.right = avdr.rcDraw.left + avatarWidth; avdr.dwFlags = AVDRQ_FALLBACKPROTO | AVDRQ_FORCEALPHA; avdr.alpha = 255; CallService(MS_AV_DRAWAVATAR, 0, (LPARAM)&avdr); rc.left += avatarWidth + 5; } } char *proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)m_hContact, 0); if (true) { CONTACTINFO ci = {0}; ci.cbSize = sizeof(ci); ci.hContact = m_hContact; ci.szProto = proto; ci.dwFlag = CNF_UNIQUEID | CNF_TCHAR; if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM) & ci)) { TCHAR name[128]; name[0] = 0; switch (ci.type) { case CNFT_ASCIIZ: mir_sntprintf(name, SIZEOF(name), _T("%s"), ci.pszVal); mir_free((void *)ci.pszVal); break; case CNFT_DWORD: mir_sntprintf(name, SIZEOF(name), _T("%u"), ci.dVal); break; } TextOut(hdc, rc.left + 20, rc.top, name, lstrlen(name)); GetTextExtentPoint32(hdc, name, lstrlen(name), &sz); } } if (true) { HIMAGELIST hIml = (HIMAGELIST)CallService(MS_CLIST_GETICONSIMAGELIST, 0, 0); int iIcon = CallService(MS_CLIST_GETCONTACTICON, (WPARAM)m_hContact, 0); ImageList_Draw(hIml, iIcon, hdc, rc.left, rc.top + (sz.cy - 16) / 2, ILD_TRANSPARENT); } rc.top += sz.cy + 5; rc.left += 10; struct { TCHAR *text; bool out; } msgs[10] = {0}; if (true) { int hMsgs = 0; int n = 0; HANDLE hEvent = (HANDLE)CallService(MS_DB_EVENT_FINDLAST, (WPARAM)m_hContact, 0); while (hEvent) { BYTE buf[1024]; DBEVENTINFO dbei = {0}; dbei.cbSize = sizeof(dbei); dbei.cbBlob = sizeof(buf); dbei.pBlob = buf; if (!CallService(MS_DB_EVENT_GET, (WPARAM)hEvent, (LPARAM)&dbei)) { if (dbei.eventType == EVENTTYPE_MESSAGE) { msgs[n].text = DbGetEventTextT(&dbei, CP_ACP); msgs[n].out = dbei.flags & DBEF_SENT ? true : false; RECT rcCopy = rc; hMsgs += DrawText(hdc, msgs[n].text, -1, &rcCopy, DT_LEFT|DT_NOPREFIX|DT_WORDBREAK|DT_TOP|DT_CALCRECT); if (n && hMsgs > rc.bottom - rc.top) { mir_free(msgs[n].text); msgs[n].text = 0; break; } hMsgs += 3; if (++n >= SIZEOF(msgs)) break; } } hEvent = (HANDLE)CallService(MS_DB_EVENT_FINDPREV, (WPARAM)hEvent, 0); } } if (true) { for (int i = SIZEOF(msgs); i--; ) { if (!msgs[i].text) continue; TCHAR szDir[] = { (msgs[i].out ? (WCHAR)0xbb : (WCHAR)0xab), 0 }; rc.left -= 10; DrawText(hdc, szDir, -1, &rc, DT_LEFT|DT_NOPREFIX|DT_WORDBREAK|DT_TOP); rc.left += 10; rc.top += 3 + DrawText(hdc, msgs[i].text, -1, &rc, DT_LEFT|DT_NOPREFIX|DT_WORDBREAK|DT_TOP); mir_free(msgs[i].text); } } SelectObject(hdc, hfntSave); DeleteDC(hdc); MakeBitmapOpaque(hbmp); SetThumbnail(hbmp); DeleteObject(hbmp); }