/* * add a message to the sending queue. * iLen = required size of the memory block to hold the message */ int SendQueue::addTo(TWindowData *dat, const int iLen, int dwFlags) { int iLength = 0, i; int iFound = NR_SENDJOBS; if (m_currentIndex >= NR_SENDJOBS) { _DebugPopup(dat->hContact, _T("Send queue full")); return 0; } /* * find a free entry in the send queue... */ for (i = 0; i < NR_SENDJOBS; i++) { if (m_jobs[i].hOwner != 0 || m_jobs[i].iStatus != 0) { // this entry is used, check if it's orphaned and can be removed... if (m_jobs[i].hwndOwner && IsWindow(m_jobs[i].hwndOwner)) // window exists, do not reuse it continue; if (time(NULL) - m_jobs[i].dwTime < 120) // non-acked entry, but not old enough, don't re-use it continue; clearJob(i); iFound = i; goto entry_found; } iFound = i; break; } entry_found: if (iFound == NR_SENDJOBS) { _DebugPopup(dat->hContact, _T("Send queue full")); return 0; } iLength = iLen; if (iLength > 0) { if (m_jobs[iFound].sendBuffer == NULL) { if (iLength < HISTORY_INITIAL_ALLOCSIZE) iLength = HISTORY_INITIAL_ALLOCSIZE; m_jobs[iFound].sendBuffer = (char *)malloc(iLength); m_jobs[iFound].dwLen = iLength; } else { if (iLength > m_jobs[iFound].dwLen) { m_jobs[iFound].sendBuffer = (char *)realloc(m_jobs[iFound].sendBuffer, iLength); m_jobs[iFound].dwLen = iLength; } } CopyMemory(m_jobs[iFound].sendBuffer, dat->sendBuffer, iLen); } m_jobs[iFound].dwFlags = dwFlags; m_jobs[iFound].dwTime = time(NULL); HWND hwndDlg = dat->hwnd; dat->cache->saveHistory(0, 0); ::SetDlgItemText(hwndDlg, IDC_MESSAGE, _T("")); ::SetFocus(GetDlgItem(hwndDlg, IDC_MESSAGE)); UpdateSaveAndSendButton(dat); sendQueued(dat, iFound); return 0; }
void xWorkingThread::exitThread(bool bWaited) { if(m_pRunner == NULL) return ; xThreadProc::exitThread(bWaited); clearJob(); m_pRunner->KillObject(); m_pRunner = NULL; return ; }
int SendQueue::addTo(TWindowData *dat, size_t iLen, int dwFlags) { int i; int iFound = NR_SENDJOBS; if (m_currentIndex >= NR_SENDJOBS) { _DebugPopup(dat->hContact, _T("Send queue full")); return 0; } // find a mir_free entry in the send queue... for (i = 0; i < NR_SENDJOBS; i++) { if (m_jobs[i].hContact != 0 || m_jobs[i].iStatus != 0) { // this entry is used, check if it's orphaned and can be removed... if (m_jobs[i].hOwnerWnd && IsWindow(m_jobs[i].hOwnerWnd)) // window exists, do not reuse it continue; if (time(NULL) - m_jobs[i].dwTime < 120) // non-acked entry, but not old enough, don't re-use it continue; clearJob(i); iFound = i; goto entry_found; } iFound = i; break; } entry_found: if (iFound == NR_SENDJOBS) { _DebugPopup(dat->hContact, _T("Send queue full")); return 0; } SendJob &job = m_jobs[iFound]; job.szSendBuffer = (char*)mir_alloc(iLen); memcpy(job.szSendBuffer, dat->sendBuffer, iLen); job.dwFlags = dwFlags; job.dwTime = time(NULL); HWND hwndDlg = dat->hwnd; dat->cache->saveHistory(0, 0); ::SetDlgItemText(hwndDlg, IDC_MESSAGE, _T("")); ::SetFocus(GetDlgItem(hwndDlg, IDC_MESSAGE)); UpdateSaveAndSendButton(dat); sendQueued(dat, iFound); return 0; }
TransferManagerWindow::TransferManagerWindow(QXmppTransferManager *transferManager, QWidget *parent) : QMainWindow(parent), ui(new Ui::TransferManagerWindow), m_transferManager(transferManager) { ui->setupUi(this); m_transferManagerModel = new TransferManagerModel(this); ui->tableView->setModel(m_transferManagerModel); ui->tableView->horizontalHeader()->setStretchLastSection(true); ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows); ui->tableView->setAlternatingRowColors(true); connect(ui->actionStopTransfer, SIGNAL(triggered()), this, SLOT(stopTransferJob()) ); connect(ui->actionCleanList, SIGNAL(triggered()), m_transferManagerModel, SLOT(clearJob()) ); ui->tableView->setContextMenuPolicy(Qt::CustomContextMenu); connect(ui->tableView, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(showCustomContextMenu(const QPoint &)) ); setAttribute(Qt::WA_QuitOnClose, false); }
int SendQueue::ackMessage(TWindowData *dat, WPARAM wParam, LPARAM lParam) { ACKDATA *ack = (ACKDATA *) lParam; DBEVENTINFO dbei = { 0}; HANDLE hNewEvent; int iFound = SendQueue::NR_SENDJOBS, iNextFailed; TContainerData *m_pContainer = 0; if (dat) m_pContainer = dat->pContainer; iFound = (int)(LOWORD(wParam)); //i = (int)(HIWORD(wParam)); if (m_jobs[iFound].iStatus == SQ_ERROR) { // received ack for a job which is already in error state... if (dat) { // window still open if (dat->iCurrentQueueError == iFound) { dat->iCurrentQueueError = -1; showErrorControls(dat, FALSE); } } /* * we must discard this job, because there is no message window open to handle the * error properly. But we display a tray notification to inform the user about the problem. */ else goto inform_and_discard; } // failed acks are only handled when the window is still open. with no window open, they will be *silently* discarded if (ack->result == ACKRESULT_FAILED) { if (dat) { /* * "hard" errors are handled differently in multisend. There is no option to retry - once failed, they * are discarded and the user is notified with a small log message. */ if (!nen_options.iNoSounds && !(m_pContainer->dwFlags & CNT_NOSOUND)) SkinPlaySound("SendError"); TCHAR *szAckMsg = mir_a2t((char *)ack->lParam); mir_sntprintf(m_jobs[iFound].szErrorMsg, safe_sizeof(m_jobs[iFound].szErrorMsg), CTranslator::get(CTranslator::GEN_MSG_DELIVERYFAILURE), szAckMsg); m_jobs[iFound].iStatus = SQ_ERROR; mir_free(szAckMsg); KillTimer(dat->hwnd, TIMERID_MSGSEND + iFound); if (!(dat->dwFlags & MWF_ERRORSTATE)) handleError(dat, iFound); return 0; } else { inform_and_discard: _DebugPopup(m_jobs[iFound].hOwner, CTranslator::get(CTranslator::GEN_SQ_DELIVERYFAILEDLATE)); clearJob(iFound); return 0; } } dbei.cbSize = sizeof(dbei); dbei.eventType = EVENTTYPE_MESSAGE; dbei.flags = DBEF_SENT; dbei.szModule = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) m_jobs[iFound].hOwner, 0); dbei.timestamp = time(NULL); dbei.cbBlob = lstrlenA(m_jobs[iFound].sendBuffer) + 1; if (dat) dat->cache->updateStats(TSessionStats::BYTES_SENT, dbei.cbBlob - 1); else { CContactCache *c = CContactCache::getContactCache(m_jobs[iFound].hOwner); if(c) c->updateStats(TSessionStats::BYTES_SENT, dbei.cbBlob - 1); } if (m_jobs[iFound].dwFlags & PREF_UNICODE) dbei.cbBlob *= sizeof(TCHAR) + 1; if (m_jobs[iFound].dwFlags & PREF_RTL) dbei.flags |= DBEF_RTL; if (m_jobs[iFound].dwFlags & PREF_UTF) dbei.flags |= DBEF_UTF; dbei.pBlob = (PBYTE) m_jobs[iFound].sendBuffer; hNewEvent = (HANDLE) CallService(MS_DB_EVENT_ADD, (WPARAM) m_jobs[iFound].hOwner, (LPARAM) & dbei); if (m_pContainer) { if (!nen_options.iNoSounds && !(m_pContainer->dwFlags & CNT_NOSOUND)) SkinPlaySound("SendMsg"); } if (dat && (m_jobs[iFound].hOwner == dat->hContact)) { if (dat->hDbEventFirst == NULL) { dat->hDbEventFirst = hNewEvent; SendMessage(dat->hwnd, DM_REMAKELOG, 0, 0); } } m_jobs[iFound].hSendId = NULL; m_jobs[iFound].iAcksNeeded--; if (m_jobs[iFound].iAcksNeeded == 0) { // everything sent //if (m_jobs[iFound].hOwner != 0 && dat) // EnableSending(dat, TRUE); clearJob(iFound); if (dat) { KillTimer(dat->hwnd, TIMERID_MSGSEND + iFound); dat->iOpenJobs--; } m_currentIndex--; } if (dat) { checkQueue(dat); if ((iNextFailed = findNextFailed(dat)) >= 0 && !(dat->dwFlags & MWF_ERRORSTATE)) handleError(dat, iNextFailed); //MAD: close on send mode else { if (M->GetByte("AutoClose", 0)) { if(M->GetByte("adv_AutoClose_2", 0)) SendMessage(dat->hwnd, WM_CLOSE, 0, 1); else SendMessage(dat->pContainer->hwnd, WM_CLOSE, 0, 0); } } //MAD_ } return 0; }
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; }
void xWorkingThreadPool::uninit() { clearJob(); if(m_pQueueLocker) m_pQueueLocker->KillObject(); }
int SendQueue::ackMessage(TWindowData *dat, WPARAM wParam, LPARAM lParam) { ACKDATA *ack = (ACKDATA *)lParam; TContainerData *m_pContainer = 0; if (dat) m_pContainer = dat->pContainer; int iFound = (int)(LOWORD(wParam)); SendJob &job = m_jobs[iFound]; if (job.iStatus == SQ_ERROR) { // received ack for a job which is already in error state... if (dat) { // window still open if (dat->iCurrentQueueError == iFound) { dat->iCurrentQueueError = -1; showErrorControls(dat, FALSE); } } // we must discard this job, because there is no message window open to handle the // error properly. But we display a tray notification to inform the user about the problem. else goto inform_and_discard; } // failed acks are only handled when the window is still open. with no window open, they will be *silently* discarded if (ack->result == ACKRESULT_FAILED) { if (dat) { // "hard" errors are handled differently in multisend. There is no option to retry - once failed, they // are discarded and the user is notified with a small log message. if (!nen_options.iNoSounds && !(m_pContainer->dwFlags & CNT_NOSOUND)) SkinPlaySound("SendError"); TCHAR *szAckMsg = mir_a2t((char *)ack->lParam); mir_sntprintf(job.szErrorMsg, TranslateT("Delivery failure: %s"), szAckMsg); job.iStatus = SQ_ERROR; mir_free(szAckMsg); KillTimer(dat->hwnd, TIMERID_MSGSEND + iFound); if (!(dat->dwFlags & MWF_ERRORSTATE)) handleError(dat, iFound); return 0; } inform_and_discard: _DebugPopup(job.hContact, TranslateT("A message delivery has failed after the contacts chat window was closed. You may want to resend the last message")); clearJob(iFound); return 0; } DBEVENTINFO dbei = { sizeof(dbei) }; dbei.eventType = EVENTTYPE_MESSAGE; dbei.flags = DBEF_SENT; dbei.szModule = GetContactProto(job.hContact); dbei.timestamp = time(NULL); dbei.cbBlob = (int)mir_strlen(job.szSendBuffer) + 1; if (dat) dat->cache->updateStats(TSessionStats::BYTES_SENT, dbei.cbBlob - 1); else { CContactCache *cc = CContactCache::getContactCache(job.hContact); if (cc) cc->updateStats(TSessionStats::BYTES_SENT, dbei.cbBlob - 1); } if (job.dwFlags & PREF_RTL) dbei.flags |= DBEF_RTL; dbei.flags |= DBEF_UTF; dbei.pBlob = (PBYTE)job.szSendBuffer; MessageWindowEvent evt = { sizeof(evt), (INT_PTR)job.hSendId, job.hContact, &dbei }; NotifyEventHooks(PluginConfig.m_event_WriteEvent, 0, (LPARAM)&evt); job.szSendBuffer = (char*)dbei.pBlob; MEVENT hNewEvent = db_event_add(job.hContact, &dbei); if (m_pContainer) if (!nen_options.iNoSounds && !(m_pContainer->dwFlags & CNT_NOSOUND)) SkinPlaySound("SendMsg"); M.BroadcastMessage(DM_APPENDMCEVENT, job.hContact, LPARAM(hNewEvent)); job.hSendId = NULL; job.iAcksNeeded--; if (job.iAcksNeeded == 0) { // everything sent clearJob(iFound); if (dat) { KillTimer(dat->hwnd, TIMERID_MSGSEND + iFound); dat->iOpenJobs--; } m_currentIndex--; } if (dat) { checkQueue(dat); int iNextFailed = findNextFailed(dat); if (iNextFailed >= 0 && !(dat->dwFlags & MWF_ERRORSTATE)) handleError(dat, iNextFailed); else { if (M.GetByte("AutoClose", 0)) { if (M.GetByte("adv_AutoClose_2", 0)) SendMessage(dat->hwnd, WM_CLOSE, 0, 1); else SendMessage(dat->pContainer->hwnd, WM_CLOSE, 0, 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; }