📄 convedit.cpp
字号:
// ConvEdit.cpp : implementation file
//
#include "stdafx.h"
#include "Netmsg.h"
#include "ConvEdit.h"
#include "Conversation.h"
#include "ImageDataObject.h"
#include "ContactView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//The edit boxes in the conversation dialogs
//or should I say... RICH edit, now anyway
CConvEdit::CConvEdit()
{
m_lpConv = NULL;
}
CConvEdit::~CConvEdit()
{
}
BEGIN_MESSAGE_MAP(CConvEdit, CRichEditCtrl)
//{{AFX_MSG_MAP(CConvEdit)
ON_WM_DROPFILES()
ON_WM_CREATE()
ON_WM_CHAR()
ON_WM_SYSCHAR()
ON_WM_RBUTTONDOWN()
ON_COMMAND(ID_MENU_COPY, OnMenuCopy)
ON_COMMAND(ID_MENU_CUT, OnMenuCut)
ON_COMMAND(ID_MENU_UNDO, OnMenuUndo)
ON_COMMAND(ID_MENU_PASTE, OnMenuPaste)
ON_WM_DESTROY()
ON_WM_ERASEBKGND()
ON_WM_SIZE()
ON_WM_VSCROLL()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CConvEdit message handlers
void CConvEdit::OnDropFiles(HDROP hDropInfo)
{
char FileName[2048];
DragQueryFile(hDropInfo, 0, FileName, 2048);
if (m_lpConv)
m_lpConv->FileDropped(FileName, 2048);
DragFinish(hDropInfo);
}
int CConvEdit::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CRichEditCtrl::OnCreate(lpCreateStruct) == -1)
return -1;
DragAcceptFiles(TRUE);
OleInitialize(NULL);
return 0;
}
void CConvEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if (nChar == 13)
{
int len = GetWindowTextLength();
CConversation *Conv = (CConversation *)GetParent();
Conv->OnSend();
}
else
{
CRichEditCtrl::OnChar(nChar, nRepCnt, nFlags);
GetParent()->SendMessage(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), EN_CHANGE), (LPARAM) m_hWnd);
}
}
void CConvEdit::OnSysChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
CRichEditCtrl::OnSysChar(nChar, nRepCnt, nFlags);
}
void CConvEdit::Enable(bool bEnable)
{
if (bEnable)
ShowWindow(SW_SHOW);
else
ShowWindow(SW_HIDE);
}
BOOL CConvEdit::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext, CConversation *lpConv)
{
m_lpConv = lpConv;
if (!::AfxInitRichEditEx())
{
return FALSE;
}
return CWnd::Create("RichEdit20A", lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext);
}
BOOL CConvEdit::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, void *lpExtra, CConversation *lpConv)
{
m_lpConv = lpConv;
if (!::AfxInitRichEditEx())
{
return FALSE;
}
return CWnd::CreateEx(dwExStyle, "RichEdit20A", lpszWindowName, dwStyle, rect, pParentWnd, nID, lpExtra);
}
_AFX_RICHEDITEX_STATE::_AFX_RICHEDITEX_STATE()
{
m_hInstRichEdit20 = NULL;
}
_AFX_RICHEDITEX_STATE::~_AFX_RICHEDITEX_STATE()
{
if (m_hInstRichEdit20 != NULL)
{
::FreeLibrary(m_hInstRichEdit20);
}
}
_AFX_RICHEDITEX_STATE _afxRichEditStateEx;
BOOL PASCAL AfxInitRichEditEx()
{
if (!::AfxInitRichEdit())
{
return FALSE;
}
_AFX_RICHEDITEX_STATE* l_pState = &_afxRichEditStateEx;
if (l_pState->m_hInstRichEdit20 == NULL)
{
l_pState->m_hInstRichEdit20 = LoadLibraryA("RICHED20.DLL");
}
return l_pState->m_hInstRichEdit20 != NULL;
}
char *stristr(const char * str1, const char * str2)
{
char *cp = (char *) str1;
char *s1, *s2;
if ( !*str2 )
return (char *) str1;
while (*cp)
{
s1 = cp;
s2 = (char *) str2;
while ( *s1 && *s2 && ( !(*s1-*s2) ||
!(*s1-tolower(*s2)) || !(*s1-toupper(*s2)) ) )
s1++, s2++;
if (!*s2)
return cp;
cp++;
}
return NULL;
}
void strstp(const char *in, char *before, const char *txt, char *after)
{
char *cmp = stristr(in, txt);
if (!cmp) return;
strncpy(before, in, cmp - in);
before[cmp - in] = 0;
char *out = cmp + strlen(txt);
strcpy(after, out);
}
void CConvEdit::AppendWindowTextF(USERFONT *uf, int nIndent, const char *fmt, ...)
{
va_list args;
CHARFORMAT cf;
PARAFORMAT pf;
pf.cbSize = sizeof(PARAFORMAT);
pf.dwMask = PFM_OFFSETINDENT | PFM_RIGHTINDENT;
pf.dxRightIndent = nIndent;
pf.dxStartIndent = nIndent;
SetParaFormat(pf);
va_start(args, fmt);
char buf[1024];
_vsnprintf(buf, sizeof(buf), fmt, args);
strrpl(buf, "$CRLF", "\r\n");
char *s = buf;
char before[1024], after[1024];
int len = strlen(s);
memset(&cf, 0, sizeof(CHARFORMAT));
cf.cbSize = sizeof(CHARFORMAT);
cf.dwMask = CFM_COLOR | CFM_ITALIC | CFM_STRIKEOUT | CFM_BOLD | CFM_UNDERLINE | CFM_FACE | CFM_SIZE;
strcpy(cf.szFaceName, uf->lfFont.lfFaceName);
cf.yHeight = uf->nPointSize * 2;
cf.crTextColor = uf->crColor;
cf.bPitchAndFamily = uf->lfFont.lfPitchAndFamily;
if (uf->lfFont.lfItalic) cf.dwEffects |= CFE_ITALIC;
if (uf->lfFont.lfWeight >= FW_BOLD) cf.dwEffects |= CFE_BOLD;
if (uf->lfFont.lfItalic) cf.dwEffects |= CFE_ITALIC;
if (uf->lfFont.lfStrikeOut) cf.dwEffects |= CFE_STRIKEOUT;
if (uf->lfFont.lfUnderline) cf.dwEffects |= CFE_UNDERLINE;
if (AfxGetApp()->GetProfileInt("Settings", "UseEmoticons", 1))
{
for (;;)
{
char next[16] = { NULL }, *rpl = NULL;
HBITMAP hbmNext = NULL;
POSITION pos;
CList<EMOTICON *, EMOTICON *> &Emoticons = GetApp()->View->Emoticons;
pos = Emoticons.GetHeadPosition();
while (pos)
{
EMOTICON *Emoticon = Emoticons.GetNext(pos);
char *txt = stristr(s, Emoticon->szActivationText);
if ((txt < rpl && txt) || !rpl && txt)
{
rpl = txt;
hbmNext = Emoticon->hBitmap;
strcpy(next, Emoticon->szActivationText);
}
}
if (rpl)
{
strstp(s, before, next, after);
AppendText(&cf, before);
AppendBitmap(hbmNext);
s = after;
}
else
{
if (strlen(s) > 0) AppendText(&cf, s);
break;
}
}
}
else
{
AppendText(&cf, s);
}
pf.dxRightIndent = -nIndent;
pf.dxStartIndent = -nIndent;
SetParaFormat(pf);
}
int strcchr(const char *in, int chr)
{
int ret = 0;
while (*in++)
if (*(in - 1) == chr) ret++;
return ret;
}
void CConvEdit::AppendText(CHARFORMAT *pfmt, const char *text)
{
int end;
int len = GetWindowTextLength();
char *buf = new char [GetWindowTextLength() + 1];
GetWindowText(buf, GetWindowTextLength());
SetSel(len, len);
ReplaceSel(text);
end = GetWindowTextLength();
SetSel(len - strcchr(buf, '\n'), end);
if (pfmt)
{
SetSelectionCharFormat(*pfmt);
}
SetSel(end, end);
SendMessage(WM_VSCROLL, SB_BOTTOM, 0);
UpdateScrollInfo();
delete [] buf;
}
void CConvEdit::AppendBitmap(HBITMAP hbm)
{
LineScroll(1);
CImageDataObject::InsertBitmap(GetIRichEditOle(), this, hbm);
}
BOOL CConvEdit::PreCreateWindow(CREATESTRUCT& cs)
{
cs.style &= ~ES_WANTRETURN;
return CRichEditCtrl::PreCreateWindow(cs);
}
void CConvEdit::OnRButtonDown(UINT nFlags, CPoint point)
{
CPoint pos;
CMenu Menu;
CMenu *subMenu;
GetCursorPos(&pos);
Menu.LoadMenu(IDR_RICHEDITMENU);
subMenu = Menu.GetSubMenu(0);
SetForegroundWindow();
subMenu->TrackPopupMenu(0, pos.x, pos.y, this, NULL);
PostMessage(WM_NULL, 0, 0);
CRichEditCtrl::OnRButtonDown(nFlags, point);
}
void CConvEdit::OnMenuCopy()
{
Copy();
}
void CConvEdit::OnMenuCut()
{
Cut();
GetParent()->SendMessage(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), EN_CHANGE), (LPARAM) m_hWnd);
}
void CConvEdit::OnMenuUndo()
{
Undo();
GetParent()->SendMessage(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), EN_CHANGE), (LPARAM) m_hWnd);
}
void CConvEdit::OnMenuPaste()
{
Paste();
GetParent()->SendMessage(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), EN_CHANGE), (LPARAM) m_hWnd);
}
void CConvEdit::OnDestroy()
{
SetWindowText(""); //VITAL!
CRichEditCtrl::OnDestroy();
}
BOOL CConvEdit::OnEraseBkgnd(CDC* pDC)
{
return CRichEditCtrl::OnEraseBkgnd(pDC);
}
void CConvEdit::OnSize(UINT nType, int cx, int cy)
{
CRichEditCtrl::OnSize(nType, cx, cy);
UpdateScrollInfo();
}
void CConvEdit::UpdateScrollInfo()
{
RECT rect;
SCROLLINFO sif;
memset(&sif, 0, sizeof(SCROLLINFO));
sif.cbSize = sizeof(SCROLLINFO);
sif.fMask = SIF_ALL;
GetClientRect(&rect);
if (!GetScrollInfo(SB_VERT, &sif))
return;
if (sif.nMax > rect.bottom && sif.nPage)
{
if (!m_bHasScrollBar)
{
CConversation *Conv;
Conv = (CConversation *)GetParent();
::SetTimer(Conv->m_bgWnd.m_hWnd, 1, 1, 0);
::SetTimer(Conv->m_hWnd, 3, 1, 0);
}
m_bHasScrollBar = true;
}
else
{
if (m_bHasScrollBar) GetParent()->RedrawWindow();
m_bHasScrollBar = false;
}
}
void CConvEdit::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
CRichEditCtrl::OnVScroll(nSBCode, nPos, pScrollBar);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -