Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

A comprehensive CE class library to replace ATL and MFC

, 4 Oct 2000
A collection of classes for CE that do not use ATL or MFC, plus an FTP client, database viewer, and sample application that solves beam deflection equations.
kgwince-old.zip
WinCe
BeamEx
app.ico
BeamEx.dsp
BeamEx.dsw
BeamEx.ini
BeamEx.plg
bitmap1.bmp
bmp00001.bmp
bmp00002.bmp
calc.bmp
calc16.bmp
circ_cross.ico
cir_cross.ico
cross_4.ico
help16.bmp
help4.bmp
ico00001.ico
ico00002.ico
ico00005.ico
ico00008.ico
ico00009.ico
ico00010.ico
icon1.ico
icon2.ico
icon4.ico
id_downl.bmp
Install
BeamEx.inf
BeamEx.ini
BeamEx.MIPS_PPCBW.CAB
BeamEx.MIPS_PPCColor.CAB
BeamEx.SH3_PPCColor.CAB
Setup.exe
i_cross.ico
l_cross.ico
magenic.ico
mssccprj.scc
obl_corss.ico
obl_cross.ico
options.bmp
options1.bmp
ping16.bmp
rect_cross.ico
scene_5.ico
scene_6.ico
tri_cross.ico
vssver.scc
CeLib
CeLabel.inl
CeLib.aps
CeLib.dsp
CeLib.dsw
CeLib.old
CeLib.plg
CeLib.vcp
CeMisc.inl
CeProperty.inl
CeTab.inl
CeWnd.inl
mssccprj.scc
vssver.scc
WinLib.dsp
WinLib.dsw
dbView
bitmap1.bmp
bmp00001.bmp
db5.bmp
dbView.aps
DbView.dsp
dbView.dsw
dbView.old
dbView.plg
DbView.vcp
deldb.bp2
deldb5.bmp
delrec.bp2
delrecor.bmp
help16.bmp
help4.bmp
icon1.ico
icon2.ico
Install
dbView.inf
dbView.ini
Setup.exe
magenic.bmp
magenic.ico
mssccprj.scc
vssver.scc
ftpView
appicon.ico
bitmap1.bmp
bitmap2.bmp
bitmap3.bmp
bitmap4.bmp
bmp00001.bmp
bmp00002.bmp
db5.bmp
deldb.bp2
delrec.bp2
FtpView.dsp
ftpView.dsw
FtpView.old
ftpView.plg
FtpView.vcl
FtpView.vcp
help16.bmp
help4.bmp
ico00001.ico
ico00002.ico
ico171.ico
ico35.ico
icon1.ico
icon2.ico
imagelis.bmp
IMAGES.bmp
Install
ftpView.inf
ftpView.ini
Setup.exe
vssver.scc
magenic.bmp
magenic.ico
mssccprj.scc
options.bmp
options1.bmp
seperato.bmp
vssver.scc
Setup
ico101.ico
Setup.aps
Setup.dsp
setup.ico
Setup.plg
WinCe.dsw
WinLib.dsw
kgwince.zip
app.ico
BeamEx.dsp
BeamEx.dsw
BeamEx.ini
BeamEx.plg
BeamEx.vcl
BeamEx.vcp
bitmap1.bmp
bmp00001.bmp
bmp00002.bmp
calc.bmp
calc16.bmp
circ_cross.ico
cir_cross.ico
cross_4.ico
help16.bmp
help4.bmp
ico00001.ico
ico00002.ico
ico00005.ico
ico00008.ico
ico00009.ico
ico00010.ico
icon1.ico
icon2.ico
icon4.ico
id_downl.bmp
BeamEx.inf
BeamEx.ini
Setup.exe
i_cross.ico
l_cross.ico
magenic.ico
mssccprj.scc
obl_corss.ico
obl_cross.ico
options.bmp
options1.bmp
ping16.bmp
rect_cross.ico
scene_5.ico
scene_6.ico
tri_cross.ico
vssver.scc
CeFtp.vcp
CeFtp.vcw
CeLabel.inl
CeLib.aps
CeLib.dsp
CeLib.dsw
CeLib.plg
CeLib.vcl
CeLib.vcp
CeMisc.inl
CeProperty.inl
CeTab.inl
CeWnd.inl
mssccprj.scc
vssver.scc
WinLib.dsp
WinLib.dsw
bitmap1.bmp
bitmap2.bmp
bmp00001.bmp
db5.bmp
DbView.dsp
dbView.dsw
dbView.plg
DbView.vcl
DbView.vcp
deldb.bp2
deldb5.bmp
delrec.bp2
delrecor.bmp
help16.bmp
help4.bmp
icon1.ico
icon2.ico
dbView.inf
dbView.ini
Setup.exe
magenic.bmp
magenic.ico
menu1_5.bmp
mssccprj.scc
vssver.scc
appicon.ico
bitmap1.bmp
bitmap2.bmp
bitmap3.bmp
bitmap4.bmp
bmp00001.bmp
bmp00002.bmp
db5.bmp
deldb.bp2
delrec.bp2
FtpView.dsp
ftpView.dsw
ftpView.plg
FtpView.vcl
FtpView.vcp
FtpView.vcw
help16.bmp
help4.bmp
ico00001.ico
ico00002.ico
ico171.ico
ico35.ico
icon1.ico
icon2.ico
imagelis.bmp
IMAGES.bmp
ftpView.inf
ftpView.ini
Setup.exe
vssver.scc
magenic.bmp
magenic.ico
mssccprj.scc
newmenu.bmp
options.bmp
options1.bmp
rcdata1.bin
seperato.bmp
toolbar1.bmp
vssver.scc
WinCe.dsw
WinCe.vcw
#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
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Kenny G

United States United States
No Biography provided

| Advertise | Privacy | Mobile
Web01 | 2.8.140814.1 | Last Updated 5 Oct 2000
Article Copyright 2000 by Kenny G
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid