File:  [RetroPC.NET] / np2 / embed / menubase / menudlg.c
Revision 1.9: download - view: text, annotated - select for diffs
Sat Feb 12 06:17:22 2005 JST (20 years, 8 months ago) by yui
Branches: MAIN
CVS tags: VER_0_82_x64, VER_0_82, VER_0_81A, VER_0_81, HEAD
fix...

#include	"compiler.h"
#include	"strres.h"
#include	"fontmng.h"
#include	"vramhdl.h"
#include	"vrammix.h"
#include	"menudeco.inc"
#include	"menubase.h"


typedef struct _dprm {
struct _dprm	*next;
	UINT16		width;
	UINT16		num;
	VRAMHDL		icon;
	OEMCHAR		str[96];
} _DLGPRM, *DLGPRM;

#define	PRMNEXT_EMPTY	((DLGPRM)-1)

typedef struct {
	POINT_T		pt;
	void		*font;
} DLGTEXT;

typedef struct {
	void		*font;
	int			fontsize;
} DLGTAB;

typedef struct {
	void		*font;
	SINT16		fontsize;
	SINT16		scrollbar;
	SINT16		dispmax;
	SINT16		basepos;
} DLGLIST;

typedef struct {
	SINT16		minval;
	SINT16		maxval;
	int			pos;
	UINT8		type;
	UINT8		moving;
	UINT8		sldh;
	UINT8		sldv;
} DLGSLD;

typedef struct {
	VRAMHDL		vram;
} DLGVRAM;

typedef struct _ditem {
	int			type;
	MENUID		id;
	MENUFLG		flag;
	MENUID		page;
	MENUID		group;
	RECT_T		rect;
	DLGPRM		prm;
	int			prmcnt;
	int			val;
	VRAMHDL		vram;
	union {
		DLGTEXT		dt;
		DLGTAB		dtl;
		DLGLIST		dl;
		DLGSLD		ds;
		DLGVRAM		dv;
	} c;
} _DLGHDL, *DLGHDL;

typedef struct {
	VRAMHDL		vram;
	LISTARRAY	dlg;
	LISTARRAY	res;
	int			locked;
	int			closing;
	int			sx;
	int			sy;
	void		*font;
	MENUID		page;
	MENUID		group;
	int			(*proc)(int msg, MENUID id, long param);

	int			dragflg;
	int			btn;
	int			lastx;
	int			lasty;
	MENUID		lastid;
} _MENUDLG, *MENUDLG;


static	_MENUDLG	menudlg;

static void drawctrls(MENUDLG dlg, DLGHDL hdl);


// ----

static BOOL seaprmempty(void *vpItem, void *vpArg) {

	if (((DLGPRM)vpItem)->next == PRMNEXT_EMPTY) {
		menuicon_unlock(((DLGPRM)vpItem)->icon);
		((DLGPRM)vpItem)->icon = NULL;
		return(TRUE);
	}
	(void)vpArg;
	return(FALSE);
}

static DLGPRM resappend(MENUDLG dlg, const OEMCHAR *str) {

	DLGPRM	prm;

	prm = listarray_enum(dlg->res, seaprmempty, NULL);
	if (prm == NULL) {
		prm = (DLGPRM)listarray_append(dlg->res, NULL);
	}
	if (prm) {
		prm->next = NULL;
		prm->width = 0;
		prm->num = 0;
		prm->icon = NULL;
		prm->str[0] = '\0';
		if (str) {
			milstr_ncpy(prm->str, str, NELEMENTS(prm->str));
		}
	}
	return(prm);
}

static void resattachicon(MENUDLG dlg, DLGPRM prm, UINT16 icon,
													int width, int height) {

	if (prm) {
		menuicon_unlock(prm->icon);
		prm->num = icon;
		prm->icon = menuicon_lock(icon, width, height, dlg->vram->bpp);
	}
}

static DLGPRM ressea(DLGHDL hdl, int pos) {

	DLGPRM	prm;

	if (pos >= 0) {
		prm = hdl->prm;
		while(prm) {
			if (!pos) {
				return(prm);
			}
			pos--;
			prm = prm->next;
		}
	}
	return(NULL);
}

static BOOL dsbyid(void *vpItem, void *vpArg) {

	if (((DLGHDL)vpItem)->id == (MENUID)(unsigned long)vpArg) {
		return(TRUE);
	}
	return(FALSE);
}

static DLGHDL dlghdlsea(MENUDLG dlg, MENUID id) {

	return((DLGHDL)listarray_enum(dlg->dlg, dsbyid, (void *)(long)id));
}

static BRESULT gettextsz(DLGHDL hdl, POINT_T *sz) {

	DLGPRM	prm;

	prm = hdl->prm;
	if (prm == NULL) {
		goto gts_err;
	}
	*sz = hdl->c.dt.pt;
	if (prm->icon) {
		if (sz->x) {
#if defined(SIZE_QVGA)
			sz->x += 1;
#else
			sz->x += 2;
#endif
		}
		sz->x += sz->y;
	}
	return(SUCCESS);

gts_err:
	return(FAILURE);
}

static void getleft(POINT_T *pt, const RECT_T *rect, const POINT_T *sz) {

	pt->x = rect->left;
	pt->y = rect->top;
	(void)sz;
}

static void getcenter(POINT_T *pt, const RECT_T *rect, const POINT_T *sz) {

	pt->x = rect->left;
	pt->x += (rect->right - rect->left - sz->x) >> 1;
	pt->y = rect->top;
}

static void getright(POINT_T *pt, const RECT_T *rect, const POINT_T *sz) {

	pt->x = rect->right - sz->x - MENU_DSTEXT;
	pt->y = rect->top;
}

static void getmid(POINT_T *pt, const RECT_T *rect, const POINT_T *sz) {

	pt->x = rect->left;
	pt->x += (rect->right - rect->left - sz->x) >> 1;
	pt->y = rect->top;
	pt->y += (rect->bottom - rect->top - sz->y) >> 1;
}


static BRESULT _cre_settext(MENUDLG dlg, DLGHDL hdl, const void *arg) {

const OEMCHAR	*str;

	str = (OEMCHAR *)arg;
	if (str == NULL) {
		str = str_null;
	}
	hdl->prm = resappend(dlg, str);
	hdl->c.dt.font = dlg->font;
	fontmng_getsize(dlg->font, str, &hdl->c.dt.pt);
	return(SUCCESS);
}

static void dlg_text(MENUDLG dlg, DLGHDL hdl,
									const POINT_T *pt, const RECT_T *rect) {

	VRAMHDL		icon;
const OEMCHAR	*string;
	int			color;
	POINT_T		fp;
	POINT_T		p;

	if (hdl->prm == NULL) {
		return;
	}
	fp = *pt;
	icon = hdl->prm->icon;
	if (icon) {
		if (icon->alpha) {
			vramcpy_cpyex(dlg->vram, &fp, icon, NULL);
		}
		else {
			vramcpy_cpy(dlg->vram, &fp, icon, NULL);
		}
		fp.x += icon->width;
#if defined(SIZE_QVGA)
		fp.x += 1;
#else
		fp.x += 2;
#endif
	}
	string = hdl->prm->str;
	if (string) {
		if (!(hdl->flag & MENU_GRAY)) {
			color = MVC_TEXT;
		}
		else {
			p.x = fp.x + MENU_DSTEXT;
			p.y = fp.y + MENU_DSTEXT;
			vrammix_text(dlg->vram, hdl->c.dt.font, string,
										menucolor[MVC_GRAYTEXT2], &p, rect);
			color = MVC_GRAYTEXT1;
		}
		vrammix_text(dlg->vram, hdl->c.dt.font, string,
										menucolor[color], &fp, rect);
	}
}


// ---- base

static BRESULT dlgbase_create(MENUDLG dlg, DLGHDL hdl, const void *arg) {

	RECT_T		rct;

	rct.right = hdl->rect.right - hdl->rect.left -
										((MENU_FBORDER + MENU_BORDER) * 2);
	hdl->vram = vram_create(rct.right, MENUDLG_CYCAPTION, FALSE, menubase.bpp);
	if (hdl->vram == NULL) {
		goto dbcre_err;
	}
	hdl->vram->posx = (MENU_FBORDER + MENU_BORDER);
	hdl->vram->posy = (MENU_FBORDER + MENU_BORDER);
	rct.left = 0;
	rct.top = 0;
	rct.bottom = MENUDLG_CYCAPTION;
	menuvram_caption(hdl->vram, &rct, MICON_NULL, (OEMCHAR *)arg);
	return(SUCCESS);

dbcre_err:
	(void)dlg;
	return(FAILURE);
}


static void dlgbase_paint(MENUDLG dlg, DLGHDL hdl) {

	OEMCHAR	*title;

	title = NULL;
	if (hdl->prm) {
		title = hdl->prm->str;
	}
	menuvram_base(dlg->vram);
	vrammix_cpy(dlg->vram, NULL, hdl->vram, NULL);
	menubase_setrect(dlg->vram, NULL);
}


static void dlgbase_onclick(MENUDLG dlg, DLGHDL hdl, int x, int y) {

	RECT_T	rct;

	vram_getrect(hdl->vram, &rct);
	dlg->dragflg = rect_in(&rct, x, y);
	dlg->lastx = x;
	dlg->lasty = y;
}


static void dlgbase_move(MENUDLG dlg, DLGHDL hdl, int x, int y, int focus) {

	if (dlg->dragflg) {
		x -= dlg->lastx;
		y -= dlg->lasty;
		if ((x) || (y)) {
			menubase_clrrect(dlg->vram);
			dlg->vram->posx += x;
			dlg->vram->posy += y;
			menubase_setrect(dlg->vram, NULL);
		}
	}
	(void)hdl;
	(void)focus;
}


