root/MailEditView.cpp

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. IMPLEMENT_DYNCREATE
  2. CMailEditView
  3. PreCreateWindow
  4. OnDraw
  5. OnPreparePrinting
  6. OnBeginPrinting
  7. OnEndPrinting
  8. AssertValid
  9. Dump
  10. GetDocument
  11. OnInitialUpdate
  12. OnChar
  13. OnKeyDown
  14. GetText
  15. Font
  16. OnEditPaste
  17. OnLink
  18. OnRButtonDown
  19. OnEditviewPaste
  20. OnEditviewCopy
  21. OnEditviewSelall
  22. OnEditviewCut
  23. OnEditviewUndo
  24. GetPos
  25. OnEditviewPasteQuotation
  26. SetFontEx
  27. SetFontColorAndLink
  28. OnDropFiles

/*
 * Copyright (C) 2002-2003 chik, s.hiranaka
 * For license terms, see the file COPYING in this directory.
 */

// MailEditView.cpp : CMailEditView クラスの動作の定義を行います。
//

#include "stdafx.h"
#include "Pochy.h"
#include "PochyDoc.h"
#include "MailEditView.h"
#include "mainfrm.h"
#include "GpgKeyListDlg.h"
#include "lib.h"
#include "CodeConvert.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CMailEditView

IMPLEMENT_DYNCREATE(CMailEditView, CRichEditView)

BEGIN_MESSAGE_MAP(CMailEditView, CRichEditView)
        //{{AFX_MSG_MAP(CMailEditView)
        ON_WM_CHAR()
        ON_WM_KEYDOWN()
        ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
        ON_WM_RBUTTONDOWN()
        ON_COMMAND(ID_EDITVIEW_PASTE, OnEditviewPaste)
        ON_COMMAND(ID_EDITVIEW_COPY, OnEditviewCopy)
        ON_COMMAND(ID_EDITVIEW_SELALL, OnEditviewSelall)
        ON_COMMAND(ID_EDITVIEW_CUT, OnEditviewCut)
        ON_COMMAND(ID_EDITVIEW_UNDO, OnEditviewUndo)
        ON_COMMAND(ID_EDITVIEW_PASTE_QUOTATION, OnEditviewPasteQuotation)
        ON_WM_DROPFILES()
        //}}AFX_MSG_MAP
        // 標準印刷コマンド
        ON_COMMAND(ID_FILE_PRINT, CRichEditView::OnFilePrint)
        ON_COMMAND(ID_FILE_PRINT_DIRECT, CRichEditView::OnFilePrint)
        ON_COMMAND(ID_FILE_PRINT_PREVIEW, CRichEditView::OnFilePrintPreview)
        ON_NOTIFY_REFLECT_EX(EN_LINK, OnLink)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMailEditView クラスの構築/消滅

CMailEditView::CMailEditView()
{
}

CMailEditView::~CMailEditView()
{
}

BOOL CMailEditView::PreCreateWindow(CREATESTRUCT& cs)
{
        BOOL bPreCreated = CRichEditView::PreCreateWindow(cs);
//      cs.style &= ~(ES_AUTOHSCROLL|WS_HSCROLL);       // ワード ラップを使用可能にします

        return bPreCreated;
}

/////////////////////////////////////////////////////////////////////////////
// CMailEditView クラスの描画

void CMailEditView::OnDraw(CDC* pDC)
{
        CPochyDoc* pDoc = GetDocument();
        ASSERT_VALID(pDoc);
        // TODO: この場所にネイティブ データ用の描画コードを追加します。
}

/////////////////////////////////////////////////////////////////////////////
// CMailEditView クラスの印刷

BOOL CMailEditView::OnPreparePrinting(CPrintInfo* pInfo)
{
        // デフォルトの CEditView の印刷準備
        return CRichEditView::OnPreparePrinting(pInfo);
}

void CMailEditView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)
{
        // デフォルトの CEditView で印刷を開始します。
        CRichEditView::OnBeginPrinting(pDC, pInfo);
}

void CMailEditView::OnEndPrinting(CDC* pDC, CPrintInfo* pInfo)
{
        // デフォルトの CEditView の印刷後の後処理
        CRichEditView::OnEndPrinting(pDC, pInfo);
}

/////////////////////////////////////////////////////////////////////////////
// CMailEditView クラスの診断

#ifdef _DEBUG
void CMailEditView::AssertValid() const
{
        CRichEditView::AssertValid();
}

void CMailEditView::Dump(CDumpContext& dc) const
{
        CRichEditView::Dump(dc);
}

CPochyDoc* CMailEditView::GetDocument() /* 非デバッグ バージョンはインラインです。 */
{
        ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CPochyDoc)));
        return (CPochyDoc*)m_pDocument;
}
#endif _DEBUG

/////////////////////////////////////////////////////////////////////////////
// CMailEditView クラスのメッセージ ハンドラ

void CMailEditView::OnInitialUpdate() 
{
        CPochyApp* app = (CPochyApp*)AfxGetApp();
        CRichEditView::OnInitialUpdate();

        long lENM=GetRichEditCtrl().GetEventMask();
        lENM|=ENM_LINK;
        GetRichEditCtrl().SetEventMask(lENM);
        BOOL bEnable=1;
        ::SendMessage(m_hWnd,EM_AUTOURLDETECT,bEnable,0);

        LOGFONT lf;
        LPBYTE pData;
        UINT nSize;
        if(app->GetProfileBinary("EditViewFont", "LogFont", &pData, &nSize)){
                ASSERT(nSize == sizeof(LOGFONT));
                ::CopyMemory(&lf, pData, sizeof(LOGFONT));
                delete [] pData; 
        }else{
                lf.lfHeight = -16;
                lf.lfWidth = 0;
                lf.lfEscapement = 0;
                lf.lfOrientation = 0;
                lf.lfWeight = 400;
                lf.lfItalic = 0;
                lf.lfUnderline = 0;
                lf.lfStrikeOut = 0;
                lf.lfCharSet = 128;
                lf.lfOutPrecision = 3;
                lf.lfClipPrecision = 2;
                lf.lfQuality = 1;
                lf.lfPitchAndFamily = 49;
                strcpy(lf.lfFaceName, "MS ゴシック");
        }
        SetFontEx(lf);

        // デフォルトの文字属性設定
        CHARFORMAT2 cf;
        CRichEditCtrl& r = GetRichEditCtrl();
        r.GetDefaultCharFormat(cf);

        cf.dwMask = CFM_COLOR | CFM_PROTECTED | CFM_FACE | CFM_SIZE | CFM_CHARSET | CFM_SUBSCRIPT;
        cf.crTextColor = RGB(
                app->GetProfileInt("EditViewColor", "TxtColorR", DEF_TXT_COLOR_R),
                app->GetProfileInt("EditViewColor", "TxtColorG", DEF_TXT_COLOR_G),
                app->GetProfileInt("EditViewColor", "TxtColorB", DEF_TXT_COLOR_B));
        cf.dwEffects = CFE_PROTECTED | CFE_SUBSCRIPT;

        // フォントを変える
//      m_font_size = 8;
//      strncpy(cf.szFaceName, "FixedSys", m_font_size);
//      cf.szFaceName[8]='\0';
//      cf.bPitchAndFamily=FIXED_PITCH;
//      cf.bCharSet=SHIFTJIS_CHARSET;
//      cf.yHeight=280;
//      r.SetDefaultCharFormat(cf);
//      cf.cbSize=sizeof(cf);
        r.SendMessage(EM_SETCHARFORMAT,(WPARAM)SCF_ALL,(LPARAM)&cf);


        // 行間を調整する
/*      PARAFORMAT2 pf;
        pf.cbSize = sizeof(pf);
        pf.dwMask = PFM_LINESPACING | PFM_SPACEAFTER;
        pf.dySpaceAfter = 0;
        pf.bLineSpacingRule = 4;
        pf.dyLineSpacing = 280;
        r.SetSel(0,-1);
        r.SendMessage(EM_SETPARAFORMAT,0,(LPARAM)&pf);
        r.SetSel(0,0);*/

        // 本文を設定
        CDraftFrame* df = (CDraftFrame*)GetParentFrame();
        CString body;
        if(df->m_me.GetMode() == ME_MODE_PGP){
                body = df->m_me.GetMultipartBody(1);
                r.SetReadOnly();
        }else{
                body = df->m_me.GetMultipartBody(0);
        }
        CCodeConvert cc(body);
        body = cc.ToSjis();
        SetWindowText(body);

        // その他の設定
        r.SetBackgroundColor(FALSE, RGB(
    app->GetProfileInt("EditViewColor", "BkColorR", DEF_BKG_COLOR_R),
    app->GetProfileInt("EditViewColor", "BkColorG", DEF_BKG_COLOR_G),
    app->GetProfileInt("EditViewColor", "BkColorB", DEF_BKG_COLOR_B)));
        m_nWordWrap = WrapNone;
        WrapChanged(); // 折り返しなし
        r.SetOptions(ECOOP_OR,ECO_AUTOHSCROLL);
}

