318 lines
8.7 KiB
C++
318 lines
8.7 KiB
C++
// ==========================================================================
|
|
// Class Implementation : COXGridEdit
|
|
// ==========================================================================
|
|
|
|
// Source file : OXGridEdit.cpp
|
|
|
|
// Version: 9.3
|
|
|
|
// This software along with its related components, documentation and files ("The Libraries")
|
|
// is © 1994-2007 The Code Project (1612916 Ontario Limited) and use of The Libraries is
|
|
// governed by a software license agreement ("Agreement"). Copies of the Agreement are
|
|
// available at The Code Project (www.codeproject.com), as part of the package you downloaded
|
|
// to obtain this file, or directly from our office. For a copy of the license governing
|
|
// this software, you may contact us at legalaffairs@codeproject.com, or by calling 416-849-8900.
|
|
|
|
// //////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
#include "OXGridEdit.h"
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char BASED_CODE THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
IMPLEMENT_DYNAMIC(COXGridEdit, CEdit)
|
|
|
|
#define new DEBUG_NEW
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Definition of static members
|
|
// Data members -------------------------------------------------------------
|
|
// protected:
|
|
// CString m_sDeferedWindowText;
|
|
// --- The window text to be set during the next OnSize event
|
|
// (if m_bDeferedWindowText == TRUE)
|
|
|
|
// BOOL m_bDeferedWindowText;
|
|
// --- Whether to change the window text during the next OnSize event
|
|
|
|
// CString m_sOldWindowText;
|
|
// --- The window text before it was changed during OnSize
|
|
|
|
// CPoint m_ptWindowPos;
|
|
// --- The new top left corner of this control (if m_bWindowPos == TRUE)
|
|
|
|
// BOOL m_bWindowPos;
|
|
// --- Whether to keep the control at the fixed position of m_ptWindowPos
|
|
|
|
// int m_nWindowHeight;
|
|
// --- The new height of this control (if m_bWindowHeight == TRUE)
|
|
|
|
// BOOL m_bWindowHeight;
|
|
// --- Whether to keep the control at the fixed height of m_nWindowHeight
|
|
|
|
// int m_nCXOffset;
|
|
// --- An additional ofset that must be added to the normal width
|
|
|
|
// BOOL m_bAdjustWindowWidth;
|
|
// --- Whether to calculate the edit control width from the text width
|
|
// and to add m_nCXOffset
|
|
|
|
// UINT m_nEndKeyChar;
|
|
// --- Virtual key code with which the editing was ended (0 if ended in another way)
|
|
|
|
// BOOL m_bEndKeyShift;
|
|
// --- The shift status when the key was pressed that ended the editing
|
|
// BOOL m_bEndKeyCtrl;
|
|
// --- The ctrl status when the key was pressed that ended the editing
|
|
|
|
// private:
|
|
|
|
// Member functions ---------------------------------------------------------
|
|
// public:
|
|
|
|
COXGridEdit::COXGridEdit()
|
|
{
|
|
Initialize();
|
|
ASSERT_VALID(this);
|
|
}
|
|
|
|
void COXGridEdit::Initialize()
|
|
{
|
|
m_sDeferedWindowText.Empty();
|
|
m_bDeferedWindowText = FALSE;
|
|
m_ptWindowPos = CPoint(0,0);
|
|
m_bWindowPos = FALSE;
|
|
m_nWindowHeight = 0;
|
|
m_bWindowHeight = FALSE;
|
|
m_bAdjustWindowWidth = FALSE;
|
|
m_nCXOffset = 0;
|
|
m_nEndKeyChar = 0;
|
|
m_bEndKeyShift = FALSE;
|
|
m_bEndKeyCtrl = FALSE;
|
|
m_nRightParentBorder = -1;
|
|
m_bFitToClient=FALSE;
|
|
}
|
|
|
|
void COXGridEdit::SetDeferedWindowText(LPCTSTR lpszString)
|
|
{
|
|
m_sDeferedWindowText = lpszString;
|
|
m_bDeferedWindowText = TRUE;
|
|
}
|
|
|
|
void COXGridEdit::SetWindowPos(const CPoint& pt)
|
|
{
|
|
m_ptWindowPos = pt;
|
|
m_bWindowPos = TRUE;
|
|
}
|
|
|
|
void COXGridEdit::SetWindowHeight(int nHeight)
|
|
{
|
|
m_nWindowHeight = nHeight;
|
|
m_bWindowHeight = TRUE;
|
|
}
|
|
|
|
void COXGridEdit::AdjustWindowWidth(int nWidth)
|
|
{
|
|
m_nCXOffset = nWidth;
|
|
m_bAdjustWindowWidth = TRUE;
|
|
}
|
|
|
|
BOOL COXGridEdit::GetEndKey(UINT& nChar, BOOL& bShift, BOOL& bCtrl)
|
|
{
|
|
nChar = m_nEndKeyChar;
|
|
bShift = m_bEndKeyShift;
|
|
bCtrl = m_bEndKeyCtrl;
|
|
return (nChar != 0);
|
|
}
|
|
|
|
#ifdef _DEBUG
|
|
void COXGridEdit::AssertValid() const
|
|
{
|
|
CEdit::AssertValid();
|
|
}
|
|
|
|
void COXGridEdit::Dump(CDumpContext& dc) const
|
|
{
|
|
CEdit::Dump(dc);
|
|
dc << _T("\nm_sDeferedWindowText: ") << m_sDeferedWindowText;
|
|
dc << _T("\nm_bDeferedWindowText: ") << m_bDeferedWindowText;
|
|
dc << _T("\nm_ptWindowPos: (") << m_ptWindowPos.x << _T(", ") << m_ptWindowPos.y << _T(")");
|
|
dc << _T("\nm_bWindowPos: ") << m_bWindowPos;
|
|
dc << _T("\nm_nWindowHeight: ") << m_nWindowHeight;
|
|
dc << _T("\nm_bWindowHeight: ") << m_bWindowHeight;
|
|
dc << _T("\nm_nCXOffset: ") << m_nCXOffset;
|
|
dc << _T("\nm_bAdjustWindowWidth: ") << m_bAdjustWindowWidth;
|
|
dc << _T("\nm_nEndKeyChar: ") << m_nEndKeyChar;
|
|
dc << _T("\nm_bEndKeyShift: ") << m_bEndKeyShift;
|
|
dc << _T("\nm_bEndKeyCtrl: ") << m_bEndKeyCtrl;
|
|
dc << _T("\n");
|
|
}
|
|
#endif //_DEBUG
|
|
|
|
COXGridEdit::~COXGridEdit()
|
|
{
|
|
}
|
|
|
|
BEGIN_MESSAGE_MAP(COXGridEdit, CEdit)
|
|
//{{AFX_MSG_MAP(COXGridEdit)
|
|
ON_WM_SIZE()
|
|
ON_WM_WINDOWPOSCHANGING()
|
|
ON_WM_CHAR()
|
|
ON_WM_KEYDOWN()
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
void COXGridEdit::OnSize(UINT nType, int cx, int cy)
|
|
{
|
|
CEdit::OnSize(nType, cx, cy);
|
|
|
|
// If the defered window text has not yet been set, do it now
|
|
if (m_bDeferedWindowText)
|
|
{
|
|
m_bDeferedWindowText = FALSE;
|
|
// ... Make sure the window exists
|
|
ASSERT(::IsWindow(m_hWnd));
|
|
SetWindowText(m_sDeferedWindowText);
|
|
// ... Make sure the window still exists after the SetWindowText !
|
|
ASSERT(::IsWindow(m_hWnd));
|
|
}
|
|
}
|
|
|
|
void COXGridEdit::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos)
|
|
{
|
|
// Adjust window position if necessary
|
|
if (m_bWindowPos)
|
|
{
|
|
lpwndpos->x = m_ptWindowPos.x;
|
|
lpwndpos->y = m_ptWindowPos.y;
|
|
}
|
|
|
|
// Adjust window width if necessary
|
|
if (m_bWindowHeight)
|
|
lpwndpos->cy = m_nWindowHeight;
|
|
|
|
// Adjust window width if necessary
|
|
if (m_bAdjustWindowWidth)
|
|
{
|
|
// Appearently there is no good way to calculate the exact width of the
|
|
// text in this edit control.
|
|
// In Win95 we use the function PosFromChar which gives the best results
|
|
// When this function is not available we use GetTextExtentPoint which appears
|
|
// to have a quit large deviation
|
|
int nTextSizeX = 0;
|
|
int nTextLength = GetWindowTextLength();
|
|
if (nTextLength != 0)
|
|
{
|
|
CPoint ptFirst(0, 0);
|
|
CPoint ptLast(0, 0);
|
|
ptFirst = PosFromChar(0);
|
|
// PosFromChar(nTextLength) should return the coordinates of the character position
|
|
// just past the last character.
|
|
// But this does not work, so we use PosFromChar(nTextLength - 1) and
|
|
// add the avarage character size to it
|
|
ptLast=PosFromChar(nTextLength - 1);
|
|
if(ptLast.x!=0)
|
|
{
|
|
nTextSizeX = ptLast.x - ptFirst.x;
|
|
if (nTextLength != 1)
|
|
nTextSizeX = (nTextSizeX * nTextLength) / (nTextLength - 1);
|
|
else
|
|
// If only one character in control, use fixed value (for speed)
|
|
nTextSizeX = 10;
|
|
}
|
|
else
|
|
{
|
|
// PosFromChar falied, probably using Win NT 3.51 and not Window 95
|
|
// (will use GetTextExtentPoint instead)
|
|
CString sText;
|
|
GetWindowText(sText);
|
|
CSize textSize(0, 0);
|
|
CDC* pDC=GetDC();
|
|
ASSERT_VALID(pDC);
|
|
VERIFY(GetTextExtentPoint(pDC->GetSafeHdc(),
|
|
(LPCTSTR)sText, sText.GetLength(), &textSize));
|
|
nTextSizeX = textSize.cx;
|
|
ReleaseDC(pDC);
|
|
}
|
|
}
|
|
|
|
lpwndpos->cx = nTextSizeX + m_nCXOffset;
|
|
}
|
|
|
|
|
|
// Get the right border position of the parent window
|
|
// (if we haven't done so before)
|
|
if (m_nRightParentBorder < 0)
|
|
{
|
|
CWnd* pParent;
|
|
CWnd* pParentsParent;
|
|
pParent = GetParent();
|
|
pParentsParent = pParent->GetParent();
|
|
|
|
CRect parentRect;
|
|
pParent->GetClientRect(parentRect);
|
|
// pParent->ClientToScreen(parentRect);
|
|
m_nRightParentBorder = parentRect.right;
|
|
}
|
|
|
|
// Make sure this edit control is completely within its parent's
|
|
// client area
|
|
if(m_bFitToClient || m_nRightParentBorder<lpwndpos->x+lpwndpos->cx)
|
|
lpwndpos->cx=m_nRightParentBorder-lpwndpos->x;
|
|
|
|
CEdit::OnWindowPosChanging(lpwndpos);
|
|
}
|
|
|
|
|
|
void COXGridEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
|
|
{
|
|
// Check whether the Tab key key was pressed
|
|
if (nChar == VK_TAB)
|
|
{
|
|
// Store the key that ended the editing
|
|
m_nEndKeyChar = nChar;
|
|
if (::GetKeyState(VK_SHIFT) & 0x8000)
|
|
m_bEndKeyShift = TRUE;
|
|
if (::GetKeyState(VK_CONTROL) & 0x8000)
|
|
m_bEndKeyCtrl = TRUE;
|
|
|
|
// End the editing in the edit control by setting the focus
|
|
// back to the list control (parent)
|
|
GetParent()->SetFocus();
|
|
|
|
// Do not call the base class, because VT_TAB is an illegal key
|
|
// and this will produce a message beep
|
|
return;
|
|
}
|
|
|
|
CEdit::OnChar(nChar, nRepCnt, nFlags);
|
|
}
|
|
|
|
void COXGridEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
|
|
{
|
|
// Check whether the Insert key was pressed
|
|
if ((nChar == VK_INSERT) || (nChar == VK_UP) || (nChar == VK_DOWN))
|
|
{
|
|
// Store the key that ended the editing
|
|
m_nEndKeyChar = nChar;
|
|
if (::GetKeyState(VK_SHIFT) & 0x8000)
|
|
m_bEndKeyShift = TRUE;
|
|
if (::GetKeyState(VK_CONTROL) & 0x8000)
|
|
m_bEndKeyCtrl = TRUE;
|
|
|
|
// End the editing in the edit control by setting the focus
|
|
// back to the list control (parent)
|
|
GetParent()->SetFocus();
|
|
}
|
|
|
|
CEdit::OnKeyDown(nChar, nRepCnt, nFlags);
|
|
}
|
|
|
|
// protected:
|
|
// private:
|
|
|
|
// ==========================================================================
|