// ---- close

static void dlgclose_paint(MENUDLG dlg, DLGHDL hdl) {

	menuvram_closebtn(dlg->vram, &hdl->rect, hdl->val);
}


static void dlgclose_onclick(MENUDLG dlg, DLGHDL hdl, int x, int y) {

	hdl->val = 1;
	drawctrls(dlg, hdl);
	(void)x;
	(void)y;
}


static void dlgclose_move(MENUDLG dlg, DLGHDL hdl, int x, int y, int focus) {

	if (hdl->val != focus) {
		hdl->val = focus;
		drawctrls(dlg, hdl);
	}
	(void)x;
	(void)y;
}


static void dlgclose_rel(MENUDLG dlg, DLGHDL hdl, int focus) {

	if (focus) {
		dlg->proc(DLGMSG_CLOSE, 0, 0);
	}
	(void)hdl;
}


// ---- button

static void dlgbtn_paint(MENUDLG dlg, DLGHDL hdl) {

	POINT_T	sz;
	POINT_T	pt;
	UINT	c;

	vram_filldat(dlg->vram, &hdl->rect, menucolor[MVC_BTNFACE]);
	if (!hdl->val) {
		c = MVC4(MVC_HILIGHT, MVC_DARK, MVC_LIGHT, MVC_SHADOW);
	}
	else {
		c = MVC4(MVC_DARK, MVC_DARK, MVC_SHADOW, MVC_SHADOW);
	}
	menuvram_box2(dlg->vram, &hdl->rect, c);

	if (gettextsz(hdl, &sz) == SUCCESS) {
		getmid(&pt, &hdl->rect, &sz);
		if (hdl->val) {
			pt.x += MENU_DSTEXT;
			pt.y += MENU_DSTEXT;
		}
		dlg_text(dlg, hdl, &pt, &hdl->rect);
	}
}


static void dlgbtn_onclick(MENUDLG dlg, DLGHDL hdl, int x, int y) {

	hdl->val = 1;
	drawctrls(dlg, hdl);
	(void)x;
	(void)y;
}

static void dlgbtn_move(MENUDLG dlg, DLGHDL hdl, int x, int y, int focus) {

	if (hdl->val != focus) {
		hdl->val = focus;
		drawctrls(dlg, hdl);
	}
	(void)x;
	(void)y;
}

static void dlgbtn_rel(MENUDLG dlg, DLGHDL hdl, int focus) {

	if (hdl->val != 0) {
		hdl->val = 0;
		drawctrls(dlg, hdl);
	}
	if (focus) {
		dlg->proc(DLGMSG_COMMAND, hdl->id, 0);
	}
}


// ---- list

static void *dlglist_setfont(DLGHDL hdl, void *font) {
										// 後でスクロールバーの調整をすべし
	void	*ret;
	POINT_T	pt;

	ret = hdl->c.dl.font;
	hdl->c.dl.font = font;
	fontmng_getsize(font, mstr_fontcheck, &pt);
	if ((pt.y <= 0) || (pt.y >= 65536)) {
		pt.y = 16;
	}
	hdl->c.dl.fontsize = (SINT16)pt.y;
	hdl->c.dl.dispmax = (SINT16)(hdl->vram->height / pt.y);
	return(ret);
}

static void dlglist_reset(MENUDLG dlg, DLGHDL hdl) {

	DLGPRM	dp;
	DLGPRM	next;

	vram_filldat(hdl->vram, NULL, 0xffffff);
	dp = hdl->prm;
	while(dp) {
		next = dp->next;
		dp->next = PRMNEXT_EMPTY;
		dp = next;
	}
	hdl->prm = NULL;
	hdl->prmcnt = 0;
	hdl->val = -1;
	hdl->c.dl.scrollbar = 0;
	hdl->c.dl.basepos = 0;
}

static BRESULT dlglist_create(MENUDLG dlg, DLGHDL hdl, const void *arg) {

	int		width;
	int		height;

	width = hdl->rect.right - hdl->rect.left - (MENU_LINE * 4);
	height = hdl->rect.bottom - hdl->rect.top - (MENU_LINE * 4);
	hdl->vram = vram_create(width, height, FALSE, menubase.bpp);
	if (hdl->vram == NULL) {
		goto dlcre_err;
	}
	hdl->vram->posx = hdl->rect.left + (MENU_LINE * 2);
	hdl->vram->posy = hdl->rect.top + (MENU_LINE * 2);
	dlglist_setfont(hdl, dlg->font);
	dlglist_reset(dlg, hdl);
	return(SUCCESS);

dlcre_err:
	(void)dlg;
	(void)arg;
	return(FAILURE);
}

static void dlglist_paint(MENUDLG dlg, DLGHDL hdl) {

	menuvram_box2(dlg->vram, &hdl->rect,
						MVC4(MVC_SHADOW, MVC_HILIGHT, MVC_DARK, MVC_LIGHT));
	vrammix_cpy(dlg->vram, NULL, hdl->vram, NULL);
}

static void dlglist_drawitem(DLGHDL hdl, DLGPRM prm, int focus,
												POINT_T *pt, RECT_T *rct) {

	VRAMHDL	icon;
	POINT_T	fp;

	vram_filldat(hdl->vram, rct, menucolor[focus?MVC_CURBACK:MVC_HILIGHT]);
	fp.x = pt->x;
	fp.y = pt->y;
	icon = prm->icon;
	if (icon) {
		if (icon->alpha) {
			vramcpy_cpyex(hdl->vram, &fp, icon, NULL);
		}
		else {
			vramcpy_cpy(hdl->vram, &fp, icon, NULL);
		}
		fp.x += icon->width;
#if defined(SIZE_QVGA)
		fp.x += 1;
#else
		fp.x += 2;
#endif
	}
	vrammix_text(hdl->vram, hdl->c.dl.font, prm->str,
							menucolor[focus?MVC_CURTEXT:MVC_TEXT], &fp, rct);
}

static BOOL dlglist_drawsub(DLGHDL hdl, int pos, int focus) {

	DLGPRM	prm;
	POINT_T	pt;
	RECT_T	rct;

	prm = ressea(hdl, pos);
	if (prm == NULL) {
		return(FALSE);
	}
	pos -= hdl->c.dl.basepos;
	if (pos < 0) {
		return(FALSE);
	}
	pt.x = 0;
	pt.y = pos * hdl->c.dl.fontsize;
	if (pt.y >= hdl->vram->height) {
		return(FALSE);
	}
	rct.left = 0;
	rct.top = pt.y;
	rct.right = hdl->vram->width;
	if (hdl->prmcnt > hdl->c.dl.dispmax) {
		rct.right -= MENUDLG_CXVSCR;
	}
	rct.bottom = rct.top + hdl->c.dl.fontsize;
	dlglist_drawitem(hdl, prm, focus, &pt, &rct);
	return(TRUE);
}

static void dlglist_setbtn(DLGHDL hdl, int flg) {

	RECT_T		rct;
	POINT_T		pt;
	UINT		mvc4;
const MENURES2	*res;

	res = menures_scrbtn;
	rct.right = hdl->vram->width;
	rct.left = rct.right - MENUDLG_CXVSCR;
	if (!(flg & 2)) {
		rct.top = 0;
	}
	else {
		rct.top = hdl->vram->height - MENUDLG_CYVSCR;
		if (rct.top < MENUDLG_CYVSCR) {
			rct.top = MENUDLG_CYVSCR;
		}
		res++;
	}
	rct.bottom = rct.top + MENUDLG_CYVSCR;

	vram_filldat(hdl->vram, &rct, menucolor[MVC_BTNFACE]);
	if (flg & 1) {
		mvc4 = MVC4(MVC_SHADOW, MVC_SHADOW, MVC_LIGHT, MVC_LIGHT);
	}
	else {
		mvc4 = MVC4(MVC_LIGHT, MVC_DARK, MVC_HILIGHT, MVC_SHADOW);
	}
	menuvram_box2(hdl->vram, &rct, mvc4);
	pt.x = rct.left + (MENU_LINE * 2);
	pt.y = rct.top + (MENU_LINE * 2);
	if (flg & 1) {
		pt.x += MENU_DSTEXT;
		pt.y += MENU_DSTEXT;
	}
	menuvram_res3put(hdl->vram, res, &pt, MVC_TEXT);
}

static void dlglist_drawall(DLGHDL hdl) {

	DLGPRM	prm;
	POINT_T	pt;
	RECT_T	rct;
	int		pos;

	rct.left = 0;
	rct.top = 0 - (hdl->c.dl.basepos * hdl->c.dl.fontsize);
	rct.right = hdl->vram->width;
	if (hdl->prmcnt > hdl->c.dl.dispmax) {
		rct.right -= MENUDLG_CXVSCR;
	}

	prm = hdl->prm;
	pos = 0;
	while(prm) {
		if (rct.top >= hdl->vram->height) {
			break;
		}
		if (rct.top >= 0) {
			rct.bottom = rct.top + hdl->c.dl.fontsize;
			pt.x = 0;
			pt.y = rct.top;
			dlglist_drawitem(hdl, prm, (pos == hdl->val), &pt, &rct);
		}
		prm = prm->next;
		pos++;
		rct.top += hdl->c.dl.fontsize;
	}
	rct.bottom = hdl->vram->height;
	vram_filldat(hdl->vram, &rct, menucolor[MVC_HILIGHT]);
}

static int dlglist_barpos(DLGHDL hdl) {

	int		ret;

	ret = hdl->vram->height - (MENUDLG_CYVSCR * 2);
	ret -= hdl->c.dl.scrollbar;
	ret *= hdl->c.dl.basepos;
	ret /= (hdl->prmcnt - hdl->c.dl.dispmax);
	return(ret);
}

static void dlglist_drawbar(DLGHDL hdl) {

	RECT_T	rct;

	rct.right = hdl->vram->width;
	rct.left = rct.right - MENUDLG_CXVSCR;
	rct.top = MENUDLG_CYVSCR;
	rct.bottom = hdl->vram->height - MENUDLG_CYVSCR;
	vram_filldat(hdl->vram, &rct, menucolor[MVC_SCROLLBAR]);

	rct.top += dlglist_barpos(hdl);
	rct.bottom = rct.top + hdl->c.dl.scrollbar;
	vram_filldat(hdl->vram, &rct, menucolor[MVC_BTNFACE]);
	menuvram_box2(hdl->vram, &rct,
						MVC4(MVC_LIGHT, MVC_DARK, MVC_HILIGHT, MVC_SHADOW));
}

static BOOL dlglist_append(MENUDLG dlg, DLGHDL hdl, const void *arg) {

	BOOL	r;
	DLGPRM	*sto;
	int		barsize;

	r = FALSE;
	sto = &hdl->prm;
	while(*sto) {
		sto = &((*sto)->next);
	}
	*sto = resappend(dlg, (OEMCHAR *)arg);
	if (*sto) {
		r = dlglist_drawsub(hdl, hdl->prmcnt, FALSE);
		hdl->prmcnt++;
		if (hdl->prmcnt > hdl->c.dl.dispmax) {
			barsize = hdl->vram->height - (MENUDLG_CYVSCR * 2);
			if (barsize >= 8) {
				barsize *= hdl->c.dl.dispmax;
				barsize /= hdl->prmcnt;
				barsize = max(barsize, 6);
				if (!hdl->c.dl.scrollbar) {
					dlglist_drawall(hdl);
					dlglist_setbtn(hdl, 0);
					dlglist_setbtn(hdl, 2);
				}
				hdl->c.dl.scrollbar = barsize;
				dlglist_drawbar(hdl);
			}
		}
	}
	return(r);
}

static BOOL dlglist_setex(MENUDLG dlg, DLGHDL hdl, const ITEMEXPRM *arg) {

	DLGPRM	dp;
	UINT	cnt;

	if ((arg == NULL) || (arg->pos >= hdl->prmcnt)) {
		return(FALSE);
	}
	cnt = arg->pos;
	dp = hdl->prm;
	while((cnt) && (dp)) {
		cnt--;
		dp = dp->next;
	}
	if (dp == NULL) {
		return(FALSE);
	}
	resattachicon(dlg, dp, arg->icon, hdl->c.dl.fontsize,
											hdl->c.dl.fontsize);
	milstr_ncpy(dp->str, arg->str, NELEMENTS(dp->str));
	return(dlglist_drawsub(hdl, arg->pos, (arg->pos == hdl->val)));
}

static int dlglist_getpos(DLGHDL hdl, int y) {

	int		val;

	val = (y / hdl->c.dl.fontsize) + hdl->c.dl.basepos;
	if ((unsigned int)val < (unsigned int)hdl->prmcnt) {
		return(val);
	}
	else {
		return(-1);
	}
}

enum {
	DLCUR_OUT		= -1,
	DLCUR_INLIST	= 0,
	DLCUR_UP		= 1,
	DLCUR_INBAR		= 2,
	DLCUR_DOWN		= 3,
	DLCUR_PGUP		= 4,
	DLCUR_PGDN		= 5,
	DLCUR_INCUR		= 6
};

static int dlglist_getpc(DLGHDL hdl, int x, int y) {

	if ((unsigned int)x >= (unsigned int)hdl->vram->width) {
		goto dlgp_out;
	}
	if ((unsigned int)y >= (unsigned int)hdl->vram->height) {
		goto dlgp_out;
	}

	if ((hdl->prmcnt < hdl->c.dl.dispmax) ||
		(x < (hdl->vram->width - MENUDLG_CXVSCR))) {
		return(DLCUR_INLIST);
	}
	else if (y < MENUDLG_CYVSCR) {
		return(DLCUR_UP);
	}
	else if (y >= (hdl->vram->height - MENUDLG_CYVSCR)) {
		return(DLCUR_DOWN);
	}
	y -= MENUDLG_CYVSCR;
	y -= dlglist_barpos(hdl);
	if (y < 0) {
		return(DLCUR_PGUP);
	}
	else if (y < (int)hdl->c.dl.scrollbar) {
		return(DLCUR_INBAR);
	}
	else {
		return(DLCUR_PGDN);
	}

dlgp_out:
	return(DLCUR_OUT);
}

static void dlglist_setval(MENUDLG dlg, DLGHDL hdl, int val) {

	BOOL	r;

	if ((unsigned int)val >= (unsigned int)hdl->prmcnt) {
		val = -1;
	}
	if (val != hdl->val) {
		r = dlglist_drawsub(hdl, hdl->val, FALSE);
		r |= dlglist_drawsub(hdl, val, TRUE);
		hdl->val = val;
		if (r) {
			drawctrls(dlg, hdl);
		}
	}
}

static void dlglist_setbasepos(MENUDLG dlg, DLGHDL hdl, int pos) {

	int		displimit;

	if (pos < 0) {
		pos = 0;
	}
	else {
		displimit = hdl->prmcnt - hdl->c.dl.dispmax;
		if (displimit < 0) {
			displimit = 0;
		}
		if (pos > displimit) {
			pos = displimit;
		}
	}
	if (hdl->c.dl.basepos != pos) {
		hdl->c.dl.basepos = pos;
		dlglist_drawall(hdl);
		dlglist_drawbar(hdl);
	}
	(void)dlg;
}

static void dlglist_onclick(MENUDLG dlg, DLGHDL hdl, int x, int y) {

	int		flg;
	int		val;

	x -= (MENU_LINE * 2);
	y -= (MENU_LINE * 2);
	flg = dlglist_getpc(hdl, x, y);
	dlg->dragflg = flg;
	switch(flg) {
		case DLCUR_INLIST:
			val = dlglist_getpos(hdl, y);
			if ((val == hdl->val) && (val != -1)) {
				dlg->dragflg = DLCUR_INCUR;
			}
			dlglist_setval(dlg, hdl, val);
			dlg->proc(DLGMSG_COMMAND, hdl->id, 0);
			break;

		case 1:
		case 3:
			dlglist_setbtn(hdl, flg);
			dlglist_setbasepos(dlg, hdl, hdl->c.dl.basepos + flg - 2);
			drawctrls(dlg, hdl);
			break;

		case DLCUR_INBAR:
			y -= MENUDLG_CYVSCR;
			y -= dlglist_barpos(hdl);
			if ((unsigned int)y < (unsigned int)hdl->c.dl.scrollbar) {
				dlg->lasty = y;
			}
			else {
				dlg->lasty = -1;
			}
			break;

		case DLCUR_PGUP:
			dlglist_setbasepos(dlg, hdl, hdl->c.dl.basepos
														- hdl->c.dl.dispmax);
			drawctrls(dlg, hdl);
			break;

		case DLCUR_PGDN:
			dlglist_setbasepos(dlg, hdl, hdl->c.dl.basepos
														+ hdl->c.dl.dispmax);
			drawctrls(dlg, hdl);
			break;
	}
}

static void dlglist_move(MENUDLG dlg, DLGHDL hdl, int x, int y, int focus) {

	int		flg;
	int		val;
	int		height;

	x -= (MENU_LINE * 2);
	y -= (MENU_LINE * 2);
	flg = dlglist_getpc(hdl, x, y);
	switch(dlg->dragflg) {
		case DLCUR_INLIST:
		case DLCUR_INCUR:
			if (flg == DLCUR_INLIST) {
				val = dlglist_getpos(hdl, y);
				if (val != hdl->val) {
					dlg->dragflg = DLCUR_INLIST;
					dlglist_setval(dlg, hdl, val);
					dlg->proc(DLGMSG_COMMAND, hdl->id, 0);
				}
			}
			break;

		case 1:
		case 3:
			dlglist_setbtn(hdl, dlg->dragflg - ((dlg->dragflg == flg)?0:1));
			drawctrls(dlg, hdl);
			break;

		case DLCUR_INBAR:
			if (dlg->lasty >= 0) {
				y -= MENUDLG_CYVSCR;
				y -= dlg->lasty;
				height = hdl->vram->height - (MENUDLG_CYVSCR * 2);
				height -= hdl->c.dl.scrollbar;
				if (y < 0) {
					y = 0;
				}
				else if (y > height) {
					y = height;
				}
				y *= (hdl->prmcnt - hdl->c.dl.dispmax);
				y /= height;
				dlglist_setbasepos(dlg, hdl, y);
				drawctrls(dlg, hdl);
			}
			break;
	}
	(void)focus;
}

static void dlglist_rel(MENUDLG dlg, DLGHDL hdl, int focus) {

	switch(dlg->dragflg) {
		case 1:
		case 3:
			dlglist_setbtn(hdl, dlg->dragflg - 1);
			drawctrls(dlg, hdl);
			break;

		case DLCUR_INCUR:
			dlg->proc(DLGMSG_COMMAND, hdl->id, 1);
			break;
	}
	(void)focus;
}


// ---- slider

