Category : Files from Magazines
Archive   : DFLT18.ZIP
Filename : MENUBAR.C

 
Output of file : MENUBAR.C contained in archive : DFLT18.ZIP
/* ---------------- menubar.c ------------------ */

#include "dflat.h"

static void reset_menubar(WINDOW);

static struct {
int x1, x2; /* position in menu bar */
char sc; /* shortcut key value */
} menu[10];
static int mctr;

MBAR *ActiveMenuBar;
static MENU *ActiveMenu;

static WINDOW mwnd;
static BOOL Selecting;

static WINDOW Cascaders[MAXCASCADES];
static int casc;
static WINDOW GetDocFocus(void);

/* ----------- SETFOCUS Message ----------- */
static int SetFocusMsg(WINDOW wnd, PARAM p1)
{
int rtn;
rtn = BaseWndProc(MENUBAR, wnd, SETFOCUS, p1, 0);
if (!(int)p1)
SendMessage(GetParent(wnd), ADDSTATUS, 0, 0);
return rtn;
}

/* --------- BUILDMENU Message --------- */
static void BuildMenuMsg(WINDOW wnd, PARAM p1)
{
int offset = 3;
reset_menubar(wnd);
mctr = 0;
ActiveMenuBar = (MBAR *) p1;
ActiveMenu = ActiveMenuBar->PullDown;
while (ActiveMenu->Title != NULL &&
ActiveMenu->Title != (void*)-1) {
char *cp;
if (strlen(GetText(wnd)+offset) <
strlen(ActiveMenu->Title)+3)
break;
GetText(wnd) = DFrealloc(GetText(wnd),
strlen(GetText(wnd))+5);
memmove(GetText(wnd) + offset+4, GetText(wnd) + offset,
strlen(GetText(wnd))-offset+1);
CopyCommand(GetText(wnd)+offset,ActiveMenu->Title,FALSE,
wnd->WindowColors [STD_COLOR] [BG]);
menu[mctr].x1 = offset;
offset += strlen(ActiveMenu->Title) + (3+MSPACE);
menu[mctr].x2 = offset-MSPACE;
cp = strchr(ActiveMenu->Title, SHORTCUTCHAR);
if (cp)
menu[mctr].sc = tolower(*(cp+1));
mctr++;
ActiveMenu++;
}
ActiveMenu = ActiveMenuBar->PullDown;
}

/* ---------- PAINT Message ---------- */
static void PaintMsg(WINDOW wnd)
{
if (Selecting)
return;
if (wnd == inFocus)
SendMessage(GetParent(wnd), ADDSTATUS, 0, 0);
SetStandardColor(wnd);
wputs(wnd, GetText(wnd), 0, 0);
if (ActiveMenuBar->ActiveSelection != -1 &&
(wnd == inFocus || mwnd != NULL)) {
char *sel, *cp;
int offset, offset1;

sel = DFmalloc(200);
offset=menu[ActiveMenuBar->ActiveSelection].x1;
offset1=menu[ActiveMenuBar->ActiveSelection].x2;
GetText(wnd)[offset1] = '\0';
SetReverseColor(wnd);
memset(sel, '\0', 200);
strcpy(sel, GetText(wnd)+offset);
cp = strchr(sel, CHANGECOLOR);
if (cp != NULL)
*(cp + 2) = background | 0x80;
wputs(wnd, sel,
offset-ActiveMenuBar->ActiveSelection*4, 0);
GetText(wnd)[offset1] = ' ';
if (mwnd == NULL && wnd == inFocus) {
char *st = ActiveMenu
[ActiveMenuBar->ActiveSelection].StatusText;
if (st != NULL)
SendMessage(GetParent(wnd), ADDSTATUS,
(PARAM)st, 0);
}
free(sel);
}
}

