
// MemDumpDlg.cpp : файл реализации
//

#include "pch.h"
#include "afxdialogex.h"
#include "resource.h"
#include "MemDumpDlg.h"
#include "Config.h"
#include "Debugger.h"
#include "BKMessageBox.h"
#include "Board.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// диалоговое окно CMemDumpDlg
DISPLAY_MODE_PARAM CMemDumpDlg::m_dmArray[DISPLAY_MODES_NUM] =
{
	{ DUMP_DISPLAY_MODE::DD_WORD_VIEW, IDS_MEMDUMP_WORD },
	{ DUMP_DISPLAY_MODE::DD_BYTE_VIEW, IDS_MEMDUMP_BYTE }
};

CMemDumpDlg::CMemDumpDlg(CWnd *pParent /*=nullptr*/)
	: CDialogEx(CMemDumpDlg::IDD, pParent)
	, m_pDebugger(nullptr)
	, m_nCurrentDDM(0)
	, m_hAccelTable(nullptr)
	, m_strDumpAddr(_T("0"))
{
}

CMemDumpDlg::~CMemDumpDlg()
{
	m_hFont.DeleteObject();
}

CSize CMemDumpDlg::GetMinSize()
{
	CSize size;
	MINMAXINFO mmi;
	m_Resizer.GetMinMaxInfo(&mmi);
	size.cx = mmi.ptMinTrackSize.x;
	size.cy = mmi.ptMinTrackSize.y;
	return size;
}

void CMemDumpDlg::DoDataExchange(CDataExchange *pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_LIST_MD_MEMORY, m_ListMemory);
	DDX_Control(pDX, IDC_EDIT_MD_DUMPADDR, m_EditAddr);
	DDX_Text(pDX, IDC_EDIT_MD_DUMPADDR, m_strDumpAddr);
}

BEGIN_MESSAGE_MAP(CMemDumpDlg, CDialogEx)
	ON_WM_PAINT()
	ON_WM_SIZE()
	ON_WM_GETMINMAXINFO()
	ON_WM_SETFOCUS()
	ON_MESSAGE(WM_DBG_TOP_ADDRESS_UPDATE, &CMemDumpDlg::OnDumpAddressChange)
	ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST_MD_MEMORY, &CMemDumpDlg::OnLvnItemchangedMdMemory)
	ON_BN_CLICKED(IDC_BUTTON_MD_DUMPMODE, &CMemDumpDlg::OnBnClickedButtonDumpMode)
	ON_BN_CLICKED(IDC_BUTTON_MD_SAVE, &CMemDumpDlg::OnBnClickedButtonSaveDump)
	ON_BN_CLICKED(IDC_BUTTON_MD_LOAD, &CMemDumpDlg::OnBnClickedButtonLoadDump)
END_MESSAGE_MAP()

void CMemDumpDlg::AttachDebugger(CDebugger *pDbgr)
{
	m_pDebugger = pDbgr;
}
// обработчики сообщений CMemDumpDlg

BOOL CMemDumpDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();
	m_hAccelTable = LoadAccelerators(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME));
	LOGFONT lf;
	::GetObject((HGDIOBJ)::SendMessage(GetSafeHwnd(), WM_GETFONT, 0, 0), sizeof(LOGFONT), &lf);
	_tcscpy_s(lf.lfFaceName, LF_FACESIZE, _T("Courier New\0"));

	if (!m_hFont.CreateFontIndirect(&lf))
	{
		_tcscpy_s(lf.lfFaceName, LF_FACESIZE, _T("Lucida Console\0"));
		m_hFont.CreateFontIndirect(&lf);
	}

	// Подсказки
	m_ToolTip.Create(this, WS_POPUP | TTS_NOPREFIX | TTS_USEVISUALSTYLE | TTS_ALWAYSTIP/* | TTS_BALLOON*/);
	m_ToolTip.SetDelayTime(TTDT_AUTOPOP, 20000);
	m_ToolTip.SetDelayTime(TTDT_INITIAL, 300);
	//*** you could change the default settings ***
	m_ToolTip.SetMaxTipWidth(400);
	//m_ToolTip.SetTipBkColor(RGB(121, 121, 121));
	//m_ToolTip.SetTipTextColor(RGB(255, 0, 0));
	m_ToolTip.AddTool(GetDlgItem(IDC_EDIT_MD_DUMPADDR), IDS_FIELD_DUMPADDR_STR);
	m_ToolTip.AddTool(GetDlgItem(IDC_BUTTON_MD_DUMPMODE), IDS_BUTTON_DUMPMODE_STR);
	m_ToolTip.AddTool(GetDlgItem(IDC_BUTTON_MD_SAVE), IDS_BUTTON_SAVEDUMP_STR);
	m_ToolTip.AddTool(GetDlgItem(IDC_BUTTON_MD_LOAD), IDS_BUTTON_LOADDUMP_STR);
	m_ToolTip.Activate(TRUE);
	m_Resizer.Init(this);
	m_Resizer.AddCtrl(IDC_LIST_MD_MEMORY, DT_LEFT | DT_TOP | DT_RIGHT | DT_BOTTOM, FALSE, FALSE);
	m_Resizer.AddCtrl(IDC_EDIT_MD_DUMPADDR, DT_LEFT | DT_TOP, TRUE, TRUE);
	m_Resizer.AddCtrl(IDC_BUTTON_MD_DUMPMODE, DT_LEFT | DT_TOP, TRUE, TRUE);
	m_EditAddr.SetLimitText(6);
	CString t;
	t.LoadString(m_dmArray[m_nCurrentDDM].strID);
	SetDlgItemText(IDC_BUTTON_MD_DUMPMODE, t); // на кнопке нарисуем начальное значение
	m_ListMemory.SetFont(&m_hFont, FALSE);
	m_ListMemory.Init(m_dmArray[m_nCurrentDDM].mode);
	UpdateData(FALSE);
	return TRUE;  // возврат значения TRUE, если фокус не передан элементу управления
}

// отменяем действие кнопок enter и esc в диалоге
void CMemDumpDlg::OnOK()
{
}

void CMemDumpDlg::OnCancel()
{
}

void CMemDumpDlg::OnSize(UINT nType, int cx, int cy)
{
	CDialogEx::OnSize(nType, cx, cy);
	m_Resizer.OnSize(cx, cy);
}


void CMemDumpDlg::OnGetMinMaxInfo(MINMAXINFO *lpMMI)
{
	m_Resizer.GetMinMaxInfo(lpMMI);
}

void CMemDumpDlg::OnSetFocus(CWnd *pOldWnd)
{
	CDialogEx::OnSetFocus(pOldWnd);
	m_ListMemory.SetFocus();
}

void CMemDumpDlg::SetAddress(uint16_t addr)
{
	m_ListMemory.SetAddress(addr);
	m_strDumpAddr = ::WordToOctString(addr);
	UpdateData(FALSE);
}

LRESULT CMemDumpDlg::OnDumpAddressChange(WPARAM wParam, LPARAM lParam)
{
	UpdateData(TRUE);
	uint16_t addr = ::OctStringToWord(m_strDumpAddr);
	// обновим значение, чтобы оно было всегда 6 значным
	m_strDumpAddr = ::WordToOctString(addr);
	UpdateData(FALSE);
	m_ListMemory.SetAddress(addr);
	m_ListMemory.RefreshItems(addr, true);
	return S_OK;
}


