www.pudn.com > clking_src.rar > GuiEdit.cpp
//-----------------------------------------------------------------------// // This is a part of the GuiLib MFC Extention. // // Autor : Francisco Campos // // (C) 2002 Francisco CamposAll rights reserved // // This code is provided "as is", with absolutely no warranty expressed // // or implied. Any use is at your own risk. // // You must obtain the author's consent before you can include this code // // in a software library. // // If the source code in this file is used in any application // // then acknowledgement must be made to the author of this program // // fcampos@tutopia.com // //-----------------------------------------------------------------------// #include "stdafx.h" #include "GuiEdit.h" #include "GuiDrawLayer.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CGuiEdit CGuiEdit::CGuiEdit() { m_szMask=_T(""); m_szShowMask=_T(""); StrToUse=_T("()-,.@#AaXx/:\\"); //caracteres para armar la mascara m_cadResult=_T(""); m_enMask=MASK_FREEMASK; m_KeySpecial=0; } CGuiEdit::~CGuiEdit() { } BEGIN_MESSAGE_MAP(CGuiEdit, CEdit) //{{AFX_MSG_MAP(CGuiEdit) ON_WM_CREATE() ON_WM_PAINT() ON_WM_SYSCOLORCHANGE() ON_WM_NCPAINT() ON_WM_SIZE() ON_WM_NCCALCSIZE() ON_WM_CHAR() ON_WM_KEYDOWN() ON_WM_SETFOCUS() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CGuiEdit message handlers void CGuiEdit::PreSubclassWindow() { CEdit::PreSubclassWindow(); } int CGuiEdit::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CEdit::OnCreate(lpCreateStruct) == -1) return -1; m_tooltipCtrl.Create(this,TTS_ALWAYSTIP); m_tooltipCtrl.Activate(TRUE); m_tooltipCtrl.BringWindowToTop(); return 0; } void CGuiEdit::OnPaint() { CClientDC dc(this); Default(); RecalLayout(); } void CGuiEdit::OnSysColorChange() { CEdit::OnSysColorChange(); } BOOL CGuiEdit::AddButton(HICON hIcon,UINT nID,CMenu* m_menu,CString mToolTip) { if (!m_bnt.Create(_T(""), WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON | BS_OWNERDRAW, CRect(0,0,0,0), this, nID)) return FALSE; m_bnt.SetImage(hIcon); m_bnt.SetToolTip(mToolTip); m_bnt.SetStyleBorder(CGuiButton::STYLE_SEMIFLAT); m_bnt.SetMenu(m_menu); RecalLayout(); return TRUE; } void CGuiEdit::RecalLayout() { CRect rc; GetClientRect(rc); if (!m_bnt.GetSafeHwnd()) return; CSize msz= m_bnt.GetSizeButton(); rc.left=rc.right-msz.cx+1; m_bnt.MoveWindow(&rc); } void CGuiEdit::SetToolTip(LPCTSTR lpMsg) { CRect rc; LPCTSTR m_lpMsg=lpMsg; if (GetSafeHwnd ()== NULL) return; if (m_lpMsg != NULL) { if (m_tooltipCtrl.GetSafeHwnd () == NULL) { m_tooltipCtrl.Create(this,TTS_ALWAYSTIP); m_tooltipCtrl.Activate(TRUE); m_tooltipCtrl.AddTool(this,lpMsg); } else { m_tooltipCtrl.UpdateTipText(lpMsg,this); } } else { if (m_tooltipCtrl.GetSafeHwnd () == NULL) { m_tooltipCtrl.Create(this,TTS_ALWAYSTIP); m_tooltipCtrl.AddTool(this,lpMsg); } else m_tooltipCtrl.UpdateTipText(lpMsg,this); m_tooltipCtrl.Activate(FALSE); } } void CGuiEdit::OnNcPaint() { CRect rcWindow; CRect rcClient; CWindowDC dc(this); GetWindowRect(&rcWindow); GetClientRect(&rcClient); CBrush cbr; cbr.CreateSolidBrush(GuiDrawLayer::GetRGBColorFace()); rcClient.OffsetRect(-rcWindow.TopLeft()); rcWindow.OffsetRect(-rcWindow.TopLeft()); ScreenToClient(rcWindow); rcClient.OffsetRect(-rcWindow.left,-rcWindow.top); dc.ExcludeClipRect(rcClient); rcWindow.OffsetRect(-rcWindow.left, -rcWindow.top); int ibotton=rcWindow.bottom; rcWindow.top=rcWindow.bottom; dc.FillRect(rcWindow,&cbr); rcWindow.top=0; dc.FillRect(rcWindow,&cbr); dc.Draw3dRect(rcWindow,GuiDrawLayer::GetRGBColorFace(),GuiDrawLayer::GetRGBColorFace()); rcWindow.DeflateRect(1,1); dc.Draw3dRect(rcWindow,GuiDrawLayer::GetRGBCaptionXP(),GuiDrawLayer::GetRGBCaptionXP()); } void CGuiEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) { // TODO: Add your message handler code here and/or call default if (!m_szMask.IsEmpty()) { ValidMask(nChar); if (nChar == 8) return; switch(m_enMask) { case MASK_HOUR12: // EvalHour(nChar,12); break; case MASK_HOUR24: // EvalHour(nChar,24); break; case MASK_HOURFREE: // EvalHour(nChar); break; case MASK_IPADDRESS: break; case MASK_DATEDDMMYYYY: break; case MASK_DATEMMDDYYYY: break; case MASK_DATEYYYYDDMM: break; case MASK_DATEYYYYMMDD: break; case MASK_FREEMASK: break; } return; } CEdit::OnChar(nChar, nRepCnt, nFlags); } void CGuiEdit::DeleteString(int nStartPos,int nEndPos ) { for (int i=nStartPos; i <= nEndPos; i++) m_szShowMask.SetAt(i,m_cadResult.GetAt(i)); int nNext = GetNextPos(nStartPos); SetWindowText(m_szShowMask); if (nNext > 0) SetSel(nNext-1,nNext-1); m_KeySpecial=0; } void CGuiEdit::DeleteAndAjust(int nStartPos,int nEndPos ) { int nNext=nStartPos; int difchar=DifCharReal(nStartPos, nEndPos); if (IsPosMask(nStartPos)) nNext = GetNextPos(nStartPos); while(nNext < nNext+difchar) { AjustaCadena(nNext,nNext+difchar); difchar-=1; } } void CGuiEdit::AjustaCadena(int nStartPos,int nEndPos ) { int numCharMove=0; int LastChar=FindLasCharR(); //el ultimo caracter valido de la cadena int LastCharDel=LastChar; int init =nStartPos; for (int i=nStartPos; i <= LastChar; i++) { int nNext = GetNextPos(nStartPos); if (IsValidChar(m_szShowMask.GetAt(nNext),nNext) || m_szShowMask.GetAt(nNext)==m_cadResult.GetAt(i))//el caracter se puede mover a esa posicion { //se mueve el caracter m_szShowMask.SetAt(nStartPos,m_szShowMask.GetAt(nNext)); //se reemplaza la ultima posicion despues del ultimo caracter con el //equivalente en la mascara //obtenemos la proxima posicion donde se moveria el proximo caracter nStartPos = GetNextPos(nStartPos); numCharMove++; } } DeleteString(LastCharDel,LastCharDel); SetSel(init,init); m_KeySpecial=0; } int CGuiEdit::FindLasCharR() { for (int i=m_szShowMask.GetLength()-1;i> -1; i--) { if (m_szShowMask.GetAt(i) ==' ' || IsPosMask(i)) continue; else return i; } return i; } int CGuiEdit::NumCharNoMask() { int numEfect=0; for (int i=0;i m_cadResult.GetLength()-1) ntempStartpos=m_cadResult.GetLength()-1; if (!IsValidChar(nChar,ntempStartpos) && m_KeySpecial ==0 || nChar == 32 || nChar == 8) { if (m_KeySpecial == 1) { //si esta un caracter no valido de la mascara //emita un pito y ubique el proximo valido. if (IsPosMask(ntempStartpos)) { Beep(500,1); nNext = GetNextPos(ntempStartpos); SetSel(nNext,nNext); m_KeySpecial=0; return; } else { AjustaCadena(nStartPos,nEndPos ); m_KeySpecial=0; } } else if(m_KeySpecial == 0) { //primero verificar que no sea un caracter de la mascara por //ejemplo ( - etc.. nNext = GetNextPos(ntempStartpos); if (IsValidChar(nChar,nNext)) { m_szShowMask.SetAt(nNext,nChar); nNext = GetNextPos(nNext); SetWindowText(m_szShowMask); SetSel(nNext,nNext); } else //el caracter se desconoce SetSel(ntempStartpos,ntempStartpos); } else { //si es back se debe encontrar la proxima posición y //eliminar dicho espacio nNext = GetNextPos(nStartPos); m_szShowMask.SetAt(nNext,m_cadResult.GetAt(nNext)); SetWindowText(m_szShowMask); SetSel(nNext,nNext); m_KeySpecial=0; } } else { //entrada de datos normal if (!IsValPos(nChar,ntempStartpos)) return; m_szShowMask.SetAt(ntempStartpos,nChar); nNext = GetNextPos(ntempStartpos); SetWindowText(m_szShowMask); SetSel(nNext, nNext); if (ntempStartpos==m_szMask.GetLength()-1) SetSel(nNext+1, nNext+1); } } BOOL CGuiEdit::IsPosMask(int nStartPos) { TCHAR Char =m_szMask.GetAt(nStartPos); if (Char == '#' || Char == '0') return FALSE; else if (Char == 'A' || Char == 'a') return FALSE; return TRUE; } BOOL CGuiEdit::IsValidChar(UINT nChar,int nStartPos) { TCHAR Char =m_szMask.GetAt(nStartPos); if (Char == '#' || Char == '0') { if( !isdigit( nChar )) return FALSE; } else if (Char == 'A' || Char == 'a') { if( !isalpha( nChar )) return FALSE; } else return FALSE; return TRUE; } int CGuiEdit::GetNextPos(int start) { if (m_KeySpecial == 2) { for (int i= start-1; i>-1;i--) { if (m_szMask.GetAt(i) == '#' || m_szMask.GetAt(i) == '0' || m_szMask.GetAt(i) == 'A' || m_szMask.GetAt(i) == 'a' ) return i; } } for (int i= start+1; i< m_szMask.GetLength();i++) { TCHAR m=m_szMask.GetAt(i); if (m_szMask.GetAt(i) == '#' || m_szMask.GetAt(i) == '0' || m_szMask.GetAt(i) == 'A' || m_szMask.GetAt(i) == 'a' ) return i; } return start; } void CGuiEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { // TODO: Add your message handler code here and/or call default if (!m_szMask.IsEmpty()) { if (nChar == VK_DELETE) { m_KeySpecial=1; AfxCallWndProc(this, m_hWnd, WM_CHAR, ' ', 1); return; } if (nChar == VK_BACK) { m_KeySpecial=2; return; } if(nChar == VK_RIGHT) { int nStartPos, nEndPos; GetSel( nStartPos, nEndPos ); m_KeySpecial=3; //controlar que si no existen caracteres validos hacia //adelante el cursor debe detenerce. if (!ValSpecialKey(nStartPos,nEndPos)) { SetSel(nStartPos,nStartPos); return; } } } CEdit::OnKeyDown(nChar, nRepCnt, nFlags); } BOOL CGuiEdit::ValSpecialKey(int nStartPos, int nEndPos) { int nNext=nStartPos; TCHAR Char =m_szMask.GetAt(nStartPos); if (m_KeySpecial == 3) { nNext = GetNextPos(nStartPos); if (m_szShowMask.GetAt(nNext) == m_cadResult.GetAt(nNext)) { m_KeySpecial=0; return FALSE; } } m_KeySpecial=0; return TRUE; } void CGuiEdit::SetMask(CString mszMask,CString mszShowMask,Mask enTypeMask) { m_szMask=mszMask; m_szShowMask=mszShowMask; m_enMask=enTypeMask; m_cadResult=mszShowMask; SetWindowText(m_szShowMask); SetLimitText( m_szMask.GetLength()+1); int nNext = GetNextPos(0); SetSel(nNext, nNext); } BOOL CGuiEdit::PreTranslateMessage(MSG* pMsg) { // TODO: Add your specialized code here and/or call the base class if (pMsg->lParam == WM_MOUSEMOVE) m_tooltipCtrl.RelayEvent(pMsg); return CEdit::PreTranslateMessage(pMsg); } void CGuiEdit::OnSize(UINT nType, int cx, int cy) { CEdit::OnSize(nType, cx, cy); RecalLayout(); // TODO: Add your message handler code here } BOOL CGuiEdit::IsValPos(UINT nChar,int pos) { if (IsValidChar(nChar,pos)) { if (pos > 0) { m_KeySpecial=2; int nNext=GetNextPos(pos); m_KeySpecial=0; if (m_szShowMask.GetAt(nNext) == m_cadResult.GetAt(nNext) && pos > nNext) { SetSel(nNext,nNext); return FALSE; } else return TRUE; //todo Ok } else return TRUE; } return FALSE; } void CGuiEdit::OnSetFocus(CWnd* pOldWnd) { CEdit::OnSetFocus(pOldWnd); int nNext=GetNextPos(0); SetSel(nNext,nNext); }