/* ------------ KEYBOARD Message ------------- */
static void KeyboardMsg(WINDOW wnd, PARAM p1)
{
MENU *mnu;
int sel;
if (mwnd == NULL) {
/* ----- search for menu bar shortcut keys ---- */
int c = tolower((int)p1);
int a = AltConvert((int)p1);
int j;
for (j = 0; j < mctr; j++) {
if ((inFocus == wnd && menu[j].sc == c) ||
(a && menu[j].sc == a)) {
SendMessage(wnd, SETFOCUS, TRUE, 0);
SendMessage(wnd, MB_SELECTION, j, 0);
return;
}
}
}
/* -------- search for accelerator keys -------- */
mnu = ActiveMenu;
while (mnu->Title != (void *)-1) {
struct PopDown *pd = mnu->Selections;
if (mnu->PrepMenu)
(*(mnu->PrepMenu))(GetDocFocus(), mnu);
while (pd->SelectionTitle != NULL) {
if (pd->Accelerator == (int) p1) {
if (pd->Attrib & INACTIVE)
beep();
else {
if (pd->Attrib & TOGGLE)
pd->Attrib ^= CHECKED;
SendMessage(GetDocFocus(),
SETFOCUS, TRUE, 0);
PostMessage(GetParent(wnd),
COMMAND, pd->ActionId, 0);
}
return;
}
pd++;
}
mnu++;
}
switch ((int)p1) {
case F1:
if (ActiveMenu == NULL || ActiveMenuBar == NULL)
break;
sel = ActiveMenuBar->ActiveSelection;
if (sel == -1) {
BaseWndProc(MENUBAR, wnd, KEYBOARD, F1, 0);
return;
}
mnu = ActiveMenu+sel;
if (mwnd == NULL ||
mnu->Selections[0].SelectionTitle == NULL) {
DisplayHelp(wnd,mnu->Title);
return;
}
break;
case '\r':
if (mwnd == NULL &&
ActiveMenuBar->ActiveSelection != -1)
SendMessage(wnd, MB_SELECTION,
ActiveMenuBar->ActiveSelection, 0);
break;
case F10:
if (wnd != inFocus && mwnd == NULL) {
SendMessage(wnd, SETFOCUS, TRUE, 0);
if ( ActiveMenuBar->ActiveSelection == -1)
ActiveMenuBar->ActiveSelection = 0;
SendMessage(wnd, PAINT, 0, 0);
break;
}
/* ------- fall through ------- */
case ESC:
if (inFocus == wnd && mwnd == NULL) {
ActiveMenuBar->ActiveSelection = -1;
SendMessage(GetDocFocus(),SETFOCUS,TRUE,0);
SendMessage(wnd, PAINT, 0, 0);
}
break;
case FWD:
ActiveMenuBar->ActiveSelection++;
if (ActiveMenuBar->ActiveSelection == mctr)
ActiveMenuBar->ActiveSelection = 0;
if (mwnd != NULL)
SendMessage(wnd, MB_SELECTION,
ActiveMenuBar->ActiveSelection, 0);
else
SendMessage(wnd, PAINT, 0, 0);
break;
case BS:
if (ActiveMenuBar->ActiveSelection == 0 ||
ActiveMenuBar->ActiveSelection == -1)
ActiveMenuBar->ActiveSelection = mctr;
--ActiveMenuBar->ActiveSelection;
if (mwnd != NULL)
SendMessage(wnd, MB_SELECTION,
ActiveMenuBar->ActiveSelection, 0);
else
SendMessage(wnd, PAINT, 0, 0);
break;
default:
break;
}
}

/* --------------- LEFT_BUTTON Message ---------- */
static void LeftButtonMsg(WINDOW wnd, PARAM p1)
{
int i;
int mx = (int) p1 - GetLeft(wnd);
/* --- compute the selection that the left button hit --- */
for (i = 0; i < mctr; i++)
if (mx >= menu[i].x1-4*i &&
mx <= menu[i].x2-4*i-5)
break;
if (i < mctr)
if (i != ActiveMenuBar->ActiveSelection || mwnd == NULL)
SendMessage(wnd, MB_SELECTION, i, 0);
}

/* -------------- MB_SELECTION Message -------------- */
static void SelectionMsg(WINDOW wnd, PARAM p1, PARAM p2)
{
int wd, mx, my;
MENU *mnu;

if (!p2) {
ActiveMenuBar->ActiveSelection = -1;
SendMessage(wnd, PAINT, 0, 0);
}
Selecting = TRUE;
mnu = ActiveMenu+(int)p1;
if (mnu->PrepMenu != NULL)
(*(mnu->PrepMenu))(GetDocFocus(), mnu);
wd = MenuWidth(mnu->Selections);
if (p2) {
int brd = GetRight(wnd);
mx = GetLeft(mwnd) + WindowWidth(mwnd) - 1;
if (mx + wd > brd)
mx = brd - wd;
my = GetTop(mwnd) + mwnd->selection;
}
else {
int offset = menu[(int)p1].x1 - 4 * (int)p1;
if (mwnd != NULL)
SendMessage(mwnd, CLOSE_WINDOW, 0, 0);
ActiveMenuBar->ActiveSelection = (int) p1;
if (offset > WindowWidth(wnd)-wd)
offset = WindowWidth(wnd)-wd;
mx = GetLeft(wnd)+offset;
my = GetTop(wnd)+1;
}
mwnd = CreateWindow(POPDOWNMENU, NULL,
mx, my,
MenuHeight(mnu->Selections),
wd,
NULL,
wnd,
NULL,
SHADOW);
if (!p2) {
Selecting = FALSE;
SendMessage(wnd, PAINT, 0, 0);
Selecting = TRUE;
}
if (mnu->Selections[0].SelectionTitle != NULL) {
SendMessage(mwnd, BUILD_SELECTIONS, (PARAM) mnu, 0);
SendMessage(mwnd, SETFOCUS, TRUE, 0);
SendMessage(mwnd, SHOW_WINDOW, 0, 0);
}
Selecting = FALSE;
}