void CMailEditView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
        TRACE("char=%d\n",nChar);
        CDraftFrame* df = (CDraftFrame*)GetParentFrame();
        if(df->Char(nChar,this))
                return;

        long a,b;
        int y;

        CRichEditCtrl& r = GetRichEditCtrl();
        r.GetSel(a,b);
        y = r.LineFromChar(a);
        int li = r.LineIndex();
        int pli = r.LineIndex(y-1);
        int nli = r.LineIndex(y+1);
        int len = r.LineLength();
        int plen = r.LineLength(pli);
        int nlen = r.LineLength(nli);

        switch(nChar){ // emacsライクな操作。ちょっとムリが。。。
                case 2:
                        r.SetSel(a-1,a-1);
                        return;
                case 16:
                        if(plen<(a-li))
                                r.SetSel(pli+plen,pli+plen);
                        else
                                r.SetSel(pli+a-li,pli+a-li);
                        return;
                case 14:
                        if(nlen<(a-li))
                                r.SetSel(nli+nlen,nli+nlen);
                        else
                                r.SetSel(nli+a-li,nli+a-li);
                        return;
                case 6:
                        r.SetSel(a+1,a+1);
                        return;
                case 32:
                        if(a!=b)
                                r.SetSel(b,b);
                }
                CRichEditView::OnChar(nChar, nRepCnt, nFlags);
}

void CMailEditView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
        CDraftFrame* df = (CDraftFrame*)GetParentFrame();

        if(df->KeyDown(nChar,this))
                return;
        CRichEditView::OnKeyDown(nChar, nRepCnt, nFlags);
}

void CMailEditView::GetText(CString &buf)
{
        buf.Empty();
        CRichEditCtrl &r = GetRichEditCtrl();
        CHARRANGE cr;
        char *tmp;
        tmp = new char [r.GetTextLength()+1];
        r.GetSel(cr);
        r.HideSelection(TRUE,FALSE);
        r.SetSel(0,r.GetTextLength());
        r.GetSelText(tmp);
        r.SetSel(cr);
        buf=tmp;
        delete [] tmp;
}

void CMailEditView::Font()
{
        CRichEditCtrl& r = GetRichEditCtrl();
        CHARFORMAT cf;
        DWORD dwMask = r.GetDefaultCharFormat(cf);

        LOGFONT lf = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "\0"};
        if(cf.dwEffects & CFE_STRIKEOUT)
                lf.lfStrikeOut = 1;
        if(cf.dwEffects & CFE_UNDERLINE)
                lf.lfUnderline = 1;
        if(cf.dwEffects & CFE_ITALIC)
                lf.lfItalic |= 1;
        if(cf.dwEffects & CFE_BOLD)
                lf.lfWeight = FW_BOLD;
        else
                lf.lfWeight = FW_NORMAL;
        strcpy(lf.lfFaceName, cf.szFaceName);
        lf.lfPitchAndFamily = cf.bPitchAndFamily;
        lf.lfCharSet = cf.bCharSet;
        lf.lfHeight = cf.yHeight * 4/3 * 1/20;

        CFontDialog fd(&lf, CF_EFFECTS | CF_SCREENFONTS | CF_BOTH, NULL, this);
        fd.m_cf.rgbColors = cf.crTextColor;
        if(fd.DoModal() == IDOK){
                int minilen = min(strlen(lf.lfFaceName), LF_FACESIZE);
                strncpy(cf.szFaceName, lf.lfFaceName, minilen);
                cf.szFaceName[minilen] = '\0';

                cf.bPitchAndFamily = lf.lfPitchAndFamily;
                cf.bCharSet = lf.lfCharSet;

                cf.yHeight = fd.m_cf.iPointSize * 2;
                cf.crTextColor = fd.m_cf.rgbColors;
                cf.dwEffects &= ~CFE_AUTOCOLOR;
                cf.dwMask = CFM_BOLD | CFM_CHARSET | CFM_COLOR | CFM_FACE | CFM_ITALIC | CFM_SIZE | CFM_OFFSET | CFM_STRIKEOUT | CFM_UNDERLINE;
                if(lf.lfStrikeOut)
                        cf.dwEffects |= CFE_STRIKEOUT;
                else
                        cf.dwEffects &= ~CFE_STRIKEOUT;
                if(lf.lfUnderline)
                        cf.dwEffects |= CFE_UNDERLINE;
                else
                        cf.dwEffects &= ~CFE_UNDERLINE;
                if(lf.lfItalic)
                        cf.dwEffects |= CFE_ITALIC;
                else
                        cf.dwEffects &= ~CFE_ITALIC;
                if(lf.lfWeight > FW_NORMAL)
                        cf.dwEffects |= CFE_BOLD;
                else
                        cf.dwEffects &= ~CFE_BOLD;

                long nStartChar, nEndChar;
                r.GetSel(nStartChar, nEndChar);
                r.SetDefaultCharFormat(cf);
                r.SetSel(nStartChar, nEndChar);

                Invalidate(TRUE);
        }
}

/*void CMailEditView::Export()
{
/*      CPochyApp* app = (CPochyApp*)AfxGetApp();
        HANDLE hOutputReadTmp,hOutputRead,hOutputWrite;
        HANDLE hInputWriteTmp,hInputRead,hInputWrite;
        HANDLE hErrorReadTmp,hErrorRead,hErrorWrite;
        SECURITY_ATTRIBUTES sa;
        sa.nLength = sizeof(SECURITY_ATTRIBUTES);
        sa.lpSecurityDescriptor = NULL;
        sa.bInheritHandle = TRUE;

        // Create the child output pipe. 
        if (!CreatePipe(&hOutputReadTmp,&hOutputWrite,&sa,0))
                AfxMessageBox("CreatePipe");
        if (!CreatePipe(&hErrorReadTmp,&hErrorWrite,&sa,0))
                AfxMessageBox("CreatePipe");
        if (!CreatePipe(&hInputRead,&hInputWriteTmp,&sa,0))
                AfxMessageBox("CreatePipe");

        if (!DuplicateHandle(GetCurrentProcess(),hErrorReadTmp,
                GetCurrentProcess(),&hErrorRead,0,TRUE,DUPLICATE_SAME_ACCESS))
                AfxMessageBox("DuplicateHandle");
        if (!DuplicateHandle(GetCurrentProcess(),hOutputReadTmp,
                GetCurrentProcess(),&hOutputRead,0,FALSE,DUPLICATE_SAME_ACCESS))
                AfxMessageBox("DuplicateHandle");
        if (!DuplicateHandle(GetCurrentProcess(),hInputWriteTmp,
                GetCurrentProcess(),&hInputWrite,0,FALSE,DUPLICATE_SAME_ACCESS))
                AfxMessageBox("DuplicateHandle");

        // Close inheritable copies of the handles you do not want to be
        // inherited.
        if (!CloseHandle(hOutputReadTmp)) AfxMessageBox("CloseHandle");
        if (!CloseHandle(hInputWriteTmp)) AfxMessageBox("CloseHandle");
        if (!CloseHandle(hErrorReadTmp)) AfxMessageBox("CloseHandle");

        // 画面の文章をファイルに書き込む
        CString buf;
        GetRichEditCtrl().GetWindowText(buf);

        // 鍵の選択
        CGpgKeyListDlg lkd;
        CString exported_key;
        exported_key.Empty();
        if(lkd.DoModal()==IDOK && app->m_key_id_list.GetSize()){
                for(int i=0;i<app->m_key_id_list.GetSize();i++)
                        exported_key += " " + app->m_key_id_list[i];

                // プロセス起動
                STARTUPINFO siStartInfo;
                PROCESS_INFORMATION pi;
                ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
                siStartInfo.hStdError = hErrorWrite;
                siStartInfo.hStdOutput = hOutputWrite;
                siStartInfo.hStdInput = hInputRead;
                siStartInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
                siStartInfo.wShowWindow = SW_HIDE;
                siStartInfo.cb = sizeof(STARTUPINFO);
                CString tmps = "gpg --verbose --always-trust -a -o tmpout --export"+exported_key;
                LPSTR lps = tmps.GetBuffer(0);
                if(!CreateProcess(NULL,lps,
                        NULL,NULL,TRUE,CREATE_NEW_CONSOLE,NULL,NULL,&siStartInfo,&pi))
                        AfxMessageBox("process creation failed.");
                WaitForSingleObject(pi.hProcess,INFINITE);
                CloseHandle(pi.hProcess);
                CloseHandle(pi.hThread);

                // エラーのチェック
                CString body;
#if 1
                DWORD len;
                LPSTR pbody;
                pbody = body.GetBuffer(1000);
                ReadFile(hErrorRead,pbody,1000,&len,NULL);
                pbody[len]=0;
                body.ReleaseBuffer();
                if(body.Find("error")!=-1){
                        AfxMessageBox(body);
                        app->m_gpg_passphrase.Empty();
                        if(!CloseHandle(hInputWrite)) AfxMessageBox("CloseHandle");
                        if(!CloseHandle(hOutputRead)) AfxMessageBox("CloseHandle");
                        if(!CloseHandle(hErrorRead)) AfxMessageBox("CloseHandle");
                        DeleteFile("tmpfile");
                        return;
                }
#endif
                // gpgの出力を読み込む
                g_file2cstring("tmpout",body);
                DeleteFile("tmpout");

                if(!CloseHandle(hInputWrite)) AfxMessageBox("CloseHandle");
                if(!CloseHandle(hOutputRead)) AfxMessageBox("CloseHandle");
                if(!CloseHandle(hErrorRead)) AfxMessageBox("CloseHandle");

                // 表示
                GetRichEditCtrl().SetWindowText(body);
        }
        DeleteFile("tmpfile");
}*/

void CMailEditView::OnEditPaste() 
{
        char * buffer;

        if(OpenClipboard()){
                HANDLE hData = ::GetClipboardData(CF_TEXT);
                buffer = (char*)GlobalLock(hData);
                GlobalUnlock(hData);
                CloseClipboard();
        }

        CString source;
        source=buffer;

        if(OpenClipboard()){
                HGLOBAL clipbuffer;
                EmptyClipboard();
                clipbuffer = GlobalAlloc(GMEM_DDESHARE, source.GetLength()+1);
                buffer = (char*)GlobalLock(clipbuffer);
                strcpy(buffer, LPCSTR(source));
                GlobalUnlock(clipbuffer);
                SetClipboardData(CF_TEXT,clipbuffer);
                CloseClipboard();
        }
        GetRichEditCtrl().Paste();
}

void CMailEditView::OnLink( NMHDR* in_pNotifyHeader, LRESULT* out_pResult )
{
        *out_pResult = 0;
        CPochyApp *app = (CPochyApp *)AfxGetApp();
        CMainFrame *mf = (CMainFrame*)app->m_pMainWnd;
        ENLINK * pLink = (ENLINK*)in_pNotifyHeader;
        if(pLink->msg == WM_LBUTTONDBLCLK && m_onlink != pLink->lParam){
                // 二重起動を防ぐために現在のマウスのクリックされたポイントを保存しておく
                m_onlink = pLink->lParam; // 苦肉の策
                // クリックされたリンクの文字列を取得
                GetRichEditCtrl().SetSel(pLink->chrg);
                CString link = GetRichEditCtrl().GetSelText();
                if(link.Find("mailto:") == 0){
                        // 初期化
                        app->m_me.Initialize();
                        // To の設定
                        if(link.Find("?", 7) != -1) // mailto:hoge@hoge.com?subject=PGP%20Key&Body=Please%20send%20keyとか
                                // subject body とかは未実装
                                app->m_me.SetTo(link.Mid(7, link.Find("?", 7)-7));
                        else
                                app->m_me.SetTo(link.Mid(7));
                        // From の設定
                        CString path = app->m_app_path+"\\"+mf->m_pAcntV->GetCurrentAccountName()+"\\account.ini";
                        CString address;
                        GetPrivateProfileString("mailbox", "address", "", address.GetBuffer(BUF_LENGTH), BUF_LENGTH, path);
                        address.ReleaseBuffer();
                        app->m_me.SetFrom(address);
                        // 署名の取得
                        CString signature;
                        g_file2cstring(app->m_app_path+"\\"+mf->m_pAcntV->GetCurrentAccountName()+"\\signature", signature);
                        // 本文を設定
                        app->m_me.AddText(signature);
                        // draftframe
                        app->CreateDraftFrame(mf->m_pAcntV->GetCurrentAccountName());
                }
                else
                        ShellExecute(this->GetSafeHwnd(), _T( "open" ), link, NULL, NULL, SW_SHOWNORMAL);
        }
}

void CMailEditView::OnRButtonDown(UINT nFlags, CPoint point) 
{
        POINT pt;

        PostMessage(WM_NULL, 0, 0); /* this is point */
        GetCursorPos(&pt);
        CMenu menu;

        menu.LoadMenu(IDR_EDITVIEW_POPUP);

        // 文字列が選択されているかどうか確認
        CRichEditCtrl &r = GetRichEditCtrl();
        if(r.GetSelText().IsEmpty()){
                menu.EnableMenuItem(ID_EDITVIEW_COPY, MF_GRAYED /* 無効 */);
                menu.EnableMenuItem(ID_EDITVIEW_CUT, MF_GRAYED /* 無効 */);
        }else{
                menu.EnableMenuItem(ID_EDITVIEW_COPY, MF_ENABLED /* 有効 */);
                menu.EnableMenuItem(ID_EDITVIEW_CUT, MF_ENABLED /* 無効 */);
        }

        // undoが可能かどうか確認
        if(r.CanUndo())
                menu.EnableMenuItem(ID_EDITVIEW_UNDO, MF_ENABLED /* 有効 */);
        else
                menu.EnableMenuItem(ID_EDITVIEW_UNDO, MF_GRAYED /* 無効 */);

        // 「すべて選択」が可能かどうか確認
        if(r.GetTextLength() == 0)
                menu.EnableMenuItem(ID_EDITVIEW_SELALL, MF_GRAYED /* 無効 */);
        else
                menu.EnableMenuItem(ID_EDITVIEW_SELALL, MF_ENABLED /* 有効 */);

        CMenu *pPopup = menu.GetSubMenu(0);
        pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, (int)pt.x, (int)pt.y, this);    
        CRichEditView::OnRButtonDown(nFlags, point);
}

void CMailEditView::OnEditviewPaste() 
{
        char * buffer;

        if(OpenClipboard()){
                HANDLE hData = ::GetClipboardData(CF_TEXT);
                buffer = (char*)GlobalLock(hData);
                GlobalUnlock(hData);
                CloseClipboard();
        }

        CString source;
        source=buffer;

        if(OpenClipboard()){
                HGLOBAL clipbuffer;
                EmptyClipboard();
                clipbuffer = GlobalAlloc(GMEM_DDESHARE, source.GetLength()+1);
                buffer = (char*)GlobalLock(clipbuffer);
                strcpy(buffer, LPCSTR(source));
                GlobalUnlock(clipbuffer);
                SetClipboardData(CF_TEXT,clipbuffer);
                CloseClipboard();
        }
        GetRichEditCtrl().Paste();
}

void CMailEditView::OnEditviewCopy() 
{
        CRichEditCtrl &r = GetRichEditCtrl();
        r.Copy();
}

void CMailEditView::OnEditviewSelall() 
{
        // すべて選択
        CRichEditCtrl &r = GetRichEditCtrl();
        r.SetSel(0, -1);        
}

void CMailEditView::OnEditviewCut() 
{
        CRichEditCtrl &r = GetRichEditCtrl();
        r.Cut();
}

void CMailEditView::OnEditviewUndo() 
{
        CRichEditCtrl &r = GetRichEditCtrl();
        r.Undo();
}

int CMailEditView::GetPos()
{
        CDraftFrame* df = (CDraftFrame*)GetParentFrame();
        CPoint p;
        p = GetCaretPos();
        return p.x/m_font_size-1;
}

void CMailEditView::OnEditviewPasteQuotation() 
{
        char * buffer;

        if(OpenClipboard()){
                HANDLE hData = ::GetClipboardData(CF_TEXT);
                buffer = (char*)GlobalLock(hData);
                GlobalUnlock(hData);
                CloseClipboard();
        }

        CString source;
        source=buffer;

        source.Replace("\r\n", "\r\n> ");
        source = "> "+source;

        if(OpenClipboard()){
                HGLOBAL clipbuffer;
                EmptyClipboard();
                clipbuffer = GlobalAlloc(GMEM_DDESHARE, source.GetLength()+1);
                buffer = (char*)GlobalLock(clipbuffer);
                strcpy(buffer, LPCSTR(source));
                GlobalUnlock(clipbuffer);
                SetClipboardData(CF_TEXT,clipbuffer);
                CloseClipboard();
        }
        GetRichEditCtrl().Paste();
}


void CMailEditView::SetFontEx(LOGFONT &lf)
{
        CRichEditCtrl &r = GetRichEditCtrl();

        m_font.DeleteObject();
        if(m_font.CreateFontIndirect(&lf))
                r.SetFont(&m_font);
        SetFontColorAndLink();
}

void CMailEditView::SetFontColorAndLink()
{
        CRichEditCtrl &r = GetRichEditCtrl();
        CPochyApp* app = (CPochyApp*)AfxGetApp();

        // clickable url を有効にする
        long lENM = r.GetEventMask();
        lENM |= ENM_LINK;
        r.SetEventMask(lENM);
        BOOL bEnable = 1;
        ::SendMessage(m_hWnd, EM_AUTOURLDETECT, bEnable, 0);

        // 文字の属性を設定
        CHARFORMAT2 cf;
        r.GetDefaultCharFormat(cf);
        cf.dwMask = CFM_COLOR | CFM_PROTECTED | CFM_FACE | CFM_SIZE | CFM_CHARSET | CFM_SUBSCRIPT;
        cf.crTextColor = RGB(
                app->GetProfileInt("EditViewColor", "TxtColorR", DEF_TXT_COLOR_R),
                app->GetProfileInt("EditViewColor", "TxtColorG", DEF_TXT_COLOR_G),
                app->GetProfileInt("EditViewColor", "TxtColorB", DEF_TXT_COLOR_B));
        cf.dwEffects = CFE_PROTECTED | CFE_SUBSCRIPT;
//      cf.bCharSet=GB2312_CHARSET;
        r.SendMessage(EM_SETCHARFORMAT,(WPARAM)SCF_ALL,(LPARAM)&cf);
}

void CMailEditView::OnDropFiles(HDROP hDropInfo) 
{
//      CRichEditView::OnDropFiles(hDropInfo);

        this->GetRichEditCtrl().UpdateData(TRUE);
        CDraftFrame *df = (CDraftFrame*)GetParentFrame();

        // count number of droped file
        int num = DragQueryFile(hDropInfo,~0lu, NULL, 0);

        for(int i=0; i<num; i++){
                // get length of file name
                int len = DragQueryFile(hDropInfo, i, NULL, 0);

                // get file path
                CString file_path;
                DragQueryFile(hDropInfo, i, file_path.GetBuffer(len+1), len+1);
                file_path.ReleaseBuffer();

                // add m_me
                if(!df->m_me.AddAttachedFile(file_path)){
                        AfxMessageBox("cannot open file");
                        continue;
                }

                // add item to attachedfielview.
                df->m_pListV2->AddFile(file_path.GetBuffer(0));
                file_path.ReleaseBuffer();
        }
        df->HideAttachedFileView(FALSE);
        df->ReArrangeSplit();
//      df->m_pEditV->SetFocus();
        this->GetRichEditCtrl().UpdateData(FALSE);

//      CRichEditView::OnDropFiles(hDropInfo);
}

/* [<][>][^][v][top][bottom][index][help] */