static void dlgslider_setflag(DLGHDL hdl) {

	int		size;
	UINT	type;

	if (!(hdl->flag & MSS_VERT)) {
		size = hdl->rect.bottom - hdl->rect.top;
	}
	else {
		size = hdl->rect.right - hdl->rect.left;
	}
	if (size < 13) {
		type = 0 + (9 << 8) + (5 << 16);
	}
	else if (size < 21) {
		type = 1 + (13 << 8) + (7 << 16);
	}
	else {
		type = 2 + (21 << 8) + (11 << 16);
	}
	hdl->c.ds.type = (UINT8)type;
	if (!(hdl->flag & MSS_VERT)) {
		hdl->c.ds.sldh = (UINT8)(type >> 16);
		hdl->c.ds.sldv = (UINT8)(type >> 8);
	}
	else {
		hdl->c.ds.sldh = (UINT8)(type >> 8);
		hdl->c.ds.sldv = (UINT8)(type >> 16);
	}
}

static int dlgslider_setpos(DLGHDL hdl, int val) {

	int		range;
	int		width;
	int		dir;

	range = hdl->c.ds.maxval - hdl->c.ds.minval;
	if (range) {
		dir = (range > 0)?1:-1;
		val -= hdl->c.ds.minval;
		val *= dir;
		range *= dir;
		if (val < 0) {
			val = 0;
		}
		else if (val >= range) {
			val = range;
		}
		hdl->val = hdl->c.ds.minval + (val * dir);
		if (!(hdl->flag & MSS_VERT)) {
			width = hdl->rect.right - hdl->rect.left;
			width -= hdl->c.ds.sldh;
		}
		else {
			width = hdl->rect.bottom - hdl->rect.top;
			width -= hdl->c.ds.sldv;
		}
		if ((width > 0) || (range)) {
			val *= width;
			val /= range;
		}
		else {
			val = 0;
		}
	}
	else {
		val = 0;
	}
	return(val);
}

static BRESULT dlgslider_create(MENUDLG dlg, DLGHDL hdl, const void *arg) {

	hdl->c.ds.minval = (SINT16)(long)arg;
	hdl->c.ds.maxval = (SINT16)((long)arg >> 16);
	hdl->c.ds.moving = 0;
	dlgslider_setflag(hdl);
	hdl->c.ds.pos = dlgslider_setpos(hdl, 0);
	(void)dlg;
	return(SUCCESS);
}

static void dlgslider_paint(MENUDLG dlg, DLGHDL hdl) {

	UINT		flag;
	int			ptr;
	RECT_U		rct;
	POINT_T		pt;
	MENURES2	src;

	flag = hdl->flag;
	switch(flag & MSS_POSMASK) {
		case MSS_BOTH:
			ptr = 1;
			break;
		case MSS_TOP:
			ptr = 2;
			break;
		default:
			ptr = 0;
			break;
	}
	vram_filldat(dlg->vram, &hdl->rect, menucolor[MVC_STATIC]);
	if (!(hdl->flag & MSS_VERT)) {
		rct.r.left = hdl->rect.left;
		rct.r.right = hdl->rect.right;
		rct.r.top = hdl->rect.top + ptr +
									(hdl->c.ds.sldv / 2) - (MENU_LINE * 2);
		rct.r.bottom = rct.r.top + (MENU_LINE * 4);
		menuvram_box2(dlg->vram, &rct.r,
						MVC4(MVC_SHADOW, MVC_HILIGHT, MVC_DARK, MVC_LIGHT));
		pt.x = hdl->rect.left + hdl->c.ds.pos;
		pt.y = hdl->rect.top;
	}
	else {
		rct.r.left = hdl->rect.left + ptr +
									(hdl->c.ds.sldh / 2) - (MENU_LINE * 2);
		rct.r.right = rct.r.left + (MENU_LINE * 4);
		rct.r.top = hdl->rect.top;
		rct.r.bottom = hdl->rect.bottom;
		menuvram_box2(dlg->vram, &rct.r,
						MVC4(MVC_SHADOW, MVC_HILIGHT, MVC_DARK, MVC_LIGHT));
		pt.x = hdl->rect.left;
		pt.y = hdl->rect.top + hdl->c.ds.pos;
		ptr += 3;
	}
	ptr *= 2;
	if ((hdl->flag & MENU_GRAY) || (hdl->c.ds.moving)) {
		ptr++;
	}
	src.width = hdl->c.ds.sldh;
	src.height = hdl->c.ds.sldv;
	src.pat = menures_slddat + menures_sldpos[hdl->c.ds.type][ptr];
	menuvram_res2put(dlg->vram, &src, &pt);
}

static void dlgslider_setval(MENUDLG dlg, DLGHDL hdl, int val) {

	int		pos;

	pos = dlgslider_setpos(hdl, val);
	if (hdl->c.ds.pos != pos) {
		hdl->c.ds.pos = pos;
		drawctrls(dlg, hdl);
	}
}

static void dlgslider_onclick(MENUDLG dlg, DLGHDL hdl, int x, int y) {

	int		width;
	int		range;
	int		dir;

	if (!(hdl->flag & MSS_VERT)) {
		width = hdl->c.ds.sldh;
	}
	else {
		width = hdl->c.ds.sldv;
		x = y;
	}
	x -= hdl->c.ds.pos;
	if ((x >= -1) && (x <= width)) {
		dlg->dragflg = x;
		hdl->c.ds.moving = 1;
		drawctrls(dlg, hdl);
	}
	else {
		dlg->dragflg = -1;
		dir = (x > 0)?1:0;
		range = hdl->c.ds.maxval - hdl->c.ds.minval;
		if (range < 0) {
			range = 0 - range;
			dir ^= 1;
		}
		if (range < 16) {
			range = 16;
		}
		range >>= 4;
		if (!dir) {
			range = 0 - range;
		}
		dlgslider_setval(dlg, hdl, hdl->val + range);
		dlg->proc(DLGMSG_COMMAND, hdl->id, 0);
	}
}

static void dlgslider_move(MENUDLG dlg, DLGHDL hdl, int x, int y, int focus) {

	int		range;
	int		width;
	int		dir;

	if (hdl->c.ds.moving) {
		range = hdl->c.ds.maxval - hdl->c.ds.minval;
		if (range) {
			dir = (range > 0)?1:-1;
			range *= dir;
			if (!(hdl->flag & MSS_VERT)) {
				width = hdl->rect.right - hdl->rect.left;
				width -= hdl->c.ds.sldh;
			}
			else {
				width = hdl->rect.bottom - hdl->rect.top;
				width -= hdl->c.ds.sldv;
				x = y;
			}
			x -= dlg->dragflg;
			if ((x < 0) || (width <= 0)) {
				x = 0;
			}
			else if (x >= width) {
				x = range;
			}
			else {
				x *= range;
				x += (width >> 1);
				x /= width;
			}
			x = hdl->c.ds.minval + (x * dir);
			dlgslider_setval(dlg, hdl, x);
			dlg->proc(DLGMSG_COMMAND, hdl->id, 0);
		}
	}
	(void)focus;
}


static void dlgslider_rel(MENUDLG dlg, DLGHDL hdl, int focus) {

	if (hdl->c.ds.moving) {
		hdl->c.ds.moving = 0;
		drawctrls(dlg, hdl);
	}
	(void)focus;
}


// ---- tablist

static void *dlgtablist_setfont(DLGHDL hdl, void *font) {

	void	*ret;
	POINT_T	pt;
	DLGPRM	prm;

	ret = hdl->c.dtl.font;
	hdl->c.dtl.font = font;
	fontmng_getsize(font, mstr_fontcheck, &pt);
	if ((pt.y <= 0) || (pt.y >= 65536)) {
		pt.y = 16;
	}
	hdl->c.dtl.fontsize = pt.y;
	prm = hdl->prm;
	while(prm) {
		fontmng_getsize(hdl->c.dtl.font, prm->str, &pt);
		prm->width = pt.x;
		prm = prm->next;
	}
	return(ret);
}

static BRESULT dlgtablist_create(MENUDLG dlg, DLGHDL hdl, const void *arg) {

	RECT_T	rct;

	rct.right = hdl->rect.right - hdl->rect.left;
	hdl->val = -1;
	dlgtablist_setfont(hdl, dlg->font);
	(void)arg;
	return(SUCCESS);
}

