|
|
/*
* e n v h o s t . c p p * * Purpose: * * History * * Copyright (C) Microsoft Corp. 1995, 1996. */
#include <pch.hxx>
#include "resource.h"
#include "envcid.h"
#include "commdlg.h"
#include "docobj.h"
#include "dllmain.h"
#include "msoert.h"
#include "mimeole.h"
#include "envhost.h"
#include "richedit.h"
#include "init.h"
#include "shellapi.h"
HINSTANCE s_hRichEdit; HINSTANCE g_hLocRes ; HACCEL g_hAccelMailSend;
HRESULT HrRicheditStreamOut(HWND hwndRE, LPSTREAM pstm, ULONG uSelFlags); void SaveFocus(BOOL fActive, HWND *phwnd);
static const TCHAR c_szGWNoteWndClass[] = "GW_Note";
//+---------------------------------------------------------------
//
// Member: Constructor
//
// Synopsis:
//
//---------------------------------------------------------------
CEnvHost::CEnvHost(IUnknown *pUnkOuter) : CPrivateUnknown(pUnkOuter) { DllAddRef(); }
//+---------------------------------------------------------------
//
// Member: Destructor
//
// Synopsis:
//
//---------------------------------------------------------------
CEnvHost::~CEnvHost() { DllRelease(); }
//+---------------------------------------------------------------
//
// Member: PrivateQueryInterface
//
// Synopsis:
//
//---------------------------------------------------------------
HRESULT CEnvHost::PrivateQueryInterface(REFIID riid, LPVOID *lplpObj) { if(!lplpObj) return E_INVALIDARG;
*lplpObj = NULL;
if (IsEqualIID(riid, IID_IUnknown)) *lplpObj = (LPVOID)(IMsoEnvelopeHost *)this; else if (IsEqualIID(riid, IID_IMsoEnvelopeHost)) *lplpObj = (LPVOID)(IMsoEnvelopeHost *)this; else { return E_NOINTERFACE; } AddRef(); return NOERROR; }
HRESULT CEnvHost::CreateNote(IUnknown *punk, REFCLSID clsidCreate, LPCWSTR wszTheme, LPCWSTR wszAuthor, LPCWSTR wszPrefix, DWORD grfCreate) { return HrCreateNote(clsidCreate, grfCreate); }
HRESULT CEnvHost::LockServer(BOOL fLock) { return S_OK; }
//+---------------------------------------------------------------
//
// Member: Constructor
//
// Synopsis:
//
//---------------------------------------------------------------
CGWNote::CGWNote(IUnknown *pUnkOuter) : CPrivateUnknown(pUnkOuter) { m_pEnv=NULL; m_hwnd=NULL; m_hwndRE=NULL; m_pComponent=NULL; m_hwndFocus=NULL;
DllAddRef(); }
//+---------------------------------------------------------------
//
// Member: Destructor
//
// Synopsis:
//
//---------------------------------------------------------------
CGWNote::~CGWNote() { DllRelease(); }
//+---------------------------------------------------------------
//
// Member: PrivateQueryInterface
//
// Synopsis:
//
//---------------------------------------------------------------
HRESULT CGWNote::PrivateQueryInterface(REFIID riid, LPVOID *lplpObj) { if(!lplpObj) return E_INVALIDARG;
*lplpObj = NULL;
if (IsEqualIID(riid, IID_IUnknown)) *lplpObj = (LPVOID)(IPersistMime *)this; else if (IsEqualIID(riid, IID_IServiceProvider)) *lplpObj = (LPVOID)(IServiceProvider *)this; else if (IsEqualIID(riid, IID_IPersistMime)) *lplpObj = (LPVOID)(IPersistMime *)this; else if (IsEqualIID(riid, IID_IMsoEnvelopeSite)) *lplpObj = (LPVOID)(IMsoEnvelopeSite *)this; else if (IsEqualIID(riid, IID_IMsoComponentManager)) *lplpObj = (LPVOID)(IMsoComponentManager *)this; else { return E_NOINTERFACE; } AddRef(); return NOERROR; }
//+---------------------------------------------------------------
//
// Member: GetClassID
//
// Synopsis:
//
//---------------------------------------------------------------
HRESULT CGWNote::GetClassID(CLSID *pClassID) { *pClassID = CLSID_GWEnvelopeHost; return NOERROR; }
// *** IServiceProvider ***
//+---------------------------------------------------------------
//
// Member: QueryService
//
// Synopsis:
//
//---------------------------------------------------------------
HRESULT CGWNote::QueryService(REFGUID guidService, REFIID riid, LPVOID *ppvObject) { if (IsEqualGUID(guidService, IID_IMsoComponentManager)) return PrivateQueryInterface(riid, ppvObject);
return E_NOINTERFACE; }
// *** IPersistMime ***
//+---------------------------------------------------------------
//
// Member: Load
//
// Synopsis:
//
//---------------------------------------------------------------
HRESULT CGWNote::Load(IMimeMessage *pMsg) { return E_NOTIMPL; }
//+---------------------------------------------------------------
//
// Member: Save
//
// Synopsis:
//
//---------------------------------------------------------------
HRESULT CGWNote::Save(IMimeMessage *pMsg, DWORD dwFlags) { IPersistMime *pPM; IStream *pstm; HRESULT hr;
// save envelope props
if (m_pEnv && m_pEnv->QueryInterface(IID_IPersistMime, (LPVOID *)&pPM)==S_OK) { hr = pPM->Save(pMsg, dwFlags); pPM->Release(); }
// save body props
if (MimeOleCreateVirtualStream(&pstm)==S_OK) { if (HrRicheditStreamOut(m_hwndRE, pstm, SF_TEXT)==S_OK) pMsg->SetTextBody(TXT_PLAIN, IET_BINARY, NULL, pstm, NULL); pstm->Release(); } return hr; }
HRESULT CGWNote::RequestResize(int *pcHeight) { RECT rc;
m_cyEnv = *pcHeight;
GetClientRect(m_hwnd, &rc); rc.top +=2; rc.bottom = m_cyEnv+2; m_pEnv->Resize(&rc);
GetClientRect(m_hwnd, &rc); rc.top += m_cyEnv + 4; rc.bottom -=2; SetWindowPos(m_hwndRE, NULL, 0, rc.top, rc.right-rc.left, rc.bottom-rc.top, SWP_NOZORDER); return S_OK; }
HRESULT CGWNote::CloseNote(DWORD grfClose) { SendMessage(m_hwnd, WM_CLOSE, 0, 0); return S_OK; }
HRESULT CGWNote::GetBody(IStream *pstm, DWORD dwCodePage, DWORD grfBody) { return E_NOTIMPL; }
HRESULT CGWNote::SetBody(IStream *pstm, DWORD dwCodePage, DWORD grfBody) { return S_OK; }
HRESULT CGWNote::SetFocus(BOOL fTab) { if (fTab) ::SetFocus(m_hwndRE); return S_OK; }
HRESULT CGWNote::OnEnvSetFocus() { return S_OK; }
HRESULT CGWNote::OnPropChange(ULONG dispid) { return S_OK; }
HRESULT CGWNote::IsBodyDirty() { return S_OK; }
HRESULT CGWNote::HandsOff() { return S_OK; }
HRESULT CGWNote::GetMsoInst(HMSOINST *phinst) { return E_NOTIMPL; }
HRESULT CGWNote::GetFrameWnd(HWND *phwndFrame) { return E_NOTIMPL; }
HRESULT CGWNote::DisplayMessage(HRESULT hr, LPCWSTR wszError, DWORD grfMsg) { return S_OK; }
LRESULT CGWNote::ExtWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { CGWNote *pNote;
if(msg==WM_CREATE) { pNote=(CGWNote *)((LPCREATESTRUCT)lParam)->lpCreateParams; if(!pNote) return -1;
if(FAILED(pNote->OnCreate(hwnd))) return -1; } pNote = (CGWNote *)GetWndThisPtr(hwnd); if(pNote) return pNote->WndProc(hwnd, msg, wParam, lParam); else return DefWindowProc(hwnd, msg, wParam, lParam);
}
LRESULT CGWNote::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { LONG lret;
switch (msg) { case WM_NOTIFY: return (WMNotify(wParam, (NMHDR *)lParam)==S_OK);
case WM_COMMAND: if (WMCommand( GET_WM_COMMAND_HWND(wParam, lParam), GET_WM_COMMAND_ID(wParam, lParam), GET_WM_COMMAND_CMD(wParam, lParam))==S_OK) return 0;
break;
case WM_SIZE: RequestResize((int *)&m_cyEnv); break;
case WM_NCDESTROY: OnNCDestroy(); break; }
lret = DefWindowProc(hwnd, msg, wParam, lParam);
if(msg==WM_ACTIVATE) { // post-process wm_activates to set focus back to
// control
SaveFocus((BOOL)(LOWORD(wParam)), &m_hwndFocus); g_pActiveNote = (LOWORD(wParam)==WA_INACTIVE)?NULL:this; }
return lret;
}
HRESULT CGWNote::Init(REFCLSID clsidEnvelope, DWORD dwFlags) {
HRESULT hr=S_OK; HWND hwnd; WNDCLASS wc; HMENU hMenu;
TraceCall("CDocHost::Init");
if (!GetClassInfo(g_hInst, c_szGWNoteWndClass, &wc)) { ZeroMemory(&wc, sizeof(WNDCLASS)); wc.lpfnWndProc = CGWNote::ExtWndProc; wc.hInstance = g_hInst; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.lpszClassName = c_szGWNoteWndClass; wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); wc.style = CS_DBLCLKS;
if(!RegisterClass(&wc)) return E_OUTOFMEMORY; }
hMenu = LoadMenu(g_hInst, "GWNOTEMENU"); if (!hMenu) return E_OUTOFMEMORY;
hwnd=CreateWindowEx(WS_EX_WINDOWEDGE|WS_EX_CONTROLPARENT, c_szGWNoteWndClass, "GW Note Control", WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN, 0, 0, 400, 400, NULL, hMenu, g_hInst, (LPVOID)this); if(!hwnd) { hr=E_OUTOFMEMORY; goto error; }
hr = InitEnvelope(clsidEnvelope, dwFlags);
error: return hr; }
HRESULT CGWNote::OnCreate(HWND hwnd) { CHARFORMAT cf={0};
m_hwnd = hwnd; SetWindowLong(hwnd, GWL_USERDATA, (LPARAM)this);
m_hwndRE = CreateWindowEx(WS_EX_CLIENTEDGE, "RichEdit", "", //ES_MULTILINE|ES_SAVESEL|ES_AUTOVSCROLL|ES_SELECTIONBAR|ES_WANTRETURN|WS_VSCROLL|WS_CHILD|WS_TABSTOP|WS_VISIBLE,
ES_SAVESEL|ES_WANTRETURN|ES_MULTILINE|WS_CHILD|WS_TABSTOP|WS_VISIBLE|ES_AUTOVSCROLL|WS_VSCROLL, 0, 0, 0, 0, hwnd, (HMENU)99, g_hInst, NULL); if (!m_hwndRE) return E_FAIL;
cf.cbSize = sizeof(CHARFORMAT); cf.dwMask = CFM_COLOR|CFM_FACE; cf.crTextColor = RGB(0,0,255); lstrcpy(cf.szFaceName, "Verdana");
SendMessage(m_hwndRE, EM_SETCHARFORMAT, 0, (LPARAM)&cf); SendMessage(m_hwndRE, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf); SendMessage(m_hwndRE, EM_SETEVENTMASK, 0, ENM_KEYEVENTS); AddRef(); return S_OK; }
HRESULT CGWNote::OnNCDestroy() { SafeRelease(m_pEnv); if (m_pComponent) { m_pComponent->Terminate(); SafeRelease(m_pComponent); }
SetWindowLong(m_hwnd, GWL_USERDATA, NULL); m_hwnd = NULL; Release(); return S_OK; }
HRESULT CGWNote::Show() { ShowWindow(m_hwnd, SW_SHOW); return S_OK; }
HRESULT CGWNote::InitEnvelope(REFCLSID clsidEnvelope, DWORD dwFlags) { HRESULT hr; RECT rc;
hr = CoCreateInstance(clsidEnvelope, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, IID_IMsoEnvelope, (LPVOID *)&m_pEnv); if (FAILED(hr)) goto error;
hr = m_pEnv->Init(NULL, (IMsoEnvelopeSite *)this, dwFlags); if (FAILED(hr)) goto error;
hr = m_pEnv->SetParent(m_hwnd); if (FAILED(hr)) goto error;
hr = m_pEnv->Show(TRUE); if (FAILED(hr)) goto error;
m_pEnv->SetFocus(ENV_FOCUS_INITIAL);
error: return hr; }
HRESULT CGWNote::TranslateAcclerator(MSG *lpmsg) { if (!g_hAccelMailSend) g_hAccelMailSend= LoadAccelerators(g_hInst, MAKEINTRESOURCE(idacMail_SendNote));
if (::TranslateAccelerator(m_hwnd, g_hAccelMailSend, lpmsg)) return S_OK;
if (m_pComponent && m_pComponent->FPreTranslateMessage(lpmsg)) return S_OK;
return S_FALSE; }
DWORD CALLBACK EditStreamOutCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG FAR *pcb) { return ((LPSTREAM)dwCookie)->Write(pbBuff, cb, (ULONG *)pcb); }
HRESULT HrRicheditStreamOut(HWND hwndRE, LPSTREAM pstm, ULONG uSelFlags) { EDITSTREAM es;
if(!pstm) return E_INVALIDARG;
if(!IsWindow(hwndRE)) return E_INVALIDARG;
HrRewindStream(pstm);
es.dwCookie = (DWORD)pstm; es.pfnCallback=(EDITSTREAMCALLBACK)EditStreamOutCallback; SendMessage(hwndRE, EM_STREAMOUT, uSelFlags, (LONG)&es); return S_OK; }
BOOL CGWNote::FRegisterComponent(IMsoComponent *piComponent, const MSOCRINFO *pcrinfo, DWORD *pdwComponentID) { if (m_pComponent) // only one register allowed
return E_FAIL;
ReplaceInterface(m_pComponent, piComponent); *pdwComponentID=666; return TRUE; }
BOOL CGWNote::FRevokeComponent(DWORD dwComponentID) { return TRUE; }
BOOL CGWNote::FUpdateComponentRegistration(DWORD dwComponentID, const MSOCRINFO *pcrinfo) { return FALSE; }
BOOL CGWNote::FOnComponentActivate(DWORD dwComponentID) { return FALSE; }
BOOL CGWNote::FSetTrackingComponent(DWORD dwComponentID, BOOL fTrack) { return FALSE; }
void CGWNote::OnComponentEnterState(DWORD dwComponentID, ULONG uStateID, ULONG uContext,ULONG cpicmExclude,IMsoComponentManager **rgpicmExclude, DWORD dwReserved) { }
BOOL CGWNote::FOnComponentExitState(DWORD dwComponentID, ULONG uStateID, ULONG uContext,ULONG cpicmExclude,IMsoComponentManager **rgpicmExclude) { return FALSE; }
BOOL CGWNote::FInState(ULONG uStateID, void *pvoid) { return FALSE; }
BOOL CGWNote::FContinueIdle () { return FALSE; }
BOOL CGWNote::FPushMessageLoop(DWORD dwComponentID, ULONG uReason, void *pvLoopData) { return FALSE; }
BOOL CGWNote::FCreateSubComponentManager(IUnknown *piunkOuter, IUnknown *piunkServProv,REFIID riid, void **ppvObj) { return FALSE; }
BOOL CGWNote::FGetParentComponentManager(IMsoComponentManager **ppicm) { return FALSE; }
BOOL CGWNote::FGetActiveComponent(DWORD dwgac, IMsoComponent **ppic, MSOCRINFO *pcrinfo, DWORD dwReserved) { return FALSE; }
BOOL CGWNote::FDebugMessage(HMSOINST hinst, UINT message, WPARAM wParam, LPARAM lParam) { return FALSE; }
HRESULT CGWNote::WMCommand(HWND hwndCmd, int id, WORD wCmd) { if (wCmd > 1) return S_FALSE;
switch(id) { case idmNewMsg: ShellExecute(m_hwnd, NULL, "mailto:", 0, 0, SW_SHOW); return S_OK;
case idmProperties: MessageBox(m_hwnd, "PlaceHolder", "Properties", MB_OK); return S_OK;
case idmSaveAs: return SaveAs();
case idmClose: PostMessage(m_hwnd, WM_CLOSE, 0, 0); return S_OK;
case idmCheckNames: return HrHeaderExecCommand(MSOEENVCMDID_CHECKNAMES, MSOCMDEXECOPT_PROMPTUSER, NULL);
case idmPickRecipients: return HrHeaderExecCommand(MSOEENVCMDID_SELECTRECIPIENTS, MSOCMDEXECOPT_DODEFAULT, NULL);
case idmViewContacts: return HrHeaderExecCommand(MSOEENVCMDID_VIEWCONTACTS, MSOCMDEXECOPT_DODEFAULT, NULL); default: MessageBox(m_hwnd, "Not Yet Implemented", "Menu Command", MB_OK); return S_OK; } return S_FALSE; }
HRESULT CGWNote::HrHeaderExecCommand(UINT uCmdID, DWORD nCmdExecOpt, VARIANTARG *pvaIn) { HRESULT hr = S_FALSE; IOleCommandTarget *pCmdTarget;
if(m_pEnv && m_pEnv->QueryInterface(IID_IOleCommandTarget, (LPVOID *)&pCmdTarget)==S_OK) { hr = pCmdTarget->Exec(&CGID_Envelope, uCmdID, nCmdExecOpt, pvaIn, NULL); pCmdTarget->Release(); } return hr;
}
HRESULT CGWNote::WMNotify(int idFrom, NMHDR *pnmh) { MSGFILTER *pmf=(MSGFILTER *)pnmh; BOOL fShift;
switch (pnmh->code) { case EN_MSGFILTER: if (pmf->msg == WM_KEYDOWN && pmf->wParam == VK_TAB && !(GetKeyState(VK_CONTROL) & 0x8000)) { // shift tab puts focus in the envelope
if (GetKeyState(VK_SHIFT)&0x8000 && m_pEnv) { m_pEnv->SetFocus(ENV_FOCUS_TAB); return S_OK; } } break; } return S_FALSE; }
void SaveFocus(BOOL fActive, HWND *phwnd) { if(fActive&&IsWindow(*phwnd)) SetFocus(*phwnd); else *phwnd=GetFocus(); }
static char c_szFilter[] = "Rfc 822 Messages (*.eml)\0*.eml\0\0";
HRESULT CGWNote::SaveAs() { OPENFILENAME ofn; TCHAR szFile[MAX_PATH]; TCHAR szTitle[MAX_PATH]; TCHAR szDefExt[30]; WCHAR szFileW[MAX_PATH];
lstrcpy(szFile, "c:\\*.eml"); lstrcpy(szDefExt, ".eml"); lstrcpy(szTitle, "Save Message As..."); ZeroMemory (&ofn, sizeof (ofn)); ofn.lStructSize = sizeof (ofn); ofn.hwndOwner = m_hwnd; ofn.lpstrFilter = c_szFilter; ofn.nFilterIndex = 1; ofn.lpstrFile = szFile; ofn.nMaxFile = sizeof (szFile); ofn.lpstrTitle = szTitle; ofn.lpstrDefExt = szDefExt; ofn.Flags = OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT;
if (*szFile==NULL) return E_FAIL;
// Show OpenFile Dialog
if (!GetSaveFileName(&ofn)) return MIMEEDIT_E_USERCANCEL; MultiByteToWideChar(CP_ACP, 0, szFile, -1, szFileW, MAX_PATH);
return SaveToFile(szFileW); }
HRESULT CGWNote::SaveToFile(LPWSTR pszW) { IPersistMime *ppm; IPersistFile *pPF; IMimeMessage *pMsg; HRESULT hr;
hr = CoCreateInstance(CLSID_IMimeMessage, NULL, CLSCTX_INPROC_SERVER, IID_IMimeMessage, (LPVOID *)&pMsg); if (!FAILED(hr)) { pMsg->InitNew(); hr = pMsg->QueryInterface(IID_IPersistFile, (LPVOID *)&pPF); if (!FAILED(hr)) { hr = Save(pMsg, 0); if (!FAILED(hr)) { hr = pPF->Save(pszW, FALSE); } pPF->Release(); } pMsg->Release(); } return hr; }
HRESULT CGWNote::DirtyToolbars(void) { return S_OK; }
HRESULT CGWNote::SetHelpMode(BOOL fEnter) { return S_OK; }
HRESULT CGWNote::TranslateAccelerators(MSG *pMsg) { return S_FALSE; }
|