Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1038 lines
30 KiB

/////////////////////////////////////////////////////////////////////////////
// Copyright (C) 1993-1996 Microsoft Corporation. All Rights Reserved.
//
// MODULE: Order.cpp
//
// PURPOSE: Implements the order articles dialog. Allows the user to
// sequence multipart articles for decoding.
//
#include "pch.hxx"
#include "storutil.h"
#include "mimeole.h"
#include "mimeutil.h"
#include "resource.h"
#include "shlwapip.h"
#include "thormsgs.h"
#include "order.h"
#include "error.h"
#include "demand.h"
#include "imsgsite.h"
#include "note.h"
#include "xputil.h"
// NOTE - The drag list control requires us to register a message and use that
// for notifications sent from the list to the dialog. This message
// is defined only for this dialog. -- SteveSer.
static UINT g_mDragList = 0;
#define CND_GETNEXTARTICLE (WM_USER + 101)
#define CND_OPENNOTE (WM_USER + 102)
#define CND_MESSAGEAVAIL (WM_USER + 103)
CCombineAndDecode::CCombineAndDecode()
{
m_cRef = 1;
m_hwndParent = NULL;
m_pTable = NULL;
m_rgRows = NULL;
m_cRows = 0;
m_pszBuffer = NULL;
m_iItemToMove = -1;
m_cLinesTotal = 0;
m_cCurrentLine = 0;
m_cPrevLine = 0;
m_dwCurrentArt = 0;
m_pMsgParts = NULL;
m_pCancel = 0;
m_hTimeout = 0;
m_hwndDlg = 0;
}
CCombineAndDecode::~CCombineAndDecode()
{
SafeRelease(m_pTable);
SafeRelease(m_pMsgParts);
SafeRelease(m_pCancel);
CallbackCloseTimeout(&m_hTimeout);
}
HRESULT STDMETHODCALLTYPE CCombineAndDecode::QueryInterface(REFIID riid, void **ppvObj)
{
if (IsEqualIID(riid, IID_IUnknown))
*ppvObj = (void*) (IUnknown *)(IStoreCallback *)this;
else if (IsEqualIID(riid, IID_IStoreCallback))
*ppvObj = (void*) (IStoreCallback *) this;
else
{
*ppvObj = NULL;
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
ULONG STDMETHODCALLTYPE CCombineAndDecode::AddRef()
{
return ++m_cRef;
}
ULONG STDMETHODCALLTYPE CCombineAndDecode::Release()
{
if (--m_cRef == 0)
{
delete this;
return 0;
}
return m_cRef;
}
//
// FUNCTION: CCombineAndDecode::Start()
//
// PURPOSE:
//
// PARAMETERS:
// [in] hwndParent
// [in] pTable
// [in] rgRows
// [in] cRows
//
// RETURN VALUE:
// HRESULT
//
HRESULT CCombineAndDecode::Start(HWND hwndParent, IMessageTable *pTable,
ROWINDEX *rgRows, DWORD cRows, FOLDERID idFolder)
{
int nResult = -1;
TraceCall("CCombineAndDecode::Start");
// Verify we got everything we needed
if (!IsWindow(hwndParent) || !pTable || !rgRows || 0 == cRows)
return (E_INVALIDARG);
// Keep these for later
m_hwndParent = hwndParent;
m_pTable = pTable;
m_pTable->AddRef();
m_rgRows = rgRows;
m_cRows = cRows;
m_idFolder = idFolder;
// Create the order dialog and get to work
nResult = (int) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddOrderMessages),
m_hwndParent, OrderDlgProc, (LPARAM) this);
// If the user pressed OK, then we go ahead and decode
if (nResult == IDOK)
{
DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddCombineAndDecode), m_hwndParent,
CombineDlgProc, (LPARAM) this);
}
return (S_OK);
}
//
// FUNCTION: CCombineAndDecode::OrderDlgProc()
//
// PURPOSE: Public callback function for the message ordering dialog proc
//
INT_PTR CALLBACK CCombineAndDecode::OrderDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
CCombineAndDecode *pThis;
if (uMsg == WM_INITDIALOG)
{
SetWindowLongPtr(hwnd, DWLP_USER, lParam);
pThis = (CCombineAndDecode *) lParam;
}
else
pThis = (CCombineAndDecode *) GetWindowLongPtr(hwnd, DWLP_USER);
if (pThis)
return (pThis->_OrderDlgProc(hwnd, uMsg, wParam, lParam));
return (FALSE);
}
//
// FUNCTION: CCombineAndDecode::_OrderDlgProc()
//
// PURPOSE: Private callback function for the message ordering dialog proc
//
INT_PTR CALLBACK CCombineAndDecode::_OrderDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_INITDIALOG:
return (BOOL) HANDLE_WM_INITDIALOG(hwnd, wParam, lParam, _Order_OnInitDialog);
case WM_COMMAND:
HANDLE_WM_COMMAND(hwnd, wParam, lParam, _Order_OnCommand);
return (TRUE);
case WM_CLOSE:
HANDLE_WM_CLOSE(hwnd, wParam, lParam, _Order_OnClose);
return (TRUE);
default:
if (uMsg == g_mDragList)
return (_Order_OnDragList(hwnd, (int) wParam, (DRAGLISTINFO*) lParam));
}
return (FALSE);
}
//
// FUNCTION: CCombineAndDecode::_Order_OnInitDialog()
//
// PURPOSE: Initializes the order dialog by filling in the message headers.
//
BOOL CCombineAndDecode::_Order_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam)
{
HWND hwndList;
HDC hdc;
SIZE size;
int cx = 0;
HFONT hfontOld;
HFONT hfont;
int cxScrollBar;
LPMESSAGEINFO pInfo;
int iItem;
LPSTR pszSubject = NULL;
CHAR szNoSubject[CCHMAX_STRINGRES] = "";
CenterDialog(hwnd);
// Get some drawing information about the ListBox so we can set the scroll
// bar width correctly later.
hwndList = GetDlgItem(hwnd, IDC_MESSAGE_LIST);
hdc = GetDC(hwndList);
hfont = (HFONT) SendMessage(hwndList, WM_GETFONT, 0, 0L);
hfontOld = (HFONT) SelectObject(hdc, hfont);
cxScrollBar = GetSystemMetrics(SM_CXHTHUMB);
// Fill the listbox with the article subjects
for (DWORD i = 0; i < m_cRows; i++)
{
// Get the message header from the table
if (SUCCEEDED(m_pTable->GetRow(m_rgRows[i], &pInfo)))
{
if(pInfo->pszSubject)
pszSubject = pInfo->pszSubject;
else
{
LoadString(g_hLocRes, idsEmptySubjectRO, szNoSubject, sizeof(szNoSubject));
pszSubject = szNoSubject;
}
Assert(pszSubject);
// Figure out which string is widest before inserting
GetTextExtentPoint32(hdc, pszSubject, lstrlen(pszSubject), &size);
if (cx < size.cx)
cx = size.cx;
// Add the string
iItem = (int) SendMessage(hwndList, LB_ADDSTRING, 0, (LPARAM) pszSubject);
if (LB_ERR != iItem)
SendMessage(hwndList, LB_SETITEMDATA, iItem, (LPARAM) m_rgRows[i]);
// Free the memory
m_pTable->ReleaseRow(pInfo);
}
}
// Clean up the GDI objects
SelectObject(hdc, hfontOld);
ReleaseDC(hwndList, hdc);
// Make sure there are scroll bars if needed.
SendMessage(hwndList, LB_SETHORIZONTALEXTENT, cx + cxScrollBar, 0L);
// Make the list box a drag list box
if (MakeDragList(hwndList))
g_mDragList = RegisterWindowMessage(DRAGLISTMSGSTRING);
SendMessage(hwndList, LB_SETCURSEL, 0, 0);
return (FALSE);
}
//
// FUNCTION: CCombineAndDecode::_Order_OnCommand()
//
// PURPOSE: Handle the commands generated by the buttons on the dialog.
//
void CCombineAndDecode::_Order_OnCommand(HWND hwnd, int id, HWND hwndCtl,
UINT codeNotify)
{
HWND hwndList = GetDlgItem(hwnd, IDC_MESSAGE_LIST);
switch (id)
{
case IDOK:
{
// Get the info we need out of the ListBox
for (DWORD i = 0; i < m_cRows; i++)
{
m_rgRows[i] = (ROWINDEX) ListBox_GetItemData(hwndList, i);
}
EndDialog(hwnd, 1);
break;
}
case IDCANCEL:
EndDialog(hwnd, 0);
break;
case IDC_MOVE_UP:
case IDC_MOVE_DOWN:
{
LPTSTR pszBuffer;
DWORD cch;
UINT index;
LPARAM lpData;
// Get the currently selected item
index = (DWORD) SendMessage(hwndList, LB_GETCURSEL, 0, 0);
// If nothing is selected the listbox returns LB_ERR
if (index == LB_ERR)
return;
// Check the bounds
if ((id == IDC_MOVE_UP && index == 0) ||
(id == IDC_MOVE_DOWN && (int) index == (ListBox_GetCount(hwndList) - 1)))
return;
// Move the item in the listbox
cch = (DWORD) SendMessage(hwndList, LB_GETTEXTLEN, index, 0L);
if (!MemAlloc((LPVOID*) &pszBuffer, sizeof(TCHAR) * (cch + 1)))
return;
// Get the source string and data
SendMessage(hwndList, LB_GETTEXT, index, (LPARAM) pszBuffer);
lpData = SendMessage(hwndList, LB_GETITEMDATA, index, 0);
// Delete the source
SendMessage(hwndList, LB_DELETESTRING, index, 0L);
// Insert the new one
if (id == IDC_MOVE_UP)
index--;
else
index++;
SendMessage(hwndList, LB_INSERTSTRING, index, (LPARAM) pszBuffer);
SendMessage(hwndList, LB_SETITEMDATA, index, lpData);
SendMessage(hwndList, LB_SETCURSEL, index, 0L);
MemFree(pszBuffer);
break;
}
}
}
//
// FUNCTION: Order_OnDragList()
//
// PURPOSE: Handles the drag list notifications which reorder the messages.
//
// PARAMETERS:
// hwnd - handle of the parent of the drag list
// idCtl - identifer of the drag list sending the notification
// lpdli - pointer to a DRAGLISTINFO struct with info about the
// notification.
//
// RETURN VALUE:
// Dependant on the notification.
//
// COMMENTS:
// This function uses the SetDlgMsgResult() macro defined in WINDOWSX.H to
// set the return value for each message since the parent window is a
// dialog.
//
LRESULT CCombineAndDecode::_Order_OnDragList(HWND hwnd, int idCtl, LPDRAGLISTINFO lpdli)
{
UINT iItem;
UINT cch;
Assert(((int) m_iItemToMove) >= 0);
switch (lpdli->uNotification)
{
// The user has started dragging one of the list control's items
case DL_BEGINDRAG:
{
// Find out which item is being dragged
m_iItemToMove = LBItemFromPt(lpdli->hWnd, lpdli->ptCursor, TRUE);
// Allocate a buffer for the string
Assert(m_pszBuffer == NULL);
cch = ListBox_GetTextLen(lpdli->hWnd, m_iItemToMove) + 1;
MemAlloc((LPVOID *) &m_pszBuffer, cch);
SendMessage(lpdli->hWnd, LB_GETTEXT, m_iItemToMove, (LPARAM) m_pszBuffer);
m_lpData = SendMessage(lpdli->hWnd, LB_GETITEMDATA, m_iItemToMove, 0);
DOUT("DL_BEGINDRAG: iItem = %d, text = %100s\r\n", m_iItemToMove, m_pszBuffer);
// Draw the insert icon
DrawInsert(hwnd, lpdli->hWnd, m_iItemToMove);
// Set the return value to allow the drag to contine
SetDlgMsgResult(hwnd, g_mDragList, TRUE);
return TRUE;
}
case DL_CANCELDRAG:
{
DOUT("DL_CANCELDRAG\r\n");
DrawInsert(hwnd, lpdli->hWnd, -1);
SafeMemFree(m_pszBuffer);
return 0; // Return value is ignored
}
// The user is in the process of dragging, update the position
// and move the insert icon
case DL_DRAGGING:
{
// Find out where the cursor is now
iItem = LBItemFromPt(lpdli->hWnd, lpdli->ptCursor, TRUE);
// Dump some debug info
DOUT("DL_DRAGGING: iItem = %d\r\n", iItem);
// Update the insert icon position
DrawInsert(hwnd, lpdli->hWnd, iItem);
// If the cursor is over a valid position set the cursor to
// DL_MOVECURSOR, otherwise use the DL_STOPCURSOR
if (-1 != iItem)
SetDlgMsgResult(hwnd, g_mDragList, DL_MOVECURSOR);
else
SetDlgMsgResult(hwnd, g_mDragList, DL_STOPCURSOR);
return (LRESULT) TRUE;
}
// The user has dropped the item somewhere, if valid update it's
// position
case DL_DROPPED:
{
// Where are we now.
iItem = LBItemFromPt(lpdli->hWnd, lpdli->ptCursor, TRUE);
DOUT("DL_DROPPED: iItem = %d\r\n", iItem);
// If the drop was somewhere valid
if (iItem != -1)
{
// Remove the insert icon
DrawInsert(hwnd, lpdli->hWnd, -1);
// Move the item in the listbox
if (m_iItemToMove != iItem)
{
SendMessage(lpdli->hWnd, LB_DELETESTRING, m_iItemToMove, 0L);
SendMessage(lpdli->hWnd, LB_INSERTSTRING, iItem, (LPARAM) m_pszBuffer);
SendMessage(lpdli->hWnd, LB_SETITEMDATA, iItem, m_lpData);
SendMessage(lpdli->hWnd, LB_SETCURSEL, iItem, 0L);
}
}
m_iItemToMove = (UINT) -1;
SafeMemFree(m_pszBuffer);
m_lpData = -1;
// Set the return value to reset the cursor
SetDlgMsgResult(hwnd, g_mDragList, DL_CURSORSET);
return 0;
}
}
return TRUE;
}
//
// FUNCTION: CCombineAndDecode::_Order_OnClose()
//
// PURPOSE: This get's called when the user clicks on the "x" button in the
// title bar.
//
void CCombineAndDecode::_Order_OnClose(HWND hwnd)
{
SendMessage(hwnd, WM_COMMAND, IDCANCEL, 0L);
}
/////////////////////////////////////////////////////////////////////////////
//
// Combine and Decode Progress dialog
//
/////////////////////////////////////////////////////////////////////////////
INT_PTR CALLBACK CCombineAndDecode::CombineDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
CCombineAndDecode *pThis;
if (uMsg == WM_INITDIALOG)
{
SetWindowLongPtr(hwnd, DWLP_USER, lParam);
pThis = (CCombineAndDecode *) lParam;
}
else
pThis = (CCombineAndDecode *) GetWindowLongPtr(hwnd, DWLP_USER);
if (pThis)
return (pThis->_CombineDlgProc(hwnd, uMsg, wParam, lParam));
return (FALSE);
}
INT_PTR CALLBACK CCombineAndDecode::_CombineDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_INITDIALOG:
return (BOOL) HANDLE_WM_INITDIALOG(hwnd, wParam, lParam, _Combine_OnInitDialog);
case WM_COMMAND:
HANDLE_WM_COMMAND(hwnd, wParam, lParam, _Combine_OnCommand);
return (TRUE);
case WM_DESTROY:
HANDLE_WM_CLOSE(hwnd, wParam, lParam, _Combine_OnDestroy);
return (TRUE);
case CND_GETNEXTARTICLE:
_Combine_GetNextArticle(hwnd);
return (TRUE);
case CND_OPENNOTE:
_Combine_OpenNote(hwnd);
return (TRUE);
case CND_MESSAGEAVAIL:
_Combine_OnMsgAvail(m_hwndDlg);
return (TRUE);
}
return (FALSE);
}
//
// FUNCTION: CCombineAndDecode::_Combine_OnInitDialog()
//
// PURPOSE: Initializes the progress dialog by figuring out how many lines
// will be downloaded, etc. To finish, we post a message to start
// the first message downloading.
//
BOOL CCombineAndDecode::_Combine_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam)
{
HRESULT hr = S_OK;
LPMESSAGEINFO pInfo;
m_hwndDlg = hwnd;
// Create the CNewsMsgList for Opie's groovy combiner
hr = MimeOleCreateMessageParts(&m_pMsgParts);
if (FAILED(hr))
{
EndDialog(hwnd, 0);
return (FALSE);
}
// Get a sum of the lines we need to download for the total messages
m_cLinesTotal = 0;
for (DWORD i = 0; i < m_cRows; i++)
{
// Get the message header from the table
if (SUCCEEDED(m_pTable->GetRow(m_rgRows[i], &pInfo)))
{
m_cLinesTotal += pInfo->cbMessage;
m_pTable->ReleaseRow(pInfo);
}
}
// Set the initial state of the progress bar
SendDlgItemMessage(hwnd, IDC_DOWNLOAD_PROG, PBM_SETRANGE, 0, MAKELONG(0, 100));
SendDlgItemMessage(hwnd, IDC_DOWNLOAD_PROG, PBM_SETPOS, 0, 0);
// Set up the animation
if (Animate_Open(GetDlgItem(hwnd, IDC_DOWNLOAD_AVI), MAKEINTRESOURCE(idanDecode)))
{
Animate_Play(GetDlgItem(hwnd, IDC_DOWNLOAD_AVI), 0, -1, -1);
}
// Start the download
m_dwCurrentArt = 0;
m_cCurrentLine = 0;
PostMessage(hwnd, CND_GETNEXTARTICLE, 0, 0L);
CenterDialog(hwnd);
ShowWindow(hwnd, SW_SHOW);
return (TRUE);
}
//
// FUNCTION: CCombineAndDecode::_Combine_OnCommand()
//
// PURPOSE: When the user hit's the Cancel button, we in turn tell the store
// to stop downloading.
//
void CCombineAndDecode::_Combine_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
if (id == IDCANCEL && m_pCancel)
m_pCancel->Cancel(CT_CANCEL);
}
void CCombineAndDecode::_Combine_OnDestroy(HWND hwnd)
{
}
//
// FUNCTION: CCombineAndDecode::_Combine_GetNextArticle()
//
// PURPOSE: Called when we can start downloading another message.
//
void CCombineAndDecode::_Combine_GetNextArticle(HWND hwnd)
{
LPMIMEMESSAGE pMsg = NULL;
LPMESSAGEINFO pInfo;
TCHAR szProg[CCHMAX_STRINGRES];
TCHAR szBuf[CCHMAX_STRINGRES];
HRESULT hr;
if (SUCCEEDED(m_pTable->GetRow(m_rgRows[m_dwCurrentArt], &pInfo)))
{
// Set the progress for the current article
AthLoadString(idsProgDLMessage, szProg, ARRAYSIZE(szProg));
wnsprintf(szBuf, ARRAYSIZE(szBuf), szProg, pInfo->pszSubject);
SetDlgItemText(hwnd, IDC_GENERAL_TEXT, szBuf);
// Reset the line count
m_cPrevLine = 0;
// Check to see if the message is cached
if (!(pInfo->dwFlags & ARF_HASBODY))
{
// Request the message
hr = m_pTable->OpenMessage(m_rgRows[m_dwCurrentArt], 0, &pMsg, (IStoreCallback *) this);
if (FAILED(hr) && hr != E_PENDING)
{
AthMessageBoxW(m_hwndDlg, MAKEINTRESOURCEW(idsAthena), MAKEINTRESOURCEW(idsErrCantCombineNotConnected),
0, MB_OK | MB_ICONSTOP);
EndDialog(m_hwndDlg, 0);
}
}
else
_Combine_OnMsgAvail(hwnd);
if (pMsg)
pMsg->Release();
m_pTable->ReleaseRow(pInfo);
}
}
//
// FUNCTION: CCombineAndDecode::_Combine_OnMsgAvail()
//
// PURPOSE: Called once we've finished downloading an article.
//
void CCombineAndDecode::_Combine_OnMsgAvail(HWND hwnd)
{
LPMIMEMESSAGE pMsg = NULL;
DWORD increment;
TCHAR szProg[CCHMAX_STRINGRES];
HRESULT hr;
// Mark it read
m_pTable->Mark(&(m_rgRows[m_dwCurrentArt]), 1, APPLY_CHILDREN, MARK_MESSAGE_READ, (IStoreCallback *) this);
// Get the message now that it's available and add it to the combine list
if (SUCCEEDED(hr = m_pTable->OpenMessage(m_rgRows[m_dwCurrentArt], 0, &pMsg, (IStoreCallback *) this)))
{
// Add this to the pMsgList
m_pMsgParts->AddPart(pMsg);
pMsg->Release();
}
// Update the progress
LPMESSAGEINFO pInfo;
if (SUCCEEDED(m_pTable->GetRow(m_rgRows[m_dwCurrentArt], &pInfo)))
{
increment = pInfo->cbMessage - m_cPrevLine;
m_cCurrentLine += increment;
m_pTable->ReleaseRow(pInfo);
}
if (m_cLinesTotal)
{
increment = m_cCurrentLine * 100 / m_cLinesTotal;
SendDlgItemMessage(hwnd, IDC_DOWNLOAD_PROG, PBM_SETPOS, increment, 0);
}
// Increment the number of messages we've retrieved
m_dwCurrentArt++;
// If there are more to get, go get 'em
if (m_dwCurrentArt < m_cRows)
{
PostMessage(hwnd, CND_GETNEXTARTICLE, 0, 0L);
}
else
{
PostMessage(hwnd, CND_OPENNOTE, 0, 0);
}
}
void CCombineAndDecode::_Combine_OpenNote(HWND hwnd)
{
LPMIMEMESSAGE pMsgComb;
LPMIMEMESSAGE pMsg = NULL;
DWORD increment;
TCHAR szProg[CCHMAX_STRINGRES];
HRESULT hr;
// Update the progress
AthLoadString(idsProgCombiningMsgs, szProg, ARRAYSIZE(szProg));
SetDlgItemText(hwnd, IDC_GENERAL_TEXT, szProg);
SetDlgItemText(hwnd, IDC_SPECIFIC_TEXT, TEXT(""));
// All the articles are downloaded. Merge the message list
// and open the note.
hr = m_pMsgParts->CombineParts(&pMsgComb);
if (FAILED(hr))
{
AthMessageBoxW(hwnd, MAKEINTRESOURCEW(idsAthenaNews),
MAKEINTRESOURCEW(idsGenericError), 0, MB_OK | MB_ICONSTOP);
}
else
{
FOLDERINFO info;
INIT_MSGSITE_STRUCT initStruct;
DWORD dwCreateFlags = 0;
if (SUCCEEDED(g_pStore->GetFolderInfo(m_idFolder, &info)))
{
// If this is a find folder, we need to put the account on the message
if (!!(info.dwFlags & FOLDER_FINDRESULTS))
{
FOLDERID id;
if (SUCCEEDED(m_pTable->GetRowFolderId(*m_rgRows, &id)))
{
FOLDERINFO fiServer = {0};
if (SUCCEEDED(GetFolderServer(id, &fiServer)))
{
HrSetAccount(pMsgComb, fiServer.pszName);
g_pStore->FreeRecord(&fiServer);
}
}
}
g_pStore->FreeRecord(&info);
}
// Initialize note struct
initStruct.dwInitType = OEMSIT_MSG;
initStruct.folderID = m_idFolder;
initStruct.pMsg = pMsgComb;
// Decide whether it is news or mail
if (GetFolderType(m_idFolder) == FOLDER_NEWS)
{
FOLDERINFO rServer;
if (SUCCEEDED(GetFolderServer(m_idFolder, &rServer)))
{
HrSetAccount(pMsgComb, rServer.pszAccountId);
g_pStore->FreeRecord(&rServer);
}
dwCreateFlags = OENCF_NEWSFIRST;
}
// Create and Open Note
hr = CreateAndShowNote(OENA_READ, dwCreateFlags, &initStruct, m_hwndParent);
pMsgComb->Release();
}
EndDialog(m_hwndDlg, 0);
}
//
// FUNCTION: CCombineAndDecode::OnBegin()
//
// PURPOSE: Called when the store starts downloading an article.
//
HRESULT CCombineAndDecode::OnBegin(STOREOPERATIONTYPE tyOperation, STOREOPERATIONINFO *pOpInfo, IOperationCancel *pCancel)
{
Assert(tyOperation != SOT_INVALID);
Assert(m_pCancel == NULL);
m_type = tyOperation;
if (pCancel != NULL)
{
m_pCancel = pCancel;
m_pCancel->AddRef();
}
return(S_OK);
}
//
// FUNCTION: CCombineAndDecode::OnProgress()
//
// PURPOSE: Called while the messages are downloading to give us some
// progress.
//
HRESULT STDMETHODCALLTYPE CCombineAndDecode::OnProgress(STOREOPERATIONTYPE tyOperation, DWORD dwCurrent, DWORD dwMax, LPCSTR pszStatus)
{
int increment;
TCHAR szProg[CCHMAX_STRINGRES];
TCHAR szBuf[CCHMAX_STRINGRES];
Assert(m_hwndDlg != NULL);
// Close any timeout dialog, if present
CallbackCloseTimeout(&m_hTimeout);
// Connection progress
if (tyOperation == SOT_CONNECTION_STATUS)
{
Assert(dwCurrent < IXP_LAST);
// Create some lovely status text
int ids = XPUtil_StatusToString((IXPSTATUS) dwCurrent);
AthLoadString(ids, szBuf, ARRAYSIZE(szBuf));
SetDlgItemText(m_hwndDlg, IDC_GENERAL_TEXT, szBuf);
}
AthLoadString(idsProgDLGetLines, szProg, ARRAYSIZE(szProg));
wnsprintf(szBuf, ARRAYSIZE(szBuf), szProg, dwCurrent, dwMax);
SetDlgItemText(m_hwndDlg, IDC_SPECIFIC_TEXT, szBuf);
increment = dwCurrent - m_cPrevLine;
m_cCurrentLine += increment;
m_cPrevLine = dwCurrent;
if (m_cLinesTotal)
{
increment = m_cCurrentLine * 100 / m_cLinesTotal;
SendDlgItemMessage(m_hwndDlg, IDC_DOWNLOAD_PROG, PBM_SETPOS, increment, 0);
}
return(S_OK);
}
//
// FUNCTION: CCombineAndDecode::OnTimeout()
//
// PURPOSE: If a timeout occurs, we call through to the default timeout handler.
//
HRESULT STDMETHODCALLTYPE CCombineAndDecode::OnTimeout(LPINETSERVER pServer, LPDWORD pdwTimeout, IXPTYPE ixpServerType)
{
// Display a timeout dialog
return CallbackOnTimeout(pServer, ixpServerType, *pdwTimeout, (ITimeoutCallback *)this, &m_hTimeout);
}
//
// FUNCTION: CCombineAndDecode::OnTimeoutResponse()
//
// PURPOSE: Called when the user responds to a timeout dialog.
//
HRESULT STDMETHODCALLTYPE CCombineAndDecode::OnTimeoutResponse(TIMEOUTRESPONSE eResponse)
{
// Call into general timeout response utility
return CallbackOnTimeoutResponse(eResponse, m_pCancel, &m_hTimeout);
}
//
// FUNCTION: CCombineAndDecode::CanConnect()
//
// PURPOSE: Called if the store needs to connect to download the requested
// messages. We just call through to the default handlers.
//
HRESULT STDMETHODCALLTYPE CCombineAndDecode::CanConnect(LPCSTR pszAccountId, DWORD dwFlags)
{
HWND hwndParent;
DWORD dwReserved = 0;
GetParentWindow(dwReserved, &hwndParent);
return CallbackCanConnect(pszAccountId, hwndParent, TRUE);
}
//
// FUNCTION: CCombineAndDecode::OnLogonPrompt()
//
// PURPOSE: If the user needs to logon, we present them with the default
// logon UI.
//
HRESULT STDMETHODCALLTYPE CCombineAndDecode::OnLogonPrompt(LPINETSERVER pServer, IXPTYPE ixpServerType)
{
// Close any timeout dialog, if present
CallbackCloseTimeout(&m_hTimeout);
// Call into general OnLogonPrompt Utility
return CallbackOnLogonPrompt(m_hwndDlg, pServer, ixpServerType);
}
//
// FUNCTION: CCombineAndDecode::OnComplete()
//
// PURPOSE: When we finish downloading a message, this get's hit. We add
// this message to the list for the combiner and then request the
// next message.
//
HRESULT STDMETHODCALLTYPE CCombineAndDecode::OnComplete(STOREOPERATIONTYPE tyOperation, HRESULT hrComplete, LPSTOREOPERATIONINFO pOpInfo, LPSTOREERROR pErrorInfo)
{
Assert(m_hwndDlg != NULL);
AssertSz(m_type != SOT_INVALID, "somebody isn't calling OnBegin");
// Close any timeout dialog, if present
CallbackCloseTimeout(&m_hTimeout);
if (m_type != tyOperation)
return(S_OK);
if (m_pCancel != NULL)
{
m_pCancel->Release();
m_pCancel = NULL;
}
// If error occurred, display the error
if (FAILED(hrComplete))
{
// Call into my swanky utility
CallbackDisplayError(m_hwndDlg, hrComplete, pErrorInfo);
EndDialog(m_hwndDlg, 0);
}
else
{
if (tyOperation == SOT_GET_MESSAGE)
PostMessage(m_hwndDlg, CND_MESSAGEAVAIL, 0, 0);
}
return(S_OK);
}
//
// FUNCTION: CCombineAndDecode::OnPrompt()
//
// PURPOSE: Last time I checked, this was SSL related goo.
//
HRESULT STDMETHODCALLTYPE CCombineAndDecode::OnPrompt(HRESULT hrError, LPCTSTR pszText, LPCTSTR pszCaption, UINT uType, INT *piUserResponse)
{
// Close any timeout dialog, if present
CallbackCloseTimeout(&m_hTimeout);
// Call into my swanky utility
return CallbackOnPrompt(m_hwndDlg, hrError, pszText, pszCaption, uType, piUserResponse);
}
//
// FUNCTION: CCombineAndDecode::GetParentWindow()
//
// PURPOSE: Called if the store needs to show UI. We return our dialog
// window handle.
//
HRESULT STDMETHODCALLTYPE CCombineAndDecode::GetParentWindow(DWORD dwReserved, HWND *phwndParent)
{
Assert(m_hwndDlg != NULL);
*phwndParent = m_hwndDlg;
return(S_OK);
}
#if 0
BOOL CALLBACK CombineAndDecodeProg(HWND hwnd, UINT uMsg, WPARAM wParam,
LPARAM lParam)
{
PORDERPARAMS pop = (PORDERPARAMS) GetWindowLongPtr(hwnd, DWLP_USER);
TCHAR szProg[CCHMAX_STRINGRES];
TCHAR szBuf[CCHMAX_STRINGRES];
LPMIMEMESSAGE pMsg=0;
DWORD increment;
HRESULT hr;
switch (uMsg)
{
case IMC_BODYAVAIL:
{
LPMIMEMESSAGE pMsg = NULL;
BOOL fCached = FALSE;
Assert(pop->pGroup);
if (SUCCEEDED(wParam) && SUCCEEDED(pop->pGroup->GetArticle(pop->rgpMsgs[pop->dwCurrentArt], &pMsg, hwnd, &fCached, FALSE, GETMSG_INSECURE)) && fCached)
{
Assert(pMsg);
Order_OnMsgAvail(hwnd, pop, pMsg);
}
else
{
if ((HRESULT)wParam != hrUserCancel)
AthMessageBoxW(hwnd, MAKEINTRESOURCEW(idsAthenaNews),
MAKEINTRESOURCEW(idsErrNewsCantOpen), 0, MB_OK | MB_ICONSTOP);
PostMessage(hwnd, WM_CLOSE, 0, 0);
}
if (pMsg)
pMsg->Release();
return (TRUE);
}
}
return (FALSE);
}
#endif