// InPlaceEdit.cpp: implementation of the CInPlaceEdit class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "../include/InPlaceEdit.h"
#include "../include/Worksheet.h"
#include "../include/msg.h"
#include "../include/Text.h"
namespace mycell{
enum{ PROP_TEXT_INDENT = 2};
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CInPlaceEdit::CInPlaceEdit(Worksheet* pSheet,HFONT hFont,HWND hWndParent, RECT& rect, DWORD dwStyle, UINT nID,
int row,int col, LPCTSTR lpszCellText,LPCTSTR lpszInitText)
:pSheet_(pSheet),m_fCancel(false),font_(hFont)
{
cell_.set(row,col);
rect_ = rect; // For bizarre CE bug.
DWORD dwEditStyle = /*WS_BORDER|*/WS_CHILD|WS_VISIBLE| ES_AUTOHSCROLL //|ES_MULTILINE
| dwStyle;
//int const iTextLen=-1==row?(pSheet_->get_ColHeader().get_text(col,m_sInitText)):pSheet_->GetCellText(cell_,m_sInitText);
if(lpszCellText){
lstrcpy(m_sInitText,lpszCellText);
}
const int iTextLen=lstrlen(m_sInitText);
if (!Create(hWndParent,rect,m_sInitText,dwEditStyle, 0,nID)) return;
SetMargins(PROP_TEXT_INDENT, 0); // Force EDIT margins so text doesn't jump
SetFont(hFont);//(HFONT)::GetStockObject(DEFAULT_GUI_FONT));
SetFocus();
int iLen=lstrlen(lpszInitText);
if(iLen>1 && !(VK_LBUTTON==(UINT)lpszInitText[0] || VK_SPACE==(UINT)lpszInitText[0])){
SetWindowText(lpszInitText);
SetSel(iLen,-1);
SetModify();
return;
}else{
iLen=iTextLen;
SetWindowText(m_sInitText);
}
//AtlTrace(_T("\nlpszInitText=%s,iLen=%d"),lpszInitText,iLen);
UINT nFirstChar=lpszInitText[0];
switch (nFirstChar){
case VK_LBUTTON:
case VK_RETURN: SetSel(/*(int)m_sInitText.Length()*/iLen, -1); return;
case VK_BACK: SetSel(/*(int)m_sInitText.Length()*/iLen, -1); break;
case VK_TAB:
case VK_DOWN:
case VK_UP:
case VK_RIGHT:
case VK_LEFT:
case VK_NEXT:
case VK_PRIOR:
case VK_HOME:
case VK_SPACE:
case VK_END: SetSel(0,-1); return;
default: SetSel(0,-1);
}
// Added by KiteFly. When entering DBCS chars into cells the first char was being lost
// SenMessage changed to PostMessage (John Lagerquist)
if( nFirstChar < 0x80)
PostMessage(WM_CHAR, nFirstChar);
//else
// PostMessage(WM_IME_CHAR, nFirstChar);
}
CInPlaceEdit::~CInPlaceEdit()
{
}
void CInPlaceEdit::OnFinalMessage(HWND /*hWnd*/)
{
//pSheet_->SetFocus();
delete this;
}
void CInPlaceEdit::EndEdit()
{
// EFW - BUG FIX - Clicking on a grid scroll bar in a derived class
// that validates input can cause this to get called multiple times
// causing assertions because the edit control goes away the first time.
static BOOL bAlreadyEnding = FALSE;
if(bAlreadyEnding)
return;
bAlreadyEnding = TRUE;
int len = ::GetWindowTextLength(m_hWnd) + 1;
LPTSTR str = (LPTSTR) _alloca(len * sizeof(TCHAR));
ATLASSERT(str);
if( ::GetWindowText(m_hWnd, str, len) == 0 ) {
// Bah, an empty string AND an error causes the same return code!
//if( ::GetLastError() != 0 ) return FALSE;
if( ::GetLastError() != 0 )
_ASSERT(FALSE);
}
if(IsWindowVisible())
ShowWindow(SW_HIDE);
//-----------
TCHAR szCurText[MAX_CELLTEXT];
szCurText[0]=_T('\0');
int const iLenCurText=pSheet_->GetCellText(cell_,szCurText,EGCVD_EDIT);
if (!iLenCurText || lstrlen(str)<=0 || 0!=lstrcmp(str,szCurText))
{
BOOL bHandled=FALSE;
pSheet_->SendNotifyMessageToListener(cell_.row,cell_.col,OCN_ENDCELLEDIT,(LPARAM)str,&bHandled);
if(!bHandled){
TCHAR szNew[MAX_CELLTEXT];szNew[0]=_T('\0');
int len=pSheet_->GetCellText(cell_,szNew,EGCVD_EDIT);
const BOOL bWrapText=Text_HasReturnChar(szNew,len);
if(bWrapText){
StyleDesc sd=pSheet_->Style_GetCellStyle(cell_);
sd.Align_SetWrapText(bWrapText);
pSheet_->Style_SetCellStyle(cell_,sd);
}
if(pSheet_->get_AutoAppendRow() && cell_.row==pSheet_->get_RowHeader().get_rows()-1
&& 0!=lstrcmp(szNew,szCurText))
{
RECT const rc=pSheet_->raw_GetCellRect(CCell(cell_.row,HEADER_COL));
pSheet_->InvalidateRect(&rc,FALSE);
pSheet_->put_rows(cell_.row+2);
}
pSheet_->SetCellText(cell_,CComVariant(str),TRUE);
}
}
//HWND hWndParent=GetParent();
//if(::IsWindow(hWndParent))
// ::SendMessage(hWndParent,WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&dispinfo );
// Close this window (PostNcDestroy will delete this)
//if (IsWindow())
// SendMessage(WM_CLOSE, 0, 0);
bAlreadyEnding = FALSE;
}
LRESULT CInPlaceEdit::OnKillFocus(UINT nMsg, WPARAM wParam,
LPARAM lParam, BOOL& bHandled)
{
LRESULT lRet=DefWindowProc();
//EndEdit();
m_fCancel |= (GetModify() == FALSE);
if(!m_fCancel){
EndEdit();
}
if (IsWindow())
SendMessage(WM_CLOSE,0,0);
return lRet;
}
LRESULT CInPlaceEdit::OnChar(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL& bHandled)//UINT nChar, UINT nRepCnt, UINT nFlags)
{
UINT nChar=(UINT)wParam;
UINT nRepCnt=LOWORD(lParam);
if (nChar == VK_TAB || nChar == VK_RETURN)
{
HWND const hWndParent=GetParent();
m_nLastChar = nChar;
::SetFocus(hWndParent); // This will destroy this window
::SendMessage(hWndParent,WM_KEYDOWN/*uMsg*/,wParam,lParam);
return 0;
}
if (nChar == VK_ESCAPE)
{
USES_CONVERSION;
SetWindowText(m_sInitText); // restore previous text
m_nLastChar = nChar;
::SetFocus(GetParent());
return 0;
}
bHandled=FALSE;
if(wParam < 0x20) return 0;//always allow control chars
const StyleDesc& styleDesc=pSheet_->Style_GetCellStyle(cell_);
//ECellType const tc=pSheet_->GetCellType(cell_.row,cell_.col,styleDesc);
//ColHeader& ch=pSheet_->get_ColHeader();
const ECellType cellType=pSheet_->GetCellStore(cell_,ECSM_CELLTYPE_VALID).GetCellType();//styleDesc.CellType_GetType();//==ECT_NONE?ch.get_DefColType():styleDesc.cellType;//pSheet_->GetCellType(row,col,styleDesc);//styleDesc.cellType;
switch(cellType)
{
case ECT_UINT:
{
if(!(IsCharAlphaNumeric((TCHAR)wParam) && !IsCharAlpha((TCHAR)wParam))){
bHandled=TRUE;
::MessageBeep((UINT)-1);
}
}break;
case ECT_INT:
{
if(!(wParam=='-'||IsCharAlphaNumeric((TCHAR)wParam) && !IsCharAlpha((TCHAR)wParam))){
bHandled=TRUE;
::MessageBeep((UINT)-1);
}
}
break;
case ECT_UDOUBLE:
{
if(!(wParam>='0'&&wParam<='9'||wParam==VK_BACK||wParam=='.')){
bHandled=TRUE;
::MessageBeep((UINT)-1);
}
}
break;
case ECT_DOUBLE:
{
if(!(wParam>='0'&&wParam<='9'||wParam=='-'||wParam==VK_BACK||wParam=='.')){
bHandled=TRUE;
::MessageBeep((UINT)-1);
}
}
break;
default:
break;
}
LRESULT lRet=0;
return lRet;
}
LRESULT CInPlaceEdit::OnGetDlgCode(UINT,WPARAM,LPARAM,BOOL&)
{
return DLGC_WANTALLKEYS;
}
LRESULT CInPlaceEdit::OnKeyDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
UINT nChar=(UINT)wParam;
UINT nRepCnt=LOWORD(lParam);
switch(nChar)
{
case VK_ESCAPE:
m_fCancel = true;
// FALL THROUGH...
//case VK_LEFT:
// int lLow, lHigh;
// GetSel(lLow, lHigh);
// if( lLow != lHigh || lLow != 0 ) break;
//case VK_RIGHT:
// GetSel(lLow, lHigh);
// if( lLow != lHigh || lLow != GetWindowTextLength() ) break;
//case VK_PRIOR:
//case VK_NEXT:
//case VK_DOWN:
//case VK_UP:
case VK_RETURN:
if(IsCTRLpressed())
break;
case VK_TAB:
//(m_bExitOnArrows || GetKeyState(VK_CONTROL) < 0)*/)
{
m_nLastChar = nChar;
//::SetFocus(GetParent());
//::SendMessage(GetParent(),uMsg,wParam,lParam);
return 0;
}
}
return DefWindowProc(uMsg,wParam,lParam);
}
}//namespace mycell