// MyCell - version 1.0
// Written by Yanxueming <yanxm2003@hotmail.com>
// Copyright (C) 2006-2008
// All rights reserved.
//
// The code and information is provided "as-is" without
// warranty of any kind, either expressed or implied.
//Yanxm 2007��12��25�� 10:14:43
#include "stdafx.h"
#include "../include/Workbook.h"
#include "../include/DefaultSymbols.h"
#include "../include/EditImp.h"
namespace mycell{
BEGIN_MSG_MAP_CPP(Workbook)
MESSAGE_HANDLER(WM_CREATE,OnCreate)
MESSAGE_HANDLER(WM_POSTCREATE,OnPostCreate)
MESSAGE_HANDLER(WM_SIZE,OnSize)
NOTIFY_CODE_HANDLER(TCN_SELCHANGE,OnTabItemChange)
MESSAGE_HANDLER(WM_THEMECHANGED, OnThemeChanged)
//MESSAGE_HANDLER(WM_ACTIVATEAPP,OnActivateApp)
//ALT_MSG_MAP(1) // Scroll
//ALT_MSG_MAP(2)
if(pCurSheet_){
// MESSAGE_HANDLER(WM_GETDLGCODE,eventImpl_.OnGetDlgCode)
// MESSAGE_HANDLER(WM_KILLFOCUS,eventImpl_.OnKillFocus)
MESSAGE_HANDLER(WM_VSCROLL,pCurSheet_->OnVScroll)
MESSAGE_HANDLER(WM_HSCROLL,pCurSheet_->OnHScroll)
MESSAGE_HANDLER(WM_MOUSEWHEEL, pCurSheet_->OnMouseWheel)
// MESSAGE_HANDLER(WM_KEYDOWN,eventImpl_.OnKeyEvent)
// MESSAGE_HANDLER(WM_CHAR,eventImpl_.OnKeyEvent)
// MESSAGE_HANDLER(WM_IME_COMPOSITION,eventImpl_.OnImeComposition)
// MESSAGE_HANDLER(WM_MOUSEMOVE, eventImpl_.OnMouseEvent)
// MESSAGE_HANDLER(WM_LBUTTONDBLCLK, eventImpl_.OnMouseEvent)
// MESSAGE_HANDLER(WM_LBUTTONDOWN, eventImpl_.OnMouseEvent)
// MESSAGE_HANDLER(WM_LBUTTONUP, eventImpl_.OnMouseEvent)
// MESSAGE_HANDLER(WM_RBUTTONDOWN, eventImpl_.OnMouseEvent)
// MESSAGE_HANDLER(WM_RBUTTONUP, eventImpl_.OnMouseEvent)
// MESSAGE_HANDLER(WM_THEMECHANGED, eventImpl_.OnThemeChanged)
// MESSAGE_HANDLER(WM_PAINT,eventImpl_.OnPaint)
}
//if (uMsg == WM_MOUSEMOVE || uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONUP )
// CHAIN_MSG_MAP_MEMBER(wndTabHScroll_);
ALT_MSG_MAP(1)//Scroll bar
END_MSG_MAP()
TCHAR Workbook::tooltipText_[MAX_CELLTEXT];
Workbook::Workbook():hWndListener_(NULL),wndSheet_(cellTypeFactory_)
,bits_(B_SHOWHSCROLLBAR|B_SHOWVSCROLLBAR)
//,bShowHScrollBar_(TRUE),bShowVScrollBar_(TRUE)
,selectionMode_(ESM_SINGLESELECTION)
{
Worksheet::tooltipCell_.set(-100,-100);
pCurSheet_=Worksheet_AddNewSheet();
pCurSheet_->SetName(_T("Sheet1"));
//render_.Init(pCurSheet_);
InitTypeFactory();
}
Workbook::~Workbook()
{
for(vector<Worksheet*>::iterator it=vecWorksheet_.begin();it!=vecWorksheet_.end();++it)
{
delete *it;
}
}
void Workbook::Clear()
{
pCurSheet_=NULL;
for(vector<Worksheet*>::iterator it=vecWorksheet_.begin();it!=vecWorksheet_.end();++it){
(*it)->clear();
(*it)->m_hWnd=NULL;
}
styleStore_.Clear();
}
void Workbook::InitTypeFactory()
{
using namespace mycell;
using namespace symbol;
//const BOOL bNoHeaderSymbol=!cellTypeFactory_.GetSymbol(ECT_ROWHEADER);
//const BOOL bNoColorSymbol=!cellTypeFactory_.GetSymbol(ECT_COLOR);
//const BOOL bNoCheckSymbol=!cellTypeFactory_.GetSymbol(ECT_CHECKBOX);
{
CComPtr<ICellSymbol> pSymbol;
CComObject<TextSymbol>* ps;
CComObject<TextSymbol>::CreateInstance(&ps);
ps->QueryInterface(IID_IUnknown,(void**)&pSymbol);
CComPtr<ICellSymbol> pFillSymbol;
CComObject<SimpleFillSymbol>* pfs;
CComObject<SimpleFillSymbol>::CreateInstance(&pfs);
pfs->QueryInterface(IID_IUnknown,(void**)&pFillSymbol);
for(size_t i=0;i<cellTypeFactory_.size();++i){
const ECellType ct=(ECellType)i;
if(!cellTypeFactory_.GetSymbol(ct))
cellTypeFactory_.SetSymbol(ct,pSymbol);
if(!cellTypeFactory_.GetFillSymbol(ct))
cellTypeFactory_.SetFillSymbol(ct,pFillSymbol);
}
}
//if(bNoCheckSymbol)
{
CComPtr<ICellSymbol> pSymbol;
CComObject<ThemeCheckBoxSymbol>* ps;
CComObject<ThemeCheckBoxSymbol>::CreateInstance(&ps);
//ps->OpenThemeData(wndSheet_.m_hWnd);
ps->QueryInterface(IID_IUnknown,(void**)&pSymbol);
cellTypeFactory_.SetSymbol(ECT_CHECKBOX,pSymbol);
}
//if(bNoHeaderSymbol)
{
CComPtr<ICellSymbol> pSymbol;
CComObject<HeaderSymbol>* ps;
CComObject<HeaderSymbol>::CreateInstance(&ps);
ps->QueryInterface(IID_IUnknown,(void**)&pSymbol);
cellTypeFactory_.SetSymbol(ECT_ROWHEADER,pSymbol);
cellTypeFactory_.SetSymbol(ECT_COLHEADER,pSymbol);
cellTypeFactory_.SetSymbol(ECT_HEADERCORNER,pSymbol);
}
//if(bNoColorSymbol)
{
CComPtr<ICellSymbol> pSymbol;
CComObject<ColorSymbol>* ps;
CComObject<ColorSymbol>::CreateInstance(&ps);
ps->QueryInterface(IID_IUnknown,(void**)&pSymbol);
cellTypeFactory_.SetSymbol(ECT_COLOR,pSymbol);
}
CComPtr<ICellEditor> pEditor;
{
CComObject<editor::TextEditor>* pEdit;
CComObject<editor::TextEditor>::CreateInstance(&pEdit);
pEdit->Init(this);
pEdit->QueryInterface(IID_IUnknown,(void**)&pEditor);
ECellType ect[]={
ECT_TEXT,
ECT_UINT,
ECT_INT,
ECT_DOUBLE,
ECT_UDOUBLE,
ECT_DEGREE
};
for(size_t i=0;i<sizeof(ect)/sizeof(ect[0]);++i){
if(!cellTypeFactory_.GetEditor(ect[i]))
cellTypeFactory_.SetEditor(ect[i],pEditor);
}
}
{
pEditor.Release();
CComObject<editor::CheckBoxEditor>* pEdit;
CComObject<editor::CheckBoxEditor>::CreateInstance(&pEdit);
pEdit->Init(this);
pEdit->QueryInterface(IID_IUnknown,(void**)&pEditor);
cellTypeFactory_.SetEditor(ECT_CHECKBOX,pEditor);
}
}
int Workbook::Worksheet_FindPosByName(LPCTSTR lpszSheetName)const
{
CString strSheetName(lpszSheetName);
strSheetName.MakeLower();
for(vector<Worksheet*>::const_iterator it=vecWorksheet_.begin();it!=vecWorksheet_.end();++it)
{
CString name=(*it)->GetName();
name.MakeLower();
if(strSheetName==name)
return int(it-vecWorksheet_.begin());
}
return -1;
}
Worksheet* Workbook::Worksheet_FindByName(LPCTSTR lpszSheetName)const
{
CString strSheetName(lpszSheetName);
strSheetName.MakeLower();
for(vector<Worksheet*>::const_iterator it=vecWorksheet_.begin();it!=vecWorksheet_.end();++it)
{
CString name=(*it)->GetName();
name.MakeLower();
if(strSheetName==name)
return (*it);
}
return NULL;
}
Worksheet* Workbook::Worksheet_AddNewSheet()
{
Worksheet* pSheet=new Worksheet(this);
if(m_hWnd){
TCHAR buf[32];
wndTabHScroll_.GetFlatTabCtrl()->InsertItem((int)vecWorksheet_.size(),GetNewSheetName(buf));
pSheet->SetName(buf);
pSheet->Scroll_SetScrollBars(wndTabHScroll_.m_wndScroll/*wndHScroll_*/,wndVScroll_);
}
vecWorksheet_.push_back(pSheet);
return pSheet;
}
void Workbook::Worksheet_DeleteSheet(size_t idx)
{
_ASSERT(idx<vecWorksheet_.size());
Worksheet* pSheet=vecWorksheet_[idx];
if(pCurSheet_==pSheet){
if(idx<vecWorksheet_.size()-1)
pCurSheet_=vecWorksheet_[++idx];
else if(idx>0)
pCurSheet_=vecWorksheet_[--idx];
else
pCurSheet_=NULL;
}
delete pSheet;
wndTabHScroll_.GetFlatTabCtrl()->DeleteItem((int)idx);
vecWorksheet_.erase(vecWorksheet_.begin()+idx);
}
Worksheet* Workbook::Worksheet_SetActiveSheet(size_t idx)
{
_ASSERT(idx<vecWorksheet_.size());
if(pCurSheet_)
pCurSheet_->m_hWnd=NULL;
pCurSheet_=vecWorksheet_[idx];
wndSheet_.SetWorksheet(pCurSheet_);
wndTabHScroll_.GetFlatTabCtrl()->SetCurSel((int)idx);
return pCurSheet_;
}
BOOL Workbook::SubclassWindow(HWND hWnd)
{
BOOL bRet=baseWnd::SubclassWindow(hWnd);
CreateChildren();
//#pragma warning( disable : 4312 )
// cf_.standardCursor=(HCURSOR)SetClassLong(hWnd,GCL_HCURSOR,NULL);
// if(!cf_.standardCursor){
// cf_.standardCursor=LoadCursor(NULL,IDC_ARROW);
// }
//#pragma warning( default : 4312 )
// //pCurSheet_->m_hWnd=wndSheet_.m_hWnd;
// CreateTT();
return bRet;
}
// Sends a message to the listener in the form of a WM_NOTIFY message with
// a NM_SHEETVIEW structure attached
HRESULT Workbook::SendNotifyMessageToListener(int nRow, int nCol, int nNotifyCode,LPARAM lParam,BOOL* pbHandled) const
{
if(!m_hWnd)
return S_FALSE;
HWND hWndListener=get_listener();
if(!hWndListener)
hWndListener=GetParent();
NM_SHEETVIEW nmgv;
nmgv.hr = S_OK;
nmgv.bHandled =FALSE;
if (hWndListener && ::IsWindow(hWndListener) && IsWindow()){
nmgv.row = nRow;
nmgv.col = nCol;
nmgv.lParam = lParam;
nmgv.hdr.hwndFrom = m_hWnd;
nmgv.hdr.idFrom = GetDlgCtrlID();
nmgv.hdr.code = nNotifyCode;
::SendMessage(hWndListener,WM_NOTIFY,nmgv.hdr.idFrom, (LPARAM)&nmgv);
}
if(pbHandled)
*pbHandled=nmgv.bHandled;
return nmgv.hr;
}
void Workbook::CreateChildren()
{
//wndHScroll_.Create(this, 1, m_hWnd, CWindow::rcDefault, NULL, WS_CHILD /*| WS_VISIBLE*/);
//wndHScroll_.SetFont((HFONT)::SendMessage(GetParent(), WM_GETFONT, 0, 0));
wndVScroll_.Create(this, 1, m_hWnd, CWindow::rcDefault, NULL, WS_CHILD /*| WS_VISIBLE*/ |SBS_VERT);
wndTabHScroll_.Create(m_hWnd);//*this, CWindow::rcDefault/*rcPos*/, NULL, WS_CHILD|WS_CLIPCHILDREN | WS_VISIBLE);
wndTabHScroll_.SetFont((HFONT)::SendMessage(GetParent(), WM_GETFONT, 0, 0));
//wndTabHScroll_.GetFlatTabCtrl()->InsertItem(0, _T("Build"));
//wndTabHScroll_.GetFlatTabCtrl()->InsertItem(1, _T("Debug"));
//wndTabHScroll_.GetFlatTabCtrl()->InsertItem(2, _T("Find in File 1"));
wndVScroll_.SetFont((HFONT)::SendMessage(GetParent(), WM_GETFONT, 0, 0));
wndBottomRightCorner_.Create(m_hWnd, CWindow::rcDefault, NULL, WS_CHILD|WS_VISIBLE|WS_DISABLED|SBS_SIZEBOX/*|SBS_SIZEBOXBOTTOMRIGHTALIGN*/);
//for(vector<Worksheet*>::iterator it=vecWorksheet_.begin();it!=vecWorksheet_.end();++it){
for(size_t i=0;i<vecWorksheet_.size();++i){
Worksheet* pSheet=vecWorksheet_[i];
const LPCTSTR lpstr=pSheet->GetName();
wndTabHScroll_.GetFlatTabCtrl()->InsertItem((int)i,lpstr);
pSheet->Scroll_SetScrollBars(wndTabHScroll_.m_wndScroll,wndVScroll_);
}
wndSheet_.Create(m_hWnd,CWindow::rcDefault,NULL,WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
wndSheet_.SetWorksheet(pCurSheet_);
PostMessage(WM_POSTCREATE);
cellTypeFactory_.OnThemeChanged(wndSheet_.m_hWnd);
}
void Workbook::UpdateControlLayout(WORD cx, WORD cy, bool bMouseMove/* = false*/)
{
if(cx<=0 || cy<=0) return;
const BOOL bShowHScrollBar=IsShowHScrollBar();
const int cyHScroll=bShowHScrollBar?::GetSystemMetrics(SM_CYHSCROLL):0;
const int cxVScroll=IsShowVScrollBar()?::GetSystemMetrics(SM_CXVSCROLL):0;
const int cxSheet=cx-cxVScroll;
const int cySheet=cy-cyHScroll;
//int const xHScroll=0;
int const yHScroll=cy-cyHScroll;
int const xVScroll=cx-cxVScroll;
HDWP hdwp=::BeginDeferWindowPos(4);
::DeferWindowPos(hdwp,wndTabHScroll_,NULL,0,yHScroll,cx-cxVScroll,cyHScroll,SWP_NOZORDER|SWP_SHOWWINDOW);
::DeferWindowPos(hdwp,wndVScroll_,NULL,xVScroll,0,cxVScroll,yHScroll,SWP_NOZORDER|SWP_SHOWWINDOW);
::DeferWindowPos(hdwp,wndBottomRightCorner_,NULL,xVScroll,yHScroll,cxVScroll,cyHScroll,SWP_NOZORDER|SWP_SHOWWINDOW);
::DeferWindowPos(hdwp,wndSheet_.m_hWnd,NULL,0,0,cxSheet,cySheet,SWP_NOZORDER|SWP_NOMOVE|SWP_SHOWWINDOW);
::EndDeferWindowPos(hdwp);
}
LRESULT Workbook::OnCreate(UINT,WPARAM,LPARAM lParam,BOOL& bHandled)
{
CreateChildren();
return 0;
}
LRESULT Workbook::OnPostCreate(UINT,WPARAM,LPARAM lParam,BOOL& bHandled)
{
for(size_t i=0;i<vecWorksheet_.size();++i){
if(pCurSheet_==vecWorksheet_[i]){
wndTabHScroll_.GetFlatTabCtrl()->SetCurSel(int(i));
break;
}
}
return 0;
}
void Workbook::OnActivateApp(BOOL bActivated)//UINT,WPARAM,LPARAM lParam,BOOL&)
{
if(pCurSheet_ && bActivated){
RECT rcCli;
pCurSheet_->GetClientRect(&rcCli);
pCurSheet_->RecalcCellAxisInfo(rcCli,CCAI_CALC_ALL);
}
}
LRESULT Workbook::OnSize(UINT,WPARAM,LPARAM lParam,BOOL&)
{
if(pCurSheet_){
const WORD cx=LOWORD(lParam);
const WORD cy=HIWORD(lParam);
if(!cx || !cy) return 0;
UpdateControlLayout(cx,cy);
}
return 0;
}
LRESULT Workbook::OnTabItemChange(int,LPNMHDR pNMHDR, BOOL& bHandled)
{
if(pNMHDR->hwndFrom==wndTabHScroll_.m_hWnd && IsDrawingEnabled()){
const int nChoice = wndTabHScroll_.GetFlatTabCtrl()->GetCurSel();
Worksheet_SetActiveSheet(nChoice);
}else
bHandled=FALSE;
return 0;
}
LPTSTR Workbook::GetNewSheetName(TCHAR buf[32])
{
CString str;
for(int i=1;;++i){
str.Format(_T("Sheet%d"),i);
if(!Worksheet_FindByName(str)){
lstrcpy(buf,str);
break;
}
}
return buf;
}
}//namespace mycell