#include "StdAfx.h"
#include "DbMainWnd.h"
#include "DbViewRes.h"
#include "CeFontDlg.h"
#include "DbWiz.h"
#define IDC_TREE 100
#define IDC_LIST 101
#define IDC_BAND 102
#if defined(_WIN32_WCE_POCKETPC)
static SHACTIVATEINFO s_saiDlgBox;
static SHACTIVATEINFO s_sai;
#endif
LPCTSTR GetTypeName(WORD wType)
{
switch (wType)
{
case 0: return _T("Unspecified");
case CEVT_I2: return _T("Short");
case CEVT_UI2: return _T("UShort");
case CEVT_I4: return _T("Int");
case CEVT_UI4: return _T("UInt");
case CEVT_FILETIME: return _T("FileTime");
case CEVT_LPWSTR: return _T("String");
case CEVT_BLOB: return _T("Blob");
}
return _T("???");
}
///////////////////////////////////////////////////////////////////////////////
//
// CeAboutDlg = Dialog for displaying information about the product
//
///////////////////////////////////////////////////////////////////////////////
class CeAboutDlg: public CeScrollDialog
{
private:
CeChildMgr m_mgr;
public:
CeAboutDlg(): CeScrollDialog(IDD_ABOUT)
{}
virtual BOOL OnInitDialog();
virtual void OnSize(UINT nType, int cx, int cy, bool& bHandled)
{
m_mgr.OnSize(nType, cx, cy);
CeScrollDialog::OnSize(nType, cx, cy, bHandled);
}
};
#define IDT_ANIM_ICON 100
BOOL CeAboutDlg::OnInitDialog()
{
BOOL bRet = CeScrollDialog::OnInitDialog();
m_mgr.Manage(GetDlgItem(IDC_NAME_STATIC), AL_ADJUST_SIZE);
#ifdef _WIN32_WCE_POCKETPC
// Create a Done button and size it.
SHINITDLGINFO shidi;
shidi.dwMask = SHIDIM_FLAGS;
shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN | SHIDIF_SIZEDLGFULLSCREEN;
shidi.hDlg = m_hWnd;
SHInitDialog(&shidi);
#endif
// allow controls to be created
return bRet;
}
///////////////////////////////////////////////////////////////////////////////
class CePropDlg: public CeScrollDialog
{
private:
CeChildMgr m_mgr;
public:
CEOID m_oidDb;
CePropDlg(): CeScrollDialog()
{ m_oidDb = 0; }
virtual BOOL OnInitDialog();
virtual void OnSettingChange(WORD wFlag, LPCTSTR pszSection, bool& bHandled);
virtual void OnSize(UINT nType, int cx, int cy, bool& bHandled);
};
BOOL CePropDlg::OnInitDialog()
{
CeScrollDialog::OnInitDialog();
CeString str;
CEOIDINFO oidInfo;
ZeroMemory(&oidInfo, sizeof oidInfo);
::CeOidGetInfo(m_oidDb, &oidInfo);
SetDlgItemText(IDC_STATIC_NAME, oidInfo.infDatabase.szDbaseName);
if (oidInfo.infDatabase.dwFlags & CEDB_VALIDTYPE)
{
str.SetULong(oidInfo.infDatabase.dwDbaseType);
SetDlgItemText(IDC_STATIC_TYPE, str);
}
else
SetDlgItemText(IDC_STATIC_TYPE, _T(""));
str.SetULong(oidInfo.infDatabase.wNumRecords);
SetDlgItemText(IDC_STATIC_RECORDS, str);
str.SetULong(oidInfo.infDatabase.dwSize);
SetDlgItemText(IDC_STATIC_SIZE, str);
SYSTEMTIME st;
BOOL bSuccess = ::FileTimeToSystemTime(&oidInfo.infDatabase.ftLastModified, &st);
if (! bSuccess || st.wYear > 9999)
{
str.Empty();
}
else
{
CeString strTime;
::GetDateFormat(LOCALE_SYSTEM_DEFAULT, DATE_SHORTDATE,
&st, NULL, str.GetBufferSetLength(32), 32);
str.ReleaseBuffer();
str += _T(" ");
::GetTimeFormat(LOCALE_SYSTEM_DEFAULT, TIME_NOSECONDS,
&st, NULL, strTime.GetBufferSetLength(32), 32);
strTime.ReleaseBuffer();
str += strTime;
}
SetDlgItemText(IDC_STATIC_MODIFIED, str);
str.Format(_T("0x%x"), m_oidDb);
SetDlgItemText(IDC_STATIC_OID, str);
// Set up the columns for the sort
HWND hList = GetDlgItem(IDC_KEYS);
ListView_SetExtendedListViewStyle(hList, LVS_EX_FULLROWSELECT);
// No sorts
if (! (oidInfo.infDatabase.dwFlags & CEDB_VALIDSORTSPEC) ||
(oidInfo.infDatabase.wNumSortOrder == 1) &&
(oidInfo.infDatabase.rgSortSpecs[0].propid == 0))
return TRUE;
// Setup the columns
LVCOLUMN col;
col.mask = LVCF_TEXT;
col.pszText = _T("Column");
ListView_InsertColumn(hList, 0, &col);
col.pszText = _T("Type");
ListView_InsertColumn(hList, 1, &col);
col.pszText = _T("Style");
ListView_InsertColumn(hList, 2, &col);
LVITEM item;
for (int ii = 0; ii < oidInfo.infDatabase.wNumSortOrder; ii++)
{
CeString str;
str.SetLong(HIWORD(oidInfo.infDatabase.rgSortSpecs[ii].propid), 16);
item.mask = LVIF_TEXT;
item.pszText = (LPTSTR) (LPCTSTR) str;
item.iSubItem = 0;
item.iItem = ListView_GetItemCount(hList);
ListView_InsertItem(hList, &item);
LPCTSTR lpszType = GetTypeName(
TypeFromPropID(oidInfo.infDatabase.rgSortSpecs[ii].propid));
item.pszText = (LPTSTR) lpszType;
item.iSubItem = 1;
ListView_SetItem(hList, &item);
str.Empty();
DWORD dwFlags = oidInfo.infDatabase.rgSortSpecs[ii].dwFlags;
if (dwFlags & CEDB_SORT_DESCENDING)
str += _T("Descending ");
if (dwFlags & CEDB_SORT_CASEINSENSITIVE)
str += _T("CaseInsensitive ");
if (dwFlags & CEDB_SORT_UNKNOWNFIRST)
str += _T("UnknownFirst");
item.pszText = (LPTSTR) (LPCTSTR) str;
item.iSubItem = 2;
ListView_SetItem(hList, &item);
}
m_mgr.Manage(GetDlgItem(IDC_STATIC_NAME), AL_ADJUST_WIDTH);
m_mgr.Manage(GetDlgItem(IDC_STATIC_TYPE), AL_ADJUST_WIDTH);
m_mgr.Manage(GetDlgItem(IDC_STATIC_RECORDS), AL_ADJUST_WIDTH);
m_mgr.Manage(GetDlgItem(IDC_STATIC_SIZE), AL_ADJUST_WIDTH);
m_mgr.Manage(GetDlgItem(IDC_STATIC_MODIFIED), AL_ADJUST_WIDTH);
m_mgr.Manage(GetDlgItem(IDC_STATIC_OID), AL_ADJUST_WIDTH);
m_mgr.Manage(GetDlgItem(IDC_KEYS), AL_ADJUST_SIZE);
ListView_SetColumnWidth(hList, 0, LVSCW_AUTOSIZE_USEHEADER);
ListView_SetColumnWidth(hList, 1, LVSCW_AUTOSIZE_USEHEADER);
ListView_SetColumnWidth(hList, 2, LVSCW_AUTOSIZE_USEHEADER);
#ifdef _WIN32_WCE_POCKETPC
// Create a Done button and size it.
SHINITDLGINFO shidi;
shidi.dwMask = SHIDIM_FLAGS;
shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN | SHIDIF_SIZEDLGFULLSCREEN;
shidi.hDlg = m_hWnd;
SHInitDialog(&shidi);
#endif
return TRUE;
}
void CePropDlg::OnSize(UINT nType, int cx, int cy, bool& bHandled)
{
m_mgr.OnSize(nType, cx, cy);
CeScrollDialog::OnSize(nType, cx, cy, bHandled);
}
void CePropDlg::OnSettingChange( WORD wFlag, LPCTSTR pszSection, bool& bHandled )
{
#if defined(_WIN32_WCE_POCKETPC)
s_saiDlgBox.cbSize = sizeof s_saiDlgBox;
SHHandleWMSettingChange(m_hWnd, wFlag, (long) pszSection, &s_saiDlgBox);
bHandled = true;
#elif defined(_WIN32_WCE_PSPC)
switch (wFlag)
{
case SPI_SETSIPINFO:
{
SIPINFO si;
memset( &si, 0, sizeof( si ) );
si.cbSize = sizeof( si );
if( SHSipInfo( SPI_GETSIPINFO, 0, &si, 0 ) )
{
MoveWindow(
si.rcVisibleDesktop.left,
si.rcVisibleDesktop.top,
si.rcVisibleDesktop.right - si.rcVisibleDesktop.left,
si.rcVisibleDesktop.bottom -
si.rcVisibleDesktop.top,
TRUE );
}
}
break;
default:
break;
}
#endif // _WIN32_PPC_
}
///////////////////////////////////////////////////////////////////////////////
CeDbMainWnd::CeDbMainWnd()
{
m_hFont = NULL;
m_hImages = NULL;
m_bPalm = false;
m_bMoving = false;
m_nFontSize = 0;
m_nFirst = 0;
m_nRecs = 0;
// always 1 to start, well, not yet
m_nCols = 0;
m_hwndList = NULL;
m_hwndTree = NULL;
}
BOOL CeDbMainWnd::OnCommand(WPARAM wParam, LPARAM lParam, bool& bHandled)
{
WORD wNotify = HIWORD(wParam); // notification code
WORD wId = LOWORD(wParam); // item, control, or accelerator identifier
HWND hwndCtl = (HWND) lParam; // handle of control
// menu commands
if (0 == wNotify)
{
// Parse the menu selections:
bHandled = true;
switch (wId)
{
case IDM_ABOUT: OnAbout(); break;
case IDM_QUIT: DestroyWindow(); break;
case IDM_DELDB: OnDeleteDb(); break;
case IDM_DELRECORD: OnDeleteRecord(); break;
case IDM_REFRESH: OnRefresh(); break;
case IDM_PROPERTIES: OnProperties(); break;
case ID_VIEW_OPTIONS: OnOptions(); break;
default:
bHandled = false;
break;
}
}
return 0;
}
void CeDbMainWnd::OnSettingChange( WORD wFlag, LPCTSTR pszSection, bool& bHandled )
{
#if defined(_WIN32_WCE_POCKETPC)
s_sai.cbSize = sizeof s_sai;
SHHandleWMSettingChange(m_hWnd, wFlag, (long) pszSection, &s_sai);
bHandled = true;
#elif defined(_WIN32_WCE_PSPC)
switch (wFlag)
{
case SPI_SETSIPINFO:
{
SIPINFO si;
memset( &si, 0, sizeof( si ) );
si.cbSize = sizeof( si );
if( SHSipInfo( SPI_GETSIPINFO, 0, &si, 0 ) )
{
MoveWindow(
si.rcVisibleDesktop.left,
si.rcVisibleDesktop.top,
si.rcVisibleDesktop.right - si.rcVisibleDesktop.left,
si.rcVisibleDesktop.bottom -
si.rcVisibleDesktop.top,
TRUE );
}
}
break;
default:
break;
}
#endif // _WIN32_PPC_
}
TCHAR* g_szSmallTips[] =
{
NULL, // skipping menu
_T("Delete Datebase"),
_T("Delete Records"),
_T("About DbView"),
_T("Database Properties"),
};
TBBUTTON g_tb[] =
{
{0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0},
{0, IDM_DELDB, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0},
{0, IDM_DELRECORD, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0},
{0, IDM_ABOUT, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0},
{0, IDM_PROPERTIES, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0},
};
extern HINSTANCE g_hInst;
void CeDbMainWnd::CreateBars()
{
#if defined(_WIN32_WCE_POCKETPC)
#pragma comment(lib, "aygshell.lib")
HDC hDC = GetWindowDC();
int nBits = ::GetDeviceCaps(hDC, BITSPIXEL);
ReleaseDC(hDC);
SHMENUBARINFO mbi;
//set up menu bar structure
memset(&mbi, 0, sizeof(SHMENUBARINFO));
mbi.cbSize = sizeof(SHMENUBARINFO);
mbi.hwndParent = m_hWnd;
mbi.nToolBarId = IDR_MENU1;
mbi.hInstRes = g_hInst;
mbi.cBmpImages = 3;
//mbi.nBmpId = IDR_MENU1;
mbi.nBmpId = (nBits <= 2) ? IDR_MENU1_4: IDR_MENU1_16;
mbi.dwFlags = 0; //SHCMBF_EMPTYBAR;
if (!SHCreateMenuBar(&mbi))
{
DWORD dw = GetLastError();
MessageBox(_T("SHCreateMenuBar Failed"), _T("Error"), MB_OK|MB_ICONERROR);
}
//m_hwndCmdBar = mbi.hwndMB;
#elif defined(_WIN32_WCE)
m_cmdband.Create(m_hWnd, IDC_BAND, RBS_SMARTLABELS|RBS_VARHEIGHT|RBS_BANDBORDERS, NULL);
REBARBANDINFO rbbi;
memset(&rbbi, 0, sizeof rbbi);
// specific init
rbbi.cbSize = sizeof REBARBANDINFO;
rbbi.wID = IDC_BAND;
rbbi.fMask = RBBIM_ID|RBBIM_IMAGE|RBBIM_STYLE;
rbbi.fStyle = RBBS_NOGRIPPER;
rbbi.iImage = 0;
if (m_cmdband.AddBands(1, &rbbi))
{
// Add the menu bar first
m_cmdband.GetCommandBar(0).InsertMenubar(IDR_MENU1, 0);
int nStd = m_cmdband.GetCommandBar(0).AddStdBitmap(IDB_STD_SMALL_COLOR);
HDC hDC = GetWindowDC();
int nBits = ::GetDeviceCaps(hDC, BITSPIXEL);
int nLocal;
ReleaseDC(hDC);
if (nBits <= 2)
{
nLocal = m_cmdband.GetCommandBar(0).AddBitmap(IDB_DELDB4, 1, 16, 16);
m_cmdband.GetCommandBar(0).AddBitmap(IDB_DELRECORD4, 1, 16, 16);
m_cmdband.GetCommandBar(0).AddBitmap(IDB_HELP4, 1, 16, 16);
}
else
{
nLocal = m_cmdband.GetCommandBar(0).AddBitmap(IDB_DELDB16, 1, 16, 16);
m_cmdband.GetCommandBar(0).AddBitmap(IDB_DELRECORD16, 1, 16, 16);
m_cmdband.GetCommandBar(0).AddBitmap(IDB_HELP16, 1, 16, 16);
}
g_tb[0].iBitmap = 0;
g_tb[1].iBitmap = nLocal + 0;
g_tb[2].iBitmap = nLocal + 1;
g_tb[3].iBitmap = nLocal + 2;
g_tb[4].iBitmap = nStd + STD_PROPERTIES;
m_cmdband.GetCommandBar(0).AddButtons(sizeof(g_tb) / sizeof(TBBUTTON), g_tb);
// Add tooltips for the buttons we added
m_cmdband.GetCommandBar(0).AddToolTips(sizeof(g_szSmallTips)/sizeof(TCHAR*), (LPTSTR) g_szSmallTips);
}
#endif
}
BOOL CeDbMainWnd::OnCreate(LPCREATESTRUCT lpCS, bool& bHandled)
{
bHandled = true;
CreateBars();
CeRect rc;
GetClientRect(&rc);
#if defined(_WIN32_WCE)
if (m_cmdband)
rc.top += m_cmdband.Height();
#endif
CeRect rcTree, rcList;
GetWindowPlacements(rc, rcTree, rcList);
//
DWORD dwStyle = WS_VISIBLE|
WS_CHILD|
TVS_HASBUTTONS|
TVS_HASLINES|
TVS_LINESATROOT|
TVS_DISABLEDRAGDROP|
TVS_SHOWSELALWAYS;
m_hwndTree = CreateWindowEx(0 /*WS_EX_CLIENTEDGE*/,
WC_TREEVIEW, NULL, dwStyle,
rcTree.left, rcTree.top, rcTree.Width(), rcTree.Height(),
*this, (HMENU) IDC_TREE, CeGetAppInstance(), NULL);
HIMAGELIST hImages = ImageList_Create(16, 16, ILC_MASK, 1, 1);
HICON hSmallIcon = (HICON) LoadImage(CeGetAppInstance(),
MAKEINTRESOURCE(IDI_ICON1),
IMAGE_ICON, 16, 16, 0);
ImageList_AddIcon(hImages, hSmallIcon);
TreeView_SetImageList(m_hwndTree, hImages, TVSIL_NORMAL);
CreateList(rcList, false);
//
AddDatabases();
#if defined(_WIN32_WCE)
if (m_cmdband)
// Add Close button
m_cmdband.AddAdornments(0);
#endif
// Get the font back from the settings
CeRegKey key;
key.Create(HKEY_LOCAL_MACHINE, _T("Software\\Magenic\\DbView"));
LOGFONT lf;
DWORD dwByteCnt = sizeof(LOGFONT);
if (S_OK == key.QueryValue((BYTE*) &lf, _T("Font"), &dwByteCnt))
{
if (sizeof(LOGFONT) == dwByteCnt)
{
// create an initial font from the LOGFONT structure written
// out to the registry
HFONT hFont = ::CreateFontIndirect(&lf);
SetCtrlFont(hFont);
}
}
return TRUE;
}
void CeDbMainWnd::CreateList(CeRect& rcList, bool bOwnerData)
{
DWORD dwStyle = WS_VISIBLE|WS_CHILD | LVS_REPORT|LVS_SHOWSELALWAYS;
if (m_hwndList)
::DestroyWindow(m_hwndList);
if (bOwnerData)
// virtual listview...
dwStyle |= LVS_OWNERDATA;
m_hwndList = CreateWindowEx(0 /*WS_EX_CLIENTEDGE*/,
WC_LISTVIEW, NULL, dwStyle,
rcList.left, rcList.top, rcList.Width(), rcList.Height(),
*this, (HMENU) IDC_LIST, CeGetAppInstance(), NULL);
// Set the panes
SetPanes(m_hwndTree, m_hwndList);
ListView_SetExtendedListViewStyle(m_hwndList, LVS_EX_FULLROWSELECT);
::SendMessage(m_hwndList, WM_SETFONT, (WPARAM) m_hFont, TRUE);
}
void CeDbMainWnd::ReCreateList(bool bOwnerData)
{
ASSERT(m_hwndList != NULL);
CeRect rc;
::GetWindowRect(m_hwndList, &rc);
ScreenToClient(&rc);
bool bVirtual = (::GetWindowLong(m_hwndList, GWL_STYLE) & LVS_OWNERDATA) ? true: false;
if (bVirtual != bOwnerData)
CreateList(rc, bOwnerData);
}
bool CeDbMainWnd::AddDatabases()
{
CeDbEnum dbenum;
TVINSERTSTRUCT tvis;
::ZeroMemory(&tvis, sizeof tvis);
tvis.hParent = TVI_ROOT;
tvis.hInsertAfter = TVI_ROOT;
tvis.item.mask = TVIF_TEXT | TVIF_PARAM;
tvis.item.pszText = _T("Databases");
tvis.item.lParam = 0xffffffff;
tvis.item.cchTextMax = 9;
// call for refresh
TreeView_DeleteAllItems(m_hwndTree);
HTREEITEM hRoot = TreeView_InsertItem(m_hwndTree, &tvis);
CEOID oid = 0;
if (! dbenum.First())
return false;
while (dbenum.Next())
{
CeString str = dbenum.GetName();
tvis.hParent = hRoot;
tvis.hInsertAfter = 0;
tvis.item.mask = TVIF_CHILDREN | TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE;
tvis.item.pszText = (LPTSTR) (LPCTSTR) str;
tvis.item.cchTextMax = str.Length();
tvis.item.cChildren = 0;
tvis.item.iImage = 0;
tvis.item.lParam = dbenum.GetOid();
HTREEITEM hSelItem = TreeView_InsertItem(m_hwndTree, &tvis);
if (0 == oid)
{
// select the first database
oid = dbenum.GetOid();
TreeView_SelectItem(m_hwndTree, hSelItem);
ResetList();
}
}
// Add the records for the selected database
return true;
}
void CeDbMainWnd::ResetContent(CEOID oidDb, DWORD dwProp)
{
// reset the content of the list
ListView_SetItemCount(m_hwndList, 0);
if (oidDb == 0)
// reuse
oidDb = m_oidDb;
else if (0xffffffff != oidDb)
// new database
m_oidDb = oidDb;
else
// at the root
m_oidDb = 0xffffffff;
// close if open
m_db.Close();
if (m_oidDb != 0xffffffff)
{
ReCreateList(true);
CEOIDINFO oidInfo;
ZeroMemory(&oidInfo, sizeof oidInfo);
if (! ::CeOidGetInfo(oidDb, &oidInfo))
return;
CEPROPID prop = 0;
for (int ii = 0; ii < oidInfo.infDatabase.wNumSortOrder; ii++)
{
if (dwProp == oidInfo.infDatabase.rgSortSpecs[ii].propid)
{
prop = dwProp;
break;
}
}
m_nRecs = m_nCols = m_nFirst = 0;
if (! m_db.Open(oidDb, prop))
{
// print error
return;
}
// Set the count to actual
ListView_SetItemCount(m_hwndList, oidInfo.infDatabase.wNumRecords);
}
else
{
ReCreateList(false);
LV_COLUMN lvc;
lvc.mask = LVCF_TEXT;
lvc.pszText = _T("Name");
ListView_InsertColumn(m_hwndList, 0, &lvc);
lvc.pszText = _T("Records");
ListView_InsertColumn(m_hwndList, 1, &lvc);
lvc.pszText = _T("Sorts");
ListView_InsertColumn(m_hwndList, 2, &lvc);
lvc.pszText = _T("Size");
ListView_InsertColumn(m_hwndList, 3, &lvc);
CeDbEnum dbenum;
if (! dbenum.First())
return;
int ii = 0;
while (dbenum.Next())
{
LV_ITEM lvi;
lvi.mask = LVIF_TEXT;
lvi.pszText = (LPWSTR) dbenum.GetName();
lvi.iItem = ListView_GetItemCount(m_hwndList);
lvi.iSubItem = 0;
lvi.iItem = ListView_InsertItem(m_hwndList, &lvi);
if (dbenum.GetInfo())
{
CeString strTmp;
strTmp.SetULong(dbenum.GetNumRecords());
lvi.pszText = (LPWSTR) (LPCWSTR) strTmp;
lvi.iSubItem++;
ListView_SetItem(m_hwndList, &lvi);
strTmp.SetULong(dbenum.GetNumSorts());
lvi.pszText = (LPWSTR) (LPCWSTR) strTmp;
lvi.iSubItem++;
ListView_SetItem(m_hwndList, &lvi);
strTmp.SetULong(dbenum.GetSize());
lvi.pszText = (LPWSTR) (LPCWSTR) strTmp;
lvi.iSubItem++;
ListView_SetItem(m_hwndList, &lvi);
}
}
ListView_SetColumnWidth(m_hwndList, 0, LVSCW_AUTOSIZE_USEHEADER);
ListView_SetColumnWidth(m_hwndList, 1, LVSCW_AUTOSIZE_USEHEADER);
ListView_SetColumnWidth(m_hwndList, 2, LVSCW_AUTOSIZE_USEHEADER);
ListView_SetColumnWidth(m_hwndList, 3, LVSCW_AUTOSIZE_USEHEADER);
ListView_SetColumnWidth(m_hwndList, 4, LVSCW_AUTOSIZE_USEHEADER);
}
}
void CeDbMainWnd::ResetList()
{
CeWaitCursor wait;
// clean up the column map
m_mapColumn.RemoveAll();
::SendMessage(m_hwndList, WM_SETREDRAW, FALSE, 0);
// remove all the columns
while (ListView_DeleteColumn(m_hwndList, 0))
;
// get the CEOID of the database selected (lParam)
// of the treeview
HTREEITEM hItem = TreeView_GetSelection(m_hwndTree);
TVITEM tvi;
tvi.mask = TVIF_HANDLE;
tvi.hItem = hItem;
TreeView_GetItem(m_hwndTree, &tvi);
CEOID oidDb = tvi.lParam;
::SendMessage(m_hwndList, WM_SETREDRAW, TRUE, 0);
ResetContent(oidDb, 0);
}
bool CeDbMainWnd::DeleteRecord(int nRecord)
{
if (nRecord < m_nFirst || m_nFirst + m_nRecs <= nRecord)
// not available in the cache
return false;
memmove(&m_records[nRecord], &m_records[nRecord+1], (m_nRecs-(nRecord+1))*sizeof(m_records[0]));
memmove(&m_oids[nRecord], &m_oids[nRecord+1], (m_nRecs-(nRecord+1))*sizeof(m_oids[0]));
m_nRecs--;
return true;
}
//
// Cache records for later data retreival, additionally add the columns
// that are required for the data read in if they haven't been yet
//
bool CeDbMainWnd::CacheRecords(int nStart, int nRecords)
{
if (nStart >= m_nFirst && m_nFirst + m_nRecs >= nStart + nRecords)
// already available in the cache
return true;
if (MAX_RECS < nRecords)
return false;
TRACE2(_T("Start: %d, nRecords: %d\n"), nStart, nRecords);
// Set the Wait cursor
// HCURSOR hCursor = ::SetCursor(::LoadCursor(NULL, IDC_WAIT));
// Add the column value and row
if (! m_db.IsOpen())
return false;
// quick hack, should change
m_nFirst = nStart;
m_nRecs = nRecords;
CEOID oidRec = m_db.SeekBegin(nStart);
for (int nRow = 0; 0 != oidRec && nRow < nRecords; oidRec = m_db.SeekNext(), nRow++)
{
if (!m_db.ReadRec(m_records[nRow]))
continue;
m_oids[nRow] = oidRec;
for (int ii = 0; ii < m_records[nRow].m_wProps; ii++)
{
DWORD dwProp = m_records[nRow].m_pProps[ii].propid;
int nCol = m_mapColumn.FindKey(dwProp);
CeString str;
if (nCol < 0)
{
// Setup a new property column
nCol = m_nCols++;
m_mapColumn.Add(dwProp, nCol);
LVCOLUMN col;
col.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
switch ( TypeFromPropID(dwProp) )
{
case CEVT_I2:
col.pszText = _T("Short");
col.fmt = LVCFMT_RIGHT;
break;
case CEVT_UI2:
col.pszText = _T("UShort");
col.fmt = LVCFMT_RIGHT;
break;
case CEVT_I4:
col.pszText = _T("Int");
col.fmt = LVCFMT_RIGHT;
break;
case CEVT_UI4:
col.pszText = _T("UInt");
col.fmt = LVCFMT_RIGHT;
break;
case CEVT_FILETIME:
col.pszText = _T("FileTime");
col.fmt = LVCFMT_LEFT;
break;
case CEVT_LPWSTR:
col.pszText = _T("String");
col.fmt = LVCFMT_LEFT;
break;
case CEVT_BLOB:
col.pszText = _T("Blob");
col.fmt = LVCFMT_LEFT;
break;
}
str.Format(_T("0x%04hx (%s)"), HIWORD(dwProp), col.pszText);
col.pszText = (LPTSTR) (LPCTSTR) str;
col.cx = 80;
ListView_InsertColumn(m_hwndList, nCol, &col);
}
}
}
return true;
}
void CeDbMainWnd::OnDeleteDb()
{
// get the CEOID of the database selected (lParam)
TCHAR szBuf[CEDB_MAXDBASENAMELEN];
HTREEITEM hItem = TreeView_GetSelection(m_hwndTree);
TVITEM tvi;
tvi.mask = TVIF_HANDLE|TVIF_TEXT;
tvi.hItem = hItem;
tvi.pszText = szBuf;
tvi.cchTextMax = CEDB_MAXDBASENAMELEN;
TreeView_GetItem(m_hwndTree, &tvi);
CEOID oidDb = tvi.lParam;
if (0 == oidDb)
return;
CeString str;
str.Format(_T("Delete Database %s?"), tvi.pszText);
int nRet = MessageBox(str, _T("Delete Database"),
MB_OKCANCEL|MB_ICONWARNING);
if (IDOK != nRet)
return;
// close our active database
m_db.Close();
if (! ::CeDeleteDatabase(oidDb))
{
str.FormatMessage(GetLastError());
MessageBox(str, _T("Delete Failed"), MB_OK|MB_ICONWARNING);
}
else
{
TreeView_DeleteItem(m_hwndTree, hItem);
// force update of the newly selected database
ResetList();
}
}
CEOID CeDbMainWnd::GetListOid(int nSel)
{
int nRow = nSel - m_nFirst;
if (m_nRecs <= 0 || nRow < 0 || nRow >= m_nRecs)
return 0;
return m_oids[nRow];
}
void CeDbMainWnd::OnDeleteRecord()
{
// get the CEOID of the database selected (lParam)
HTREEITEM hItem = TreeView_GetSelection(m_hwndTree);
TVITEM tvi;
tvi.mask = TVIF_HANDLE;
tvi.hItem = hItem;
TreeView_GetItem(m_hwndTree, &tvi);
CEOID oidDb = tvi.lParam;
if (0 == oidDb || 0xffffffff == oidDb)
return;
// get the selected item
int nSel = ListView_GetNextItem(m_hwndList, -1, LVNI_SELECTED);
if (-1 == nSel)
{
//MessageBox(_T("There are no records to delete."), _T("Delete"),
// MB_OK|MB_ICONINFORMATION);
return;
}
int nRet = MessageBox(_T("Delete ALL selected records?"),
_T("Delete"), MB_YESNO|MB_ICONWARNING);
if (IDYES != nRet)
return;
for (int ii = 0; (-1 != nSel) && (ii < 40); ii++)
{
CEOID oid = GetListOid(nSel);
TRACE0("Deleting record...\n");
if (! m_db.DeleteRecord(oid))
{
CeString str;
str.FormatMessage(GetLastError());
MessageBox(str, _T("Delete Failed"), MB_OK|MB_ICONWARNING);
break;
}
nSel = ListView_GetNextItem(m_hwndList, nSel, LVNI_SELECTED);
}
ResetList();
}
void CeDbMainWnd::OnRefresh()
{
AddDatabases();
}
void CeDbMainWnd::OnOptions()
{
LOGFONT logfont;
if (NULL == m_hFont)
{
m_nFontSize = 9;
GetObject(GetStockObject(SYSTEM_FONT), sizeof LOGFONT, &logfont);
}
else
{
GetObject(m_hFont, sizeof LOGFONT, &logfont);
}
CeFontDlg dlg(m_nFontSize, &logfont);
if (IDOK == dlg.DoModal(IDD_FONTDLG, *this))
{
SetCtrlFont(dlg.m_hFont);
m_nFontSize = dlg.m_nPointSize;
}
}
void CeDbMainWnd::SetCtrlFont(HFONT hFont)
{
if (m_hFont)
::DeleteObject(m_hFont);
if (NULL == hFont)
{
m_hFont = NULL;
return;
}
LOGFONT logfont;
GetObject(hFont, sizeof logfont, &logfont);
m_hFont = ::CreateFontIndirect(&logfont);
::SendMessage(m_hwndTree, WM_SETFONT, (WPARAM) m_hFont, TRUE);
::SendMessage(m_hwndList, WM_SETFONT, (WPARAM) m_hFont, TRUE);
}
void CeDbMainWnd::OnAbout()
{
CeAboutDlg dlg;
dlg.DoModal(IDD_ABOUT, *this);
}
void CeDbMainWnd::OnProperties()
{
// get the CEOID of the database selected (lParam)
CeString strDb;
HTREEITEM hItem = TreeView_GetSelection(m_hwndTree);
TVITEM tvi;
tvi.mask = TVIF_HANDLE | TVIF_PARAM;
tvi.hItem = hItem;
TreeView_GetItem(m_hwndTree, &tvi);
CEOID oidDb = tvi.lParam;
if (0 == oidDb || 0xffffffff == oidDb)
return;
CePropDlg dlg;
dlg.m_oidDb = oidDb;
if (GetSystemMetrics(SM_CXSCREEN) >= GetSystemMetrics(SM_CYSCREEN))
// HPC
dlg.DoModal(IDD_DBPROPHPC, *this);
else
// PPC
dlg.DoModal(IDD_DBPROPPPC, *this);
}
void CeDbMainWnd::OnDestroy(bool& bHandled)
{
if (NULL != m_hFont)
{
CeRegKey key;
key.Create(HKEY_LOCAL_MACHINE, _T("Software\\Magenic\\DbView"));
LOGFONT lf;
::GetObject((HGDIOBJ) m_hFont, sizeof LOGFONT, &lf);
DWORD dwByteCnt = sizeof(LOGFONT);
key.SetValue((BYTE*) &lf, sizeof LOGFONT, _T("Font"));
}
bHandled = true;
PostQuitMessage(0);
}
void CeDbMainWnd::OnClose(bool& bHandled)
{
bHandled = true;
DestroyWindow();
}
LRESULT CeDbMainWnd::OnMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, bool& bHandled)
{
switch (uMsg)
{
case WM_HELP:
{
// PROCESS_INFORMATION pi;
// ::CreateProcess(_T("peghelp.exe"), _T("file:BeamEx.htc"),
// NULL, NULL, FALSE, 0, NULL, NULL, NULL, &pi);
// CloseHandle(pi.hProcess);
// CloseHandle(pi.hThread);
}
break;
}
return 1;
}
LRESULT CeDbMainWnd::OnNotify(int nCtrlId, LPNMHDR pNMH, bool& bHandled)
{
bHandled = false;
if (IDC_TREE == nCtrlId)
{
LPNMTREEVIEW pnmtv;
switch (pNMH->code)
{
case TVN_SELCHANGED:
pnmtv = (LPNMTREEVIEW) pNMH;
if (pnmtv->action == TVC_BYKEYBOARD || pnmtv->action == TVC_BYMOUSE)
ResetList();
break;
}
}
else if (IDC_LIST == nCtrlId)
{
bHandled = true;
switch (pNMH->code)
{
case LVN_COLUMNCLICK:
OnColumnClick((NMLISTVIEW *) pNMH);
break;
case LVN_GETDISPINFO:
return OnDispInfo((NMLVDISPINFO *) pNMH);
case LVN_ODCACHEHINT:
return OnCacheHint((NMLVCACHEHINT *) pNMH);
case LVN_ODFINDITEM:
return OnFindItem((NMLVFINDITEM *) pNMH);
}
}
return 0;
}
void CeDbMainWnd::OnColumnClick(NMLISTVIEW *pLV)
{
// ASSERT(pLV->iItem == -1);
if (m_oidDb != 0xffffffff)
{
// sort on column, but not when at the root
DWORD dwProp = m_mapColumn.ReverseLookup((WORD) pLV->iSubItem);
ResetContent(0, dwProp);
}
}
LRESULT CeDbMainWnd::OnDispInfo(NMLVDISPINFO* pDI)
{
// typedef struct tagLVDISPINFO
// {
// NMHDR hdr;
// LVITEM item;
// };
int nRow = pDI->item.iItem - m_nFirst;
if (m_nRecs <= 0 || nRow < 0 || nRow >= m_nRecs)
return 0;
CeString str;
// get the column we need data about
WORD wCol = pDI->item.iSubItem;
if (0 == wCol)
TRACE(_T("OnDispInfo: %d\n"), pDI->item.iItem);
if (pDI->item.mask & LVIF_TEXT)
{
DWORD dwProp;
int nCol = m_mapColumn.FindVal(wCol);
if (nCol != -1)
{
dwProp = m_mapColumn.GetKeyAt(nCol);
m_records[nRow].GetIdVal(HIWORD(dwProp), str);
_tcsncpy(pDI->item.pszText, str, pDI->item.cchTextMax);
}
else
*pDI->item.pszText = 0;
}
if (pDI->item.mask & LVIF_PARAM)
// doesn't get sent
pDI->item.lParam = m_oids[nRow];
if (pDI->item.mask & (LVIF_IMAGE|LVIF_STATE))
{
pDI->item.iImage = 0;
pDI->item.state = 0;
}
return 0;
}
LRESULT CeDbMainWnd::OnCacheHint(NMLVCACHEHINT * pCacheHint)
{
// typedef struct tagNMLVCACHEHINT
// {
// NMHDR hdr;
// int iFrom;
// int iTo;
// };
CacheRecords(pCacheHint->iFrom, pCacheHint->iTo - pCacheHint->iFrom + 1);
return 0;
}
LRESULT CeDbMainWnd::OnFindItem(NMLVFINDITEM * pFindItem)
{
// typedef struct tagLVFINDINFO
// {
// UINT flags;
// LPCTSTR psz;
// LPARAM lParam;
// POINT pt;
// UINT vkDirection;
// };
return -1; // nothing found
}