/* --------- COMMAND Message ---------- */
static void CommandMsg(WINDOW wnd, PARAM p1, PARAM p2)
{
if (p1 == ID_HELP) {
BaseWndProc(MENUBAR, wnd, COMMAND, p1, p2);
return;
}
if (isCascadedCommand(ActiveMenuBar, (int)p1)) {
/* find the cascaded menu based on command id in p1 */
MENU *mnu = ActiveMenu+mctr;
while (mnu->Title != (void *)-1) {
if (mnu->CascadeId == (int) p1) {
if (casc < MAXCASCADES) {
Cascaders[casc++] = mwnd;
SendMessage(wnd, MB_SELECTION,
(PARAM)(mnu-ActiveMenu), TRUE);
}
break;
}
mnu++;
}
}
else {
if (mwnd != NULL)
SendMessage(mwnd, CLOSE_WINDOW, 0, 0);
SendMessage(GetDocFocus(), SETFOCUS, TRUE, 0);
PostMessage(GetParent(wnd), COMMAND, p1, p2);
}
}

/* --------------- CLOSE_POPDOWN Message --------------- */
static void ClosePopdownMsg(WINDOW wnd)
{
if (casc > 0)
SendMessage(Cascaders[--casc], CLOSE_WINDOW, 0, 0);
else {
mwnd = NULL;
ActiveMenuBar->ActiveSelection = -1;
if (!Selecting) {
SendMessage(GetDocFocus(), SETFOCUS, TRUE, 0);
SendMessage(wnd, PAINT, 0, 0);
}
}
}

/* ---------------- CLOSE_WINDOW Message --------------- */
static void CloseWindowMsg(WINDOW wnd)
{
if (GetText(wnd) != NULL) {
free(GetText(wnd));
GetText(wnd) = NULL;
}
mctr = 0;
ActiveMenuBar->ActiveSelection = -1;
ActiveMenu = NULL;
ActiveMenuBar = NULL;
}

/* --- Window processing module for MENUBAR window class --- */
int MenuBarProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2)
{
int rtn;

switch (msg) {
case CREATE_WINDOW:
reset_menubar(wnd);
break;
case SETFOCUS:
return SetFocusMsg(wnd, p1);
case BUILDMENU:
BuildMenuMsg(wnd, p1);
break;
case PAINT:
if (!isVisible(wnd) || GetText(wnd) == NULL)
break;
PaintMsg(wnd);
return FALSE;
case BORDER:
if (mwnd == NULL)
SendMessage(wnd, PAINT, 0, 0);
return TRUE;
case KEYBOARD:
KeyboardMsg(wnd, p1);
return TRUE;
case LEFT_BUTTON:
LeftButtonMsg(wnd, p1);
return TRUE;
case MB_SELECTION:
SelectionMsg(wnd, p1, p2);
break;
case COMMAND:
CommandMsg(wnd, p1, p2);
return TRUE;
case INSIDE_WINDOW:
return InsideRect(p1, p2, WindowRect(wnd));
case CLOSE_POPDOWN:
ClosePopdownMsg(wnd);
return TRUE;
case CLOSE_WINDOW:
rtn = BaseWndProc(MENUBAR, wnd, msg, p1, p2);
CloseWindowMsg(wnd);
return rtn;
default:
break;
}
return BaseWndProc(MENUBAR, wnd, msg, p1, p2);
}

/* ------------- reset the MENUBAR -------------- */
static void reset_menubar(WINDOW wnd)
{
GetText(wnd) = DFrealloc(GetText(wnd), SCREENWIDTH+5);
memset(GetText(wnd), ' ', SCREENWIDTH);
*(GetText(wnd)+WindowWidth(wnd)) = '\0';
}

static WINDOW GetDocFocus(void)
{
WINDOW wnd = ApplicationWindow;
if (wnd != NULL) {
wnd = LastWindow(wnd);
while (wnd != NULL && (GetClass(wnd) == MENUBAR ||
GetClass(wnd) == STATUSBAR))
wnd = PrevWindow(wnd);
if (wnd != NULL)
while (wnd->childfocus != NULL)
wnd = wnd->childfocus;
}
return wnd ? wnd : ApplicationWindow;
}




  3 Responses to “Category : Files from Magazines
Archive   : DFLT18.ZIP
Filename : MENUBAR.C

  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/