/*

CLASS {AL4_form|s_csharp},
NATIVE, UNTESTED, BITWISE :

IMPORT: {Screen}, {Form}, {Control}, {Listbox}, {Dialog} .
IMPORT: {Geometry}, {Date_time}, {Long_operation}, {System_functions} .
IMPORT, ANYWAY: {Fake_parameters}, {Label}, {String_functions} . 

NATIVE: @
        "using System.Windows.Forms;"
		"using System.Drawing;"
		.
        
FUN out_system_stack, PUBLIC, UNCOOKED :.        

*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Windows.Forms;

using System.Runtime.InteropServices;
using System.IO;

using System.Threading;

using AL4;
using AL4_project;

namespace AL4
{

    public partial class AL4Form : Form
    {

        public int Handle_form;
        public Ref_obj AL4Object;
        
		public bool No_borders;
		public byte Alpha;
        public bool adjusting_columns;
        public bool button_in_taskbar;
        public bool defined_button_in_taskbar;
    
        public System.ComponentModel.IContainer Get_components
        {
            get { return components; }
        }
        public static List<Object> All_descriptors = new List<object>();
        public static int Free_position_in_descr_list = -1;

        public static int AllocDescriptor(Object obj)
        {
            if (All_descriptors.Count == 0)
                All_descriptors.Add(new Control());
            if (Free_position_in_descr_list >= 0)
            {
                int Result = Free_position_in_descr_list;
                Free_position_in_descr_list = (int)All_descriptors[Result];
                All_descriptors[Result] = obj;
                return Result;
            }
            All_descriptors.Add(obj);
            return All_descriptors.Count - 1;
        }

        public static void ReleaseDescriptor(int idx)
        {
            if (idx <= 0) return;
            All_descriptors[idx] = (Object)Free_position_in_descr_list;
            Free_position_in_descr_list = idx;
        }

        /*
        
        FUN Control_by_handle(INT H|andle_control)
        ==> {Control}, NATIVE : @
        "	Object obj = AL4Form.All_descriptors[(int)X_H];"
        "	if (obj is Control)"
        "	{"
        "		Control c = (Control)obj;"
        "		Ref_obj result = (Ref_obj) c.Tag;"
        "		return result;"
        "	}"
        "	return C_Control.NoneObj_C_Control.hard_link;" .
        
        // Called when the {Screen} object is created. Used to setup global things
        //------------------------------------------------------------------------
        
        FUN Screen_created({Screen} S|creen_object_dummy),
        NATIVE : @
        	"	if (Methods_C_AL4_form.Screen_object_ref_== null)"
        	"	{"
        	"		Methods_C_AL4_form.Screen_object_ref_ = X_S;"
        	"		Methods_C_AL4_form.Screen_object_ref_.Count += 2;"
        	"	}"
        	"	else"
        	"	{"
			"	    Object_assign_weak("
			"		    ref Methods_C_AL4_form.Screen_object_ref_, X_S.Obj);"
        	"	}"
            "   AL4Form.Do_Screen_created(X_S);" .
            
		FUN Screen_destroyed({Screen} Screen|_object_dummy) : .
        */
        public static bool screen_already_created;
        
        public static void Do_Screen_created(Ref_obj X_Screen)
        {
            if (!screen_already_created)
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);                
                screen_already_created = true;
            }
            Screen_handler sh = new Screen_handler(X_Screen);
            AL4_system.long_operation_handlers.Add(sh);
        }
        


        /*
        
		FUNCTION do_long_operation(
		{Form} Caller|_form,
		{Long_operation} Exist|ing_long_operation) ==> {Long_operation} RESULT
		|created_new, NEW, NATIVE, PUBLIC :
		//DEBUG: << "do_long_operation"#NL ;
		NATIVE @
		"RESULT = AL4Form.call_do_long_operation(X_Caller, X_Exist);" 
		.
		
		*/
		
	public static Ref_obj call_do_long_operation(Ref_obj X_Caller, Ref_obj X_Exist) 
	{
//	//?{Long_operation}
//AL4_system.WriteLine("do_long_operation:1");
        Ref_obj result = C_Long_operation.M_do_long_operation_synchronously(
        	X_Caller, X_Exist);
//AL4_system.WriteLine("result=" + result);
		return result;
//	//.
	}
		
		/*
        
        // running application until it is terminated
        //-------------------------------------------
        
		NATIVE: "public static Ref_obj Screen_object_ref_;" .   
		NATIVE: "public static bool App_running;" .

        
        FUN Run_screen_forms({Screen} Screen|_object), NATIVE :
            //INT f|orm_handle = Screen.Main_form_.Handle
            NATIVE @
            "	 Object_assign_weak("
            "		ref Methods_C_AL4_form.Screen_object_ref_, X_Screen.Obj);"
            "	 Methods_C_AL4_form.App_running = true;"
            "    AL4Form.Do_Application_Run();"
            "	 Methods_C_AL4_form.App_running = false;" .
            
	    FUN Application_terminated ==> BOOL, NATIVE : @
		"RESULT = !Methods_C_AL4_form.App_running;" .
            
            
		FUN Get_screen|_object ==> {Screen}, NATIVE : @
			"	if (Methods_C_AL4_form.Screen_object_ref_ != null)"
			"		RESULT = Methods_C_AL4_form.Screen_object_ref_;" .
		
        FUN Set_main_form_handle(
        INT H|andle_of_main_form), NATIVE : @
			"	AL4Form.Main_form_handle = (int)X_H;" 
	        "	if (X_H == 0) return;"
	        "	AL4Form F = (AL4Form)AL4Form.All_descriptors[(int)X_H];"
	        "	if (F == null) return;"
	        "	if (!F.defined_button_in_taskbar)"     
	        "		F.button_in_taskbar = true;"
	        "	F.ShowInTaskbar = true;" .
			
		FUN Ticks_from_power_up ==> INT, NATIVE : @
			"	RESULT = Environment.TickCount & Int32.MaxValue;" .
		
			
        */
        public static bool Application_running;
        public static int Main_form_handle;
        public static void Do_Application_Run()
        {
            AL4Form form = null;
            if (Main_form_handle > 0)
            	form = (AL4Form)AL4Form.All_descriptors[Main_form_handle];
            Application_running = true;
            try
            {
                if (form != null)
                    Application.Run(form);
                else Application.Run();
            }
            finally
            {
                Application_running = false;
            }
        }
        
	    public static void invalidate_controls(Control C)
	    {
	    	for (int i = 0; i < C.Controls.Count; i++)
	    	{
	    		Control c = C.Controls[i];
	    		if (!c.Visible) continue;
	    		c.Invalidate();
	    		invalidate_controls(c);
	    	}
	    }

	    public static void invalidate_all(Form F)
	    {
	    	for (int i = 0; i < F.Controls.Count; i++)
	    	{
	    		Control c = F.Controls[i];
	    		if (!c.Visible) continue;
	    		c.Invalidate();
	    		invalidate_controls(c);
	    	}
	    }

/*
------------------------------------------------- 'single instance applications'

FUN Register_instance(
	STR Uniq|ue_string,
	STR Command_line|_to_pass_to_the_first_running_instance) ==> BOOL, NATIVE
	:
@	"	RESULT = AL4Form.register_instance(X_Uniq, X_Command_line);" .

FUN Unregister_instance, NATIVE:
@	"	AL4Form.unregister_instance();" .
 	*/
	
	public static uint registered_msg;	
	public static IntPtr first_inst_mutex;
	
	[DllImport("kernel32.dll", SetLastError=true)]
	static extern bool CloseHandle(IntPtr Handle);
		
	public static void unregister_instance()
	{
	 	if (AL4Form.first_inst_mutex != (IntPtr)0)
	 	{
	 		CloseHandle(AL4Form.first_inst_mutex);
	 		first_inst_mutex = (IntPtr)0;
	 	}
	}
 	/*

FUN Main_form_running({Form} M|ain_form), NATIVE :
@	"	AL4Form.main_form_running(X_M);" .

	*/
	public static void parse_command_parameters(string p)
	{
		DynAStr a = new DynAStr();
		for (int i = 0; i < p.Length; i++)
		{
			if (p == "") break;
			if (p[0] == '"')
			{
				p = p.Substring(1);
				int e = p.IndexOf('"');
				if (e >= 0) 
				{
					string item1 = p.Substring(0, e);
					a.Add(item1);
					p = p.Substring(e+1).TrimStart();
					continue;
				}
			}
			int e2 = p.IndexOf(' ');
			if (e2 >= 0)
			{
				string item2 = p.Substring(0, e2);
				a.Add(item2);
				p = p.Substring(e2+1).TrimStart();
				continue;
			}
			string item3 = p;
			a.Add(item3);
			break;
		}
		C_Fake_parameters.M_Set_parameters(a);
	}	

	public bool can_handle_another_instance_notify;

	public static void main_form_running(Ref_obj X_M)
	{
	 	if (registered_msg != 0)
	 	{
	 		AL4Form f = (AL4Form)AL4Form.All_descriptors[
	 			(int)((C_Form)(X_M.Obj)).F_Handle];
	 		f.can_handle_another_instance_notify = true;
	 	}	
	}
	
	public static string Unique_id;
	
	[DllImport("kernel32.dll")]
	static extern IntPtr CreateMutex(IntPtr lpMutexAttributes, bool bInitialOwner,
		string lpName);
		
	[DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)]
	static extern uint RegisterWindowMessage(string lpString);
	
	[DllImport("kernel32.dll", SetLastError=true)]
	static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);
	const UInt32 WAIT_TIMEOUT = 0x102;
	
	[DllImport("kernel32.dll", SetLastError=true)]
	[PreserveSig]
	public static extern uint GetModuleFileName(
		[In] IntPtr hModule,
		[Out] StringBuilder lpFileName,
		[In] [MarshalAs(UnmanagedType.U4)] int nSize);
		
	[DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)]
	static extern IntPtr CreateFile(
		[MarshalAs(UnmanagedType.LPTStr)] string filename,
		uint access,
		uint share,
		IntPtr securityAttributes,
		uint creationDisposition,
		uint flagAndAttributes,
		IntPtr TemplateFile);
		
	const uint GENERIC_READ = 0x20000 | 1 | 0x80 | 8 | 0x100000;
	const uint GENERIC_WRITE = 0x20000 | 2 | 0x100 | 0x10 | 4 | 0x100000;
	const uint FILE_SHARE_READ = 1;
	const uint FILE_SHARE_WRITE = 2;
	const uint OPEN_EXISTING = 3;
	const uint FILE_ATTRIBUTE_NORMAL = 0x80;
	const short INVALID_HANDLE_VALUE = -1;
	
	[DllImport("kernel32.dll")]
	static extern unsafe bool ReadFile(IntPtr hFile, IntPtr bytes,
		uint nNumberOfBytesToWrite, IntPtr NumberOfBytesRead,
		IntPtr lpOverlapped);
		
	[DllImport("kernel32.dll")]
	[return: MarshalAs(UnmanagedType.Bool)]
	static extern bool WriteFile(IntPtr hFile, byte[] lpBuffer,
		uint nNumberOfBytesToWrite, out uint lpNumberOfBytesWritten,
		IntPtr lpOverlapped);
		
	[DllImport("kernel32.dll", SetLastError=true)]
	[return: MarshalAs(UnmanagedType.Bool)]
	static extern bool TerminateProcess(IntPtr hProcess, uint ExitCode);
	
	[DllImport("kernel32.dll", SetLastError=true)]
	static extern IntPtr GetCurrentProcess();
	
	const int MAX_PATH = 260;
		
	static byte[] int_to_bytes(int value)
	{
		byte[] result = new byte[4];
		result[0] = (byte)(value & 0xff);
		result[1] = (byte)((value >> 8) & 0xff);
		result[2] = (byte)((value >> 16) & 0xff);
		result[3] = (byte)((value >> 24) & 0xff);
		return result;
	}
	
	static int int_from_bytes(byte[] a)
	{
		int result = a[0] | (a[1] << 8) | (a[2] << 16) | (a[3] << 24);
		return result;
	}
	
	static string bytes_to_string(byte[] from, int len)
	{
		char[] chars = new char[len / sizeof(char)];
		System.Buffer.BlockCopy(from, 0, chars, 0, len);
		string result = new string(chars);
		return result;
	}
	
	public static bool register_instance(string X_Uniq, string X_Command_line)
	{
		AL4Form.Unique_id = X_Uniq;
		bool Result = true; // it's the first instance which is returning TRUE
		AL4Form.registered_msg = RegisterWindowMessage("Message." + X_Uniq);
		if (AL4Form.registered_msg == 0) return Result;
		
		IntPtr CritSecMutex = CreateMutex((IntPtr)0, true, "");
   		if (CritSecMutex == (IntPtr)0) return Result;
   		first_inst_mutex = CreateMutex((IntPtr)0, false, X_Uniq);
	    if (first_inst_mutex != (IntPtr)0)
	    {
	      UInt32 DW = WaitForSingleObject(first_inst_mutex, 0);
	      Result = (DW != WAIT_TIMEOUT);
            //if (true) //////////////////////////////////////////////
            //{
            //    AL4_system.WriteLine("first_inst_mutex=" + first_inst_mutex.ToString() +
            //    " Result=" + Result.ToString() + " Uniq=" + X_Uniq);
            //}
	    }
	    else
	    {
            //if (true) //////////////////////////////////////////////
            //{
            //    AL4_system.WriteLine("first_inst_mutex=" + first_inst_mutex.ToString() +
            //    " Result=" + Result.ToString() + "\ncannot create mutex!!!!!!!");
            //}
	    }
        //if (true) //////////////////////////////////////////////
        //    {
        //        AL4_system.WriteLine("(0) !");
        //    }
	    CloseHandle( CritSecMutex );
        //if (true) //////////////////////////////////////////////
        //    {
        //        AL4_system.WriteLine("(00) !");
        //    }
	    
		if (!Result)
		{
            //if (true) //////////////////////////////////////////////
            //{
            //    AL4_system.WriteLine("(1) !");
            //}
			StringBuilder buf = new StringBuilder(MAX_PATH);
			GetModuleFileName((IntPtr)0, buf, MAX_PATH);
            //if (true) //////////////////////////////////////////////
            //{
            //    AL4_system.WriteLine("(2) !");
            //}
			List<string> SL = new List<string>();
			SL.Add(buf.ToString());
			for (int i = 1; i < System_functions.Get_count_param(); i++)
				SL.Add(System_functions.Get_parameter(i));
			var MS = new MemoryStream();
			byte[] j = int_to_bytes(SL.Count);
            //if (true) { /////////////////////////////////////////////
            //    AL4_system.WriteLine("Count=" + SL.Count.ToString() +
            //        " --> " + int_from_bytes(j).ToString());
            //}
			MS.Write(j, 0, 4);
			for (int i = 0; i < SL.Count; i++)
			{
				byte[] s = Encoding.Unicode.GetBytes(SL[i]);
				j = int_to_bytes(s.Length);
                //if (true) { ////////////////////////////////////////////
                //    AL4_system.WriteLine("len=" + s.Length.ToString() +
                //        " --> " + int_from_bytes(j).ToString());
                //}
				MS.Write(j, 0, 4);
				MS.Write(s, 0, s.Length);
			}
            //if (true) { //////////////////////////////////////////////
            //    AL4_system.WriteLine("Total=" + MS.Length.ToString());
            //}

			var send_slot = CreateFile(
				@"\\.\mailslot\" + Unique_id,
				GENERIC_READ | GENERIC_WRITE,
				FILE_SHARE_READ | FILE_SHARE_WRITE,
				(IntPtr)0,
				OPEN_EXISTING,
				FILE_ATTRIBUTE_NORMAL,
				(IntPtr)0);
            //if (true) { //////////////////////////////////////////////////
            //    AL4_system.WriteLine("send_slot=" + send_slot.ToString());
            //}

			if (send_slot != (IntPtr)INVALID_HANDLE_VALUE)
			{
				uint written;
				var wf_result = WriteFile(
					send_slot, MS.ToArray(), (uint)MS.Length, 
					out written, (IntPtr)0);
                //if (true) { ////////////////////////////////////////////////
                //    AL4_system.WriteLine("written=" + wf_result.ToString());
                //}
				CloseHandle(send_slot);
				IntPtr sm_result = (IntPtr)0; 
				SendMessageTimeout(
					(IntPtr)HWND_BROADCAST, (int)AL4Form.registered_msg,
					0, 0,
					1, //SMTO_BLOCK
					100, out sm_result);
                //if (true) { /////////////////////////////////////////////
                //    AL4_system.WriteLine("sent=" + sm_result.ToString());
                //}
			}
            //if (true) { ///////////
            //    Console.ReadLine();
            //}
		    TerminateProcess(GetCurrentProcess(), 0);
		}
        //if (true) ////////////////////////////////////////////////////////
        //{
        //    AL4_system.WriteLine("register_instance, Result=" + Result.ToString());
        //}
		return Result;
	}
	
	IntPtr slot;
	
	[System.Runtime.InteropServices.DllImportAttribute("user32.dll")]
	public static extern int SendMessageTimeout(IntPtr hWnd, int Msg, int wParam,
		int lParam, 
		uint flags, uint timeout, out IntPtr result);
	
	
	[DllImport("kernel32.dll", CharSet=CharSet.Auto)]
	static extern IntPtr CreateMailslot(string lpName, uint nMaxMessageSize,
		uint lReadTimeout, IntPtr lpSecurityAttributes);
		
	[DllImport("kernel32.dll")]
	static extern bool GetMailslotInfo(
	IntPtr hFile,			
	out int maxMsgSize,		
	out int lpcbMessage,
	out int lpcMessage,	
	out int timeout);	
		
	const int MAILSLOT_WAIT_FOREVER = -1;
	const int WM_CLOSE = 0x10;
	const int WM_NCDESTROY = 0x82;
	const int WM_NCHITTEST = 0x84;
	
	protected override void WndProc(ref System.Windows.Forms.Message M)
	{
	    if (M.Msg == WM_USER+0xA1f)
	    {
	        Do_Set_form_alpha_tran(Handle_form, Alpha);
	    }            
	    if (can_handle_another_instance_notify)
		{
			if (slot == (IntPtr)0)
			{
				unchecked{
				slot = CreateMailslot(
					@"\\.\mailslot\" + AL4Form.Unique_id,
					0,
					(uint)(MAILSLOT_WAIT_FOREVER),
					(IntPtr)0);
				}
			}
		    switch (M.Msg)
		    {
		    case WM_CLOSE: 
			case WM_NCDESTROY:
		        if (first_inst_mutex != (IntPtr)0)
		        {
		          CloseHandle(first_inst_mutex);
		          first_inst_mutex = (IntPtr)0;
		          CloseHandle(slot);
		        }
		        break;
		    }
		    if (M.Msg == AL4Form.registered_msg)
		    {
			    int max_msg = 0;
			    int count_mes = 0;
			    int next_size = 0;
			    int timeout = 0;
			    bool ok = false;
			    if (slot != (IntPtr)INVALID_HANDLE_VALUE)
			    	ok = GetMailslotInfo(slot, out max_msg, 
			    		out next_size,  out count_mes, out timeout);
			    if (ok && count_mes > 0 && next_size > 0)
		    	{
			        DynAStr ss = new DynAStr();
			        int k = 0;
			        var MS = new MemoryStream();
			        byte[] buf = new byte[next_size];
			        int ready = 0;
			        unsafe{
			        	fixed(byte* dest = &buf[0]) {
			        		ReadFile(slot, (IntPtr)dest, (uint)buf.Length, 
			        			(IntPtr)(&ready), (IntPtr)0);
			        	}
			        }
			        MS.Write(buf, 0, ready);
			        //------------------------------------
			        //AL4_system.WriteLine("Total message size is " + ready.ToString());
			        //------------------------------------
			        MS.Position = 0;
			        MS.Read(buf, 0, 4);
			        k = int_from_bytes(buf);
			        //debug:
					//AL4_system.WriteLine("K=" + k.ToString());
					//----------------------------------------
			        for (int i = 1; i <= k; i++)
			        {
						MS.Read(buf, 0, 4);
			        	int len = int_from_bytes(buf);
			        	//debug:
						//AL4_system.WriteLine("len=" + len.ToString());
						//---------------------------------------
						MS.Read(buf, 0, len);
						string s = bytes_to_string(buf, len);
						//debug:
						//AL4_system.WriteLine("s=" + s);
						//-----------------------------
						ss.Add(s);        	
		    		}
		    		//debug:
		    		//AL4_system.WriteLine("!!!");
		    		//--------------------------
			        C_Fake_parameters.M_Set_parameters(ss);
			        
			        C_Form F = (C_Form)AL4Object.Obj;
			        F.Do.M_operation_started(26, F.hard_link);
				    try {
				    F.Do.M_command();
				    }
				    finally {
				    F.Do.M_operation_ended(26);
				    }
		        }
	        	M.Result = (IntPtr)0;
	        	return;
		    }
		}
	    base.WndProc(ref M);
	}

        //[DllImport("gdi32.dll")]
        //static extern int GetDeviceCaps(IntPtr hdc, int nIndex);

        //[DllImport("user32.dll")]
        //static extern IntPtr GetDC(IntPtr hWnd);

		[DllImport("user32.dll")]
		static extern void ReleaseDC(IntPtr hWnd, IntPtr hdc);

        //const int LOGPIXELSX = 88;
        //const int LOGPIXELSY = 90;

        //public static float Scale_x;
        public static float Scale_y;

        /*
        
        FUN Set_form_application_button(
        INT Handle|_of_form, BOOL Value|_set), NATIVE : @
        "	if (X_Handle == 0) return;"
        "	AL4Form F = (AL4Form)AL4Form.All_descriptors[(int)X_Handle];"
        "	if (F == null) return;"
        "	F.button_in_taskbar = X_Value;"
        "	F.defined_button_in_taskbar = true;"     
        "	F.ShowInTaskbar = X_Value;" .
        
        FUN Is_mobile_screen ==> BOOL: .
        
        //---------- points --> pixels
        
        FUN Points|_convert_to_pixels(REAL P|oints_value) ==> INT,
            NATIVE :
            "    RESULT = AL4Form.Points(X_P);" .
            
        */

        
        public static float Points_float(double pts)
        {
            if (Scale_y == 0)
            {
                    //IntPtr hdc = GetDC(IntPtr.Zero);
                    //Scale_y = GetDeviceCaps(hdc, LOGPIXELSY);
                    //ReleaseDC(IntPtr.Zero, hdc);
                	
                	using (var g = new Control().CreateGraphics())
                	{
                		Scale_y = g.DpiY;
                	}
            }
            return (float)(Scale_y / 72.0 * pts);
        }

        public static int Points(double pts)
        {
            return (int)Math.Truncate(Points_float(pts));
        }

        /*
        //---------- pixels --> points
        
        FUN Pixels|_convert_to_points(REAL P|ixels_value) ==> REAL,
        NATIVE :
            "    RESULT = AL4Form.Pixels(X_P);" .
        */
        public static double Pixels(double pix)
        {
            if (Scale_y == 0)
            {
                    //IntPtr hdc = GetDC(IntPtr.Zero);
                    //Scale_y = GetDeviceCaps(hdc, LOGPIXELSY);
                    //ReleaseDC(IntPtr.Zero, hdc);
                	
                	using (var g = new Control().CreateGraphics())
                	{
                		Scale_y = g.DpiY;
                	}
            }
            return pix * 72.0 / Scale_y;
        }

		/*
		
        FUN List_screen_monitors(INT H|andle_form), NATIVE :
            "    AL4Form.Do_list_monitors();" .
        */
		public static List<Rectangle> Monitors_stored = new List<Rectangle>();        

		public static void Do_list_monitors()
        {
			Monitors_stored.Clear();
            Screen[] All = Screen.AllScreens;
			for (int i=0; i < All.Count(); i++)
			{
				Rectangle r = new Rectangle(
					All[i].Bounds.Left,
					All[i].Bounds.Top,
					All[i].Bounds.Width,
					All[i].Bounds.Height);
				Monitors_stored.Add(r);
			}
		}
		
		/*
		
		FUNCTION Fake_screen_monitor(
			INT H|andle_form_dummy,
			{Geometry}.{rect} Bounds|_of_adding_mointor,
			BOOL Clear_before|_adding)
			: 
			do_Fake_screen_monitor(Bounds.Loc.X, Bounds.Loc.Y,
			Bounds.Width, Bounds.Height, Clear_before)
			.
			
	   	FUN do_Fake_screen_monitor(
	   		REAL X|_points, REAL Y|_points,
	   		REAL W|idth_points, REAL H|eight_points, BOOL Clear_before),
	   		NATIVE : @
            "if (X_Clear_before) AL4Form.Monitors_stored.Clear();"
            "AL4Form.Monitors_stored.Add("
                "new Rectangle("
                    "AL4Form.Points(X_X),"
                    "AL4Form.Points(X_Y),"
                    "AL4Form.Points(X_W),"
                    "AL4Form.Points(X_H)));" .

		FUN Count_screen_monitors(INT H|andle_form) ==> INT, NATIVE : @
		    "    RESULT = AL4Form.Count_screen_monitors();" 
		    "	 if (RESULT == 0)"
		    "	 {"
		    "		AL4Form.Do_list_monitors();"
		    "    	RESULT = AL4Form.Count_screen_monitors();" 
		    "	 }" .
		*/
		
		public static int Count_screen_monitors()
		{
			return Monitors_stored.Count;
	    }
	    
		/*
		
		FUNCTION Get_screen_monitor|_pixels_coordinates(
		INT H|andle_form_dummy,
		INT Index|_of_monitor) ==> {rect}
			:= {rect}(Loc = Pt(do_Get_screen_monitor(Index, "X"),
							   do_Get_screen_monitor(Index, "Y")),
					  Width = do_Get_screen_monitor(Index, "W"),
					  Height = do_Get_screen_monitor(Index, "H")) .
			
		FUN do_Get_screen_monitor(
			INT I|ndex_monitor, STR Coord|inate) ==> REAL,
			NATIVE : @
           "if (X_I < 0 || X_I >= AL4Form.Monitors_stored.Count()) return 0;"
           "switch (X_Coord[0])"
           "{"
           " case 'X': "
           "   return AL4Form.Pixels(AL4Form.Monitors_stored[(int)X_I].X);"
           " case 'Y': "
           "   return AL4Form.Pixels(AL4Form.Monitors_stored[(int)X_I].Y);"
           " case 'W': "
           "   return AL4Form.Pixels(AL4Form.Monitors_stored[(int)X_I].Width);"
           " case 'H': "
           "   return AL4Form.Pixels(AL4Form.Monitors_stored[(int)X_I].Height);"
           "}"
           .
           

		FUNCTION Screen_bounds(INT H|andle_form_dummy) ==> {rect}
			:= {rect}(Loc = Pt("X".get_Screen_bound, "Y".get_Screen_bound),
					  Width = "W".get_Screen_bound, 
					  Height= "H".get_Screen_bound) .
					  
		FUN get_Screen_bound(STR Coord|inate) ==> REAL, NATIVE : @
			"Rectangle r = SystemInformation.VirtualScreen;"
			"switch (X_Coord[0])"
			"{"
			"	case 'X': return AL4Form.Pixels(r.Left);"
			"	case 'Y': return AL4Form.Pixels(r.Top);"
			"	case 'W': return AL4Form.Pixels(r.Right - r.Left);"
			"	case 'H': return AL4Form.Pixels(r.Bottom - r.Top);"
			"}"
			.
			
        // Creates form object (also the first column on it is created, too)
        //------------------------------------------------------------------
        
        FUN Form_create|_create_form(
        {Form} F|orm_object) ==> INT
        	:
			{Screen} s|creen_object = F.Screen_
			CASE s.Default_font_size > 0 ?
				 REAL dfs|ize_of_font_default = s.Default_font_size ;
			CASE s.Default_font_face != "" ? 
			     STR dff|ace_of_font_default = s.Default_font_face ;
			RESULT = do_Form_create(F, dff, dfs) .
        FUN do_Form_create(
        {Form} F|orm_object, STR N|ame_font, REAL D|efault_font_size) 
        ==> INT, NATIVE : @
            "   RESULT = AL4Form.Do_Form_create(X_F, X_N, X_D);"
        	"	if (AL4_system.App_icon.Length > 0)"
        	"	{"
        	"		System.IO.MemoryStream ms = new System.IO.MemoryStream("
        	"		AL4_system.App_icon);"
        	"		Object icon = null;"
        	"		try {"     
        	"			icon = new Icon(ms);"
        	"		}"
        	"		catch(Exception ex) { icon = null; }"     
        	"		if (icon != null)"
        	"		{"
		    "		AL4Form f = (AL4Form)AL4Form.All_descriptors[(int)RESULT];"
		    "		if (f != null)"
		    "			f.Icon = (Icon)icon;"
        	"		}"
        	"	}"
			.
            
		FUN Form_set_icon(
		{Form} F|orm_object, 
		INT Bitmap_h|andle_containing_icon),
			NATIVE:
		INT form_h|andle = F.Handle
			NATIVE @
			"BitmapEx B = (BitmapEx)AL4Form.All_bitmaps[(int)X_Bitmap_h];"
			"if (B == null || B.Ico == null) return;" 	 
			"AL4Form f = (AL4Form)AL4Form.All_descriptors[(int)X_form_h];"
			"if (f != null)"
			"	 f.Icon = B.Ico;"     
			.
		
	 
	    FUN Set_forms_autoscroll(BOOL A|utoscroll_forms), NATIVE :
	        "AL4Form.Set_forms_autoscroll(X_A);" .

        */
        public static bool Use_autoscroll_forms = false;
        
        public static void Set_forms_autoscroll(bool a)
        {
        	Use_autoscroll_forms = a;
        }
        
        
        public static int mainThreadId; 
        
        public static int Do_Form_create(Ref_obj X_F,
        string default_font_name, double default_font_size)
        {
        	if (AL4Form.mainThreadId == 0)
        		AL4Form.mainThreadId =  Thread.CurrentThread.ManagedThreadId;
        
            AL4Form form = new AL4Form();
            form.AL4Object = X_F;
            form.Hidden = true;
            form.Visible = false;
            form.Hidden = false;
            form.AutoScroll = Use_autoscroll_forms;
            form.Height = Points(200);
            form.Width = Points(300);
            
            if (default_font_size > 0 || default_font_name != "")
				form.Font = new Font(
					default_font_name != "" ?
						default_font_name :
			     		form.Font.Name,
					default_font_size > 0 ?
			     		(float)default_font_size :
			     		form.Font.Size);

            form.Click += new EventHandler(form.Form_clicked);
            form.Move += new EventHandler(form.Form_moved);
            form.Resize += new EventHandler(form.Form_resized);
            form.MouseMove += new MouseEventHandler(form.Form_MouseMove);
            form.MouseDown += new MouseEventHandler(form.Form_MouseDown);
            form.MouseUp += new MouseEventHandler(form.Form_MouseUp);
            form.MouseDoubleClick += new MouseEventHandler(form.Form_DoubleClick);
            form.MouseWheel += new MouseEventHandler(form.Form_MouseWheel);
            
            form.KeyDown += new KeyEventHandler(form.Form_KeyDown);
            form.KeyUp += new KeyEventHandler(form.Form_KeyUp);
            form.KeyPress += new KeyPressEventHandler(form.Form_KeyPress);

            form.Shown += new EventHandler(form.Form_shown);
            form.FormClosing += new FormClosingEventHandler(form.Form_closing);
            form.Activated += new EventHandler(form.Form_activated);

            form.Popup_point = new PointF();
            form.Mouse_point = new PointF();

//?{Form}.accept
			form.AllowDrop = true;
			form.DragDrop += new DragEventHandler(form.Form_DragDrop);
			form.DragEnter += new DragEventHandler(form.Form_DragEnter);
//.
			form.ShowInTaskbar = false;
            return form.Handle_form;
        }
        
