Viewing file: StatusCtrl.cpp (10.46 KB) -rw-rw-rw- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
// StatusCtrl.cpp: Implementierungsdatei
//
#include "stdafx.h"
#include "StatusCtrl.h"
#include "EnterSomething.h"
#include "MainFrm.h"
#if defined(_DEBUG) && !defined(MMGR)
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
const COLORREF CStatusCtrl::m_ColTable[16] = {RGB(255, 255, 255),
RGB(0, 0, 0),
RGB(0, 0, 128),
RGB(0, 128, 0),
RGB(255, 0, 0),
RGB(128, 0, 0),
RGB(128, 0, 128),
RGB(128, 128, 0),
RGB(255, 255, 0),
RGB(0, 255, 0),
RGB(0, 128, 128),
RGB(0, 255, 255),
RGB(0, 0, 255),
RGB(255, 0, 255),
RGB(128, 128, 128),
RGB(192, 192, 192)
};
/////////////////////////////////////////////////////////////////////////////
// CStatusCtrl
CStatusCtrl::CStatusCtrl()
{
m_doPopupCursor = FALSE;
m_bEmpty = TRUE;
m_nMoveToBottom = 0;
m_nTimerID = 0;
m_headerPos = 0;
m_runTimer = 0;
}
CStatusCtrl::~CStatusCtrl()
{
}
BEGIN_MESSAGE_MAP(CStatusCtrl, CRichEditCtrl)
//{{AFX_MSG_MAP(CStatusCtrl)
ON_WM_ERASEBKGND()
ON_WM_CONTEXTMENU()
ON_WM_SETCURSOR()
ON_COMMAND(ID_OUTPUTCONTEXT_CLEARALL, OnOutputcontextClearall)
ON_COMMAND(ID_OUTPUTCONTEXT_COPYTOCLIPBOARD, OnOutputcontextCopytoclipboard)
ON_WM_CREATE()
ON_WM_TIMER()
ON_WM_RBUTTONUP()
ON_WM_MOUSEWHEEL()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// Behandlungsroutinen für Nachrichten CStatusCtrl
BOOL CStatusCtrl::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}
void CStatusCtrl::OnContextMenu(CWnd* pWnd, CPoint point)
{
ClientToScreen(&point);
CMenu menu;
menu.LoadMenu(IDR_OUTPUTCONTEXT);
CMenu* pPopup = menu.GetSubMenu(0);
ASSERT(pPopup != NULL);
CWnd* pWndPopupOwner = this;
//while (pWndPopupOwner->GetStyle() & WS_CHILD)
// pWndPopupOwner = pWndPopupOwner->GetParent();
if (!GetLineCount())
{
pPopup->EnableMenuItem(ID_OUTPUTCONTEXT_COPYTOCLIPBOARD,MF_GRAYED);
pPopup->EnableMenuItem(ID_OUTPUTCONTEXT_CLEARALL,MF_GRAYED);
}
HCURSOR hCursor;
hCursor = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
m_doPopupCursor = TRUE;
SetCursor(hCursor);
pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y,
pWndPopupOwner);
}
BOOL CStatusCtrl::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if (!m_doPopupCursor)
{
m_doPopupCursor = 0;
return CWnd::OnSetCursor(pWnd, nHitTest, message );
}
else
m_doPopupCursor = 0;
return 0;
}
DWORD __stdcall CStatusCtrl::RichEditStreamInCallback(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
char* output = (char*)pbBuff;
CStatusCtrl *pThis = (CStatusCtrl *)dwCookie;
if (pThis->m_headerPos != -1)
{
int len = pThis->m_RTFHeader.GetLength() - pThis->m_headerPos;
if (len > cb)
{
pThis->m_headerPos = cb;
len = cb;
}
else
pThis->m_headerPos = -1;
memcpy(output, (const char*)pThis->m_RTFHeader, len);
*pcb = len;
}
else
{
*pcb = 0;
if (pThis->m_statusBuffer.empty())
return 0;
t_buffer &buffer = pThis->m_statusBuffer.front();
if (buffer.status != _T(""))
{
if (buffer.pos == -1)
{
if (pThis->m_bEmpty)
{
pThis->m_bEmpty = false;
memcpy(output, "\\cf", 3);
output += 3;
cb -= 3;
*pcb += 3;
}
else
{
memcpy(output, "\\par \\cf", 8);
output += 8;
cb -= 8;
*pcb += 8;
}
switch (buffer.type)
{
default:
case 0:
*(output++) = '2';
break;
case 1:
*(output++) = '5';
break;
case 2:
*(output++) = '3';
break;
case 3:
*(output++) = '4';
break;
}
buffer.pos = 0;
}
LPCTSTR status = buffer.status;
LPCTSTR p = status + buffer.pos;
while (*p && cb > 9)
{
switch (*p)
{
case '\\':
*(output++) = '\\';
*(output++) = '\\';
cb -= 2;
*pcb += 2;
break;
case '{':
*(output++) = '\\';
*(output++) = '{';
cb -= 2;
*pcb += 2;
break;
case '}':
*(output++) = '\\';
*(output++) = '}';
cb -= 2;
*pcb += 2;
break;
case '\r':
break;
case '\n':
*(output++) = '\\';
*(output++) = 's';
*(output++) = 't';
*(output++) = 'a';
*(output++) = 't';
*(output++) = 'u';
*(output++) = 's';
cb -= 7;
*pcb += 7;
break;
default:
if (*p > 127)
{
int w = sprintf(output, "\\u%d?", (unsigned short)*p);
output += w;
cb -= w;
*pcb += w;
}
else
{
*(output++) = (char)*p;
cb--;
(*pcb)++;
}
}
p++;
}
if (!*p)
{
pThis->m_statusBuffer.pop_front();
if (pThis->m_statusBuffer.empty())
{
memcpy(output, "} ", 2);
output += 2;
*pcb += 2;
}
else
{
*(output++) = ' ';
(*pcb)++;
}
}
else
buffer.pos = p - status;
}
else
{
pThis->m_statusBuffer.pop_front();
if (pThis->m_statusBuffer.empty())
{
memcpy(output, "} ", 2);
output += 2;
*pcb += 2;
}
}
}
return 0;
}
void CStatusCtrl::OnOutputcontextClearall()
{
t_buffer buffer;
buffer.status = _T("");
buffer.pos = -1;
buffer.type = 0;
m_statusBuffer.push_back(buffer);
DoStreamIn();
SetSel(-1, -1);
LimitText(1000*1000);
m_bEmpty = TRUE;
m_nMoveToBottom = 0;
}
void CStatusCtrl::OnOutputcontextCopytoclipboard()
{
long nStart, nEnd;
GetSel(nStart, nEnd);
if (nStart == nEnd)
{
HideSelection(TRUE, FALSE);
SetSel(0, -1);
Copy();
SetSel(nStart, nEnd);
HideSelection(FALSE, FALSE);
}
else
Copy();
}
int CStatusCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CRichEditCtrl::OnCreate(lpCreateStruct) == -1)
return -1;
USES_CONVERSION;
m_RTFHeader = "{\\rtf1\\ansi\\deff0";
HFONT hSysFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
LOGFONT lf;
CFont* pFont = CFont::FromHandle( hSysFont );
pFont->GetLogFont( &lf );
LOGFONT m_lfFont;
pFont->GetLogFont(&m_lfFont);
m_RTFHeader += "{\\fonttbl{\\f0\\fnil "+ CString(m_lfFont.lfFaceName)+";}}";
m_RTFHeader += "{\\colortbl ;";
for (int i=0; i<16; i++)
{
CString tmp;
tmp.Format(_T("\\red%d\\green%d\\blue%d;"), GetRValue(m_ColTable[i]), GetGValue(m_ColTable[i]), GetBValue(m_ColTable[i]));
m_RTFHeader+=tmp;
}
m_RTFHeader += "}";
int pointsize = (-m_lfFont.lfHeight*72/ GetDeviceCaps(GetDC()->GetSafeHdc(), LOGPIXELSY))*2;
CString tmp;
tmp.Format(_T("%d"), pointsize);
m_RTFHeader += "\\uc1\\pard\\fi-200\\li200\\tx200\\f0\\fs"+tmp; //180*m_nAvgCharWidth;
t_buffer buffer;
buffer.status = _T("");
buffer.pos = -1;
buffer.type = 0;
m_statusBuffer.push_back(buffer);
m_headerPos = 0;
DoStreamIn();
SetSel(-1, -1);
LimitText(1000*1000);
return 0;
}
void CStatusCtrl::ShowStatus(LPCTSTR status, int nType)
{
t_buffer buffer;
buffer.status = status;
buffer.type = nType;
buffer.pos = -1;
m_statusBuffer.push_back(buffer);
if (!m_runTimer)
{
Run();
m_runTimer = SetTimer(1339, 250, 0);
}
return;
}
void CStatusCtrl::Run()
{
if (m_statusBuffer.empty())
return;
m_headerPos = 0;
CWnd *pFocusWnd = GetFocus();
if (pFocusWnd && pFocusWnd == this)
AfxGetMainWnd()->SetFocus();
long nStart, nEnd;
GetSel(nStart, nEnd);
BOOL nScrollToEnd = FALSE;
int num = 0; //this is the number of visible lines
CRect rect;
GetRect(rect);
int height = rect.Height();
for (int i = GetFirstVisibleLine();
i < GetLineCount() && GetCharPos(LineIndex(i)).y < height;
i++)
num++;
if (GetFirstVisibleLine() + num+m_nMoveToBottom >= GetLineCount())
nScrollToEnd = TRUE;
HideSelection(TRUE, FALSE);
SetSel(-1, -1);
DoStreamIn(SFF_SELECTION);
int count = GetLineCount();
if (count > 1000)
{
count = count - 1000;
int index = LineIndex(count);
nStart -= index;
nEnd -= index;
if (nStart < 0)
nEnd = 0;
if (nEnd < 0)
nEnd = 0;
SetSel(0, index);
ReplaceSel(_T(""));
}
SetSel(nStart, nEnd);
if (pFocusWnd && pFocusWnd == this)
SetFocus();
HideSelection(FALSE, FALSE);
if (nScrollToEnd)
{
if (nStart != nEnd && (LineFromChar(nStart) >= GetFirstVisibleLine() && LineFromChar(nStart) <= GetFirstVisibleLine() + num ||
LineFromChar(nEnd) >= GetFirstVisibleLine() && LineFromChar(nEnd) <= GetFirstVisibleLine() + num))
LineScroll(1);
else
{
m_nMoveToBottom++;
if (!m_nTimerID)
m_nTimerID = SetTimer(654, 25, NULL);
}
}
}
void CStatusCtrl::OnTimer(UINT_PTR nIDEvent)
{
if (nIDEvent == m_nTimerID)
{
if (m_nMoveToBottom)
{
SendMessage(WM_VSCROLL, SB_BOTTOM, 0);
m_nMoveToBottom = 0;
}
KillTimer(m_nTimerID);
m_nTimerID = 0;
}
else if (nIDEvent == static_cast<UINT>(m_runTimer))
{
KillTimer(m_runTimer);
m_runTimer = 0;
Run();
}
CRichEditCtrl::OnTimer(nIDEvent);
}
void CStatusCtrl::OnRButtonUp(UINT nFlags, CPoint point)
{
ClientToScreen(&point);
CMenu menu;
menu.LoadMenu(IDR_OUTPUTCONTEXT);
CMenu* pPopup = menu.GetSubMenu(0);
ASSERT(pPopup != NULL);
CWnd* pWndPopupOwner = this;
//while (pWndPopupOwner->GetStyle() & WS_CHILD)
// pWndPopupOwner = pWndPopupOwner->GetParent();
if (!GetLineCount())
{
pPopup->EnableMenuItem(ID_OUTPUTCONTEXT_COPYTOCLIPBOARD,MF_GRAYED);
pPopup->EnableMenuItem(ID_OUTPUTCONTEXT_CLEARALL,MF_GRAYED);
}
HCURSOR hCursor;
hCursor = AfxGetApp()->LoadStandardCursor( IDC_ARROW );
m_doPopupCursor = TRUE;
SetCursor(hCursor);
pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y,
pWndPopupOwner);
}
BOOL CStatusCtrl::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
OSVERSIONINFO info = {0};
info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&info);
if (info.dwMajorVersion >= 5)
return CRichEditCtrl::OnMouseWheel(nFlags, zDelta, pt);
LineScroll(-zDelta / 120 * 3);
return TRUE;
}
void CStatusCtrl::DoStreamIn(int extraFlags)
{
EDITSTREAM es;
es.dwCookie = (DWORD)this; // Pass a pointer to the CString to the callback function
es.pfnCallback = RichEditStreamInCallback; // Specify the pointer to the callback function.
#ifdef _UNICODE
// extraFlags |= SF_UNICODE;
#endif
StreamIn(extraFlags | SF_RTF, es); // Perform the streaming
}
|