home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Supreme Volume 6 #1
/
swsii.zip
/
swsii
/
215
/
DDJ9302.ZIP
/
CPROG.ASC
next >
Wrap
Text File
|
1993-01-11
|
18KB
|
667 lines
_C PROGRAMMING COLUMN_
by Al Stevens
[LISTING ONE]
// -------------- applicat.h
#ifndef APPLICAT_H
#define APPLICAT_H
#include "menubar.h"
#include "statbar.h"
class Application : public DFWindow {
MenuBar *menubar; // points to menu bar
StatusBar *statusbar; // points to status bar
Bool takingfocus; // true while taking focus
virtual void SetColors();
protected:
// ------------- client window coordinate adjustments
virtual void AdjustBorders();
public:
Application(char *ttl,int lf,int tp,int ht,int wd,MenuBarItem *Menu = NULL)
: DFWindow(ttl, lf, tp, ht, wd, NULL)
{ OpenWindow(Menu); }
Application(char *ttl, int ht, int wd, MenuBarItem *Menu = NULL)
: DFWindow(ttl, ht, wd, NULL)
{ OpenWindow(Menu); }
Application(int lf, int tp, int ht, int wd, MenuBarItem *Menu = NULL)
: DFWindow(lf, tp, ht, wd, NULL)
{ OpenWindow(Menu); }
Application(int ht, int wd, MenuBarItem *Menu = NULL)
: DFWindow(ht, wd, NULL)
{ OpenWindow(Menu); }
Application(char *ttl, MenuBarItem *Menu = NULL)
: DFWindow(ttl)
{ OpenWindow(Menu); }
virtual ~Application()
{ if (windowstate != CLOSED) CloseWindow(); }
// -------- API messages
virtual void OpenWindow() { OpenWindow(NULL); }
void OpenWindow(MenuBarItem *menu);
virtual void CloseWindow();
virtual Bool SetFocus();
virtual void Show();
virtual void Keyboard(int key);
virtual void ClockTick();
void StatusMessage(String& Msg);
};
void DispatchEvents(Application *ApWnd);
void InitializeEvents(void);
#endif
[LISTING TWO]
// ------------ applicat.cpp
#include "dflatpp.h"
void Application::OpenWindow(MenuBarItem *menu)
{
extern DeskTop desktop;
desktop.SetApplication(this);
windowtype = ApplicationWindow;
if (windowstate == CLOSED)
DFWindow::OpenWindow();
SetAttribute(BORDER | SAVESELF | CONTROLBOX | STATUSBAR);
SetColors();
if (menu != NULL) {
SetAttribute(MENUBAR);
menubar = new MenuBar(menu, this);
}
else
menubar = NULL;
statusbar = new StatusBar(this);
desktop.mouse().Show();
DFWindow::SetFocus();
takingfocus = False;
}
void Application::CloseWindow()
{
if (menubar != NULL)
delete menubar;
if (statusbar != NULL)
delete statusbar;
desktop.SetApplication(NULL);
DFWindow::CloseWindow();
}
// -------- set the fg/bg colors for the window
void Application::SetColors()
{
colors.fg =
colors.sfg =
colors.ffg =
colors.hfg = LIGHTGRAY;
colors.bg =
colors.sbg =
colors.fbg =
colors.hbg = BLUE;
}
void Application::AdjustBorders()
{
DFWindow::AdjustBorders();
if (attrib & MENUBAR)
TopBorderAdj++;
if (attrib & STATUSBAR)
BottomBorderAdj = 1;
}
Bool Application::SetFocus()
{
takingfocus = True;
DFWindow::SetFocus();
takingfocus = False;
return True;
}
void Application::Show()
{
if (!takingfocus || !isVisible())
DFWindow::Show();
else
Border();
}
void Application::Keyboard(int key)
{
switch (key) {
case CTRL_F4:
case ALT_F4:
CloseWindow();
break;
default:
// ---- forward unprocessed keys to the menubar
if (menubar != NULL)
menubar->Keyboard(key);
break;
}
}
void Application::ClockTick()
{
if (statusbar != NULL)
statusbar->ClockTick();
}
void Application::StatusMessage(String& Msg)
{
if (statusbar != NULL)
statusbar->StatusMessage(Msg);
}
[LISTING THREE]
// ---------- control.h
#ifndef CONTROL_H
#define CONTROL_H
#include "dfwindow.h"
class TextBox;
class Control : public DFWindow {
Bool enabled; // true if control is enabled
public:
Control(char *ttl,int lf,int tp,int ht,int wd,DFWindow *par)
: DFWindow(ttl, lf, tp, ht, wd, par)
{ OpenControl(); }
Control(char *ttl, int ht, int wd, DFWindow *par)
: DFWindow(ttl, ht, wd, par)
{ OpenControl(); }
Control(int lf, int tp, int ht, int wd, DFWindow *par)
: DFWindow(lf, tp, ht, wd, par)
{ OpenControl(); }
Control(int ht,int wd,DFWindow *par) : DFWindow(ht,wd,par)
{ OpenControl(); }
Control(char *ttl) : DFWindow(ttl)
{ OpenControl(); }
virtual ~Control() { /* null */ }
virtual void Keyboard(int key);
void OpenControl() { Enable(); }
void Enable() { enabled = True; }
void Disable() { enabled = False; }
Bool isEnabled() { return enabled; }
};
#endif
[LISTING FOUR]
// ------------ control.cpp
#include "control.h"
#include "desktop.h"
void Control::Keyboard(int key)
{
DFWindow *Wnd;
switch (key) {
case UP:
Wnd = desktop.InFocus();
do {
PrevSiblingFocus();
if (Wnd == desktop.InFocus())
break;
} while (desktop.InFocus()->WindowType() == MenubarWindow);
break;
case '\t':
case DN:
case ALT_F6:
Wnd = desktop.InFocus();
do {
NextSiblingFocus();
if (Wnd == desktop.InFocus())
break;
} while (desktop.InFocus()->WindowType() ==
MenubarWindow);
break;
default:
DFWindow::Keyboard(key);
break;
}
}
[LISTING FIVE]
// ------------- textbox.h
#ifndef TEXTBOX_H
#define TEXTBOX_H
#include "control.h"
const int SHORTCUTCHAR = '~';
const int InitialBufferSize = 1024;
class ScrollBar;
class TextBox : public Control {
ScrollBar *hscrollbar; // horizontal scroll bar
ScrollBar *vscrollbar; // vertical scroll bar
unsigned *TextPointers; // -> list of line offsets
Bool resetscrollbox;
protected:
// ---- text buffer
String *text; // window text
unsigned int bufflen; // length of buffer
int wlines; // number of lines of text
unsigned int textlen; // text length
int textwidth; // width of longest line in textbox
// ---- text display
int wtop; // text line on top of display
int wleft; // left position in window viewport
int BlkBegLine; // beginning line of marked block
int BlkBegCol; // beginning column of marked block
int BlkEndLine; // ending line of marked block
int BlkEndCol; // ending column of marked block
int shortcutfg; // shortcut key color
char *TextLine(int line)
{ return (char *)(*text) + *(TextPointers+line); }
int DisplayShortcutField(
String sc, int x, int y, int fg, int bg);
void WriteShortcutLine(int lno, int fg, int bg);
void WriteTextLine(int lno, int fg, int bg);
void BuildTextPointers();
void SetScrollBoxes();
virtual void SetColors();
public:
TextBox(char *ttl,int lf,int tp,int ht,int wd,DFWindow *par)
: Control(ttl, lf, tp, ht, wd, par)
{ OpenWindow(); }
TextBox(char *ttl, int ht, int wd, DFWindow *par)
: Control(ttl, ht, wd, par)
{ OpenWindow(); }
TextBox(int lf, int tp, int ht, int wd, DFWindow *par)
: Control(lf, tp, ht, wd, par)
{ OpenWindow(); }
TextBox(int ht, int wd, DFWindow *par) : Control(ht,wd,par)
{ OpenWindow(); }
TextBox(char *ttl) : Control(ttl)
{ OpenWindow(); }
virtual ~TextBox()
{ if (windowstate != CLOSED) CloseWindow(); }
// -------- textbox API messages
virtual void ScrollUp();
virtual void ScrollDown();
virtual void ScrollRight();
virtual void ScrollLeft();
virtual void PageUp();
virtual void PageDown();
virtual void PageRight();
virtual void PageLeft();
virtual void Home();
virtual void End();
virtual void OpenWindow();
virtual void CloseWindow();
virtual void AddText(char *txt);
virtual void SetText(char *txt);
virtual void SetTextLength(unsigned int len);
virtual void ClearText();
virtual void Show();
virtual void Paint();
virtual void Keyboard(int key);
String ExtractTextLine(int lno);
void ClearTextBlock()
{ BlkBegLine=BlkEndLine=BlkBegCol=BlkEndCol=0; }
void HorizontalPagePosition(int pct);
void VerticalPagePosition(int pct);
};
#endif
[LISTING SIX]
// ------------- textbox.cpp
#include "desktop.h"
#include "textbox.h"
#include "scrolbar.h"
// ----------- common constructor code
void TextBox::OpenWindow()
{
windowtype = TextboxWindow;
if (windowstate == CLOSED)
Control::OpenWindow();
text = NULL;
bufflen = InitialBufferSize;
hscrollbar = vscrollbar = NULL;
TextPointers = NULL;
ClearText();
SetColors();
}
void TextBox::CloseWindow()
{
ClearText();
if (hscrollbar != NULL)
delete hscrollbar;
if (vscrollbar != NULL)
delete vscrollbar;
Control::CloseWindow();
}
// ------ show the textbox
void TextBox::Show()
{
if ((attrib & HSCROLLBAR) && hscrollbar == NULL) {
hscrollbar = new ScrollBar(HORIZONTAL, this);
hscrollbar->SetAttribute(FRAMEWND);
}
if ((attrib & VSCROLLBAR) && vscrollbar == NULL) {
vscrollbar = new ScrollBar(VERTICAL, this);
vscrollbar->SetAttribute(FRAMEWND);
}
Control::Show();
}
// ------------ build the text line pointers
void TextBox::BuildTextPointers()
{
textwidth = wlines = 0;
// ---- count the lines of text
char *cp1, *cp = *text;
while (*cp) {
wlines++;
while (*cp && *cp != '\n')
cp++;
if (*cp)
cp++;
}
// ----- build the pointer array
delete TextPointers;
TextPointers = new unsigned int[wlines];
unsigned int off;
cp = *text;
wlines = 0;
while (*cp) {
off = (unsigned int) (cp - *text);
*(TextPointers + wlines++) = off;
cp1 = cp;
while (*cp && *cp != '\n')
cp++;
textwidth = max(textwidth, (unsigned int) (cp - cp1));
if (*cp)
cp++;
}
}
// --------- add a line of text to the textbox
void TextBox::AddText(char *txt)
{
String tx(txt);
int len = tx.Strlen();
if (tx[len-1] != '\n')
textlen++;
textlen += len;
if (text == NULL)
text = new String(bufflen);
if (textlen > text->StrBufLen())
text->ChangeLength(max(bufflen, textlen));
*text += tx;
if (*text[len-1] != '\n')
*text += String("\n");
BuildTextPointers();
}
// --------- set the textbox's text buffer to new text
void TextBox::SetText(char *txt)
{
ClearText();
AddText(txt);
}
// ------ set the length of the text buffer
void TextBox::SetTextLength(unsigned int len)
{
if (text != NULL)
text->ChangeLength(len);
bufflen = len;
}
// --------- clear the text from the textbox
void TextBox::ClearText()
{
if (text != NULL)
delete text;
textlen = 0;
wlines = 0;
textwidth = 0;
wtop = wleft = 0;
ClearTextBlock();
if (TextPointers != NULL)
delete TextPointers;
}
// -------- set the fg/bg colors for the window
void TextBox::SetColors()
{
colors.fg = BLACK;
colors.bg = LIGHTGRAY;
colors.sfg = LIGHTGRAY;
colors.sbg = BLACK;
colors.ffg = BLACK;
colors.fbg = LIGHTGRAY;
colors.hfg = BLACK;
colors.hbg = LIGHTGRAY;
shortcutfg = BLUE;
}
// ------- extract a text line
String TextBox::ExtractTextLine(int lno)
{
char *lp = TextLine(lno);
int offset = lp - (char *) *text;
for (int len = 0; *(lp+len) && *(lp+len) != '\n'; len++)
;
return text->mid(len, offset);
}
// ---- display a line with a shortcut key character
void TextBox::WriteShortcutLine(int lno, int fg, int bg)
{
String sc = ExtractTextLine(lno);
int x = sc.Strlen();
int y = lno-wtop;
x -= DisplayShortcutField(sc, 0, y, fg, bg);
// --------- pad the line
int wd = ClientWidth() - x;
if (wd > 0)
WriteClientString(String(wd, ' '), x, y, fg, bg);
}
// ---- display a shortcut field character
int TextBox::DisplayShortcutField(String sc, int x, int y, int fg, int bg)
{
int scs = 0;
int off = sc.FindChar(SHORTCUTCHAR);
if (off != -1) {
scs++;
if (off != 0) {
String ls = sc.left(off);
WriteClientString(ls, x, y, fg, bg);
}
WriteClientChar(sc[off+1], x+off, y, shortcutfg, bg);
int len = sc.Strlen()-off-2;
if (len > 0) {
String rs = sc.right(len);
scs += DisplayShortcutField(rs, x+off+1, y, fg, bg);
}
}
else
WriteClientString(sc, x, y, fg, bg);
return scs;
}
// ------- write a text line to the textbox
void TextBox::WriteTextLine(int lno, int fg, int bg)
{
if (lno < wtop || lno >= wtop + ClientHeight())
return;
int wd = ClientWidth();
String tl = ExtractTextLine(lno);
String ln = tl.mid(wd, wleft);
int dif = wd-ln.Strlen();
if (dif > 0)
ln = ln + String(dif, ' '); // pad the line with spaces
// ----- display the line
WriteClientString(ln, 0, lno-wtop, fg, bg);
}
// ---------- paint the textbox
void TextBox::Paint()
{
if (text == NULL)
Control::Paint();
else {
int ht = ClientHeight();
int wd = ClientWidth();
int fg = colors.fg;
int bg = colors.bg;
for (int i = 0; i < min(wlines-wtop,ht); i++)
WriteTextLine(wtop+i, fg, bg);
// ---- pad the bottom lines in the window
String line(wd, ' ');
while (i < ht)
WriteClientString(line, 0, i++, fg, bg);
if (resetscrollbox)
SetScrollBoxes();
resetscrollbox = False;
}
}
// ------ process a textbox keystroke
void TextBox::Keyboard(int key)
{
switch (key) {
case UP:
if (ClientTop() == ClientBottom())
break;
ScrollDown();
return;
case DN:
if (ClientTop() == ClientBottom())
break;
ScrollUp();
return;
case FWD:
ScrollLeft();
return;
case BS:
ScrollRight();
return;
case PGUP:
PageUp();
return;
case PGDN:
PageDown();
return;
case CTRL_PGUP:
PageLeft();
return;
case CTRL_PGDN:
PageRight();
return;
case HOME:
Home();
return;
case END:
End();
return;
default:
break;
}
Control::Keyboard(key);
}
// ------- scroll up one line
void TextBox::ScrollUp()
{
if (wtop < wlines-1) {
int fg = colors.fg;
int bg = colors.bg;
desktop.screen().Scroll(ClientRect(), 1, fg, bg);
wtop++;
int ln = wtop+ClientHeight()-1;
if (ln < wlines)
WriteTextLine(ln, fg, bg);
SetScrollBoxes();
}
}
// ------- scroll down one line
void TextBox::ScrollDown()
{
if (wtop) {
int fg = colors.fg;
int bg = colors.bg;
desktop.screen().Scroll(ClientRect(), 0, fg, bg);
--wtop;
WriteTextLine(wtop, fg, bg);
SetScrollBoxes();
}
}
// ------- scroll left one character
void TextBox::ScrollLeft()
{
if (wleft < textwidth-1)
wleft++;
Paint();
}
// ------- scroll right one character
void TextBox::ScrollRight()
{
if (wleft > 0)
--wleft;
Paint();
}
// ------- page up one screenfull
void TextBox::PageUp()
{
if (wtop) {
wtop -= ClientHeight();
if (wtop < 0)
wtop = 0;
resetscrollbox = True;
Paint();
}
}
// ------- page down one screenfull
void TextBox::PageDown()
{
if (wtop < wlines-1) {
wtop += ClientHeight();
if (wlines < wtop)
wtop = wlines-1;
resetscrollbox = True;
Paint();
}
}
// ------- page right one screenwidth
void TextBox::PageRight()
{
if (wleft < textwidth-1) {
wleft += ClientWidth();
if (textwidth < wleft)
wleft = textwidth-1;
resetscrollbox = True;
Paint();
}
}
// ------- page left one screenwidth
void TextBox::PageLeft()
{
if (wleft) {
wleft -= ClientWidth();
if (wleft < 0)
wleft = 0;
resetscrollbox = True;
Paint();
}
}
// ----- move to the first line of the textbox
void TextBox::Home()
{
wtop = 0;
Paint();
}
// ----- move to the last line of the textbox
void TextBox::End()
{
wtop = wlines-ClientHeight();
if (wtop < 0)
wtop = 0;
Paint();
}
// ----- position the scroll boxes
void TextBox::SetScrollBoxes()
{
if (vscrollbar != NULL)
vscrollbar->TextPosition(wlines ? (wtop*100)/wlines : 0);
if (hscrollbar != NULL)
hscrollbar->TextPosition(textwidth ? (wleft*100)/textwidth : 0);
}
// ---- compute the horizontal page position
void TextBox::HorizontalPagePosition(int pct)
{
wleft = (textwidth * pct) / 100;
Paint();
}
// ---- compute the vertical page position
void TextBox::VerticalPagePosition(int pct)
{
wtop = (wlines * pct) / 100;
Paint();
}