static void dlgtablist_paint(MENUDLG dlg, DLGHDL hdl) {

	VRAMHDL	dst;
	DLGPRM	prm;
	POINT_T	pt;
	RECT_T	rct;
	int		posx;
	int		lx;
	int		cnt;
	int		tabey;
	int		tabdy;

	dst = dlg->vram;
	rct = hdl->rect;
	vram_filldat(dst, &rct, menucolor[MVC_STATIC]);
	tabey = rct.top + hdl->c.dtl.fontsize +
							MENUDLG_SYTAB + MENUDLG_TYTAB + MENUDLG_EYTAB;
	rct.top = tabey;
	menuvram_box2(dst, &rct,
						MVC4(MVC_HILIGHT, MVC_DARK, MVC_LIGHT, MVC_SHADOW));

	posx = hdl->rect.left + (MENU_LINE * 2);
	prm = hdl->prm;
	cnt = hdl->val;
	while(prm) {
		if (cnt) {
			pt.x = posx;
			pt.y = hdl->rect.top + MENUDLG_SYTAB;
			menuvram_liney(dst, pt.x, pt.y + (MENU_LINE * 2),
														tabey, MVC_HILIGHT);
			pt.x += MENU_LINE;
			menuvram_liney(dst, pt.x, pt.y + MENU_LINE,
										pt.y + (MENU_LINE * 2), MVC_HILIGHT);
			menuvram_liney(dst, pt.x, pt.y + (MENU_LINE * 2),
														tabey, MVC_LIGHT);
			pt.x += MENU_LINE;
			lx = pt.x + prm->width + (MENUDLG_TXTAB * 2);
			menuvram_linex(dst, pt.x, pt.y, lx, MVC_HILIGHT);
			menuvram_linex(dst, pt.x, pt.y + MENU_LINE, lx, MVC_LIGHT);

			menuvram_liney(dst, lx, pt.y + MENU_LINE,
										pt.y + (MENU_LINE * 2), MVC_DARK);
			menuvram_liney(dst, lx, pt.y + (MENU_LINE * 2),
														tabey, MVC_SHADOW);
			lx++;
			menuvram_liney(dst, lx, pt.y + (MENU_LINE * 2),
														tabey, MVC_DARK);
			pt.x += MENUDLG_TXTAB;
			pt.y += MENUDLG_TYTAB;
			vrammix_text(dst, hdl->c.dtl.font, prm->str,
											menucolor[MVC_TEXT], &pt, NULL);
		}
		cnt--;
		posx += prm->width + (MENU_LINE * 4) + (MENUDLG_TXTAB) * 2;
		prm = prm->next;
	}

	posx = hdl->rect.left;
	prm = hdl->prm;
	cnt = hdl->val;
	while(prm) {
		if (!cnt) {
			pt.x = posx;
			pt.y = hdl->rect.top;
			if (posx == hdl->rect.left) {
				tabdy = tabey + 2;
			}
			else {
				tabdy = tabey + 1;
				menuvram_linex(dst, pt.x, tabdy,
										pt.x + (MENU_LINE * 2), MVC_STATIC);
			}
			menuvram_liney(dst, pt.x, pt.y + (MENU_LINE * 2),
														tabdy, MVC_HILIGHT);
			pt.x += MENU_LINE;
			menuvram_liney(dst, pt.x, pt.y + MENU_LINE,
										pt.y + (MENU_LINE * 2), MVC_HILIGHT);
			menuvram_liney(dst, pt.x, pt.y + (MENU_LINE * 2),
														tabdy, MVC_LIGHT);
			pt.x += MENU_LINE;
			lx = pt.x + prm->width + (MENU_LINE * 4) + (MENUDLG_TXTAB * 2);
			menuvram_linex(dst, pt.x, pt.y, lx, MVC_HILIGHT);
			menuvram_linex(dst, pt.x, pt.y + MENU_LINE, lx, MVC_LIGHT);
			menuvram_linex(dst, pt.x, tabey, lx, MVC_STATIC);
			menuvram_linex(dst, pt.x, tabey + MENU_LINE, lx, MVC_STATIC);
			tabdy = tabey + 1;
			menuvram_liney(dst, lx, pt.y + MENU_LINE,
										pt.y + (MENU_LINE * 2), MVC_DARK);
			menuvram_liney(dst, lx, pt.y + (MENU_LINE * 2),
														tabdy, MVC_SHADOW);
			lx++;
			menuvram_liney(dst, lx, pt.y + (MENU_LINE * 2),
														tabdy, MVC_DARK);
			pt.x += MENUDLG_TXTAB + (MENU_LINE * 2);
			pt.y += MENUDLG_TYTAB;
			vrammix_text(dst, hdl->c.dtl.font, prm->str,
											menucolor[MVC_TEXT], &pt, NULL);
			break;
		}
		cnt--;
		posx += prm->width + (MENU_LINE * 4) + (MENUDLG_TXTAB * 2);
		prm = prm->next;
	}
}

static void dlgtablist_setval(MENUDLG dlg, DLGHDL hdl, int val) {

	if (hdl->val != val) {
		hdl->val = val;
		drawctrls(dlg, hdl);
	}
}

static void dlgtablist_append(MENUDLG dlg, DLGHDL hdl, const void *arg) {

	DLGPRM	res;
	DLGPRM	*sto;
	POINT_T	pt;

	sto = &hdl->prm;
	while(*sto) {
		sto = &((*sto)->next);
	}
	res = resappend(dlg, (OEMCHAR *)arg);
	if (res) {
		*sto = res;
		fontmng_getsize(hdl->c.dtl.font, (OEMCHAR *)arg, &pt);
		res->width = pt.x;
		hdl->prmcnt++;
	}
}

static void dlgtablist_onclick(MENUDLG dlg, DLGHDL hdl, int x, int y) {

	DLGPRM	prm;
	int		pos;

	if (y < (hdl->c.dtl.fontsize +
							MENUDLG_SYTAB + MENUDLG_TYTAB + MENUDLG_EYTAB)) {
		pos = 0;
		prm = hdl->prm;
		while(prm) {
			x -= (MENU_LINE * 4);
			if (x < 0) {
				break;
			}
			x -= prm->width + (MENUDLG_TXTAB * 2);
			if (x < 0) {
				dlgtablist_setval(dlg, hdl, pos);
				dlg->proc(DLGMSG_COMMAND, hdl->id, 0);
				break;
			}
			pos++;
			prm = prm->next;
		}
	}
}


// ---- edit

static void dlgedit_paint(MENUDLG dlg, DLGHDL hdl) {

	RECT_T		rct;
	POINT_T		pt;
const OEMCHAR	*string;

	rct = hdl->rect;
	menuvram_box2(dlg->vram, &rct,
						MVC4(MVC_SHADOW, MVC_HILIGHT, MVC_DARK, MVC_LIGHT));
	rct.left += (MENU_LINE * 2);
	rct.top += (MENU_LINE * 2);
	rct.right -= (MENU_LINE * 2);
	rct.bottom -= (MENU_LINE * 2);
	vram_filldat(dlg->vram, &rct, menucolor[
							(hdl->flag & MENU_GRAY)?MVC_STATIC:MVC_HILIGHT]);
	if (hdl->prm == NULL) {
		goto dged_exit;
	}
	string = hdl->prm->str;
	if (string == NULL) {
		goto dged_exit;
	}
	pt.x = rct.left + MENU_LINE;
	pt.y = rct.top + MENU_LINE;
	vrammix_text(dlg->vram, hdl->c.dt.font, string,
											menucolor[MVC_TEXT], &pt, &rct);

dged_exit:
	return;
}


// ---- frame

static void dlgframe_paint(MENUDLG dlg, DLGHDL hdl) {

	RECT_T		rct;
	POINT_T		pt;

	rct.left = hdl->rect.left;
	rct.top = hdl->rect.top + MENUDLG_SYFRAME;
	rct.right = hdl->rect.right;
	rct.bottom = hdl->rect.bottom;
	menuvram_box2(dlg->vram, &rct,
					MVC4(MVC_SHADOW, MVC_HILIGHT, MVC_HILIGHT, MVC_SHADOW));
	rct.left += MENUDLG_SXFRAME;
	rct.top = hdl->rect.top;
	rct.right = rct.left + (MENUDLG_PXFRAME * 2) + hdl->c.dt.pt.x;
	rct.bottom = rct.top + hdl->c.dt.pt.y + MENU_DSTEXT;
	vram_filldat(dlg->vram, &rct, menucolor[MVC_STATIC]);
	if (hdl->prm) {
		pt.x = rct.left + MENUDLG_PXFRAME;
		pt.y = rct.top;
		dlg_text(dlg, hdl, &pt, &rct);
	}
}


// ---- radio

typedef struct {
	MENUDLG	dlg;
	MENUID	group;
} MDCB1;

static void dlgradio_paint(MENUDLG dlg, DLGHDL hdl) {

	POINT_T		pt;
const MENURES2	*src;
	int			pat;

	vram_filldat(dlg->vram, &hdl->rect, menucolor[MVC_STATIC]);
	pt.x = hdl->rect.left;
	pt.y = hdl->rect.top;
	src = menures_radio;
	pat = (hdl->flag & MENU_GRAY)?1:0;
	menuvram_res2put(dlg->vram, src + pat, &pt);
	if (hdl->val) {
		menuvram_res3put(dlg->vram, src + 2, &pt,
					(hdl->flag & MENU_GRAY)?MVC_GRAYTEXT1:MVC_TEXT);
	}
	pt.x += MENUDLG_SXRADIO;
	dlg_text(dlg, hdl, &pt, &hdl->rect);
}

static BOOL drsv_cb(void *vpItem, void *vpArg) {

	DLGHDL	item;

	item = (DLGHDL)vpItem;
	if ((item->type == DLGTYPE_RADIO) && (item->val) &&
		(item->group == ((MDCB1 *)vpArg)->group)) {
		item->val = 0;
		drawctrls(((MDCB1 *)vpArg)->dlg, item);
	}
	return(FALSE);
}

static void dlgradio_setval(MENUDLG dlg, DLGHDL hdl, int val) {

	MDCB1	mdcb;

	if (hdl->val != val) {
		if (val) {
			mdcb.dlg = dlg;
			mdcb.group = hdl->group;
			listarray_enum(dlg->dlg, drsv_cb, &mdcb);
		}
		hdl->val = val;
		drawctrls(dlg, hdl);
	}
}

static void dlgradio_onclick(MENUDLG dlg, DLGHDL hdl, int x, int y) {

	if (x < (hdl->c.dt.pt.x + MENUDLG_SXRADIO)) {
		dlgradio_setval(dlg, hdl, 1);
		dlg->proc(DLGMSG_COMMAND, hdl->id, 0);
	}
	(void)y;
}


// ---- check

