Example #1
0
        /// <summary>
        /// Simple non-OLE drag operation.
        /// Returns true if dropped, false if cancelled.
        /// </summary>
        /// <param name="window">Window or control that owns the drag operation.</param>
        /// <param name="mouseButton">Mouse button that is used for the drag operation: Left, Right.</param>
        /// <param name="onMouseKeyMessage">Callback function, called on each received mouse/key message. Optional.</param>
        public static bool SimpleDragDrop(AnyWnd window, MButtons mouseButton = MButtons.Left, Action <MsgArgs> onMouseKeyMessage = null)
        {
            AWnd w = window.Wnd;

            Api.SetCapture(w);

            bool R = false;
            var  x = new MsgArgs();

            for (; ;)
            {
                if (Api.GetCapture() != w)
                {
                    return(false);
                }
                if (Api.GetMessage(out x.Msg) <= 0)
                {
                    if (x.Msg.message == Api.WM_QUIT)
                    {
                        Api.PostQuitMessage((int)x.Msg.wParam);
                    }
                    break;
                }

                bool call = false;
                int  m    = x.Msg.message;
                if (m >= Api.WM_MOUSEFIRST && m <= Api.WM_MOUSELAST)
                {
                    if (m == Api.WM_LBUTTONUP)
                    {
                        if (R = (mouseButton & MButtons.Left) != 0)
                        {
                            break;
                        }
                    }
                    else if (m == Api.WM_RBUTTONUP)
                    {
                        if (R = (mouseButton & MButtons.Right) != 0)
                        {
                            break;
                        }
                    }
                    call = true;
                }
                else if (m == Api.WM_KEYDOWN || m == Api.WM_KEYUP || m == Api.WM_SYSKEYDOWN || m == Api.WM_SYSKEYUP)
                {
                    //on key down/up caller may want to update cursor when eg Ctrl pressed/released
                    if (x.Msg.wParam == (byte)KKey.Escape)
                    {
                        break;
                    }
                    call = true;
                }

                if (call && onMouseKeyMessage != null)
                {
                    onMouseKeyMessage(x);
                    if (x._stopped)
                    {
                        break;
                    }
                    if (x.Cursor != null)
                    {
                        Api.SetCursor(x.Cursor.Handle);
                        x.Cursor = null;
                    }
                }

                Api.DispatchMessage(x.Msg);
            }

            Api.ReleaseCapture();
            return(R);
        }
Example #2
0
 /// <summary>
 /// Prepares to get control names.
 /// </summary>
 /// <param name="w">Any top-level or child window of that process.</param>
 /// <exception cref="AuWndException">w invalid.</exception>
 /// <exception cref="AuException">Failed to allocate process memory (see <see cref="AProcessMemory"/>) needed to get control names, usually because of [](xref:uac).</exception>
 public AWinFormsControlNames(AWnd w)
 {
     _pm = new AProcessMemory(w, 4096);             //throws
     _w  = w;
 }
Example #3
0
 ///
 public HotkeyTriggerArgs(HotkeyTrigger trigger, AWnd w, KKey key, KMod mod)
 {
     Trigger = trigger;
     Window  = w; Key = key; Mod = mod;
 }
Example #4
0
 WButton(AWnd w)
 {
     W = w;
 }
Example #5
0
        int _anonymousStructSuffixCounter;                                            //used to create unique name for anonymous struct

        /// <summary>
        /// Converts C++ header-list file cppFile to C# declarations and saves in file csFile.
        /// </summary>
        /// <param name="is32bit">Prefer 32-bit. Although the converter tries to create declarations that don't depend on 32/64 bit, in some places it will create different declaration if this is true, for example IntPtr size will be 4 bytes.</param>
        public void Convert(string cppFile, string csFile, bool is32bit)
        {
            _cppFile = cppFile;
            _is32bit = is32bit;

            try {
                if (_src != null)
                {
                    throw new Exception("cannot call Convert multiple times. Create new Converter instance.");
                }

                using (var reader = new StreamReader(_cppFile)) {
                    long n = reader.BaseStream.Length + 4; if (n > int.MaxValue / 4)
                    {
                        throw new Exception("file too big");
                    }
                    reader.Read(_src = new char[n], 0, (int)n);
                }

                _InitTables();
                _InitSymbols();
                _InitMaps();
                _InitCsKeywords();

                string stf = null;

                fixed(char *p = _src)
                {
                    _s0 = p;
                    _Tokenize(p);
                    _InitInterfaces();

                    //Test(); return;

                    _i = 1;
                    _ConvertAll(0);

                    //_ConvertTypedefAndTag();

                    //AOutput.Write("#define CONST:");
                    //AOutput.Write(_defineConst);
                    //AOutput.Write("#define other:");
                    //AOutput.Write(_defineOther);
                    //OutList(_defineConst.Count, _defineOther.Count);
                    //27890, 1061
                    //27659, 998
                    //27605, 983

                    _FunctionsFinally();

                    stf = _PostProcessTypesFunctionsInterfaces();
                    //AOutput.Write(stf);
                }

                string sh = @"// Windows API declarations for C#.
// Download and more info: https://www.quickmacros.com/download.html
// Don't add this file to your project. Copy-paste only declarations that you need.
// Not all declarations can be compiled without editing.
//    For example, cannot declare some struct pointer (use IntPtr instead, or in struct replace non-blittable types with IntPtr etc), cannot use undefined struct pointer/ref/out (use IntPtr instead).
// Not all declarations are correct, usually because declarations in Windows SDK files from which they have been automatically converted lack some info.
//    For example, some function parameters that should be 'out' or '[Out]' or '[In]' or array now are just 'ref', because SDK declarations didn't have proper in/out annotations. Also for this reason some parameters that should be 'string' now are 'char*'.
//    You may want to create overloads where parameters can be of more than one type.
//    You may want to add 'SetLastError=true' to DllImport attribute parameters.
// Some declarations contain pointers and therefore can be used only in 'unsafe' context, in some cases with 'fixed'. Or you can replace pointers to IntPtr.
// These declarations are for Windows 10. Some Windows API are different or missing on other Windows versions.
// In some cases need to use different declarations in 32-bit and 64-bit process. This file contains everything that is not different, + 64-bit versions, + 32-bit versions with name suffix ""__32"".

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

using Wnd = System.IntPtr; //HWND (window handle)
using LPARAM = System.IntPtr; //LPARAM, WPARAM, LRESULT, X_PTR, SIZE_T, ... (integer types of pointer size)

//add this to projects that will use these API
[module: DefaultCharSet(CharSet.Unicode)]

internal static unsafe class API
{
";

                using (var writer = new StreamWriter(csFile)) {
                    writer.Write(sh);
                    writer.Write(stf);
                    //if(_sbType.Length > 0 || _sbInterface.Length > 0) {
                    //	writer.Write("\r\n// USED TAG-TYPES\r\n");
                    //	if(_sbType.Length > 0) writer.Write(_sbType.ToString());
                    //	if(_sbInterface.Length > 0) writer.Write(_sbInterface.ToString());
                    //}
                    //writer.WriteLine("\r\n// COCLASS");
                    //writer.Write(_sbCoclass.ToString());
                    writer.WriteLine("\r\n// VARIABLE");
                    writer.Write(_sbVar.ToString());
                    writer.WriteLine("\r\n// CONSTANT\r\n");
                    _ConstantsFinally(writer);
                    writer.Write("\r\n}\r\n");
                }
            }
            //#if !TEST_SMALL
            catch (ConverterException e) {
                AOutput.Write(e);
                AWnd.FindFast(null, "QM_Editor").SendS(Api.WM_SETTEXT, 1, $"M \"api_converter_error\" A(||) {e.Message}||{_cppFile}||{e.Offset}");
                throw;
            }
            catch (Exception e) {
                AOutput.Write(e);
                AWnd.FindFast(null, "QM_Editor").SendS(Api.WM_SETTEXT, 1, $"M \"api_converter_error\" A(||) {" "}||{_cppFile}||{_Pos(_i)}");
                throw;
            }
            //#endif
            finally {
                Marshal.FreeHGlobal((IntPtr)_keywordMemory);
            }

            AOutput.Write($"DONE {(is32bit ? 32 : 64)}-bit");
        }
Example #6
0
    static void _Main()
    {
        bool isConsole = AOutput.IsConsoleProcess;

        if (!isConsole)
        {
            AOutput.QM2.UseQM2 = true;
            AOutput.Clear();
        }

        var docfx   = @"Q:\Programs\DocFx\docfx.exe";
        var objDir  = @"Q:\Temp\Au\DocFX\obj";
        var docDir  = @"Q:\app\Au\Other\DocFX\_doc";
        var siteDir = docDir + @"\_site";
        var apiDir  = docDir + @"\api";

        //ProcessYamlFile(apiDir + @"\Au.AaaDocFX.yml", true); return;
        //ProcessHtmlFiles(siteDir, true); return;
        //ProcessToc(siteDir); return;

        //Compress(docDir); return;
        //Upload(docDir); return;
        //CompressAndUpload(docDir); return;

        foreach (var v in Process.GetProcessesByName("docfx"))
        {
            v.Kill();
        }
        if (isConsole)
        {
            int k = 0;
            foreach (var v in AWnd.FindAll(@"C:\WINDOWS\system32\cmd.exe", "ConsoleWindowClass"))
            {
                if (k++ > 0)
                {
                    v.Close();
                }
            }
        }

        AFile.Delete(siteDir);
        Directory.SetCurrentDirectory(docDir);

        var t1 = ATime.PerfMilliseconds;

        using (var fw = new FileSystemWatcher(apiDir, "*.yml")) {
            fw.Changed += (sen, e) => {
                //AOutput.Write(e.Name);
                if (e.Name.Starts("Au.", true))
                {
                    ProcessYamlFile(e.FullPath, false);
                }
            };
            fw.EnableRaisingEvents = true;
            fw.NotifyFilter        = NotifyFilters.LastWrite;

            bool serving = false;
            try {
                AExec.RunConsole(o => {
                    AOutput.Write(o);
                    if (o.Starts("Serving"))
                    {
                        throw new OperationCanceledException();
                    }
                }, docfx, $@"docfx.json --intermediateFolder ""{objDir}"" --serve");
                // --force
            }
            catch (OperationCanceledException) {
                serving = true;
            }
            //if(!serving) { ADialog.Show("error?"); return; } //need if this process is not hosted
            if (!serving)
            {
                return;
            }
        }

        var t2 = ATime.PerfMilliseconds;

        ProcessHtmlFiles(siteDir, false);

        var t3 = ATime.PerfMilliseconds; AOutput.Write("speed (s):", (t2 - t1) / 1000, (t3 - t2) / 1000);

        //AWnd.Find("* Chrome").Activate();
        //AKeys.Key("F5");

        1.s();
        if (1 == ADialog.Show("Upload?", null, "1 Yes|2 No" /*, secondsTimeout: 5*/))
        {
            CompressAndUpload(docDir);
        }

        //Delete obj folder if big. Each time it grows by 10 MB, and after a day or two can be > 1 GB. After deleting builds slower by ~50%.
        if (AFile.More.CalculateDirectorySize(objDir) / 1024 / 1024 > 500)
        {
            AOutput.Write("Deleting obj folder."); AFile.Delete(objDir);
        }
        //info: if DocFX starts throwing stack overflow exception, delete the obj folder manually. It is likely to happen after many refactorings in the project.
    }
Example #7
0
 /// <summary>
 /// Sets NativeErrorCode = (winApiErrorCode != 0) ? winApiErrorCode : (w.IsAlive ? ALastError.Code : ERROR_INVALID_WINDOW_HANDLE).
 /// </summary>
 public AuWndException(AWnd w, int winApiErrorCode, string message, Exception innerException)
     : base(_Code(winApiErrorCode, w), message, innerException)
 {
     Window = w;
 }
Example #8
0
            /// <summary>
            /// Starts or stops capturing.
            /// Does nothing if already in that state.
            /// </summary>
            public void StartStop(bool start)
            {
                if (start == Capturing)
                {
                    return;
                }
                var wForm = (AWnd)_form;

                if (start)
                {
                    //let other forms stop capturing
                    wForm.Prop.Set(c_propName, 1);
                    AWnd.Find(null, "WindowsForms*", also: o => {
                        if (o != wForm && o.Prop[c_propName] == 1)
                        {
                            o.Send(c_stopMessage);
                        }
                        return(false);
                    });

                    if (!Api.RegisterHotKey(wForm, 1, 0, KKey.F3))
                    {
                        ADialog.ShowError("Failed to register hotkey F3", owner: _form);
                        return;
                    }
                    Capturing = true;

                    //set timer that shows AO rect
                    if (_timer == null)
                    {
                        _osr   = TUtil.CreateOsdRect();
                        _timer = new ATimer(t => {
                            //Don't capture too frequently.
                            //	Eg if the callback is very slow. Or if multiple timer messages are received without time interval (possible in some conditions).
                            long t1 = ATime.PerfMilliseconds, t2 = t1 - _prevTime; _prevTime = t1; if (t2 < 100)
                            {
                                return;
                            }

                            //show rect of UI object from mouse
                            AWnd w = AWnd.FromMouse(WXYFlags.NeedWindow);
                            RECT?r = default;
                            if (!(w.Is0 || w == wForm || w.OwnerWindow == wForm))
                            {
                                r = _cbGetRect();
                            }
                            if (r.HasValue)
                            {
                                var rr = r.GetValueOrDefault();
                                rr.Inflate(2, 2);                                 //2 pixels inside, 2 outside
                                _osr.Rect = rr;
                                _osr.Show();
                            }
                            else
                            {
                                _osr.Visible = false;
                            }
                        });
                    }
                    _timer.Every(250);
                }
                else
                {
                    Capturing = false;
                    Api.UnregisterHotKey(wForm, 1);
                    wForm.Prop.Remove(c_propName);
                    _timer.Stop();
                    _osr.Hide();
                }
            }
Example #9
0
 /// <summary>
 /// Sets NativeErrorCode = (winApiErrorCode != 0) ? winApiErrorCode : (w.IsAlive ? ALastError.Code : ERROR_INVALID_WINDOW_HANDLE).
 /// Sets Message = "Failed.".
 /// </summary>
 public AuWndException(AWnd w, int winApiErrorCode)
     : base(_Code(winApiErrorCode, w))
 {
     Window = w;
 }
Example #10
0
 /// <summary>
 /// Sets NativeErrorCode = w.IsAlive ? 0 : ERROR_INVALID_WINDOW_HANDLE.
 /// </summary>
 public AuWndException(AWnd w, string message, Exception innerException)
     : base(message, innerException)
 {
     Window = w; NativeErrorCode = _Code(0, w);
 }
Example #11
0
 /// <summary>
 /// Sets NativeErrorCode = w.IsAlive ? 0 : ERROR_INVALID_WINDOW_HANDLE.
 /// Sets Message = "Failed.".
 /// </summary>
 public AuWndException(AWnd w)
     : base()
 {
     Window = w; NativeErrorCode = _Code(0, w);
 }
Example #12
0
 void TriggerActionExample2(AWnd w)
 {
     AOutput.Write("TriggerActionExample2", w);
 }
Example #13
0
    /// <summary>
    /// Processes command line of this program.
    /// Returns true if this instance must exit: 1. If finds previous program instance; then sends the command line to it if need. 2. If incorrect command line.
    /// </summary>
    public static bool OnProgramStarted(string[] a)
    {
        string s           = null;
        int    cmd         = 0;
        bool   activateWnd = true;

        if (a.Length > 0)
        {
            //AOutput.Write(a);

            for (int i = 0; i < a.Length; i++)
            {
                if (a[i].Starts('-'))
                {
                    a[i] = a[i].ReplaceAt(0, 1, "/");
                }
                if (a[i].Starts('/'))
                {
                    a[i] = a[i].Lower();
                }
            }

            s = a[0];
            if (s.Starts('/'))
            {
                for (int i = 0; i < a.Length; i++)
                {
                    s = a[i];
                    switch (s)
                    {
                    case "/test":
                        if (++i < a.Length)
                        {
                            TestArg = a[i];
                        }
                        break;

                    case "/v":
                        StartVisible = true;
                        break;

                    default:
                        ADialog.ShowError("Unknown command line parameter", s);
                        return(true);
                    }
                    //rejected: /h start hidden. Not useful.
                }
            }
            else                 //one or more files
            {
                if (a.Length == 1 && FilesModel.IsWorkspaceDirectory(s))
                {
                    switch (cmd = ADialog.Show("Workspace", s, "1 Open|2 Import|0 Cancel", footerText: FilesModel.GetSecurityInfo("v|")))
                    {
                    case 1: WorkspaceDirectory = s; break;

                    case 2: _importWorkspace = s; break;
                    }
                }
                else
                {
                    cmd          = 3;
                    _importFiles = a;
                }
            }
        }

        //single instance
        s_mutex = new Mutex(true, "Au.Mutex.1", out bool createdNew);
        if (createdNew)
        {
            return(false);
        }

        var w = AWnd.FindFast(null, "Au.Editor.Msg", true);

        if (!w.Is0)
        {
            if (activateWnd)
            {
                AWnd wMain = (AWnd)w.Send(Api.WM_USER);
                if (!wMain.Is0)
                {
                    try { wMain.Activate(); }
                    catch (Exception ex) { ADebug.Print(ex); }
                }
            }

            switch (cmd)
            {
            case 3:             //import files
                s = string.Join("\0", a);
                break;
            }
            if (cmd != 0)
            {
                AWnd.More.CopyDataStruct.SendString(w, cmd, s);
            }
        }
        return(true);
    }
Example #14
0
 /// <summary>
 /// Returns true if window class name starts with "WindowsForms".
 /// Usually it means that we can get Windows Forms control name of w and its child controls.
 /// </summary>
 /// <param name="w">The window. Can be top-level or control.</param>
 public static bool IsWinFormsControl(AWnd w)
 {
     return(w.ClassNameIs("WindowsForms*"));
 }
Example #15
0
 //Adds nonclient space at the right, to draw our buttons.
 void _OnNcCalcSize(AWnd w, int msg, LPARAM wParam, LPARAM lParam)
 {
     ref RECT r = ref *(RECT *)lParam;
Example #16
0
 internal static extern EError Cpp_AccFind(AWnd w, Cpp_Acc *aParent, in Cpp_AccParams ap, AccCallbackT also, out Cpp_Acc aResult, [MarshalAs(UnmanagedType.BStr)] out string sResult);
Example #17
0
    protected override unsafe void WndProc(ref Message m)
    {
        AWnd w = (AWnd)m.HWnd; LPARAM wParam = m.WParam, lParam = m.LParam;

        //AWnd.More.PrintMsg(m, Api.WM_ENTERIDLE, Api.WM_SETCURSOR, Api.WM_GETTEXT, Api.WM_GETTEXTLENGTH, Api.WM_GETICON, Api.WM_NCMOUSEMOVE);

        switch (m.Msg)
        {
        case RunningTasks.WM_TASK_ENDED:         //WM_USER+900
            Program.Tasks.TaskEnded2(m.WParam);
            return;

        case Api.WM_ACTIVATE:
            int isActive = AMath.LoUshort(wParam);             //0 inactive, 1 active, 2 click-active
            if (isActive == 1 && !w.IsActive && !Api.SetForegroundWindow(w))
            {
                //Normally at startup always inactive, because started as admin from task scheduler. SetForegroundWindow sometimes works, sometimes not.
                //workaround for: If clicked a window after our app started but before w activated, w is at Z bottom and in some cases without taskbar button.
                ADebug.Print("window inactive");
                AWnd.More.TaskbarButton.Add(w);
                if (!w.ActivateLL())
                {
                    AWnd.More.TaskbarButton.Flash(w, 5);
                }
            }
            //restore focused control correctly
            if (isActive == 0)
            {
                _wFocus = AWnd.ThisThread.Focused;
            }
            else if (_wFocus.IsAlive)
            {
                AWnd.ThisThread.Focus(_wFocus);
            }
            return;

        case Api.WM_SYSCOMMAND:
            int sc = (int)wParam;
            if (sc >= 0xf000)              //system
            {
                sc &= 0xfff0;
                if (sc == Api.SC_CLOSE && Visible && Program.Settings.runHidden)
                {
                    this.WindowState = FormWindowState.Minimized;
                    this.Visible     = false;
                    EdUtil.MinimizeProcessPhysicalMemory(500);
                    return;
                    //initially this code was in OnFormClosing, but sometimes hides instead of closing, because .NET gives incorrect CloseReason. Cannot reproduce and debug.
                }
            }
            else                 //our
            {
                switch (sc)
                {
                case c_menuid_Exit: Strips.Cmd.File_Exit(); return;
                }
            }
            break;

        case Api.WM_POWERBROADCAST:
            if (wParam == 4)
            {
                Program.Tasks.EndTask();                         //PBT_APMSUSPEND
            }
            break;

        case Api.WM_WINDOWPOSCHANGING:
            var p = (Api.WINDOWPOS *)lParam;
            //AOutput.Write(p->flags);
            //workaround: if started maximized, does not receive WM_SHOWWINDOW. Then .NET at first makes visible, then creates controls and calls OnLoad.
            if (p->flags.Has(Native.SWP.SHOWWINDOW) && Program.Loaded == EProgramState.LoadedWorkspace)
            {
                //p->flags &= ~Native.SWP.SHOWWINDOW; //no, adds 5 duplicate messages
                var m2 = Message.Create(m.HWnd, Api.WM_SHOWWINDOW, (IntPtr)1, default);
                base.WndProc(ref m2);                 //creates controls and calls OnLoad and OnVisibleChanged
                return;
            }
            break;
        }
Example #18
0
 /// <summary>
 /// Executes test code that finds an object in window.
 /// Returns the found object and the speed.
 /// </summary>
 /// <param name="code">
 /// Must start with one or more lines that find window or control and set AWnd variable named wndVar. Can be any code.
 /// The last line must be a 'find object' function call. Example: <c>AAcc.Find(...);</c>. Without 'var obj = ', without +, without Wait.
 /// </param>
 /// <param name="wndVar">Name of AWnd variable of the window or control in which to search.</param>
 /// <param name="wnd">Window or control in which to search.</param>
 /// <param name="bTest">The 'Test' button. This function disables it while executing code.</param>
 /// <param name="lSpeed">Label control that displays speed.</param>
 /// <param name="getRect">Callback function that returns object's rectangle in screen. Called when object has been found.</param>
 /// <remarks>
 /// The test code is executed in this thread. Else would get invalid AO etc. If need, caller can use Task.Run.
 /// </remarks>
 /// <example>
 /// <code><![CDATA[
 /// var r = await TUtil.RunTestFindObject(code, _wndVar, _wnd, _bTest, _lSpeed, o => (o as AAcc).Rect);
 /// ]]></code>
 /// </example>
 public static TestFindObjectResults RunTestFindObject(
     string code, string wndVar, AWnd wnd, Button bTest, Label lSpeed, Func <object, RECT> getRect, bool activateWindow = false)
 {
     if (code.NE())
     {
         return(default);
Example #19
0
partial class Script : AScript { [STAThread] static void Main(string[] a) => new Script(a); Script(string[] args) { //;;;

/*
The programming language is C#.

In scripts you can use classes/functions of the automation library provided by
this program, as well as of .NET Core and everything that can be used in C#.
Also you can create and use new functions, classes, libraries and .exe programs.

Script properties are saved in /*/ /*/ comments at the very start of script.
You can change them in the Properties dialog.

Like all C# programs, a script starts with standard code: using directives,
class and function Main where the program starts. Click the small [+] box at
the top-left to see and edit that code when need. The //. and //; are used to
fold (hide) code.

To avoid 'static' everywhere, function Main creates a class instance. Your script
code is in the constructor function. The function and the class end with } and }.

To run a script, you can click the ► Run button on the toolbar, or use command line,
or call ATask.Run from another scrit, or in Options set to run at startup.

Triggers such as hotkeys, autotext, mouse and window are used to execute functions
in a running script. Also you can create custom toolbars and menus. To start
using them: menu File -> New -> Examples -> @Triggers and toolbars.
*/

//Examples of automation functions.

AOutput.Write("Main script code.");

ADialog.Show("Message box.");

AExec.Run(AFolders.System + "notepad.exe");
var w = AWnd.Wait(0, true, "*- Notepad");
AKeys.Key("F5 Enter*2");
AKeys.Text(w.Name);
2.s();
w.Close();
var w2 = AWnd.Wait(-3, true, "Notepad", "#32770");
if(!w2.Is0) {
	500.ms();
	var c = +w2.Child(null, "Button", skip: 1); // "Don't Save"
	AMouse.Click(c);
	500.ms();
}

//Examples of .NET functions.

string s = "Example";
var b = new System.Text.StringBuilder();
for(int i = 0; i < s.Length; i++) {
	b.Append(s[i]).AppendLine();
}
MessageBox.Show(b.ToString());

//Example of your function and how functions can share variables.

_sharedVariable = 1;
FunctionExample("Example");
AOutput.Write(_sharedVariable);

} //end of main function