Category : C++ Source Code
Archive   : PXEWIN.ZIP
Filename : DBDISPLY.CPP

 
Output of file : DBDISPLY.CPP contained in archive : PXEWIN.ZIP
// PXEWIN - (C) Copyright 1992 by Beam Engineering, INC.

// DBDISPLY_CPP //

// Contents ----------------------------------------------------------------
//
// This header contains members for the DBDISPLAY class.
//
// End ---------------------------------------------------------------------

// External Reference Name For This Header ---------------------------------

#ifndef DBDISPLY_CPP
#define DBDISPLY_CPP

// End ---------------------------------------------------------------------

// Interface Dependencies --------------------------------------------------

#ifndef DBDISPLY_HPP
#include "dbdisply.hpp"
#endif // DBDISPLY_HPP //

#ifndef PXLISTBX_CPP
#include "pxlistbx.cpp"
#endif // PXLISTBX_CPP //

#ifndef BROWSE_HPP
#include "browse.hpp"
#endif // BROWSE_HPP //

// End ---------------------------------------------------------------------

// constructor DBDISPLAY //

inline DBDISPLAY::DBDISPLAY()
{
my_parm = NULL;
UpdateFlag = 1;

// Set your engine object pointer to this

EngDataPtr->PXEObjPtr = this;
top_rec = 1;
item = 0;
field = 0;
}

// Description -------------------------------------------------------------
//
// Constructor for DBDISPLAY. Set my_parm to NULL, UpdateFlag for
// display updates, set the EngDataPtr to this object since it will
// be the parent object, top_rec to first record, item to first item
// in the list box. field is the first field in the record.
//
// End ---------------------------------------------------------------------

// member build of DBDISPLAY //

PTStreamable DBDISPLAY::build()
{
return new DBDISPLAY(streamableInit);
}

TStreamableClass RegDBDISPLAY("DBDISPLAY",DBDISPLAY::build,
__DELTA(DBDISPLAY));

// Description -------------------------------------------------------------
//
// When the streamable constructor is called, TStreamable dispatches
// the build member to construct the object. To do this, it must
// know where to find this member functions for the specific class.

// This is the reason for the stream registration.
//
// End ---------------------------------------------------------------------

// member read of DBDISPLAY //

inline Pvoid DBDISPLAY::read(Ripstream is)
{
PXDIS::read(is);
my_parm = NULL;
UpdateFlag = 1;

// Set your engine object pointer to this

EngDataPtr->PXEObjPtr = this;
is >> (RECORDNUMBER)top_rec >> item;
return this;
}

// Summary -----------------------------------------------------------------
//
// Read this object off the stream.
//
// Parameters
//
// is. The incomming stream.
//
// Return Value
//
// Returns this objects pointer.
//
// Functional Description
//
// 1. Call base class reader.
// 2. Intialize as you would in the constructor.
// 3. Get the top_rec and item off the stream.
//
// End ---------------------------------------------------------------------

// member write of DBDISPLAY //

inline void DBDISPLAY::write(Ropstream os)
{
PXDIS::write(os);
os << (RECORDNUMBER)top_rec << item;
}

// Summary -----------------------------------------------------------------
//
// Write top_rec and item to the stream.
//
// End ---------------------------------------------------------------------

// member FillBoxes //

