macro_file dialog;
#INCLUDE  windows.sh
#INCLUDE  dialog.sh
#INCLUDE  mew_dlgs.sh
#INCLUDE  mew_btn.sh
#INCLUDE  mewlist2.sh
#include  mewhelp.sh
#include  mewlib.sh
#include  mew.sh
#INCLUDE  fprompt.sh

/****************** Multi-Edit INTEGER Macro Function ***********************

 NAME:         DlgCreate
 RETURNS:      The dialog
 DESCRIPTION:  Creates a dialog handle

 PARAMETERS:

handle, or zero if the function failed.

*****************************02-08-94 03:15pm*******************************/
int DlgCreate( int &dlg )
{
	struct DlgCtrl ctrl;
	dlg = menu_create;
	str mstr;

	ctrl.ctrltype = 255;
	ctrl.c = 0;
	ctrl.r = 0;
	ctrl.cw = 0;
	ctrl.ch = 0;
	ctrl.x = 0;
	ctrl.y = 0;
	ctrl.w = 0;
	ctrl.h = 0;
	ctrl.ux = 0;
	ctrl.uy = 0;
	ctrl.uw = 0;
	ctrl.uh = 0;
	ctrl.whandle = 0;
	ctrl.id = 0;

	struct_To_Str( mstr, ctrl );
	menu_set_item( dlg, 1, "", "", mstr, 0, 0, 0 );

	return( 1 );
}

global
{
  int retstrcount "~retstrcount";
}


void DlgSaveRetStr( m )
{
  if(m)
  {
    --retstrcount;
    return_str = global_str("~RETSTR_" + str(retstrcount));
    set_global_str("~RETSTR_" + str(retstrcount), "");
  }
  else
  {
    set_global_str("~RETSTR_" + str(retstrcount), return_str);
    ++retstrcount;
  }
}


/****************** Multi-Edit VOID Macro Function ***********************

 NAME:         DlgAddCtrl

 DESCRIPTION:  Creates a dialog control

 PARAMETERS:   int dlg        the dialog handle create with DlgCreate
							 int ctrltype   the control type
							 str ctrltitle  the control title
							 int x          the x coordinate or column number
							 int y          the y coordinate or row number
							 int width      the width of the control
							 int height     the height of the control
							 int ctrlid     the identifying number for the control
							 str misc       miscelaneous parameters



*****************************02-08-94 04:04pm*******************************/
int DlgAddCtrl(    int dlg,
									 int ctrltype,
									 str ctrltext,
									 int x,
									 int y,
									 int width,
									 int height,
									 int ctrlid,
									 int flags,
									 str misc
							 )
{
	int count = menu_count(dlg);
	str mstr = menu_item_str( dlg, count, 3 );

	int xs= x & 0xffff0000,
			ys= y & 0xffff0000,
			ws = width & 0xffff0000,
			hs = height & 0xffff0000;

	x &= 0xffff;
	y &= 0xffff;
	width &= 0xffff;
	height &= 0xffff;

	struct DlgCtrl ctrl, prevctrl;

	if( count > 1)
		Str_To_struct( prevctrl, mstr );
	else
	{
		prevctrl.c = 0;
		prevctrl.r = 0;
		prevctrl.cw = 0;
		prevctrl.ch = 0;
		prevctrl.x = 0;
		prevctrl.y = 0;
		prevctrl.w = 0;
		prevctrl.h = 0;
		prevctrl.ux = 0;
		prevctrl.uy = 0;
		prevctrl.uw = 0;
		prevctrl.uh = 0;
	}

	ctrl.x = 0;
	ctrl.y = 0;
	ctrl.w = 0;
	ctrl.h = 0;
	ctrl.whandle = 0;

	if(!(xs & DLG_Units ))
	{
		x = (x * DLG_Units_Per_Col);
		if(!(xs & (DLG_PosOffset | DLG_NegOffset)))
			x = (x - DLG_Units_Per_Col) + 1;
	}

	if(!(ys & DLG_Units ))
	{
		y = (y * DLG_Units_Per_Line);
		if(!(ys & (DLG_PosOffset | DLG_NegOffset)))
			y = (y - DLG_Units_Per_Line) + 1;
	}

	if( xs & DLG_PosOffset )
	{
		x = x + prevctrl.ux;
	}
	else
	if( xs & DLG_NegOffset )
	{
		if(prevctrl.ux)
			x=prevctrl.ux - x;
	}

	if( ys & DLG_PosOffset )
	{
		y = y + prevctrl.uy;
	}
	else
	if( ys & DLG_NegOffset )
	{
		if(prevctrl.uy)
			y = prevctrl.uy - y;
	}

	if(!(ws & DLG_Units ))
	{
		width = width *  4;
	}

	if(!(hs & DLG_Units ))
	{
		if(height != 0)
			height = (height *  DLG_Units_Per_Line) - 1;
	}


	ctrl.c  = (x / DLG_Units_Per_Col) + 1;
	ctrl.r  = (y / DLG_Units_Per_Line) + 1;

	ctrl.ux = x;
	ctrl.uy = y;

	ctrl.cw = width / DLG_Units_Per_Col;
	ctrl.ch = (height + 1) / DLG_Units_Per_Line;

	ctrl.uw = width;
	ctrl.uh = height;

	ctrl.id = ctrlid;
	ctrl.ctrltype = ctrltype;
	ctrl.flags = flags;
	ctrl.whandle  = 0;

	struct_To_Str( mstr, ctrl );
	menu_set_item( dlg, count + 1, misc, ctrltext, mstr, ctrltype, 0, ctrlid );
	return(1);
}

		// Gets the X and Y coordinates of a control in dlg units
void DlgGetXY(  int dlg,
								int ctrlid,
								int &x,
								int &y )
{
	int jx = 1, id, count = menu_count(dlg);
	struct DlgCtrl ctrl;

	while( jx <= count )
	{
		if( ((id = menu_item_int(dlg,jx,3)) & 0xffff) == ctrlid)
		{
			str tstr = menu_item_str(dlg,jx,3);
			Str_to_Struct( ctrl,tstr );
			x = ctrl.ux;
			y = ctrl.uy;
			return();
		}
		++jx;
	}
	return();
}

		// Gets the column and row coordinates of a control in dlg units
void DlgGetCR(  int dlg,
								int ctrlid,
								int &c,
								int &r )
{
	int jx = 1, id, count = menu_count(dlg);
	struct DlgCtrl ctrl;

	while( jx <= count )
	{
		if( ((id = menu_item_int(dlg,jx,3)) & 0xffff) == ctrlid)
		{
			str tstr = menu_item_str(dlg,jx,3);
			Str_to_Struct( ctrl,tstr );
			c = ctrl.c;
			r = ctrl.r;
			return();
		}
		++jx;
	}
	return();
}

/****************** Multi-Edit INTEGER Macro Function ***********************

 NAME:         DlgGetInt

 DESCRIPTION:  Gets the integer value for a dialog control

 PARAMETERS:   struct Dlgstruct dlg    the dialog handle
							 int ctrlid     the control id

 RETURNS:      The integer value

*****************************02-08-94 03:27pm*******************************/
int DlgGetInt( int dlg, int ctrlid )
{
	int jx = 1, id, count = menu_count(dlg);

	while( jx <= count )
	{
		if( ((id = menu_item_int(dlg,jx,3)) & 0xffff) == ctrlid)
		{
			return( menu_item_int(dlg,jx,2));
		}
		++jx;
	}
	return(0);
}

/******************** Multi-Edit STR Macro Function *************************

 NAME:         DlgGetStr

 DESCRIPTION:  Gets the string value for a dialog control

 PARAMETERS:   int dlg    the dialog handle
							 int ctrlid     the control id

 RETURNS:      The string value

*****************************02-08-94 03:27pm*******************************/
str DlgGetStr( int dlg, int ctrlid )
{
	int jx = 1, id, count = menu_count(dlg);

	while( jx <= count )
	{
		if( ((id = menu_item_int(dlg,jx,3)) & 0xffff) == ctrlid)
		{
			return( menu_item_str(dlg,jx,2));
		}
		++jx;
	}
	return("");
}

/******************** Multi-Edit VOID Macro Function ************************

 NAME:         DlgSetInt

 DESCRIPTION:  Sets the integer value of the specified dialog control


*****************************02-08-94 04:11pm*******************************/
void DlgSetInt( int dlg, int ctrlid, int value )
{
	int jx = 1, id;

	while( jx <= menu_count(dlg) )
	{
		if( ((id = menu_item_int(dlg,jx,3)) & 0xffff) == ctrlid)
		{
			menu_set_int( dlg, jx, 2, value );
			return( );
		}
		++jx;
	}
	return( );
}

/******************** Multi-Edit VOID Macro Function ************************

 NAME:         DlgSetStr

 DESCRIPTION:  Sets the string value of the specified dialog control


*****************************02-08-94 04:11pm*******************************/
void DlgSetStr( int dlg, int ctrlid, str value[max_line_length] )
{
	int jx = 1, id;

	while( jx <= menu_count(dlg) )
	{
		if( ((id = menu_item_int(dlg,jx,3)) & 0xffff) == ctrlid)
		{
			menu_set_str( dlg, jx, 2,value );
			return( );
		}
		++jx;
	}
	return( );
}

/******************** Multi-Edit VOID Macro Function ************************

 NAME:         DlgKill

 DESCRIPTION:  Deletes a dialog structure from memory

 PARAMETERS:   int dlg    the dialog handle


*****************************02-08-94 03:29pm*******************************/
void DlgKill( int dlg )
{
	menu_delete( dlg );
	dlg = 0;
}


str DlgFitFileName( str fn, int w  )
/********************************************************************
													 Multi-Edit Macro
													 12/14/95 11:42AM

	Function: Fits a filename into a specified width.

						 copyright 1995 by American Cybernetics, Inc.
***********************************************************************/
{
	str Result = fn;

	int line_height = 0, font_height = 0, font_width = 0, dfont = 0;
	Get_MEW_Dlg_Metrics( 0, line_height, font_height, font_width, dfont );

	if(w & DLG_UNITS)
	{
		w=((w&0xffff) * 4) / font_width;
	}
	else
	{
		w=(w&0xffff) * font_width;
	}

	ZShortenPath( result, 255, 0, dfont, w );

	return ( Result );

}  // DlgFitFileName

int GetDefaultButton( int w )
{
	int r = SendMessage( w, DM_GETDEFID , 0, 0 );
	if( (r >> 16) == DC_HASDEFID )
	{
		return( r & 0xFFFF );
	}
	return(0);
}

int SetDefaultButton( int w, int id )
{
	int def_id = GetDefaultButton( w );
	if(def_id == id)
	{
		return( 1 );
	}
	if ( def_id != 0 )
	{
		// Reset the current default push button to a regular button.
		SendDlgItemMessage(w, def_id, BM_SETSTYLE, BS_PUSHBUTTON, TRUE);
	}
	// Update the default push button's control ID.
	SendMessage(w, DM_SETDEFID, id, 0);

	// Set the new style.
	SendDlgItemMessage(w, id, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE);


	RedrawWindow( GetDlgItem( w, id ), 0,0, rdw_Invalidate );

	if(def_id != 0)
		RedrawWindow( GetDlgItem( w, def_id ), 0,0, rdw_Invalidate | rdw_UpdateNow );
	return( 1 );
}

str Set_Bitmap( str bitmap_str, int parent )
{
    DlgSaveRetStr( false );
		rm("DB /LT=Select bitmap/F=BUTTONS.DB/HF=MEWHDRS.DB/HPT=BUTTONS.HDR/LO=1/NDH=1/NDF=1/FV=" + bitmap_str);
		if(return_int)
		{
			bitmap_str = return_str;
		}
    DlgSaveRetStr( true );
		return( bitmap_str );
}

str Set_KeyCode( str key_str, int parent, str title[80], int flags )

{
		str  tstr;
		int kwin, bwin, twin = getfocus;
		int line_height = 0, font_height = 0, font_width = 0, dfont = 0;
		struct tmsg msg;

		if(title == "")
		{
			title = "Press Key to Assign";
		}
		kwin = Create_MEW_Dlg( title, "", parent,0);
		Get_MEW_Dlg_Metrics( kwin, line_height, font_height, font_width, dfont );


		int cancel_pos = 9;
		int button_row = 1;

		if( !(flags & SK_NoCurrentAssign ))
		{
			button_row = 3;
			bwin = Create_MEW_Ctrl( "STATIC", "Current assignment:",
									ws_child | ws_visible,
									4,
									4,
									font_width * 23,
									font_height + 1,
									kwin,1100,
									app_handle,  0
								);



			bwin = Create_MEW_Ctrl( "STATIC", "" ,
									ws_child | ws_visible | ss_blackframe,
									4,
									6 + font_height,
									font_width * 29,
									line_height + 2,
									kwin,1101,
									app_handle,  0
								);

			tstr = Make_Key_Name( Make_Word( parse_int("/K1=",key_str),
																			 parse_int("/K2=",key_str)));
			bwin = Create_MEW_Ctrl( "STATIC", tstr,
									ws_child | ws_visible,
									6,
									9 + font_height,
									font_width * 27,
									font_height + 1,
									kwin,1102,
									app_handle,  0
								);

		}
		else
		{
			bwin = Create_MEW_Ctrl( "STATIC", "" ,
									ws_child | ws_visible | ss_blackframe,
									2,
									1,
									font_width * 29,
									1,
									kwin,1101,
									app_handle,  0
								);

		}

		if( !(flags & SK_NoDelete))
		{
			cancel_pos = 20;
			bwin = Create_MEW_Ctrl( "BUTTON", "Delete",
									ws_child | bs_pushbutton | ws_visible,
									2,
									line_height * button_row,
									font_width * 10,
									line_height + 2,
									kwin,1002,
									app_handle,  0
								);
		}
		bwin = Create_MEW_Ctrl( "BUTTON", "Cancel",
								ws_child | bs_defpushbutton  | bs_pushbutton | ws_visible,
								font_width * cancel_pos,
								line_height * button_row,
								font_width * 10,
								line_height + 2,
								kwin,1001,
								app_handle,  0
							);
		ShowWindow( kwin, sw_show );
		SetFocus( bwin );
	kloop:
		if( peekmessage( &msg, 0, 0, 0, 0 ))
		{
			if(( msg.message == WM_KEYDOWN ) || ( msg.message == WM_SYSKEYDOWN))
			{
				if( check_key )
				{
					if(!(		( key1 == VK_SHIFT )
								||( key1 == VK_CONTROL)
								||( key1 == VK_MENU)
								||( key1 == VK_CAPITAL)
						))
					{
						call create_keycode;
            int jx;   // Lets double up Slashes for the parse_Str
            if ( jx = xpos( "/", tstr, 1))
            {
              tstr = Str_Ins ("/", tstr, jx);
            }
						key_str = "/KL=" + tstr + "/K1=" + str(key1) + "/K2=" + str(key2);
						return_int = TRUE;
						goto kdone;
					}
				}
			}
			else
			{
				if ( getmessage( &msg,0,0,0) )
				{
          if((msg.hwnd == parent) && (msg.message == WM_MEW_DLGRETURN))
					{
						if( msg.wparam == 1001 ) {
							goto kcancel;
						}
						if( msg.wparam = 1002 ) {
							key_str = "";
							goto kcancel;
						}
					}
					if( !IsDialogMessage( kwin, &msg) )
					{
							translatemessage( &msg );
							dispatchmessage( &msg );
					}
				}
			}
		}
		goto kloop;
kdone:

kcancel:
		Destroy_Mew_Dlg( kwin );
		SetFocus( twin );

	return( key_str );


create_keycode:
	{
		if((key1 == 0) && (key2 == 0))
		{
			tstr = '';
		}
		else
		{
			tstr = make_key_name( make_word( key1, key2 ) );
		}
	}
	ret;
}

int DlgBuild( int dlg,
							str title[80],
							str helpindex [80],
              str misc,
							int flags
							)
{
		str
						 MStr,
						 c_str1[20]
					 ;


		int   t_refresh = Refresh,
					field_count,    /* The number of fields */
					jx, jy, jz,
					tt,tw, hc,
					ll,             /* Temp label length */
					protect,        /* field protect status */
					C_Parm,         /* The parm string being worked on */
					old_win = cur_window,
					parent_window = parse_int("/PARENT=", misc ),
					Display_Lines = 0,
					result = 0,
					xmenu_count,
					dialog_done = FALSE,
					unique_id = 0xFFF0
					 ;

			if(!parent_window)
			{
				parent_window = frame_handle;
			}

			int main_dlg, origin_x, origin_y;

			int line_height = 0, font_height = 0, font_width = 0, dfont = 0;
			int jx1;

      int def_btn_id = 0, xo = 0,yo = 0;

			struct DlgCtrl ctrl;

			str tstr[max_line_length],tstr2;
      int xstyle, old_tt, th, dstr, yofs, title_length, icon_id;

			str class[40] = "", history_str[20];
			real T_Real;


      mstr = global_str( parse_str("/RPOS=", misc ) );
      if(mstr == "")
      {
        mstr = misc;
      }
      xo = parse_int("/XPOS=", mstr );
      yo = parse_int("/YPOS=", mstr );

      if(xo || yo)
      {
        flags |= DLG_NOCENTER;
      }

			mstr = menu_item_str(  dlg, 1, 3 );
			str_to_struct( ctrl, mstr );

			if( ctrl.whandle == 0)
			{
				ctrl.whandle = Create_MEW_Dlg( title, helpindex, parent_window, flags);
			}
			main_dlg = ctrl.whandle;
			origin_x = ctrl.x;
			origin_y = ctrl.y;

			struct_to_str( mstr, ctrl );
			menu_set_str(  dlg, 1, 3, mstr );


      if (( xo != 0) || (yo != 0))
      {  // when using these flags, you must use the DLG_NOCENTER flag also.
    //    struct trect rect;

    //    GetWindowRect(main_dlg, &rect);
        SetWindowPos(main_dlg, 0, xo,yo, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
      }
			Get_MEW_Dlg_Metrics( main_dlg, line_height, font_height, font_width, dfont );

			int dc;

			call get_our_dc;

			refresh = false;
			working;

			Return_Int = False;
			field_count = 0;
			Push_Labels;

				/* Get the count of the fields */
			field_count = menu_count(dlg);

			tt = 1000;
			C_Parm = 2;
			while(  (C_Parm <= field_count)  ) {
				MStr = menu_item_str( dlg,  C_Parm, 3);
				Str_To_struct( ctrl, mstr );

				mstr = menu_item_str( dlg, c_parm, 1 );
				tstr = menu_item_str( dlg, c_parm, 2 );

				if( ctrl.id == -1 )
				{
					ctrl.id = unique_id;
					--unique_id;
				}

				if( !ctrl.id )
					ctrl.id = 100 + c_parm;

				class = "STATIC";
				xstyle  = 0;


				old_tt = tt;
				tt = ctrl.ctrltype;


				switch ( tt )
				{
					case DLG_Keycode :
					case DLG_MacroBtnStr :
					case DLG_Static :
					case DLG_BitmapStatic :
					case DLG_GroupBox :
					case DLG_BlackFrame :
					case DLG_GreyFrame :
									break;

					case DLG_RadioButton :
					case DLG_CheckBox :
					case DLG_3State :
								tstr = shorten_str(tstr);
								if( old_tt != tt ) {
									xstyle |= ws_group;
									if( tt != 12)
									{
										xstyle = xstyle | ws_tabstop;
									}
								}
								break;

					case DLG_PushButton :
								tstr = shorten_str(tstr);

					default:
						xstyle |= ws_tabstop + ws_group;
				}


					if(ctrl.uw == 0)
					{
						switch ( tt )
						{
							case DLG_BitmapBtn :

							default:
								jx = svl(tstr);
								if( title_length = xpos("&", tstr, 1 ) )
								{
									tstr2 = Str_Del( tstr, title_length, 1 );
									--jx;
									title_length = GetTextExtent( dc, tstr2, jx) AND 0xFFFF;
								}
								else
								{
									title_length = GetTextExtent( dc, tstr, jx) AND 0xFFFF;
								}

								if(( tt > 3) && (tt != DLG_ListBox )) {
									ctrl.w = title_length;
									switch ( tt )
									{
										case DLG_PushButton   :
												ctrl.w += font_width + font_width;
												break;

										case DLG_RadioButton  :
										case DLG_CheckBox     :
										case DLG_3State :
                        ctrl.w += 18;
									}
								}
								else {
									ctrl.w=(jx + 1 ) * font_width;
									if(title_length > ctrl.w)
										ctrl.w=title_length;
								}
						}
						ctrl.uw = (ctrl.w / font_width) * 4;
					}
					else
					{
						ctrl.w = ((ctrl.uw * font_width) / 4);
					}

				dstr = 1;
				yofs = 0;
				history_str = '';

				ctrl.x=((ctrl.ux * font_width ) / 4) + 5 + origin_x;
				ctrl.y=((ctrl.uy * font_height) / 8) + 5 + origin_y;

				if(ctrl.uh == 0)
				{
					switch ( tt )
					{
						case DLG_PushButton :
							ctrl.uh = DLG_DefBtnHeight;
							break;

						case DLG_ListBox :
							break;

						case DLG_Static :
							ctrl.ch = 1;
							ctrl.uh = DLG_Units_Per_Row;
							break;

						default:
							ctrl.ch = 1;
							ctrl.uh = DLG_Units_Per_Line - 1;
					}
				}

				if(!ctrl.h)
				{
					switch ( tt )
					{
						case DLG_ListBox :
								if(ctrl.uh != 0)
									ctrl.h = ((ctrl.uh * font_height) / 8) + 5;
								break;

						default:
							ctrl.h = ((ctrl.uh * font_height) / 8) + 1;
					}
				}

				if(  (tt != 17) && (tt != 18)  ) {
					switch(tt) {
					case DLG_Text :
					case DLG_Integer :
					case DLG_RealNumber :
						history_str = parse_str("/HISTORY=",mstr);
						if(history_str != "")
						{
							class = "COMBOBOX";
							xstyle |= cbs_dropdown | cbs_autohscroll;
							ctrl.ch = parse_int('/#=', global_str(history_str));
							if ( ctrl.ch > 10 )
							{
								ctrl.ch = 10;
								xstyle |= ws_vscroll;
							}
							++ctrl.ch;
              ctrl.h = (font_height * ctrl.ch) + (font_height * 2);
						}
						else
						{
							class = "EDIT";
							xstyle |= ws_border | (ctrl.flags >> 16);

              if (ctrl.flags & DLGF_Es_HScrollBar) {
                xstyle |= WS_HSCROLL;
              }

							if( !(xstyle & es_multiline) )
							{
								xstyle |= es_autohscroll;
							}
							else
							{
								xstyle |= ws_vscroll;
							}

						}

						if( tt == DLG_Integer )
						{
							tstr = str( menu_item_int( dlg, c_parm, 2 ));
						}
						else
						{
							tstr = menu_item_str( dlg, c_parm, 2 );
						}
						call create_ctrl;

						if ( ctrl.flags & DLGF_GetTextFromWin )
						{
							jx = parse_int("/WID=", mstr );
							if( switch_win_id(jx))
							{
								tof;
								str_block_begin;
								eof;
								int bhandle;
								TextToBuffer( bhandle, 0xffff, FALSE );
								int tptr = GlobalLock( bhandle );
								SendMessage( ctrl.whandle, WM_SETTEXT, 0, tptr );
								GlobalUnlock( bhandle );
								GlobalFree( bhandle );
								switch_window( old_win );
							}
						}

						int max_len = parse_int("/ML=", mstr );
						if(!max_len)
							max_len = ctrl.cw;

						if(max_len)
						{
							if(class == "COMBOBOX")
							{
								SendMessage (ctrl.whandle, CB_LIMITTEXT, max_len, 0);
							}
							else
							{
								SendMessage (ctrl.whandle, EM_LIMITTEXT, max_len, 0);
							}
						}


						if( tt == DLG_Integer )
						{
								int minint = 0 - 0x7ffffffe;
								int maxint = 0x7FFFFFFF;
								if( xpos("/MAX=", mstr,1 ) )
									var_parse_int( "/MAX=", mstr, maxint );
								if( xpos("/MIN=", mstr,1 ) )
									var_parse_int( "/MIN=", mstr, minint );

								int spinwin = CreateWindow("mewspin", "1,99,50",
												 WS_VISIBLE | WS_CHILD | (MSS_VERTICAL | MSS_TEXTHASRANGE | MSS_INVERTRANGE),
												 ctrl.x + ctrl.w + 2, ctrl.y, (font_width * 2) + 1, line_height,
												 main_dlg, 0, app_handle, 0);

                SubClass_With_Macro( ctrl.whandle, "DlgSpinProc",
                    "/SPINW=" + str(spinwin) +
                    "/MIN=" + str(minint) +
                    "/MAX=" + str(maxint) );

								MSHAssociateSet( spinwin, ctrl.whandle );
						}
						break;


					case DLG_Choice :
						{
							class = "COMBOBOX";
							xstyle |= cbs_dropdown | cbs_dropdownlist;
							call create_ctrl;

							int c_choice = menu_item_int( dlg,c_parm, 2 );
							int res;
							if(  (C_Choice < 1)  ) {
								C_Choice = 1;
							}
							tstr = menu_item_str( dlg, c_parm, 2 );
							int jx1 = 1;
							int jx2 = 1;
							int count = 0;
						loop:
							jx1 = xpos( '(', tstr, jx1 + 1 );
							if(  jx1 != 0  ) {
								if(  copy(tstr, jx1 + 1, 1) == '('  ) {
									tstr = str_del( tstr, jx1, 1);
									goto loop;
								}
								++count;
								jy = xpos( ')', tstr, jx1 + 1);
								// helpstr = copy( tstr, jx1 + 1, jy - jx1 - 1 );
								mstr = copy( tstr, jx2, jx1 - jx2 );
								res = 0;
								if(  svl(mstr) > 0  ) {
									if(  str_char( mstr, svl(mstr) ) == '|254'  ) {
										mstr = copy(mstr, 1, svl(mstr) - 1 );
										res = 1;
									}
								}
								SendDlgItemMessageStr( main_dlg, ctrl.id, cb_addstring, 0, mstr);
								jx2 = jy + 1;
								goto loop;
							}
							SetWindowPos( ctrl.whandle, 0,0,0, ctrl.w, line_height + (count * font_height), SWP_NOMOVE | SWP_NOZORDER );
							SendDlgItemMessage( main_dlg, ctrl.id, cb_setcursel, c_choice - 1, 0);
							MStr = menu_item_str( dlg,  C_Parm, 3);
						}
						break;

					case DLG_MacroBtnStr :
					case DLG_Keycode :
						//yofs = -2;
						class = "EDIT";
						xstyle = xstyle | ws_border | es_nohidesel;
						if ( tt == DLG_Keycode )
						{
							tstr = menu_item_str( dlg, c_parm, 2 );
							key1 = parse_int("/K1=", tstr );
							key2 = parse_int("/K2=", tstr );
							call create_keycode;
						}
						else
						{
							tstr = menu_item_str( dlg, c_parm, 2 );
						}
						ctrl.w -= (font_width * 3) + (font_width / 2) - 4;

						int bwin =  Create_MEW_Ctrl( "BUTTON", "...",
															WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON | WS_TABSTOP,
															ctrl.x + ctrl.w + 2,
															ctrl.y,
															 (font_width * 3) + (font_width / 2), line_height,
															main_dlg,unique_id,
															app_handle,  0
														);

						call create_ctrl;

						SubClass_With_Macro( bwin, "DlgPopupBtnProc", "/HN=" + str( ctrl.whandle) );
						SubClass_With_Macro( ctrl.whandle, "DlgPopupProc",
							"/CID=" + str( unique_id ) + "/#=" + str(c_parm) +
							"/K=" + str( tt == DLG_Keycode ) +
							"/FLAGS=" + str (parse_int ("/FLAGS=", mstr)) +
							"/DLG=" + str(dlg) + menu_item_str(dlg,c_parm,1)
							 );
						--unique_id;
						break;


					case DLG_Icon :
            xstyle |= ss_icon;
						ctrl.y += (line_height / 2) - 2;
						class = "STATIC";
						xstyle |= ctrl.flags >> 16;

            if(val(icon_id, tstr) == 0)
            {
              call create_ctrl_int;
            }
            else
            {
              call create_ctrl;
            }
						break;


					case DLG_Static :
						class = "STATIC";
						xstyle |= ctrl.flags >> 16;
						call create_ctrl;
						break;


					case DLG_GROUPBOX :
						class = "BUTTON";
						xstyle |= bs_groupbox;
						ctrl.y+=2;
						ctrl.h+=1;
						call create_ctrl;
						break;

					case DLG_BlackFrame :
						xstyle |= ss_blackframe;
						call create_static_frame;
						break;

					case DLG_GreyFrame :
						xstyle |= ss_grayframe;
						call create_static_frame;
						break;

					case DLG_WhiteFrame :
						xstyle |= ss_whiteframe;
						call create_static_frame;
						break;

					case DLG_BlackRect :
						xstyle |= ss_blackrect;
						call create_static_frame;
						break;

					case DLG_GreyRect :
						xstyle |= ss_grayrect;
						call create_static_frame;
						break;

					case DLG_WhiteRect :
						xstyle |= ss_whiterect;
						call create_static_frame;
						break;

          case DLG_OwnerButton :
            class = "BUTTON";
            xstyle = xstyle | BS_OWNERDRAW;
						call create_ctrl;

            break;

          case DLG_DirButton :
					case DLG_PushButton  :  /* if button */
						class = "BUTTON";
						if ( menu_item_int( dlg, c_parm, 2 ) )
						{
							def_btn_id = ctrl.id;
							xstyle |= bs_defpushbutton;
						}
						else if ( ctrl.flags & DLGF_DefButton )
						{
							def_btn_id = ctrl.id;
							xstyle |= bs_defpushbutton;
						}
						else
						{
							xstyle = xstyle | bs_pushbutton;
						}

						call create_ctrl;
						break;

					case DLG_RadioButton :
						if(  menu_item_int( dlg, c_parm, 2 ) > 0  ) {
							var_parse_str( '/G=', mstr, c_str1 );
							if(  svl(c_str1) > 0  ) {
								var_parse_int( '/R=', mstr, ll );
								set_global_int( c_str1, ll );
							}
						}
						class = "BUTTON";
						xstyle = xstyle + bs_autoradiobutton;
						call create_ctrl;
						if( menu_item_int( dlg, c_parm, 2 ) )
							SendDlgItemMessage( main_dlg, ctrl.id, bm_setcheck,1, 0 );
						break;


					case DLG_CheckBox :
						class = "BUTTON";
						xstyle = xstyle + bs_autocheckbox;
						call create_ctrl;
						if( menu_item_int( dlg, c_parm, 2 ) )
							SendDlgItemMessage( main_dlg, ctrl.id, bm_setcheck,1, 0 );
						break;

					case DLG_3State :
						class = "BUTTON";
						xstyle = xstyle + bs_auto3state;
						call create_ctrl;
						SendDlgItemMessage( main_dlg, ctrl.id, bm_setcheck, menu_item_int( dlg, c_parm, 2 ), 0 );
						break;


					case DLG_ListTextBox :
						Display_Lines = parse_int('/DISP#=',MStr);
						switch_window( parse_int('/WIN=', mstr) );
						window_attr =  0x90;

						call calculate_list_field;


						int tdc = dc;

						if(dc != 0)
							call release_our_dc;

						ctrl.whandle = Create_MEW_List( "", cur_window,
										ws_child | ws_visible | ws_border | ws_vscroll | ws_tabstop,
										ctrl.x, ctrl.y, ctrl.w, ctrl.h, main_dlg, ctrl.id);

						goto_col(1);

						var_parse_int ('/INCO=', mstr, jx);
						if ( jx )
						{
							SendMessage (ctrl.whandle, WM_COMMAND, 1000, jx);
						}

						if(tdc != 0)
							call get_our_dc;

						break;

					case DLG_ViewTextBox :
						switch_window( parse_int('/WIN=', mstr) );
						int tdc = dc;

						if(dc != 0)
							call release_our_dc;

						ctrl.whandle = Create_MEW_List( "", cur_window,
										ws_child | ws_visible | ws_vscroll | ws_tabstop | ws_hscroll,
										ctrl.x, ctrl.y, ctrl.w, ctrl.h, main_dlg, ctrl.id);

						if(tdc != 0)
							call get_our_dc;

						break;


					case DLG_ListBox :
						int lflags = ctrl.flags >> 16;
						if(parse_int("/INCO=", mstr))
							lflags |= _LB_FLAG_INCSEARCH;

						switch_window( parse_int('/WIN=', mstr) );
						window_attr =  0x90;

						call calculate_list_field;
						if(!ctrl.w)
						{
							ctrl.w = (ll * font_width) + 5;
						}
						if(!ctrl.h)
						{
							if(hc < 5)
								hc = 5;
							if(hc > 20)
								hc = 20;
							ctrl.h = (hc * (font_height + 1)) + 5;
						}

						int tdc = dc;

						if(dc != 0)
							call release_our_dc;


						ctrl.whandle = ListBoxCreate( cur_window, 1, xmenu_count,
										ctrl.x, ctrl.y, ctrl.w, ctrl.h, ctrl.id,
										lflags, 0, main_dlg,
										menu_item_str( dlg, c_parm, 2 ));

						sendmessage( ctrl.whandle, WM_ML2_SETKEYWCMD, parse_int("/INSWCMD=", mstr) , 0);
						sendmessage( ctrl.whandle, WM_ML2_SETKEYWCMD, parse_int("/DELWCMD=", mstr) , 1);
						jx = parse_int("/HSCROLL=", mstr);
						if(jx)
							SendMessage( ctrl.whandle, lb_sethorizontalext, jx * font_width, 0 );



						if(tdc != 0)
							call get_our_dc;

						break;


					case DLG_ViewTextBox :
						break;


					case DLG_SubDlg :
						ctrl.whandle = 0;
						break;

					case DLG_BitmapDefine :
					case DLG_BitmapStatic :
					case DLG_BitmapBtn :
						{
							int name_offset = 0,
									oem_flag = 0;
              jx = 0;
							tstr = menu_item_str(dlg, c_parm, 2 );
							jy = xpos(" ", tstr,1);
							if(!jy)
							{
								jy = max_line_length;
							}
							else
							{
								jx |= MEWBTN_TEXTANDBITMAP;
							}

							name_offset = xpos("^",tstr, 1 );
							if(!name_offset || (name_offset > jy))
							{
								name_offset = 1;
							}
							else
							{
								++name_offset;
							}

							tstr = copy(tstr, name_offset, jy - 1 );
              name_offset = 1;

							if (str_char(tstr,1) == "~")
							{
								tstr = copy(tstr, 2,max_line_length);
								oem_flag = 1;
                name_offset = 2;
							}

							if ( menu_item_int( dlg, c_parm, 2 ) )
							{
								def_btn_id = ctrl.id;
								jx |= MEWBTN_DEFPUSHBUTTON;
								xstyle |= bs_defpushbutton;
							}
							else if ( ctrl.flags & DLGF_DefButton )
							{
								def_btn_id = ctrl.id;
								jx |= MEWBTN_DEFPUSHBUTTON;
								xstyle |= bs_defpushbutton;
							}
							else
							{
								xstyle |= bs_pushbutton;
							}

							if ( ctrl.flags & DLGF_BitmapTgl )
							{
								xstyle |= MEWBTN_TOGGLEBUTTON;
							}

							if( tt == DLG_BitmapStatic )
							{
								jx |= MEWBTN_STATICBUTTON | MEWBTN_SIZETOBITMAP;
							}
							else
							{
								jx |= MEWBTN_PUSHBUTTON | MEWBTN_SIZETOBITMAP;
							}

              if( val( name_offset, copy(tstr,name_offset,255) ) != 0 )
							{
								if (oem_flag) {
									ctrl.whandle = BuildMEWComboButton( main_dlg, MEWBTN_RT_WIN31OEM,
													tstr,
													copy(menu_item_str( dlg, c_parm, 2 ),jy + 1,max_line_length),
													xstyle, jx,
													ctrl.id, ctrl.x, ctrl.y, ctrl.w, ctrl.h,
													8,0,
													dfont,
													0,0,0 );
								} else {
									ctrl.whandle = BuildMEWComboButton( main_dlg, MEWBTN_RT_RESNAME,
													copy(menu_item_str( dlg, c_parm, 2 ),1,jy - 1),
													copy(menu_item_str( dlg, c_parm, 2 ),jy + 1,max_line_length),
													xstyle, jx,
													ctrl.id, ctrl.x, ctrl.y, ctrl.w, ctrl.h,
													8,0,
													dfont,
													0,0,0 );
								}
							}
							else
							{
								if (oem_flag) {
                  ctrl.whandle = BuildMEWComboButtonInt( main_dlg, MEWBTN_RT_WIN31OEM,
													name_offset,
													copy(menu_item_str( dlg, c_parm, 2 ),jy + 1,max_line_length),
													xstyle, jx,
													ctrl.id, ctrl.x, ctrl.y, ctrl.w, ctrl.h,
													8,0,
													dfont,
													0,0,0 );
								} else {
									ctrl.whandle = BuildMEWComboButtonInt( main_dlg, MEWBTN_RT_RESID,
													name_offset,
													copy(menu_item_str( dlg, c_parm, 2 ),jy + 1,max_line_length),
													xstyle, jx,
													ctrl.id, ctrl.x, ctrl.y, ctrl.w, ctrl.h,
													8,0,
													dfont,
													0,0,0 );
								}
							}
						}
						break;


					default :
					}
				}

				struct_to_str(tstr, ctrl );
				menu_set_str(dlg, c_parm,3,tstr );

				if( ctrl.flags & DLGF_Disable )
				{
					EnableWindow( ctrl.whandle, false );
					tt = -1;
				}

				if( svl(history_str) > 0)
				{

					int ic = 0;

					mstr = global_str( history_str + str(ic) );
					if( mstr != "" )
					{
						SendDlgItemMessageStr( main_dlg, ctrl.id, cb_addstring, 0, mstr );
					}

					for( ic = parse_int('/#=', global_str(history_str)); ic > 0; ic--)
					{
						mstr = global_str( history_str + str(ic) );

						if( mstr != "" )
						{
							SendDlgItemMessageStr( main_dlg, ctrl.id, cb_addstring, 0, mstr );
						}
					}
					if ( (tt == DLG_Text))
					{
						SetDlgItemText( main_dlg, ctrl.id, menu_item_str( dlg, c_parm, 2 ) );
					}
				}
				menu_set_int( dlg, c_parm, 3, make_long(ctrl.id, ctrl.whandle) );
				++C_Parm;
			}

		call release_our_dc;

		if(def_btn_id)
			SetDefaultButton( main_dlg, def_btn_id );

		return( main_dlg );


	get_our_dc:
		dc = GetDc( main_dlg );
		Selectobject( dc, dfont );

		ret;

	release_our_dc:
		ReleaseDC( main_dlg, dc );
		dc = 0;
		ret;

	create_ctrl:
		int tdc = dc;

		if(dc != 0)
			call release_our_dc;
		ctrl.whandle = Create_MEW_Ctrl( class, tstr,
								xstyle,
								ctrl.x,
								ctrl.y,
								ctrl.w,
								ctrl.h,
								main_dlg,ctrl.id,
								app_handle,  0
							);
		if(tdc != 0)
			call get_our_dc;
		ret;

  create_ctrl_int:
		int tdc = dc;

  //  make_message(str(icon_id));
		if(dc != 0)
			call release_our_dc;
    ctrl.whandle = CreateMEWCtrlInt( class, icon_id,
								xstyle,
								ctrl.x,
								ctrl.y,
								ctrl.w,
								ctrl.h,
								main_dlg,ctrl.id,
								app_handle,  0
							);
		if(tdc != 0)
			call get_our_dc;
		ret;


	create_keycode:
		{
			if((key1 == 0) && (key2 == 0))
			{
				tstr = '';
			}
			else
			{
				tstr = make_key_name( make_word( key1, key2 ) );
			}
		}
		ret;

	calc_xmenu_count:
		mark_pos;
		eof;
		xmenu_count = c_line;
		if(  c_col == 1  ) {
			--xmenu_count;
		}
		goto_mark;
		ret;

		/*  returns:
				ll := width,
				xmenu_count := count,
				hc := height
			*/
	calculate_list_field:
		mark_pos;
		tof;
		xmenu_count = 0;
		ll = 0;
		if( !parse_int("/W=", mstr) ) {
			while(  NOT( at_eof )  ) {
				++xmenu_count;
				jx = length(get_line);
				if(  jx > ll  ) {
					ll = jx;
				}
				down;
			}
		}
		else {
//			if( !parse_int("/HT=", mstr) )
				call calc_xmenu_count;
		}
		goto_mark;
		if(  at_eof  ) {
			goto_col(1);
			if(  at_eof  ) {
				goto_line( c_line - 1 );
			}
		}

		++ll;
		hc = xmenu_count;
		ret;

	create_static_frame:
			class = "STATIC";
			ctrl.x-=2;
			ctrl.w+=2;
			ctrl.y-= (line_height / 3);
			ctrl.h+= ((line_height / 3) * 2) - 2;
			call create_ctrl;
			ret;

}

void DlgSetFields( int dlg )
{
	int jx,jy, field_count = menu_count(dlg);
	str mstr[max_line_length];
	struct DlgCtrl ctrl;
	int main_dlg;
	int tr = refresh;
	int tw = cur_window;
	int tv;
	refresh = false;

  DlgSaveRetStr( false );

	mstr = menu_item_str( dlg, 1, 3 );
	str_to_struct( ctrl, mstr );
	main_dlg = ctrl.whandle;

	for( jx = 2; jx <= field_count; jx++ )
	{
		mstr = menu_item_str( dlg, jx, 3 );
		str_to_struct( ctrl, mstr );
		switch ( ctrl.ctrltype )
		{
			case DLG_Text :
			case DLG_RealNumber :
      case DLG_MacroBtnStr :
				if ( ctrl.flags & DLGF_GetTextFromWin )
				{
					jy = parse_int("/WID=", menu_item_str(dlg,jx,1) );
					if( switch_win_id(jy))
					{
						tof;
						str_block_begin;
						eof;
						delete_block;
						int bhandle = GlobalAlloc( GMEM_MOVEABLE, 0xffff );
						if(  bhandle )
						{
							jy = globallock( bhandle );
							if(jy)
							{
                // JKP - 9/11/95 4:13PM fixed problem with NT and zero length
                int len = GetWindowTextLength (ctrl.whandle);
                if ( len )
                {
                  len = sendmessage( ctrl.whandle, WM_GETTEXT, 0xFFFE, jy );
                }
								GlobalUnlock( bhandle );
                if ( len )
                {
                  BufferToText( bhandle );
                }
							}
							GlobalFree( bhandle );
						}
						switch_window( tw );
					}
				}
				else
				{
					GetDlgItemText( main_dlg, ctrl.id, mstr, max_line_length );
					menu_set_str( dlg, jx, 2, mstr );
				}
				return_str = mstr;
				call do_history;

				break;

			case DLG_Integer :
				GetDlgItemText( main_dlg, ctrl.id, mstr, 1023 );
				tv = 0;
				val( tv, mstr );
				menu_set_int( dlg, jx, 2, tv);
				call do_history;
				break;

      case DLG_Choice : {
        str t_str;
				menu_set_int( dlg, jx, 2,
				SendDlgItemMessage( main_dlg, ctrl.id, cb_getcursel, 0, 0) + 1);
        SendDlgItemMessageStr( main_dlg, ctrl.id, cb_getlbtext, menu_item_int(dlg, jx, 2) - 1, t_str);
        menu_set_str(dlg, jx, 2, t_str);
				break;
      }

			case DLG_RadioButton :
			case DLG_CheckBox :
			case DLG_3State :
				menu_set_int( dlg, jx, 2, IsDlgButtonChecked( main_dlg, ctrl.id ));
				break;

			case DLG_ListTextBox :
				switch_window( parse_int("/WIN=", menu_item_str( dlg, jx, 1 )));
				menu_set_int( dlg, jx, 3, c_line );
				break;

		}
	}

	if (  cur_window != tw )
	{
		switch_window(tw);
	}
	refresh = tr;
  DlgSaveRetStr( true );
	return();

do_history:
	mstr = parse_str("/HISTORY=", menu_item_str( dlg, jx, 1 ) );
	if( mstr != "" )
	{
		rm("HISTORY_LIST /M=1/HISTORY=" + mstr);
	}
	ret;

}

int DlgProcessSub( int win, int dlg, int s_index )
{
	struct DlgCtrl master_ctrl;
	int jx, field_count,c_parm, master_index, wparam;
	str mstr;

	mstr = menu_item_str(dlg,s_index,1);
	int sub_id = parse_int("/SD=", mstr );
	if(sub_id != 0)
	{
		wparam =  sub_id;
		call id_parm;
		if(c_parm != 0)
		{
			master_index = c_parm;
			MStr = menu_item_str( dlg,  master_index, 3);
			Str_To_struct( master_ctrl, mstr );

			mstr = menu_item_str( dlg, master_index, 2 );
			if(master_ctrl.whandle)
			{
				if(parse_int("/CID=", mstr) == sub_id)
				{
					return( 0 );
				}
				DlgKill( parse_int("/DATAHANDLE=", mstr ));
				DestroyWindow( master_ctrl.whandle );
			}

			int tdlg;
			DlgCreate(tdlg );

			struct DlgCtrl subdlg_ctrl;

			MStr = menu_item_str( tdlg,  1, 3);
			str_to_struct( subdlg_ctrl, mstr );


			subdlg_ctrl.whandle =
				Create_Mew_DlgEx ("", WS_CHILD | WS_VISIBLE, master_ctrl.x, master_ctrl.y, win ,
						DLG_NOSIZE | DLG_NOCENTER | DLG_NOPARDISABLE);

			menu_set_str( dlg, master_index,2, "/DATAHANDLE=" + str( tdlg ) );

			master_ctrl.whandle = subdlg_ctrl.whandle;

			struct_to_str(mstr, subdlg_ctrl );
			menu_set_str( tdlg, 1, 3, mstr );

			struct_to_str(mstr, master_ctrl );
			menu_set_str( dlg, master_index, 3, mstr );

			MStr = menu_item_str( dlg,  s_index, 1);

			if (jx = xpos("/M=", mstr,1)) {     // Run macro
				mstr =  copy(mstr, jx + 3, max_line_length );
				if (xpos(" ", mstr, 1) == 0) {
					mstr = mstr + " ";
				}
				jx = return_int;
				rm(mstr + "/M=0/DLGHANDLE=" + str(win) + "/DATAHANDLE=" + str(tdlg) );
				return_int = jx;
			}
			DlgBuild( tdlg, "", "", "", 0 );
			SubClass_With_Macro( subdlg_ctrl.whandle, "DlgMessageProc", "/DLG=" + str(tdlg) );
			Auto_Size_Mew_Dlg( subdlg_ctrl.whandle, 10, 10 );
			ShowWindow( subdlg_ctrl.whandle, SW_SHOW );
		}
	}
	return( 0 );

 id_parm:
		c_parm = 1;
		while( c_parm <= field_count )
		{
			if(( menu_item_int( dlg, c_parm, 3) & 0xfff) == wparam)
			{
				ret;
			}
			++c_parm;
		}
		c_parm = 0;
		ret;
}

// This macro handles message processing for integer text controls with
// spin buttons.
int DlgSpinProc( int &retval, int window, message, wparam, lparam, str parms ) no_break
{
	int result = 0;
  if( message == WM_GET_SPINWIN )
  {
    result = 1;
    retval = parse_int( "/SPINW=", parms );
  }
  else
	switch(message)
	{
    case WM_SHOWWINDOW :
      ShowWindow( parse_int("/SPINW=", parms), wparam );
      break;

		case WM_VSCROLL :
			str tstr[30];
			int tv = 0;
			int minint,maxint;

			if(getfocus() != window)
				SetFocus(window);

			var_parse_int("/MIN=", parms, minint );
			var_parse_int("/MAX=", parms, maxint );

			GetWindowText( window, tstr, 29 );
			val(tv,tstr);

			switch ( wparam )
			{
				case  SB_LINEUP :
					if( tv < maxint )
						++tv;
					break;

				case  SB_LINEDOWN :
					if(tv > minint )
						--tv;
					break;
			}
			SetWindowText( window, str( tv ) );
      SendMessage( window, EM_SETSEL, 0, Make_Long( 0, 0xffff ) );
			result = 1;
			break;
	}
	return(result);
}

int DlgRunStrMacro( int dlg, int window, str cmdline  )
{
	int jx = XPos('/M=', cmdline, 1 );
	if(  jx  ) {
/* Check to see if command line parameters already exist in the macro name.  If
so, don't add a space between macro name and the params we are adding */
		cmdline = Copy(cmdline,jx + 3, 255);
		if(  (XPos(' ',cmdline,1) == 0)  ) {
			cmdline = cmdline + ' ';
		}
    DlgSaveRetStr( false );
		str mstr;
		GetWindowText(window, mstr, 254 );
		return_str = mstr;
		jx = return_int;
		rm(cmdline + "/DLGHANDLE=" + str(window) + "/DATAHANDLE=" + str(dlg) );
		if(  return_int > 0  ) {
			mstr = return_str;
			SetWindowText( window, mstr);
		}
		return_int = jx;
    DlgSaveRetStr( true );
	}
	return(0);
}
 
global
{
	int DlgPopupFocus 		"~DlgPopupFocus";
	int DlgPrevDefaultBtn "~DlgPrevDefaultBtn";
}

int DlgPopupBtnProc( int &retval, int window, message, wparam, int lparam, str parms ) no_break
{
	int result = 0;
//  msglog( 1, "DlgPopupBtnProc", window, message, wparam, lparam  );
	if(message == WM_TRIGGER_POPUP)
	{
		int jx = parse_int("/HN=", parms);
		SetFocus(jx);
		SendMessage( jx, WM_TRIGGER_POPUP, 0, 0 );
		result = 1;
	}
	else
	{
		switch ( message )
		{
			case WM_KILLFOCUS :
				SendMessage(parse_int("/HN=", parms),EM_SETSEL, 0, 0 );
				break;

			case  WM_SETFOCUS :
        SendMessage(parse_int("/HN=", parms),EM_SETSEL, 0, Make_Long( 0,  0xffff ) );
				break;
		}
	}
	return(result);
}

int DlgPopupProc( int &retval, int window, message, wparam, lparam, str parms ) no_break
{
	int result = 0;

	if(message == WM_TRIGGER_POPUP)
	{
		if(parse_int("/K=", parms))
		{
			int dlg = parse_int("/DLG=", parms );
			int n 	= parse_int("/#=", parms );

			menu_set_str ( dlg, n, 2,
				Set_Keycode(menu_item_str(dlg,n,2), GetParent(window),
					"", parse_int ("/FLAGS=", parms) ));
			SetWindowText( window, parse_str("/KL=",menu_item_str(dlg,n,2) ));
		}
		else
		{
			DlgRunStrMacro( parse_int("/DLG=", parms), window, parms );
		}
		SetFocus( getDlgItem(getparent(window),parse_int("/CID=", parms)));
    SendMessage( window, EM_SETSEL, 0, Make_Long( 0,  0xffff ) );
	}
	else
	{
		//msglog( 1, "DlgPopupProc", window, message, wparam, lparam  );
		switch(message)
		{
			case WM_SETFOCUS :
				SetFocus( getDlgItem(getparent(window),parse_int("/CID=", parms)));
				result = 1;
				retval = 0;
				break;

			case WM_LBUTTONDOWN :
				SetFocus( getDlgItem(getparent(window),parse_int("/CID=", parms)));
				result = 1;
				retval = 0;
				break;

			case WM_KEYDOWN :
				if( (wparam == vk_space) || (wparam == vk_down))
				{
					PostMessage( getparent(window), WM_COMMAND, parse_int("/CID=", parms ), 0 );
				}
				result = 1;
				retval = 1;
				break;

			case WM_LBUTTONDBLCLK :

				PostMessage( getparent(window), WM_COMMAND, parse_int("/CID=", parms ), 0 );
				result = 1;
				retval = 1;
				break;


			case WM_LBUTTONUP :
			case WM_KEYUP :
			case WM_CUT :
			case WM_COPY :
			case WM_PASTE :
					result = 1;
					retval = 1;
					break;

			case WM_GETDLGCODE :
					retval = 0;
					result = 1;
					break;

		}
	}
	return(result);
}

str double_slashes(str t_str) {
/*******************************************************************************
                                Multi-Edit MACRO

 NAME: double_slashes()

 RETURNS: the converted string

 DESCRIPTION: scans t_str for any slash characters and adds a slash for any
              found.  Useful for building a macro command line from strings
              of unknown value that may have slash characters

 PARAMETERS: t_str is the string to be converted

*******************************************************************************/
  int t_int = 1;

  while (t_int = xpos("/", t_str, t_int)) {
    t_str = str_ins("/", t_str, ++t_int++);
  }
  return(t_str);
}

int DlgMessageProc( int &retval, int window, message, wparam, lparam, str parms ) no_break
{
	int j;
	int result = 0;
	int modeless = parse_int("/M=", parms);
  int destroy_flag = 0;

	switch(  message )
	{
    case WM_ACTIVATE :
      if ( Modeless ) {

        int Dlg = Parse_Int( "/DLG=", Parms );
        int ActiveWindow = Window_Id;

        if ( WParam == 0 ) {
          if ( Global_Str( "!DLG_DEACT_MSTR" + Str( Dlg ) ) != "" ) {
            Rm( Global_Str( "!DLG_DEACT_MSTR" + Str( Dlg ) ) + "/DEACTIVE=1" );
            Switch_Win_Id( ActiveWindow );
          }
        }
				else {
          if ( Global_Str( "!DLG_ACT_MSTR" + Str( Dlg ) ) != "" ) {
            Rm( Global_Str( "!DLG_ACT_MSTR" + Str( Dlg ) ) + "/ACTIVE=1" );
            Switch_Win_Id( ActiveWindow );
          }
				}
      }
      break;

    case WM_DESTROY : {
      int dlg = parse_int("/DLG=", parms);
      if( parse_str("/RPOS=", parms) != "")
      {
          struct trect rect;
          GetWindowRect(window, &rect);
          Set_Global_Str( parse_str("/RPOS=", parms), "/XPOS=" + str(rect.left) + "/YPOS=" + str(rect.top));
      }
      if (global_str("!DLG_EXIT_MSTR" + str(dlg)) != "") {
				// run the special exit macro if it exists
        int active_window = window_id;
        str mstr = global_str("!DLG_EXIT_MSTR" + str(dlg));
        Set_global_str("!DLG_EXIT_MSTR" + str(dlg),"");
        RM(mstr + "/EXITDLG=1");
        switch_win_id(active_window);
      }
      Set_Global_Str( "!DLG_DEACT_MSTR" + Str( Dlg ),"" );
      Set_Global_Str( "!DLG_ACT_MSTR" + Str( Dlg ), "" );
			if ( Modeless ) {
				DlgKill( Parse_Int( "/DLG=", Parms ) );
			}
			break;
    }
		case WM_COMMAND :
			if(wparam > 60000)
			{
				SendDlgItemMessage( window, wparam, WM_TRIGGER_POPUP, 0, 0 );
				call check_active;
				result = TRUE;
			}
			else
			{
				switch( wparam )
				{
					case 1 :
					case 998 :
							j = GetDefaultButton( window );
							if(j)
							{
								wparam = j;
								call process_wcmd;
							}
							break;

					case 2 :
							break;

					default:
							call process_wcmd;
				}
			}
			break;
	}
  if (destroy_flag) {
		DestroyWindow(window);
    RetVal = 0;
    return(1);
  }
	return(result);

	{
// PROCESS_WCMD is the main subroutine inside these scoping braces
// DO NOT call any of the other subroutines inside these braces
// from outside the braces!!!!!!!

	process_wcmd:
		int jx, dlg, field_count, c_parm;
    str mstr,
        xstr = "",
        misc;
    struct DlgCtrl ctrl;

		{
			var_parse_int( "/DLG=", parms, dlg );
			field_count = menu_count(dlg);
			call id_menu_item;
			if ( C_Parm > 0 ) {

				int Notice = lParam >> 16;

        MStr = Menu_Item_Str( Dlg,  C_Parm, 1 );
				Result = True;
				switch ( Ctrl.CtrlType ) {
          case DLG_Text :
          case DLG_Integer :
						switch ( Notice ) {
							case en_Change :
								call Process_ChangeMac;
								break;

							case en_SetFocus :
								XStr = "/FOCUS=1";

							case en_KillFocus :
								call Process_FocusMac;
								break;
            }
            break;

          case DLG_DirButton :
          case DLG_Checkbox :
					case DLG_3State :
					case Dlg_RadioButton :
          case DLG_PushButton :
            if ( Notice == BN_CLICKED) {
              call Process_ChangeMac;
            }
            if ( Ctrl.CtrlType == DLG_PushButton ) {
              goto Do_Pushbutton;
            }
            else if ( Ctrl.CtrlType == DLG_DirButton ) {
              call Process_DirButton;
            }
            break;

          case DLG_ListBox :
            switch ( Notice ) {
							case lbn_SetFocus :
								XStr = "/FOCUS=1";

							case lbn_KillFocus :
							case lbn_SelChange :

              	int hCtrl = GetDlgItem( Window, wParam );
                int Active_Window = Window_Id;
                int Sel_Int = SendMessage( hCtrl, LB_GETCURSEL, 0, 0 );
                int Win_Num = SendMessage( hCtrl, WM_ML2_GETLISTBUF, 0, 0 );

              	if ( Win_Num ) {
                	XStr += "/SELINT=" + Str( Sel_Int ) +
											"/SELSTR=" + Double_Slashes( Get_Line_From_Win( Sel_Int + 1, Win_Num ) );
									if ( Notice == lbn_SelChange ) {
                		call Process_ChangeMac;
									}
									else {
										call Process_FocusMac;
									}
              	}
            }
            break;

          case DLG_Choice :
						switch ( Notice ) {
							case cbn_SetFocus :
								XStr = "/FOCUS=1";

							case cbn_KillFocus :
            	case cbn_SelChange :

                int hCtrl = GetDlgItem( Window, wParam );
                int Sel_Int = SendMessage( hCtrl, CB_GETCURSEL, 0, 0 );

                str Sel_Text;

                SendMessageStr( hCtrl, CB_GETLBTEXT, Sel_Int, Sel_Text );
								XStr += "/SELINT=" + Str( Sel_Int ) +
										"/SELSTR=" + Double_Slashes( Sel_Text );
								if ( Notice == cbn_SelChange ) {
									call Process_ChangeMac;
								}
								else {
									call Process_FocusMac;
								}
								break;
            }
            break;

					case DLG_MacroBtnInt :
						call run_int_macro;
						break;

					case DLG_BitmapBtn :
//          case DLG_PushButton :

Do_Pushbutton:
						call process_button;
						break;

					case DLG_BitMapDefine :
						menu_set_str(dlg,c_parm,2,
								Set_Bitmap(menu_item_str(dlg,c_parm, 2), window));
						ctrl.whandle =
							ReBuildMEWButton( window, MEWBTN_RT_RESNAME, menu_item_str(dlg,c_parm,2) ,
											ctrl.whandle,bs_pushbutton, MEWBTN_PUSHBUTTON | MEWBTN_SIZETOBITMAP,
											ctrl.id,
											ctrl.x,
											ctrl.y,
											0,
											0 );
						menu_set_int( dlg, c_parm, 3, make_long(ctrl.id,ctrl.whandle) );
						struct_to_str( mstr, ctrl );
						menu_set_str( dlg, c_parm, 3, mstr );
						call check_active;
						break;

					default:
						result = 0;
				}
			}
			ret;
		}

	id_menu_item:
		c_parm = 1;
		while( c_parm <= field_count )
		{
      if(( menu_item_int( dlg, c_parm, 3) & 0xffff) == wparam)
			{
				MStr = menu_item_str( dlg,  C_Parm, 3);
				Str_To_struct( ctrl, mstr );
				ret;
			}
			++c_parm;
		}
		c_parm = 0;
		ret;

	process_button:
		if(ctrl.flags & DLGF_SubDlgSwitch)
		{
			goto process_subdlg;
		}
		mstr = menu_item_str(dlg,c_parm,1);
		if (jx = xpos("/M=", mstr,1)) {     // Run macro
			mstr =  copy(mstr, jx + 3, max_line_length );
			if (xpos(" ", mstr, 1) == 0) {
				mstr = mstr + " ";
			}
			jx = return_int;
      DlgSaveRetStr( false );
			Rm( MStr + "/DLGHANDLE=" + Str( Window ) + "/DATAHANDLE=" + Str( Dlg) +
					"/CTRLID=" + Str( Ctrl.Id ) );

			mstr = menu_item_str(dlg,c_parm,1);
			mstr = copy(mstr,1,xpos("/M=", mstr,1)  - 1);

      if (return_str == "DESTROY_WINDOW") {
        destroy_flag = 1;
      }
      if (modeless) {
        if (xpos("/R=", mstr, 1)) {
          if(parse_int("/R=", mstr) == 0) {
            destroy_flag = 1;
          }
        }
      }
      if(parse_int("/R=", mstr)) {
        if(return_int) {
          result = FALSE;
        }
      }

      if(parse_int("/SV=", mstr))
      {
        if(return_int)
        {
          menu_set_str(dlg,c_parm,2, return_str);
        }
      }

			return_int = jx;
      DlgSaveRetStr( true );
			call check_active;
    } else {
			if(parse_int("/R=", mstr ) == 2)
			{
				MewHelp_Context (); // (parse_str("/H=", parms ) );
      } else {
        if ((modeless) && (xpos("/R=", mstr, 1)) && (parse_int("/R=", mstr) == 0)) {
          return_int = 0;
          destroy_flag = 1;
        } else {
          PostMessage( GetWindow(window, GW_OWNER) , WM_MEW_DLGRETURN, wparam, lparam );
        }
			}
			result = TRUE;
		}
		ret;

Process_DirButton:
  {
    mstr = menu_item_str( dlg,  C_Parm, 1);
    jx = parse_int("/SID=", mstr );
    if(jx)
    {
      GetDlgItemText( window, jx, mstr, 254 );
      if(SelectDirectory(window, mstr, "Select Directory", "", 0 ))
      {
        SetDlgItemText( window, jx, mstr );
      }
			SetFocus( GetDlgItem( window,wparam ) );
    }
    ret;
  }

process_subdlg:
		DlgProcessSub( window, dlg, c_parm );
		result = true;
		ret;

 run_int_macro:
		jx = XPos('/M=',menu_item_str( dlg,  C_Parm, 1  ),1);
		if(  jx  ) {
	/* Check to see if command line parameters already exist in the macro name.  If
	so, don't add a space between macro name and the params we are adding */
			MStr = Copy(menu_item_str( dlg,  C_Parm, 1  ),Return_Int + 3, 255);
			if(  (XPos(' ',MStr,1) == 0)  ) {
				MStr = MStr + ' ';
			}
			Return_int = menu_item_int( dlg, C_PARM, 2);
			jx = return_int;
			rm(mstr + "/DLGHANDLE=" + str(window) + "/DATAHANDLE=" + str(dlg) );
			if(  return_int > 0  ) {
				menu_set_int( dlg, c_parm, 2, return_int );
			}
			return_int = jx;
			call check_active;
		}
		ret;


Process_ChangeMac:
    if ( Global_Int( "!DLG_UPDATING_CTRL" ) ) {
      ret;
    }
    if ( XPos( "/CHANGEMAC=", MStr, 1 ) ) {
      MStr = Parse_Str( "/CHANGEMAC=", MStr );

RunMac:
      if ( XPos( " ", Mstr, 1 ) == 0 ) {
        MStr += " ";
      }
      Rm( MStr + "/DLGHANDLE=" + Str( Window ) + "/DATAHANDLE=" + Str( Dlg ) +
					"/CTRLID=" + Str( Ctrl.Id ) + XStr );
      Result = Return_Int;
    }
    ret;


Process_FocusMac:
  	if ( Global_Int( "!DLG_UPDATING_CTRL" ) ) {
    	ret;
  	}
  	if ( XPos( "/FOCUSMAC=", MStr, 1 ) ) {
    	MStr = Parse_Str( "/FOCUSMAC=", MStr );
			goto RunMac;
  	}
  	ret;
	}


Check_Active:
		if(!IsWindowEnabled( window ) )
		{
			EnableWindow( window, TRUE );
		}
		if( GetActiveWindow() != window )
		{
			BringWindowToTop( window );
		}
		update_status_line;
		ret;

}

int DlgExecute(  int dlg,
								 int startid,
								 str title[80],
								 str helpindex[80],
								 str misc,
								 int flags
							 )
{
	str MStr;
	str T_Str;
	str Loop_Parm_Str;

	/* The following are special macros that can be optionally specified
   	to run at various stages in this macro.  The terminology used to
   	describe them is intended to be generic and not platform-specific
	*/
	// /DEACTIVEMAC= is a macro to be run if a modeless dialog is deactivated
  str Deactive_MStr = Parse_Str( "/DEACTIVEMAC=", Misc );

	// /ACTIVAEMAC= is a macro to be run if a modeless dialog is activated
	str Active_MStr = Parse_Str( "/ACTIVEMAC=", Misc );

	// /INITMAC= is a macro to be run before the dialog box appears
	str Init_MStr = Parse_Str( "/INITMAC=", Misc );

	// /PRELOOPMAC= is a macro to be run after the dialog box appears and before keystrokes, etc. are accepted
	str PreLoop_MStr = Parse_Str( "/PRELOOPMAC=", Misc );

	/* /LOOPMAC= is a macro to be run during the main execution of dialog box and can be used to intercept an event like a keystroke
   The macro is expected to set value of return int upon exit to
   one of the following values:
          0 = behave normally
          1 = don't run the macro any more
          2 = exit the dialog box
          3 = don't process the event
	*/
	str Loop_MStr = Parse_Str( "/LOOPMAC=", Misc );

	// /EXITMAC= is a macro to be run upon exiting the dialog box
	str Exit_MStr = Parse_Str( "/EXITMAC=", Misc );


	int	t_refresh = Refresh,
			field_count,    /* The number of fields */
			C_Parm,         /* The parm string being worked on */
			old_win = cur_window,
			result = 0,
			dialog_done = FALSE,
			hooked = 0,
			loop_return_int,
			t_int,
			run_loop_mac = 0,
			run_exit_mac = 0,
			message_result
					 ;

			int main_dlg;

			struct DlgCtrl ctrl;

			struct TMsg msg;

      struct TRECT dlg_rect;


		MStr = menu_item_str( dlg,  1, 3);
		Str_To_struct( ctrl, mstr );

		if(!ctrl.whandle) {
			main_dlg = DlgBuild( dlg, title, helpindex, misc , flags );
		} else {
			main_dlg = ctrl.whandle;
		}

		refresh = false;
		working;
		//Var_Parse_Str('/RGS=',MParm_Str, Rgs);

		Set_Global_Int('MENU_LEVEL', Global_Int('MENU_LEVEL') + 1);

			/* Get the count of the fields */
		field_count = menu_count(dlg);

		mstr = parse_str( "/HOOK=", misc );
/*
		if ( mstr == "" )
		{
			mstr = "DlgMessageProc";
		}
		else
			hooked = TRUE;
*/
		if ( mstr == "" ) {
			mstr = "DlgMessageProc";
			t_str = "";
		} else {
			if (t_int = xpos(" ",mstr,1)) {
				t_str = copy(mstr, t_int + 1, 255);
				mstr = copy(mstr, 1, t_int - 1);
			}
			hooked = TRUE;
		}

		Loop_Parm_Str = "/HDLG=" + str(main_dlg) +
                  "/DLGHANDLE=" + str(main_dlg) +
									"/DLG=" + str(dlg) +
                  "/DATAHANDLE=" + str(dlg) +
									"/M=" + str((flags & DLG_Modeless) != 0)  +
									"/H=" +  helpindex  + t_str;

		if ( Svl( Init_Mstr ) ) {
			if ( !XPos( " ", Init_MStr, 1 ) ) {
				Init_MStr += " ";
			}
			Init_Mstr += Loop_Parm_Str;
		}

		if ( Svl( PreLoop_MStr ) ) {
			if ( !XPos( " ", PreLoop_MStr, 1 ) ) {
				PreLoop_MStr += " ";
			}
			PreLoop_Mstr += Loop_Parm_Str;
		}

		if ( Svl( Loop_MStr ) ) {
			if ( !XPos( " ", Loop_MStr, 1 ) ) {
				Loop_MStr += " ";
			}
			Loop_MStr += Loop_Parm_Str;
			Run_Loop_Mac = True;
		}

		if ( Svl( Exit_MStr ) ) {
			if ( !XPos( " ", Exit_MStr, 1 ) ) {
				Exit_MStr += " ";
			}
			Exit_Mstr += Loop_Parm_Str;
			Run_Exit_Mac = True;
		}
    Set_Global_Str("!DLG_EXIT_MSTR" + str(dlg), exit_mstr);

    if ( Svl( Deactive_MStr ) ) {
			if ( !XPos( " ", Deactive_MStr, 1 ) ) {
				Deactive_MStr += " ";
			}
      Deactive_MStr += Loop_Parm_Str;
		}
    Set_Global_Str( "!DLG_DEACT_MSTR" + Str( Dlg ), Deactive_MStr );

    if ( Svl( Active_MStr ) ) {
			if ( !XPos( " ", Active_MStr, 1 ) ) {
				Active_MStr += " ";
			}
      Active_MStr += Loop_Parm_Str;
		}
    Set_Global_Str( "!DLG_ACT_MSTR" + Str( Dlg ), Active_MStr );

		if (svl(init_mstr)) {
			RM(init_mstr);
		}

		SubClass_With_Macro(main_dlg, mstr, "/DLG=" + str(dlg) +
				"/M=" + str((flags & DLG_Modeless) != 0)  +
        "/H=" +  helpindex  + "/RPOS=" + parse_str("/RPOS=", misc) + t_str);

		SendMessage(main_dlg, WM_COMMAND, DLG_WCMD_INIT, 0 );

		refresh =  TRUE;
		ShowWindow( main_dlg, sw_shownormal );

    if ((ctrl.ux != 0) || (ctrl.uy != 0)) {
      GetWindowRect(main_dlg, &dlg_rect);
      MoveWindow(main_dlg, ctrl.ux, ctrl.uy,
            dlg_rect.right - dlg_rect.left,
            dlg_rect.bottom - dlg_rect.top, true);
    }

		update_status_line;

		msg.wparam = startid;
		call id_menu_item;

		SetFocus(ctrl.whandle);
		switch( ctrl.ctrltype )
		{
			case DLG_Text :
			case DLG_Integer :
			case DLG_Hex :
			case DLG_Realnumber :
              if( parse_str("/HISTORY=",menu_item_str( dlg,  C_Parm, 1)) != "")
              {
                SendMessage( ctrl.whandle, CB_SETEDITSEL, 0, Make_Long( 0,  0xffff ) );
              }
              else
              {
                SendMessage( ctrl.whandle, EM_SETSEL, 0, Make_Long( 0,  0xffff ) );
              }
							break;

			case DLG_PushButton :
			case DLG_BitmapBtn :
							SetDefaultButton( main_dlg, ctrl.id );
							break;

		}

		if( flags & DLG_Modeless)
		{
      if (svl(preloop_mstr)) {
        RM(preloop_mstr);
      }
			goto exit;
		}

    int downer = GetWindow( main_dlg, GW_OWNER );


    /*
    while ( PeekMessage( &msg, 0,WM_MEW_DLGRETURN,WM_MEW_DLGRETURN, PM_REMOVE )) {
// just to get the dialog box drawn
		}
     */
		if (svl(preloop_mstr)) {
			RM(preloop_mstr);
		}


    while (!dialog_done) {
			if (run_loop_mac) {
				loop_return_int = return_int;
				return_int = 0;
				RM(loop_mstr);
				switch (return_int) {
					case 1 : // turn macro off
						run_loop_mac = 0;
						break;
					case 2 : // exit loop
						dialog_done = 1;
					case 3 : // skip loop - use this one with caution
						return_int = loop_return_int;
						goto LOOP_SKIP;
						break;
				}
				return_int = loop_return_int;

//USE A PEEK MESSAGE IF WE ARE RUNNING THE MACRO
				message_result = peekmessage( &msg, 0, 0, 0, PM_REMOVE );
			} else {
				message_result = getmessage( &msg, 0, 0, 0 );
			}
//      if(getmessage( &msg, 0, 0, 0 ))
			if(message_result)
			{
        if ( (msg.message == WM_MEW_DLGRETURN) && (msg.hwnd == downer ))
				{
					if ( (msg.wparam == 1) || (msg.wparam  == 998) )
					{
						result = 1;
						break;
					}
					else if(msg.wparam == 2 )
					{
						result = 0;
						break;
					}
					else
					{
						call id_menu_item;
						if(c_parm > 0)
						{
							switch ( ctrl.ctrltype )
							{
								case DLG_PushButton :
								case DLG_BitmapBtn :
										mstr = menu_item_str(dlg,c_parm,1);
										if(xpos("/R=",mstr,1))
										{
											var_parse_int("/R=", mstr, result );
											if (result == 2) {
												MewHelp_Context (); //(helpindex);
												break;
											}
										}
										else
										{
											result = ctrl.id;
										}
										dialog_done = TRUE;
										break;
							}
							update_status_line;
						}
					}
				}
	//      else if ((msg.message == WM_KEYDOWN) && (msg.wparam == VK_F1))
	//      {
	//        mewhelp(helpindex);
	//      }
				else if( !IsDialogMessage( main_dlg, &msg) )
				{
						translatemessage( &msg );
						dispatchmessage( &msg );
				}
			}
LOOP_SKIP:
		}

	message_exit:
		refresh = false;

		DlgSetFields( dlg );
/*
		if (svl(exit_mstr)) {
			RM(exit_mstr);
		}
*/
	
	big_exit2:
    Destroy_Mew_Dlg(main_dlg);
  /*
    while ( PeekMessage( &msg, 0,WM_MEW_DLGRETURN,WM_MEW_DLGRETURN, PM_REMOVE ))
		{
		}
   */
		goto exit;



	id_menu_item:
		c_parm = 1;
		while( c_parm <= field_count )
		{
			if(( menu_item_int( dlg, c_parm, 3) & 0xfff) == msg.wparam)
			{
				MStr = menu_item_str( dlg,  C_Parm, 3);
				Str_To_struct( ctrl, mstr );
				ret;
			}
			++c_parm;
		}
		c_parm = 0;
		ret;


	



	set_main_dlg:
		EnableWindow( main_dlg, TRUE );
		BringWindowToTop( main_dlg );
		ret;


	get_help:
		ret;

	

	EXIT:
		if(  ((result == 0) & (Parse_Int('/VA=',misc) == True))  ) {
	/* Verify abort */
			RM('VERIFY /S=1/H=' + parse_str('/H=', mparm_str) +
					'/T=Are you sure you want to cancel these changes?');
			if(  (Return_Int == 0)  ) {
			 // Goto MAIN_LOOP;
			} else {
				Return_Int = 0;
			}
		}

		if(  (cur_window != old_win) & (parse_int('/NOW=', mparm_str) == 0)  ) {
			switch_window( old_win );
		}

		Set_Global_Int('MENU_LEVEL', Global_Int('MENU_LEVEL') - 1);
		refresh = t_refresh;
	big_exit:

		update_status_line;

	return(result);
}

int DlgGetWhandle(int dlg) {
/*
 This macro is retained for downward compatibilty and is not
 recommended to be used for any new code
*/
	struct DlgCtrl ctrl;

	Str t_str[max_line_length] = menu_item_str(dlg, 1, 3);
	str_to_struct(ctrl, t_str);
	RETURN(ctrl.whandle);
}

void DlgGetStruct(int dlg, m_int, struct DlgCtrl &t_struct) {
/*
 Intended to be called from several macros that follow and not
 externally
*/
	Str t_str[max_line_length] = menu_item_str(dlg, m_int, 3);
	str_to_struct(t_struct, t_str);
	RETURN();
}

int DlgGetId(int dlg, seq_num) {
/*******************************************************************************
                                Multi-Edit MACRO

 NAME: DlgGetId()

 RETURNS: The control id corresponding to the "array index" for a dialog control

 PARAMETERS: dlg - The dialog data handle (not the Windows handle)
            seq_num - The "array index" of the menu item data structure for the
                      desired control.

*******************************************************************************/
	struct DlgCtrl ctrl;
	DlgGetStruct(dlg, seq_num, ctrl)
	RETURN(ctrl.id);
}

int DlgIdToSeq(int dlg, ctrl_id) {
/*******************************************************************************
                                Multi-Edit MACRO

 NAME: DlgIdToSeq()

 RETURNS: The "array index" of the menu item data structure corresponding to the
          to ctrl_id

 PARAMETERS: dlg - The dialog data handle (not the Windows handle)
            ctrl_id - The control id of the control

*******************************************************************************/
	int field_count = menu_count(dlg),
			jx;
	struct DlgCtrl ctrl;

	for( jx = 2; jx <= field_count; jx++ ) {
    DlgGetStruct(dlg, jx, ctrl);
    if (ctrl.id == ctrl_id) {
			RETURN(jx);
		}
	}
	RETURN(0);
}

void DlgSetFocus( int Dlg, int CtrlId ) {
/******************************************************************************
															 Multi-Edit Macro
															 24-Jul-95  10:21

  Function: Set the input focus to CtrlId.
  Entry   : int Dlg				- The dialog data handle ( not the Windows handle )
						int CtrlId		- The control id number
  Exit    : None

							 Copyright (C) 1995 by American Cybernectic, Inc.
********************************************************************( ldh )***/

	struct DlgCtrl Ctrl;

  DlgGetStruct( Dlg, 1, Ctrl );
  if ( Ctrl.WHandle ) {
    SetFocus( GetDlgItem( Ctrl.WHandle, CtrlId ) );
  }
}  // DlgSetFocus

void DlgSetActiveWindow( int Dlg ) {
/******************************************************************************
															 Multi-Edit Macro
															 24-Jul-95  00:06

  Function: Makes the dialog window for Dlg the active window.
  Entry   : int Dlg				- The dialog data handle ( not the Windows handle )
	Exit		: None

							 Copyright (C) 1995 by American Cybernectic, Inc.
********************************************************************( ldh )***/

	struct DlgCtrl Ctrl;

	DlgGetStruct( Dlg, 1, Ctrl );
	if ( Ctrl.WHandle ) {
		SetActiveWindow( Ctrl.WHandle );
	}
}  // DlgSetActiveWindow

void DlgEnableCtrl( int Dlg, int CtrlId, int Enable ) {
/******************************************************************************
															 Multi-Edit Macro
															 24-Jul-95  10:15

  Function: Enables or Disables an existing dialog control for input.
  Entry   : int Dlg   		- The dialog data handle ( not the Windows handle )
						int CtrlId		- The control id number
						int Enable		- True to enable control, False to disable control.
  Exit    : None

							 Copyright (C) 1995 by American Cybernectic, Inc.
********************************************************************( ldh )***/

	struct DlgCtrl Ctrl;

  DlgGetStruct( Dlg, 1, Ctrl );
  if ( Ctrl.WHandle ) {
    EnableWindow( GetDlgItem( Ctrl.WHandle, CtrlId), Enable );
  }
}  // DlgEnableCtrl

int DlgCtrlIsEnabled( int Dlg, int CtrlId ) {
/******************************************************************************
															 Multi-Edit Macro
															 24-Jul-95  10:56

  Function: Used to determine if a control is active and can receive input
  Entry   : int Dlg				- The dialog data handle ( not the Windows handle )
						int CtrlId		- The control id number
  Exit    : int
							True				- Control is enabled
							False				- Contorl is not enabled

							 Copyright (C) 1995 by American Cybernectic, Inc.
********************************************************************( ldh )***/

	struct DlgCtrl Ctrl;

	int Result = 0;

  DlgGetStruct( Dlg, 1, Ctrl );
  if ( Ctrl.WHandle ) {
    Result = IsWindowEnabled( GetDlgItem( Ctrl.WHandle, CtrlId ) );
  }
  return ( Result );

}  // DlgCtrlIsEnabled

void DlgUpdateCtrl( int Dlg, int Ctrl_Id, int Seq_Int ) {
/*******************************************************************************
                                Multi-Edit MACRO

 NAME: DlgUpdateCtrl()

 RETURNS: Nothing

 DESCRIPTION: Updates a control from the data in its associated menu_item data
              structure

 PARAMETERS: dlg - The dialog data handle (not the Windows handle)
            ctrl_id - The control id of the control
            seq_int - If 0, ctrl_id will be used to find the correct menu_item.
                      if it is non-zero, it is expected to have the value of the
                      menu item.  The value 0 is most often used.

 *******************************************************************************/

  int T_Int;

	struct DlgCtrl Ctrl;

  Set_Global_Int( "!DLG_UPDATING_CTRL", 1 );

  if ( Seq_Int < 2 ) {
    if ( !( Seq_Int = DlgIdToSeq( Dlg, Ctrl_Id ) ) ) {
      Set_Global_Int( "!DLG_UPDATING_CTRL", 0 );
      return ( );
    }
  }
  DlgGetStruct( Dlg, Seq_Int, Ctrl );
  switch ( Ctrl.CtrlType ) {
    case dlg_Text :
    case dlg_Static :
      if ( Ctrl.Flags & dlgf_es_MultiLine) {
        T_Int = Window_Id;
        if ( Switch_Win_Id( Parse_Int( "/WID=", Menu_Item_Str( Dlg, Seq_Int, 1 ) ) ) ) {
          Tof;
          Str_Block_Begin;
          Eof;
          int bhandle;
          TextToBuffer(bhandle, 0xffff, FALSE);
          int tptr = GlobalLock(bhandle);
          SendMessage(ctrl.whandle, WM_SETTEXT, 0, tptr);
          GlobalUnlock(bhandle);
          GlobalFree(bhandle);
          switch_win_id(t_int);
        }
      }
			else {
        str t_str = menu_item_str(dlg, seq_int, 2);
        SendMessageStr(ctrl.whandle, WM_SETTEXT, 0, t_str);
      }
      break;

    case DLG_Integer : {
      str t_str[10] = str(menu_item_int(dlg, seq_int, 2));
      SendMessageStr(ctrl.whandle, WM_SETTEXT, 0, t_str);
      break;
    }
    case DLG_Checkbox :
		case DLG_3State :
      SendMessage(ctrl.whandle, BM_SETCHECK, menu_item_int(dlg, seq_int, 2), 0);
      break;

    case DLG_Choice :
      T_Int = Menu_Item_Int( Dlg, Seq_Int, 2 );
      if ( T_Int > 0 ) {
        --T_Int;
      }
      SendMessage( Ctrl.WHandle, cb_SetCurSel, T_Int, 0 );
      break;

    case DLG_ViewTextBox :
      RedrawWindow(ctrl.whandle , 0, 0, rdw_Invalidate );
      break;

    case DLG_ListTextBox :
    case DLG_ListBox :

      if (t_int = SendMessage(ctrl.whandle, WM_ML2_GETLISTBUF, 0 ,0)) {
        int active_window = window_id,
            is_empty;

        switch_window(t_int);
        mark_pos;

        tof;
        is_empty = at_eof;
        eof;
        if (c_col == 1) {
          up;
        }
        ListSetCount(ctrl.whandle, c_line);
        goto_mark;
        if (!is_empty) {
          SendMessage(ctrl.whandle, LB_SETCURSEL ,c_line - 1 ,0);
        }
        switch_win_id(active_window);
      }
      break;
  }
  Set_Global_Int("!DLG_UPDATING_CTRL", 0);
  Return();
}

void DlgInsertText(int Dlg, ctrl_id, str t_str) {
/*******************************************************************************
                                Multi-Edit MACRO

 NAME: DlgInsertText()

 RETURNS: Nothing

 DESCRIPTION: Inserts the text in t_str into a Dlg_text type control

 PARAMETERS: dlg - The dialog data handle (not the Windows handle)
            ctrl_id - The control id of the control
            t_str - the string to insert

 *******************************************************************************/
	struct DlgCtrl ctrl;
  int index;

  DlgGetStruct(dlg, DlgIdToSeq(dlg, Ctrl_id), ctrl);
  switch (ctrl.ctrltype) {
    case DLG_Text :
      for (index = 1; index <= Svl(t_str); ++index) {
        SendMessage(ctrl.whandle, WM_CHAR, ascii(str_char(t_str, index)), 0);
      }
      break;
  }
}

void DlgChoice2Win( int Dlg, int CtrlId ) {
/******************************************************************************
															 Multi-Edit Macro
															 24-Jul-95  10:52

  Function: Puts all the choices in a dlg_Choice type control into the current
						MEW window
  Entry   : int Dlg				- The dialog data handle ( not the Windows handle )
						int CtrlId		- The control id number
  Exit    : None

							 Copyright (C) 1995 by American Cybernectic, Inc.
********************************************************************( ldh )***/

	struct DlgCtrl Ctrl;

  DlgGetStruct( Dlg, DlgIdToSeq( Dlg, CtrlId ), Ctrl );
  if ( Ctrl.CtrlType == dlg_Choice ) {

    int Index = SendMessage( Ctrl.WHandle, cb_GetCount, 0, 0 );
    int SelInt = SendMessage( Ctrl.WHandle, cb_GetCurSel, 0, 0 ) + 1;

    str TStr;

    for ( --Index; Index >= 0; --Index ) {
      SendMessageStr( Ctrl.WHandle, cb_GetLbText, Index, TStr );
      if ( !At_Eof ) {
        Cr;
        Up;
      }
      Put_Line( TStr );
    }
    Goto_Line( SelInt );
  }
}  // DlgChoice2Win

void DlgWin2Choice( int Dlg, int CtrlId ) {
/******************************************************************************
															 Multi-Edit Macro
															 24-Jul-95  10:46

  Function: Updates a dlg_Choice type control from line of text in the current
						MEW window.

  Entry   : int Dlg				- The dialog data handle ( not the Windows handle )
						int CtrlId		- The control id number
  Exit    : None

							 Copyright (C) 1995 by American Cybernectic, Inc.
********************************************************************( ldh )***/

	struct DlgCtrl Ctrl;

  int Index = 0;
	int SelInt;

  str TStr;

  DlgGetStruct( Dlg, DlgIdToSeq( Dlg, CtrlId ), Ctrl );
  if ( Ctrl.CtrlType == dlg_Choice ) {
		// delete current list
		SendMessage( Ctrl.WHandle, cb_ResetContent, 0, 0 );
    SelInt = C_Line - 1;
    Tof;
    while ( !At_Eof ) {
      TStr = Get_line( );
      SendMessageStr( Ctrl.WHandle, cb_AddString, 0, TStr );
      Down;
    }
    SendMessage( Ctrl.WHandle, cb_SetCurSel, SelInt, 0 );
  }
}  // DlgWin2Choice

void DlgGetCtrlPos( int Dlg, int Ctrl_Id, int &X, int &Y ) {
/*******************************************************************************
                                Multi-Edit MACRO

 NAME: DlgGetCtrlPos()

 RETURNS: Nothing, but sets the value of the parameters x and y

 DESCRIPTION: Used to get the screen coordinates of a control in a dialog box

 PARAMETERS: dlg - The dialog data handle (not the Windows handle)
            ctrl_id - The control id of the control
            x, y - these 2 are set to the coordinates

 *******************************************************************************/

  struct TPoint Tp;
	struct DlgCtrl Ctrl;

  int hDlg;

  DlgGetStruct( Dlg, 1, Ctrl );
  hDlg = Ctrl.WHandle;

  DlgGetStruct( Dlg, DlgIdToSeq( Dlg, Ctrl_Id ), Ctrl );
  Tp.X = Ctrl.X;
  Tp.Y = Ctrl.Y;
  ClientToScreen( hDlg, &Tp );
  X = Tp.X;
  Y = Tp.Y;

} // DlgGetCtrlPos

void DlgSetPos( int dlg, x, y) {
/*******************************************************************************
                                Multi-Edit MACRO

 NAME:  DlgSetPos

 RETURNS:

 DESCRIPTION:
        Allows the user to set the postion of a dialog box.  This
        can only be used after a DlgCreate() and its corresponding
        DlgExecute()

 PARAMETERS: dlg - The dialog data handle (not the Windows handle)
            x, y - the x and y coordinates in pixels

 *******************************************************************************/

  struct DlgCtrl ctrl;
	str mstr;

  mstr = Menu_Item_Str(dlg, 1, 3);
  Str_To_Struct(ctrl, mstr);

  ctrl.ux = x;
  ctrl.uy = y;

  Struct_To_Str( mstr, ctrl );
  Menu_Set_Str( dlg, 1, 3, mstr );
}

int DlgGetHandle( int Dlg, int CtrlId )
/******************************************************************************
                               Multi-Edit Macro
                               26-Jan-96  14:01

  Function: Return the Windows handle for CtrlId
  Entry   : int Dlg     - Data dialog handle
            int CtrlId  - Control Id

  Exit    : int         - The Windows handle for CtrlId

               Copyright (C) 1996 by American Cybernetics, Inc.
********************************************************************( ldh )***/
{
  struct DlgCtrl Ctrl;

  DlgGetStruct( Dlg, DlgIdToSeq( Dlg, CtrlId ), Ctrl );
  return ( Ctrl.WHandle );

}  // DlgGetHandle