// FVSDKLogList.cpp : implementation file
//
// Copyright © 1997-2008 - Rhino Software, Inc.
// FTP Voyager® is a registered trademark of Rhino Software, Inc.
// http://www.RhinoSoft.com/
//
// Author: Mark P. Peterson
// Date: August 19, 2005
//
// You are free to use/modify this code but leave this header intact.
// This code is public domain so you are free to use it any of your
// applications (Freeware, Trialware, Commercial, etc.). FTP Voyager,
// the FTP Voyager Software Development Kit, and FtpTree ActiveX Control
// are not public domain. Any registration IDs or non-public domain software
// from Rhino Software, Inc. remains copyrighted. For more information
// refer to the license agreement distributed with the FTP Voyager SDK.
//
// If you decide to use the FTP Voyager Software Development Kit, or FtpTree
// ActiveX control, you must first purchase a license. For more information
// visit http://www.RhinoSoft.com/
//------------------------------------------------------------------------------
//
// NOTE: This FTP Voyager SDK sample is more complex than the C Sample found in
// C:\Program Files\RhinoSoft.com\FVSDK\SampleC
// The intent of this sample is to cover all of the FTP Voyager SDK's functionality
//
//------------------------------------------------------------------------------
#include "stdafx.h"
#include "SampleCPP.h"
#include "FVSDKLogList.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
/////////////////////////////////////////////////////////////////////////////
// CFVSDKLogList dialog
CFVSDKLogList::CFVSDKLogList()
{
// init vars
m_nMaxPromptLen = 0;
m_bSetParaFormat = FALSE;
m_nLogLines = 0;
// set the colors to use in the rich edit control log
m_clrCommand = RGB(0, 0x7f, 0x00); // green
m_clrResponse = RGB(0, 0, 0); // black
m_clrError = RGB(0x7f, 0, 0); // red
m_clrStatus = RGB(0, 0, 0xff); // light blue
} // CFVSDKLogList
CFVSDKLogList::~CFVSDKLogList()
{
} // ~CFVSDKLogList
/////////////////////////////////////////////////////////////////////////////
// CFVSDKLogList log operations
void CALLBACK CFVSDKLogList::LogTextCallback(FVSDK_CALLBACK_DATA pvLogTextData, UINT nType, LPCTSTR pszText)
{
// if we have a pointer to the control, do the actual callback
if (pvLogTextData) {
// log the text to the rich edit control
((CFVSDKLogList *) pvLogTextData)->LogText(nType, pszText);
} // if
} // LogTextCallback
char *detab_str(char* buf, char* str)
{
int i = -1, ii = 0;
while (buf[++i]) {
if (buf[i] == '\t') {
do {
str[ii] = ' ';
++ii;
} while (! ((ii % 8) == NULL));
--ii;
} /* if */
else
str[ii] = buf[i];
++ii;
} /* while */
if (ii >= 1)
str[ii] = '\0';
return (str);
} /* detab_str */
void CFVSDKLogList::LogText(UINT nType, LPCTSTR pszText)
{
char szBuf[4096];
CString sStr, sOutput;
int anStrs[] = {IDS_COMMAND_PROMPT, 0, 0, IDS_STATUS_PROMPT, IDS_ERROR_PROMPT};
// is there a prompt associated with the item
if ((nType < (sizeof(anStrs) / sizeof(anStrs[0]))) && (anStrs[nType])) {
// load the string from our resources
sOutput.LoadString(anStrs[nType]);
// get rid of trailing space
sOutput.TrimRight();
} // if
// get the line of text
if (*pszText)
sStr = detab_str((char *) pszText, szBuf);
// append the rest
sOutput += ("\t" + sStr);
// new line
if (m_nLogLines > 0)
AppendText("\r\n");
// new line
++m_nLogLines;
// write it out
OutputLine(nType, sOutput);
} // LogText
/////////////////////////////////////////////////////////////////////////////
// CFVSDKLogList rich edit control operations
void CFVSDKLogList::SetupCallback(FVSDK_Session* pSession)
{
// setup the callback function
pSession->pfnLogText = LogTextCallback;
pSession->pvLogTextData = this;
// initialize the rich edit control
Init();
} // SetupCallback
void CFVSDKLogList::Init()
{
// initialize if we're up
if ((m_hWnd) && (::IsWindow(m_hWnd)) && (! m_bSetParaFormat)) {
LOGFONT LogFont;
int anStrs[] = {IDS_COMMAND_PROMPT, IDS_STATUS_PROMPT, IDS_ERROR_PROMPT, 0};
int nIndex = 0;
CHARFORMAT cfCharFormat;
// get the font
if (SystemParametersInfo(SPI_GETICONTITLELOGFONT, 0, &LogFont, 0)) {
// done with the font
if ((HFONT) m_Font)
m_Font.Detach();
// create indirect font
m_Font.CreateFontIndirect(&LogFont);
// set the default font
CWnd::SetFont(&m_Font);
} // if
// initialize the character format
cfCharFormat.dwMask = 0xffffffff;
cfCharFormat.cbSize = sizeof(cfCharFormat);
GetDefaultCharFormat(cfCharFormat);
// setup the font
strcpy(cfCharFormat.szFaceName, LogFont.lfFaceName);
// no auto color
cfCharFormat.dwEffects = 0;
// set the default character format
SetDefaultCharFormat(cfCharFormat);
// select the font
CDC* pDC = GetDC();
CFont* pFont = pDC->SelectObject(&m_Font);
// determine the number of pixels per inch
int nPixPerInch = pDC->GetDeviceCaps(LOGPIXELSX);
// initialize the tab stop to nothing
m_pfParaFormat.rgxTabs[0] = 0;
// determine the width
while (anStrs[nIndex]) {
CString sStr;
// load the string
sStr.LoadString(anStrs[nIndex]);
// get the text extent for the string
CSize Size = pDC->GetOutputTextExtent(sStr);
// calculate the number of TWIPS for the end of the string
Size.cx = (int) (((double) Size.cx / (double) nPixPerInch) * (double) 1440 /* twips per inch */);
// set the max size
m_pfParaFormat.rgxTabs[0] = max(m_pfParaFormat.rgxTabs[0], Size.cx);
// max prompt len
m_nMaxPromptLen = max(m_nMaxPromptLen, sStr.GetLength());
// next
++nIndex;
} // while
// restore the font
if (pFont)
pDC->SelectObject(pFont);
// release the DC
ReleaseDC(pDC);
// we have one tab stop
m_pfParaFormat.dwMask = PFM_TABSTOPS;
m_pfParaFormat.cTabCount = 1;
// set the size of the structure
m_pfParaFormat.cbSize = sizeof(m_pfParaFormat);
// set the default paragraph format
m_bSetParaFormat = SetParaFormat(m_pfParaFormat);
// only allow read
SetReadOnly(TRUE);
} // if
} // Init
void CFVSDKLogList::AppendText(LPCTSTR lpszText, CHARFORMAT* pcf /*=NULL*/)
{
long nEnd = GetTextLength();
// turn off redraw
SetRedraw(FALSE);
// reset the paragraph format
SetParaFormat(m_pfParaFormat);
// select the end
SetSel(nEnd, nEnd);
// change the selection format?
if (pcf)
SetSelectionCharFormat(*pcf);
// output the text
ReplaceSel(lpszText);
// what is the first character of the last line?
nEnd = LineIndex(LineFromChar(GetTextLength()));
// move to the first character of the last line, we do this so that we don't get a lot of flutter bang ...
// ... when lines need to scroll to the right horizontally
SetSel(nEnd, nEnd);
// scroll forward one line
LineScroll(1);
// turn redraw back on
SetRedraw(TRUE);
// redraw the whole window
Invalidate();
} // AppendText
void CFVSDKLogList::OutputLine(UINT nType, LPCTSTR lpszText)
{
CHARFORMAT cf;
// setup the record
cf.cbSize = sizeof(cf);
cf.dwEffects = 0;
cf.dwMask = CFM_COLOR;
// setup for the item
switch (nType) {
case FVSDK_COMMAND_LOG_TYPE :
cf.crTextColor = m_clrCommand;
break;
case FVSDK_RESPONSE_LOG_TYPE :
case FVSDK_UNSOLICITED_LOG_TYPE :
cf.crTextColor = m_clrResponse;
break;
case FVSDK_STATUS_LOG_TYPE :
cf.crTextColor = m_clrStatus;
break;
case FVSDK_ERROR_LOG_TYPE :
cf.crTextColor = m_clrError;
break;
} // switch
// output the text
AppendText(lpszText, &cf);
} // OutputLine
void CFVSDKLogList::ClearLog()
{
// select all
SetSel(0, -1);
// put in nothing
ReplaceSel("");
// nothing in the log
m_nLogLines = 0;
} // ClearLog