void DBDISPLAY::FillBoxes(RECORDNUMBER rec)
{
int i; /* Field index */
int j; /* Record index */
int sel; /* Temperary item selection
variable */
int upper_limit; /* Number of records to
get */
Pchar temp;

// Set mouse cursor to wait

SendMessage(AP->Parent->HWindow,WM_SETWTCUR,0,0);

// Reset update flag

UpdateFlag = 0;

// Check and see if record number is less than first record.

if(rec < 1)
rec = 1;

// Get the number of records in the table.

my_table->NumRecs();

// If you have less records then a PAGE_SIZE, then set your first
// record of the page to the first record in the database. Set the
// upper limit of the last record you will get to the number of
// records in the database.

if(EngDataPtr->num_recs < PAGE_SIZE)
{
upper_limit = EngDataPtr->num_recs;
top_rec = 1;
}
else
{

// Else, set the upper limit to the page size.

upper_limit = PAGE_SIZE;

// If you are less than a page size away from the end of the
// database, set the top record to the number of records in
// the database minus the size of the page.

if(rec + PAGE_SIZE > EngDataPtr->num_recs){
top_rec = EngDataPtr->num_recs - PAGE_SIZE + 1;
sel = rec - top_rec;
}
else
{

// Else, leave the top record value at the parameter
// setting.

top_rec = rec;
sel = item;
}
}

// Empty the list boxes.

for(i = 0;i < EngDataPtr->num_fields;i++)
my_parm[i]->my_box->ClearList();

my_record->GoTo(top_rec);
for(j = 0;j < upper_limit;j++)
{

// Get the record data into the record transfer buffer.

my_record->Get();
for(i = 0;i < EngDataPtr->num_fields;i++)
{

// Get the field data and put in into the list box.


temp = PXDIS::Get(i);
my_parm[i]->my_box->AddString(temp);
}

// Go to the next record.

my_record->RecNext();
}

// Set item out of bounds so it will pass through range check ok

item = -1;

// Set update flag

UpdateFlag = 1;

// Select the item

SelRecord(sel);

// Set mouse cursor to normal

SendMessage(AP->Parent->HWindow,WM_SETNMCUR,0,0);
}

// Summary -----------------------------------------------------------------
//
// This member fills the list boxes with data from the database.
//
// Parameters
//
// rec. This is the record number of the top record in the list boxes.
//
// Return Value
//
// None.
//
// Functional Description
//
// 1. Set the mouse cursor to the wait cursor.
//
// 2. Reset the UpdateFlag so updates will not occur until the list
// boxes are refilled. This flag will be read by the PXListBox
// routine to make sure Updates as they would normally when WMPaint is
// called (TControl version of WMPaint).
//
// 3. Range check rec. If it is less than the first record, reset it
// to the first record. For a table that is less the a PAGE_SIZE, limit
// the upperbound accordingly. Else the upperbound is the PAGE_SIZE.
// If rec plus PAGE_SIZE is greater than the number of records then set
// top_rec to PAGE_SIZE less than the number of records and your
// selection is somewhere in between. Else leave rec untouched and
// set you selection to the top record.
//
// 4. Empty the list boxes.
//
// 5. Fill the list boxes.
//
// 6. You need to set the item number out of bounds so the selection
// routine sees that the selection has changed.
//
// 7. Set the UpdateFlag to allow updates and call the selection
// routine.
//
// 8. Set the mouse cursor to normal.
//
// End ---------------------------------------------------------------------

// member SetUp //

int DBDISPLAY::SetUp(PBrowser AParent)
{
Pchar header; /* Temp location for header
*/
int hd_len; /* Length of header */
int char_size; /* Is the number of ASCII
characters it takes to
represent the field. */
int i; /* Field index */
HDC hdc; /* Window device context */
char szFaceName[LF_FACESIZE]; /* Recieves current fonts
name */
TEXTMETRIC tm; /* Data structure for font
info. */

EngDataPtr->name = AParent->name;
AP = AParent;
sum = 1;

// Get a context handle in the current window.

hdc = GetDC(AParent->HWindow);

// This will get the name of the type face into the face name array

GetTextFace(hdc,sizeof(szFaceName),szFaceName);

// Load the data structure with the font info.

GetTextMetrics(hdc,&tm);

// We will set the character width to the maximum size just to
// be on the safe side.

char_width = tm.tmMaxCharWidth;

// Release the handle so you don't run out of handles.

ReleaseDC(AParent->HWindow,hdc);

// Setup database

PXDIS::SetUp(0,0,EXISTS,0);
if(EngDataPtr->Errors.pxerr != PXSUCCESS)
return EngDataPtr->Errors.pxerr;

// Make an array of field parameter pointers

my_parm = new PLB_PARM [EngDataPtr->num_fields];

for(i = 0;i < EngDataPtr->num_fields;i++){
my_parm[i] = new LB_PARM;

// Set up a field pointer

my_parm[i]->my_field = my_field[i];

// If parameter set is the first set, initialize x
// coordinate of the list box independently.

if(i == 0)
my_parm[i]->x = 2;
else{

// Else, the list box coordinate depends on
// where the previous list box ends.

my_parm[i]->x = my_parm[i - 1]->x +
my_parm[i - 1]->w + 2;
}

// Precalc some things we will be using more than once.

header = my_parm[i]->my_field->RetName();
hd_len = strlen(header);
char_size = my_parm[i]->my_field->RetCharSize();

// The width of the list box is calculated. It is
// the character size of the field times the
// character width unless the field header is larger.

if(char_size > hd_len){
my_parm[i]->w = char_size*char_width;
sum += char_size;
}
else{
my_parm[i]->w = hd_len*char_width;
sum += hd_len;
}

// Set up the list box.

my_parm[i]->my_box = new PXListBox(AParent,i,
my_parm[i]->x,20,my_parm[i]->w,16.5*PAGE_SIZE);

// Set up header for your list boxes

my_parm[i]->my_header = new TStatic(AParent,-1,
header,my_parm[i]->x,1,200,15,hd_len + 1);

}
return PXSUCCESS;
}

// Summary -----------------------------------------------------------------
//
// This sets up the database for displaying all the fields.
//
// Parameters
//
// AParent. Needs the parent window object to construct the list boxes
// and the field headers.
//
// Functional Description
//
// 1. Call the SetUp routine for setting up the database.
//
// 2. Construct a parameter array for storing list box info.
//
// 3. Construct a for loop that will initialize all the fields for
// display. The information necessary for storing the list box data is
// saved in the LB_PARM structure. Placement locations and sizes of
// each list box are calculated. Headers for each field are placed
// at the top of the list box.
//
// End ---------------------------------------------------------------------

// Destructor ~DBDISPLAY //

DBDISPLAY::~DBDISPLAY()
{
int i; /* Field index */

// if ther is no parameter pointer, then the number of fields is
// unknown so set to zero.

if(!my_parm)
EngDataPtr->num_fields = 0;
for(i = 0;i < EngDataPtr->num_fields;i++)
delete my_parm[i];
delete my_parm;
}

// End ---------------------------------------------------------------------

// Summary -----------------------------------------------------------------
//
// Kills all buffers used in DBDISPLAY.
//
// End ---------------------------------------------------------------------

// member SelRecord //

void DBDISPLAY::SelRecord(int ITEM)
{
int i; /* Field index */

// Range check item

if(ITEM >= PAGE_SIZE)
ITEM = PAGE_SIZE - 1;
if(ITEM < 0)
ITEM = 0;
if(item == ITEM)
{
if(item == 0)
ScrollDwn();
else{
if(item == PAGE_SIZE - 1)
ScrollUp();
}
}

// Select items if you are somewhere within a page or your have
// incremented past the page but you are not at the last record.
// For a decrement before the page you don't need to select since
// you are doing and insert at the first record.

if((item == PAGE_SIZE - 1) || item != ITEM)
{
for(i = 0;i < EngDataPtr->num_fields;i++)
{
my_parm[i]->my_box->SetSelIndex(ITEM);
}
}
item = ITEM;
}

// Summary -----------------------------------------------------------------
//
// Selects the record cooresponding to the item number in the list boxes
//
// Parameters
//
// item. This is the list box item number.
//
// Return Value
//
// None.
//
// Description
//
// 1. The item number is range checked. If the item number is greater
// then the page size then it is set to the page size. If the item
// number is less than the first item number, it is set to the first
// item.
//
// 2. If the old item number is equal to the new item number then check
// for a scroll up or down situation. It is scroll up if item is the
// first item, scroll down if item is the last item in the list box.
//
// 3. If item selected is at the end of the list or somewhere in
// the middle of the list, then set all the lists to the same item.
//
// End ---------------------------------------------------------------------