void CMemDumpDlg::OnLvnItemchangedMdMemory(NMHDR *pNMHDR, LRESULT *pResult)
{
	auto pNMListView = reinterpret_cast<LPNMLISTVIEW >(pNMHDR);
	int nSubItem = pNMListView->iSubItem;
	int nItem = pNMListView->iItem;

	switch (m_ListMemory.GetDisplayMode())
	{
		case DUMP_DISPLAY_MODE::DD_WORD_VIEW:
		{
			if (CDumpListCtrl::DUMP_LISTW::W_COL1 <= nSubItem && nSubItem <= CDumpListCtrl::DUMP_LISTW::W_COL4)
			{
				register int addr = m_ListMemory.GetAddress() + nItem * 010;
				register int nPos = (nSubItem - CDumpListCtrl::DUMP_LISTW::W_COL1) * 2; // 2 - кол-во charов в wordе
				addr += nPos;
				register auto pstr = reinterpret_cast<CString *>(pNMListView->lParam);
				register uint16_t value = ::OctStringToWord(*pstr);
				CString str = m_ListMemory.GetItemText(nItem, CDumpListCtrl::DUMP_LISTW::W_ASCII);
				str.SetAt(nPos++, m_ListMemory.GetMemDumpByteAsANSI(LOBYTE(value)));
				str.SetAt(nPos,   m_ListMemory.GetMemDumpByteAsANSI(HIBYTE(value)));
				m_ListMemory.SetEndEdit(nItem, nSubItem);

				if (m_pDebugger)
				{
					m_pDebugger->OnDebugModify_Memory(addr, value);
				}

				m_ListMemory.SetItemWithModified(value, nItem, nSubItem);
				m_ListMemory.SetItemWithModifiedASCII(str, nItem, CDumpListCtrl::DUMP_LISTW::W_ASCII);
			}

			break;
		}

		case DUMP_DISPLAY_MODE::DD_BYTE_VIEW:
		{
			if (CDumpListCtrl::DUMP_LISTB::B_COL1 <= nSubItem && nSubItem <= CDumpListCtrl::DUMP_LISTB::B_COL8)
			{
				register int addr = m_ListMemory.GetAddress() + nItem * 010;
				register int nPos = (nSubItem - CDumpListCtrl::DUMP_LISTB::B_COL1);
				addr += nPos;
				register auto pstr = reinterpret_cast<CString *>(pNMListView->lParam);
				register uint8_t value = LOBYTE(::OctStringToWord(*pstr));
				register TCHAR ch = m_ListMemory.GetMemDumpByteAsANSI(value);
				CString str = m_ListMemory.GetItemText(nItem, CDumpListCtrl::DUMP_LISTB::B_ASCII);
				str.SetAt(nPos, ch);
				m_ListMemory.SetEndEdit(nItem, nSubItem);

				if (m_pDebugger)
				{
					m_pDebugger->OnDebugModify_Memory(addr, value);
				}

				m_ListMemory.SetItemWithModifiedByte(value, nItem, nSubItem);
				m_ListMemory.SetItemWithModifiedASCII(str, nItem, CDumpListCtrl::DUMP_LISTB::B_ASCII);
			}

			break;
		}
	}

	*pResult = S_OK;
}

void CMemDumpDlg::OnBnClickedButtonDumpMode()
{
	if (++m_nCurrentDDM >= DISPLAY_MODES_NUM)
	{
		m_nCurrentDDM = 0;
	}

	CString t;
	t.LoadString(m_dmArray[m_nCurrentDDM].strID);
	SetDlgItemText(IDC_BUTTON_MD_DUMPMODE, t);
	m_ListMemory.SetDisplayMode(m_dmArray[m_nCurrentDDM].mode);
}

uint16_t CMemDumpDlg::GetDebugMemDumpWord(uint16_t dumpAddress)
{
	if (m_pDebugger)
	{
		return m_pDebugger->GetDebugMemDumpWord(dumpAddress);
	}

	return 0;
}
uint8_t CMemDumpDlg::GetDebugMemDumpByte(uint16_t dumpAddress)
{
	if (m_pDebugger)
	{
		return m_pDebugger->GetDebugMemDumpByte(dumpAddress);
	}

	return 0;
}

void CMemDumpDlg::DisplayMemDump()
{
	m_ListMemory.RefreshItems();
}