static void dlgcheck_paint(MENUDLG dlg, DLGHDL hdl) {

	POINT_T	pt;
	RECT_T	rct;
	UINT32	basecol;
	UINT32	txtcol;

	vram_filldat(dlg->vram, &hdl->rect, menucolor[MVC_STATIC]);
	rct.left = hdl->rect.left;
	rct.top = hdl->rect.top;
	rct.right = rct.left + MENUDLG_CXCHECK;
	rct.bottom = rct.top + MENUDLG_CYCHECK;
	if (!(hdl->flag & MENU_GRAY)) {
		basecol = MVC_HILIGHT;
		txtcol = MVC_TEXT;
	}
	else {
		basecol = MVC_STATIC;
		txtcol = MVC_GRAYTEXT1;
	}
	vram_filldat(dlg->vram, &rct, menucolor[basecol]);
	menuvram_box2(dlg->vram, &rct,
						MVC4(MVC_SHADOW, MVC_HILIGHT, MVC_DARK, MVC_LIGHT));
	if (hdl->val) {
		pt.x = rct.left + (MENU_LINE * 2);
		pt.y = rct.top + (MENU_LINE * 2);
		menuvram_res3put(dlg->vram, &menures_check, &pt, txtcol);
	}
	pt.x = rct.left + MENUDLG_SXCHECK;
	pt.y = rct.top;
	dlg_text(dlg, hdl, &pt, &hdl->rect);
}

static void dlgcheck_setval(MENUDLG dlg, DLGHDL hdl, int val) {

	if (hdl->val != val) {
		hdl->val = val;
		drawctrls(dlg, hdl);
	}
}

static void dlgcheck_onclick(MENUDLG dlg, DLGHDL hdl, int x, int y) {

	if (x < (hdl->c.dt.pt.x + MENUDLG_SXCHECK)) {
		dlgcheck_setval(dlg, hdl, !hdl->val);
		dlg->proc(DLGMSG_COMMAND, hdl->id, 0);
	}
	(void)y;
}


// ---- text

static void dlgtext_paint(MENUDLG dlg, DLGHDL hdl) {

	POINT_T	sz;
	POINT_T	pt;
	void	(*getpt)(POINT_T *pt, const RECT_T *rect, const POINT_T *sz);

	vram_filldat(dlg->vram, &hdl->rect, menucolor[MVC_STATIC]);
	if (gettextsz(hdl, &sz) == SUCCESS) {
		switch(hdl->flag & MST_POSMASK) {
			case MST_LEFT:
			default:
				getpt = getleft;
				break;

			case MST_CENTER:
				getpt = getcenter;
				break;

			case MST_RIGHT:
				getpt = getright;
				break;
		}
		getpt(&pt, &hdl->rect, &sz);
		dlg_text(dlg, hdl, &pt, &hdl->rect);
	}
}

static void dlgtext_itemset(MENUDLG dlg, DLGHDL hdl, const void *arg) {

const OEMCHAR	*str;

	if (hdl->prm) {
		str = (OEMCHAR *)arg;
		if (str == NULL) {
			str = str_null;
		}
		milstr_ncpy(hdl->prm->str, str, NELEMENTS(hdl->prm->str));
		fontmng_getsize(hdl->c.dt.font, str, &hdl->c.dt.pt);
	}
	(void)dlg;
}

static void dlgtext_iconset(MENUDLG dlg, DLGHDL hdl, const void *arg) {

	if (hdl->prm) {
		resattachicon(dlg, hdl->prm, (UINT16)(long)arg,
											hdl->c.dt.pt.y, hdl->c.dt.pt.y);
	}
	(void)dlg;
}


// ---- icon/vram

static void iconpaint(MENUDLG dlg, DLGHDL hdl, VRAMHDL src) {

	RECT_U		r;
	UINT32		bgcol;

	r.p.x = hdl->rect.left;
	r.p.y = hdl->rect.top;
	bgcol = menucolor[MVC_STATIC];
	if (src) {
		if (src->alpha) {
			r.r.right = r.r.left + src->width;
			r.r.bottom = r.r.top + src->height;
			vram_filldat(dlg->vram, &r.r, bgcol);
			vramcpy_cpyex(dlg->vram, &r.p, src, NULL);
		}
		else {
			vramcpy_cpy(dlg->vram, &r.p, src, NULL);
		}
	}
	else {
		vram_filldat(dlg->vram, &hdl->rect, bgcol);
	}
}

static BRESULT dlgicon_create(MENUDLG dlg, DLGHDL hdl, const void *arg) {

	hdl->prm = resappend(dlg, NULL);
	resattachicon(dlg, hdl->prm, (UINT16)(long)arg,
		hdl->rect.right - hdl->rect.left, hdl->rect.bottom - hdl->rect.top);
	return(SUCCESS);
}

static void dlgicon_paint(MENUDLG dlg, DLGHDL hdl) {

	DLGPRM	prm;

	prm = hdl->prm;
	if (prm) {
		iconpaint(dlg, hdl, prm->icon);
	}
}

static BRESULT dlgvram_create(MENUDLG dlg, DLGHDL hdl, const void *arg) {

	hdl->c.dv.vram = (VRAMHDL)arg;
	(void)dlg;
	return(SUCCESS);
}

static void dlgvram_paint(MENUDLG dlg, DLGHDL hdl) {

	iconpaint(dlg, hdl, hdl->c.dv.vram);
}


// ---- line

static void dlgline_paint(MENUDLG dlg, DLGHDL hdl) {

	if (!(hdl->flag & MSL_VERT)) {
		menuvram_linex(dlg->vram, hdl->rect.left, hdl->rect.top,
											hdl->rect.right, MVC_SHADOW);
		menuvram_linex(dlg->vram, hdl->rect.left, hdl->rect.top + MENU_LINE,
											hdl->rect.right, MVC_HILIGHT);
	}
	else {
		menuvram_liney(dlg->vram, hdl->rect.left, hdl->rect.top,
											hdl->rect.bottom, MVC_SHADOW);
		menuvram_liney(dlg->vram, hdl->rect.left+MENU_LINE, hdl->rect.top,
											hdl->rect.bottom, MVC_HILIGHT);
	}
}


// ---- box

static void dlgbox_paint(MENUDLG dlg, DLGHDL hdl) {

	menuvram_box2(dlg->vram, &hdl->rect,
					MVC4(MVC_SHADOW, MVC_HILIGHT, MVC_HILIGHT, MVC_SHADOW));
}


// ---- procs

static BRESULT _cre(MENUDLG dlg, DLGHDL hdl, const void *arg) {

	(void)dlg;
	(void)hdl;
	(void)arg;
	return(SUCCESS);
}

#if 0		// not used
static void _paint(MENUDLG dlg, DLGHDL hdl) {

	(void)dlg;
	(void)hdl;
}
#endif

#if 0		// not used
static void _onclick(MENUDLG dlg, DLGHDL hdl, int x, int y) {

	(void)dlg;
	(void)hdl;
	(void)x;
	(void)y;
}
#endif

static void _setval(MENUDLG dlg, DLGHDL hdl, int val) {

	(void)dlg;
	(void)hdl;
	(void)val;
}

static void _moverel(MENUDLG dlg, DLGHDL hdl, int focus) {

	(void)dlg;
	(void)hdl;
	(void)focus;
}

typedef BRESULT (*DLGCRE)(MENUDLG dlg, DLGHDL hdl, const void *arg);
typedef void (*DLGPAINT)(MENUDLG dlg, DLGHDL hdl);
typedef void (*DLGSETVAL)(MENUDLG dlg, DLGHDL hdl, int val);
typedef void (*DLGCLICK)(MENUDLG dlg, DLGHDL hdl, int x, int y);
typedef void (*DLGMOV)(MENUDLG dlg, DLGHDL hdl, int x, int y, int focus);
typedef void (*DLGREL)(MENUDLG dlg, DLGHDL hdl, int focus);

static const DLGCRE dlgcre[] = {
		dlgbase_create,				// DLGTYPE_BASE
		_cre,						// DLGTYPE_CLOSE
		_cre_settext,				// DLGTYPE_BUTTON
		dlglist_create,				// DLGTYPE_LIST
		dlgslider_create,			// DLGTYPE_SLIDER
		dlgtablist_create,			// DLGTYPE_TABLIST
		_cre_settext,				// DLGTYPE_RADIO
		_cre_settext,				// DLGTYPE_CHECK
		_cre_settext,				// DLGTYPE_FRAME
		_cre_settext,				// DLGTYPE_EDIT
		_cre_settext,				// DLGTYPE_TEXT
		dlgicon_create,				// DLGTYPE_ICON
		dlgvram_create,				// DLGTYPE_VRAM
		_cre,						// DLGTYPE_LINE
		_cre						// DLGTYPE_BOX
};

static const DLGPAINT dlgpaint[] = {
		dlgbase_paint,				// DLGTYPE_BASE
		dlgclose_paint,				// DLGTYPE_CLOSE
		dlgbtn_paint,				// DLGTYPE_BUTTON
		dlglist_paint,				// DLGTYPE_LIST
		dlgslider_paint,			// DLGTYPE_SLIDER
		dlgtablist_paint,			// DLGTYPE_TABLIST
		dlgradio_paint,				// DLGTYPE_RADIO
		dlgcheck_paint,				// DLGTYPE_CHECK
		dlgframe_paint,				// DLGTYPE_FRAME
		dlgedit_paint,				// DLGTYPE_EDIT
		dlgtext_paint,				// DLGTYPE_TEXT
		dlgicon_paint,				// DLGTYPE_ICON
		dlgvram_paint,				// DLGTYPE_VRAM
		dlgline_paint,				// DLGTYPE_LINE
		dlgbox_paint				// DLGTYPE_BOX
};

static const DLGSETVAL dlgsetval[] = {
		_setval,					// DLGTYPE_BASE
		_setval,					// DLGTYPE_CLOSE
		_setval,					// DLGTYPE_BUTTON
		dlglist_setval,				// DLGTYPE_LIST
		dlgslider_setval,			// DLGTYPE_SLIDER
		dlgtablist_setval,			// DLGTYPE_TABLIST
		dlgradio_setval,			// DLGTYPE_RADIO
		dlgcheck_setval				// DLGTYPE_CHECK
};

static const DLGCLICK dlgclick[] = {
		dlgbase_onclick,			// DLGTYPE_BASE
		dlgclose_onclick,			// DLGTYPE_CLOSE
		dlgbtn_onclick,				// DLGTYPE_BUTTON
		dlglist_onclick,			// DLGTYPE_LIST
		dlgslider_onclick,			// DLGTYPE_SLIDER
		dlgtablist_onclick,			// DLGTYPE_TABLIST
		dlgradio_onclick,			// DLGTYPE_RADIO
		dlgcheck_onclick			// DLGTYPE_CHECK
};

static const DLGMOV dlgmov[] = {
		dlgbase_move,				// DLGTYPE_BASE
		dlgclose_move,				// DLGTYPE_CLOSE
		dlgbtn_move,				// DLGTYPE_BUTTON
		dlglist_move,				// DLGTYPE_LIST
		dlgslider_move				// DLGTYPE_SLIDER
};

static const DLGREL dlgrel[] = {
		_moverel,					// DLGTYPE_BASE
		dlgclose_rel,				// DLGTYPE_CLOSE
		dlgbtn_rel,					// DLGTYPE_BUTTON
		dlglist_rel,				// DLGTYPE_LIST
		dlgslider_rel				// DLGTYPE_SLIDER
};


// ---- draw

static void draw(VRAMHDL dst, const RECT_T *rect, void *arg) {

	MENUDLG		dlg;

	dlg = (MENUDLG)arg;
	vrammix_cpy2(dst, rect, dlg->vram, NULL, 2);
}


typedef struct {
	MENUDLG	dlg;
	DLGHDL	hdl;
	RECT_T	rect;
} MDCB2;

static BOOL dc_cb(void *vpItem, void *vpArg) {

	DLGHDL	hdl;
	MDCB2	*mdcb;

	hdl = (DLGHDL)vpItem;
	mdcb = (MDCB2 *)vpArg;
	if (hdl == mdcb->hdl) {
		mdcb->hdl = NULL;
	}
	if ((mdcb->hdl != NULL) || (hdl->flag & MENU_DISABLE)) {
		goto dccb_exit;
	}
	if (rect_isoverlap(&mdcb->rect, &hdl->rect)) {
		hdl->flag |= MENU_REDRAW;
	}

dccb_exit:
	return(FALSE);
}


static BOOL dc_cb2(void *vpItem, void *vpArg) {

	MENUDLG	dlg;
	DLGHDL	hdl;

	hdl = (DLGHDL)vpItem;
	dlg = (MENUDLG)vpArg;
	if (hdl->flag & MENU_REDRAW) {
		hdl->flag &= ~MENU_REDRAW;
		if ((!(hdl->flag & MENU_DISABLE)) &&
			((UINT)hdl->type < NELEMENTS(dlgpaint))) {
			dlgpaint[hdl->type](dlg, hdl);
			menubase_setrect(dlg->vram, &hdl->rect);
		}
	}
	return(FALSE);
}


static void drawctrls(MENUDLG dlg, DLGHDL hdl) {

	MDCB2	mdcb;

	if (hdl) {
		if (hdl->flag & MENU_DISABLE) {
			goto dcs_end;
		}
		mdcb.rect = hdl->rect;
	}
	else {
		mdcb.rect.left = 0;
		mdcb.rect.top = 0;
		mdcb.rect.right = dlg->vram->width;
		mdcb.rect.bottom = dlg->vram->height;
	}
	mdcb.dlg = dlg;
	mdcb.hdl = hdl;
	listarray_enum(dlg->dlg, dc_cb, &mdcb);
	if (!dlg->locked) {
		listarray_enum(dlg->dlg, dc_cb2, dlg);
		menubase_draw(draw, dlg);
	}

dcs_end:
	return;
}

static void drawlock(BOOL lock) {

	MENUDLG	dlg;

	dlg = &menudlg;
	if (lock) {
		dlg->locked++;
	}
	else {
		dlg->locked--;
		if (!dlg->locked) {
			listarray_enum(dlg->dlg, dc_cb2, dlg);
			menubase_draw(draw, dlg);
		}
	}
}


// ----

static int defproc(int msg, MENUID id, long param) {

	if (msg == DLGMSG_CLOSE) {
		menubase_close();
	}
	(void)id;
	(void)param;
	return(0);
}


BRESULT menudlg_create(int width, int height, const OEMCHAR *str,
								int (*proc)(int msg, MENUID id, long param)) {

	MENUBASE	*mb;
	MENUDLG		dlg;

	dlg = &menudlg;
	if (menubase_open(2) != SUCCESS) {
		goto mdcre_err;
	}
	ZeroMemory(dlg, sizeof(_MENUDLG));
	if ((width <= 0) || (height <= 0)) {
		goto mdcre_err;
	}
	width += (MENU_FBORDER + MENU_BORDER) * 2;
	height += ((MENU_FBORDER + MENU_BORDER) * 2) +
					MENUDLG_CYCAPTION + MENUDLG_BORDER;
	mb = &menubase;
	dlg->font = mb->font;
	dlg->vram = vram_create(width, height, FALSE, mb->bpp);
	if (dlg->vram == NULL) {
		goto mdcre_err;
	}
	dlg->vram->posx = (mb->width - width) >> 1;
	dlg->vram->posy = (mb->height - height) >> 1;
	dlg->dlg = listarray_new(sizeof(_DLGHDL), 32);
	if (dlg->dlg == NULL) {
		goto mdcre_err;
	}
	dlg->res = listarray_new(sizeof(_DLGPRM), 32);
	if (dlg->res == NULL) {
		goto mdcre_err;
	}
	if (menudlg_append(DLGTYPE_BASE, SID_CAPTION, 0, str,
										0, 0, width, height) != SUCCESS) {
		goto mdcre_err;
	}
	if (menudlg_append(DLGTYPE_CLOSE, SID_CLOSE, 0, NULL,
							width - (MENU_FBORDER + MENU_BORDER) -
									(MENUDLG_CXCLOSE + MENUDLG_PXCAPTION),
							(MENU_FBORDER + MENU_BORDER) +
								((MENUDLG_CYCAPTION - MENUDLG_CYCLOSE) / 2),
							MENUDLG_CXCLOSE, MENUDLG_CYCLOSE) != SUCCESS) {
		goto mdcre_err;
	}
	dlg->sx = (MENU_FBORDER + MENU_BORDER);
	dlg->sy = (MENU_FBORDER + MENU_BORDER) +
							(MENUDLG_CYCAPTION + MENUDLG_BORDER);
	if (proc == NULL) {
		proc = defproc;
	}
	dlg->proc = proc;
	dlg->locked = 0;
	drawlock(TRUE);
	proc(DLGMSG_CREATE, 0, 0);
	drawctrls(dlg, NULL);
	drawlock(FALSE);

	return(SUCCESS);

mdcre_err:
	menubase_close();
	return(FAILURE);
}


static BOOL mdds_cb(void *vpItem, void *vpArg) {

	vram_destroy(((DLGHDL)vpItem)->vram);
	(void)vpArg;
	return(FALSE);
}

static BOOL delicon(void *vpItem, void *vpArg) {

	menuicon_unlock(((DLGPRM)vpItem)->icon);
	(void)vpArg;
	return(FALSE);
}

void menudlg_destroy(void) {

	MENUDLG		dlg;

	dlg = &menudlg;

	if (dlg->closing) {
		return;
	}
	dlg->closing = 1;
	dlg->proc(DLGMSG_DESTROY, 0, 0);
	listarray_enum(dlg->dlg, mdds_cb, NULL);
	menubase_clrrect(dlg->vram);
	vram_destroy(dlg->vram);
	dlg->vram = NULL;
	listarray_destroy(dlg->dlg);
	dlg->dlg = NULL;
	listarray_enum(dlg->res, delicon, NULL);
	listarray_destroy(dlg->res);
	dlg->res = NULL;
}


// ----

BRESULT menudlg_appends(const MENUPRM *res, int count) {

	BRESULT	r;

	r = SUCCESS;
	while(count--) {
		r |= menudlg_append(res->type, res->id, res->flg, res->arg,
							res->posx, res->posy, res->width, res->height);
		res++;
	}
	return(r);
}

BRESULT menudlg_append(int type, MENUID id, MENUFLG flg, const void *arg,
								int posx, int posy, int width, int height) {

	MENUDLG		dlg;
	DLGHDL		hdl;
	_DLGHDL		dhdl;

	dlg = &menudlg;

	if (flg & MENU_TABSTOP) {
		dlg->group++;
	}
	switch(type) {
		case DLGTYPE_LTEXT:
			type = DLGTYPE_TEXT;
			flg &= ~MST_POSMASK;
			flg |= MST_LEFT;
			break;

		case DLGTYPE_CTEXT:
			type = DLGTYPE_TEXT;
			flg &= ~MST_POSMASK;
			flg |= MST_CENTER;
			break;

		case DLGTYPE_RTEXT:
			type = DLGTYPE_TEXT;
			flg &= ~MST_POSMASK;
			flg |= MST_RIGHT;
			break;
	}

	ZeroMemory(&dhdl, sizeof(dhdl));
	dhdl.type = type;
	dhdl.id = id;
	dhdl.flag = flg;
	dhdl.page = dlg->page;
	dhdl.group = dlg->group;
	dhdl.rect.left = dlg->sx + posx;
	dhdl.rect.top = dlg->sy + posy;
	dhdl.rect.right = dhdl.rect.left + width;
	dhdl.rect.bottom = dhdl.rect.top + height;
	dhdl.prm = NULL;
	dhdl.prmcnt = 0;
	dhdl.val = 0;
	if (((UINT)type >= NELEMENTS(dlgcre)) ||
		(dlgcre[type](dlg, &dhdl, arg))) {
		goto mda_err;
	}
	drawlock(TRUE);
	hdl = (DLGHDL)listarray_append(dlg->dlg, &dhdl);
	drawctrls(dlg, hdl);
	drawlock(FALSE);
	return(SUCCESS);

mda_err:
	return(FAILURE);
}


