// MyCell - version 1.0
// Written by Yanxueming <yanxm2003@hotmail.com>
// Copyright (C) 2006-2006
// All rights reserved.
//
// The code and information is provided "as-is" without
// warranty of any kind, either expressed or implied.
#include "stdafx.h"
#include "../include/base.h"
#include "../include/EditImp.h"
#include "../include/GridBase.h"
#include "../include/InPlaceEdit.h"
#include <atltypes.h>
#pragma comment(lib,"Imm32.lib")
#pragma message( "Auto load Imm32.lib " __FILE__ )
namespace mycell{
//LRESULT EditImpl::OnEndInPlaceEdit(int, LPNMHDR lpnm,BOOL& bHandled)
//LRESULT OnEndInPlaceEdit(int row,int col,LPCSTR lpszText)
//{
// // In case OnEndInPlaceEdit called as window is being destroyed
// if (!pGrid_->IsWindow())
// return 1;
// //HWND const hListener=pGrid_->put_listener(NULL);
// //NM_GRIDVIEW* disp=(NM_GRIDVIEW*)lpnm;
// //LPCSTR lpszText=(LPCSTR)disp->lParam;
// TCHAR szCurText[MAX_CELLTEXT];
// int len=pGrid_->GetCellText(disp->row,disp->col,szCurText);
// //pGrid_->put_listener(hListener);
// if (!szCurText || !lpszText || 0!=_tcsnccmp(lpszText,szCurText,len))
// {
// pGrid_->SendMessageToListener(disp->row,disp->col,OCN_ENDCELLEDIT,(LPARAM)lpszText);
// }
// return 1;
//}
//void EditImpl::OnEndEditCell(int row, int col,LPCSTR lpszText)
//{
// TCHAR szCurText[MAX_CELLTEXT];
// int len=pGrid_->GetCellText(row,col,szCurText);
// if (!szCurText || !lpszText || 0!=_tcsnccmp(lpszText,szCurText,len))
// {
// pGrid_->SendMessageToListener(row,col,OCN_ENDLABELEDIT,(LPARAM)lpszText);
// }
//}
LRESULT EditImpl::OnImeComposition(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
bHandled=FALSE;
#define MyError(x)
if(lParam & GCS_RESULTSTR)
{
HIMC hIMC = ::ImmGetContext(pGrid_->m_hWnd);
if (!hIMC)
;//MyError(ERROR_NULLCONTEXT);
// Get the size of the result string.
DWORD dwSize = ImmGetCompositionString(hIMC, GCS_RESULTSTR, NULL, 0);
// increase buffer size for NULL terminator,
// maybe it is in UNICODE
dwSize += sizeof(WCHAR);
HGLOBAL hstr = GlobalAlloc(GHND,dwSize);
if (hstr == NULL)
MyError(ERROR_GLOBALALLOC);
LPSTR lpstr = (LPSTR)GlobalLock(hstr);
if (lpstr == NULL)
MyError(ERROR_GLOBALLOCK);
// Get the result strings that is generated by IME into lpstr.
ImmGetCompositionString(hIMC, GCS_RESULTSTR, lpstr, dwSize);
ImmReleaseContext(pGrid_->m_hWnd, hIMC);
// add this string into text buffer of application
//int ActiveRow=0,ActiveCol=0;
//GetActiveCell(&ActiveRow,&ActiveCol);
CellID const activeCell=pGrid_->get_ActiveCell();
OnEditCell(activeCell.row,activeCell.col,lpstr);
GlobalUnlock(hstr);
GlobalFree(hstr);
}
return 0;
}
LRESULT EditImpl::OnChar(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
bHandled=FALSE;
UINT nChar=(UINT)wParam;
if(nChar < 0x20) return 0;//control chars
if(nChar >= 0x80)//When entering DBCS chars into cells
return 0;
eMouseMode const emm=pGrid_->get_MouseMode();
if (!IsCTRLpressed() && emm == MOUSE_NOTHING && nChar != VK_ESCAPE)
{
BOOL const bHandleTabKey=pGrid_->get_HandleTabKey();
if (!bHandleTabKey || (bHandleTabKey && nChar != VK_TAB))
{
CellID const activeCell=pGrid_->get_ActiveCell();
OnEditCell(activeCell.row,activeCell.col, nChar);
}
}
return DefWindowProc(pGrid_->m_hWnd,uMsg,wParam,lParam);
}
void EditImpl::OnEditCell(int row, int col,LPCSTR lpszInit)
{
_ASSERT(row>=0);
_ASSERT(col>=0);
CRect rect;
VisibleMergeCellMgr& vmc=pGrid_->GetVisibleMergeCellMgr();
MergeCells* pMergeCells=vmc.GetMergeCells(row,col);
if(pMergeCells){
row=pMergeCells->first.row;
col=pMergeCells->first.col;
pGrid_->EnsureVisible(row, col);
RECT rc=pGrid_->get_RangeRect(pMergeCells->first.row,pMergeCells->first.col,pMergeCells->second.row,pMergeCells->second.col);
RECT rcContent;
pGrid_->GetClientRect(&rcContent);
pGrid_->get_ContentRect(&rcContent);
IntersectRect(&rect,&rc,&rcContent);
}else{
pGrid_->EnsureVisible(row, col);
rect=pGrid_->GetCellRect(row,col);
}
rect.DeflateRect(0,0,1,1);
CellTypeConstants const tc=pGrid_->get_CellType(row,col);
switch(tc){
case cellEdit: //�ı���
{
CInPlaceEdit* pEdit=new CInPlaceEdit(pGrid_,pGrid_->m_hWnd,rect,ES_CENTER|ES_AUTOHSCROLL,0,row,col,lpszInit);
m_hwndInplace=pEdit->m_hWnd;
}break;
case cellCombo: //������
case cellCheck: //��ѡ��
case cellCalendar: //���ڿ�
case cellButton: //��ť
case cellHyperLink: //������
case cellDefault: //ȱʡ����
break;
case cellDegree://��γ�ȱ༭��
{
CInPlaceEdit* pEdit=new CInPlaceEdit(pGrid_,pGrid_->m_hWnd,rect,ES_CENTER,0,row,col,lpszInit);
m_hwndInplace=pEdit->m_hWnd;
}break;
}
//SetDirty();
}
LRESULT EditImpl::OnLButtonDblClk(UINT,WPARAM,LPARAM lParam,BOOL& bHandled)
{
bHandled=FALSE;
POINT point={GET_X_LPARAM(lParam),GET_Y_LPARAM(lParam)};// MAKEPOINTS(lParam); // position of cursor
CellHitTestConstants hct;
CellID const cell=pGrid_->HitTest(point.x,point.y,hct);
if(cell.row<0 || cell.col<=0)
return 0;
eMouseMode const emm=pGrid_->get_MouseMode();
switch(emm)
{
case MOUSE_NOTHING:
{
if (cell.row>=HEADER_ROW && cell.col>=HEADER_COL){
OnEditCell(cell.row,cell.col, VK_LBUTTON);
}/*else if (get_ListMode()){
if (!IsValid(MouseRow,MouseCol)) return 0;
if (MouseRow >= iFixedRowCount && MouseCol < iFixedColumnCount)
OnEditCell(MouseRow,MouseCol, VK_LBUTTON);
}
*/
CellTypeConstants const tc=pGrid_->get_CellType(cell.row,cell.col);
if(cellOwnerDraw==tc || cellDefault==tc){
pGrid_->SendMessageToListener(cell.row,cell.col,OCN_LBUTTONDBLCLK,0);
}
}
}
return 0;
}
LRESULT EditImpl::OnLButtonDown(UINT,WPARAM,LPARAM lParam,BOOL& bHandled)
{
bHandled=FALSE;
POINT const point={LOWORD(lParam),HIWORD(lParam)};
CellHitTestConstants hct;
CellID const cell=pGrid_->HitTest(point.x,point.y,hct);
if(cell.row<0 || cell.col<0)
return 0;
CRect rcCell=pGrid_->GetCellRect(cell.row,cell.col);
CPoint _pt=rcCell.CenterPoint();
int cx=rcCell.Width();
if(rcCell.Height()<cx)
cx=rcCell.Height();
cx=(cx-4)>>1;
rcCell.SetRect(_pt.x-cx,_pt.y-cx,_pt.x+cx,_pt.y+cx);
if(!rcCell.PtInRect(point))
return 0;
CellTypeConstants const cellType=pGrid_->get_CellType(cell.row,cell.col);
switch(cellType)
{
case cellCheck:
{
TCHAR szText[MAX_CELLTEXT];
szText[0]=_T('\0');
pGrid_->GetCellText(cell.row,cell.col,szText);
BOOL const bCheck=0!=lstrcmp(szText,_T("0"));
CellRange cr=pGrid_->get_Selection();
if(cr.first.row<0) cr.first.row=0;
if(cr.first.col<0) cr.first.col=0;
if(cell.row>=cr.first.row && cell.row<=cr.second.row
&& cell.col>=cr.first.col && cell.col<=cr.second.col)
{
for(int ir=cr.first.row;ir<=cr.second.row;++ir){
for(int ic=cr.first.col;ic<=cr.second.col;++ic)
{
if(cellCheck==pGrid_->get_CellType(ir,ic)){
CheckCell(ir,ic,bCheck);
}
}
}
bHandled=TRUE;
}else{
CheckCell(cell.row,cell.col,bCheck);
}
RECT rcSel=pGrid_->get_RangeRect(cr.first.row,cr.first.col,cr.second.row,cr.second.col);
RECT rcContent;
pGrid_->GetClientRect(&rcContent);
RECT rc;
IntersectRect(&rc,&rcContent,&rcSel);
pGrid_->InvalidateRect(&rc,FALSE);
pGrid_->UpdateWindow();
}break;
}
return 0;
}
void EditImpl::CheckCell(long row,long col,BOOL bCheck)
{
if(row>0){
LPCTSTR str=bCheck?_T("0"):_T("1");
pGrid_->SendMessageToListener(row,col,OCN_ENDCELLEDIT,(LPARAM)str);
}
}
}//namespace