// CAsHexadecimalTextCell.cpp
//
#include "stdafx.h"
#include "AsHexadecimalTextCell.h"
#include "AsHexadecimalEdit.h"
#include "DrawUtils.h"
#include <assert.h>
CAsHexadecimalTextCell::CAsHexadecimalTextCell():
editBox_(NULL),
bitCount_(32),
value_(0),
readOnly_(false)
{
}
CAsHexadecimalTextCell::~CAsHexadecimalTextCell()
{
KillFocus(false, false);
}
void CAsHexadecimalTextCell::SetDrawArea(const CRect& drawArea)
{
CAsBaseCell::SetDrawArea(drawArea);
if (HasFocus()) {
CRect textArea;
textArea = GetTextBoxArea();
editBox_->SetWindowPos(&CWnd::wndTop, textArea.left, textArea.top, textArea.Width(), textArea.Height(), SWP_SHOWWINDOW);
}
}
CSize CAsHexadecimalTextCell::GetMinSize()
{
return drawArea_.Size();
}
void CAsHexadecimalTextCell::Draw(CDC* pDC)
{
if (!visible_ || IsHidden())
return;
CAsBaseCell::Draw(pDC);
if (HasFocus())
editBox_->RedrawWindow(drawArea_);
}
bool CAsHexadecimalTextCell::HitTest(const CPoint& pt)
{
BOOL ret;
ret = drawArea_.PtInRect(pt);
return ret == TRUE;
}
void CAsHexadecimalTextCell::SetVisible(bool visible)
{
CAsBaseCell::SetVisible(visible);
if (visible)
SetFocus();
else
KillFocus(false);
}
void CAsHexadecimalTextCell::SetText(const string& text)
{
CAsBaseCell::SetText(text);
if (HasFocus())
editBox_->SetWindowText(text.c_str());
}
bool CAsHexadecimalTextCell::ProcessMessage(DWORD msg, DWORD lParam, DWORD wParam, const CPoint& pt, const CRect& parentRect, bool& needRedraw)
{
bool processed;
processed = CAsBaseCell::ProcessMessage(msg, lParam, wParam, pt, parentRect, needRedraw);
//processed = false;
switch (msg) {
case WM_LBUTTONDOWN:
{
BOOL ret;
ret = parentRect.PtInRect(drawArea_.TopLeft()) && drawArea_.PtInRect(pt);
if (ret)
SetFocus();
else
KillFocus(true);
break;
}
case WM_KEYDOWN:
{
if (HasFocus()) {
switch (wParam) {
case VK_ESCAPE:
KillFocus(false, false);
processed = true;
needRedraw = true;
break;
case VK_RETURN:
KillFocus(true, false);
processed = true;
needRedraw = true;
break;
}
}
}
}
return processed;
}
void CAsHexadecimalTextCell::SetFocus(bool redraw)
{
if (HasFocus() || readOnly_)
return;
CAsBaseCell::SetFocus(false);
CRect textArea;
textArea = GetTextBoxArea();
assert(editBox_ == NULL);
editBox_ = new CAsHexadecimalEdit;
editBox_->Create(WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL, textArea, parentWnd_, -1);
font_.CreateFont(-fontInfo_.GetFontSize(),
0, /* width */
0, /* escapement */
0, /* orientation */
fontInfo_.GetFontBold() ? FW_BOLD : FW_NORMAL, /* weight*/
0, /* italic*/
0, /* underline */
0, /* strikeout */
ANSI_CHARSET, /* charset */
OUT_DEFAULT_PRECIS, /* out precision */
CLIP_DEFAULT_PRECIS, /* clip precision */
DEFAULT_QUALITY, /* quality */
DEFAULT_PITCH, /* pitch family */
fontInfo_.GetFontName().c_str());
editBox_->SetFont(&font_);
editBox_->SetBitCount(bitCount_);
//editBox_->SetWindowText(text_.c_str());
editBox_->SetFocus();
editBox_->SetValue(value_);
editBox_->SetSel((int)text_.length(), text_.length());
editBox_->SetWindowPos(&CWnd::wndTop, textArea.left, textArea.top, textArea.Width(), textArea.Height(), SWP_SHOWWINDOW);
editBox_->SetMargins(0, 0);
editBox_->ModifyStyleEx(0, WS_EX_CONTROLPARENT);
text_ = "0x";
if (redraw && parentWnd_)
parentWnd_->RedrawWindow(drawArea_);
}
void CAsHexadecimalTextCell::SetFontInfo(const CAsFontInfo& fontInfo)
{
fontInfo_ = fontInfo;
// if (editMode_)
// editBox_->SetFont(fontInfo_.GetFont());
}
void CAsHexadecimalTextCell::KillFocus(bool storeData, bool redraw)
{
if (!HasFocus())
return;
if (storeData)
StoreData();
CAsBaseCell::KillFocus(storeData, false);
if (editBox_ == NULL || !editBox_->GetSafeHwnd())
return;
delete editBox_;
editBox_ = NULL;
if (font_.GetSafeHandle())
font_.DeleteObject();
if (redraw && parentWnd_)
parentWnd_->RedrawWindow(drawArea_);
}
void CAsHexadecimalTextCell::SetBitCount(long bitCount)
{
if (bitCount < 1)
bitCount = 1;
else if (bitCount > 32)
bitCount = 32;
bitCount_ = bitCount;
if (editBox_)
editBox_->SetBitCount(bitCount);
}
long CAsHexadecimalTextCell::GetBitCount()
{
return bitCount_;
}
void CAsHexadecimalTextCell::SetValue(long value, bool redraw)
{
string newText;
value = ValidateValue(value);
value_ = value;
if (editBox_)
editBox_->SetValue(value);
newText = HasFocus() ? "0x" : FormatValue(value);
if (text_ != newText) {
text_ = newText;
if (parentWnd_ && redraw)
parentWnd_->RedrawWindow();
}
}
long CAsHexadecimalTextCell::GetValue()
{
if (HasFocus())
StoreData();
return value_;
}
long CAsHexadecimalTextCell::ValidateValue(long value)
{
value &= (0xffffffff >> (32 - bitCount_));
return value;
}
string CAsHexadecimalTextCell::FormatValue(long value)
{
CString tmp;
tmp.Format("0x%08X", value);
return (const char*)tmp;
}
CRect CAsHexadecimalTextCell::GetTextBoxArea()
{
CRect tmp;
tmp = drawArea_;
//tmp.DeflateRect(7, 4, 5, 1);
tmp.DeflateRect(22, 4, 5, 1);
return tmp;
}
void CAsHexadecimalTextCell::StoreData()
{
if (HasFocus()) {
CString tmp;
long oldValue;
oldValue = value_;
editBox_->Validate();
value_ = editBox_->GetValue();
text_ = FormatValue(value_);
if (value_ != oldValue && cellListener_) {
bool ret;
ret = cellListener_->OnValueChanged(name_, oldValue, value_);
if (!ret) {
editBox_->SetWindowText(FormatValue(oldValue).c_str());
text_ = FormatValue(oldValue);
}
}
}
}
void CAsHexadecimalTextCell::SetReadOnly(bool readOnly)
{
readOnly_ = readOnly;
KillFocus(true, true);
}
bool CAsHexadecimalTextCell::IsReadOnly() const
{
return readOnly_;
}