gecko-dev/cmd/winfe/msgview.cpp
1998-06-22 21:19:46 +00:00

970 lines
24 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "stdafx.h"
#include "msgcom.h"
#include "mailfrm.h"
#include "msgview.h"
#include "fegui.h"
#include "shcut.h"
#include "cxsave.h"
#include "thrdfrm.h"
#include "rdfglobal.h"
#ifndef _AFXDLL
#undef new
#endif
IMPLEMENT_DYNCREATE(CMessageBodyView, CNetscapeView)
#ifndef _AFXDLL
#define new DEBUG_NEW
#endif
#ifdef _WIN32
/////////////////////////////////////////////////////////////////////
//
// CAttachmentDataSource
//
// DataSource for attachment download for drag-and-drop
//
class CAttachmentDataSource: public COleDataSource
{
protected:
CString m_csURL, m_csName;
public:
CAttachmentDataSource(LPCTSTR lpszURL, LPCTSTR lpszName);
virtual BOOL OnRenderGlobalData(LPFORMATETC lpFormatEtc, HGLOBAL* phGlobal);
virtual BOOL OnRenderFileData(LPFORMATETC lpFormatEtc, CFile* pFile);
virtual BOOL OnRenderData(LPFORMATETC lpFormatEtc, LPSTGMEDIUM lpStgMedium);
};
CAttachmentDataSource::CAttachmentDataSource(LPCTSTR lpszURL, LPCSTR lpszName)
{
m_csURL = lpszURL;
m_csName = lpszName;
}
BOOL CAttachmentDataSource::OnRenderGlobalData(LPFORMATETC lpFormatEtc, HGLOBAL* phGlobal)
{
BOOL bRes = FALSE;
if (sysInfo.m_bWinNT && !*phGlobal)
{
bRes = CSaveCX::SaveToGlobal(phGlobal, m_csURL, m_csName);
}
return bRes;
}
BOOL CAttachmentDataSource::OnRenderFileData(LPFORMATETC lpFormatEtc, CFile *pFile)
{
BOOL bRes = FALSE;
if (pFile) {
bRes = CSaveCX::SaveToFile(pFile, m_csURL, m_csName);
}
return bRes;
}
BOOL CAttachmentDataSource::OnRenderData(LPFORMATETC lpFormatEtc, LPSTGMEDIUM
lpStgMedium)
{
if (lpFormatEtc->tymed & TYMED_ISTREAM)
{
COleStreamFile file;
if (lpStgMedium->tymed == TYMED_ISTREAM)
{
ASSERT(lpStgMedium->pstm != NULL);
file.Attach(lpStgMedium->pstm);
}
else
{
if (!file.CreateMemoryStream())
AfxThrowMemoryException();
}
// get data into the stream
if (OnRenderFileData(lpFormatEtc, &file))
{
lpStgMedium->tymed = TYMED_ISTREAM;
lpStgMedium->pstm = file.Detach();
return TRUE;
}
if (lpStgMedium->tymed == TYMED_ISTREAM)
file.Detach();
}
return COleDataSource::OnRenderData(lpFormatEtc, lpStgMedium);
}
#endif
/////////////////////////////////////////////////////////////////////
//
// CAttachmentTray
//
CAttachmentTray::CAttachmentTray()
{
m_hFont = 0;
SetCSID(CIntlWin::GetSystemLocaleCsid(), FALSE);
::SetRectEmpty(&m_rcClient);
m_pAttachmentData = NULL;
m_nAttachmentCount = 0;
m_aAttachAux = NULL;
m_sizeSpacing.cx = ::GetSystemMetrics(SM_CXICONSPACING);
m_sizeSpacing.cy = ::GetSystemMetrics(SM_CYICONSPACING);
m_sizeIcon.cx = ::GetSystemMetrics(SM_CXICON);
m_sizeIcon.cy = ::GetSystemMetrics(SM_CYICON);
m_ptOrigin.x = 0;
m_ptOrigin.y = 0;
m_sizeMax.cx = 0;
m_sizeMax.cy = 0;
}
CAttachmentTray::~CAttachmentTray()
{
for (int i = 0; i < m_nAttachmentCount; i++)
#ifdef _WIN32
ImageList_Destroy(m_aAttachAux[i].hImage);
#else
DestroyIcon(m_aAttachAux[i].hIcon);
#endif
delete [] m_aAttachAux;
theApp.ReleaseAppFont(m_hFont);
}
HICON CAttachmentTray::DredgeUpIcon(char *name)
{
// Get the default icon
HICON res = ::LoadIcon(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_FILE));
#ifdef _WIN32
if (sysInfo.m_bWin4) {
// Do we have a name?
if (name) {
// Dig out the extension
char *pszExt = strrchr(name, '.');
// Did we get an extension?
if (pszExt) {
// Look up the file type
_TCHAR szBuf[32];
LONG cbBuf = 32;
LONG lres = ::RegQueryValue( HKEY_CLASSES_ROOT, pszExt, szBuf, &cbBuf );
// Did we find a file type?
if (lres == ERROR_SUCCESS) {
// Figure out the default icon path
_TCHAR szIconPath[_MAX_PATH];
_TCHAR szRegKey[_MAX_PATH];
LONG cbIconPath = _MAX_PATH;
_tcscpy(szRegKey, szBuf);
_tcscat(szRegKey, _T("\\DefaultIcon"));
lres = ::RegQueryValue( HKEY_CLASSES_ROOT, szRegKey, szIconPath, &cbIconPath );
// Did we get an icon path
if (lres == ERROR_SUCCESS) {
// Split up the path given to us
_TCHAR *pszPath = _tcstok(szIconPath, ",");
_TCHAR *pszIndex = _tcstok(NULL, ",");
UINT nIndex = pszIndex ? _ttoi(pszIndex) : 0;
// Go get the icon
HICON resIcon = ::ExtractIcon(AfxGetInstanceHandle(), pszPath, nIndex);
if (resIcon && (int) resIcon != 1) {
res = resIcon;
}
}
}
}
}
}
#endif
return res;
}
void CAttachmentTray::SetAttachments(int nAttachmentCount, MSG_AttachmentData *pAttachmentData)
{
// Clean up old images
if (nAttachmentCount < m_nAttachmentCount) {
for (int i = 0; i < m_nAttachmentCount; i++)
#ifdef _WIN32
ImageList_Destroy(m_aAttachAux[i].hImage);
#else
DestroyIcon(m_aAttachAux[i].hIcon);
#endif
delete [] m_aAttachAux;
m_aAttachAux = NULL;
m_nAttachmentCount = 0;
}
AttachAux *aTemp = nAttachmentCount > 0 ? new AttachAux[nAttachmentCount] : NULL;
if (nAttachmentCount > 0) {
int i = 0;
while (i < nAttachmentCount) {
if (i < m_nAttachmentCount) {
aTemp[i] = m_aAttachAux[i];
} else {
aTemp[i].bSelected = FALSE;
#ifdef _WIN32
aTemp[i].hImage = ImageList_Create(m_sizeIcon.cx, m_sizeIcon.cy, ILC_MASK, 1, 1);
ImageList_AddIcon(aTemp[i].hImage, DredgeUpIcon(pAttachmentData[i].real_name));
#else
aTemp[i].hIcon = DredgeUpIcon(pAttachmentData[i].real_name);
#endif
aTemp[i].ptPos.x = 0;
aTemp[i].ptPos.y = 0;
}
i++;
}
}
delete [] m_aAttachAux;
m_aAttachAux = aTemp;
m_nAttachmentCount = nAttachmentCount;
m_pAttachmentData = pAttachmentData;
Layout();
UpdateWindow();
}
void CAttachmentTray::Layout()
{
int x = 0;
int y = 0;
for (int i = 0; i < m_nAttachmentCount; i++) {
m_aAttachAux[i].ptPos.x = x;
m_aAttachAux[i].ptPos.y = y;
m_sizeMax.cx = MAX(x + m_sizeSpacing.cx, m_sizeMax.cy);
m_sizeMax.cy = MAX(y + m_sizeSpacing.cy, m_sizeMax.cy);
x += m_sizeSpacing.cx;
if ( (x + m_sizeSpacing.cx) > m_rcClient.right ) {
x = 0;
y += m_sizeSpacing.cy;
}
}
if (m_sizeMax.cy > m_rcClient.bottom) {
ShowScrollBar(SB_VERT, TRUE);
#ifdef WIN32
SCROLLINFO ScrollInfo;
ScrollInfo.cbSize = sizeof(SCROLLINFO);
ScrollInfo.fMask = SIF_PAGE|SIF_RANGE|SIF_POS;
ScrollInfo.nMin = 0;
ScrollInfo.nMax = m_sizeMax.cy;
ScrollInfo.nPage = m_sizeSpacing.cy;
ScrollInfo.nPos = m_ptOrigin.y;
SetScrollInfo(SB_VERT, &ScrollInfo, TRUE);
#else
SetScrollPos(SB_VERT, m_ptOrigin.y);
SetScrollRange(SB_VERT, 0, m_sizeMax.cy - m_sizeSpacing.cy + 1, TRUE);
#endif
} else {
ShowScrollBar ( SB_VERT, FALSE );
}
}
BOOL CAttachmentTray::WaitForDrag()
{
BOOL bDrag = FALSE;
POINT pt;
RECT rcDrag;
#ifdef _WIN32
int dx = ::GetSystemMetrics(SM_CXDRAG);
int dy = ::GetSystemMetrics(SM_CYDRAG);
#else
int dx = ::GetSystemMetrics(SM_CXDOUBLECLK);
int dy = ::GetSystemMetrics(SM_CYDOUBLECLK);
#endif
GetCursorPos(&pt);
::SetRect(&rcDrag, pt.x - dx, pt.y - dy, pt.x + dx, pt.y + dy);
SetCapture();
while (!bDrag)
{
// some applications steal capture away at random times
if (CWnd::GetCapture() != this)
break;
// peek for next input message
MSG msg;
if (::PeekMessage(&msg, NULL, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE) ||
::PeekMessage(&msg, NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE))
{
// check for button cancellation (any button down will cancel)
if (msg.message == WM_LBUTTONUP || msg.message == WM_RBUTTONUP ||
msg.message == WM_LBUTTONDOWN || msg.message == WM_RBUTTONDOWN)
break;
// check for keyboard cancellation
if (msg.message == WM_KEYDOWN && msg.wParam == VK_ESCAPE)
break;
// check for drag start transition
bDrag = !::PtInRect(&rcDrag, msg.pt);
}
}
ReleaseCapture();
return bDrag;
}
int CAttachmentTray::Point2Index(POINT pt)
{
int i = 0;
int x = pt.x + m_ptOrigin.x;
int y = pt.y + m_ptOrigin.y;
while (i < m_nAttachmentCount) {
if (x >= m_aAttachAux[i].ptPos.x &&
y >= m_aAttachAux[i].ptPos.y &&
x < (m_aAttachAux[i].ptPos.x + m_sizeSpacing.cx) &&
y < (m_aAttachAux[i].ptPos.y + m_sizeSpacing.cy)) {
return i;
}
i++;
}
return -1;
}
void CAttachmentTray::Index2Rect(int idx, RECT &rect)
{
::SetRectEmpty(&rect);
if (idx < 0 || idx >= m_nAttachmentCount)
return;
rect.left = m_aAttachAux[idx].ptPos.x - m_ptOrigin.x;
rect.top = m_aAttachAux[idx].ptPos.y - m_ptOrigin.y;
rect.right = rect.left + m_sizeSpacing.cx;
rect.bottom = rect.top + m_sizeSpacing.cy;
}
void CAttachmentTray::ClearSelection()
{
for (int i = 0; i < m_nAttachmentCount; i++) {
if (m_aAttachAux[i].bSelected) {
m_aAttachAux[i].bSelected = FALSE;
RECT rcInval;
Index2Rect(i, rcInval);
InvalidateRect(&rcInval);
}
}
}
BEGIN_MESSAGE_MAP(CAttachmentTray, CWnd)
ON_WM_PAINT()
ON_WM_SIZE()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONDBLCLK()
ON_WM_RBUTTONDOWN()
ON_WM_VSCROLL()
END_MESSAGE_MAP()
void CAttachmentTray::OnPaint()
{
CPaintDC dc(this);
HBRUSH hbrush = CreateSolidBrush( GetSysColor( COLOR_WINDOW ) );
::FillRect( dc.m_hDC, &dc.m_ps.rcPaint, hbrush );
VERIFY(::DeleteObject(hbrush));
int i = 0;
HFONT hOldFont = (HFONT) dc.SelectObject(m_hFont);
COLORREF oldTextColor = dc.SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
COLORREF oldTextBkColor = dc.SetBkColor(GetSysColor(COLOR_WINDOW));
while (i < m_nAttachmentCount) {
int x = m_aAttachAux[i].ptPos.x - m_ptOrigin.x;
int y = m_aAttachAux[i].ptPos.y - m_ptOrigin.y;
RECT rcInter, rcIcon;
::SetRect(&rcIcon, x, y, x + m_sizeSpacing.cx, y + m_sizeSpacing.cy);
if (::IntersectRect(&rcInter, &rcIcon, &dc.m_ps.rcPaint)) {
RECT rcText;
::SetRect(&rcText, x, y + m_sizeIcon.cy + 8, x+m_sizeSpacing.cx, y + m_sizeSpacing.cy - 2);
int dx = x + (m_sizeSpacing.cx - m_sizeIcon.cx) / 2;
int dy = y + 6;
#ifdef _WIN32
if (m_aAttachAux[i].hImage)
ImageList_Draw(m_aAttachAux[i].hImage, 0, dc.m_hDC, dx, dy,
m_aAttachAux[i].bSelected ? ILD_SELECTED : ILD_NORMAL);
#else
if (m_aAttachAux[i].hIcon) {
dc.DrawIcon(dx, dy, m_aAttachAux[i].hIcon);
}
#endif
if (m_aAttachAux[i].bSelected) {
dc.SetTextColor(GetSysColor(COLOR_HIGHLIGHTTEXT));
dc.SetBkColor(GetSysColor(COLOR_HIGHLIGHT));
} else {
dc.SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
dc.SetBkColor(GetSysColor(COLOR_WINDOW));
}
if (m_pAttachmentData[i].real_name)
WFE_DrawTextEx(0, dc.m_hDC, m_pAttachmentData[i].real_name, -1, &rcText,
DT_CENTER|DT_NOPREFIX, WFE_DT_CROPRIGHT);
}
i++;
}
if (hOldFont)
dc.SelectObject(hOldFont);
dc.SetTextColor(oldTextColor);
dc.SetBkColor(oldTextBkColor);
}
void CAttachmentTray::OnSize( UINT nType, int cx, int cy )
{
if (nType != SIZE_MINIMIZED &&
(m_rcClient.right != cx || m_rcClient.bottom != cy)) {
m_rcClient.right = cx;
m_rcClient.bottom = cy;
Layout();
}
}
#define ABS(x) ((x) < 0 ? (-x) : (x))
void CAttachmentTray::OnLButtonDown( UINT nFlags, CPoint point )
{
int idx = Point2Index(point);
// Ignore if nothing hit, for now
if (idx >= 0) {
RECT rect;
Index2Rect(idx, rect);
BOOL bSel = m_aAttachAux[idx].bSelected;
BOOL bCtrl = ::GetKeyState(VK_CONTROL) & 0x8000;
// If not selected, select immediately
if (!bSel) {
ClearSelection();
m_aAttachAux[idx].bSelected = TRUE;
InvalidateRect(&rect);
UpdateWindow();
}
if (WaitForDrag()) {
CString csUntitled;
csUntitled.LoadString(IDS_UNTITLED);
// Drag Drop Section
const char *name = "";
if (m_pAttachmentData[idx].real_name)
name = m_pAttachmentData[idx].real_name;
else
name = csUntitled;
#ifdef _WIN32
COleDataSource *pDataSource = new CAttachmentDataSource(m_pAttachmentData[idx].url, name);
HGLOBAL hfgd = GlobalAlloc(GMEM_ZEROINIT|GMEM_SHARE,sizeof(FILEGROUPDESCRIPTOR));
LPFILEGROUPDESCRIPTOR lpfgd = (LPFILEGROUPDESCRIPTOR) GlobalLock(hfgd);
// one file in the file descriptor block
lpfgd->cItems = 1;
lpfgd->fgd[0].dwFlags = 0;
strcpy(lpfgd->fgd[0].cFileName, name);
GlobalUnlock (hfgd);
// register the file descriptor clipboard format
UINT cfFileDescriptor = RegisterClipboardFormat(CFSTR_FILEDESCRIPTOR);
// register the clipboard format for file contents
UINT cfFileContents = RegisterClipboardFormat(CFSTR_FILECONTENTS);
pDataSource->CacheGlobalData(cfFileDescriptor, hfgd);
FORMATETC formatEtc;
formatEtc.cfFormat = cfFileContents;
formatEtc.ptd = NULL;
formatEtc.dwAspect = DVASPECT_CONTENT;
formatEtc.lindex = 0;
if (sysInfo.m_bWinNT)
formatEtc.tymed = TYMED_HGLOBAL;
else
formatEtc.tymed = TYMED_ISTREAM;
pDataSource->DelayRenderFileData(cfFileContents, &formatEtc);
#else
COleDataSource *pDataSource = new COleDataSource;
#endif
RDFGLOBAL_DragTitleAndURL(pDataSource, name, m_pAttachmentData[idx].url);
DROPEFFECT res = pDataSource->DoDragDrop( DROPEFFECT_COPY|DROPEFFECT_SCROLL );
pDataSource->Empty();
delete pDataSource;
} else {
if (bSel && bCtrl) {
m_aAttachAux[idx].bSelected = FALSE;
InvalidateRect(&rect);
UpdateWindow();
}
}
}
}
void CAttachmentTray::OnLButtonDblClk( UINT nFlags, CPoint point )
{
int idx = Point2Index(point);
if (idx >= 0) {
GetParentFrame()->PostMessage(WM_COMMAND, (WPARAM) (FIRST_ATTACH_MENU_ID + idx), (LPARAM) 0);
}
}
void CAttachmentTray::OnRButtonDown( UINT nFlags, CPoint point )
{
int idx = Point2Index(point);
// Ignore if nothing hit, for now
if (idx >= 0) {
RECT rect;
Index2Rect(idx, rect);
BOOL bSel = m_aAttachAux[idx].bSelected;
BOOL bCtrl = ::GetKeyState(VK_CONTROL) & 0x8000;
// If not selected, select immediately
if (!bSel) {
ClearSelection();
m_aAttachAux[idx].bSelected = TRUE;
InvalidateRect(&rect);
UpdateWindow();
}
HMENU hMenu = ::CreatePopupMenu();
::AppendMenu(hMenu, MF_STRING, (FIRST_ATTACH_MENU_ID + idx), szLoadString(IDS_POPUP_OPENATTACHMENT));
::AppendMenu(hMenu, MF_STRING, (FIRST_SAVEATTACH_MENU_ID + idx), szLoadString(IDS_POPUP_SAVEATTACHMENTAS));
::AppendMenu(hMenu, MF_SEPARATOR, 0, NULL);
::AppendMenu(hMenu, MF_STRING, (FIRST_ATTACHPROP_MENU_ID + idx), szLoadString(IDS_POPUP_ATTACHMENTPROP));
::ClientToScreen(m_hWnd, &point);
::TrackPopupMenu(hMenu, TPM_LEFTALIGN|TPM_RIGHTBUTTON, point.x, point.y, 0,
GetParentFrame()->GetSafeHwnd(), NULL);
::DestroyMenu(hMenu);
}
}
void CAttachmentTray::OnVScroll( UINT nSBCode, UINT nPos, CScrollBar* pScrollBar )
{
POINT ptOld = m_ptOrigin;
switch (nSBCode) {
case SB_BOTTOM:
m_ptOrigin.y = m_sizeMax.cy - m_sizeSpacing.cy;
break;
case SB_ENDSCROLL:
break;
case SB_LINEDOWN:
m_ptOrigin.y++;
break;
case SB_LINEUP:
m_ptOrigin.y--;
break;
case SB_PAGEDOWN:
m_ptOrigin.y += m_sizeSpacing.cy;
break;
case SB_PAGEUP:
m_ptOrigin.y -= m_sizeSpacing.cy;
break;
case SB_THUMBPOSITION:
case SB_THUMBTRACK:
m_ptOrigin.y = nPos;
break;
case SB_TOP:
m_ptOrigin.y = 0;
break;
}
if (m_ptOrigin.y < 0)
m_ptOrigin.y = 0;
if (m_ptOrigin.y > (m_sizeMax.cy - m_rcClient.bottom))
m_ptOrigin.y = m_sizeMax.cy - m_rcClient.bottom;
int iDiff = ptOld.y - m_ptOrigin.y;
if ( iDiff != 0 )
{
ScrollWindow(0, iDiff );
UpdateWindow();
}
SetScrollPos ( SB_VERT, m_ptOrigin.y );
}
void CAttachmentTray::SetCSID(int16 doc_csid, XP_Bool updateWindow)
{
if (m_hFont)
theApp.ReleaseAppFont(m_hFont);
LOGFONT lf;
memset(&lf,0,sizeof(LOGFONT));
lf.lfPitchAndFamily = FF_SWISS | VARIABLE_PITCH;
lf.lfWeight = FW_NORMAL;
lf.lfCharSet = IntlGetLfCharset(doc_csid);
if (doc_csid == CS_LATIN1)
strcpy(lf.lfFaceName, "MS Sans Serif");
else
strcpy(lf.lfFaceName, IntlGetUIPropFaceName(doc_csid));
lf.lfQuality = PROOF_QUALITY;
lf.lfHeight = -10; // 8 points
m_hFont = theApp.CreateAppFont( lf );
if (updateWindow)
{
Layout();
Invalidate();
UpdateWindow();
}
}
/////////////////////////////////////////////////////////////////////
//
// CMessageBodyView
//
BEGIN_MESSAGE_MAP(CMessageBodyView, CNetscapeView)
ON_WM_SETFOCUS()
ON_WM_KILLFOCUS()
END_MESSAGE_MAP()
void CMessageBodyView::OnSetFocus(CWnd *pOldWnd)
{
CNetscapeView::OnSetFocus(pOldWnd);
CMessageView* pParentView = (CMessageView*)GetParent();
if (pParentView->GetParentFrame()->IsKindOf(RUNTIME_CLASS(C3PaneMailFrame)))
{
pParentView->UpdateFocusFrame();
((C3PaneMailFrame*)pParentView->GetParentFrame())->SetFocusWindow(this);
}
}
void CMessageBodyView::OnKillFocus(CWnd *pOldWnd)
{
CNetscapeView::OnKillFocus(pOldWnd);
CMessageView* pParentView = (CMessageView*)GetParent();
if (pParentView->GetParentFrame()->IsKindOf(RUNTIME_CLASS(C3PaneMailFrame)))
{
((CMessageView*)GetParent())->UpdateFocusFrame();
}
}
/////////////////////////////////////////////////////////////////////
//
// CMessageView
//
CMessageView::CMessageView()
{
m_pViewMessage = NULL;
m_pWndAttachments = NULL;
#ifdef WIN32
m_iAttachmentsHeight = ::GetSystemMetrics(SM_CYICONSPACING) +
::GetSystemMetrics(SM_CYEDGE) * 2;
m_iSliderHeight = ::GetSystemMetrics(SM_CYSIZEFRAME);
#else
m_iAttachmentsHeight = ::GetSystemMetrics(SM_CYICONSPACING) +
::GetSystemMetrics(SM_CYBORDER) * 2;
m_iSliderHeight = ::GetSystemMetrics(SM_CYFRAME);
#endif
m_bAttachmentsVisible = FALSE;
::SetRectEmpty(&m_rcClient);
}
CMessageView::~CMessageView()
{
delete m_pWndAttachments;
}
void CMessageView::SetAttachments(int nAttachmentCount, MSG_AttachmentData *pAttachmentData)
{
m_nAttachmentCount = nAttachmentCount;
ASSERT(m_pWndAttachments);
m_pWndAttachments->SetAttachments(nAttachmentCount, pAttachmentData);
OnSize(0, m_rcClient.right, m_rcClient.bottom);
}
void CMessageView::ShowAttachments(BOOL bShow)
{
if (m_bAttachmentsVisible != bShow) {
m_bAttachmentsVisible = bShow;
OnSize(0, m_rcClient.right, m_rcClient.bottom);
}
}
BOOL CMessageView::AttachmentsVisible() const
{
return m_bAttachmentsVisible;
}
BOOL CMessageView::OnCommand( WPARAM wParam, LPARAM lParam )
{
BOOL res = (BOOL) m_pViewMessage->SendMessage(WM_COMMAND, wParam, lParam);
if (!res)
res = CView::OnCommand(wParam, lParam);
return res;
}
BOOL CMessageView::OnCmdMsg( UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo )
{
BOOL res = m_pViewMessage->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
if (!res)
res = CView::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
return res;
}
void CMessageView::OnDraw(CDC* pDC)
{
HBRUSH hbrushButton = CreateSolidBrush( GetSysColor(COLOR_BTNFACE));
HPEN hpenLight = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_BTNHIGHLIGHT));
HPEN hpenShadow = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_BTNSHADOW));
::FillRect(pDC->m_hDC, &m_rcSlider, hbrushButton);
HPEN hpenOld = (HPEN) SelectObject(pDC->m_hDC, hpenLight);
::MoveToEx(pDC->m_hDC, m_rcSlider.left, m_rcSlider.top, NULL);
::LineTo(pDC->m_hDC, m_rcSlider.right, m_rcSlider.top);
SelectObject(pDC->m_hDC, hpenShadow);
::MoveToEx(pDC->m_hDC, m_rcSlider.left, m_rcSlider.bottom - 1, NULL);
::LineTo(pDC->m_hDC, m_rcSlider.right, m_rcSlider.bottom - 1);
SelectObject(pDC->m_hDC, hpenOld);
VERIFY(::DeleteObject(hbrushButton));
VERIFY(::DeleteObject(hpenLight));
VERIFY(::DeleteObject(hpenShadow));
if (GetParentFrame()->IsKindOf(RUNTIME_CLASS(C3PaneMailFrame)))
{
HBRUSH hBrush = NULL;
CWnd* pFocusWnd = GetFocus();
if (pFocusWnd && (pFocusWnd == this || pFocusWnd == m_pViewMessage ||
pFocusWnd == m_pWndAttachments))
hBrush = ::CreateSolidBrush( RGB(0, 0, 0) );
else
hBrush = ::CreateSolidBrush( GetSysColor( COLOR_WINDOW ) );
RECT clientRect;
GetClientRect(&clientRect);
::FrameRect( pDC->m_hDC, &clientRect, hBrush );
VERIFY(DeleteObject( hBrush ));
}
}
BEGIN_MESSAGE_MAP(CMessageView, CView)
ON_WM_CREATE()
ON_WM_SIZE()
ON_WM_SETCURSOR()
ON_WM_SETFOCUS()
ON_WM_KILLFOCUS()
ON_WM_LBUTTONDOWN()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONUP()
ON_WM_DESTROY()
END_MESSAGE_MAP()
int CMessageView::OnCreate( LPCREATESTRUCT lpCreateStruct )
{
int res = CView::OnCreate(lpCreateStruct);
if (res != -1) {
m_pViewMessage = (CMessageBodyView *) RUNTIME_CLASS(CMessageBodyView)->CreateObject();
#ifdef _WIN32
m_pViewMessage->CreateEx(0, NULL, NULL,
WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS,
0,0,0,0, m_hWnd, (HMENU) IDW_MESSAGE_PANE, lpCreateStruct->lpCreateParams);
#else
m_pViewMessage->Create(NULL, NULL,
WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS,
CRect(0,0,0,0), this, IDW_MESSAGE_PANE, (CCreateContext *) lpCreateStruct->lpCreateParams);
#endif
m_pViewMessage->SendMessage(WM_INITIALUPDATE);
m_pWndAttachments = new CAttachmentTray;
#ifdef _WIN32
m_pWndAttachments->CreateEx(0, NULL, NULL,
WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS,
0,0,0,0, m_hWnd, (HMENU) IDW_ATTACHMENTS_PANE, lpCreateStruct->lpCreateParams );
#else
m_pWndAttachments->Create(NULL, NULL,
WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS,
CRect(0,0,0,0), this, IDW_ATTACHMENTS_PANE, (CCreateContext *) lpCreateStruct->lpCreateParams);
#endif
}
return res;
}
void CMessageView::OnSize( UINT nType, int cx, int cy )
{
if (nType == SIZE_MINIMIZED || !cx || !cy)
return;
m_rcClient.right = cx;
m_rcClient.bottom = cy;
if (m_bAttachmentsVisible && m_nAttachmentCount > 0) {
::SetRect(&m_rcSlider, 0, cy - m_iAttachmentsHeight - m_iSliderHeight - 1, cx, cy - m_iAttachmentsHeight);
} else {
::SetRect(&m_rcSlider, 0, cy - 1, cx, cy);
}
if (m_pViewMessage) {
m_pViewMessage->MoveWindow(1, 1, cx - 2, m_rcSlider.top - 1);
}
if (m_pWndAttachments) {
m_pWndAttachments->MoveWindow(1, m_rcSlider.bottom, cx - 2, cy - m_rcSlider.bottom - 1);
}
Invalidate();
UpdateWindow();
}
BOOL CMessageView::OnSetCursor( CWnd* pWnd, UINT nHitTest, UINT message )
{
POINT pt;
GetCursorPos(&pt);
ScreenToClient(&pt);
// Handle in OnMouseMove
if (::PtInRect(&m_rcSlider, pt)) {
SetCursor( theApp.LoadCursor ( AFX_IDC_VSPLITBAR ) );
return TRUE;
}
return CView::OnSetCursor(pWnd, nHitTest, message);
}
void CMessageView::UpdateFocusFrame()
{
if (GetParentFrame()->IsKindOf(RUNTIME_CLASS(C3PaneMailFrame)))
{
RECT clientRect;
GetClientRect(&clientRect);
InvalidateRect(&clientRect, FALSE);
::InflateRect(&clientRect, -1, -1);
ValidateRect(&clientRect);
UpdateWindow();
}
}
void CMessageView::OnSetFocus(CWnd *pOldWnd)
{
CView::OnSetFocus(pOldWnd);
if (GetParentFrame()->IsKindOf(RUNTIME_CLASS(C3PaneMailFrame)))
{
UpdateFocusFrame();
((C3PaneMailFrame*)GetParentFrame())->SetFocusWindow(m_pViewMessage);
}
else
m_pViewMessage->SetFocus();
}
void CMessageView::OnKillFocus(CWnd *pOldWnd)
{
CView::OnKillFocus(pOldWnd);
if (GetParentFrame()->IsKindOf(RUNTIME_CLASS(C3PaneMailFrame)))
{
UpdateFocusFrame();
}
}
void CMessageView::OnLButtonDown( UINT nFlags, CPoint point )
{
if (::PtInRect(&m_rcSlider, point)) {
SetCapture();
m_ptHit = point;
m_iOldHeight = m_iAttachmentsHeight;
}
}
void CMessageView::OnMouseMove( UINT nFlags, CPoint point )
{
if (GetCapture() == this) {
RECT rect;
GetClientRect(&rect);
m_iAttachmentsHeight = m_iOldHeight + (m_ptHit.y - point.y);
// Oh, the sanity...
if (m_iAttachmentsHeight < 0)
m_iAttachmentsHeight = 0;
if (m_iAttachmentsHeight > (m_rcClient.bottom - m_iSliderHeight))
m_iAttachmentsHeight = m_rcClient.bottom - m_iSliderHeight;
OnSize(0, rect.right, rect.bottom);
}
}
void CMessageView::OnLButtonUp( UINT nFlags, CPoint point )
{
if (GetCapture() == this) {
ReleaseCapture();
}
}
void CMessageView::OnDestroy()
{
CView::OnDestroy();
}
void CMessageView::SetCSID(int16 doc_csid)
{
if (m_pWndAttachments)
m_pWndAttachments->SetCSID(doc_csid);
}
BOOL CMessageView::HasFocus()
{
CWnd* pFocusWnd = CWnd::GetFocus();
return(pFocusWnd == this || pFocusWnd == m_pWndAttachments ||
pFocusWnd == m_pViewMessage);
}
#ifndef _AFXDLL
#undef new
#endif
IMPLEMENT_DYNCREATE(CMessageView, CView)
#ifndef _AFXDLL
#define new DEBUG_NEW
#endif