// для того, чтобы акселераторы работали, их надо загрузить и в этот диалог
// и передавать главному фрейму.
// способа проще найти не получилось.
BOOL CMemDumpDlg::PreTranslateMessage(MSG *pMsg)
{
	if (m_hAccelTable)
	{
		if (::TranslateAccelerator(AfxGetMainWnd()->GetSafeHwnd(), m_hAccelTable, pMsg))
		{
			return TRUE;
		}
	}

	if (pMsg->message >= WM_MOUSEFIRST && pMsg->message <= WM_MOUSELAST)
	{
		m_ToolTip.RelayEvent(pMsg);
	}

	return CDialogEx::PreTranslateMessage(pMsg);
}

#pragma warning(disable:4996)

void CMemDumpDlg::OnBnClickedButtonSaveDump()
{
	SvDmpParam sBinParam;
	GetDlgItem(IDC_BUTTON_MD_SAVE)->GetWindowRect(&sBinParam.rect);
	auto SvDmpDlg = new CSvDmpParamDlg(&sBinParam);

	if (SvDmpDlg)
	{
		if (SvDmpDlg->DoModal() == IDOK)
		{
			int nAddr = sBinParam.nBgnAddr;
			int nLen = sBinParam.nLength;

			if (nAddr + nLen >= 0200000)
			{
				nLen = 0200000 - nAddr;
			}

			if (nLen > 0)
			{
				CString strDefExt(MAKEINTRESOURCE(IDS_FILEEXT_BINARY));
				CString strFilter(MAKEINTRESOURCE(IDS_FILEFILTER_BIN));
				CFileDialog dlg(FALSE, strDefExt, nullptr,
				                OFN_HIDEREADONLY | OFN_CREATEPROMPT | OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR | OFN_EXPLORER,
				                strFilter, this);
				dlg.GetOFN().lpstrInitialDir = g_Config.m_strBinPath.GetString(); // диалог всегда будем начинать с директории для bin файлов

				if (dlg.DoModal() == IDOK)
				{
					CString str = dlg.GetPathName();
					auto buf = new uint8_t[nLen];

					if (buf)
					{
						if (m_pDebugger)
						{
							auto pBoard = m_pDebugger->GetBoard();

							if (pBoard)
							{
								pBoard->StopCPU();
								//pBoard->SetMemPages(sBinParam.nPage0, sBinParam.nPage1);
							}
						}

						for (int addr = nAddr, i = 0; i < nLen; ++i)
						{
							buf[i] = GetDebugMemDumpByte(addr++);
						}

						::SaveBinFile(buf, nAddr, nLen, str);

						if (m_pDebugger)
						{
							auto pBoard = m_pDebugger->GetBoard();

							if (pBoard)
							{
								//pBoard->RestoreMemPages();
								pBoard->RunCPU();
							}
						}

						delete [] buf;
					}
					else
					{
						g_BKMsgBox.Show(IDS_BK_ERROR_NOTENMEMR, MB_OK);
					}
				}
			}
		}

		delete SvDmpDlg;
	}
}


void CMemDumpDlg::OnBnClickedButtonLoadDump()
{
	if (!!(::GetAsyncKeyState(VK_SHIFT) & 0x8000))
	{
		SvDmpParam sBinParam;
		GetDlgItem(IDC_BUTTON_MD_LOAD)->GetWindowRect(&sBinParam.rect);
		auto LdDmpDlg = new CLdDmpParamDlg(&sBinParam);

		if (LdDmpDlg)
		{
			if (LdDmpDlg->DoModal() == IDOK)
			{
				// если БК11(М) - подключить нужные страницы
				if (m_pDebugger)
				{
					auto pBoard = m_pDebugger->GetBoard();

					if (pBoard)
					{
						pBoard->StopCPU();
						pBoard->SetMemPages(sBinParam.nPage0, sBinParam.nPage1);
					}
				}

				LoadFunc(sBinParam.nBgnAddr);

				// если БК11(М) - отключить нужные страницы и вернуть как было
				if (m_pDebugger)
				{
					auto pBoard = m_pDebugger->GetBoard();

					if (pBoard)
					{
						pBoard->RestoreMemPages();
						pBoard->RunCPU();
					}
				}
			}

			delete LdDmpDlg;
		}
	}
	else
	{
		LoadFunc();
	}
}

void CMemDumpDlg::LoadFunc(uint16_t nLoadAddr)
{
	CString strDefExt(MAKEINTRESOURCE(IDS_FILEEXT_BINARY));
	CString strFilter(MAKEINTRESOURCE(IDS_FILEFILTER_BIN));
	CFileDialog dlg(TRUE, strDefExt, nullptr,
	                OFN_HIDEREADONLY | OFN_CREATEPROMPT | OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR | OFN_EXPLORER,
	                strFilter, this);
	dlg.GetOFN().lpstrInitialDir = g_Config.m_strBinPath.GetString(); // диалог всегда будем начинать с директории для bin файлов

	if (dlg.DoModal() == IDOK)
	{
		CString str = dlg.GetPathName();
		uint16_t nAddr, nLen;
		uint8_t *buf = nullptr;

		if (::LoadBinFile(&buf, &nAddr, &nLen, str, false))
		{
			// !!! Косяк - невозможно загружать принудительно с нулевого адреса.
			// Тут бы очень помогли отрицательные числа, но их ввод в поле адреса не предусмотрен,
			// как быть, пока идей нет.
			if (nLoadAddr)
			{
				nAddr = nLoadAddr;
			}

			if (int(nAddr) + int(nLen) >= 0200000)
			{
				nLen = 0200000 - nAddr;
			}

			if (m_pDebugger)
			{
				for (int i = 0; i < nLen; ++i)
				{
					m_pDebugger->OnDebugModify_Memory(nAddr++, buf[i]);
				}
			}

			delete [] buf;
		}
	}
}

IMPLEMENT_DYNAMIC(CSvDmpParamDlg, CDialogEx)

CSvDmpParamDlg::CSvDmpParamDlg(SvDmpParam *pParam, CWnd *pParent /*= nullptr*/)
	: CDialogEx(CSvDmpParamDlg::IDD, pParent)
	, m_pParam(pParam)
	, m_nBgnAddr(0)
	, m_nEndAddr(040000)
	, m_nLength(m_nEndAddr - m_nBgnAddr)
{
	m_strBgnAddr = ::WordToOctString(m_nBgnAddr);
	m_strEndAddr = ::WordToOctString(m_nEndAddr);
	m_strLength = ::WordToOctString(m_nLength);
}

CSvDmpParamDlg::~CSvDmpParamDlg()
    = default;

BEGIN_MESSAGE_MAP(CSvDmpParamDlg, CDialogEx)
	ON_MESSAGE(WM_DBG_TOP_ADDRESS_UPDATE, &CSvDmpParamDlg::OnEditChange)
	ON_EN_KILLFOCUS(IDC_EDIT_SVDMP_BGNADDR, &CSvDmpParamDlg::OnEnKillfocusEditSvdmpBgnaddr)
	ON_EN_KILLFOCUS(IDC_EDIT_SVDMP_ENDADDR, &CSvDmpParamDlg::OnEnKillfocusEditSvdmpEndaddr)
	ON_EN_KILLFOCUS(IDC_EDIT_SVDMP_LENGTH, &CSvDmpParamDlg::OnEnKillfocusEditSvdmpLength)
END_MESSAGE_MAP()

void CSvDmpParamDlg::DoDataExchange(CDataExchange *pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_EDIT_SVDMP_BGNADDR, m_EditBgnAddr);
	DDX_Control(pDX, IDC_EDIT_SVDMP_ENDADDR, m_EditEndAddr);
	DDX_Control(pDX, IDC_EDIT_SVDMP_LENGTH, m_EditLength);
	DDX_Text(pDX, IDC_EDIT_SVDMP_BGNADDR, m_strBgnAddr);
	DDX_Text(pDX, IDC_EDIT_SVDMP_ENDADDR, m_strEndAddr);
	DDX_Text(pDX, IDC_EDIT_SVDMP_LENGTH, m_strLength);
}

BOOL CSvDmpParamDlg::OnInitDialog()
{
	CRect r2;
	GetWindowRect(r2);
	MoveWindow(m_pParam->rect.left, m_pParam->rect.top + m_pParam->rect.Height(), r2.Width(), r2.Height(), FALSE);
	CDialogEx::OnInitDialog();
	m_EditBgnAddr.SetLimitText(6);
	m_EditEndAddr.SetLimitText(6);
	m_EditLength.SetLimitText(6);
	UpdateData(FALSE);
	return TRUE;
}

void CSvDmpParamDlg::OnOK()
{
	if (m_pParam)
	{
		m_pParam->nBgnAddr = m_nBgnAddr;
		m_pParam->nLength = m_nLength;
	}

	CDialogEx::OnOK();
}


LRESULT CSvDmpParamDlg::OnEditChange(WPARAM wParam, LPARAM lParam)
{
	UpdateData(TRUE);

	switch (wParam)
	{
		case IDC_EDIT_SVDMP_BGNADDR:
			m_nBgnAddr = ::OctStringToWord(m_strBgnAddr);

			if (m_nBgnAddr > 65536)
			{
				m_nBgnAddr = 0;
			}

			if (m_nBgnAddr > m_nEndAddr)
			{
				std::swap(m_nBgnAddr, m_nEndAddr);
			}

			m_nLength = m_nEndAddr - m_nBgnAddr;
			break;

		case IDC_EDIT_SVDMP_ENDADDR:
			m_nEndAddr = ::OctStringToWord(m_strEndAddr);

			if (m_nEndAddr > 65536)
			{
				m_nEndAddr = 0;
			}

			if (m_nBgnAddr > m_nEndAddr)
			{
				std::swap(m_nBgnAddr, m_nEndAddr);
			}

			m_nLength = m_nEndAddr - m_nBgnAddr;
			break;

		case IDC_EDIT_SVDMP_LENGTH:
			m_nLength = ::OctStringToWord(m_strLength);

			if (m_nLength > 65536)
			{
				m_nLength = 65536;
			}

			m_nEndAddr = m_nBgnAddr + m_nLength;

			if (m_nEndAddr > 65536)
			{
				m_nEndAddr = 65536;
				m_nLength = m_nEndAddr - m_nBgnAddr;
			}

			break;

		default:
			return LRESULT();
	}

	m_strBgnAddr = ::WordToOctString(m_nBgnAddr);
	m_strEndAddr = ::WordToOctString(m_nEndAddr);
	m_strLength = ::WordToOctString(m_nLength);
	UpdateData(FALSE);
	return LRESULT();
}


void CSvDmpParamDlg::OnEnKillfocusEditSvdmpBgnaddr()
{
	OnEditChange(IDC_EDIT_SVDMP_BGNADDR, 0);
}


void CSvDmpParamDlg::OnEnKillfocusEditSvdmpEndaddr()
{
	OnEditChange(IDC_EDIT_SVDMP_ENDADDR, 0);
}


void CSvDmpParamDlg::OnEnKillfocusEditSvdmpLength()
{
	OnEditChange(IDC_EDIT_SVDMP_LENGTH, 0);
}


IMPLEMENT_DYNAMIC(CLdDmpParamDlg, CDialogEx)

CLdDmpParamDlg::CLdDmpParamDlg(SvDmpParam *pParam /*= nullptr*/, CWnd *pParent /*= nullptr*/)
	: CDialogEx(CLdDmpParamDlg::IDD, pParent)
	, m_pParam(pParam)
	, m_nBgnAddr(0)
	, m_nPg0(5)
	, m_nPg1(1)
{
	m_strBgnAddr = ::WordToOctString(m_nBgnAddr);
}

CLdDmpParamDlg::~CLdDmpParamDlg()
    = default;

BEGIN_MESSAGE_MAP(CLdDmpParamDlg, CDialogEx)
	ON_MESSAGE(WM_DBG_TOP_ADDRESS_UPDATE, &CLdDmpParamDlg::OnEditChange)
	ON_EN_KILLFOCUS(IDC_EDIT_LDDMP_ADDR, &CLdDmpParamDlg::OnEnKillfocusEditLddmpAddr)
END_MESSAGE_MAP()

void CLdDmpParamDlg::DoDataExchange(CDataExchange *pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_EDIT_LDDMP_ADDR, m_EditBgnAddr);
	DDX_Text(pDX, IDC_EDIT_LDDMP_ADDR, m_strBgnAddr);
	DDX_Control(pDX, IDC_EDIT_LDDMP_PG0, m_EditPG0); // IDC_EDIT_LDDMP_PG0 - номер страницы 1 ( на адрес 040000 )
	DDX_Control(pDX, IDC_EDIT_LDDMP_PG1, m_EditPG1);// IDC_EDIT_LDDMP_PG1 - страница 2 ( на адрес 100000 )
	DDX_Text(pDX, IDC_EDIT_LDDMP_PG0, m_nPg0);
	DDX_Text(pDX, IDC_EDIT_LDDMP_PG1, m_nPg1);
}

BOOL CLdDmpParamDlg::OnInitDialog()
{
	CRect r2;
	GetWindowRect(r2);
	MoveWindow(m_pParam->rect.left, m_pParam->rect.top + m_pParam->rect.Height(), r2.Width(), r2.Height(), FALSE);
	CDialogEx::OnInitDialog();
	m_EditBgnAddr.SetLimitText(6);
	m_EditPG0.SetLimitText(1);
	m_EditPG1.SetLimitText(1);

	// Если сейчас не БК11М и её конфигурации, засерим контролы выбора страниц.
	// В других местах - не юзаем результаты в контролах и не сохраняем
	if (!(g_Config.isBK11() || g_Config.isBK11M()))
	{
		GetDlgItem(IDC_EDIT_LDDMP_PG0)->EnableWindow(FALSE);
		GetDlgItem(IDC_EDIT_LDDMP_PG1)->EnableWindow(FALSE);
		GetDlgItem(IDC_TEXT_LDDMP_PG0)->EnableWindow(FALSE);
		GetDlgItem(IDC_TEXT_LDDMP_PG1)->EnableWindow(FALSE);
	}

	UpdateData(FALSE);
	return TRUE;
}

void CLdDmpParamDlg::OnOK()
{
	UpdateData(TRUE);

	if (m_pParam)
	{
		m_nBgnAddr = ::OctStringToWord(m_strBgnAddr);
		m_pParam->nBgnAddr = m_nBgnAddr;
		m_pParam->nPage0 = m_nPg0;
		m_pParam->nPage1 = m_nPg1;
	}

	CDialogEx::OnOK();
}


LRESULT CLdDmpParamDlg::OnEditChange(WPARAM wParam, LPARAM lParam)
{
	UpdateData(TRUE);

	switch (wParam)
	{
		case IDC_EDIT_LDDMP_ADDR:
			m_nBgnAddr = ::OctStringToWord(m_strBgnAddr);

			if (m_nBgnAddr > 65536)
			{
				m_nBgnAddr = 0;
			}

			break;

		default:
			return LRESULT();
	}

	m_strBgnAddr = ::WordToOctString(m_nBgnAddr);
	UpdateData(FALSE);
	return LRESULT();
}

void CLdDmpParamDlg::OnEnKillfocusEditLddmpAddr()
{
	OnEditChange(IDC_EDIT_LDDMP_ADDR, 0);
}