//?{Form}.accept
		void Form_DragEnter(object sender, DragEventArgs e)
		{
		   // If the data is a file or a bitmap, display the copy cursor.
		   if (e.Data.GetDataPresent(DataFormats.FileDrop) ) 
		   {
		      e.Effect = DragDropEffects.Copy;
		   }
		   else
		   {
		      e.Effect = DragDropEffects.None;
		   }
		}
		
		private void Form_DragDrop(object sender, DragEventArgs e)
		{
		   if(e.Data.GetDataPresent(DataFormats.FileDrop) )
		   {
		      // Assign the file names to a string array, in 
		      // case the user has selected multiple files.
		      string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
		      try
		      {
		      	 DynAStr a = new DynAStr();
		      	 a.Add(System_functions.Get_parameter(0));
		      	 for (int i = 0; i < files.Length; i++)
		      	 	a.Add(files[i]);
		         Point Pt = this.PointToClient(new Point(e.X, e.Y) );
		         Mouse_point.X = (float) Pixels(Pt.X);
		         Mouse_point.Y = (float) Pixels(Pt.Y);
		         
 				 C_Fake_parameters.M_Set_parameters(a);
 				 
				  C_Form F = (C_Form)AL4Object.Obj;
		          F.Do.M_operation_started(26, F.hard_link);
			      try {
			      if (F.Do.M_accept())
			      	F.Do.M_command();
			      }
			      finally {
			      F.Do.M_operation_ended(26);
			      }
		      }
		      catch(Exception Ex)
		      {
		      	 if (Ex is AL4_Exception) throw;
		         return;
		      }
		   }
		}
