home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
ool.zip
/
OOL
/
source
/
xcontain.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1997-04-04
|
23KB
|
587 lines
#include "XContain.h"
#include "XContInf.h"
#include "XContObj.h"
#include "XControl.h"
#include "XString.h"
#include "XMsgBox.h"
#include "XContCol.h"
#include <string.h>
#include <stdlib.h>
/*@
@class XContainerControl
@parent XControl
@type overview
@symbol _
@remarks XContainerControl represents a container with multiple views like tree-, list- or icon view for a large amount of objects.
*/
/*@ XContainerControl :: SetObjectEmphasis( const XContainerObject * obj, const SHORT emph, const BOOL enableEmph)
@group object settings
@remarks Sets the emphasis of an object so displaying the objects icon is changed
@parameters <t '°' c=2>
°XContainerObject * theObject °object to change
°SHORT emphasis °the needed emphasis, valid values are:
<t '°' c=2>
°CON_CURSORED °the object is cursored
°CON_DISABLED °the object is disabled
°CON_INUSE °the objects icon is displayed open
°CON_PICKED °the objects icon is displayed dragged
°CON_SELECTED °the object is selected
°CON_SOURCE °the object get source-emphasis
</t>
(can be or-ed)
°BOOL enable °enable/disable emphasis
</t>
*/
void XContainerControl::SetObjectEmphasis(const XContainerObject * obj, const SHORT emph, const BOOL enableEmph) const
{
WinSendMsg(winhandle, CM_SETRECORDEMPHASIS, MPFROMP(obj->core), MPFROM2SHORT(enableEmph, emph));
}
/*@ XContainerControl :: ExpandTreeObject( const XContainerObject * obj, const BOOL expand)
@group expanding
@remarks Expands/collaps an object in tree-view.
@parameters <t '°' c=2>
°XContainerObject * obj °the object to expand/collaps
°BOOL expand °TRUE=expand<BR>FALSE=collapse
<t>
@returns TRUE success
*/
BOOL XContainerControl::ExpandTreeObject(const XContainerObject * obj, const BOOL expand) const
{
if (expand)
return (BOOL) WinSendMsg(winhandle, CM_EXPANDTREE, MPFROMP(obj->core), 0);
else
return (BOOL) WinSendMsg(winhandle, CM_COLLAPSETREE, MPFROMP(obj->core), 0);
}
SHORT EXPENTRY SortRecord(const PRECORDCORE p1, const PRECORDCORE p2, const void *p3);
/*@ XContainerControl :: SortObjects( void )
@group misc
@remarks Sort the objects in the container. On default the objects are sorted
by the title of the object. To sort them on a user-defined way you must override
the method Sort() of the XContainerObject.
*/
void XContainerControl::SortObjects(void) const
{
WinSendMsg(winhandle, CM_SORTRECORD, MPFROMP(SortRecord), 0);
}
/*@ XContainerControl :: HScroll( const LONG pix )
@group display
@remarks Scrolls the container content horizontal
@parameters LONG pixels how much pixels to scroll
*/
void XContainerControl::HScroll(const LONG pix) const
{
WinSendMsg(winhandle, CM_SCROLLWINDOW, MPFROMSHORT(CMA_HORIZONTAL), (MRESULT) pix);
}
/*@ XContainerControl :: VScroll( const LONG pix )
@group display
@remarks Scrolls the container content vertical
@parameters LONG pixels how much pixels to scroll
*/
void XContainerControl::VScroll(const LONG pix) const
{
WinSendMsg(winhandle, CM_SCROLLWINDOW, MPFROMSHORT(CMA_VERTICAL), (MRESULT) pix);
}
/*@ XContainerControl :: UpdateColumns( void )
@group columns
@remarks Update columns in detail-view. If you have inserted, deleted or modified
one ore more columns you must call UpdateColumns to make your changes visible.
*/
void XContainerControl::UpdateColumns(void) const
{
WinSendMsg(winhandle, CM_INVALIDATEDETAILFIELDINFO, 0, 0);
}
/*@ XContainerControl :: FindObject( const XContainerObject * startObject, const SHORT select)
@group searching
@remarks Get an object from the container with relative positions
@parameters <t '°' c=2>
°XContainerObject * startObject °search relative to this object (default is NULL)
°SHORT select °serach settings, valid values are:
<t '°' c=2>
°CON_FIRST °get the first object of the container
°CON_FIRSTCHILD °get the first child of startObject
°CON_LAST °get the last object of the container
°CON_LASTCHILD °get the last child of startObject
°CON_NEXT °get the next object relative to startObject
°CON_PARENT °get the parent of startObject
°CON_PREV °get the previous object relative to startObject
</t>
default is CON_FIRST
</t>
@returns XContainerObject * pointer to the found object (NULL if nothing is found)
*/
XContainerObject *XContainerControl::FindObject(const XContainerObject * startObject, const SHORT select)
{
RECORDCORE *res, *rel = NULL;
if (startObject != NULL)
rel = startObject->core;
res = (RECORDCORE *) WinSendMsg(winhandle, CM_QUERYRECORD, MPFROMP(rel), MPFROM2SHORT(select, CMA_ITEMORDER));
if (res > 0)
{
RECORDCORE *pr = (RECORDCORE *) ((PBYTE) res + sizeof(RECORDCORE));
XContainerObject *obj;
memcpy(&obj, pr, 4);
return obj;
}
else
return NULL;
}
/*@ XContainerControl :: GetObject( const XContainerObject * startObject, const SHORT filter)
@group searching
@remarks Get an object from the container by querying the objects emphasis
@parameters <t '°' c=2>
°XContainerObject * startObject °search relative to this object (default is NULL)
°SHORT filter °the emphasis to search
<t '°' c=2>
°CON_CURSORED °the object has the cursored
°CON_DISABLED °the object is disabled
°CON_INUSE °the objects icon is displayed open
°CON_PICKED °the objects icon is displayed dragged
°CON_SELECTED °the object is selected
°CON_SOURCE °the object get source-emphasis
</t>
(default is CON_SELECTED, can be or-ed)
</t>
@returns XContainerObject * pointer to the found object (NULL if nothing is found)
*/
XContainerObject *XContainerControl::GetObject(const XContainerObject * startObject, const SHORT filter)
{
RECORDCORE *res, *rel;
XContainerObject *obj;
if (startObject)
rel = startObject->core;
else
rel = (PRECORDCORE) CON_FIRST;
res = (RECORDCORE *) WinSendMsg(winhandle, CM_QUERYRECORDEMPHASIS, MPFROMP(rel), MPFROMSHORT(filter));
if (res > 0)
{
PRECORDCORE pr = (PRECORDCORE) ((PBYTE) res + sizeof(RECORDCORE));
memcpy(&obj, pr, 4);
return obj;
}
else
return NULL;
}
/*@ XContainerControl :: InvalidateObject( const XContainerObject * obj, const SHORT option) const
@group display
@remarks Invalidates one ore all objects
@parameters <t '°' c=2>
°XContainerObject * theObject °the object to invalidate (default is NULL)
°SHORT options °options, valid values are:
<t '°' c=2>
°CON_ERASE °erase the background
°CON_REPOSITION °reposition
°CON_NOREPOSITION °no reposition
°CON_TEXTCHANGED °redraw the text
</t>
(default is CON_REPOSITION, can be or-ed)
</t>
*/
void XContainerControl::InvalidateObject(const XContainerObject * obj, const SHORT option) const
{
if (obj)
WinSendMsg(winhandle, CM_INVALIDATERECORD, MPFROMP(&obj->core), MPFROM2SHORT(1, option));
else
WinSendMsg(winhandle, CM_INVALIDATERECORD, 0, 0);
}
/*@ XContainerControl :: RemoveObject( XContainerObject * obj, const BOOL destroyObject, const BOOL redraw)
@group inserting/removing objects
@remarks Removes an object from the container
@parameters <t '°' c=2>
°XContainerObject * theObject °the object to remove
°BOOL destryObject °if TRUE the destructor of the object is called
if FALSE it exist (usefull if an object is member
of multiple container-controls)
(default is TRUE)
°BOOL redraw °redraw the container (default is TRUE)
</t>
@returns BOOL success
*/
BOOL XContainerControl::RemoveObject(XContainerObject * obj, const BOOL destroyObject, const BOOL redraw) const
{
SHORT settings = 0;
if (destroyObject)
settings = CMA_FREE;
if (redraw)
settings |= CMA_INVALIDATE;
if ((LONG) WinSendMsg(winhandle, CM_REMOVERECORD, MPFROMP(&obj->core), MPFROM2SHORT(1, settings)) == -1)
return FALSE;
if (destroyObject)
delete obj; // new
return TRUE;
}
/*@ XContainerControl :: RemoveObjectList( XContainerObject ** obj, const SHORT count, const BOOL destroyObject, const BOOL redraw)
@group inserting/removing objects
@remarks Removes an array of objects from the container
@parameters <t '°' c=2>
°XContainerObject ** theObjects °an array of pointer to objects to remove
°SHORT count °the count of object in the array
°BOOL destryObject °if TRUE the destructor of the objects are called
if FALSE it exist (usefull if an object is member
of multiple container-controls)
(default is TRUE)
°BOOL redraw °redraw the container (default is TRUE)
</t>
@returns BOOL success
*/
BOOL XContainerControl::RemoveObjectList(XContainerObject ** obj, const SHORT count, const BOOL destroyObject, const BOOL redraw) const
{
SHORT settings = 0;
if (destroyObject)
settings = CMA_FREE;
if (redraw)
settings |= CMA_INVALIDATE;
RECORDCORE **core = (RECORDCORE **) malloc(count * sizeof(void *));
int i;
for (i = 0; i < count; i++)
core[i] = obj[i]->core;
if ((LONG) WinSendMsg(winhandle, CM_REMOVERECORD, MPFROMP(core), MPFROM2SHORT(count, settings)) == -1)
return FALSE;
if (destroyObject)
{
for (i = 0; i < count; i++)
delete obj[i];
}
free(core);
return TRUE;
}
/*@ XContainerControl::AddObject(XContainerObject * object, XContainerObject * parentObject, XContainerObject * sibObject, BOOL draw)
@group inserting/removing objects
@remarks Add an object to the container. If you insert a large amount of objects you should set
parameter <redraw> to FALSE and call InvalidateObject(NULL) if you have finished inserting.
@parameters <t '°' c=2>
°XContainerObject * theObject °object to add
°XContainerObject * parentObject °parent of the object (for tree-view)
(default is NULL)
°XContainerObject * sibObject °sibling object to insert behind, or:
<t '°' c=2>
°CON_FIRST °insert at the top
°CON_END °insert at the end
</t>
In this cases you have to make a typecast: (XContainerObject *)
(default is CON_END)
°BOOL redraw °redraw the object
</t>
@returns BOOL success
*/
BOOL XContainerControl::AddObject(XContainerObject * object, XContainerObject * parentObject, XContainerObject * sibObject, BOOL draw)
{
RECORDINSERT ri;
ri.cb = sizeof(RECORDINSERT);
ri.zOrder = CMA_BOTTOM;
ri.cRecordsInsert = 1;
ri.fInvalidateRecord = draw;
ri.pRecordParent = parentObject ? parentObject->core : NULL;
if (sibObject)
{
if (sibObject != (XContainerObject *) CMA_END && sibObject != (XContainerObject *) CMA_FIRST)
ri.pRecordOrder = sibObject->core;
else
ri.pRecordOrder = (PRECORDCORE) sibObject;
}
else
ri.pRecordOrder = (PRECORDCORE) CMA_END;
return (BOOL) WinSendMsg(winhandle, CM_INSERTRECORD, (MPARAM) object->core, (MPARAM) & ri);
}
/*@ XContainerControl::AddObjectList(XContainerObject ** objectList, const USHORT count, XContainerObject * parentObject, XContainerObject * sibObject, BOOL draw)
@group inserting/removing objects
@remarks Add an object to the container. If you insert a large amount of objects you should set
parameter <redraw> to FALSE and call InvalidateObject(NULL) if you have finished inserting.
@parameters <t '°' c=2>
°XContainerObject ** theObject °an array of pointer to objects to add
°SHORT count °count of object in the array
°XContainerObject * parentObject °parent of the objects (for tree-view)
(default is NULL)
°XContainerObject * sibObject °sibling object to insert behind, or:
<t '°' c=2>
°CON_FIRST °insert at the top
°CON_END °insert at the end
</t>
In this cases you have to make a typecast: (XContainerObject *)
(default is CON_END)
°BOOL redraw °draw the objects
</t>
@returns BOOL success
*/
BOOL XContainerControl::AddObjectList(XContainerObject ** objectList, const USHORT count, XContainerObject * parentObject, XContainerObject * sibObject, BOOL draw)
{
if (count == 0)
return TRUE;
RECORDINSERT ri;
ri.cb = sizeof(RECORDINSERT);
ri.zOrder = CMA_BOTTOM;
ri.cRecordsInsert = count;
ri.fInvalidateRecord = draw;
ri.pRecordParent = parentObject ? parentObject->core : NULL;
if (sibObject)
{
if (sibObject != (XContainerObject *) CMA_END && sibObject != (XContainerObject *) CMA_FIRST)
ri.pRecordOrder = sibObject->core;
else
ri.pRecordOrder = (PRECORDCORE) sibObject;
}
else
ri.pRecordOrder = (PRECORDCORE) CMA_END;
RECORDCORE **core = (RECORDCORE **) malloc(count * sizeof(void *));
for (int i = 0; i < count; i++)
core[i] = objectList[i]->core;
return (BOOL) WinSendMsg(winhandle, CM_INSERTRECORDARRAY, (MPARAM) core, (MPARAM) & ri);
free(core);
}
/*@ XContainerControl::GetInfo(XContainerInfo * info)
@group info
@remarks Querys information about the container.
@parameters XContainerInfo * the information buffer to hold the information (See the description of XContainerInfo )
*/
void XContainerControl::GetInfo(XContainerInfo * info)
{
WinSendMsg(winhandle, CM_QUERYCNRINFO, MPFROMP(&info->cnrinfo), (MRESULT) sizeof(CNRINFO));
info->changes = 0;
}
/*@ XContainerControl::SetInfo(XContainerInfo * info)
@group info
@remarks Set information how to display the container.
@parameters XContainerInfo * the information See the description of XContainerInfo
*/
void XContainerControl::SetInfo(XContainerInfo * info)
{
WinSendMsg(winhandle, CM_SETCNRINFO, MPFROMP(&info->cnrinfo), MPFROMLONG(info->changes));
info->changes = 0;
}
/*@ XContainerControl::Arrange(void)
@group display
@remarks Rearrange the object is the container
*/
void XContainerControl::Arrange(void) const
{
WinSendMsg(winhandle, CM_ARRANGE, 0, 0);
}
void XContainerControl::Clean(PRECORDCORE first)
{
XContainerObject *o;
PRECORDCORE pr;
PRECORDCORE core = first, buffer;
while (core)
{
pr = (RECORDCORE *) ((PBYTE) core + sizeof(RECORDCORE));
PRECORDCORE co2 = (PRECORDCORE) WinSendMsg(winhandle, CM_QUERYRECORD, core, MPFROM2SHORT(CMA_FIRSTCHILD, CMA_ITEMORDER));
if (co2)
Clean(co2);
memcpy(&o, pr, 4);
if (o)
delete o;
buffer = (PRECORDCORE) WinSendMsg(winhandle, CM_QUERYRECORD, core, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
WinSendMsg(winhandle, CM_REMOVERECORD, &core, MPFROM2SHORT(1, CMA_FREE));
core = buffer;
}
}
/*@ XContainerControl::RemoveAll(BOOL destroyRecords)
@group inserting/removing objects
@remarks Remove all objects from a container
@parameters BOOL destroyObjects the destructors of the objects are called and
memory ascociated with the container is freed.
*/
void XContainerControl::RemoveAll(BOOL destroyRecords)
{
if (destroyRecords)
{
PRECORDCORE core = (PRECORDCORE) WinSendMsg(winhandle, CM_QUERYRECORD, NULL, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
if (core == (PRECORDCORE) - 1)
return;
Clean(core);
}
else
WinSendMsg(winhandle, CM_REMOVERECORD, 0, 0);
}
/*@ XContainerControl :: XContainerControl(const XWindow * owner, const XRect * rec, const USHORT id, const ULONG style, const char *font):XControl(rec, style, owner, "", WC_CONTAINER, id, font)
@group constructors/destructors
@remarks
@parameters <t '°' c=2>
°XWindow * theOwner °The owning window.
°XRect * rectangle °Position and size.
°USHORT id °The id of the window.
Default is zero.
°ULONG style °The style. valid values are:
<t '°' c=2>
°CON_AUTOPOSITION °objects are arranged automaticaly
°CON_EXTENDSEL °extended selection is enabled
°CON_MULTIPLESEL °mutiple selection is enabled
°CON_READONLY °directe diting is disabled
°CON_SINGLESEL °only one object can be selected
</t>
</t>
*/
XContainerControl :: XContainerControl(const XWindow * owner, const XRect * rec, const USHORT id, const ULONG style, const char *font):XControl(rec, style, owner, "", WC_CONTAINER, id, font)
{
}
/*@ XContainerControl::RemoveColumn(XContainerColumn * column, const SHORT option)
@group columns
@remarks Removes a column
@parameters <t '°' c=2>
°XContainerColumn * theColumn °The column to delete
°SHORT option °How to delete. Valid values are:
<t '°' c=2>
°CON_FREE °Destruct the column and free
container related memory
°CON_INVALIDATE °Redraw the container
</t>
</t>
@returns BOOL success
*/
BOOL XContainerControl::RemoveColumn(XContainerColumn * column, const SHORT option)
{
LONG res = (LONG) WinSendMsg(winhandle, CM_REMOVEDETAILFIELDINFO, MPFROMP(column->info), MPFROM2SHORT(1, option));
if (option & CON_FREE)
delete column;
if (res < 0)
return FALSE;
else
return TRUE;
}
/*@ XContainerControl::GetColumn(const XContainerColumn * col, const SHORT option)
@group columns
@remarks Query a column from a container.
@parameters <t '°' c=2>
°XContainerColumn * theColumnToSearch °Relative position to begin search. In cases
CMA_FIRST and CMA_LAST ignored.
°SHORT options °Valid values are:
<t '°' c=2>
°CON_FIRST °Get the first column.
°CON_LAST °Get the last column.
°CON_NEXT °Get the next relative to theColumnToSearch.
°CON_PREV °Get the previous relative to theColumnToSearch.
</t>
</t>
@returns XContainerControl * The found column.
*/
XContainerColumn * XContainerControl::GetColumn(const XContainerColumn * col, const SHORT option)
{
FIELDINFO *i, *p;
if (col != (XContainerColumn *) CMA_LAST && col != (XContainerColumn *) CMA_FIRST && col != (XContainerColumn *) CMA_PREV && col != (XContainerColumn *) CMA_NEXT)
p = col->info;
else
p = (FIELDINFO *) col;
i = (FIELDINFO *) WinSendMsg(winhandle, CM_QUERYDETAILFIELDINFO, MPFROMP(p), MPFROMSHORT(option));
if (i == NULL || i == (FIELDINFO *) - 1)
return NULL;
XContainerColumn *c = NULL;
memcpy(c, i->pUserData, sizeof(void *));
return c;
}
/*@ XContainerControl::InsertColumn(const XContainerColumn * column, const XContainerColumn * insertBehind, const BOOL redraw)
@group columns
@remarks Insert a column into a container. After you have added one or more columns,
you must call Invalidate() so the columns are drawn.
@parameters <t '°' c=2>
°XContainerColumn * theColumnToInsert °This column should be inserted
°XContainerColumn * insertPosition °The position to insert. Valid values are:
<t '°' c=2>
°CON_FIRST °Insert as the first column.
°CON_LAST °Insert as the last column.
°XContaineColumn* °The column behind which the
column should be inserted.
</t>
</t>
@returns BOOL success
*/
BOOL XContainerControl::InsertColumn(const XContainerColumn * column, const XContainerColumn * insertBehind, const BOOL redraw)
{
FIELDINFOINSERT insert;
insert.cb = sizeof(insert);
insert.fInvalidateFieldInfo = redraw;
if (insertBehind)
{
if (insertBehind != (XContainerColumn *) CMA_FIRST && insertBehind != (XContainerColumn *) CMA_END)
insert.pFieldInfoOrder = insertBehind->info;
else
insert.pFieldInfoOrder = (FIELDINFO *) insertBehind;
}
else
insert.pFieldInfoOrder = (FIELDINFO *) CMA_FIRST;
insert.cFieldInfoInsert = 1;
if (SHORT1FROMMR(WinSendMsg(winhandle, CM_INSERTDETAILFIELDINFO, MPFROMP(column->info), MPFROMP(&insert))) == 0)
return FALSE;
else
return TRUE;
}