?? dbdataview.cpp.txt
字號:
// DbDataView.cpp : implementation file
//
#include "stdafx.h"
#include "minidatabase.h"
#include "DbDataView.h"
#include "TextView.h"
#include "DbTreeView.h"
#include "MainFrm.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define IDC_GRID_CTRL 1002
/////////////////////////////////////////////////////////////////////////////
// CDbDataView
IMPLEMENT_DYNCREATE(CDbDataView, CView)
CDbDataView::CDbDataView()
{
m_pTable = NULL;
}
CDbDataView::~CDbDataView()
{
}
void CDbDataView::SetFirstRow(TABLE *table)
{
if (table == NULL)
return;
for (int i = 0; i < m_gridCtrl.GetColumnCount(); i++)
{
FIELD *f = table->fields + i;
GV_ITEM Item;
Item.mask = GVIF_TEXT | GVIF_FORMAT;
Item.row = 0;
Item.col = i;
Item.nFormat = DT_LEFT | DT_WORDBREAK;
Item.szText.Format(_T("%s"), f->name);
m_gridCtrl.SetItem(&Item);
}
}
CString GetFieldString(FIELD *f, BYTE *buff)
{
CString str;
switch (f->type)
{
case FIELD_TYPE_CHAR:
if (f->count > 1)
str.Format(_T("%s"), (char *)buff);
else
str.Format(_T("%c"), (char)(*buff));
break;
case FIELD_TYPE_BYTE:
{
CString strOne;
BYTE *b = buff;
for (int k = 0, last = f->count - 1; k < f->count; k++, b++)
{
strOne.Format(_T("0x%02x"), *b);
str += strOne;
if (k < last)
str += _T(", ");
}
}
break;
case FIELD_TYPE_SHORT:
if (f->count == 1)
{
str.Format(_T("%d"), *(WORD *)buff);
}
else
{
CString strOne;
SHORT *v = (SHORT *)buff;
str.Empty();
for (int k = 0, last = f->count - 1; k < f->count; k++, v++)
{
strOne.Format(_T("%d"), *v);
str += strOne;
if (k < last)
str += _T(", ");
}
}
break;
case FIELD_TYPE_WORD:
{
CString strOne;
WORD *v = (WORD *)buff;
str.Empty();
for (int k = 0, last = f->count - 1; k < f->count; k++, v++)
{
strOne.Format(_T("%u"), *v);
str += strOne;
if (k < last)
str += _T(", ");
}
}
break;
case FIELD_TYPE_INT:
{
CString strOne;
INT *v = (INT *)buff;
str.Empty();
for (int k = 0, last = f->count - 1; k < f->count; k++, v++)
{
strOne.Format(_T("%d"), *v);
str += strOne;
if (k < last)
str += _T(", ");
}
}
break;
case FIELD_TYPE_UINT:
{
CString strOne;
UINT *v = (UINT *)buff;
str.Empty();
for (int k = 0, last = f->count - 1; k < f->count; k++, v++)
{
strOne.Format(_T("%u"), *v);
str += strOne;
if (k < last)
str += _T(", ");
}
}
break;
}
return str;
}
void CDbDataView::LoadRecords(TABLE *table)
{
if (table == NULL)
return;
//m_gridCtrl.ShowWindow(SW_HIDE);
m_gridCtrl.DeleteAllItems();
// 顯示數據
m_gridCtrl.SetRowCount((table->max_rows == 1 ? 1 : ((table->used_rows < table->max_rows) ? (table->used_rows + 1) : table->used_rows)) + 1);
m_gridCtrl.SetFixedRowCount(1);
m_gridCtrl.SetColumnCount(table->field_count);
m_gridCtrl.SetFixedColumnCount(0);
m_gridCtrl.SetRowResize(FALSE);
SetFirstRow(table);
// 載入數據
int nRow = 1;
RECORD *record = table->records;
do
{
if (record == NULL)
break;
BYTE *bpos = record->data;
for (int i = 0; i < table->field_count; i++)
{
FIELD *f = table->fields + i;
GV_ITEM Item;
Item.mask = GVIF_TEXT | GVIF_FORMAT;
Item.row = nRow;
Item.col = i;
Item.nFormat = DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS;
Item.szText = GetFieldString(f, bpos + f->offset);
m_gridCtrl.SetItem(&Item);
}
m_gridCtrl.SetItemData(nRow, 0, (LPARAM)record);
nRow++;
record = record->next;
} while (record != table->records);
m_gridCtrl.AutoSize();
m_gridCtrl.ShowWindow(SW_SHOW);
}
BEGIN_MESSAGE_MAP(CDbDataView, CView)
//{{AFX_MSG_MAP(CDbDataView)
ON_UPDATE_COMMAND_UI(ID_EDIT_INDICATOR_CRLF, OnUpdateIndicatorCRLF)
ON_UPDATE_COMMAND_UI(ID_INDICATOR_OVR, OnUpdateIndicatorOvr)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_WM_SIZE()
ON_NOTIFY(GVN_ENDLABELEDIT, IDC_GRID_CTRL, OnEndLabelEditGridCtrl)
ON_NOTIFY(GVN_RCLICK, IDC_GRID_CTRL, OnRclickGridCtrl)
ON_COMMAND(ID_DELETE_RECORD, OnDeleteRecord)
//}}AFX_MSG_MAP
ON_MESSAGE(WM_SET_DATA, OnSetData)
ON_MESSAGE(WM_HIDE_GRID, OnHideGrid)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDbDataView drawing
void CDbDataView::OnDraw(CDC* pDC)
{
CDocument* pDoc = GetDocument();
// TODO: add draw code here
}
/////////////////////////////////////////////////////////////////////////////
// CDbDataView diagnostics
#ifdef _DEBUG
void CDbDataView::AssertValid() const
{
CView::AssertValid();
}
void CDbDataView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CDbDataView message handlers
void CDbDataView::OnUpdateIndicatorCRLF(CCmdUI* pCmdUI)
{
pCmdUI->SetText(NULL);
pCmdUI->Enable(FALSE);
}
void CDbDataView::OnUpdateIndicatorOvr(CCmdUI* pCmdUI)
{
pCmdUI->Enable(FALSE);
}
void CDbDataView::OnSetData(TABLE *table, LPARAM)
{
if (table)
{
if (m_pTable != table)
{
m_pTable = table;
LoadRecords(m_pTable);
}
}
}
void CDbDataView::OnHideGrid(WPARAM, LPARAM)
{
m_pTable = NULL;
m_gridCtrl.ShowWindow(SW_HIDE);
}
int CDbDataView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
DWORD dwStyle = WS_CHILD | WS_BORDER;
m_gridCtrl.Create(CRect(0, 0, 0, 0), this, IDC_GRID_CTRL, dwStyle);
m_gridCtrl.SetDoubleBuffering(TRUE);
return 0;
}
void CDbDataView::OnDestroy()
{
CView::OnDestroy();
// TODO: Add your message handler code here
}
void CDbDataView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
CRect rcClient;
GetClientRect(&rcClient);
m_gridCtrl.SetWindowPos (&wndTop, rcClient.left, rcClient.top,
rcClient.Width(), rcClient.Height(),
m_gridCtrl.GetColumnCount() > 0 ? SWP_SHOWWINDOW : SWP_HIDEWINDOW);
}
void CDbDataView::OnEndLabelEditGridCtrl(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_GRIDVIEW *nmgv = (NM_GRIDVIEW *)pNMHDR;
// 第0行為固定標題
if (m_pTable && nmgv->iRow > 0 && nmgv->iColumn < m_pTable->field_count)
{
RECORD *record = (RECORD *)m_gridCtrl.GetItemData(nmgv->iRow, 0);
if (record == NULL) // 新紀錄
{
record = (RECORD *)new BYTE[RECORD_HDRSIZE + m_pTable->record_size];
// 連入數據庫鏈表
if (record)
{
m_pTable->records = insert_record_link(m_pTable->records, record, NULL);
m_gridCtrl.SetItemData(nmgv->iRow, 0, (LPARAM)record);
m_pTable->used_rows++;
// 插入一條新記錄備用
if (m_pTable->used_rows < m_pTable->max_rows)
m_gridCtrl.InsertRow(_T(""));
}
}
if (record)
{
FIELD *f = m_pTable->fields + nmgv->iColumn;
BYTE *buff = record->data + f->offset;
CString strText = m_gridCtrl.GetItemText(nmgv->iRow, nmgv->iColumn);
// 檢查缺省值
if (f->type == FIELD_TYPE_CHAR && f->count > 1)
{
char *s = (char *)buff;
strncpy(s, strText, f->count);
}
else if (f->count > 1)
{
void *ptr = buff;
int vcnt = f->count;
if (ReadArrayValue(strText, &ptr, &vcnt, f->type) > 0)
MessageBox(_T("不合法的數字數組!"), _T("提示信息"), MB_OK | MB_ICONINFORMATION);
}
else
{
if (!IsFitNumber(strText, strText.GetLength()))
MessageBox(_T("不合法的數字!"), _T("提示信息"), MB_OK | MB_ICONINFORMATION);
else
{
char *szStopped;
ULONG v = StringToULong((char *)(LPCTSTR)strText, &szStopped);
switch (f->type)
{
case FIELD_TYPE_CHAR:
case FIELD_TYPE_BYTE:
*buff = (BYTE)v;
break;
case FIELD_TYPE_SHORT:
case FIELD_TYPE_WORD:
*(WORD *)buff = (WORD)v;
break;
case FIELD_TYPE_INT:
case FIELD_TYPE_UINT:
*(UINT *)buff = (UINT)v;
break;
}
}
}
m_gridCtrl.SetItemText(nmgv->iRow, nmgv->iColumn, GetFieldString(f, buff));
}
}
*pResult = 0;
}
void CDbDataView::OnRclickGridCtrl(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO: Add your control notification handler code here
NM_GRIDVIEW *nmgv = (NM_GRIDVIEW *)pNMHDR;
POINT ptCursor;
::GetCursorPos(&ptCursor);
// 彈出菜單
CMenu menu, *pSubMenu;
int nMenuHeight = GetSystemMetrics(SM_CYMENUSIZE) * 4, cy = GetSystemMetrics(SM_CYSCREEN);
// Clicking with right button brings up a context menu
if (!menu.LoadMenu(IDR_POPUP_DATA))
return;
if (!(pSubMenu = menu.GetSubMenu(0)))
return;
if (m_gridCtrl.GetItemData(nmgv->iRow, 0) == NULL ||
m_pTable->max_rows == 1)
pSubMenu->EnableMenuItem(0, MF_BYPOSITION | MF_GRAYED);
if ((ptCursor.y + nMenuHeight) > cy)
ptCursor.y = cy - nMenuHeight - 5;
// Display and track the popup menu
::TrackPopupMenu(pSubMenu->m_hMenu, 0, ptCursor.x, ptCursor.y, 0,
GetSafeHwnd(), NULL);
// BUGFIX: See "PRB: Menus for Notification Icons Don't Work Correctly"
PostMessage(WM_NULL, 0, 0);
menu.DestroyMenu();
*pResult = 0;
}
void CDbDataView::OnDeleteRecord()
{
// TODO: Add your command handler code here
CDbTreeView *pTree = (CDbTreeView *)((CMainFrame *)GetParentFrame())->m_pEditDbView[0];
CCellRange cr = m_gridCtrl.GetSelectedCellRange();
for (int iRow = cr.GetMinRow(); iRow <= cr.GetMaxRow(); iRow++)
{
RECORD *record = (RECORD *)m_gridCtrl.GetItemData(iRow, 0);
if (record)
{
m_pTable->records = delete_record_link(m_pTable->records, record);
m_pTable->used_rows--;
if (pTree->IsPrivateMemory(record))
delete record;
else
m_pTable->deleted = insert_record_link(m_pTable->deleted, record, NULL);
m_gridCtrl.DeleteRow(cr.GetMinRow());
}
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -