int SendQueue::sendQueued(TWindowData *dat, const int iEntry) { HWND hwndDlg = dat->hwnd; if (dat->sendMode & SMODE_MULTIPLE) { HANDLE hContact, hItem; int iJobs = 0; int iMinLength = 0; CContactCache* c = 0; hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); m_jobs[iEntry].hOwner = dat->hContact; m_jobs[iEntry].iStatus = SQ_INPROGRESS; m_jobs[iEntry].hwndOwner = hwndDlg; int iSendLength = getSendLength(iEntry, dat->sendMode); do { hItem = (HANDLE) SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_FINDCONTACT, (WPARAM) hContact, 0); if (hItem && SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_GETCHECKMARK, (WPARAM) hItem, 0)) { c = CContactCache::getContactCache(hContact); if(c) iMinLength = (iMinLength == 0 ? c->getMaxMessageLength() : min(c->getMaxMessageLength(), iMinLength)); } } while (hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0)); if(iSendLength >= iMinLength) { TCHAR tszError[256]; mir_sntprintf(tszError, 256, CTranslator::get(CTranslator::GEN_SQ_SENDLATER_ERROR_MSG_TOO_LONG), iMinLength); ::SendMessage(dat->hwnd, DM_ACTIVATETOOLTIP, IDC_MESSAGE, reinterpret_cast<LPARAM>(tszError)); sendQueue->clearJob(iEntry); return(0); } hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); do { hItem = (HANDLE) SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_FINDCONTACT, (WPARAM) hContact, 0); if (hItem && SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_GETCHECKMARK, (WPARAM) hItem, 0)) { doSendLater(iEntry, 0, hContact, false); iJobs++; } } while (hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0)); sendQueue->clearJob(iEntry); if(iJobs) sendLater->flushQueue(); // force queue processing return(0); } else { if (dat->hContact == NULL) return 0; //never happens dat->nMax = dat->cache->getMaxMessageLength(); // refresh length info if (dat->sendMode & SMODE_FORCEANSI && M->GetByte(dat->cache->getActiveContact(), dat->cache->getActiveProto(), "UnicodeSend", 1)) M->WriteByte(dat->cache->getActiveContact(), dat->cache->getActiveProto(), "UnicodeSend", 0); else if (!(dat->sendMode & SMODE_FORCEANSI) && !M->GetByte(dat->cache->getActiveContact(), dat->cache->getActiveProto(), "UnicodeSend", 0)) M->WriteByte(dat->cache->getActiveContact(), dat->cache->getActiveProto(), "UnicodeSend", 1); if (M->GetByte("autosplit", 1) && !(dat->sendMode & SMODE_SENDLATER)) { BOOL fSplit = FALSE; DWORD dwOldFlags; /* * determine send buffer length */ if(getSendLength(iEntry, dat->sendMode) >= dat->nMax) fSplit = true; if (!fSplit) goto send_unsplitted; m_jobs[iEntry].hOwner = dat->hContact; m_jobs[iEntry].hwndOwner = hwndDlg; m_jobs[iEntry].iStatus = SQ_INPROGRESS; m_jobs[iEntry].iAcksNeeded = 1; m_jobs[iEntry].chunkSize = dat->nMax; dwOldFlags = m_jobs[iEntry].dwFlags; if (dat->sendMode & SMODE_FORCEANSI) m_jobs[iEntry].dwFlags &= ~PREF_UNICODE; if (!(m_jobs[iEntry].dwFlags & PREF_UNICODE) || dat->sendMode & SMODE_FORCEANSI) mir_forkthread(DoSplitSendA, (LPVOID)iEntry); else mir_forkthread(DoSplitSendW, (LPVOID)iEntry); m_jobs[iEntry].dwFlags = dwOldFlags; } else { send_unsplitted: m_jobs[iEntry].hOwner = dat->hContact; m_jobs[iEntry].hwndOwner = hwndDlg; m_jobs[iEntry].iStatus = SQ_INPROGRESS; m_jobs[iEntry].iAcksNeeded = 1; if(dat->sendMode & SMODE_SENDLATER) { TCHAR tszError[256]; int iSendLength = getSendLength(iEntry, dat->sendMode); if(iSendLength >= dat->nMax) { mir_sntprintf(tszError, 256, CTranslator::get(CTranslator::GEN_SQ_SENDLATER_ERROR_MSG_TOO_LONG), dat->nMax); SendMessage(dat->hwnd, DM_ACTIVATETOOLTIP, IDC_MESSAGE, reinterpret_cast<LPARAM>(tszError)); clearJob(iEntry); return(0); } doSendLater(iEntry, dat); clearJob(iEntry); return(0); } m_jobs[iEntry].hSendId = (HANDLE) CallContactService(dat->hContact, MsgServiceName(dat->hContact, dat, m_jobs[iEntry].dwFlags), (dat->sendMode & SMODE_FORCEANSI) ? (m_jobs[iEntry].dwFlags & ~PREF_UNICODE) : m_jobs[iEntry].dwFlags, (LPARAM) m_jobs[iEntry].sendBuffer); if (dat->sendMode & SMODE_NOACK) { // fake the ack if we are not interested in receiving real acks ACKDATA ack = {0}; ack.hContact = dat->hContact; ack.hProcess = m_jobs[iEntry].hSendId; ack.type = ACKTYPE_MESSAGE; ack.result = ACKRESULT_SUCCESS; SendMessage(hwndDlg, HM_EVENTSENT, (WPARAM)MAKELONG(iEntry, 0), (LPARAM)&ack); } else SetTimer(hwndDlg, TIMERID_MSGSEND + iEntry, PluginConfig.m_MsgTimeout, NULL); } } dat->iOpenJobs++; m_currentIndex++; // give icon feedback... if (dat->pContainer->hwndActive == hwndDlg) ::UpdateReadChars(dat); if (!(dat->sendMode & SMODE_NOACK)) ::HandleIconFeedback(dat, PluginConfig.g_IconSend); if (M->GetByte(SRMSGSET_AUTOMIN, SRMSGDEFSET_AUTOMIN)) ::SendMessage(dat->pContainer->hwnd, WM_SYSCOMMAND, SC_MINIMIZE, 0); return 0; }
int SendQueue::sendQueued(TWindowData *dat, const int iEntry) { CContactCache *ccActive = CContactCache::getContactCache(dat->hContact); if (ccActive == NULL) return 0; HWND hwndDlg = dat->hwnd; if (dat->sendMode & SMODE_MULTIPLE) { int iJobs = 0; int iMinLength = 0; m_jobs[iEntry].iStatus = SQ_INPROGRESS; m_jobs[iEntry].hContact = ccActive->getActiveContact(); m_jobs[iEntry].hOwnerWnd = hwndDlg; size_t iSendLength = getSendLength(iEntry); for (MCONTACT hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) { HANDLE hItem = (HANDLE)SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_FINDCONTACT, hContact, 0); if (hItem && SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_GETCHECKMARK, (WPARAM)hItem, 0)) { CContactCache *c = CContactCache::getContactCache(hContact); if (c) iMinLength = (iMinLength == 0 ? c->getMaxMessageLength() : min(c->getMaxMessageLength(), iMinLength)); } } if (iSendLength >= iMinLength) { TCHAR tszError[256]; mir_sntprintf(tszError, TranslateT("The message cannot be sent delayed or to multiple contacts, because it exceeds the maximum allowed message length of %d bytes"), iMinLength); ::SendMessage(dat->hwnd, DM_ACTIVATETOOLTIP, IDC_MESSAGE, LPARAM(tszError)); sendQueue->clearJob(iEntry); return 0; } for (MCONTACT hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) { HANDLE hItem = (HANDLE)SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_FINDCONTACT, hContact, 0); if (hItem && SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_GETCHECKMARK, (WPARAM)hItem, 0)) { doSendLater(iEntry, 0, hContact, false); iJobs++; } } sendQueue->clearJob(iEntry); if (iJobs) sendLater->flushQueue(); // force queue processing return 0; } if (dat->hContact == NULL) return 0; //never happens dat->nMax = dat->cache->getMaxMessageLength(); // refresh length info if (M.GetByte("autosplit", 0) && !(dat->sendMode & SMODE_SENDLATER)) { // determine send buffer length BOOL fSplit = FALSE; if (getSendLength(iEntry) >= dat->nMax) fSplit = true; if (!fSplit) goto send_unsplitted; m_jobs[iEntry].hContact = ccActive->getActiveContact(); m_jobs[iEntry].hOwnerWnd = hwndDlg; m_jobs[iEntry].iStatus = SQ_INPROGRESS; m_jobs[iEntry].iAcksNeeded = 1; m_jobs[iEntry].chunkSize = dat->nMax; DWORD dwOldFlags = m_jobs[iEntry].dwFlags; mir_forkthread(DoSplitSendA, (LPVOID)iEntry); m_jobs[iEntry].dwFlags = dwOldFlags; } else { send_unsplitted: m_jobs[iEntry].hContact = ccActive->getActiveContact(); m_jobs[iEntry].hOwnerWnd = hwndDlg; m_jobs[iEntry].iStatus = SQ_INPROGRESS; m_jobs[iEntry].iAcksNeeded = 1; if (dat->sendMode & SMODE_SENDLATER) { TCHAR tszError[256]; size_t iSendLength = getSendLength(iEntry); if (iSendLength >= dat->nMax) { mir_sntprintf(tszError, TranslateT("The message cannot be sent delayed or to multiple contacts, because it exceeds the maximum allowed message length of %d bytes"), dat->nMax); SendMessage(dat->hwnd, DM_ACTIVATETOOLTIP, IDC_MESSAGE, LPARAM(tszError)); clearJob(iEntry); return 0; } doSendLater(iEntry, dat); clearJob(iEntry); return 0; } m_jobs[iEntry].hSendId = (HANDLE)CallContactService(dat->hContact, PSS_MESSAGE, m_jobs[iEntry].dwFlags, (LPARAM)m_jobs[iEntry].szSendBuffer); if (dat->sendMode & SMODE_NOACK) { // fake the ack if we are not interested in receiving real acks ACKDATA ack = { 0 }; ack.hContact = dat->hContact; ack.hProcess = m_jobs[iEntry].hSendId; ack.type = ACKTYPE_MESSAGE; ack.result = ACKRESULT_SUCCESS; SendMessage(hwndDlg, HM_EVENTSENT, (WPARAM)MAKELONG(iEntry, 0), (LPARAM)&ack); } else SetTimer(hwndDlg, TIMERID_MSGSEND + iEntry, PluginConfig.m_MsgTimeout, NULL); } dat->iOpenJobs++; m_currentIndex++; // give icon feedback... if (dat->pContainer->hwndActive == hwndDlg) ::UpdateReadChars(dat); if (!(dat->sendMode & SMODE_NOACK)) ::HandleIconFeedback(dat, PluginConfig.g_IconSend); if (M.GetByte(SRMSGSET_AUTOMIN, SRMSGDEFSET_AUTOMIN)) ::SendMessage(dat->pContainer->hwnd, WM_SYSCOMMAND, SC_MINIMIZE, 0); return 0; }