//.
        
        /*
        // Get form window handle
        //-----------------------
        
        FUN Get_window_handle(INT H|andle_native) ==> INT, NATIVE :
        	CASE H == 0 ? ==> ;
        NATIVE
        @	"	  if (X_H >= AL4Form.All_descriptors.Count) return 0;"   
        	"     Control C = (Control)AL4Form.All_descriptors[(int)X_H];"
        	"	  if (C != null)"     
            "        RESULT = (int)C.Handle;" .

		FUN Call_any_change({Form} F|orm_object), NATIVE:
			INT h|andle_form = F.Handle
			CASE h <= 0 ? ==> ;
			NATIVE @
			"	AL4Form F = (AL4Form)AL4Form.All_descriptors[(int)X_h];"
			"	if (F == null) return;"     
			"	C_Form CF = (C_Form)F.AL4Object.Obj;"
			"	F.SuspendLayout();"
			"	Screen_handler.Allow_handle_events -= 1;"     
			"	try {"
			"	    CF.Do.M_Any_change();"
			"	}"     
			"	finally {"
			"		Screen_handler.Allow_handle_events += 1;"     
			"	    F.ResumeLayout();" 
			"	}"     
			.
			

        
        // Destroy form object
        //--------------------
        FUN Destroy_form(INT H|andle_native), NATIVE :
            "     AL4Form.Do_Destroy_form((int)X_H);" .
        */
        public static void Do_Destroy_form(int H)
        {
            AL4Form form = (AL4Form)All_descriptors[H];
            if (form == null) return;
            form.Close();
            
            form.Click -= new EventHandler(form.Form_clicked);
            form.Move -= new EventHandler(form.Form_moved);
            form.Resize -= new EventHandler(form.Form_resized);
            form.MouseMove -= new MouseEventHandler(form.Form_MouseMove);
            form.MouseDown -= new MouseEventHandler(form.Form_MouseDown);
            form.MouseUp -= new MouseEventHandler(form.Form_MouseUp);
            form.MouseDoubleClick -= new MouseEventHandler(form.Form_DoubleClick);
            form.MouseWheel -= new MouseEventHandler(form.Form_MouseWheel);
            form.Shown -= new EventHandler(form.Form_shown);
            form.Activated -= new EventHandler(form.Form_activated);
            
            form.Handle_form = 0;
            AL4Form.ReleaseDescriptor(H);
        }

        /*
        // Close form object
        //--------------------
        FUN Form_close(INT H|andle_native), NATIVE :
			//DEBUG: << ">>>>>>>>>>>>>>>>> Form_close"#NL Trace_stack(100) #NL 
			//>> STR dummy|_input ;
		NATIVE @	
		"AL4Form.Do_form_close((int)X_H);" .
        
		*/		
				
        public List<Panel> Trays_timers = new List<Panel>();

        public static void Do_form_close(int X_H)
        {
          //if (X_H == 0) return;
	      AL4Form F = (AL4Form)AL4Form.All_descriptors[(int)X_H];
	      if (F == null) return;
//?{Form}.closed
          C_Form CF = (C_Form)F.AL4Object.Obj;
//.
		  //F.Hidden = true;
          F.Close();
          F.Deactivate_trays_timers();
//?{Form}.closed
     
          CF.Do.M_operation_started(0, CF.hard_link);
          try {
	          try {
	          	CF.Do.M_closed();
	          } //catch(Stop) {}
	          catch (Exception Ex) {
	        	  if (Ex is AL4_Exception) throw;
	          }
          }
          finally {
          CF.Do.M_operation_ended(0);
          }
//.
        }
    	/*    
        // Return TRUE if  form is visible
        //--------------------------------
        
        FUN Form_visible(INT H|andle_native) ==> BOOL, NATIVE : @
           "if (X_H == 0) return false;"
           "AL4Form form = (AL4Form)AL4Form.All_descriptors[(int)X_H];"
           "if (form == null) return false;"
           "return !form.Hidden && form.Visible;" .

        FUN Form_hidden(INT H|andle_native) ==> BOOL, NATIVE : @
           "if (X_H == 0) return false;"
           "AL4Form form = (AL4Form)AL4Form.All_descriptors[(int)X_H];"
           "return form.Hidden;" .
        */
        
        protected override void SetVisibleCore(bool value)
        {
            if (!IsDisposed)
                base.SetVisibleCore(!Hidden);
        }

        /*
        // Show or hide form
        //------------------
        FUN Show_hide|_form(INT H|andle_native, BOOL Show|_or_hide),
            NATIVE :
            "    if (X_H > 0) AL4Form.Do_show_hide((int)X_H, X_Show);" .
            
		FUN Show_form_noactivate(
			INT H|andle_native), NATIVE :
			"    if (X_H > 0) AL4Form.Do_show_noactivate((int)X_H);" .
        */
        public static void Do_show_noactivate(int H)
        {
        	AL4Form form = (AL4Form)AL4Form.All_descriptors[H];
            if (form == null) return;
            Application_running = true; // added to provide adjusting 
            form.Hidden = false;
            form.Visible = true;
            form.Form_shown(form, null);
        }

        public static void Do_show_hide(int H, bool Show)
        {
            AL4Form form = (AL4Form)AL4Form.All_descriptors[H];
            if (form == null) return;
            if (Show)
            {
            //AL4_system.WriteLine("do_shown"); ///////////////////
            	Application_running = true; // added to provide adjusting 
            								// columns just before application
            								// running
                form.Hidden = false;
                if (form.WindowState == FormWindowState.Minimized)
                	form.WindowState = FormWindowState.Normal;
                form.Show();
                form.ShowInTaskbar = form.button_in_taskbar;
                bool save_topmost = form.TopMost;
                form.TopMost = true;
                form.BringToFront();
                form.TopMost = save_topmost;
                form.Form_shown(form, null);
            }
            else
            {
                form.ShowInTaskbar = form.button_in_taskbar;
                form.Hidden = true;
                form.Hide();
            }
        }
        
        /*
        // Show dialog form modal
        //------------------
        FUN Show_form_modal({Dialog} D|ialog_to_show , {Form} P|arent_form),
            NATIVE :
            INT h|andle_dialog = D.Handle
            INT p|arent_handle = P.Handle
            List_monitors
            FOR i IN [0 TO Count_monitors-1] :
                CASE Monitor(i).Contains(P.Bounds.Loc) ?
                     CASE !Monitor(i).Contains(D.Bounds.Loc) ?
                          {point} pos|ition_centered = P.Bounds.Loc.Offset(
                          	(P.Width - D.Width)/2, (P.Height - D.Height)/2)
                          	
                          D.Set_position(pos.X, pos.Y, 'POSITION_AS_IS')
                     ;
                     BREAK i ;
            ;
            NATIVE @
            "    AL4Form.Do_show_modal((int)X_h, (int)X_p);" .
        */
        
        public static void Do_show_modal(int H, int P)
        {
//?{Dialog}       
            AL4Form form = (AL4Form)AL4Form.All_descriptors[H];
            if (form == null) return;
            form.Hidden = false;
            //if (form.button_in_taskbar) form.ShowInTaskbar = true;
            form.ShowInTaskbar = form.button_in_taskbar;
            bool save_click_disabled = form.click_disabled;
            form.click_disabled = false;
            
            //--------------- 'reset level_event on parent form while modalling'
            AL4Form pform = (AL4Form)AL4Form.All_descriptors[P];
            if (pform==null) return;
            
            C_Form cpform = (C_Form)pform.AL4Object.Obj;
            int save_plevel = (int)cpform.F_level_event;
            cpform.F_level_event = 0;
            string save_menu_alias = cpform.F_menu_alias;
            cpform.F_menu_alias = "";
            
            bool was_key_disabled = key_disabled;
            key_disabled = false;
            try 
            {
                form.ShowDialog();
            }
            finally
            {
            	key_disabled = was_key_disabled;
            	
            	cpform.F_level_event = save_plevel;
            	cpform.F_menu_alias = save_menu_alias;
            	
                form.click_disabled = save_click_disabled;
                form.Hide();
                //------------------ 'reactivate parent form'
                try {
                	//AL4_system.WriteLine("activating...");
                	pform.Activate();
                	//AL4_system.WriteLine("activated !!!");
                }
                catch(Exception Ex) {
                	if (Ex is AL4_Exception) throw;
                }
            }
//.
        }
        
        public void Deactivate_trays_timers()
        {
            for (int i = Trays_timers.Count-1; i >= 0; i--)
            {
                if (Trays_timers[i] is TrayPanel)
                {
                    ((TrayPanel)Trays_timers[i]).TrayObject.Visible = false;
                }
                else if (Trays_timers[i] is TimerPanel)
                {
                    ((TimerPanel)Trays_timers[i]).TimerObject.Enabled = false;
                }
            }
            for (int i = Control_timers.Count-1; i >= 0; i--)
            {
                Control_timers[i].Stop();
            }
        }        
        
        /*
        // Set modal result
        //---------------------
        FUN Set_modal_result(INT H|andle_native, STR Result|_set),
            NATIVE : @
            "	 if (X_H == 0) return;"
            "    AL4Form F = (AL4Form)AL4Form.All_descriptors[(int)X_H];"
            "    if (F == null) return;" 
            "    C_Form CF = (C_Form)F.AL4Object.Obj;"
            "    F.DialogResult = DialogResult.OK;"
            "    F.Hidden = true;"
            "    F.Hide();"
            "    F.Deactivate_trays_timers();" .
        
        // Get form caption
        //---------------------
        
        FUN Get_form_caption(INT H|andle_native) ==> STR, NATIVE :
            "    RESULT = AL4Form.Do_Get_form_caption((int)X_H);" .
        */
        public static string Do_Get_form_caption(int H)
        {
            AL4Form form = (AL4Form)AL4Form.All_descriptors[H];
            if (form == null) return "";
            return form.Text;
        }

        /*
        // Set form caption
        //-----------------
        
        FUN Set_form_caption(
        {Form} Form|_object, STR V|alue_caption), NATIVE : @
            "    AL4Form.Do_Set_form_caption("
            "		(int)((C_Form)X_Form.Obj).F_Handle, X_V);" .
        */
        public static void Do_Set_form_caption(int H, string V)
        {
            AL4Form form = (AL4Form)AL4Form.All_descriptors[H];
            if (form == null) return;
            form.Text = V;
        }

        /*
        
        FUN Set_window_taskbar_button_progress(
        	{Form} F|orm_object, INT Value|_0_to_100), NATIVE 
            :
            INT h|andle_window = F.Handle
            NATIVE @
            "AL4Form.Taskbar_set_value((int)X_h, (int)X_Value, 100);" .

        */
	public static class TaskbarProgress
    {
        public enum TaskbarStates
        {
            NoProgress = 0,
            Indeterminate = 0x1,
            Normal = 0x2,
            Error = 0x4,
            Paused = 0x8
        }

        [ComImportAttribute()]
        [GuidAttribute("ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf")]
        [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
        private interface ITaskbarList3
        {
            // ITaskbarList
            [PreserveSig]
            void HrInit();
            [PreserveSig]
            void AddTab(IntPtr hwnd);
            [PreserveSig]
            void DeleteTab(IntPtr hwnd);
            [PreserveSig]
            void ActivateTab(IntPtr hwnd);
            [PreserveSig]
            void SetActiveAlt(IntPtr hwnd);

            // ITaskbarList2
            [PreserveSig]
            void MarkFullscreenWindow(IntPtr hwnd, [MarshalAs(UnmanagedType.Bool)] bool fFullscreen);

            // ITaskbarList3
            [PreserveSig]
            void SetProgressValue(IntPtr hwnd, UInt64 ullCompleted, UInt64 ullTotal);
            [PreserveSig]
            void SetProgressState(IntPtr hwnd, TaskbarStates state);
        }

        [GuidAttribute("56FDF344-FD6D-11d0-958A-006097C9A090")]
        [ClassInterfaceAttribute(ClassInterfaceType.None)]
        [ComImportAttribute()]
        private class TaskbarInstance
        {
        }

        private static bool taskbarSupported = 
        	Environment.OSVersion.Version >= new Version(6, 1);

        public static void SetState(Form form, TaskbarStates taskbarState)
        {
            if (taskbarSupported)
            {
                var taskbarInstance = (ITaskbarList3)new TaskbarInstance();
                taskbarInstance.SetProgressState(form.Handle, taskbarState);
            }
        }

        public static void SetValue(Form form, double progressValue, double progressMax)
        {
            if (taskbarSupported)
            {
                var taskbarInstance = (ITaskbarList3)new TaskbarInstance();
                taskbarInstance.SetProgressValue(form.Handle, 
                	(ulong)progressValue, (ulong)progressMax);
            }
        }
    }
    
    	public static void Taskbar_set_value(int h, int value, int max_value)
    	{
    		AL4Form form = (AL4Form)AL4Form.All_descriptors[h];
    		TaskbarProgress.SetValue(form, value, max_value);
    	}
    	
        /*
        // Get form left position in points
        //---------------------------------
        FUN Get_form_left(INT F|orm_native_handler) ==> REAL, NATIVE :
            "    RESULT = AL4Form.Do_get_form_left((int)X_F); " .
        */
        public static double Do_get_form_left(int H)
        {
            AL4Form form = (AL4Form)AL4Form.All_descriptors[H];
            if (form == null) return 0;
            return Pixels(form.Left);
        }
        
        /*
        // Get form top position in points
        //--------------------------------
        FUN Get_form_top(INT F|orm_native_handler) ==> REAL, NATIVE :
            "    RESULT = AL4Form.Do_get_form_top((int)X_F); " .
        */
        public static double Do_get_form_top(int H)
        {
            AL4Form form = (AL4Form)AL4Form.All_descriptors[H];
            if (form == null) return 0;
            return Pixels(form.Top);
        }
		
        /*
        // Set form position in points
        //----------------------------
        FUN Set_form_position(INT F|orm_native_handler,
            REAL L|eft_position, REAL T|op_position), NATIVE :
            "    AL4Form.Do_Set_form_pos((int)X_F, X_L, X_T);" .
        */
        public static void Do_Set_form_pos(int H, double X_L, double X_T)
        {
            AL4Form form = (AL4Form)AL4Form.All_descriptors[H];
            if (form == null) return;
            form.StartPosition = FormStartPosition.Manual;
            int L = Points(X_L);
            int T = Points(X_T);
            form.Left = L;
            form.Top = T;
        }

        /*
        // Get form width in points
        //-------------------------
        FUN Get_form_width(INT F|orm_native_handler) ==> REAL, NATIVE :
			CASE F == 0 ? ==> ;
			NATIVE @
            "    RESULT = AL4Form.Do_Get_form_width((int)X_F); " .
        */
        public static double Do_Get_form_width(int H)
        {
            AL4Form form = (AL4Form)AL4Form.All_descriptors[H];
            if (form == null) return 0;
            return Pixels(form.Width);
        }

        /*
        // Get form height in points
        //--------------------------
        
        FUN Get_form_height(
        INT F|orm_native_handler) ==> REAL, NATIVE :
			CASE F == 0 ? ==> ;
			NATIVE @
            "    RESULT = AL4Form.Do_Get_form_height((int)X_F); " .
        */
        public static double Do_Get_form_height(int H)
        {
            AL4Form form = (AL4Form)AL4Form.All_descriptors[H];
            if (form == null) return 0;
            return Pixels(form.Height);
        }

        /*
        // Set form size in points
        //------------------------
        
        FUN Set_form_size(INT F|orm_native_handler,
            REAL W|idth_points, REAL H|eight_points),
            NATIVE :
            "    AL4Form.Do_Set_form_size((int)X_F, X_W, X_H); " .
        */
        public static void Do_Set_form_size(int F, double X_W, double X_H)
        {
            AL4Form form = (AL4Form)AL4Form.All_descriptors[F];
            if (form == null) return;
            int W = Points(X_W);
            int H = Points(X_H);
            form.Width = W;
            form.Height = H;
        }
        /*
        
        FUN Set_form_minimal_size(INT F|orm_native_handler,
            REAL W|idth_points, REAL H|eight_points),
            NATIVE :
            "    AL4Form.Do_Set_form_min_size((int)X_F, X_W, X_H); " .
        */
        public static void Do_Set_form_min_size(int F, double X_W, double X_H)
        {
            AL4Form form = (AL4Form)AL4Form.All_descriptors[F];
            if (form == null) return;
            int W = Points(X_W);
            int H = Points(X_H);
            form.MinimumSize = new System.Drawing.Size(W, H);
        }
        /*
        
		FUN Set_form_bounds(
		INT F|orm_handle, REAL L|eft_position, REAL T|op_position,
		REAL W|idth_form, REAL H|eight_form), NATIVE :
			INT p_l|eft_pixels = L.Points
			INT p_t|op_pixels = T.Points
			INT p_w|idth_pixels = W.Points
			INT p_h|eight_points = H.Points
		NATIVE @
		   "AL4Form F = (AL4Form)AL4Form.All_descriptors[(int)X_F];"
		   "F.Size = new Size((int)X_p_w, (int)X_p_h);" 
		   "F.WindowState = FormWindowState.Normal;" 
		   "F.StartPosition = FormStartPosition.Manual;" 
		   "F.Location = new Point((int)X_p_l, (int)X_p_t);" .
		
        FUN Get_form_state(
        INT F|orm_handle) ==> {Form}.{state}, NATIVE:
        CASE F == 0 ? ==> ;
        NATIVE@     
        "    AL4Form form = (AL4Form)AL4Form.All_descriptors[(int)X_F];"
        "	 switch (form.WindowState)"
        "	 {"
        "		case FormWindowState.Normal: return 0;"
        "		case FormWindowState.Minimized: return 1;"
        "		case FormWindowState.Maximized: return 2;"
        "	 }" .
		        
        FUN Set_form_state(
        INT F|orm_handle, {Form}.{state} V|alue_to_set), NATIVE: @
        "    AL4Form form = (AL4Form)AL4Form.All_descriptors[(int)X_F];"
        "	 switch (X_V)"
        "	 {"
        "		case 0: form.WindowState = FormWindowState.Normal; break;"
        "		case 1: form.WindowState = FormWindowState.Minimized; break;"
        "		case 2: form.WindowState = FormWindowState.Maximized; break;"
        "	 }" .
		        
		FUN Form_client_pos|ition_in_points(
		INT F|orm_native_handler,
		STR What|_X_Y) ==> REAL,
		NATIVE :
			CASE "X" IN What ? BOOL x|_position = TRUE ;
			NATIVE
		@	"    AL4Form form = (AL4Form)AL4Form.All_descriptors[(int)X_F];"
        	"	 if (form == null) return 0;"
			"	var P = form.PointToScreen(new Point(0,0));"
		    "   if (X_x) "
		    "		RESULT = AL4Form.Pixels(P.X);"
		    "	else RESULT = AL4Form.Pixels(P.Y);"
		    .
		  
        
        
        FUN Form_client_size(
        INT F|orm_native_handler,
        STR What|_side_W_H) ==> REAL,
        NATIVE :
			CASE "W" IN What ? BOOL w|idth_to_get = TRUE ;
        	NATIVE
        @	"    AL4Form form = (AL4Form)AL4Form.All_descriptors[(int)X_F];"
        	"	 if (form == null) return 0;"
            "    if (X_w) "
            "		RESULT = AL4Form.Pixels(form.ClientSize.Width);"
            //"		- AL4Form.Pixels(4) * 2;"
            "	 else RESULT = AL4Form.Pixels(form.ClientSize.Height);"
            //"		- AL4Form.Pixels(2) * 2;" 
            .
            
        FUN Set_form_client_size(
        INT F|orm_native_handler,
        REAL W|idth_points, REAL H|eight_points) ==> BOOL,
        NATIVE :
        @	"    AL4Form form = (AL4Form)AL4Form.All_descriptors[(int)X_F];"
        	"	 int w = AL4Form.Points(X_W); // + AL4Form.Points(4) * 2;"
        	"	 int h = AL4Form.Points(X_H); // AL4Form.Points(2) * 2;"
        	"	 form.ClientSize = new Size(w, h);" 
            "	 RESULT = true;" .
		
        
        FUN Set_form_stay_on_top(
        	INT F|orm_native_handler, BOOL T|opmost_Z),
            NATIVE :
        @   "    AL4Form form = (AL4Form)AL4Form.All_descriptors[(int)X_F];"
        	"	 if (form == null) return;"
            "    form.TopMost = X_T;" .
            
		FUN Set_form_no_frame(
			INT F|orm_native_handle, BOOL No_frame|_flag), NATIVE:
		@	"	AL4Form form = (AL4Form)AL4Form.All_descriptors[(int)X_F];"
			"	if (form == null) return;"
			"	form.SuspendLayout();"
			"	try"
			"	{"
			"	    if (X_No_frame)"
			"	    {"
			"		    //form.Text = "#QU#QU";"
			"			form.Text = String.Empty;"   
			"		    form.ShowInTaskbar = form.button_in_taskbar;"
			"		    //form.FormBorderStyle = FormBorderStyle.Sizable;"
			"			form.FormBorderStyle = FormBorderStyle.None;"     
			"			form.ControlBox = false;"
			"	    }"
			"	    else"
			"	    {"
			"		    form.ControlBox = true;"
			"		    form.FormBorderStyle = FormBorderStyle.Sizable;"
			"		    C_Form C_F = (C_Form)form.AL4Object.Obj;"
			"		    form.Text = C_F.F_local_caption;"
			"		    form.ShowInTaskbar = form.button_in_taskbar;"
			"	    }"
			"	}"
			"	finally {"
			"		form.ResumeLayout();"
			"	}" 
			.
			
		FUN Start_move_form(INT F|orm_native_handle),
			NATIVE, DEPRECATED('Platform dependent'):
		@	"	AL4Form.Do_Start_move_form((int)X_F);" .	
			
		*/
		public const int WM_NCLBUTTONDOWN = 0xA1;
		public const int HT_CAPTION = 0x2;
		[System.Runtime.InteropServices.DllImportAttribute("user32.dll")]
		public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam,
			int lParam);
		[System.Runtime.InteropServices.DllImportAttribute("user32.dll")]
		public static extern bool ReleaseCapture();
		
		const uint HWND_BROADCAST = 0xffff;
		
		public static void Do_Start_move_form(int X_F)
		{
		 	AL4Form form = (AL4Form)AL4Form.All_descriptors[(int)X_F];
		 	if (form == null) return;
		 	ReleaseCapture();
		 	SendMessage(form.Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
		}
		
		/*
			
		FUN Set_form_columns_no_borders(
			INT F|orm_native_handle, BOOL No_borders|_flag), NATIVE:
		@	"	AL4Form form = (AL4Form)AL4Form.All_descriptors[(int)X_F];"
			"	if (form == null) return;"
			"	form.No_borders = X_No_borders;" 
			"	if (X_No_borders) "
			"	{"
			//"		if (!form.button_in_taskbar) form.ShowInTaskbar = false;"
			"	}"
			"	else {"
			//"		form.ControlBox = true;"
			//"		form.FormBorderStyle = FormBorderStyle.Sizable;"     
			"	}"     
			"".
			
		FUN Set_form_alpha_tran
			|sparency_0opaque_1invisible(
			INT F|orm_native_handle, REAL Tran|sparency_value), NATIVE:
			INT alpha|_value_0invisible_255opaque = 255 - (Tran * 255).Int
			NATIVE @
			"	AL4Form.Do_Set_form_alpha_tran((int)X_F, (int)X_alpha);" .
			
		FUN swap_R_B(INT c|olor_to_swap) ==> INT :
			RESULT = c & 0xFF_00FF00 | c.ShiftR(16)&0xFF | (c&0xFF).ShiftL(16) .
			
		FUN Set_form_colors(
			INT F|orm_native_handle, INT FColor|_int, INT BColor|_int), NATIVE:
			INT b|ackground = swap_R_B(BColor | 0xFF000000)
			INT f|oreground = swap_R_B(FColor | 0xFF000000)
			NATIVE @
			"	AL4Form form = (AL4Form)AL4Form.All_descriptors[(int)X_F];"
			"	form.BackColor = Color.FromArgb((int)X_b);"
			"	form.ForeColor = Color.FromArgb((int)X_f);"
			.
			
		FUN Make_form_tool_window(
		INT F|orm_native_handle, BOOL Yes|_make), NATIVE : @
			"	AL4Form form = (AL4Form)AL4Form.All_descriptors[(int)X_F];"
		    "	AL4Form.Do_Make_form_tool_window(form, X_Yes);" .
			
		*/
		
	[DllImport("user32.dll")]
	static extern IntPtr SetWindowPos(
    	IntPtr hwnd, int hWndInsertAfter, int x, int y, int cx, int cy, 
    	uint dwFlags);
		
	public static void Do_Make_form_tool_window(AL4Form form, bool yes)
	{
		uint ex = GetWindowLong(form.Handle, GWL_EXSTYLE);
		uint WS_EX_TOOLWINDOW = 128;
		//uint WS_EX_WINDOWEDGE = 256;
		//uint WS_EX_THIKFRAME = 0x40000;
		
		uint SWP_FRAMECHANGED = 0x20;
		uint SWP_NOACTIVATE = 0x10;
		uint SWP_NOMOVE = 2;
		uint SWP_NOSIZE = 1;
		uint SWP_NOOWNERZORDER = 0x200;
		uint SWP_NOZORDER = 4;
		if (yes) 
		{
			ex |= WS_EX_TOOLWINDOW;
			//ex |= WS_EX_WINDOWEDGE;
			//ex |= WS_EX_THIKFRAME;
		}
		else ex &= ~(WS_EX_TOOLWINDOW); 
		SetWindowLong(form.Handle, GWL_EXSTYLE, ex);
		SetWindowPos(form.Handle, 0, 0, 0, 0, 0, SWP_FRAMECHANGED 
		| SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOOWNERZORDER
		| SWP_NOZORDER);
	}
		
	public const uint LWA_ALPHA=0x00000002;
	public const uint WS_EX_LAYERED=0x00080000;
	public const int GWL_EXSTYLE = -20;
	
	[DllImport("user32.dll")]
    static extern bool SetLayeredWindowAttributes(
    	IntPtr hwnd, uint crKey, byte bAlpha, uint dwFlags);
 
    [DllImport("user32.dll")]
    public static extern long SetWindowLong(
    	IntPtr hWnd, int nIndex, uint dwNewLong);
 
    [DllImport("user32.dll")]
    public static extern uint GetWindowLong(
    	IntPtr hWnd, int nIndex);
 
		
		public static void Do_Set_form_alpha_tran(int X_F, int X_alpha)
		{
			AL4Form form = (AL4Form)AL4Form.All_descriptors[(int)X_F];
			if (form == null) return;
			form.Alpha = (byte)X_alpha;
			//if (!form.shown) return;
	        uint dw = GetWindowLong( form.Handle, GWL_EXSTYLE );
	        if (X_alpha > 0)
	        {
	            SetWindowLong( form.Handle, GWL_EXSTYLE, dw | WS_EX_LAYERED );
	            SetLayeredWindowAttributes( form.Handle, 0, (byte)X_alpha, LWA_ALPHA);
	        } else
	            SetWindowLong( form.Handle, GWL_EXSTYLE, dw & ~WS_EX_LAYERED );
		}

	
	

		/*
            
        FUN Is_form_active(INT H|andle_form) ==> BOOL, NATIVE :
            "   RESULT = AL4Form.Do_Is_form_active((int)X_H);" .
            
        FUN Make_form_active(INT H|andle_form), NATIVE :
            "   AL4Form.Do_Make_form_active((int)X_H);" .
            
   		FUN Set_form_enabled(
   			INT F|orm_handle, BOOL E|nable_form), NATIVE :
        @	"	 if (X_F == 0) return;"   
        	"    AL4Form form = (AL4Form)AL4Form.All_descriptors[(int)X_F];"
        	"	 if (form == null) return;"
            "    form.Enabled = X_E;" .
            
        */
        [DllImport("user32.dll")]
        public static extern IntPtr GetForegroundWindow();
        
        public static bool Do_Is_form_active(int X_H)
        {
            AL4Form form = (AL4Form)AL4Form.All_descriptors[(int)X_H];
            if (form == null) return false;
            bool RESULT = form.Handle == GetForegroundWindow();
            return RESULT;
        }
        
        [DllImport("user32.dll")]
        public static extern void SetForegroundWindow(IntPtr Handle);
        
        public static void Do_Make_form_active(int X_H)
        {
            AL4Form form = (AL4Form)AL4Form.All_descriptors[(int)X_H];
            if (form == null) return;
            SetForegroundWindow(form.Handle);
        }
        

        /*
        // Set current column handler (it will be a parent for all new controls)
        //----------------------------------------------------------------------
        
        FUN Set_form_current_column_handle(
        	INT H|andle_form, 
            INT Col|umn_handler), NATIVE :
            "     AL4Form.Do_Set_form_current_column_handle("
            "		(int)X_H, (int)X_Col);" .
        */
        public int Current_column_handle;
        
        public static void Do_Set_form_current_column_handle(int H, int Col) {
            AL4Form form = (AL4Form)AL4Form.All_descriptors[H];
            if (form == null) return;
            form.Current_column_handle = Col;
        }
        
        public static void Adjust_control_font(Control C) {
        	//if (!(C.Parent is ContainerControl)) return;
        	//ContainerControl P = (ContainerControl)C.Parent;
        	Control P = C.Parent;
        	while (P != null) {
        		if (P is AL4Column) {
        			AL4Column col = (AL4Column)P;
        			if (col.Custom_font) {
        				C.Font = new Font(
        					col.Font.Name, col.Font.Size, col.Font.Style);
        				return;
        			}
        		}
        		if (P is AL4Form) {
        			C.Font = new Font(P.Font.Name, P.Font.Size, P.Font.Style);
        			return;
        		}
        		P = P.Parent;
        	}
        }
        
        /*
        
        
        FUN Set_column_padding(INT Padding|_pixels),
        NATIVE : @
        "	AL4Form.column_padding = (int)X_Padding;" .
        
        // Create column panel on form OR on the current column as a nesting panel
        //------------------------------------------------------------------------
        
        FUN Create_column(INT F|orm_native_handle,
        	{Form}.{layout} Layout | column,
			REAL	Width | of_column,
			REAL	Label_w | idth,
			INT		Nested_in  | column_handle) ==> INT, NATIVE
        	:
			CASE F == 0 ? ==> ;
			NATIVE @
        "RESULT = AL4Form.Do_Create_column("
        "	(int)X_F, X_Layout, X_Width, X_Label_w, (int)X_Nested_in);" .
        */
        public static int column_padding = 4;
        
        public static int Do_Create_column(int H, byte Layout, double Width,
        double Label_w, int Nested_in)
        {
            AL4Form F = (AL4Form)All_descriptors[H];
            AL4Column LastCol = null;
            LastCol = new AL4Column();
            if (AL4Form.column_padding == 0)
            	LastCol.BorderStyle 
            	= System.Windows.Forms.BorderStyle.None;
            else if (!F.No_borders)
            	LastCol.BorderStyle 
            	= System.Windows.Forms.BorderStyle.FixedSingle;

            LastCol.Click += new EventHandler(F.Form_clicked);
            LastCol.MouseMove += new MouseEventHandler(F.Form_MouseMove);
            LastCol.MouseDown += new MouseEventHandler(F.Form_MouseDown);
            LastCol.MouseUp += new MouseEventHandler(F.Form_MouseUp);
            LastCol.MouseDoubleClick += new MouseEventHandler(F.Form_DoubleClick);
            LastCol.Resize += new System.EventHandler(LastCol.Resized);
            int p = (int)Pixels(column_padding);
            LastCol.Margin = new System.Windows.Forms.Padding(p, p, p, p);
            LastCol.Padding = new System.Windows.Forms.Padding(p, p, p, p);
            
            if (Nested_in >= 0)
            {
            	LastCol.Nested_in = Nested_in;
            }

            F.Controls.Add(LastCol);
            F.Columns.Add(LastCol);
 
            LastCol.Label_width = Points(Label_w);
            LastCol.Column_layout = Layout;
            LastCol.Horizontal = Layout >= 3;
            if (Width > 0)
            {
            	LastCol.Fixed_width = Points(Width);
                LastCol.Width = Points(Width);
                LastCol.Height = LastCol.Horizontal ?
			     					Points(28) : Points(Width);
            }
            else 
            { 
                LastCol.Width = Points(200);
                LastCol.Height = LastCol.Horizontal ?
			     					Points(28) : Points(200);
            }
            F.Adjust_columns_docking();
            F.Current_column_handle = LastCol.Handle_column;
            return LastCol.Handle_column;
        }
        
        /*
        
        FUN Adjust_columns(INT F|orm_native_handle), NATIVE :
            "    AL4Form.Do_adjust_form_columns((int)X_F);" .
            
		FUN Get_form_mobile_config|uration(
		INT F|orm_handle) ==> {Form}.{mobile_config} : .
			
		FUN Set_form_mobile_config|uration(
		INT F|orm_handle, {mobile_config} MC|onfiguration_to_set)
		: .
        */
        public static void Do_adjust_form_columns(int H)
        {
            if (H == 0) return;
            AL4Form F = (AL4Form)All_descriptors[H];
            if (F == null) return;
            F.Adjust_columns_docking();
        }        
        
        public void Adjust_columns_docking()
        {
            if (!Application_running) return;
            if (((C_Form)AL4Object.Obj).F_suspended_count > 1) return;
            
            if (adjusting_columns) return;
            SuspendLayout();
            try {
            	adjusting_columns = true;
	            try {
	            	Rectangle r = ClientRectangle;
	            	C_Form.M_Do_adjust_columns(AL4Object, r.Width, r.Height);
	                adjusting_columns = false;
	                //foreach (AL4Column Col in Columns)
	                //    Adjust_control_location(Col);
	            }
	            finally {
	                ResumeLayout(false);
	                adjusting_columns = false;
	            }
            }
            finally {
                foreach (AL4Column Col in Columns)
                    Adjust_control_location(Col);
            }
        }
        
        /*
        
        FUN Form_suspend_layout(
        INT Handle|_of_form_to_suspend), NATIVE : @
        "	if (X_Handle == 0) return;"
        "	AL4Form F = (AL4Form)AL4Form.All_descriptors[(int)X_Handle];"
        "	if (F == null) return;"
        "	F.SuspendLayout();" .
        
        FUN Form_resume_layout(
        INT Handle|_of_form_to_resume), NATIVE : @
        "	if (X_Handle == 0) return;"
        "	AL4Form F = (AL4Form)AL4Form.All_descriptors[(int)X_Handle];"
        "	if (F == null) return;"
        "	F.ResumeLayout(false);" .
        
        FUN Form_suspend_column(
        INT Handle|_of_form, INT Col|umn_index), NATIVE: @
        "	if (X_Handle == 0 || X_Col < 0) return;"
        "	AL4Form F = (AL4Form)AL4Form.All_descriptors[(int)X_Handle];"
        "	if (F == null) return;"
        "	AL4Column col = F.Columns[(int)X_Col];"
        "	col.SuspendLayout();"
        "	col.suspend_count ++;" .
        
        FUN Form_resume_column(
        INT Handle|_of_form, INT Col|umn_index), NATIVE: @
        "	if (X_Handle == 0 || X_Col < 0) return;"
        "	AL4Form F = (AL4Form)AL4Form.All_descriptors[(int)X_Handle];"
        "	if (F == null) return;"
        "	AL4Column col = F.Columns[(int)X_Col];"
        "	col.ResumeLayout();"
        "	if (--col.suspend_count == 0)" 
        "		AL4Form.Adjust_control_location(col);" .
        
        FUN Get_form_column_controls_layout(
        	INT Col|umn_handler) ==> {Form}.{controls_layout}, NATIVE : @
        "	AL4Column col = (AL4Column)AL4Form.All_descriptors[(int)X_Col];"
        "	RESULT = col.controls_layout;" .

        FUN Set_form_column_controls_layout(
        	INT Col|umn_handler,
        	{controls_layout} CL|ayout_controls), NATIVE : @
        "	AL4Column col = (AL4Column)AL4Form.All_descriptors[(int)X_Col];"
        "	col.controls_layout = X_CL;" .

        FUN Get_column_label_width|_limit(
        	INT C|olumn_handle) ==> REAL, NATIVE :
			CASE C == 0 ? ==> ;
			NATIVE @
           "AL4Column LastCol = (AL4Column)AL4Form.All_descriptors[(int)X_C];"
           "RESULT = AL4Form.Pixels(LastCol.Label_width);" .
           
        // Set column label width which is sufficient short to label next control 
        // to right (rather then place it below):
        //-------------------------
        
        FUN Set_column_label_width_limit(
        	INT C|olumn_handle, REAL Lab|el_width), NATIVE :
			CASE C == 0 ? ==> ;
			NATIVE @
           "AL4Column LastCol = (AL4Column)AL4Form.All_descriptors[(int)X_C];"
           "LastCol.Label_width = AL4Form.Points(X_Lab);" .
           
        // Set column width/height
        // (in points, only for BOTTOM and TOP aligned columns):
        //-------------------------
        
        FUN Get_form_column_uses_margins(INT C|olumn_handle) ==> BOOL,
        	NATIVE :
			CASE C == 0 ? ==> ;
			NATIVE @     
        "   AL4Column LastCol = (AL4Column)AL4Form.All_descriptors[(int)X_C];"
        "	RESULT = !LastCol.No_margins;" .
        
        FUN Set_form_column_margins(INT C|olumn_handle, BOOL Use_margins),
        	NATIVE :
			CASE C == 0 ? ==> ;
			NATIVE @     
        "   AL4Column LastCol = (AL4Column)AL4Form.All_descriptors[(int)X_C];"
        "   if (X_Use_margins) {"
        "	   int p = (int)AL4Form.Pixels(4);"     
        "	   LastCol.Margin = new System.Windows.Forms.Padding(p, p, p, p);"
        "	   LastCol.No_margins = false;"     
        "	}"
        "	else {"
        "	   LastCol.Margin = new System.Windows.Forms.Padding(0, 0, 0, 0);"
        "	   LastCol.No_margins = true;"     
        "	}" .     
        

        FUN Set_form_column_width(
        	INT C|olumn_handle, REAL Width|_value), NATIVE :
			CASE C == 0 ? ==> ;
			NATIVE @
        @   "   AL4Column LastCol = (AL4Column)AL4Form.All_descriptors["
        	"		(int)X_C];"
            "   LastCol.Width = AL4Form.Points(X_Width);"
            "   LastCol.Fixed_width = AL4Form.Points(X_Width);"
            "	if (LastCol.Parent != null)"     
            "   	((AL4Form)LastCol.Parent).Adjust_columns_docking();" .

        FUN Set_form_column_height(
        	INT C|olumn_handle, REAL Height|_value), NATIVE :
			CASE C == 0 ? ==> ;
			NATIVE @
        @   "   AL4Column LastCol = (AL4Column)AL4Form.All_descriptors["
        	"		(int)X_C];"
            "   LastCol.Height = AL4Form.Points(X_Height);"
            "	if (LastCol.Parent != null)"     
            "   	((AL4Form)LastCol.Parent).Adjust_columns_docking();" .
        
        FUN Set_form_column_auto_arrange(
            INT C|olumn_handle, BOOL A|uto_arrange), NATIVE :
			CASE C == 0 ? ==> ;
			NATIVE @
        @   "   AL4Column LastCol = (AL4Column)AL4Form.All_descriptors["
        	"						(int)X_C];"
            "   LastCol.auto_arrange = X_A;"
            "   if (X_A) AL4Form.Adjust_control_location(LastCol);" .
        
		FUN Set_default_forms_font(
		{Screen} Screen|_object, STR Face|name, REAL Size|points)
			:
			Screen.Default_font_face = Face
			Screen.Default_font_size = Size .
		
        FUN Set_form_column_font(
        INT C|olumn_handle,
        STR Face | name,
		REAL Size| font,
		STR Styles| B_I_U_S), NATIVE :
			CASE C == 0 ? ==> ;
			NATIVE : @
		    "AL4Column LastCol = (AL4Column)AL4Form.All_descriptors[(int)X_C];"
		    "FontStyle fs = new FontStyle();"
		    "if (X_Styles.Contains('B')) fs = fs | FontStyle.Bold;"
		    "if (X_Styles.Contains('I')) fs = fs | FontStyle.Italic;"
		    "if (X_Styles.Contains('U')) fs = fs | FontStyle.Underline;"
		    "if (X_Styles.Contains('S')) fs = fs | FontStyle.Strikeout;"
		    "LastCol.Font = new Font(X_Face, (float)(X_Size <= 0 ? 8 : X_Size),"
		    " fs);" 
		    "LastCol.Custom_font = true;".
		    
        // Set column string "name"
        //-------------------------
        
        FUN Set_column_alias(
        	INT C|olumn_handle, STR Alias|_of_column), NATIVE :
			CASE C == 0 ? ==> ;
			NATIVE @
            "     AL4Form.Do_Set_column_alias((int)X_C, X_Alias);" .
        */
        public static void Do_Set_column_alias(int HC, string Alias)
        {
            AL4Column LastCol = (AL4Column)AL4Form.All_descriptors[HC];
            LastCol.Alias = Alias;
        }
      
      	/*
      	  
        FUN Disable_column_scroll(INT C|olumn_handle),
        NATIVE : @
		"    AL4Column LastCol = (AL4Column)AL4Form.All_descriptors[(int)X_C];"
		"    LastCol.VerticalScroll.Visible = false;"
		"	 LastCol.AutoScroll = false;" .     
		*/

        /*
        // Get column width in points
        //----------------------------
        
        FUN Get_column_width(INT C|olumn_handle) ==> REAL, NATIVE :
			CASE C == 0 ? ==> ;
			NATIVE @
            "    RESULT = AL4Form.Do_Get_column_width((int)X_C);" .
            
        FUN Get_column_pos_pixels(
        INT C|olumn_handle, STR W|hich_size_T_L_W_H) ==> INT, NATIVE :
			CASE C <= 0 ? ==> ;
			NATIVE @
            "    AL4Column Col = (AL4Column)AL4Form.All_descriptors[(int)X_C];"
            "	switch(X_W[0]) {"
            "	case 'L': return Col.Left;"
            "	case 'T': return Col.Top;"
            "	case 'W': return Col.Fixed_width > 0 ?"
            "				Col.Fixed_width : Col.Width;"
            "	case 'H': return Col.Height;"
            "	}" .
            
        FUN Set_column_position_pixels(
        INT C|olumn_handle, INT Left|_position, INT Top|_position), NATIVE : @
        "	AL4Column Col = (AL4Column)AL4Form.All_descriptors[(int)X_C];"
        "	Col.Left = (int)X_Left;"
        "	Col.Top = (int)X_Top;"   .
			
        FUN Set_column_width_pixels(
        INT C|olumn_handle, INT W|idth_pixels), NATIVE : @
        "	AL4Column Col = (AL4Column)AL4Form.All_descriptors[(int)X_C];"
        "	Col.Width = (int)X_W;"   .
			
        FUN Set_column_height_pixels(
        INT C|olumn_handle, INT H|eight_pixels), NATIVE : @
        "	AL4Column Col = (AL4Column)AL4Form.All_descriptors[(int)X_C];"
        "	Col.Height = (int)X_H;"   .
			
        */
        public static double Do_Get_column_width(int H)
        {
            AL4Column Col = (AL4Column)AL4Form.All_descriptors[H];
            if (Col.Fixed_width > 0) return Pixels(Col.Fixed_width);
            return Pixels(Col.ClientRectangle.Width);
        }

        /*
        // Get column height in points
        //----------------------------
        
        FUN Get_column_height(INT C|olumn_handle) ==> REAL, NATIVE :
			CASE C == 0 ? ==> ;
			NATIVE @
            "    RESULT = AL4Form.Do_Get_column_height((int)X_C);" .
        */
        public static double Do_Get_column_height(int H)
        {
            AL4Column Col = (AL4Column)AL4Form.All_descriptors[H];
            return Pixels(Col.ClientRectangle.Height);
        }

        /*
        // Get column (parent to a certain control) left position
        //----------------------------
        
        FUN Get_parent_column_visible(INT Handle|control) ==> BOOL,
            NATIVE :
            "    RESULT = AL4Form.Do_Get_parent_column_visible((int)X_Handle);" 
            .
        */
        public static bool Do_Get_parent_column_visible(int H)
        {
        	if (H == 0) return false;
            Control C = (Control)AL4Form.All_descriptors[H];
            AL4Column Col = (AL4Column)C.Parent;
            if (Col == null) return false;
            return Col.Visible;
        }

        /*
        // Get column (parent to a certain control) left position
        //----------------------------
        
        FUN Get_parent_column_left(INT Handle|control) ==> REAL,
            NATIVE :
            "    RESULT = AL4Form.Do_Get_parent_column_left((int)X_Handle);" .
        */
        public static double Do_Get_parent_column_left(int H)
        {
        	if (H == 0) return 0;
            Control C = (Control)AL4Form.All_descriptors[H];
            AL4Column Col = (AL4Column)C.Parent;
            if (Col == null) return 0;
            return Pixels(Col.Location.X);
        }
        
        /*
        // Get column (parent to a certain control) top position
        //----------------------------
        
        FUN Get_parent_column_top(
        	INT Handle|control) ==> REAL, NATIVE :
            "    RESULT = AL4Form.Do_Get_parent_column_top((int)X_Handle);" .
        */
        public static double Do_Get_parent_column_top(int H)
        {
        	if (H == 0) return 0;
            Control C = (Control)AL4Form.All_descriptors[H];
            AL4Column Col = (AL4Column)C.Parent;
            if (Col == null) return 0;
            return Pixels(Col.Location.Y);
        }

        /*
        // Get column visible
        //----------------------------
        
        FUN Get_column_visible(
        	INT C|olumn_handle) ==> BOOL, NATIVE :
			CASE C == 0 ? ==> ;
			NATIVE @
            "    RESULT = AL4Form.Do_Get_column_visible((int)X_C);" .
        */
        public static bool Do_Get_column_visible(int H)
        {
            AL4Column Col = (AL4Column)AL4Form.All_descriptors[H];
            return Col.Visible;
        }
        
        /*
        // Get column hidden
        //----------------------------
        
        FUN Get_column_hidden(
        	INT C|olumn_handle) ==> BOOL, NATIVE :
			CASE C == 0 ? ==> ;
			NATIVE @
            "    RESULT = AL4Form.Do_Get_column_hidden((int)X_C);" .
        */
        public static bool Do_Get_column_hidden(int H)
        {
            AL4Column Col = (AL4Column)AL4Form.All_descriptors[H];
            return Col.Hidden;
        }

        /*
        // Set column visible
        //----------------------------
        
        FUN Set_column_visible(
        	INT C|olumn_handle, BOOL V|isible_value), NATIVE :
			CASE C == 0 ? ==> ;
			NATIVE @
            "    AL4Form.Do_Set_column_visible((int)X_C, X_V);" .
        */
        public static void Do_Set_column_visible(int H, bool V)
        {
            AL4Column Col = (AL4Column)AL4Form.All_descriptors[H];
            //if (Col.Visible == V) return;
            Col.Visible = V;
            Col.Hidden = !V;
            AL4Form form = Parent_form(Col);
            form.Adjust_columns_docking();
        }

        /*
        
        FUN Control_suspend({Control} T|he_control), NATIVE :
        	INT h|andle_control = T.Handle
        	CASE h == 0 ? ==> ;
        	NATIVE @
        	"Control C = (Control)AL4Form.All_descriptors[(int)X_h];" 
        	"C.SuspendLayout();" .
        
        FUN Control_resume({Control} T|he_control), NATIVE :
        	INT h|andle_control = T.Handle
        	CASE h == 0 ? ==> ;
        	NATIVE @
        	"Control C = (Control)AL4Form.All_descriptors[(int)X_h];" 
        	"C.ResumeLayout();" .
        

        
        // Destroy control object
        //-----------------------
        
        FUN Destroy_control|_native(
        {Control} C|ontrol_object)
        	:
            STR save|_current_column = C.Form_.Current_column
            
            C.Form_.Set_current_column(Parent_column_alias(C))
            do_destroy_control(C.Form_.Handle, C.Handle) 
            C.Form_.Set_current_column(save) .
        
        FUN do_destroy_control|_native(INT H|andle_form, 
            INT Contr|ol_handle), NATIVE :
			CASE Contr == 0 ? ==> ;
			NATIVE @
            "     AL4Form.Do_Destroy_control((int)X_H, (int)X_Contr);" .
        */
        public static void Do_Destroy_control(int X_H, int X_C)
        {
            Control C = (Control)AL4Form.All_descriptors[(int)X_C];
            C.Parent = null;
            AL4Form.ReleaseDescriptor(X_C);
            C.Dispose();
        }
        
        /*
        
        FUN Parent_column_alias(
        {Control} C|ontrol_which_parent_alias_needed) ==> STR, NATIVE: @
        "	RESULT = AL4Form.Parent_column_alias(X_C);" .
        */
        
        public static string Parent_column_alias(Ref_obj CC) {
        	Control C = (Control)AL4Form.All_descriptors[
        			(int)((C_Control)CC.Obj).F_Handle]; 
        	AL4Column parent_column = (AL4Column)C.Parent;
        	return parent_column != null ? parent_column.Alias : "";
        }
        
        /*
        // Terminate application immediately
        //----------------------------------
        
        FUN Application_terminate, NATIVE :
            //"    Application.Exit();" 
            "    Environment.Exit(0);" .
        
        // Get active control on form
        //---------------------------
        
        FUN Obtain_active_control(
        {Form} F|orm_object) ==> {Control}, NATIVE :
			INT h|andle_form = F.Handle
			CASE h == 0 ? ==> ;
			NATIVE @
            "    RESULT = AL4Form.Do_Obtain_active_control((int)X_h);" .
        */
        public static Ref_obj Do_Obtain_active_control(int H)
        {
            AL4Form F = (AL4Form)AL4Form.All_descriptors[H];
            if (F == null) return C_Control.NoneObj_C_Control.hard_link;
            Control A = F.ActiveControl;
            if (A == null || A.Tag == null)
            	return C_Control.NoneObj_C_Control.hard_link;
            return (Ref_obj)(A.Tag);
        }

        /*
        // Activate certain control
        //-------------------------
        
        FUN Activate_control(
        	INT H|andle_form, INT C|ontrol_native), NATIVE :
			CASE H == 0 ? ==> ;
			//DEBUG: << "activate control: " Trace_stack(100) #NL ;
			NATIVE @
            "     AL4Form.Do_Activate_control((int)X_H, (int)X_C);" .
        */
        //[DllImport("user32.dll")]
        //static extern IntPtr GetFocus();
        [DllImport("user32.dll")]
        static extern bool ShowCaret(IntPtr hWnd);
        [DllImport("user32.dll")]
        static extern bool HideCaret(IntPtr hWnd);
        [DllImport("user32.dll")]
    	static extern bool PostMessage(
    	IntPtr hWnd, uint Msg, int wParam, int lParam);
    	
        public static void Do_Activate_control(int H, int X)
        {
            Control C = (Control)AL4Form.All_descriptors[(int)X];
            try
            {
                if (C.CanFocus) {
                	C.Parent.Focus();
                	C.Select();
                	
                	//Application.DoEvents();
                	//HideCaret(C.Handle);
                    AL4Form F = (AL4Form)AL4Form.All_descriptors[H];
                	Control N = F.GetNextControl(C, false);
                	if (N != null) N.Focus();
                	C.Focus();
	
                    //try {
                    //SendMessage(F.Handle, 0x28 /*WM_NEXTDLGCTL*/, 1, 0);
                    //SendMessage(F.Handle, 0x28 /*WM_NEXTDLGCTL*/, 0, 0);
                    //} catch(Exception) {}
                	//if (GetFocus() == C.Handle) 
                	//	ShowCaret(C.Handle);
                }
            }
            catch(Exception Ex) 
            {
            	if (Ex is AL4_Exception) throw; 
            }
        }

        /*
        // Move control into view area on parent column if  it is scrolled out
        //--------------------------------------------------------------------
        
        FUN Make_control_visible(INT H|andle_form, 
        	INT C|ontrol_to_move_to_view), NATIVE :
			CASE C == 0 ? ==> ;
			NATIVE @
            "     AL4Form.Do_Make_visible((int)X_H, (int)X_C);" .
        */
        public static void Do_Make_visible(int H, int X)
        {
            //todo:
        }

        /*
        // Get control left position in points (on its column)
        //----------------------------------------------------
        
        FUN Get_control_left|_position(
        {Control} C|ontrol_object) ==> REAL, NATIVE :
		 	INT h|andle_control = C.Handle
			CASE h == 0 ? ==> ;
			NATIVE @
            "     RESULT = AL4Form.Do_Get_control_left((int)X_h);" .
        */
        public static double Do_Get_control_left(int H)
        {
            Control C = (Control)AL4Form.All_descriptors[H];
            return Pixels(C.Left);
        }

        /*
        // Get control top position in points (on its column)
        //---------------------------------------------------
        
        FUN Get_control_top|_position(
        {Control} C|ontrol_object) ==> REAL, NATIVE :
		 	INT h|andle_control = C.Handle
			CASE h == 0 ? ==> ;
			NATIVE @
            "     RESULT = AL4Form.Do_Get_control_top((int)X_h);" .
        */
        public static double Do_Get_control_top(int H)
        {
            Control C = (Control)AL4Form.All_descriptors[H];
            return Pixels(C.Top);
        }

        /*
        // Set control position in points
        //-------------------------------
        
        FUN Set_control_pos|ition(INT C|ontrol_to_pos, 
        	REAL X|_offset, REAL Y|_offset), NATIVE :
			CASE C == 0 ? ==> ;
			NATIVE @
            "     AL4Form.Do_Set_control_pos((int)X_C, X_X, X_Y);" .
        */
        public static void Do_Set_control_pos(int H, double X, double Y)
        {
            Control C = (Control)AL4Form.All_descriptors[H];
            C.Location = new Point(Points(X), Points(Y));
        }
        
        /*
        // Is autosized ?
        //---------------------------
        
        FUN Is_autosized_control(
        	INT C|ontrol_to_check) ==> BOOL, NATIVE :
        	CASE C == 0 ? ==> ;
       NATIVE @	
       		"RESULT = true;"
        	"Control C = (Control)AL4Form.All_descriptors[(int)X_C];"
        	"if (C is Label) RESULT = ((Label)C).AutoSize;"
        	"else if (C is Button) RESULT = true;" .
        
        // Get control width in points
        //----------------------------
        
        FUN Get_control_width(
        {Control} C|ontrol_object) ==> REAL, NATIVE :
			INT h|andle_control = C.Handle
			CASE h == 0 ? ==> ;
			NATIVE @
            "     RESULT = AL4Form.Do_Get_control_width((int)X_h);" .
        */
        public static double Do_Get_control_width(int H)
        {
            Control C = (Control)AL4Form.All_descriptors[H];
            return Pixels(C.Width);
        }

        /*
        
        FUN Get_label_desired_width(
        {Control} C|ontrol_label) ==> REAL, NATIVE :
        	INT h|andle_control = C.Handle
        	//STR t|ext_of_label = C.Text
			CASE h == 0 ? ==> ;
			NATIVE @     
        	//{Bitmap} b|itmap_temp = New_bitmap(1, 1, 32)
        	"RESULT = AL4Form.Do_Get_label_desired_width((int)X_h);" .
        */	
        
        public static double Do_Get_label_desired_width(int H)
        {
			Label C = (Label)AL4Form.All_descriptors[H];
			Bitmap b = new Bitmap(1, 1);
			Graphics g = Graphics.FromImage(b);
			var sz = g.MeasureString(C.Text, C.Font);
			return Pixels(sz.Width);
        }
        
        /*
        // Get control height in points
        //-----------------------------
        
        FUN Get_control_height(
        {Control} C|ontrol_object) ==> REAL, NATIVE :
			INT h|andle_control = C.Handle
			CASE h == 0 ? ==> ;
			NATIVE @
            "     RESULT = AL4Form.Do_Get_control_height((int)X_h);" .
        */
        public static double Do_Get_control_height(int H)
        {
            Control C = (Control)AL4Form.All_descriptors[H];
            return Pixels(C.Height);
        }

        /*
        FUN Get_control_client_width(
        {Control} C|ontrol_object) ==> REAL, NATIVE :
			INT h|andle_control = C.Handle
			CASE h == 0 ? ==> ;
			NATIVE @
            "     RESULT = AL4Form.Do_Get_control_client_width((int)X_h);" .
        */
        public static double Do_Get_control_client_width(int H)
        {
            Control C = (Control)AL4Form.All_descriptors[H];
            return Pixels(C.ClientSize.Width);
        }
        /*
        FUN Get_control_client_height(
        {Control} C|ontrol_object) ==> REAL, NATIVE :
			INT h|andle_control = C.Handle
			CASE h == 0 ? ==> ;
			NATIVE @
            "     RESULT = AL4Form.Do_Get_control_client_height((int)X_h);" .
        */
        public static double Do_Get_control_client_height(int H)
        {
            Control C = (Control)AL4Form.All_descriptors[H];
            return Pixels(C.ClientSize.Height);
        }
        
		/*
        
        // Set control size in points
        //---------------------------
        
        FUN Set_control_size_auto(
        	INT C|ontrol_to_pos, REAL W|idth_set, REAL H|eight_set), NATIVE :
			CASE C == 0 ? ==> ;
			NATIVE @
			"	AL4Form.automatic_control_size = true;"
			"	try {"
			"		AL4Form.Do_Set_control_size((int)X_C, X_W, X_H);"     
			"	}"
			"	finally {"
			"		AL4Form.automatic_control_size = false;	"
			"	}"
            .
        
        FUN Set_control_size(
        	INT C|ontrol_to_pos, REAL W|idth_set, REAL H|eight_set), NATIVE :
			CASE C == 0 ? ==> ;
			NATIVE @
            "     AL4Form.Do_Set_control_size((int)X_C, X_W, X_H);" .
        */
        public static bool automatic_control_size;
        
        public static void Do_Set_control_size(int H, double Width,
            double Height)
        {
            Control C = (Control)AL4Form.All_descriptors[H];
            ignore_control_resize = true;
            int h = Points(Height);
            try {
	            if (C is Label && h <= 0) {
	            	C.Width = Points(Width);
	            } else {
            		C.Size = new Size(Points(Width), h);
	            }
            }
            finally {
            	ignore_control_resize = false;
            }
            if  (C is Label && !automatic_control_size)
            {
            	((Label)C).AutoSize = false;
            }
        }

        /*
        // Set control text
        //-----------------
        
        FUN Set_control_caption(
        {Control} C|ontrol_object, STR Text|_set), NATIVE :
			INT h|andle_control = C.Handle
			CASE h == 0 ? ==> ;
			C.local_caption = Text
			NATIVE @
        	"     AL4Form.Do_Set_control_caption((int)X_h, X_Text);" .
        */
        public static void Do_Set_control_caption(int H, string Text)
        {
            Control C = (Control)AL4Form.All_descriptors[H];
            bool same_text = C.Text==Text;
            C.Text = Text;
            if (C.Parent == null) return;
            
            if ((C is Button || C is CheckBox || C is Label) 
            && ((AL4Column)C.Parent).Horizontal
            && (!(C is Label) || C.AutoSize))
            {
            	if (!(C is Label && !C.AutoSize)) {
	            	Bitmap B = new Bitmap(1,1);
	            	Graphics g = Graphics.FromImage(B);
	            	Font f = C.Font;
	            	SizeF sz = g.MeasureString(Text, f);
	            	C.Width = (int)sz.Width + (int)sz.Height * 2 
	            		+ (C is CheckBox ? (int)sz.Height * 2 : 0);
            	}
            }
            if (same_text) return;
            
            AL4Form F = Parent_form(C);
            bool save_click_disabled = F.click_disabled;
            try {
            	F.click_disabled = false;
            	F.Control_changed(C, null);
            	C.Refresh();
            }
            finally {
            	F.click_disabled = save_click_disabled;
            }
        }

        /*
        // Return control text
        //--------------------
        
        FUN Get_control_caption(
        {Control} C|ontrol_object) ==> STR, NATIVE :
			INT h|andle_control = C.Handle
			NATIVE @ "     RESULT = AL4Form.Do_Get_control_caption((int)X_h);" .
        */
        public static string Do_Get_control_caption(int H)
        {
        	if (H==0) return "";
            Control C = (Control)AL4Form.All_descriptors[H];
            return C.Text;
        }

        /*
        
        FUN Set_control_align(
        {Control} C|ontrol_object, {Control}.{text_align} TA|lignment), NATIVE 
        	:
        	INT h|andle_control = C.Handle
        	CASE h==0 ? ==> ;
        	NATIVE @     
            "Control C = (Control)AL4Form.All_descriptors[(int)X_h];"
            "ContentAlignment CA = ContentAlignment.MiddleLeft;"    
            "HorizontalAlignment HA = HorizontalAlignment.Left;"     
            "switch (X_TA) {"
            "case 1: CA = ContentAlignment.MiddleCenter;"
            "		 HA = HorizontalAlignment.Center;"     
            "		 break;"
            "case 2: CA = ContentAlignment.MiddleRight;"
            "		 HA = HorizontalAlignment.Right;"     
            "		 break;"     
            "}"     
            "if (C is Label) { ((Label)C).TextAlign = CA; "
            
            //"		((Label) C).BorderStyle  = BorderStyle.FixedSingle;"
                 
            "}"
            "else if (C is TextBox) { ((TextBox)C).TextAlign = HA; }"     
            .
        
        
        // Return TRUE if control is DISABLED (!)
        //---------------------------------------
        
        FUN Get_control_disabled(
        {Control} C|ontrol_object) ==> BOOL, NATIVE :
			INT h|andle_control = C.Handle
			NATIVE @ "     RESULT = AL4Form.Do_Get_disabled((int)X_h);" .
        */
        public static bool Do_Get_disabled(int H)
        {
            Control C = (Control)AL4Form.All_descriptors[H];
            return !C.Enabled;
        }

        /*
        // Set control disabled (TRUE - disabled, FALSE - enabled)
        //--------------------------------------------------------
            
        FUN Set_control_disabled(
        {Control} C|ontrol_object,
        BOOL Disable|_control), NATIVE :
			INT h|andle_control = C.Handle
			NATIVE @ "     AL4Form.Do_Set_disabled((int)X_h, X_Disable);" .
        */
        public static void Do_Set_disabled(int H, bool D)
        {
            Control C = (Control)AL4Form.All_descriptors[H];
            C.Enabled = !D;
            //C.Invalidate();
            if (C is ListBox)
            {
                if (D)
                    C.BackColor = SystemColors.Control;
                else C.BackColor = SystemColors.Window;
            }
        }

        /*
        // Get TRUE when control is hidden (FALSE if visible)
        //---------------------------------------------------
        
        FUN Get_control_hidden(
        {Control} C|ontrol_object) ==> BOOL, NATIVE :
			INT h|andle_control = C.Handle
			CASE h == 0 ? RESULT = TRUE ==> ;
			NATIVE @ "     RESULT = AL4Form.Do_Get_hidden((int)X_h);" .
        */
        public static bool Do_Get_hidden(int H)
        {
            Control C = (Control)AL4Form.All_descriptors[H];
            return !C.Visible;
        }

        /*
        // Set control hidden state (TRUE - hidden, FALSE - Visible)
        //----------------------------------------------------------
        
        FUN Set_control_hidden(
        {Control} C|ontrol_object, BOOL M|ake_hidden), NATIVE :
			INT h|andle_control = C.Handle
			CASE h == 0 ? ==> ;
			NATIVE @ "     AL4Form.Do_Set_hidden((int)X_h, X_M);" .
        */
        public static void Do_Set_hidden(int H, bool M)
        {
        	if (H == 0) return;
            Control C = (Control)AL4Form.All_descriptors[H];
            bool same = C.Visible == !M;
            C.Visible = !M;
            AL4Column parent_column = (AL4Column)C.Parent;
            if (parent_column == null) return;
            if (M) {
            	if (!parent_column.Hidden_controls.Contains(C))
            		parent_column.Hidden_controls.Add(C);
            }
            else parent_column.Hidden_controls.Remove(C);
            if (!same)
            	Adjust_control_location(parent_column);
        }
        
        /*
        
        FUN Get_control_foreground(
        {Control} C|ontrol_object) ==> INT, NATIVE :
			INT h|andle_control = C.Handle
			CASE h == 0 ? ==> ;
			NATIVE @
        @   "   Control C = (Control)AL4Form.All_descriptors[(int)X_h];"
            "   RESULT = C.ForeColor.R | C.ForeColor.G << 8 "
            "   | C.ForeColor.B << 16;" .

        FUN Set_control_foreground(
        {Control} C|ontrol_object, INT Color|_set), NATIVE :
			INT h|andle_control = C.Handle
			CASE h == 0 ? ==> ;
			NATIVE @
        @   "   Control C = (Control)AL4Form.All_descriptors[(int)X_h];"
            "   C.ForeColor = Color.FromArgb("
            "					(int)(X_Color & 0xff), "
            "       			(int)(X_Color & 0xff00) >> 8, "
            "					(int)(X_Color & 0xff0000) >> 16);" .

        FUN Get_control_background(
        {Control} C|ontrol_object) ==> INT, NATIVE :
			INT h|andle_control = C.Handle
			CASE h == 0 ? ==> ;
			NATIVE @
        @   "   Control C = (Control)AL4Form.All_descriptors[(int)X_h];"
            "   RESULT = C.BackColor.R | C.BackColor.G << 8 "
            "   | C.BackColor.B << 16;" .

        FUN Set_control_background(
        {Control} C|ontrol_object, INT Color|_set), NATIVE :
			INT h|andle_control = C.Handle
			CASE h == 0 ? ==> ;
			NATIVE @
        @   "   Control C = (Control)AL4Form.All_descriptors[(int)X_h];"
            "   C.BackColor = Color.FromArgb("
            "		(int)(X_Color & 0xff), "
            "       (int)(X_Color & 0xff00) >> 8, "
            "		(int)(X_Color & 0xff0000) >> 16);" .

        FUN Get_control_font_face(
        {Control} C|ontrol_object) ==> STR, NATIVE :
			INT h|andle_control = C.Handle
			CASE h == 0 ? ==> ;
			NATIVE @
        @   "   Control C = (Control)AL4Form.All_descriptors[(int)X_h];"
            "   RESULT = C.Font.Name;" .

        FUN Set_control_font_face(
        {Control} C|ontrol_object, STR Face|_set), NATIVE :
			INT h|andle_control = C.Handle
			CASE h == 0 ? ==> ;
			NATIVE @
        @   "   Control C = (Control)AL4Form.All_descriptors[(int)X_h];"
            "   C.Font = new Font(X_Face, C.Font.Size, C.Font.Style);" .
            
        FUN Get_control_font_size(
        {Control} C|ontrol_object) ==> REAL, NATIVE :
			INT h|andle_control = C.Handle
			CASE h == 0 ? ==> ;
			NATIVE @
        @   "   Control C = (Control)AL4Form.All_descriptors[(int)X_h];"
            "   RESULT = C.Font.Size;" .

        FUN Set_control_font_size(
        {Control} C|ontrol_object, REAL Size|_set), NATIVE :
			INT h|andle_control = C.Handle
			CASE h == 0 ? ==> ;
			NATIVE @
        @   "   if (X_Size < 0.01) return;"
            "   Control C = (Control)AL4Form.All_descriptors[(int)X_h];"
            "   C.Font = new Font(C.Font.Name, (float)X_Size, C.Font.Style);" .
            
        FUN Get_control_font_styles(
        {Control} C|ontrol_object) ==> STR, NATIVE :
			INT h|andle_control = C.Handle
			CASE h == 0 ? ==> ;
			NATIVE @
        @   "   Control C = (Control)AL4Form.All_descriptors[(int)X_h];"
            "	if (C.Font.Bold) RESULT += 'B';"
            "   if (C.Font.Italic) RESULT += 'I';"
            "   if (C.Font.Underline) RESULT += 'U';"
            "   if (C.Font.Strikeout) RESULT += 'S';" .

        FUN Set_control_font_styles(
        {Control} C|ontrol_object, STR St|yles_string_B_U_I_S), NATIVE :
			INT h|andle_control = C.Handle
			CASE h == 0 ? ==> ;
			NATIVE @
        @   "   Control C = (Control)AL4Form.All_descriptors[(int)X_h];"
            "   FontStyle fs = FontStyle.Regular;"
            "   for (int i = 0; i < X_St.Length; i++)"
            "   {"
            "       switch (X_St[i])"
            "       {"
            "       case 'B': fs |= FontStyle.Bold; break;"
            "       case 'I': fs |= FontStyle.Italic; break;"
            "       case 'U': fs |= FontStyle.Underline; break;"
            "       case 'S': fs |= FontStyle.Strikeout; break;"
            "       }"
            "   }"
            "   C.Font = new Font(C.Font.Name, C.Font.Size, fs); " .
            
        FUNCTION List_fonts_installed(
        INT Op|tions_1Mono_2True,
        STR Names|_of_fonts[]), NATIVE:
            "   AL4Form.Do_list_fonts((int)X_Op, X_Names);" .
        */
        
        public static void Do_list_fonts(int Op, ArrayStr X_Names)
        {
            foreach (FontFamily ff in System.Drawing.FontFamily.Families)
        	{
        		if (ff.IsStyleAvailable(FontStyle.Regular))
        		{
        			Font f = new Font(ff, 10);
        			float diff = 0;
                    if ((Op & 1) != 0)
                        diff = TextRenderer.MeasureText("WWW", f).Width
                            - TextRenderer.MeasureText("iii", f).Width;
                    bool is_mono = diff < 1e-2;
                    if ((Op & 1) != 0 && !is_mono) continue;
        			X_Names.Add(ff.Name);
        		}
        	}        
        } 

        /*
        // Show message modal (until user press OK)
        //-----------------------------------------
        
        FUN Show_message(
        	INT H|andler_form, STR Text|_show), NATIVE :
            "     AL4Form.Do_show_message((int)X_H, X_Text);" .
        */
        public static void Do_show_message(int H, string T)
        {
            AL4Form form = (AL4Form)AL4Form.All_descriptors[H];
            Form r_form = form;
            if (r_form == null) r_form = Form.ActiveForm;
            if (form != null && form.Visible)
                MessageBox.Show(form,
                T, form.Text, MessageBoxButtons.OK, MessageBoxIcon.None);
            else
				MessageBox.Show(null,
            	T, 
            	form != null ? form.Text 
            	: Path.GetFileNameWithoutExtension(Application.ExecutablePath), 
            	MessageBoxButtons.OK, MessageBoxIcon.None,
            	MessageBoxDefaultButton.Button1,
            	MessageBoxOptions.DefaultDesktopOnly);                
            
        	try {
        		if (r_form != null && r_form.Visible) {
        			if (r_form is AL4Form)
        				((AL4Form)r_form).WantReactivate();
        			else
	                    PostMessage(r_form.Handle, 0x6 //WM_ACTIVATE
	                    , 1, 0);
        		}
        	}
        	catch(Exception Ex) 
        	{
        		if (Ex is AL4_Exception) throw;
        	}
        }
        
        System.Windows.Forms.Timer TimerReactivate;
        
       	void WantReactivate()
       	{
       		if (TimerReactivate == null)
       		{
       			TimerReactivate = new System.Windows.Forms. Timer();
            	TimerReactivate.Enabled = false;
            	TimerReactivate.Tick += new EventHandler(DoReactivate);
       			TimerReactivate.Interval = 10;
       		}
       		TimerReactivate.Enabled = true;
       	}
       	
       	void DoReactivate(Object Sender, EventArgs E) {
       		try {
	       		TimerReactivate.Enabled = false;
	       		Activate();
       		}
       		catch(Exception Ex) 
       		{
       			if (Ex is AL4_Exception) throw;
       		}
       	}

        /*
        // Ask a question which requres an answer Yes or No
        //-------------------------------------------------
        
        FUN Message_box_yes_no(
        	INT H|andler_form, STR Text|_show) ==> BOOL, NATIVE :
            "    RESULT = AL4Form.Do_ask_yes_no((int)X_H, X_Text);" .
        */
        public static bool Do_ask_yes_no(int H, string T)
        {
            //AL4Form form = (AL4Form)AL4Form.All_descriptors[H];
            //bool r = MessageBox.Show(T, form == null ? "" : form.Text,
            //    MessageBoxButtons.YesNo) == DialogResult.Yes;
            	
            //form.WantReactivate();
			AL4Form form = (AL4Form)AL4Form.All_descriptors[H];
			bool r = false;
            Form r_form = form;
            if (r_form == null) r_form = Form.ActiveForm;
            if (form != null && form.Visible)
                r = MessageBox.Show(form,
                T, form.Text, MessageBoxButtons.YesNo, MessageBoxIcon.None)
                == DialogResult.Yes;
            else
				r = MessageBox.Show(null,
            	T, 
            	form != null ? form.Text 
            	: Path.GetFileNameWithoutExtension(Application.ExecutablePath), 
            	MessageBoxButtons.YesNo, MessageBoxIcon.None,
            	MessageBoxDefaultButton.Button1,
            	MessageBoxOptions.DefaultDesktopOnly)
            	== DialogResult.Yes;                
            
        	try {
        		if (r_form != null && r_form.Visible) {
        			if (r_form is AL4Form)
        				((AL4Form)r_form).WantReactivate();
        			else
	                    PostMessage(r_form.Handle, 0x6 //WM_ACTIVATE
	                    , 1, 0);
        		}
        	}
        	catch(Exception Ex) 
        	{
        		if (Ex is AL4_Exception) throw;
        	}            return r;
        }
        
        /*
        
        FUN Column_children_count(INT C|olumn_handle) ==> INT, NATIVE : @
            "AL4Column Col = (AL4Column)AL4Form.All_descriptors[(int)X_C];"   
            "RESULT = Col.Child_controls.Count;" .
        
        FUN Column_child(INT C|olumn_handle, INT Index|_of_child) ==> {Control},
        NATIVE : @
            "AL4Column Col = (AL4Column)AL4Form.All_descriptors[(int)X_C];"
            "Control c = X_Index < 0 || X_Index >= Col.Child_controls.Count ?"
            " 			 null : Col.Child_controls[(int)X_Index];"
            "if (c == null || c.Tag == null)"
            "	return C_Control.NoneObj_C_Control.hard_link;"
            "RESULT = (Ref_obj)c.Tag;"
            "RESULT.Count += 2;" .
        
        FUN Adjust_control_location(INT C|olumn_handle), NATIVE : @
        "	AL4Column Col = (AL4Column)AL4Form.All_descriptors[(int)X_C];"
        "	AL4Form.Adjust_control_location(Col);" .
        
        */
        
        public static int debug_entry;
        public static void Adjust_control_location(AL4Column Parent)
        {
            if (!Parent.auto_arrange) return;
            if (Parent.suspend_count > 0) return;
            if (Parent.adjusting_controls) return;
            
            AL4Form form = Parent_form(Parent);
            if (form == null) return;
            //if (form.adjusting_columns) return;
            if (Parent.adjusting_controls) return;
            if (((C_Form)form.AL4Object.Obj).F_suspended_count > 1) return;
            
            Parent.adjusting_controls = true;
            try {
            	C_Form.M_Do_adjust_controls(form.AL4Object, Parent.Handle_column);
            }
            finally {
            	Parent.adjusting_controls = false;
            }
        }
        

        public static void Set_control_events(AL4Column Parent, Control C)
        {
        	AL4Form F = Parent_form(Parent);
            if (F != null)
            {
                C.Click += new EventHandler(F.Control_clicked);
                C.Resize += new EventHandler(F.Control_resized);
                C.MouseMove += new MouseEventHandler(F.Control_MouseMove);
                C.MouseDown += new MouseEventHandler(F.Control_MouseDown);
                C.MouseUp += new MouseEventHandler(F.Control_MouseUp);
                C.MouseDoubleClick += new MouseEventHandler(F.Control_DoubleClick);
                C.KeyDown += new KeyEventHandler(F.Control_KeyDown);
                C.KeyUp += new KeyEventHandler(F.Control_KeyUp);
                C.KeyPress +=new KeyPressEventHandler(F.Control_KeyPress);
                C.Enter += new EventHandler(F.Control_Enter);
        		C.Leave += new EventHandler(F.Control_Leave);
            }
        }
        
        public static AL4Column Get_parent_for_new_control(int H) {
        	if (H == 0) return null;
            AL4Form F = (AL4Form)AL4Form.All_descriptors[H];
            if (F.Current_column_handle == 0)
            {
                C_Form X_F = (C_Form)F.AL4Object.Obj;
                X_F.Do.M_initial_column();
            }
            AL4Column C = (AL4Column)AL4Form.All_descriptors[
            						 F.Current_column_handle];
            return C;
        }
        
		/*
		
		FUN Set_control_anchor_bottom(
		{Control} C|ontrol_changed, BOOL A|nchor_bottom), NATIVE : @ 
			"//do not remove this function, it is necessary for interpreting" .
			
		
        FUN Invalidate_control(
        	INT C|ontrol_handle), NATIVE :
		@	"	Control C = (Control)AL4Form.All_descriptors[(int)X_C];"
			"	C.Invalidate();" .
			
		FUN Invalidate_form(INT H|andle_form), NATIVE : @
		    "	AL4Form f = (AL4Form)AL4Form.All_descriptors[(int)X_H];" 
		    "	f.Refresh();" .
        */

        //------------------------------------------------------- L A B E L

        /*
        // Create label control, return integer descripto to it
        //-----------------------------------------------------
        
        FUN Create_label({Control} L|abel_control) ==> INT :
            RESULT = do_create_label(L.Form_.Handle, L) .

        FUN do_create_label(INT P|arent_handle,
            {Control} L|abel_create) ==> INT, NATIVE :
            "     RESULT = AL4Form.Do_Create_label((int)X_P, X_L);" .
        */
        
        public class NoWrapLabel : Label
		{
		    public NoWrapLabel() {}
		
		    protected override void OnPaint(PaintEventArgs e)
		    {
		    	Size sz = e.Graphics.MeasureString(Text, Font).ToSize();
		    	int x = 0;
		    	int y = 0;
		    	switch (TextAlign)
		    	{
			    	case ContentAlignment.TopLeft: break;
			    	case ContentAlignment.MiddleLeft: 
		        		y = (Height - sz.Height)/2; break;
			    	case ContentAlignment.BottomLeft:
			    		y = (Height - sz.Height); break;
			    	case ContentAlignment.TopCenter:
		        		x = (Width - sz.Width)/2; break;
			    	case ContentAlignment.MiddleCenter: 
		        		x = (Width - sz.Width)/2; break;
		        		y = (Height - sz.Height)/2; break;
			    	case ContentAlignment.BottomCenter:
		        		x = (Width - sz.Width)/2; break;
			    		y = (Height - sz.Height); break;
			    	case ContentAlignment.TopRight:
		        		x = (Width - sz.Width); break;
			    	case ContentAlignment.MiddleRight: 
		        		x = (Width - sz.Width); break;
		        		y = (Height - sz.Height)/2; break;
			    	case ContentAlignment.BottomRight:
		        		x = (Width - sz.Width); break;
			    		y = (Height - sz.Height); break;
		    	}
		        e.Graphics.DrawString(Text, Font, 
		        	new SolidBrush(ForeColor), x, y);
		    }
		}
        public static int Do_Create_label(int H, Ref_obj X_L)
        {
            AL4Column P = Get_parent_for_new_control(H);
            Label L = new NoWrapLabel();
            int Result = AL4Form.AllocDescriptor(L);
            L.Tag = X_L;
            P.Controls.Add(L);
            P.Child_controls.Add(L);
            Adjust_control_font(L);
            L.AutoSize = true;
            Adjust_control_location(P);
            Set_control_events(P, L);
            return Result;
        }
        
        //---------------------------------------------------- B U T T O N

        /*
        // Create button control, return descriptor
        //------------------------------------------
        
        FUN Create_button(
        	{Control} B|utton_control) ==> INT
        	:
            RESULT = do_create_button(B.Form_.Handle, B) .

        FUN do_create_button(INT F|orm_handle, 
            {Control} B|utton_create) ==> INT, NATIVE :
			CASE F == 0 ? ==> ;
			NATIVE @
            "     RESULT = AL4Form.Do_Create_button((int)X_F, X_B);" .
        */
 		public static int default_button_height = 0;       
	
        public static int Do_Create_button(int H, Ref_obj X_B)
        {
            AL4Column P = Get_parent_for_new_control(H);
            Button B = new Button();
            B.Margin = new Padding(0, 0, 0, 0);
            
            B.AutoSize = true;
            B.AutoSizeMode = AutoSizeMode.GrowOnly;
            B.UseCompatibleTextRendering = true;
            //B.Height = default_button_height;
            B.Tag = X_B;
            int Result = AL4Form.AllocDescriptor(B);
            //B.Parent = P;
            P.Controls.Add(B);
            P.Child_controls.Add(B);
            Adjust_control_font(B);
            if (default_button_height == 0)
            {
                Graphics g = B.CreateGraphics();
                Size sz = g.MeasureString("Ap_^/|", B.Font).ToSize();
                default_button_height = sz.Height * 2;
            //	AL4_system.WriteLine("default_button_height=" +
            //		default_button_height.ToString());
            }
            Adjust_control_location(P);
            Set_control_events(P, B);
            return Result;
        }

        /*
        
        FUN Set_form_default_button(
        	INT H|andle_form, INT B|utton_handle), NATIVE :
			CASE H == 0 || B == 0 ? ==> ;
			NATIVE @
        @   "   AL4Form F = (AL4Form)AL4Form.All_descriptors[(int)X_H];"
        	"	if (F == null) return;"
            "   Button B = (Button)AL4Form.All_descriptors[(int)X_B];"
            "   F.AcceptButton = B;"
            .
            
        FUN Set_form_cancel_button(
        	INT H|andle_form, INT B|utton_handle), NATIVE :
			CASE H == 0 || B == 0 ? ==> ;
			NATIVE @
        @   "   AL4Form F = (AL4Form)AL4Form.All_descriptors[(int)X_H];"
        	"	if (F == null) return;"
            "   Button B = (Button)AL4Form.All_descriptors[(int)X_B];"
            "   F.CancelButton = B;" .
        */
        
        
        //------------------------------------------------- C H E C K B O X

        /*
        // Create checkbox, return descriptor
        //-----------------------------------
        
        FUN Create_checkbox(
        	{Control} C|heckbox_control) ==> INT
        	:
            RESULT = do_create_checkbox(C.Form_.Handle, C) .

        FUN do_create_checkbox(INT F|orm_handle,
            {Control} C|checkbox_create) ==> INT, NATIVE :
            "     RESULT = AL4Form.Do_Create_checkbox((int)X_F, X_C);" .
        */
        public static int Do_Create_checkbox(int H, Ref_obj X_C)
        {
            AL4Column P = Get_parent_for_new_control(H);
            CheckBox C = new CheckBox();
            int Result = AL4Form.AllocDescriptor(C);
            C.Tag = X_C;
            P.Controls.Add(C);
            P.Child_controls.Add(C);
            Adjust_control_font(C);
            Adjust_control_location(P);
            Set_control_events(P, C);
            AL4Form F = Parent_form(P);
            C.CheckedChanged += new EventHandler(F.Control_changed);
            return Result;
        }

        /*
        // Return TRUE if checkbox is checked
        //-----------------------------------
        
        FUN Get_checkbox_checked(
        {Control} C|heckbox_control) ==> BOOL, NATIVE :
			INT h|andle_checkbox = C.Handle
			NATIVE @ "    RESULT = AL4Form.Do_Get_checkbox_checked((int)X_h);" .
        */
        public static bool Do_Get_checkbox_checked(int H)
        {
            CheckBox C = (CheckBox)AL4Form.All_descriptors[H];
            return C.Checked;
        }

        /*
        // Set checkbox state (TRUE - checked, FALSE - unchecked)
        //-------------------------------------------------------
        
        FUN Set_checkbox_checked(
        {Control} C|heckbox_control, BOOL V|alue_checked), NATIVE :
			INT h|andle_control = C.Handle
			NATIVE @ "    AL4Form.Do_Set_checkbox_checked((int)X_h, X_V);" .
        */
        public static void Do_Set_checkbox_checked(int H, bool X_V)
        {
        	if (H == 0) return;
            CheckBox C = (CheckBox)AL4Form.All_descriptors[H];
            C.Checked = X_V;
        }
        
        /*
        // Get checkbox text
        //-------------------------------------------------------
        FUN Get_checkbox_text(INT C|heckbox_handle) ==> STR, NATIVE :
           @"    CheckBox C = (CheckBox)AL4Form.All_descriptors[(int)X_C];" 
            "    RESULT = C.Text;" .
            
        // Set checkbox text
        //-------------------------------------------------------
        
        FUN Set_checkbox_text(
        	INT C|heckbox_handle, STR T|ext_set), NATIVE :
           @"    CheckBox C = (CheckBox)AL4Form.All_descriptors[(int)X_C];" 
            "    C.Text = X_T;" .
        */
        

        //------------------------------------------------------ E D I T

        /*
        // Create edit control, return descriptor
        //---------------------------------------
        
        FUN Create_edit(
            {Control} E|dit_control,
            STR Password|_char,
            BOOL Read|_only) ==> INT, NATIVE
            :
            INT form|_handle = E.Form_.Handle
            NATIVE  @
            "     RESULT = AL4Form.Do_Create_edit("
            "           (int)X_form, X_E, X_Password, X_Read);" .
        */
        public static int Do_Create_edit(int H, Ref_obj X_E, string X_Password,
            bool X_Readonly)
        {
        	if (H == 0) return 0;
            AL4Column P = Get_parent_for_new_control(H);
            TextBox E = new TextBox();
            int Result = AL4Form.AllocDescriptor(E);
            E.Tag = X_E;
            if (X_Readonly)
            	E.ReadOnly = true;
            //E.Parent = P;
            P.Controls.Add(E);
            P.Child_controls.Add(E);
            Adjust_control_font(E);
            Adjust_control_location(P);
            Set_control_events(P, E);
            AL4Form F = Parent_form(P);
            if (X_Password != "") E.PasswordChar = X_Password[0];
            E.TextChanged += new EventHandler(F.Control_changed);
            
            //if (!X_Readonly)
            //	E.Enter += new EventHandler(F.Edit_enter);
            
            return Result;
        }

        /*
        // Get edit selection text
        //------------------------------
        
        FUN Get_edit_selection(
        	INT E|dit_control) ==> STR, NATIVE :
            "    RESULT = AL4Form.Do_Get_edit_selection((int)X_E);" .
        */
        public static string Do_Get_edit_selection(int H)
        {
            TextBox T = (TextBox)AL4Form.All_descriptors[H];
            return T.SelectedText;
        }
        
        /*
        // Get/set edit selection range
        //------------------------------
        
        FUN Get_edit_selection_start(
        	INT E|dit_control) ==> INT, NATIVE :
        @   "    TextBox T = (TextBox)AL4Form.All_descriptors[(int)X_E];"
            "    RESULT = T.SelectionStart;" .

        FUN Get_edit_selection_length(
        	INT E|dit_control) ==> INT, NATIVE :
        @   "    TextBox T = (TextBox)AL4Form.All_descriptors[(int)X_E];"
            "    RESULT = T.SelectionLength;" .

        FUN Set_edit_selection_range(
        	INT E|dit_control, INT Start|_selection,
            INT Length|_selection), NATIVE :
        @   "    TextBox T = (TextBox)AL4Form.All_descriptors[(int)X_E];"
            "    T.SelectionStart = (int)X_Start;"
            "    T.SelectionLength = (int)X_Length;" .
        */

        /*
        // Replace edit selection with another text
        //-----------------------------------------
        
        FUN Set_edit_selection(
        	INT E|dit_control, STR Text|_replace_selection), NATIVE :
            "    AL4Form.Do_Set_edit_selection((int)X_E, X_Text);" .
        */
        public static void Do_Set_edit_selection(int H, string X_Text)
        {
            TextBox T = (TextBox)AL4Form.All_descriptors[H];
            T.SelectedText = X_Text;
        }

        /*
        // Set edit maximal length
        //------------------------
        
        FUN Set_edit_max_len(
        	INT E|dit_control, INT V|alue_max_len), NATIVE : @
            "    AL4Form.Do_Set_edit_max_len((int)X_E, "
            "		X_V < int.MaxValue ? (int)X_V : 0x7FFFffff);" .
        */
        public static void Do_Set_edit_max_len(int H, int X_V)
        {
            TextBox T = (TextBox)AL4Form.All_descriptors[H];
            if  (X_V < 0) X_V = 0;
            T.MaxLength = X_V;
        }

        //------------------------------------------------------- M E M O

        /*
        // Create memo control, return descriptor
        //---------------------------------------
        
        FUN Create_memo({Control} M|emo_control,
            STR S|crolls_and_options_Vertical_Horizontal_Readonly) ==> INT
            :
            RESULT = do_create_memo(M.Form_.Handle, M, 
            	"R" IN S, "H" !IN S, "V" !IN S)
            .
        FUN do_create_memo(INT Form|_handle, {Control} M|emo_control,
            BOOL Read|_only,
            BOOL No_h|scroll,
            BOOL No_v|scroll) ==> INT, NATIVE
            :
            NATIVE @
            "     RESULT = AL4Form.Do_Create_memo((int)X_Form, X_M,"
            "       X_Read, X_No_h, X_No_v);" .
        */
        public static int Do_Create_memo(int H, Ref_obj X_M, bool X_Read,
            bool X_No_h, bool X_No_v)
        {
            AL4Column P = Get_parent_for_new_control(H);
            TextBox M = new TextBox();
            M.Multiline = true;
            if (X_Read) M.ReadOnly = true;
            if (!X_No_h && !X_No_v) M.ScrollBars = ScrollBars.Both;
            else if (!X_No_v) M.ScrollBars = ScrollBars.Vertical;
            else if (!X_No_h) M.ScrollBars = ScrollBars.Horizontal;
            //if (X_No_h) M.WordWrap = true;
            M.WordWrap = X_No_h;
            int Result = AL4Form.AllocDescriptor(M);
            M.Tag = X_M;
            //M.Parent = P;
            P.Controls.Add(M);
            P.Child_controls.Add(M);
            Adjust_control_font(M);
            M.Height = Points(100);
            Adjust_control_location(P);
            Set_control_events(P, M);
            AL4Form F = Parent_form(P);
            M.Text = "";
            M.TextChanged += new EventHandler(F.Control_changed);
            return Result;
        }

        /*
        // Memo is providing lines in API.
        //----------------------------------------------
        
        FUN Memo_supports_lines ==> BOOL :
			RESULT = TRUE .
        */

        /*
        // Return memo line by index
        //--------------------------
        
        FUN Get_memo_item(
        	INT M|emo_control, INT Row|_index) ==> STR, NATIVE :
            "    RESULT = AL4Form.Do_Get_memo_item((int)X_M, (int)X_Row);" .
        */
        public static string Do_Get_memo_item(int H, int X_Row)
        {
            TextBox M = (TextBox)AL4Form.All_descriptors[H];
            if (X_Row >= 0 && X_Row < M.Lines.Length)
                return M.Lines[X_Row];
            return "";
        }

        /*
        // Set memo line by index
        //-----------------------
        
        FUN Set_memo_item(
        	INT M|emo_control, INT Row|_index, STR V|alue_set), NATIVE :
            "    AL4Form.Do_Set_memo_item((int)X_M, (int)X_Row, X_V);" .
        */
        public static void Do_Set_memo_item(int H, int X_Row, string X_V)
        {
            TextBox M = (TextBox)AL4Form.All_descriptors[H];

            int start = M.SelectionStart;
            int length = M.SelectionLength;

            if (X_Row == M.Lines.Length)
            {
                if (M.Lines.Length > 0)
                    M.Text += Environment.NewLine + X_V;
                else M.Text += X_V;
            }
            else if (X_Row >= 0 && X_Row < M.Lines.Length)
            {
                int Beg = M.GetFirstCharIndexFromLine(X_Row);
                int End = M.GetFirstCharIndexFromLine(X_Row + 1);
                if (End < 0)
                    M.Text = M.Text.Substring(0, Beg) + X_V + Environment.NewLine;
                else
                    M.Text = M.Text.Substring(0, Beg) + X_V + Environment.NewLine +
                        M.Text.Substring(End);
            }
            try
            {
                M.SelectionStart = start;
                M.SelectionLength = length;
            }
            catch(Exception Ex) 
            {
            	if (Ex is AL4_Exception) throw; 
            }
        }

        /*
        // Get memo selection text
        //------------------------
        
        FUN Get_memo_selection(
        	INT M|emo_control) ==> STR, NATIVE :
            "    RESULT = AL4Form.Do_Get_memo_selection((int)X_M);" .
        */
        public static string Do_Get_memo_selection(int H)
        {
            TextBox M = (TextBox)AL4Form.All_descriptors[H];
            return M.SelectedText;
        }

        /*
        // Replace memo selection with another text
        //-----------------------------------------
        
        FUN Set_memo_selection(
        	INT M|emo_control, 
            STR Text|_replacing_selection), NATIVE :
            "    AL4Form.Do_Set_memo_selection((int)X_M, X_Text);" .
        */
        public static void Do_Set_memo_selection(int H, string X_Text)
        {
            TextBox M = (TextBox)AL4Form.All_descriptors[H];
            M.Text = M.Text.Substring(0, M.SelectionStart) + X_Text +
                M.Text.Substring(M.SelectionStart + M.SelectionLength);
        }

        /*
        // Return count lines in memo
        //---------------------------
        
        FUN Get_memo_count_lines(
        	INT M|emo_control) ==> INT, NATIVE :
            "    RESULT = AL4Form.Do_Get_memo_count_lines((int)X_M);" .
        */
        public static int Do_Get_memo_count_lines(int H)
        {
            TextBox M = (TextBox)AL4Form.All_descriptors[H];
            return M.Lines.Length;
        }

        /*
        // Return TRUE indicating that text limit is supported
        //---------------------------
        
        FUN Memo_supports_text_limit ==> BOOL :
			RESULT = TRUE .
        */
        
        /*
        // Set memo maximal length
        //---------------------------
        
        FUN Set_memo_max_len(
        	INT M|emo_control, INT V|alue_max_len), NATIVE : @
            "    AL4Form.Do_Set_memo_max_len((int)X_M, "
            "		X_V < int.MaxValue ? (int)X_V : 0x7FFFffff);" .
        */
        public static void Do_Set_memo_max_len(int H, int X_V)
        {
            TextBox M = (TextBox)AL4Form.All_descriptors[H];
            M.MaxLength = X_V;
        }
        
        /*
        // Get memo range selection
        //---------------------------
        
        FUNCTION Get_memo_range_sel(
        	INT M|emo_control) ==> {Control}.{from_to}
        	:
			RESULT = {from_to}(From = get_memo_sel(M, TRUE))
			RESULT.To = RESULT.From + get_memo_sel(M, FALSE)
			.
        FUN get_memo_sel(
        	INT H|andle_memo,
        	BOOL Start|_otherwise_Length) ==> INT, NATIVE : @
            "TextBox M = (TextBox)AL4Form.All_descriptors[(int)X_H];"
            "if (X_Start) RESULT = M.SelectionStart;"
            "else RESULT = M.SelectionLength;"
            .
            
        // Set memo range selection
        //---------------------------
        
        FUNCTION Set_memo_range_sel(
        	INT M|emo_control, {from_to} R|ange_selection)
        	:
			do_Set_memo_range_sel(M, R.Line_from, R.Line_to, R.From, R.To)
			.
        FUN do_Set_memo_range_sel(INT M|emo_control,
        INT Line_fr|om_or_0, INT Line_to|_or_0,
        INT Fr|om_character, INT To|_character), NATIVE : @
        "TextBox M = (TextBox)AL4Form.All_descriptors[(int)X_M];"
        "M.SelectionStart = AL4Form.char_index_from_pos("
        "			M, (int)X_Line_fr, (int)X_Fr);"
        "int len = AL4Form.char_index_from_pos(M, (int)X_Line_to, (int)X_To)"
        "	- M.SelectionStart;"
        "if (len < 0) len = 0;"
        "M.SelectionLength = len;"     
        .
        
        */
		public static int char_index_from_pos(TextBox M, int Line, int Pos)
		{
			if (M.Lines.Length > Line)
			{
				if (Line > 0 && Pos > M.Lines[Line].Length)
					Pos = M.Lines[Line].Length;
				return(M.GetFirstCharIndexFromLine(Line)+Pos);
			}
			else if (M.Lines.Length == Line)
			{
				if (Line == 0) return 0;
				return(M.GetFirstCharIndexFromLine(Line-1) + 
					M.Lines[Line-1].Length);
			}
			return M.Text.Length;
		}
		
		/*
		
		FUNCTION Get_memo_entire_text_shown(
		{Control} M|emo_control) ==> BOOL, NATIVE:
			INT handle|_of_memo = M.Handle
			NATIVE@
		"TextBox M = (TextBox)AL4Form.All_descriptors[(int)X_handle];"
		"if (M.Lines.Count()==0 "
		"	|| M.Lines.Count()==1 && M.Lines[0].Trim().Length == 0)"
		"	return true;"     
		"int LL1C = M.GetFirstCharIndexFromLine(M.Lines.Count()-1);"
		"int LLLC = LL1C + M.Lines[M.Lines.Count()-1].Length-1;"     
		"System.Drawing.Point e = M.GetPositionFromCharIndex(LLLC);" 
		"RESULT = e.X <= M.Width && e.Y + M.PreferredHeight <= M.Height;"
		.

		*/
        //--------------------------------------------- L I S T B O X
        
        /*
        // Create listbox control, return descriptor.
        //-------------------------------------------
        
        FUN Create_listbox(
        	{Control} L|istbox_control,
            BOOL Multi|select) ==> INT
            :
            RESULT = do_create_listbox(L.Form_.Handle, L, Multi) .

        FUN do_create_listbox(
        	INT F|orm_handle, {Control} L|istbox_create, 
            BOOL Multi|select) ==> INT, NATIVE :
			CASE F == 0 ? ==> ;
			NATIVE @
            "     RESULT = AL4Form.Do_Create_listbox((int)X_F, X_L, X_Multi);" .
        */
        public static int Do_Create_listbox(int H, Ref_obj X_L,
            Boolean X_Multiselect)
        {
            AL4Column P = Get_parent_for_new_control(H);
            ListBox L = new ListBox();
            int Result = AL4Form.AllocDescriptor(L);
            L.Tag = X_L;
            //L.Parent = P;
            P.Controls.Add(L);
            P.Child_controls.Add(L);
            Adjust_control_font(L);
            L.SelectionMode = X_Multiselect ? SelectionMode.MultiExtended
                                            : SelectionMode.One;
            Adjust_control_location(P);
            Set_control_events(P, L);
            AL4Form F = Parent_form(P);
            L.SelectedIndexChanged += new System.EventHandler(
                F.Control_SelectedIndexChanged);
            return Result;            
        }

        /*
        
        FUNCTION Listbox_clear(
        	INT H|andle_listbox), NATIVE :
			CASE H == 0 ? ==> ;
			NATIVE @
        @   "   ListBox L = (ListBox)AL4Form.All_descriptors[(int)X_H];"
            "   L.Items.Clear();" .
        
        
        // Return listbox item string by its index
        //----------------------------------------------------------------------
        
        FUN Get_listbox_item(
        	INT L|istbox_control, INT Index|_item) ==> STR, NATIVE :
			CASE L == 0 ? ==> ;
			NATIVE @
           @"    ListBox L = (ListBox)AL4Form.All_descriptors[(int)X_L];"
            "    if (X_Index < 0 || X_Index >= L.Items.Count) return "#QU#QU";"
            "    String Result = L.Items[(int)X_Index].ToString();"
            "    RESULT = Result;" .


        // Set listbox item string by its index
        //----------------------------------------------------------------------
        
        FUN Set_listbox_item(
        	INT L|istbox_control, INT Index|_item, STR Value|_set), NATIVE :
			CASE L == 0 ? ==> ;
			NATIVE @
           @"    ListBox L = (ListBox)AL4Form.All_descriptors[(int)X_L];"
            "    if (X_Index < 0 || X_Index >= L.Items.Count) return;"
            "    L.Items[(int)X_Index] = X_Value;" .


        // Get listbox items count
        //----------------------------------------------------------------------
        
        FUN Get_listbox_count|_items(
        	INT L|istbox_control) ==> INT, NATIVE :
			CASE L == 0 ? ==> ;
			NATIVE @
           @"    ListBox L = (ListBox)AL4Form.All_descriptors[(int)X_L];"
            "    RESULT = L.Items.Count;" .
            
        // Add listbox item string 
        //----------------------------------------------------------------------
        
        FUN Listbox_add_item(
        	INT L|istbox_control, STR Value|_set) ==> INT, NATIVE :
			CASE L == 0 ? ==> ;
			NATIVE @
           @"    ListBox L = (ListBox)AL4Form.All_descriptors[(int)X_L];"
            "    L.Items.Add(X_Value);"
            "    RESULT = L.Items.Count-1;".


        // Insert item into listbox at given position 
        //----------------------------------------------------------------------
        
        FUN Listbox_insert_item(
        	INT L|istbox_control, INT Index|_before, STR Value|_set) ==> INT,
        	NATIVE :
			CASE L == 0 ? ==> ;
			NATIVE @
           @"    ListBox L = (ListBox)AL4Form.All_descriptors[(int)X_L];"
            "    if (X_Index < 0 || X_Index > L.Items.Count) return -1;"
            "    L.Items.Insert((int)X_Index, X_Value);"
            "    RESULT = X_Index;" .


        // Delete item in listbox by index 
        //----------------------------------------------------------------------
        
        FUN Listbox_delete_item(
        	INT L|istbox_control, INT Index|_delete), NATIVE :
			CASE L == 0 ? ==> ;
			NATIVE @
           @"    ListBox L = (ListBox)AL4Form.All_descriptors[(int)X_L];"
            "    if (X_Index < 0 || X_Index >= L.Items.Count) return;"
            "    L.Items.RemoveAt((int)X_Index);" .


        // Select/deselect item in listbox by index 
        //----------------------------------------------------------------------
        
        FUN Listbox_select_item(
        	{Listbox} L|istbox_control, INT Index|_of_item,
            BOOL Select|_or_deselect), NATIVE :
			INT h|andle_listbox = L.Handle
			CASE h == 0 ? ==> ;
			NATIVE @
           @"    ListBox L = (ListBox)AL4Form.All_descriptors[(int)X_h];"
            "    if (X_Index < 0 || X_Index >= L.Items.Count) return;"
            "    if (X_Select && L.SelectionMode == SelectionMode.One)"
            "    {"
            "        L.SelectedIndex = (int)X_Index;"
            "        return;"
            "    }"
            "    if (X_Select)"
            "        L.SelectedIndices.Add((int)X_Index);"
            "    else L.SelectedIndices.Remove((int)X_Index);" .


        // Select all items in listbox
        //----------------------------------------------------------------------
        
        FUN Listbox_select_all(
        	{Listbox} L|istbox_control), NATIVE :
			INT h|andle_listbox = L.Handle
			CASE h == 0 ? ==> ;
			NATIVE @
           @"    ListBox L = (ListBox)AL4Form.All_descriptors[(int)X_h];"
            "    if (L.SelectionMode == SelectionMode.One) return;"
            "    for (int i = 0; i < L.Items.Count; i++)"
            "        L.SetSelected(i, true);" .


        // Deselect all items in listbox
        //----------------------------------------------------------------------
        
        FUN Listbox_select_none(
        	{Listbox} L|istbox_control), NATIVE :
			INT h|andle_listbox = L.Handle
			CASE h == 0 ? ==> ;
			NATIVE @
           @"    ListBox L = (ListBox)AL4Form.All_descriptors[(int)X_h];"
            "    L.ClearSelected();" .


        // Get count of selected items in listbox
        //----------------------------------------------------------------------
        
        FUN Listbox_get_sel_count(
        	{Listbox} L|istbox_control) ==> INT, NATIVE:
			INT h|andle_listbox = L.Handle
			CASE h == 0 ? ==> ;
			NATIVE @
           @"    ListBox L = (ListBox)AL4Form.All_descriptors[(int)X_h];"
            "    RESULT = L.SelectedItems.Count;" .


        // Delete all selected items in listbox
        //----------------------------------------------------------------------
        
        FUN Listbox_delete_selected(
        	{Listbox} L|istbox_control), NATIVE :
			INT h|andle_listbox = L.Handle
			CASE h == 0 ? ==> ;
			NATIVE @
           @"    ListBox L = (ListBox)AL4Form.All_descriptors[(int)X_h];"
            "    for (int i = L.Items.Count-1; i >= 0; i--)"
            "         if (L.GetSelected(i))"
            "             L.Items.RemoveAt(i);" .


        // Get next selected item in listbox
        //----------------------------------------------------------------------
        
        FUN Listbox_get_next_sel(
        {Listbox} L|istbox_control, INT From|_index) ==> INT, NATIVE :
			INT h|andle_listbox = L.Handle
			CASE h == 0 ? ==> ;
			NATIVE @
           @"    ListBox L = (ListBox)AL4Form.All_descriptors[(int)X_h];"
            "    if (L.SelectedItems.Count == 0) return -1;"
            "    if (X_From < 0)"
            "       if (L.SelectionMode == SelectionMode.One)"
            "           return L.SelectedIndex;"
            "    if (X_From < -1) X_From = -1;"
            "    for (int i = (int)X_From+1; i < L.Items.Count; i++)"
            "       if (i > X_From && L.GetSelected(i)) return i;"
            "    RESULT = -1;" .
            
        */
        

        //--------------------------------------------- C O M B O B O X

        /*
        // Create combobox control, return descriptor
        //-------------------------------------------
        
        FUN Create_combo(
        	{Control} C|ombo_control) ==> INT
        	:
            RESULT = do_create_combo(C.Form_.Handle, C) .

        FUN do_create_combo(INT F|orm_handle,
            {Control} C|ombo_create) ==> INT, NATIVE :
            "     RESULT = AL4Form.Do_Create_combo((int)X_F, X_C);" .
        */
        public static int Do_Create_combo(int H, Ref_obj X_C)
        {
            AL4Column P = Get_parent_for_new_control(H);
            ComboBox C = new ComboBox();
            C.DropDownStyle = ComboBoxStyle.DropDownList;
            int Result = AL4Form.AllocDescriptor(C);
            C.Tag = X_C;
            P.Controls.Add(C);
            P.Child_controls.Add(C);
            Adjust_control_font(C);
            Adjust_control_location(P);
            Set_control_events(P, C);
            AL4Form F = Parent_form(P);
            C.TextChanged += new EventHandler(F.Control_changed);
            C.SelectedIndexChanged += new System.EventHandler(
                F.Control_SelectedIndexChanged);
            return Result;
        }

        /*
        // Fill combo items list with strings (separated by #CR or #NL)
        //-------------------------------------------------------------
        
        FUN Set_combo_items(
        	INT C|ombo_control,
            STR V|alue_items), NATIVE :
            "    AL4Form.Do_Set_combo_items((int)X_C, X_V);" .
        */
        public static void Do_Set_combo_items(int H, string X_V)
        {
            ComboBox C = (ComboBox)AL4Form.All_descriptors[H];
            C.BeginUpdate();
            try
            {
                C.Items.Clear();
                if (X_V.Length > 0) {
	                string[] items = X_V.Split(new char[] { (Char)13 });
	                for (int i = 0; i < items.Length; i++)
	                {
	                    if (items[i] != "" && items[i][0] == (Char)10)
	                        items[i] = items[i].Substring(1);
	                    C.Items.Add(items[i]);
	                }
                }
            }
            finally
            {
                C.EndUpdate();
            }
        }

        /*
        // Get count items in combobox
        //---------------------------
        
        FUN Get_combo_count_items(
        	INT C|ombo_control) ==> INT, NATIVE :
        	CASE C == 0 ? ==> ;
        	NATIVE @     
            "    RESULT = AL4Form.Do_Get_combo_count_items((int)X_C);" .
        */
        public static int Do_Get_combo_count_items(int H)
        {
            ComboBox C = (ComboBox)AL4Form.All_descriptors[H];
            return C.Items.Count;
        }

        /*
        // Get combobox item by index
        //---------------------------
        
        FUN Combo_get_item(
        	INT C|ombo_control, INT Row|_combo) ==> STR, NATIVE :
            "    RESULT = AL4Form.Do_Get_combo_item((int)X_C, (int)X_Row);" .
        */
        public static string Do_Get_combo_item(int H, int Row) {
            ComboBox C = (ComboBox)AL4Form.All_descriptors[H];
            return C.Items[Row].ToString();
        }

        /*
        // Set combobox item by index
        //---------------------------
        
        FUN Combo_set_item(
        	INT C|ombo_control, INT Row|_combo, STR V|alue_set), NATIVE :
            "    AL4Form.Do_Set_combo_item((int)X_C, (int)X_Row, X_V);" .
        */
        public static void Do_Set_combo_item(int H, int Row, string V)	{
            ComboBox C = (ComboBox)AL4Form.All_descriptors[H];
            C.Items[Row] = V;
        }

        /*
        // Search cobobox item by string pattern
        //--------------------------------------
        
        FUN Find_combo_item(
        	INT C|ombo_control, STR F|inding_str) ==> INT, NATIVE :
            "    RESULT = AL4Form.Do_Find_combo_item((int)X_C, X_F);" .
        */
        public static int Do_Find_combo_item(int H, string X_F)
        {
            ComboBox C = (ComboBox)AL4Form.All_descriptors[H];
            return C.Items.IndexOf(X_F);
        }

        /*
        // Add an item into the end of combobox
        //-------------------------------------
        
        FUN Add_combo_item(
        	INT C|ombo_control, STR A|dding_str) ==> INT, NATIVE :
            "    RESULT = AL4Form.Do_Add_combo_item((int)X_C, X_A);" .
        */
        public static int Do_Add_combo_item(int H, string X_A)
        {
            ComboBox C = (ComboBox)AL4Form.All_descriptors[H];
            return C.Items.Add(X_A);
        }

        /*
        // Insert an item into combobox at a position
        //-------------------------------------
        
        FUN Insert_combo_item(
        	INT C|ombo_control,
            INT I|ndex_where_insert, STR A|dding_str), NATIVE :
            "    AL4Form.Do_Insert_combo_item((int)X_C, (int)X_I, X_A);" .
        */
        public static void Do_Insert_combo_item(int H, int X_I, string X_A)
        {
            ComboBox C = (ComboBox)AL4Form.All_descriptors[H];
            C.Items.Insert(X_I, X_A);
        }

        /*
        // Get current index selected in combobox (-1 if nothing is selected)
        //-------------------------------------------------------------------
        
        FUN Get_combo_current_index(
        	INT C|ombo_control) ==> INT, NATIVE :
        	CASE C == 0 ? ==> ; 
        	NATIVE @
            "    RESULT = AL4Form.Do_Get_combo_current_index((int)X_C);" .
        */
        public static int Do_Get_combo_current_index(int H)
        {
            ComboBox C = (ComboBox)AL4Form.All_descriptors[H];
            return C.SelectedIndex;
        }

        /*
        // Set new current index (-1 is allowed to unselect all)
        //------------------------------------------------------
        
        FUN Set_combo_current_index(
        	INT C|ombo_control, INT Index|_set), NATIVE :
            "    AL4Form.Do_Set_combo_current_index((int)X_C, (int)X_Index);" .
        */
        public static void Do_Set_combo_current_index(int H, int X_Index)
        {
            ComboBox C = (ComboBox)AL4Form.All_descriptors[H];
            if (X_Index >= -1 && X_Index < C.Items.Count)
            {
                C.SelectedIndex = X_Index;
                AL4Form F = Parent_form(C);
                F.Control_SelectedIndexChanged(C, null);
            }
        }

        /*
        // Get combo selection text
        //------------------------------
        
        FUN Get_combo_selection(
        	INT C|ombo_control) ==> STR, NATIVE :
            "    RESULT = AL4Form.Do_Get_combo_selection((int)X_C);" .
        */
        public static string Do_Get_combo_selection(int H)
        {
            ComboBox C = (ComboBox)AL4Form.All_descriptors[H];
            return C.SelectedText;
        }

        /*
        // Replace combo selection with another text
        //-----------------------------------------
        
        FUN Set_combo_selection(
        	INT C|ombo_control, STR Text|_new_selection), NATIVE :
            "    AL4Form.Do_Set_combo_selection((int)X_C, X_Text);" .
        */
        public static void Do_Set_combo_selection(int H, string X_Text)
        {
            ComboBox C = (ComboBox)AL4Form.All_descriptors[H];
            C.SelectedText = X_Text;
        }

        /*
        // Set combo maximal length (of Edit sub-control part)
        //------------------------
        
        FUN Set_combo_max_len(
        	INT C|ombo_control, INT V|alue_max_len), NATIVE :
            "    AL4Form.Do_Set_combo_max_len((int)X_C, (int)X_V);" .
        */
        public static void Do_Set_combo_max_len(int H, int X_V)
        {
            ComboBox C = (ComboBox)AL4Form.All_descriptors[H];
            if  (X_V < 0) X_V = 0;
            C.MaxLength = X_V;
        }


        //------------------------------------------------------ D A T E  P I C K E R

        /*
        // Create date picker control, return descriptor
        //----------------------------------------------
        
        FUN Create_date_picker(
        	{Control} D|atepicker_control) ==> INT
        	:
            RESULT = do_create_datepicker(D.Form_.Handle, D) .

        FUN do_create_datepicker(INT F|orm_handle,
            {Control} D|atepicker_create) ==> INT, NATIVE :
            "     RESULT = AL4Form.Do_Create_datepicker((int)X_F, X_D);" .
        */
        public static int Do_Create_datepicker(int H, Ref_obj X_D)
        {
            AL4Column P = Get_parent_for_new_control(H);
            DateTimePicker D = new DateTimePicker();
            D.Width = 120;
            int Result = AL4Form.AllocDescriptor(D);
            D.Tag = X_D;
            //D.Parent = P;
            P.Controls.Add(D);
            P.Child_controls.Add(D);
            Adjust_control_font(D);
            D.Value = DateTime.Now.Date;
            //--------------------------------- 'setup date picker pos & events'
            Adjust_control_location(P);
            Set_control_events(P, D);
            AL4Form F = Parent_form(P);
            D.ValueChanged +=new EventHandler(F.Control_changed);
            return Result;
        }

        /*
        // Get date picker date
        //---------------------
        
        FUNCTION Get_date_picker_date(
        	INT D|atepicker_control) ==> {Date_time}.{date_time}
        	:= Date_time(DT = get_date_picker_date(D)) .
        FUN get_date_picker_date(INT D|atepicker_control) ==> REAL, NATIVE : @
           "DateTimePicker D = (DateTimePicker)AL4Form.All_descriptors["
           "			(int)X_D];"
           "RESULT = D.Value.Date.ToOADate() * 24.0 * 3600000;"
           .
           
        // Set date picker date
        //---------------------
        
        FUNCTION Set_date_picker_date(
        	INT D|atepicker_control, 
            {date_time} Value|_date)
            :
			do_set_date_picker_date(D, Value.DT)
			.
        FUN do_set_date_picker_date(
        INT D|atepicker_control, REAL Date|_to_set), NATIVE : @
            "DateTimePicker D = (DateTimePicker)AL4Form.All_descriptors["
        	"	(int)X_D];"
            "D.Value = DateTime.FromOADate(X_Date / 24.0 / 3600000);"
            .
            
        // Get date picker text
        //---------------------
        
        FUN Get_date_picker_text(
        	INT D|atepicker_control) ==> STR, NATIVE :
            "    RESULT = AL4Form.Do_Get_datepicker_text((int)X_D);" .
        */
        public static string Do_Get_datepicker_text(int H)
        {
            DateTimePicker D = (DateTimePicker)AL4Form.All_descriptors[H];
            return D.Text;
        }

        /*
        // Get date picker Ok
        //---------------------
        
        FUN Get_date_picker_OK(
        	INT D|atepicker_control_dummy) ==> BOOL
        	:
            RESULT = TRUE .
        */
        //-------------------------------------------- P R O G R E S S   B A R

        /*
        // Create progres bar control, return descriptor
        //----------------------------------------------
        
        FUN Create_progress_bar(
        	{Control} P|rogress_control) ==> INT
        	:
            RESULT = do_create_progress(P.Form_.Handle, P) .

        FUN do_create_progress(INT F|orm_handle,
            {Control} P|rogress_bar_create) ==> INT, NATIVE :
            "     RESULT = AL4Form.Do_Create_progress_bar((int)X_F, X_P);" .
        */
        public static int Do_Create_progress_bar(int H, Ref_obj X_P)
        {
            AL4Column P = Get_parent_for_new_control(H);
            ProgressBar PB = new ProgressBar();
            int Result = AL4Form.AllocDescriptor(PB);
            PB.Tag = X_P;
            //PB.Parent = P;
            P.Controls.Add(PB);
            P.Child_controls.Add(PB);
            Adjust_control_font(PB);
            Adjust_control_location(P);
            Set_control_events(P, PB);
            return Result;
        }

        /*
        // Get progress bar value
        //-----------------------
        FUN Get_progress_bar_value(INT P|rogress_control) ==> INT,
            NATIVE :
            "    RESULT = AL4Form.Do_Get_progress_bar_progress((int)X_P);" .
        */
        public static int Do_Get_progress_bar_progress(int H)
        {
            ProgressBar P = (ProgressBar)AL4Form.All_descriptors[H];
            return P.Value;
        }

        /*
        // Set progress bar value
        //-----------------------
        FUN Set_progress_bar_value(INT P|rogress_control, REAL V|alue_set),
            NATIVE :
            "   AL4Form.Do_Set_progress_bar_progress((int)X_P, (int)(X_V));" .
        */
        public static void Do_Set_progress_bar_progress(int H, int Value)
        {
            ProgressBar P = (ProgressBar)AL4Form.All_descriptors[H];
            if (Value < P.Minimum) Value = P.Minimum;
            else if (Value > P.Maximum) Value = P.Maximum;
            P.Value = Value;
        }

        /*
        // Get progress bar maximum
        //-----------------------
        FUN Get_progress_bar_maximum(INT P|rogress_control) ==> REAL,
            NATIVE :
            "    RESULT = AL4Form.Do_Get_progress_bar_maximum((int)X_P);" .
        */
        public static int Do_Get_progress_bar_maximum(int H)
        {
            ProgressBar P = (ProgressBar)AL4Form.All_descriptors[H];
            return P.Maximum;
        }

        /*
        // Set progress bar maximum
        //-------------------------
        FUN Set_progress_bar_maximum(INT P|rogress_control, REAL V|alue_set),
            NATIVE :
            "   AL4Form.Do_Set_progress_bar_maximum((int)X_P, (int)(X_V));" .
        */
        public static void Do_Set_progress_bar_maximum(int H, int Value)
        {
            ProgressBar P = (ProgressBar)AL4Form.All_descriptors[H];
            P.Maximum = Value;
        }

        /*
        // Get progress bar minimum
        //-----------------------
        FUN Get_progress_bar_minimum(INT P|rogress_control) ==> INT,
            NATIVE :
            "    RESULT = AL4Form.Do_Get_progress_bar_minimum((int)X_P);" .
        */
        public static int Do_Get_progress_bar_minimum(int H)
        {
            ProgressBar P = (ProgressBar)AL4Form.All_descriptors[H];
            return P.Minimum;
        }

        /*
        // Set progress bar minimum
        //-------------------------
        FUN Set_progress_bar_minimum(INT P|rogress_control, INT V|alue_set),
            NATIVE :
            "   AL4Form.Do_Set_progress_bar_minimum((int)X_P, (int)X_V);" .
        */
        public static void Do_Set_progress_bar_minimum(int H, int Value)
        {
            ProgressBar P = (ProgressBar)AL4Form.All_descriptors[H];
            P.Minimum = Value;
        }


        //------------------------------------------------------------ M E N U

        private static int Add_menu_items(
        	MenuPanel MP, ContextMenuStrip PM, ToolStripItem Parent_item,
            ref int idx, string[] L)
        {
            int i = idx - 1;
            int count_items = 0;
            ///////////////////////////////////
            //Console.WriteLine("Add_menu_items " + L.Length.ToString() +
            //"i=" + i.ToString() );
            try {
	            while (i < L.Length - 1)
	            {
                    i++;
                    if (L[i] == ")")
                    {
                        idx = i; return count_items;
                    }
                    string s = L[i];
                    string a = s;
                    int j = s.IndexOf(':');
                    if (j >= 0)
                    {
                        a = s.Substring(0, j).Trim();
                        s = s.Substring(j + 1).TrimStart();
                    }
                    if (a + s == "") continue;
                    
                    string[] aa = a.Split(',');
                    if (aa.Length > 1) a = aa[0].Trim();
                    
                    ToolStripItem Item = null;
                    if (s == "-") {
                	    Item = new ToolStripSeparator();
                    }
                    else {
                	    string tabbed = "";
                	    if (s.Contains('\t'))
                	    {                 
                		    int n = s.IndexOf('\t');
                		    tabbed = s.Substring(n+1);
                		    s = s.Substring(0, n);
                	    }
                	    Item = new ToolStripMenuItem(s);
                	    
                	    if (tabbed != "")
						    ((ToolStripMenuItem)Item).ShortcutKeyDisplayString 
						    = tabbed;
                    }
                    
                    for (int k = 1; k < aa.Length; k++)
                    {
                        //if (aa[k].Trim().ToLower() == "disabled")
                        if (aa[k].Trim().ToLower()[0] == 'd')
                            Item.Enabled = false;
                        //else if (aa[k].Trim().ToLower() == "checked")
                        else if (aa[k].Trim().ToLower()[0] == 'c')
                            ((ToolStripMenuItem)Item).Checked = true;
                    }
    
                    if (a != "" && MP.track_submenu)
                    {
                	    Item.MouseEnter += new EventHandler(MP.Item_selected);
                    }
    
                    if (i < L.Length - 1 && L[i + 1] == "(") { }
                    else if (s == "-") { }
                    else
                    {
                        Item.Click += new EventHandler(MP.Item_clicked);
                    }
                    Item.Tag = (Object)a;
                    MP.AliasesList.Add(a);
                    MP.AllItemsList.Add(Item);
                    if (Parent_item != null)
                        ((ToolStripMenuItem)Parent_item).DropDownItems.Add(Item)
                        ;
                    else
                        PM.Items.Add(Item);
                    count_items += 1;
                    if (i < L.Length - 1 && L[i + 1] == "(")
                    {
                        i += 2;
                        if (MP.track_submenu)
                        {
	                        var dropDown = new ToolStripDropDown();
	                        dropDown.Tag = Item;
	                        ((ToolStripMenuItem)Item).DropDown = dropDown;
	                        dropDown.KeyUp+=new KeyEventHandler(MP.Item_key_up);
	                        dropDown.LayoutStyle
	                           = ToolStripLayoutStyle.VerticalStackWithOverflow;
                        }
                        if (Add_menu_items(MP, PM, Item, ref i, L) == 0)
                    	    Item.Enabled = false;
                    }
            	}
            }
            catch { }
            return count_items;
        }
        
        public MenuPanel MenuPanel_to_remove;

        public static MenuPanel Do_Create_menu(int H, string X_V)
        {
            AL4Column P = Get_parent_for_new_control(H);
            AL4Form F = Parent_form(P);
            if (F.MenuPanel_to_remove != null) {
                F.MenuPanel_to_remove = null;
            }
            MenuPanel M = new MenuPanel();
            F.MenuPanel_to_remove = M;
            M.track_submenu = ((C_Form)F.AL4Object.Obj).F_tracking_menu_sel;
            P.Controls.Add(M);
            P.Child_controls.Add(M);
            M.Visible = false;
            M.Enabled = false;
            M.Size = new Size(0, 0);
            M.MenuObject = new ContextMenuStrip();
            M.MenuObject.Closed += 
            	new ToolStripDropDownClosedEventHandler(M.MenuObject_Closed);
            //------------------------------------- fill menu items tree 
            string[] L = X_V.Split((Char)13);
            for (int i=0; i < L.Length; i++)
                if (L[i] != "" && L[i][0] == (Char)10)
                    L[i] = L[i].Substring(1);
            int j = 0;
            ///////////////////////////////////////////
            //Console.WriteLine("Calling Add_menu_items from Do_Create_menu"+
            //", L[]:" + L.Length.ToString());
            Add_menu_items(M, M.MenuObject, null, ref j, L);
            return M;
        }

        public static void Do_Destroy_menu(MenuPanel M)
        {
            //MenuPanel M = (MenuPanel)AL4Form.All_descriptors[H];
            M.Dispose();
        }

        /*
        // Show menu, return selected item's alias
        //----------------------------------------------------------------------
        
        FUN Popup_menu(
        {Form} F|orm_showing_menu, STR M|enu_definition)
        	:
            {point} pt|_to_popup = F.Get_popup_point
            do_popup_menu(F.Handle, M, pt.X, pt.Y)
            .
        FUN do_popup_menu(INT F|orm_handle, STR M|enu_definition,
            REAL X|_coordinate, REAL Y|_coordinate), NATIVE :
            "    AL4Form.Do_Popup_menu((int)X_F, X_M, X_X, X_Y);" .
        */
        public static void Do_Popup_menu(int H, string X_M, 
            double X, double Y)
        {
            MenuPanel MP = Do_Create_menu(H, X_M);
            AL4Form form = Parent_form(MP);
            Point P = new Point(Points(X), Points(Y));
            MP.Ready = false;
            MP.Alias = "";
            MP.Enabled = true;
            if (form.Visible)
                MP.MenuObject.Show(form, P);
            else
            {
                int maxy = 2000;
                foreach (Screen s in Screen.AllScreens)
                    if (s.Bounds.Bottom > maxy)
                        maxy = s.Bounds.Bottom;

                bool h = form.Hidden;
                int y = form.Top;
                form.Hidden = false;
                form.Top = maxy + 1;
                form.Visible = true;
                try
                {
                    MP.MenuObject.Show(form, P);
                }
                finally
                {
                    form.Hidden = h;
                    form.Visible = false;
                    form.Top = y;
                }
            }
        }

        //--------------------------------------------------------------- T I M E R

        /*
        // Create timer, return descriptor.
        //----------------------------------------------------------------------------
        FUN Create_timer({Control} T|imer_object,
            INT Interval, BOOL Active|_state) ==> INT
            :
            RESULT = do_create_timer(T.Form_.Handle, T)
            Set_timer_interval(RESULT, Interval)
            Set_timer_active(RESULT, Active) .

        FUN do_create_timer(INT F|orm_handle,
            {Control} T|imer_create) ==> INT, NATIVE :
            "     RESULT = AL4Form.Do_Create_timer((int)X_F, X_T);" .
        */
        public static int Do_Create_timer(int H, Ref_obj X_T)
        {
            AL4Column P = Get_parent_for_new_control(H);
            AL4Form F = Parent_form(P);
            TimerPanel TP = new TimerPanel();
            int Result = AL4Form.AllocDescriptor(TP);
            TP.Tag = X_T;
            //TP.Parent = P;
            P.Controls.Add(TP);
            P.Child_controls.Add(TP);
            TP.Visible = false;
            TP.Enabled = false;
            TP.Size = new Size(0, 0);
            TP.TimerObject = new System.Windows.Forms. Timer();
            TP.TimerObject.Enabled = false;
            TP.TimerObject.Tag = TP;
            TP.TimerObject.Tick += new EventHandler(F.Form_timer);
            return Result;
        }

        /*
        // Set timer Interval
        //-------------------
        FUN Set_timer_interval(INT T|imer_control, INT V|alue_interval),
            NATIVE :
            "    AL4Form.Do_Set_timer_interval((int)X_T, (int)X_V);" .
        */
        public static void Do_Set_timer_interval(int H, int X_V)
        {
            TimerPanel TP = (TimerPanel)AL4Form.All_descriptors[H];
            TP.TimerObject.Interval = X_V;
        }

        /*
        // Set timer Active state
        //-----------------------
        FUN Set_timer_active(INT T|imer_control, BOOL A|ctive_state),
            NATIVE :
            "    AL4Form.Do_Set_timer_active((int)X_T, X_A);" .
            
        */
        public static void Do_Set_timer_active(int H, bool X_A)
        {
            TimerPanel TP = (TimerPanel)AL4Form.All_descriptors[H];
            TP.TimerObject.Enabled = X_A;
        }
        
		/*
		
		FUN Time_BeginPrecision(INT Prec|ision_milliseconds),
			NATIVE :
			CASE Prec > 1000 ? ==> ;
			NATIVE @     
			"	AL4Form.Do_Time_BeginPrecision((int)X_Prec);" .
	
		FUN Time_EndPrecision(INT Prec|ision_milliseconds),
			NATIVE :
			CASE Prec > 1000 ? ==> ;
			NATIVE @     
			"	AL4Form.Do_Time_EndPrecision((int)X_Prec);" .
	
		*/
		
		[DllImport("winmm.dll", EntryPoint="timeBeginPeriod")]
		public static extern uint timeBeginPeriod(uint uMilliseconds);
		[DllImport("winmm.dll", EntryPoint="timeEndPeriod")]
		public static extern uint timeEndPeriod(uint uMilliseconds);
		
		public static void Do_Time_BeginPrecision(int P)
		{
			timeBeginPeriod((uint)P);
		}
        
		public static void Do_Time_EndPrecision(int P)
		{
			timeEndPeriod((uint)P);
		}
        
        //------------------------------------------------------------
        //public Ref_obj AL4Object;
        public bool Hidden;
        public List<AL4Column> Columns = new List<AL4Column>();

        // Form construction. By default, appearing position set to Default
        public AL4Form()
        {
            Handle_form = AL4Form.AllocDescriptor(this);
            InitializeComponent();
            StartPosition = FormStartPosition.WindowsDefaultLocation;
        }

        // Form destruction: releasing descriptor
        ~AL4Form()
        {
            AL4Form.ReleaseDescriptor(Handle_form);
        }

        // container for components
        private System.ComponentModel.IContainer components = null;

        // initialization of components container, Scale mode, default form caption (Form1)
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            //this.Text = "Form1";
        }

        // dispose (components dispose)
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }
        
        /*
        // Process all form messages
        //------------------------------------
        
        FUN Process_all_form_messages(
        	INT H|andle_form_dummy), NATIVE :
            "    Application.DoEvents();" .
        */

        //------------------------------- AL4Form events:

        // any control is clicked
        public bool click_disabled;
        public PointF Popup_point;
        public PointF Mouse_point;
        public int Mouse_button;
        public double Mouse_wheel_vertical;
        public double Mouse_wheel_horizontal;        
        
        /*
        // Get point on form used to pop up menu by default
        //-------------------------------------------------
        
        FUNCTION Get_form_popup_point(
        INT F|orm_handle) ==> {point}
        	:= Pt(F.get_form_popup_point(TRUE), F.get_form_popup_point(FALSE)) .
        FUN get_form_popup_point(
        INT F|orm_handle, BOOL X|_coordinate) ==> REAL, NATIVE :
			CASE F == 0 ? ==> ;
			NATIVE @
            "    AL4Form form = (AL4Form)AL4Form.All_descriptors[(int)X_F];"
            "	 if (form == null) return 0;"
            "	 if (X_X) RESULT = form.Popup_point.X;"
            "    else RESULT = form.Popup_point.Y;" .

        FUNCTION Set_form_popup_point(
        INT F|orm_handle, 
        REAL Px|_coordinate_points, REAL Py|_coordinate_points), 
        NATIVE : @
            "    AL4Form form = (AL4Form)AL4Form.All_descriptors[(int)X_F];"
            "	 if (form == null) return;"
            "	 form.Popup_point.X = (float)X_Px;"
            "    form.Popup_point.Y = (float)X_Py;" .

        // Get mouse point on form for current mouse event
        //-------------------------------------------------
        
        FUN Form_get_mouse_point(INT F|orm_handle) ==> {point}
        	:= Pt(F.get_mouse_point(TRUE), F.get_mouse_point(FALSE)) .
        FUN get_mouse_point(
        INT F|orm_handle, BOOL X|_coordinate) ==> REAL, NATIVE :
			CASE F == 0 ? ==> ;
			NATIVE @
            "    AL4Form form = (AL4Form)AL4Form.All_descriptors[(int)X_F];"
            "	 if (form == null) return 0;"
            "    if (X_X) RESULT = form.Mouse_point.X;" 
            "    else RESULT = form.Mouse_point.Y;"
            .
            
        // Get mouse button clicked
        //-------------------------------------------------
        FUN Form_mouse_button(INT F|orm_handle) ==> {Form}.{button}, NATIVE :
			CASE F == 0 ? ==> ;
			NATIVE @
        @	"    AL4Form form = (AL4Form)AL4Form.All_descriptors[(int)X_F];"
            "	 if (form == null) return 0;"
            "    RESULT = (byte)form.Mouse_button;" .
            
        // Get mouse wheel distance
        //-------------------------------------------------
        FUN Form_vertical_wheel(INT F|orm_handle) ==> REAL, NATIVE :
			CASE F == 0 ? ==> ;
			NATIVE @
           @"    AL4Form form = (AL4Form)AL4Form.All_descriptors[(int)X_F];"
            "	 if (form == null) return 0;"
            "    RESULT = form.Mouse_wheel_vertical;" .
            
        // Get mouse wheel horizontal distance
        //-------------------------------------------------
        FUN Form_horizontal_wheel(INT F|orm_handle) ==> REAL, NATIVE :
			CASE F == 0 ? ==> ;
			NATIVE @
           @"    AL4Form form = (AL4Form)AL4Form.All_descriptors[(int)X_F];"
            "	 if (form == null) return 0;"
            "    RESULT = form.Mouse_wheel_horizontal;" .
            
		// Get mouse point on screen
		//-------------------------------------------------
		
		FUN Get_mouse_cursor_position ==> {Geometry}.{point}
			:
			REAL mp|oint_xy[] << 0 << 0
			get_mouse_cursor(mp[])
			RESULT = Pt(mp[0], mp[1])
			.
		FUN get_mouse_cursor(REAL MP|osition[]), NATIVE : @
			"	 Point p = System.Windows.Forms.Cursor.Position;"
		    "    X_MP.set_real(0, AL4Form.Pixels(p.X));" 
		    "    X_MP.set_real(1, AL4Form.Pixels(p.Y));"
		    .
		    
		FUN Set_new_mouse_cursor_position(
		REAL X|_coordinate_points, REAL Y|_coordinate_points), NATIVE : @
			"System.Windows.Forms.Cursor.Position = new Point("
			"	AL4Form.Points(X_X), AL4Form.Points(X_Y));" .

		FUN Is_mouse_button_pressed(
		{button} Button|_checked) ==> BOOL, NATIVE :
		@	"	 RESULT = AL4Form.Is_mouse_button_pressed((int)X_Button);" .	
		
	   	FUN Is_keyboard_key_pressed(
	   	INT Key|_interesting) ==> BOOL, NATIVE : @
		"RESULT = AL4Form.Is_keyboard_key_pressed((int)X_Key);" .
	
        //FUN Is_key_pressed(
        //INT Key|_interesting) ==> BOOL, NATIVE : @
        //"RESULT = AL4Form.Is_key_pressed((int)X_Key);" .
	
        */
        
        [DllImport("user32.dll")]
        static extern short GetAsyncKeyState(int key);
        
        public static bool Is_mouse_button_pressed(int b)
        {
        	int code = 0;
            switch (b)
            {
            case 1: code = 1; break; // VK_LBUTTON
            case 2: code = 2; break; // VK_RBUTTON
            case 3: code = 4; break; // VK_MBUTTOM
            case 4: code = 5; break; // VK_XBUTTON1 
            case 5: code = 6; break; // VK_XBUTTON1 
            }
            if (code == 0) return false;
            return GetAsyncKeyState(code) < 0;
        }
        
        public static bool Is_keyboard_key_pressed(int key)
        {
        	return GetAsyncKeyState(key) < 0;
        }
        
        [DllImport("USER32.dll")]
        static extern short GetKeyState(short nVirtKey);

        //public static bool Is_key_pressed(int key)
        //{
        //    return GetKeyState((short)key) < 0;
        //}
        
        
        public static AL4Form Parent_form(Control C)
        {
            while (C != null)
            {
                if (C is AL4Form) return (AL4Form)C;
                C = C.Parent;
            }
            return null;
        }
        
        public void Control_clicked(Object Sender, EventArgs E)
        {
//?{Form}.click
            if  (click_disabled) return;
            click_disabled = true;
            try {
                Control C = (Control)Sender;
                AL4Form form = Parent_form(C);
                if (form == null) return;
C_Form F = (C_Form)form.AL4Object.Obj;
//if (form.CancelButton == C && GetAsyncKeyState(0x20) < 0) return;
                
                Point P = Control.MousePosition;
                P = form.PointToClient(P);

                try
                {
                    form.Mouse_point = new PointF(
                    	(float)Pixels(P.X),
                    	(float)Pixels(P.Y));
                    
                    P = C.PointToScreen(new Point(0, C.Height));
                    P = form.PointToClient(P);

                    form.Popup_point = new PointF(
                    	(float)Pixels(P.X),
                    	(float)Pixels(P.Y));
                }
                catch (Exception Ex)
                {
                	if (Ex is AL4_Exception) throw; 
                }
//C_Form F = (C_Form)form.AL4Object.Obj;
                //******************************
                //if (F.F_level_event > 1)
                //{
                //    return;
                //}
                //******************************
                F.Do.M_operation_started(0, (Ref_obj)C.Tag);
                try {
	                try {
	                F.Do.M_click();
	                } catch(Stop) {}
                }
                finally {
                F.Do.M_operation_ended(0);
                }
            }
            finally {
                    click_disabled = false;
            }
//.
        }
        
        /*
        
        FUN Control_click(
        {Control} C|ontrol_which_click_should_be_handled), NATIVE:
            INT h|andle_form = C.Form_.Handle
            NATIVE @
        "Control c = "
        "	(Control)AL4Form.All_descriptors["
        "		(int)((C_Control)X_C.Obj).F_Handle];"
        "AL4Form f = (AL4Form)AL4Form.All_descriptors[(int)X_h];"     
        "f.Control_clicked(c, null);" .
        	//: C.Form_.click .
	
        
        */
        
        public void Form_clicked(Object Sender, EventArgs E)
        {
//?{Form}.click
            if  (click_disabled) return;
            click_disabled = true;
            try {
                Point P = Control.MousePosition;
                P = this.PointToClient(P);
                
                this.Popup_point.X = (float)Pixels(P.X);
                this.Popup_point.Y = (float)Pixels(P.Y);
                
                C_Form F = (C_Form)AL4Object.Obj;
                //******************************
                //if (F.F_level_event > 1) return;
                //******************************
                
                F.Do.M_operation_started(0, F.hard_link);
                try {
	                try {
	                	F.Do.M_click();
	                } //catch(Stop) {}
	                catch (Exception Ex) {
			        	if (Ex is AL4_Exception) throw;
			        }
                }
                finally {
                F.Do.M_operation_ended(0);
                }
            }
            finally {
                    click_disabled = false;
            }
//.
        }
        
        public void Control_changed(Object Sender, EventArgs E)
        {
            Control C = (Control)Sender;
            AL4Form form = Parent_form(C);
            C_Form F = (C_Form)form.AL4Object.Obj;
            Ref_obj CR = (Ref_obj)C.Tag;
//?{Form}.value_change
            
            if  (click_disabled) return;
            click_disabled = true;
            try {
                F.Do.M_operation_started(5, CR);
                try {
                	try {
//.
//?{Checkbox}
	                if (C is CheckBox)
	                	((C_Checkbox)CR.Obj).Do.M_radio_select(CR);
//.
//?{Form}.value_change
	                F.Do.M_value_change();
	                } //catch(Stop) {}
	                catch (Exception Ex) {
			        	if (Ex is AL4_Exception) throw;
			        }
                }
                finally {
                F.Do.M_operation_ended(5);
                }
            }
            finally {
                    click_disabled = false;
            }
//.
			F.Do.M_Any_change();
        }
        
        public void Control_selection_changed(Object Sender, EventArgs E)
        {
//?{Form}.sel_change
            if  (click_disabled) return;
            click_disabled = true;
            try {
                Control C = (Control)Sender;
                Ref_obj CR = (Ref_obj)C.Tag;
                AL4Form form = Parent_form(C);
                C_Form F = (C_Form)form.AL4Object.Obj;
                
                F.Do.M_operation_started(6, CR);
                try {
	                try {
	                	C_Form.M_Notify_sel_change(AL4Object);
	                } //catch(Stop){}
	                catch (Exception Ex) {
			        	if (Ex is AL4_Exception) throw;
			        }
                }
                finally {
                F.Do.M_operation_ended(6);
                }
            }
            finally {
                    click_disabled = false;
            }
//.
        }
        
        /*
        FUNCTION Control_selection_change({Control} C|ontrol_changed) :
            PUSH C.Form_.sender_ = C :
            	 {Form}.Notify_sel_change(C.Form_)
            ; .
        */
        
        public void Control_SelectedIndexChanged(object Sender, EventArgs E)
        {
//?{Form}.selection_change
			bool save_click_disabled = click_disabled;
            //if  (click_disabled) return;
            Control C = (Control)Sender;
            Ref_obj CR = (Ref_obj)C.Tag;
            AL4Form form = Parent_form(C);
            C_Form F = (C_Form)form.AL4Object.Obj;
            
        	click_disabled = true;
            F.Do.M_operation_started(6, CR);
            try {
                try {
                	C_Form.M_Notify_sel_change(AL4Object);
                }
                catch (Exception Ex) {
		        	if (Ex is AL4_Exception) throw;
		        }
            }
            finally {
            click_disabled = save_click_disabled;
            F.Do.M_operation_ended(6);
            } 
//.
        }
        
        public static bool ignore_control_resize = false;

        public void Control_resized(Object Sender, EventArgs E)
        {
//?{Form}.resize
            if (click_disabled || ignore_control_resize) return;
            click_disabled = true;
            try
            {
                Control C = (Control)Sender;
                Ref_obj CR = (Ref_obj)C.Tag;
                AL4Form form = Parent_form(C);
                if (form != null && form.Handle_form > 0)
                {
                    C_Form F = (C_Form)form.AL4Object.Obj;
                    F.Do.M_operation_started(7, CR);
                    try {
	                    try {
	                    	//F.Do.M_resize();
	                    	((C_Control)CR.Obj).Do.M_resized();
	                    } //catch(Stop) {}
	                    catch (Exception Ex) {
				        	if (Ex is AL4_Exception) throw;
				        }
                    }
                    finally {
                    F.Do.M_operation_ended(7);
                    }
                }
            }
            finally
            {
                click_disabled = false;
            }
//.
        }

        public void Form_moved(Object Sender, EventArgs E)
        {
//?{Form}.moved
            C_Form F = (C_Form)(AL4Object.Obj);
            F.Do.M_operation_started(8, F.hard_link);
            try {
	            try {
	            	F.Do.M_moved();
	            } //catch(Stop) {}
	            catch (Exception Ex) {
		        	if (Ex is AL4_Exception) throw;
		        }
            }
            finally {
            F.Do.M_operation_ended(8);
            }
//.
        }

        public void Form_resized(Object Sender, EventArgs E)
        {
            Rectangle cr = ClientRectangle;
            for (int i = 1; i <= 3; i++)
            {
                Adjust_columns_docking();
                Rectangle ncr = ClientRectangle;
                if (i > 1 && cr.Left == ncr.Left && cr.Top == ncr.Top &&
                cr.Width == ncr.Width && cr.Height == ncr.Height)
                	break;
            }
//?{Form}.resize
            C_Form F = (C_Form)(AL4Object.Obj);
            
            F.Do.M_operation_started(7, F.hard_link);
            try {
	            try {
	            	F.Do.M_resize();
	            } //catch(Stop) {}
	            catch (Exception Ex) {
		        	if (Ex is AL4_Exception) throw;
		        }
            }
            finally {
            F.Do.M_operation_ended(7);
            }
//.
        }

		bool shown;
		
		[DllImport("User32.dll")]
        public static extern bool PostMessage(
        	IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
		
        public void Form_shown(Object Sender, EventArgs E)
        {
            Adjust_columns_docking();
            shown = E != null; // == event was from system
            if (Alpha > 0)
            	PostMessage(Handle, WM_USER+0xA1f, (IntPtr)0, (IntPtr)0);

            C_Form F = (C_Form)AL4Object.Obj;
			if (E == null || F.Do.M_modal()) 
			{
	            
	            F.Do.M_operation_started(9, F.hard_link);
	            try {
		            try {
		            F.Do.M_shown();
		            } //catch(Stop) {}
		            catch (Exception Ex) {
			        	if (Ex is AL4_Exception) throw;
			        }
	            }
	            finally {
	            F.Do.M_operation_ended(9);
	            }
			}
			
			if (shown)
			{
	            //F.Do.M_Any_change();
	            Form_resized(Sender, null);
			}

        }
        
	public const int WM_USER = 0x0400;
        
        public void Form_closing(Object Sender, FormClosingEventArgs E)
        {
            C_Form F = (C_Form)AL4Object.Obj; 
//?{Form}.closing
 			switch (E.CloseReason)
 			{
 			case CloseReason.UserClosing:
 				F.F_reason_closing = 0; break;
 			case CloseReason.WindowsShutDown:
 				F.F_reason_closing = 2; break;
 			default:
 				F.F_reason_closing = 1; break;
 			}
	
            bool modal_dlg = F.Do.M_modal();
            bool dont_close = false;
            
            F.Do.M_operation_started(1, F.hard_link);
            try {
	            try {
	                dont_close = F.Do.M_closing() != 0;
	                if (dont_close && E.CloseReason == CloseReason.WindowsShutDown)
	                {
	                	if (!F.F_Do_not_close) dont_close = false;
	                }
	            } //catch(Stop) {}
	            catch (Exception Ex) {
		        	if (Ex is AL4_Exception) throw;
		        }
            }
            finally {
            F.Do.M_operation_ended(1);
            }
                
            if (!modal_dlg) 
            {
                if (dont_close)
                {
                    E.Cancel = true;
                    return;
                }
            }
//.

//?{Form}.closed
            F.Do.M_operation_started(2, F.hard_link);
            try {
	            try 
	            {
	            	F.Do.M_closed();
	            } //catch(Stop) {}
	            catch (Exception Ex) {
		        	if (Ex is AL4_Exception) throw;
		        }
            }
            finally {
            F.Do.M_operation_ended(2);
            }
//.

			if (!F.Do.M_modal())
				AL4Form.All_descriptors[(int)F.F_Handle] = null;
        }

        public static bool handling_activation;
        
        public void Form_activated(Object Sender, EventArgs E)
        {
//?{Form}.activated
            if (handling_activation) return;
            C_Form F = (C_Form)AL4Object.Obj;
        	handling_activation = true;
            F.Do.M_operation_started(3, F.hard_link);
            try {
                try {
                F.Do.M_activated();
                } //catch(Stop) {}
                catch (Exception Ex) {
		        	if (Ex is AL4_Exception) throw;
		        }
            }
            finally {
	            handling_activation = false;
	            F.Do.M_operation_ended(3);
            }
//.
        }

        public void Form_MouseMove(Object Sender, MouseEventArgs E)
        {
//?{Form}.mouse_move
            C_Form F = (C_Form)AL4Object.Obj;
            Point P = PointToClient(Cursor.Position);
            Mouse_point.X = (float)Pixels(P.X);
            Mouse_point.Y = (float)Pixels(P.Y);
            Popup_point = Mouse_point;
            AL4_object.Object_assign_hard(ref F.F_Key, 
            	prepare_key(new KeyEventArgs(new Keys())));
            
            F.Do.M_operation_started(10, F.hard_link);
            try {
	            try {
	            F.Do.M_mouse_move();
	            } //catch(Stop) {}
	            catch (Exception Ex) {
		        	if (Ex is AL4_Exception) throw;
		        }
            }
            finally {
            F.Do.M_operation_ended(10);
            }
//.
        }

        public void Control_MouseMove(Object Sender, MouseEventArgs E)
        {
//?{Form}
        	bool stop_handling = false;
            C_Form F = (C_Form)AL4Object.Obj;
            Point P = PointToClient(Cursor.Position);
            Mouse_point.X = (float)Pixels(P.X);
            Mouse_point.Y = (float)Pixels(P.Y);
            Popup_point = Mouse_point;
            Control C = (Control)Sender;
            Ref_obj CR = (Ref_obj)C.Tag;
            AL4_object.Object_assign_hard(ref F.F_Key,
            	prepare_key(new KeyEventArgs(new Keys())));
            if (CR.Obj != null)
            {
            	C_Control CC = (C_Control)CR.Obj;
//?{Control}.mouse_move
	            CC.F_stop_handling = false;
	            
	            F.Do.M_operation_started(10, CC.hard_link);
	            try {
		            try {
		            	CC.Do.M_mouse_move();
		            } //catch(Stop) {}
		            catch (Exception Ex) {
			        	if (Ex is AL4_Exception) throw;
			        }
	            }
	            finally {
	            F.Do.M_operation_ended(10);
	            }
	            
				stop_handling = CC.F_stop_handling;
//.
	            
//?{Form}.mouse_move
	            if (!stop_handling)
	            {
	                F.Do.M_operation_started(10, CC.hard_link);
	                try {
		                try {
		                	F.Do.M_mouse_move();
		                } //catch(Stop) {}
		                catch (Exception Ex) {
				        	if (Ex is AL4_Exception) throw;
				        }
	                }
	                finally {
	                F.Do.M_operation_ended(10);
	                }
	            }
//.
            }
//.
        }
        
        public static int button_index(System.Windows.Forms.MouseButtons b)
        {
            switch (b)
            {
                case System.Windows.Forms.MouseButtons.Left: return 1;
                case System.Windows.Forms.MouseButtons.Right: return 2;
                case System.Windows.Forms.MouseButtons.Middle: return 3;
                case System.Windows.Forms.MouseButtons.XButton1: return 4;
                case System.Windows.Forms.MouseButtons.XButton2: return 5;
                default: return 255;
            }
        }

        public void Control_MouseDown(Object Sender, MouseEventArgs E)
        {
//?{Form}
        	bool stop_handling = false;
            C_Form F = (C_Form)AL4Object.Obj;
            Control C = (Control)Sender;
            AL4Form aF = (AL4Form)AL4Form.All_descriptors[(int)F.F_Handle];
                //******************************
                //if (F.F_level_event > 1) return;
                //******************************
            //Point P = PointToClient(Cursor.Position);
            Point P = E.Location;
            P = C.PointToScreen(P);
            P = aF.PointToClient(P);
            Mouse_point.X = (float)Pixels(P.X);
            Mouse_point.Y = (float)Pixels(P.Y);
            Popup_point = Mouse_point;
            if (button_index(E.Button) < 255)
                Mouse_button = button_index(E.Button);
            //Control C = (Control)Sender;
            Ref_obj CR = (Ref_obj)C.Tag;
            AL4_object.Object_assign_hard(ref F.F_Key,
            	prepare_key(new KeyEventArgs(new Keys())));
            if (CR.Obj != null)
            {
//{Control}.mouse_down
	            C_Control CC = (C_Control)CR.Obj;
	            CC.F_stop_handling = false;
	            
	            F.Do.M_operation_started(11, CR);
	            try {
		            try {
		            CC.Do.M_mouse_down();
		            } //catch(Stop) {}
		            catch (Exception Ex) {
			        	if (Ex is AL4_Exception) throw;
			        }
	            }
	            finally {
	            F.Do.M_operation_ended(11);
	            }
	            stop_handling = CC.F_stop_handling;
//.
//?{Form}.mouse_down
	            if (!stop_handling)
	            {
	                F.Do.M_operation_started(11, CR);
	                try {
		                try {
		                	F.Do.M_mouse_down();
		                } //catch(Stop) {}
		                catch (Exception Ex) {
				        	if (Ex is AL4_Exception) throw;
				        }
	                }
	                finally {
	                F.Do.M_operation_ended(11);
	                }
	            }
//.
            }
//.
        }

        public void Form_MouseDown(Object Sender, MouseEventArgs E)
        {
//?{Form}.mouse_down
            C_Form F = (C_Form)AL4Object.Obj;
                //******************************
                //if (F.F_level_event > 1) return;
                //******************************
            Point P = PointToClient(Cursor.Position);
            Mouse_point.X = (float)Pixels(P.X);
            Mouse_point.Y = (float)Pixels(P.Y);
            Popup_point = Mouse_point;
            if (button_index(E.Button) < 255)
                Mouse_button = button_index(E.Button);
            AL4_object.Object_assign_hard(ref F.F_Key,
            	prepare_key(new KeyEventArgs(new Keys())));
            
            F.Do.M_operation_started(11, F.hard_link);
            try {
	            try {
	            F.Do.M_mouse_down();
	            } //catch(Stop) {}
	            catch (Exception Ex) {
		        	if (Ex is AL4_Exception) throw;
		        }
            }
            finally {
            F.Do.M_operation_ended(11);
            }
//.
        }

        public void Control_MouseUp(Object Sender, MouseEventArgs E)
        {
        	try {
        	bool stop_handling = false;
            C_Form F = (C_Form)AL4Object.Obj;
                //******************************
                //if (F.F_level_event > 1 || (int)F.F_Handle == 0) return;
                //******************************
            Point P = PointToClient(Cursor.Position);
            Mouse_point.X = (float)Pixels(P.X);
            Mouse_point.Y = (float)Pixels(P.Y);
            Popup_point = Mouse_point;
            if (button_index(E.Button) < 255)
                Mouse_button = button_index(E.Button);
            AL4_object.Object_assign_hard(ref F.F_Key,
            	prepare_key(new KeyEventArgs(new Keys())));
            
            Control C = (Control)Sender;
            Ref_obj CR = (Ref_obj)C.Tag;
            if (CR.Obj != null)
            {
	            C_Control CC = (C_Control)CR.Obj;
//?{Control}.mouse_up
	            CC.F_stop_handling = false;
	            
	            F.Do.M_operation_started(12, CC.hard_link);
	            try {
		            try {
		            	CC.Do.M_mouse_up();
		            } //catch(Stop) {}
		            catch (Exception Ex) {
			        	if (Ex is AL4_Exception) throw;
			        }
	            }
	            finally {
	            F.Do.M_operation_ended(12);
	            }
	            stop_handling = CC.F_stop_handling;
//.
	            
//?{Form}.mouse_up
	            if (!stop_handling) 
	            {
	                F.Do.M_operation_started(12, CC.hard_link);
	                try {
		                try {
		                F.Do.M_mouse_up();
		                } //catch(Stop) {}
		                catch (Exception Ex) {
				        	if (Ex is AL4_Exception) throw;
				        }
	                }
	                finally {
	                F.Do.M_operation_ended(12);
	                }
	            }
//.
        	}
            }
            catch (Exception Ex) {
            	if (Ex is AL4_Exception) throw;
            }
        }

        public void Form_MouseUp(Object Sender, MouseEventArgs E)
        {
//?{Form}.mouse_up
            C_Form F = (C_Form)AL4Object.Obj;
                //******************************
                //if (F.F_level_event > 1) return;
                //******************************
            Point P = PointToClient(Cursor.Position);
            Mouse_point.X = (float)Pixels(P.X);
            Mouse_point.Y = (float)Pixels(P.Y);
            Popup_point = Mouse_point;
            if (button_index(E.Button) < 255)
                Mouse_button = button_index(E.Button);
            //F.F_sender_alias = F.F_Alias;
            AL4_object.Object_assign_hard(ref F.F_Key,
            	prepare_key(new KeyEventArgs(new Keys())));
            
            F.Do.M_operation_started(12, F.hard_link);
            try {
	            try {
	            	F.Do.M_mouse_up();
	            } //catch(Stop) {}
	            catch (Exception Ex) {
		        	if (Ex is AL4_Exception) throw;
		        }
            }
            finally {
            F.Do.M_operation_ended(12);
            }
//.
        }

        public void Control_DoubleClick(Object Sender, MouseEventArgs E)
        {
        	bool stop_handling = false;
            C_Form F = (C_Form)AL4Object.Obj;
                //******************************
                //if (F.F_level_event > 1) return;
                //******************************
            Point P = PointToClient(Cursor.Position);
            Mouse_point.X = (float)Pixels(P.X);
            Mouse_point.Y = (float)Pixels(P.Y);
            Popup_point = Mouse_point;
            if (button_index(E.Button) < 255)
                Mouse_button = button_index(E.Button);

            Control C = (Control)Sender;
            Ref_obj CR = (Ref_obj)C.Tag;
            AL4_object.Object_assign_hard(ref F.F_Key,
            	prepare_key(new KeyEventArgs(new Keys())));
            if (CR.Obj != null)
            {
//?{Control}.mouse_double_click
	            C_Control CC = (C_Control)CR.Obj;
	            CC.F_stop_handling = false;
	            
				F.Do.M_operation_started(13, CR);
				try {
		            try {
			            //-----------------
			            CC.Do.M_mouse_double_click();
		            } //catch(Stop) {}
		            catch (Exception Ex) {
			        	if (Ex is AL4_Exception) throw;
			        }
				}
				finally {
	            F.Do.M_operation_ended(13);
				}
	            stop_handling = CC.F_stop_handling;
//.
	
//?{Form}.mouse_double_click
	            if (!stop_handling)
	            {
	                //AL4_object.Object_assign_hard(ref F.F_sender, CR.Obj);
	                
	                F.Do.M_operation_started(13, CR);
	                try {
		                try {
		                	F.Do.M_mouse_double_click();
		                } //catch(Stop) {}
		                catch (Exception Ex) {
				        	if (Ex is AL4_Exception) throw;
				        }
	                }
	                finally {
	                F.Do.M_operation_ended(13);
	                }
	
                    //AL4_object.Object_assign_hard(
                    //            ref F.F_sender, C_Control.NoneObj_C_Control);
	            }
//.
            }

        }

        public void Form_DoubleClick(Object Sender, MouseEventArgs E)
        {
//?{Form}.mouse_double_click
            C_Form F = (C_Form)AL4Object.Obj;
                //******************************
                //if (F.F_level_event > 1) return;
                //******************************
            Point P = PointToClient(Cursor.Position);
            Mouse_point.X = (float) Pixels(P.X);
            Mouse_point.Y = (float) Pixels(P.Y);
            Popup_point = Mouse_point;
            if (button_index(E.Button) < 255)
                Mouse_button = button_index(E.Button);
            //F.F_sender_alias = F.F_Alias;
            AL4_object.Object_assign_hard(ref F.F_Key, 
            	prepare_key(new KeyEventArgs(new Keys())));
            
            F.Do.M_operation_started(13, F.hard_link);
            try {
	            try {
	            	F.Do.M_mouse_double_click();
	            } //catch(Stop) {}
	            catch (Exception Ex) {
		        	if (Ex is AL4_Exception) throw;
		        }
            }
            finally {
            F.Do.M_operation_ended(13);
            }
//.
        }

        public void Form_MouseWheel(Object Sender, MouseEventArgs E)
        {
//?{Form}.mouse_wheel
            C_Form F = (C_Form)AL4Object.Obj;
            Point P = PointToClient(Cursor.Position);
            Mouse_point.X = (float) Pixels(P.X);
            Mouse_point.Y = (float) Pixels(P.Y);
            Popup_point = Mouse_point;
            Mouse_wheel_vertical = E.Delta > 0 ? (E.Delta + 119) / 120.0 / 2
            								   : (E.Delta - 119) / 120.0 / 2;
            Control C = ActiveControl;
            AL4_object.Object_assign_hard(ref F.F_Key,
            	prepare_key(new KeyEventArgs(new Keys())));
            //F.F_sender_alias = F.F_Alias;
            bool handled_already = false;
            Ref_obj CR = null;
            if (C != null)
            {
                CR = (Ref_obj)C.Tag;
                if (CR != null && CR.Obj != null)
                {
	                C_Control CC = (C_Control)CR.Obj;
	                CC.F_stop_handling = false;
	                
	                F.Do.M_operation_started(14, CR);
	                try {
		                try {
		                	CC.Do.M_mouse_wheel();
		                } //catch(Stop) {}
		                catch (Exception Ex) {
				        	if (Ex is AL4_Exception) throw;
				        }
	                }
	                finally {
	                F.Do.M_operation_ended(14);
	                }
	                
	                if (!CC.F_stop_handling)
	                {
	                    //AL4_object.Object_assign_hard(ref F.F_sender, CR.Obj);
	                    
	                    F.Do.M_operation_started(14, CR);
	                    try {
		                    try {
			                    F.Do.M_mouse_wheel();
			                    handled_already = true;
		                    } catch(Stop) {}
	                    }
	                    finally {
	                    F.Do.M_operation_ended(14);
	                    }
	                }
	                else return;
                }
            }
            if (!handled_already) {
                F.Do.M_operation_started(14, CR == null ? F.hard_link : CR);
                try {
	                try {
	                	F.Do.M_mouse_wheel();
	                } //catch(Stop) {}
	                catch (Exception Ex) {
			        	if (Ex is AL4_Exception) throw;
			        }
                }
                finally {
                F.Do.M_operation_ended(14);
                }
            }
//.
        }

        private static C_Form.St_key_info prepare_key(KeyEventArgs E)
        {
            C_Form.St_key_info
            	info = (C_Form.St_key_info)C_Form.St_key_info.New().Obj;
            if ((Char)E.KeyCode >= 'A' && (Char)E.KeyCode <= 'Z' ||
                (Char)E.KeyCode >= '0' && (Char)E.KeyCode <= '9' ||
                E.KeyCode == Keys.Return || E.KeyCode == Keys.Back ||
                E.KeyCode == Keys.Space)
            {
               info.f_Char = "" + (Char)E.KeyCode;
            }
            
            int Key = (int)E.KeyCode;
            switch(Key)
            {
            case 0x5B: case 0xDB: info.f_Char = "["; Key = 0; break;
            case 0x5D: case 0xDD: info.f_Char = "]"; Key = 0; break;
            case 0x3C: case 0xBC: info.f_Char = "<"; Key = 0; break;
            case 0x3E: case 0xBE: info.f_Char = ">"; Key = 0; break;
            case 0x3A: case 0xBA: info.f_Char = ";"; Key = 0; break;
            case 0x5E: case 0xDE: info.f_Char = "'"; Key = 0; break;
            case 0x3F: case 0xBF: info.f_Char = "/"; Key = 0; break;
            case 0x5C: case 0xDC: info.f_Char =@"\";Key = 0; break;
            case 0x40: case 0xC0: info.f_Char = "~"; Key = 0; break;    
            }
            
            info.f_Special = (int)E.KeyCode;
            switch (E.KeyCode)
            {
                case Keys.CapsLock: 
                case Keys.NumLock:
                case Keys.Scroll:
                    info.f_Caps = Control.IsKeyLocked(E.KeyCode); break;
            }
            info.f_Shift = (ModifierKeys & Keys.Shift) == Keys.Shift;
            info.f_Ctrl = (ModifierKeys & Keys.Control) == Keys.Control;
            info.f_Alt = (ModifierKeys & Keys.Alt) == Keys.Alt;
            info.f_Win = (ModifierKeys & (Keys.LWin | Keys.RWin)) != 0;
            return info;
        }

        private static C_Form.St_key_info prepare_key_press(
        	KeyPressEventArgs E)
        {
            C_Form.St_key_info 
            	info = (C_Form.St_key_info)C_Form.St_key_info.New().Obj;
            info.f_Char = "" + E.KeyChar;
            info.f_Special = (int)E.KeyChar;
            info.f_Shift = (ModifierKeys & Keys.Shift) == Keys.Shift;
            info.f_Win = (ModifierKeys & (Keys.LWin | Keys.RWin)) != 0;
            info.f_Ctrl = (ModifierKeys & Keys.Control) == Keys.Control;
            info.f_Alt = (ModifierKeys & Keys.Alt) == Keys.Alt;
            if (info.f_Alt && info.f_Ctrl) {
            	bool a2 = GetKeyState(0xA2)<0;
            	bool a3 = GetKeyState(0xA3)<0;
            	bool a4 = GetKeyState(0xA4)<0;
            	bool a5 = GetKeyState(0xA5)<0;
            	if (a2 && a5 && !a3 && !a4) 
            		info.f_Ctrl = false;
            } 
            return info;
        }
        
        public static bool key_disabled;

        public void Form_KeyDown(Object Sender, KeyEventArgs E)
        {
//?{Form}.key_down
		if (ActiveControl != null) return;
            if (E.KeyValue == 0x12) return;
            if  (key_disabled) return;
            key_disabled = true;
            try {
	            C_Form F = (C_Form)AL4Object.Obj;
	                //******************************
	                //if (F.F_level_event > 1) return;
	                //******************************
	            C_Form.St_key_info info = prepare_key(E);
	            AL4_object.Object_assign_hard(ref F.F_Key, info);
	
	            F.Do.M_operation_started(15, F.hard_link);
	            try {
		            try {
			            if (F.Do.M_key_down() != 0) 
			            {
			                E.Handled = true;
			                E.SuppressKeyPress = true;
			            }
		            } //catch(Stop) {}
		            catch (Exception Ex) {
			        	if (Ex is AL4_Exception) throw;
			        }
	            }
	            finally {
	            F.Do.M_operation_ended(15);
	            }
            }
            finally {
            	key_disabled = false;
            }
//.
        }
        
        public void Control_KeyDown(Object Sender, KeyEventArgs E)
        {
//?{Form}.key_down
            if (E.KeyValue == 177) return;
            C_Form F = (C_Form)AL4Object.Obj;
                //******************************
                //if (F.F_level_event > 1) return;
                //******************************
            Control C = (Control)Sender;
//AL4Form form = Parent_form(C);
//if (form.CancelButton == C && E.KeyCode == Keys.Space) {
    //E.Handled = true;
    //return;
//}
			if  (key_disabled) return;
            key_disabled = true;
            try {
            
	            C_Form.St_key_info info = prepare_key(E);
	            AL4_object.Object_assign_hard(ref F.F_Key, info);
	
	            Ref_obj CR = (Ref_obj)C.Tag;
	            //if (C is Button && E.KeyValue == 13 && F.F_Cancel_button.Obj == CR.Obj)
	            //{
	            //    return;
	            //}
	                {
	                //AL4_object.Object_assign_hard(ref F.F_sender, CR.Obj);
	                //F.F_sender_alias = ((C_Control)F.F_sender.Obj).F_Alias;
	                }
	            F.Do.M_operation_started(15, CR);
	            try {
		            try {
			            if (F.Do.M_key_down() != 0) 
			            {
			                E.Handled = true;
			                E.SuppressKeyPress = true;
			            }
		            } //catch(Stop) {}
		            catch (Exception Ex) {
			        	if (Ex is AL4_Exception) throw;
			        }
	            }
	            finally {
	            F.Do.M_operation_ended(15);
	            }
            }
            finally {
            	key_disabled = false;
            }
        }

        public void Form_KeyUp(Object Sender, KeyEventArgs E)
        {
//?{Form}.key_up
            C_Form F = (C_Form)AL4Object.Obj;
                //******************************
                //if (F.F_level_event > 1) return;
                //******************************
            C_Form.St_key_info info = prepare_key(E);
            AL4_object.Object_assign_hard(ref F.F_Key, info);

			if  (click_disabled) return;
            click_disabled = true;
            try {
	            F.Do.M_operation_started(16, F.hard_link);
	            try {
		            try {
			            if (F.Do.M_key_up() != 0)
			            {
			                E.Handled = true;
			            }
		            } //catch(Stop) {}
		            catch (Exception Ex) {
			        	if (Ex is AL4_Exception) throw;
			        }
	            }
	            finally {
	            F.Do.M_operation_ended(16);
	            }
            }
            finally {
            	click_disabled = false;
            }
//.
        }

        public void Control_KeyUp(Object Sender, KeyEventArgs E)
        {
//?{Form}.key_up
            C_Form F = (C_Form)AL4Object.Obj;
            Control C = (Control)Sender;
            C_Form.St_key_info info = prepare_key(E);
            AL4_object.Object_assign_hard(ref F.F_Key, info);

            Ref_obj CR = (Ref_obj)C.Tag;
                {
                //AL4_object.Object_assign_hard(ref F.F_sender, CR.Obj);
                //F.F_sender_alias = ((C_Control)F.F_sender.Obj).F_Alias;
                }
                
            F.Do.M_operation_started(16, CR);
            try {
	            try {
		            if (F.Do.M_key_up() != 0)
		            {
		                E.Handled = true;
		                E.SuppressKeyPress = true;
		            }
	            } //catch(Stop) {}
	            catch (Exception Ex) {
		        	if (Ex is AL4_Exception) throw;
		        }
            }
            finally {
            F.Do.M_operation_ended(16);
            }
            
            restore_focus(C); // otherwise in C# made apps caret disappears !!!!!!!!!!!
            //AL4_object.Object_assign_hard(ref F.F_sender, C_Control.NoneObj_C_Control);
//.
        }

        public void Form_KeyPress(Object Sender, KeyPressEventArgs E)
        {
//?{Form}.key_press
            C_Form F = (C_Form)AL4Object.Obj;
                //******************************
                //if (F.F_level_event > 1) return;
                //******************************
            C_Form.St_key_info info = prepare_key_press(E);
            AL4_object.Object_assign_hard(ref F.F_Key, info);
            if (info.f_Char[0] != (char)0 && 
                info.f_Char[0] >= 'A' && info.f_Char[0] <= 'Z' && (
            	info.f_Ctrl || info.f_Alt)) return;

			if  (click_disabled) return;
            click_disabled = true;
            try {
	            F.Do.M_operation_started(17, F.hard_link);
	            try {
		            try {
		            	if (F.Do.M_key_press() != 0) E.KeyChar = (Char)0;
		            } //catch(Stop) {}
		            catch (Exception Ex) {
			        	if (Ex is AL4_Exception) throw;
			        }
	            }
	            finally {
	            F.Do.M_operation_ended(17);
	            }
            }
            finally {
            	click_disabled = false;
            }
//.
        }
        
        public void Control_KeyPress(Object Sender, KeyPressEventArgs E)
        {
            C_Form F = (C_Form)AL4Object.Obj;
            Control C = (Control)Sender;
            
//AL4Form form = Parent_form(C);
//if (form.CancelButton == C && E.KeyChar == (char)Keys.Space) {
//    E.Handled = true;
//    return;
//}
            C_Form.St_key_info info = prepare_key_press(E);
            AL4_object.Object_assign_hard(ref F.F_Key, info);
            if (info.f_Char[0] != (char)0 && 
                info.f_Char[0] >= 'A' && info.f_Char[0] <= 'Z' && (
            	info.f_Ctrl || info.f_Alt)) return;
    
    		bool do_not_restore_focus = info.f_Char[0] == '\t';
            Ref_obj CR = (Ref_obj)C.Tag;
            	C_Control CC = (C_Control)CR.Obj;
            	if (CC is C_Edit)
            	{
            		C_Edit CE = (C_Edit)CC;
            		if (CE.F_options.Contains('N'))
            		{
            			if ("\t\b0123456789.,-+".Contains(info.f_Char[0])) { }
            			else 
            			{
            				E.Handled = true;
            				return;
            			}
            		}
            	}

//?{Form}.key_press
            F.Do.M_operation_started(17, CR);
            try {
	            try {
		            if (F.Do.M_key_press() != 0)
		            {
		            	E.KeyChar = (Char)0;
		            } 
	            } //catch(Stop) {}
	            catch (Exception Ex) {
		        	if (Ex is AL4_Exception) throw;
		        }
            }
            finally {
            F.Do.M_operation_ended(17);
            }

			if (!do_not_restore_focus)            
            	restore_focus(C); // otherwise in C# made apps caret disappears !!!!!!!!!!!
//.
        }
        
        public static void restore_focus(Control C)
        {
        	Form f = Parent_form(C);
        	if (f == null || Form.ActiveForm != f) return;
        	C.Focus(); // otherwise in C# made apps caret disappears !!!!!!!!!!!
        }
        
    public void Control_Enter(object Sender, EventArgs E)
    {
//?{Form}.enter
		C_Form F = (C_Form)AL4Object.Obj;
		Control C = (Control)Sender;
		Ref_obj CR = (Ref_obj)C.Tag;
		
        F.Do.M_operation_started(24, CR);
        try {
	        try {
	        	F.Do.M_enter();
	        } //catch(Stop) {}
	        catch (Exception Ex) {
	        	if (Ex is AL4_Exception) throw;
	        }
        }
        finally {
        F.Do.M_operation_ended(24);
        }
//.
    }
    
    public void Control_Leave(object Sender, EventArgs E)
    {
//?{Form}.leave
		C_Form F = (C_Form)AL4Object.Obj;
		Control C = (Control)Sender;
		Ref_obj CR = (Ref_obj)C.Tag;

        F.Do.M_operation_started(24, CR);
        try {
	        try {
	        	F.Do.M_leave();
	        } //catch(Stop) {}
	        catch (Exception Ex) {
	        	if (Ex is AL4_Exception) throw;
	        }
        }
        finally {
        F.Do.M_operation_ended(24);
        }
//.
    }
    
        
        

        public void Form_timer(Object Sender, EventArgs E)
        {
//?{Form}.timer
            if (!Enabled) return;
            C_Form F = (C_Form)AL4Object.Obj;
            System.Windows.Forms. Timer T = (System.Windows.Forms. Timer)Sender;
            Panel TP = (Panel)T.Tag;

            Ref_obj CR = (Ref_obj)TP.Tag;
            try {
	            F.Do.M_operation_started(18, CR);
	            try {
	            	F.Do.M_timer();
	            }
	            finally {
            	F.Do.M_operation_ended(18);
	            }
            } 
            catch (Exception Ex)
                {
                	if (Ex is AL4_Exception) throw; 
                }
            
            //AL4_object.Object_assign_hard(ref F.F_sender, C_Control.NoneObj_C_Control);
//.
        }
        
        /*
        FUNCTION Begin_animation(
            INT H|andle_control, INT Count|_ticks, INT Interval|_ms ), NATIVE
            :
        @   "AL4Form.Do_begin_animation("
        	"	(int)X_H, (int)X_Count, (int)X_Interval);" .
        */
        
        public static void Do_begin_animation(
            int X_H, int X_Count, int X_Interval)
        {
        	Control C = (Control)AL4Form.All_descriptors[(int)X_H];
            AL4Form form = AL4Form.Parent_form(C);
            
        	for (int i = form.Control_timers.Count-1; i >= 0; i--)
        	{
        		Animation_timer t = form.Control_timers[i];
        		if (t.Control_handle == X_H)
        		{
        			t.Counter = 0;
        			t.Last_counter = X_Count;
        			return;
        		}
        	}
            Animation_timer at = new Animation_timer(X_H, X_Count, X_Interval);
        }
        
        public List<Animation_timer> Control_timers = new List<Animation_timer>();
       
        //[System.Runtime.InteropServices.DllImport("user32.dll")]
        //static extern IntPtr SetCapture(long hWnd);
        [DllImport("user32.dll")] 
        static extern IntPtr SetCapture(IntPtr hWnd);
        
        public static void Do_Capture_Mouse(int X_H)
        {
        	 Control C = (Control)AL4Form.All_descriptors[X_H];
        	 AL4Form form = AL4Form.Parent_form(C);
             //if (C is Scrolled_paintbox)
             //   C = ((Scrolled_paintbox)C).PBox;
        	 IntPtr WH = C.Handle;
        	 if ((long)WH == 0) return;
        	 SetCapture(WH);
        }
        
        public static void Do_Release_Mouse()
        {
        	 ReleaseCapture();
        }
        
        /*
        
        FUNCTION Capture_mouse( INT H|andle_control ), NATIVE : @ 
        	"AL4Form.Do_Capture_Mouse((int)X_H);" .

            
        FUNCTION Release_mouse( INT H|andle_control ), NATIVE : @
        	"AL4Form.Do_Release_Mouse();" .   
        
        */
        

		
        
    } // END of class AL4Form
    
    
    public class Animation_timer
    {
        AL4Form form;
        Ref_obj Ref_control;
        public int Counter;
        public int Last_counter;
        System.Windows.Forms.Timer T;
        public int Control_handle;
        
        public Animation_timer(int X_H, int X_Count, int X_Interval)
        {
        	Control_handle = X_H;
            Control C = (Control)AL4Form.All_descriptors[(int)X_H];
            form = AL4Form.Parent_form(C);
            form.Control_timers.Add(this);
            
            Ref_control = (Ref_obj)C.Tag;
            Ref_control.Obj.hard_link.Count += 2;
            
            Last_counter = X_Count;
            T = new System.Windows.Forms. Timer();
            T.Interval = X_Interval;
            T.Tick += new EventHandler(Tick_animation);
            try {
            	T.Enabled = true;
            }
            catch (Exception Ex)
                {
                	if (Ex is AL4_Exception) throw; 
                }
        }
        
        public void Tick_animation(Object Sender, EventArgs E)
        {
//?{Control}.animation
            if (++Counter >= Last_counter)
            {
                Stop();
            }
            C_Control CC = (C_Control)Ref_control.Obj;
            C_Form F = (C_Form)form.AL4Object.Obj;
            
            F.Do.M_operation_started(19, Ref_control);
            try {
	            try {
		            //AL4_system.WriteLine("Tick_animation");
		            //-------------------------------------
		            CC.Do.M_animation();
	            } //catch(Stop) {}
	            catch (Exception Ex) {
		        	if (Ex is AL4_Exception) throw;
		        }
            }
            finally {
            F.Do.M_operation_ended(19);
            }
//.
        }
        
        public void Stop()
        {
            T.Enabled = false;
            form.Control_timers.Remove(this);
            Ref_control.Ref_dec_hard();
        }
    }

    // class for Columns (panels on form to locate controls on it)
    public class AL4Column : Panel
    {
        public int Handle_column;
        public bool Horizontal;
        public int Label_width; // in pixels
        public string Alias;
        public int Column_layout;
        public int Fixed_width;
        public bool No_margins;
        public bool Custom_font;
        
        /*
        
        FUN Get_column_layout(
        INT C|olumn_handle) ==> {Form}.{layout}, NATIVE : @
        "AL4Column Col = (AL4Column)AL4Form.All_descriptors[(int)X_C];"
        "RESULT = (byte)Col.Column_layout;" .
        
        */
        public bool Hidden;
        public List<Control> Hidden_controls = new List<Control>();
        public List<Control> Child_controls = new List<Control>();
        public bool adjusting_controls;
        public bool auto_arrange;
        public int suspend_count;
        
        public byte controls_layout;
        public int Nested_in = -1;
        
    	/*
    	
    	FUN Get_nested_in(INT C|olumn_handle) ==> INT, NATIVE : @
    	"	AL4Column col = (AL4Column)AL4Form.All_descriptors[(int)X_C];"
    	"	RESULT = col.Nested_in;" .
    	
    	*/

        public AL4Column()
        {
            Handle_column = AL4Form.AllocDescriptor(this);
            HorizontalScroll.Maximum = 0;
            AutoScroll = false;
            VerticalScroll.Visible = false;
            AutoScroll = AL4Form.Use_autoscroll_forms;
            
            auto_arrange = true;
        }

        ~AL4Column()
        {
            AL4Form.ReleaseDescriptor(Handle_column);
        }
        
        public void Resized(object sender, EventArgs e)
        {
            AL4Form.Adjust_control_location(this);
        }
    }
    
    public class MenuPanel : Panel
    {
        public ContextMenuStrip MenuObject;
        public List<string> AliasesList = new List<string>();
        public List<ToolStripItem> AllItemsList = new List<ToolStripItem>();

        public bool Ready;
        public string Alias;
        public bool track_submenu;

        public void Item_clicked(Object Sender, EventArgs E)
        {
//?{Form}.menu_item
            if (!(Sender is ToolStripMenuItem)) return;
            Alias = (string)((ToolStripMenuItem)Sender).Tag;
            Ready = true;
            AL4Form form = AL4Form.Parent_form(this);
            
            AL4Form.invalidate_all(form);
            //Application.DoEvents();

            C_Form F = (C_Form)form.AL4Object.Obj;
            
            F.Do.M_operation_started(20, F.hard_link);
            try {
	            try {
		            F.F_menu_alias = Alias;
		            try {
		            	F.Do.M_menu_item();
	            	}
	            	finally {
	            		F.F_menu_alias = "";
	            	}
	            } //catch(Stop) {}
	            catch (Exception Ex) {
		        	if (Ex is AL4_Exception) throw;
		        }
            }
            finally {
            F.Do.M_operation_ended(20);
            }
            
            form.MenuPanel_to_remove = null;
//.
        }

        public void Item_selected(Object Sender, EventArgs E)
        {
//?{Form}.selection_change
            if (!(Sender is ToolStripMenuItem)) return;
            
            Alias = (string)((ToolStripMenuItem)Sender).Tag;

            AL4Form form = AL4Form.Parent_form(this);
            C_Form F = (C_Form)form.AL4Object.Obj;
            
            F.Do.M_operation_started(20, F.hard_link);
            try {
	            try {
		            F.F_menu_alias = Alias;
		            try {
		            	F.Do.M_selection_change();
	            	}
	            	finally {
	            		F.F_menu_alias = "";
	            	}
	            } //catch(Stop) {}
	            catch (Exception Ex) {
		        	if (Ex is AL4_Exception) throw;
		        }
            }
            finally {
            F.Do.M_operation_ended(20);
            }
            
            form.MenuPanel_to_remove = null;
//.
        }

        public void Item_key_up(Object Sender, EventArgs E)
        {
//?{Form}.selection_change
            ToolStripMenuItem real_sender 
            	= (ToolStripMenuItem)((ToolStripDropDown)Sender).Tag;
            foreach(var ti in real_sender.DropDownItems)
            {
            	if (!(ti is ToolStripMenuItem)) continue;
            	ToolStripMenuItem t = (ToolStripMenuItem)ti;
            	if (!t.Selected) continue;
            	
	            Alias = (string)t.Tag;
	            
	            AL4Form form = AL4Form.Parent_form(this);
	            C_Form F = (C_Form)form.AL4Object.Obj;
	            
	            F.Do.M_operation_started(20, F.hard_link);
	            try {
		            try {
		                F.F_menu_alias = Alias;
		                try {
		                    F.Do.M_selection_change();
		                }
		                finally {
		                    F.F_menu_alias = "";
		                }
		            } //catch(Stop) {}
		            catch (Exception Ex) {
			        	if (Ex is AL4_Exception) throw;
			        }
	            }
	            finally {
	            F.Do.M_operation_ended(20);
	            }
	            
	            form.MenuPanel_to_remove = null;
	            return;
            }
//.
        }

        public void MenuObject_Closed(Object Sender, EventArgs E)
        {
//?{Form}.menu_item
			ToolStripDropDownClosedEventArgs e 
				= (ToolStripDropDownClosedEventArgs)E;
            Ready = true;
            if (e.CloseReason == ToolStripDropDownCloseReason.ItemClicked)
            	return;
            AL4Form form = AL4Form.Parent_form(this);
            if (form == null) return;
            C_Form F = (C_Form)form.AL4Object.Obj;
            
            F.Do.M_operation_started(20, F.hard_link);
            try {
	            try {
		            F.F_menu_alias = "";
		            F.Do.M_menu_item();
	            } //catch(Stop) {}
	            catch (Exception Ex) {
		        	if (Ex is AL4_Exception) throw;
		        }
            }
            finally {
            F.Do.M_operation_ended(20);
            }
//.
        }
    }

    public class TimerPanel : Panel
    {
        public System.Windows.Forms.Timer TimerObject;
    }
    
	public class TrayPanel : Panel
    {
        public NotifyIcon TrayObject;

        public void Form_tray_icon_click(Object Sender, MouseEventArgs E)
        {
//?{Form}.click
            NotifyIcon C = (NotifyIcon)Sender;
            AL4Form form = AL4Form.Parent_form(this);
            if (form == null) return;
            
            Point P = Control.MousePosition;
            P = form.PointToClient(P);

            if (AL4Form.button_index(E.Button) < 255)
                form.Mouse_button = AL4Form.button_index(E.Button);
            else form.Mouse_button = 2;

            try
            {
                form.Mouse_point = new PointF(
                	(float)AL4Form.Pixels(P.X),
                	(float)AL4Form.Pixels(P.Y));
                
                form.Popup_point = new PointF(
                	(float)AL4Form.Pixels(P.X),
                	(float)AL4Form.Pixels(P.Y));
            }
            catch (Exception Ex)
                {
                	if (Ex is AL4_Exception) throw; 
                }
            
            C_Form F = (C_Form)form.AL4Object.Obj;
            //AL4_object.Object_assign_hard(ref F.F_sender, ((Ref_obj)C.Tag).Obj);
            
            F.Do.M_operation_started(0, (Ref_obj)C.Tag);
            try {
	            try {
	            	F.Do.M_click();
	            } //catch(Stop) {}
	            catch (Exception Ex) {
		        	if (Ex is AL4_Exception) throw;
		        }
            }
            finally {
            F.Do.M_operation_ended(0);
            }
            
            //AL4_object.Object_assign_hard(ref F.F_sender, C_Control.NoneObj_C_Control);
//.
        }
    }
    
    public class Screen_handler : AL4_handler
    {
        Ref_obj X_Scr;
        public static DateTime Last_time;
        //public static int Last_activity_count;
        
        /*
        
        FUN get_Last_time_activity ==> REAL, NATIVE, PUBLIC :
        @	"	RESULT = Screen_handler.Last_time.ToOADate();" .
        
        FUN do_Last_time_set, NATIVE, PUBLIC : @
        	"	Screen_handler.Last_time = DateTime.Now;" .
        
        */
        
        public Screen_handler(Ref_obj X_Screen)
        {
            //Scr = (C_Screen)X_Screen.Obj;
            X_Scr = X_Screen;
            Last_time = DateTime.Now;
        }
        
          public override void Handler()
        {
            //if (Thread.CurrentThread.Name != null
            //    && Thread.CurrentThread.Name != "") return;
            if( AL4Form.mainThreadId != Thread.CurrentThread.ManagedThreadId)
            	return;
            DateTime dNow = DateTime.Now;
            double diff = (dNow - Last_time).TotalMilliseconds;
            if (diff < 20) return;
            
            C_Form F = (C_Form)((C_Screen)X_Scr.Obj).F_Form_operation_.Obj;
            C_Long_operation L_f = (C_Long_operation)
            	((C_Screen)(F.F_Screen_.Obj)).F_long_operation_internal.Obj;
            if (F.F_Can_stop_long_operation) {
	            if (diff > 2000 && !F.Is_NONE_object)
	            {
	                Last_time = dNow;
	                var h = F.Do.M_Long_operation().Obj;
	                if (h is C_Form)
	                {
	                    C_Form L = (C_Form)h;
	                    if ((int)L.F_Handle > 0) {
	                        AL4Form Lf = (AL4Form)AL4Form.All_descriptors[
	                        								   (int)L.F_Handle];
		                    if (Lf == null || !Lf.Visible && L_f.Do.M_can_show()) 
		                        L.Do.M_Show();
	                    }
	                }
	            }
            }
            if (!L_f.Is_NONE_object && Allow_handle_events > 0
            	&& L_f.Do.M_Visible())
            {
            	Allow_handle_events -= 1;
            	try {
	                Application.DoEvents();
            	}
            	finally {
            	Allow_handle_events += 1;
            	}
                if (L_f.F_Cancelled)
                {
                    L_f.F_Cancelled = false;
                    L_f.F_Finished = true;
                    AL4Form form = (AL4Form)AL4Form.All_descriptors[
                    	(int)F.F_Handle];
                    if (form != null)
                    	form.Enabled = true;
                    //L_f.Do.M_Close(); -> null written to All_descriptors[L_f.Handle]
                    //					после чего повторно уже нечего показывать
                    throw new Stop("Long operation is cancelled");
                }
            }
        }
    	public static int Allow_handle_events = 1;
    	
    }
    
    
}

/*

END
*/