// member IncRec of DBDISPLAY //

void DBDISPLAY::IncRec()
{
SelRecord(item + 1);
}

// Summary -----------------------------------------------------------------
//
// Increments an item in the list boxes.
//
// End ---------------------------------------------------------------------

// member DecRec of DBDISPLAY //

void DBDISPLAY::DecRec()
{
SelRecord(item - 1);
}

// Summary -----------------------------------------------------------------
//
// Decrements an item in the list boxes.
//
// End ---------------------------------------------------------------------


// member ScrollUp //

void DBDISPLAY::ScrollUp()
{
int i; /* Field index */

// Make sure your not already at the last record in the table.
// Note that we specifically call for the number of records since
// this may change as we add and delete records from the database.

my_table->NumRecs();
if(top_rec + PAGE_SIZE <= EngDataPtr->num_recs){

// Go to the new record and get data

my_record->GoTo(top_rec + PAGE_SIZE);
my_record->Get();

for(i = 0;i < EngDataPtr->num_fields;i++)
{
// Delete the first item in the list

my_parm[i]->my_box->DeleteString(0);

// Add the new next item to the list

my_parm[i]->my_box->AddString(PXDIS::Get(i));
}
top_rec++;
}
}

// Summary -----------------------------------------------------------------
//
// This scrolls the display up by one record.
//
// Parameters
//
// None.
//
// Return Value
//
// None.
//
// Description
//
// 1. Do a boundary check and make sure your not at the last record.
//
// 2. Go to the last record in the list and get the data.
//
// 3. For all the lists, delete the first item in the list and add the
// new data to the end of the list.
//
// 4. Increment the top record pointer.
//
// End ---------------------------------------------------------------------

// member ScrollDwn //

void DBDISPLAY::ScrollDwn()
{
int i; /* Field index */

// Make sure your not already at the first record in the table

if(top_rec > 1){

// Go to the new record and get data

top_rec--;
my_record->GoTo(top_rec);
my_record->Get();

for(i = 0;i < EngDataPtr->num_fields;i++)
{
// Delete the last item in the list

my_parm[i]->my_box->DeleteString(PAGE_SIZE - 1);

// Add the new text item to the begining of the list

my_parm[i]->my_box->InsertString(PXDIS::Get(i),0);
}
}
}

// Summary -----------------------------------------------------------------
//
// Scrolls the display down one record.
//
// Parameters
//
// None.
//
// Return Value
//
// None.
//
// Description
//
// 1. Make sure you are not at the first record in the database.
//
// 2. Decrement the top record pointer.
//
// 3. Go to the top record and get the data.
//
// 4. For all the fields, delete the last string in the list and insert
// the new data at the first string position in the list.
//
// End ---------------------------------------------------------------------

// member PXError of DBDISPLAY //

inline void DBDISPLAY::PXError(int org)
{
// Call base class error handler.

PXEngObject::PXError(org);

// Send the PX Engine error message back to the parent window

if(EngDataPtr->Errors.pxerr != PXSUCCESS)
{
// Because you may have the display update flag reset so
// that no updates can occur while the list boxes are being
// updated, you should make sure it's set before you dispatch
// the message or Windows will eventually crash because of
// the inability to process message traffic!!!!

UpdateFlag = 1;

SendMessage(AP->Parent->HWindow,WM_PXERROR,0,0);
}
}

// Summary -----------------------------------------------------------------
//
// If you get an error, send a message back to the parent window. This
// will dispatch all PDOX errors back to the parent window.
//
// End ---------------------------------------------------------------------

#endif // DBDISPLY_CPP //

  3 Responses to “Category : C++ Source Code
Archive   : PXEWIN.ZIP
Filename : DBDISPLY.CPP

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/