// ---- moving

typedef struct {
	int		x;
	int		y;
	DLGHDL	ret;
} MDCB3;

static BOOL hps_cb(void *vpItem, void *vpArg) {

	DLGHDL	hdl;
	MDCB3	*mdcb;

	hdl = (DLGHDL)vpItem;
	mdcb = (MDCB3 *)vpArg;
	if ((!(hdl->flag & (MENU_DISABLE | MENU_GRAY))) &&
		(rect_in(&hdl->rect, mdcb->x, mdcb->y))) {
		mdcb->ret = hdl;
	}
	return(FALSE);
}

static DLGHDL hdlpossea(MENUDLG dlg, int x, int y) {

	MDCB3	mdcb;

	mdcb.x = x;
	mdcb.y = y;
	mdcb.ret = NULL;
	listarray_enum(dlg->dlg, hps_cb, &mdcb);
	return(mdcb.ret);
}

void menudlg_moving(int x, int y, int btn) {

	MENUDLG	dlg;
	DLGHDL	hdl;
	int		focus;

	drawlock(TRUE);
	dlg = &menudlg;
	x -= dlg->vram->posx;
	y -= dlg->vram->posy;
	if (!dlg->btn) {
		if (btn == 1) {
			hdl = hdlpossea(dlg, x, y);
			if (hdl) {
				x -= hdl->rect.left;
				y -= hdl->rect.top;
				dlg->btn = 1;
				dlg->lastid = hdl->id;
				if ((UINT)hdl->type < NELEMENTS(dlgclick)) {
					dlgclick[hdl->type](dlg, hdl, x, y);
				}
			}
		}
	}
	else {
		hdl = dlghdlsea(dlg, dlg->lastid);
		if (hdl) {
			focus = rect_in(&hdl->rect, x, y);
			x -= hdl->rect.left;
			y -= hdl->rect.top;
			if ((UINT)hdl->type < NELEMENTS(dlgmov)) {
				dlgmov[hdl->type](dlg, hdl, x, y, focus);
			}
			if (btn == 2) {
				dlg->btn = 0;
				if ((UINT)hdl->type < NELEMENTS(dlgrel)) {
					dlgrel[hdl->type](dlg, hdl, focus);
				}
			}
		}
	}
	drawlock(FALSE);
}


// ---- ctrl

void *menudlg_msg(int ctrl, MENUID id, void *arg) {

	void	*ret;
	MENUDLG	dlg;
	DLGHDL	hdl;
	int		flg;

	ret = NULL;
	dlg = &menudlg;
	hdl = dlghdlsea(dlg, id);
	if (hdl == NULL) {
		goto mdm_exit;
	}
	drawlock(TRUE);
	switch(ctrl) {
		case DMSG_SETHIDE:
			ret = (void *)((hdl->flag & MENU_DISABLE)?1:0);
			flg = (arg)?MENU_DISABLE:0;
			if ((hdl->flag ^ flg) & MENU_DISABLE) {
				hdl->flag ^= MENU_DISABLE;
				if (flg) {
					drawctrls(dlg, NULL);
				}
				else {
					drawctrls(dlg, hdl);
				}
			}
			break;

		case DMSG_GETHIDE:
			ret = (void *)((hdl->flag & MENU_DISABLE)?1:0);
			break;

		case DMSG_SETENABLE:
			ret = (void *)((hdl->flag & MENU_GRAY)?0:1);
			flg = (arg)?0:MENU_GRAY;
			if ((hdl->flag ^ flg) & MENU_GRAY) {
				hdl->flag ^= MENU_GRAY;
				drawctrls(dlg, hdl);
			}
			break;

		case DMSG_GETENABLE:
			ret = (void *)((hdl->flag & MENU_GRAY)?0:1);
			break;

		case DMSG_SETVAL:
			ret = (void *)hdl->val;
			if ((UINT)hdl->type < NELEMENTS(dlgsetval)) {
				dlgsetval[hdl->type](dlg, hdl, (int)arg);
			}
			break;

		case DMSG_GETVAL:
			ret = (void *)hdl->val;
			break;

		case DMSG_SETVRAM:
			if (hdl->type == DLGTYPE_VRAM) {
				ret = hdl->c.dv.vram;
				hdl->c.dv.vram = (VRAMHDL)arg;
				drawctrls(dlg, hdl);
			}
			break;

		case DMSG_SETTEXT:
			switch(hdl->type) {
				case DLGTYPE_BUTTON:
				case DLGTYPE_RADIO:
				case DLGTYPE_CHECK:
				case DLGTYPE_EDIT:
				case DLGTYPE_TEXT:
					dlgtext_itemset(dlg, hdl, arg);
					drawctrls(dlg, hdl);
					break;
			}
			break;

		case DMSG_SETICON:
			switch(hdl->type) {
				case DLGTYPE_BUTTON:
				case DLGTYPE_RADIO:
				case DLGTYPE_CHECK:
				case DLGTYPE_EDIT:
				case DLGTYPE_TEXT:
					dlgtext_iconset(dlg, hdl, arg);
					drawctrls(dlg, hdl);
					break;
			}
			break;

		case DMSG_ITEMAPPEND:
			switch(hdl->type) {
				case DLGTYPE_LIST:
					if (dlglist_append(dlg, hdl, arg)) {
						drawctrls(dlg, hdl);
					}
					break;

				case DLGTYPE_TABLIST:
					dlgtablist_append(dlg, hdl, arg);
					drawctrls(dlg, hdl);
					break;
			}
			break;

		case DMSG_ITEMRESET:
			if ((dlg->btn) && (dlg->lastid == hdl->id)) {
				dlg->btn = 0;
				if ((UINT)hdl->type < NELEMENTS(dlgrel)) {
					dlgrel[hdl->type](dlg, hdl, FALSE);
				}
			}
			if (hdl->type == DLGTYPE_LIST) {
				dlglist_reset(dlg, hdl);
				drawctrls(dlg, hdl);
			}
			break;

		case DMSG_ITEMSETEX:
			if (hdl->type == DLGTYPE_LIST) {
				if (dlglist_setex(dlg, hdl, (ITEMEXPRM *)arg)) {
					drawctrls(dlg, hdl);
				}
			}
			break;

		case DMSG_SETLISTPOS:
			if (hdl->type == DLGTYPE_LIST) {
				ret = (void *)(long)hdl->c.dl.basepos;
				dlglist_setbasepos(dlg, hdl, (int)arg);
				drawctrls(dlg, hdl);
			}
			break;

		case DMSG_GETRECT:
			ret = &hdl->rect;
			break;

		case DMSG_SETRECT:
			ret = &hdl->rect;
			if ((hdl->type == DLGTYPE_TEXT) && (arg)) {
				drawctrls(dlg, hdl);
				hdl->rect = *(RECT_T *)arg;
				drawctrls(dlg, hdl);
			}
			break;

		case DMSG_SETFONT:
			if (hdl->type == DLGTYPE_LIST) {
				ret = dlglist_setfont(hdl, arg);
				drawctrls(dlg, hdl);
			}
			else if (hdl->type == DLGTYPE_TABLIST) {
				ret = dlgtablist_setfont(hdl, arg);
				drawctrls(dlg, hdl);
			}
			else if (hdl->type == DLGTYPE_TEXT) {
				ret = hdl->c.dt.font;
				hdl->c.dt.font = arg;
				drawctrls(dlg, hdl);
			}
			break;

		case DMSG_GETFONT:
			if (hdl->type == DLGTYPE_LIST) {
				ret = hdl->c.dl.font;
			}
			else if (hdl->type == DLGTYPE_TABLIST) {
				ret = hdl->c.dtl.font;
			}
			else if (hdl->type == DLGTYPE_TEXT) {
				ret = hdl->c.dt.font;
			}
			break;

	}
	drawlock(FALSE);

mdm_exit:
	return(ret);
}


// --- page

void menudlg_setpage(MENUID page) {

	MENUDLG	dlg;

	dlg = &menudlg;
	dlg->page = page;
}


typedef struct {
	MENUID	page;
	MENUFLG	flag;
} MDCB4;

static BOOL mddph_cb(void *vpItem, void *vpArg) {

	DLGHDL	hdl;
	MDCB4	*mdcb;

	hdl = (DLGHDL)vpItem;
	mdcb = (MDCB4 *)vpArg;
	if ((hdl->page == mdcb->page) &&
		((hdl->flag ^ mdcb->flag) & MENU_DISABLE)) {
		hdl->flag ^= MENU_DISABLE;
	}
	return(FALSE);
}

void menudlg_disppagehidden(MENUID page, BOOL hidden) {

	MENUDLG	dlg;
	MDCB4	mdcb;

	dlg = &menudlg;
	mdcb.page = page;
	mdcb.flag = (hidden)?MENU_DISABLE:0;
	listarray_enum(dlg->dlg, mddph_cb, &mdcb);
	drawlock(TRUE);
	drawctrls(dlg, NULL);
	drawlock(FALSE);
}


RetroPC.NET-CVS <cvs@retropc.net>