|
// Driver.cpp : Implementation of CDriver
//
// Author : David Shepherd
// Copyright (c) 2002, DaeDoe-Software
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Driver.h"
CDriver::CDriver()
{
// initialise everything
m_LockCount=0;
}
HRESULT CDriver::FinalConstruct()
{
return S_OK;
}
void CDriver::FinalRelease()
{
}
DWORD CDriver::GetLineCount()
{
// get the ICodeMax interface
if(m_spEditor==NULL)
{
throw std::exception();
}
CComQIPtr<CodeMax::ICodeMax> spCodeMax(m_spEditor);
if(spCodeMax==NULL)
{
throw std::exception();
}
// return the number of lines in the editor
long LineCount=0;
if(!SUCCEEDED(spCodeMax->get_LineCount(&LineCount)))
{
throw std::exception();
}
return LineCount;
}
DWORD CDriver::GetLineLength(DWORD Line)
{
// get the ICodeMax interface
if(m_spEditor==NULL)
{
throw std::exception();
}
CComQIPtr<CodeMax::ICodeMax> spCodeMax(m_spEditor);
if(spCodeMax==NULL)
{
throw std::exception();
}
// return the length of the specified line in the editor
long LineLength=0;
if(!SUCCEEDED(spCodeMax->GetLineLength(Line,&LineLength)))
{
throw std::exception();
}
return LineLength;
}
CComPtr<CodeMax::IPosition> CDriver::CreatePosition(DWORD Line,DWORD Col)
{
// create the position
CComPtr<CodeMax::IPosition> spPosition;
if(!SUCCEEDED(spPosition.CoCreateInstance(__uuidof(CodeMax::Position))))
{
throw std::exception();
}
// set the line number
if(!SUCCEEDED(spPosition->put_LineNo(Line)))
{
throw std::exception();
}
// set the column number
if(!SUCCEEDED(spPosition->put_ColNo(Col)))
{
throw std::exception();
}
return spPosition;
}
CComPtr<CodeMax::IRange> CDriver::CreateRange(
DWORD StartLine,DWORD StartCol,DWORD EndLine,DWORD EndCol)
{
// create the range
CComPtr<CodeMax::IRange> spRange;
if(!SUCCEEDED(spRange.CoCreateInstance(__uuidof(CodeMax::Range))))
{
throw std::exception();
}
// disable column selection
if(!SUCCEEDED(spRange->put_ColumnSel(VARIANT_FALSE)))
{
throw std::exception();
}
// set the start line number
if(!SUCCEEDED(spRange->put_StartLineNo(StartLine)))
{
throw std::exception();
}
// set the start column number
if(!SUCCEEDED(spRange->put_StartColNo(StartCol)))
{
throw std::exception();
}
// set the end line number
if(!SUCCEEDED(spRange->put_EndLineNo(EndLine)))
{
throw std::exception();
}
// set the end column number
if(!SUCCEEDED(spRange->put_EndColNo(EndCol)))
{
throw std::exception();
}
return spRange;
}
STDMETHODIMP CDriver::get_Editor(IUnknown** pVal)
{
IMP_BEGIN
// check parameters
if(pVal==NULL)
{
throw CHResult(E_POINTER);
}
// get the editor
*pVal=m_spEditor;
if(*pVal!=NULL) // add ref it
{
(void)(*pVal)->AddRef();
}
IMP_END
return RetVal;
}
STDMETHODIMP CDriver::put_Editor(IUnknown* newVal)
{
IMP_BEGIN
// set the editor
m_spEditor=newVal;
IMP_END
return RetVal;
}
STDMETHODIMP CDriver::LockExternal(/*[in]*/ BOOL Lock)
{
IMP_BEGIN
// get the ICodeMax interface
if(m_spEditor==NULL)
{
throw CHResult(E_FAIL);
}
CComQIPtr<CodeMax::ICodeMax> spCodeMax(m_spEditor);
if(spCodeMax==NULL)
{
throw CHResult(E_FAIL);
}
// update the lock count
Lock ? m_LockCount++ : m_LockCount--;
// update the editor state
if(m_LockCount > 0)
{
// read only
if(!SUCCEEDED(spCodeMax->put_ReadOnly(VARIANT_TRUE)))
{
throw CHResult(E_FAIL);
}
}
else
{
// read writable
if(!SUCCEEDED(spCodeMax->put_ReadOnly(VARIANT_FALSE)))
{
throw CHResult(E_FAIL);
}
}
IMP_END
return RetVal;
}
STDMETHODIMP CDriver::GetLineCount(/*[out]*/ DWORD *pCount)
{
IMP_BEGIN
// check parameters
if(pCount==NULL)
{
throw CHResult(E_POINTER);
}
// return the number of lines in the editor
*pCount=GetLineCount();
IMP_END
return RetVal;
}
STDMETHODIMP CDriver::FindText(
/*[in]*/ DWORD Start,
/*[in]*/ LPCOLESTR pText,
/*[out]*/ BOOL *pFound,
/*[out]*/ DWORD *pLine)
{
IMP_BEGIN
// check parameters
if(Start >= GetLineCount())
{
throw CHResult(E_INVALIDARG);
}
if(pText==NULL)
{
throw CHResult(E_POINTER);
}
if(wcslen(pText)==0)
{
throw CHResult(E_INVALIDARG);
}
if(pFound==NULL)
{
throw CHResult(E_POINTER);
}
if(pLine==NULL)
{
throw CHResult(E_POINTER);
}
// get the ICodeMax interface
if(m_spEditor==NULL)
{
throw CHResult(E_FAIL);
}
CComQIPtr<CodeMax::ICodeMax> spCodeMax(m_spEditor);
if(spCodeMax==NULL)
{
throw CHResult(E_FAIL);
}
// look for the text in each line
*pFound=FALSE;
for(long l=Start; l<(long)GetLineCount(); l++)
{
// get the next line
CComBSTR Line;
if(!SUCCEEDED(spCodeMax->GetLine(l,&Line)))
{
throw CHResult(E_FAIL);
}
// look for an exact substring match
std::wstring str(BSTR2W(Line));
if(str.find(pText)!=std::wstring::npos)
{
*pLine=l;
*pFound=TRUE;
break; // finished
}
}
IMP_END
return RetVal;
}
STDMETHODIMP CDriver::InsertLines(
/*[in]*/ DWORD Start,
/*[in]*/ DWORD Count,
/*[in, size_is(Count)]*/ LPCOLESTR *pLines)
{
IMP_BEGIN
// check parameters
if(Start > GetLineCount())
{
throw CHResult(E_INVALIDARG);
}
if(pLines==NULL)
{
throw CHResult(E_POINTER);
}
// get the ICodeMax interface
if(m_spEditor==NULL)
{
throw CHResult(E_FAIL);
}
CComQIPtr<CodeMax::ICodeMax> spCodeMax(m_spEditor);
if(spCodeMax==NULL)
{
throw CHResult(E_FAIL);
}
if(Count==0) // special case
{
throw CHResult(S_OK);
}
// create CRLF tokenised lines
std::list<std::wstring> Lines;
ComServerStringArrayFromClient(Count,pLines,Lines);
std::wstring TokenisedLines;
if(Start==GetLineCount())
{
TokenisedLines=L"\r\n"; // required to create a new line
}
std::list<std::wstring>::const_iterator iter=Lines.begin();
while(iter!=Lines.end())
{
TokenisedLines+=iter->c_str();
iter++;
if(iter!=Lines.end()) // if more lines follow
{
TokenisedLines+=L"\r\n";
}
}
// begin following lines on a new line
if(Start!=GetLineCount())
{
TokenisedLines+=L"\r\n";
}
// get the insertion point
CComPtr<CodeMax::IPosition> spPosition;
if(Start==GetLineCount())
{
// end of last line
spPosition=CreatePosition(Start-1,GetLineLength(Start-1));
}
else
{
// start of new line
spPosition=CreatePosition(Start,0);
}
// insert the text
if(!SUCCEEDED(spCodeMax->InsertText(
CComBSTR(TokenisedLines.c_str()),spPosition)))
{
throw CHResult(E_FAIL);
}
IMP_END
return RetVal;
}
STDMETHODIMP CDriver::GetLines(
/*[in]*/ DWORD Start,
/*[in]*/ DWORD Count,
/*[out, size_is(,Count)]*/ LPOLESTR **ppLines)
{
IMP_BEGIN
// check parameters
if(Start >= GetLineCount())
{
throw CHResult(E_INVALIDARG);
}
if(Start+Count > GetLineCount())
{
throw CHResult(E_INVALIDARG);
}
if(ppLines==NULL)
{
throw CHResult(E_POINTER);
}
// get the ICodeMax interface
if(m_spEditor==NULL)
{
throw CHResult(E_FAIL);
}
CComQIPtr<CodeMax::ICodeMax> spCodeMax(m_spEditor);
if(spCodeMax==NULL)
{
throw CHResult(E_FAIL);
}
// get the required lines
std::list<std::wstring> Lines;
for(long l=Start; l<(long)(Start+Count); l++)
{
// get the next line
CComBSTR Line;
if(!SUCCEEDED(spCodeMax->GetLine(l,&Line)))
{
throw CHResult(E_FAIL);
}
// add it to the array
Lines.push_back(BSTR2W(Line));
}
*ppLines=const_cast<LPOLESTR*>(ComServerStringArrayToClient(Lines));
IMP_END
return RetVal;
}
STDMETHODIMP CDriver::DeleteLines(
/*[in]*/ DWORD Start,
/*[in]*/ DWORD Count)
{
IMP_BEGIN
// check parameters
if(Start >= GetLineCount())
{
throw CHResult(E_INVALIDARG);
}
if(Start+Count > GetLineCount())
{
throw CHResult(E_INVALIDARG);
}
// get the ICodeMax interface
if(m_spEditor==NULL)
{
throw CHResult(E_FAIL);
}
CComQIPtr<CodeMax::ICodeMax> spCodeMax(m_spEditor);
if(spCodeMax==NULL)
{
throw CHResult(E_FAIL);
}
if(Count==0) // special case
{
throw CHResult(S_OK);
}
// get the last line to delete
DWORD End=Start+Count-1;
// deletion range
CComPtr<CodeMax::IRange> spRange;
// case (a)
// there are no preceding or following lines
if(Start==0 and End==GetLineCount()-1)
{
// create the deletion range
spRange=CreateRange(Start,0,End,GetLineLength(End));
}
// case (b)
// there are no preceding lines
else if(Start==0)
{
// create the deletion range
spRange=CreateRange(Start,0,End+1,0);
}
// case (c)
// there are no following lines
else if(End==GetLineCount()-1)
{
// create the deletion range
spRange=CreateRange(
Start-1,GetLineLength(Start-1),End,GetLineLength(End));
}
// select the deletion range
if(!SUCCEEDED(spCodeMax->SetSel(spRange,VARIANT_FALSE)))
{
throw CHResult(E_FAIL);
}
// delete the lines
if(!SUCCEEDED(spCodeMax->DeleteSel()))
{
throw CHResult(E_FAIL);
}
IMP_END
return RetVal;
}
STDMETHODIMP CDriver::ModifyLines(
/*[in]*/ DWORD Start,
/*[in]*/ DWORD End,
/*[in]*/ DWORD Count,
/*[in, size_is(Count)]*/ LPCOLESTR *pLines)
{
IMP_BEGIN
// todo : add this when required
throw CHResult(E_NOTIMPL);
// todo : ensure the modified flag is correct
IMP_END
return RetVal;
}
STDMETHODIMP CDriver::GoToLine(/*[in]*/ DWORD Line)
{
IMP_BEGIN
// check parameters
if(Line >= GetLineCount())
{
throw CHResult(E_INVALIDARG);
}
// get the ICodeMax interface
if(m_spEditor==NULL)
{
throw CHResult(E_FAIL);
}
CComQIPtr<CodeMax::ICodeMax> spCodeMax(m_spEditor);
if(spCodeMax==NULL)
{
throw CHResult(E_FAIL);
}
// move the cursor to the requested line
if(!SUCCEEDED(spCodeMax->SetCaretPos(Line,0)))
{
throw CHResult(E_FAIL);
}
// get the IOleInPlaceObject interface
CComQIPtr<IOleInPlaceObject> spOleInPlaceObject(spCodeMax);
if(spOleInPlaceObject==NULL)
{
throw CHResult(E_FAIL);
}
// give focus to the editor
HWND hWnd=NULL;
if(!SUCCEEDED(spOleInPlaceObject->GetWindow(&hWnd)))
{
throw CHResult(E_FAIL);
}
(void)SetFocus(hWnd);
IMP_END
return RetVal;
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.