예제 #1
0
        private void FinalizeRecording()
        {
            string sequenceComment = $"Web Sequence Recorded {DateTime.Now}";

            dynamic commentCommand = TypeMethods.CreateTypeInstance(_container, "AddCodeCommentCommand");

            commentCommand.v_Comment = sequenceComment;

            dynamic closeBrowserCommand = TypeMethods.CreateTypeInstance(_container, "SeleniumCloseBrowserCommand");

            closeBrowserCommand.v_InstanceName = _browserInstanceName;

            dynamic sequenceCommand = TypeMethods.CreateTypeInstance(_container, "SequenceCommand");

            sequenceCommand.ScriptActions = _sequenceCommandList;
            sequenceCommand.v_Comment     = sequenceComment;

            CallBackForm.AddCommandToListView(commentCommand);

            if (_browserEngineType != "None")
            {
                CallBackForm.AddCommandToListView((ScriptCommand)_createBrowserCommand);
            }

            CallBackForm.AddCommandToListView(sequenceCommand);

            if (_browserEngineType != "None")
            {
                CallBackForm.AddCommandToListView(closeBrowserCommand);
            }
        }
 private void BuildNavigateToURLCommand(string url)
 {
     dynamic navigateToURLCommand = TypeMethods.CreateTypeInstance(_container, "SeleniumNavigateToURLCommand");
     navigateToURLCommand.v_InstanceName = _browserInstanceName;
     navigateToURLCommand.v_URL = url;
     _sequenceCommandList.Add(navigateToURLCommand);
 }
예제 #3
0
        private void BuildActivateWindowCommand()
        {
            dynamic activateWindowCommand = TypeMethods.CreateTypeInstance(_container, "ActivateWindowCommand");

            activateWindowCommand.v_WindowName = WindowName;

            _sequenceCommandList.Add(activateWindowCommand);
        }
 private void BuildElementClickActionCommand(string clickType)
 {
     dynamic clickElementActionCommand = TypeMethods.CreateTypeInstance(_container, "SeleniumElementActionCommand");
     clickElementActionCommand.v_InstanceName = _browserInstanceName;
     clickElementActionCommand.v_SeleniumSearchParameters = SearchParameters;
     clickElementActionCommand.v_SeleniumElementAction = clickType;
     _sequenceCommandList.Add(clickElementActionCommand);
 }
예제 #5
0
 private void pbForward_Click(object sender, EventArgs e)
 {
     wbElementRecorder.GoForward();
     if (IsRecordingSequence && _isRecording)
     {
         dynamic navigateForwardBrowserCommand = TypeMethods.CreateTypeInstance(_container, "SeleniumNavigateForwardCommand");
         navigateForwardBrowserCommand.v_InstanceName = _browserInstanceName;
         _sequenceCommandList.Add(navigateForwardBrowserCommand);
     }
 }
예제 #6
0
 private void pbRefresh_Click(object sender, EventArgs e)
 {
     wbElementRecorder.Reload();
     if (IsRecordingSequence && _isRecording)
     {
         dynamic refreshBrowserCommand = TypeMethods.CreateTypeInstance(_container, "SeleniumRefreshCommand");
         refreshBrowserCommand.v_InstanceName = _browserInstanceName;
         _sequenceCommandList.Add(refreshBrowserCommand);
     }
 }
예제 #7
0
        public void CreateOpenBotsProject(string mainScriptName, string mainScriptPath)
        {
            //create OpenBots specific project
            UIListView mainScriptActions = NewLstScriptActions(mainScriptName);

            List <ScriptVariable> mainScriptVariables = new List <ScriptVariable>();
            List <ScriptArgument> mainScriptArguments = new List <ScriptArgument>();
            List <ScriptElement>  mainScriptElements  = new List <ScriptElement>();
            Dictionary <string, List <AssemblyReference> > mainImportedNamespaces = new Dictionary <string, List <AssemblyReference> >(ScriptDefaultNamespaces.DefaultNamespaces);

            try
            {
                dynamic helloWorldCommand = TypeMethods.CreateTypeInstance(AContainer, "ShowMessageCommand");
                helloWorldCommand.v_Message = "\"Hello World\"";
                mainScriptActions.Items.Insert(0, CreateScriptCommandListViewItem(helloWorldCommand));
            }
            catch (Exception)
            {
                var brokenHelloWorldCommand = new BrokenCodeCommentCommand();
                brokenHelloWorldCommand.v_Comment = "Hello World";
                mainScriptActions.Items.Insert(0, CreateScriptCommandListViewItem(brokenHelloWorldCommand));
            }

            //begin saving as main.xml
            ClearSelectedListViewItems();

            try
            {
                //serialize main script
                EngineContext engineContext = new EngineContext
                {
                    Variables          = mainScriptVariables,
                    Arguments          = mainScriptArguments,
                    Elements           = mainScriptElements,
                    ImportedNamespaces = mainImportedNamespaces,
                    FilePath           = mainScriptPath,
                    Container          = AContainer
                };

                var mainScript = Script.SerializeScript(mainScriptActions.Items, engineContext);

                _mainFileName = ScriptProject.Main;

                OpenOpenBotsFile(mainScriptPath);
            }
            catch (Exception ex)
            {
                Notify("An Error Occurred: " + ex.Message, Color.Red);
            }
        }
예제 #8
0
        //build pause command
        private static void BuildPauseCommand()
        {
            if (_stopWatch.ElapsedMilliseconds < 1)
            {
                return;
            }

            _stopWatch.Stop();
            var pauseTime = _stopWatch.ElapsedMilliseconds;

            dynamic pauseCommand = TypeMethods.CreateTypeInstance(_container, "PauseScriptCommand");

            pauseCommand.v_PauseLength = pauseTime.ToString();
            GeneratedCommands.Add(pauseCommand);
            _stopWatch.Restart();
        }
예제 #9
0
        private void FinalizeRecording()
        {
            string sequenceComment = $"Advanced UI Sequence Recorded {DateTime.Now}";

            dynamic commentCommand = TypeMethods.CreateTypeInstance(_container, "AddCodeCommentCommand");

            commentCommand.v_Comment = sequenceComment;

            dynamic sequenceCommand = TypeMethods.CreateTypeInstance(_container, "SequenceCommand");

            sequenceCommand.ScriptActions = _sequenceCommandList;
            sequenceCommand.v_Comment     = sequenceComment;

            CallBackForm.AddCommandToListView(commentCommand);
            CallBackForm.AddCommandToListView(sequenceCommand);
        }
예제 #10
0
        public static bool BuildSendAdvancedKeystrokesCommand(Keys key, List <ScriptCommand> commandList, string windowName, bool isOnlyKeyDown = false)
        {
            if ((commandList.Count > 1) && (commandList[commandList.Count - 1] is ISendAdvancedKeystrokesCommand) &&
                (commandList[commandList.Count - 1] as ISendAdvancedKeystrokesCommand).v_KeyActions.Rows.Count > 0 && !isOnlyKeyDown)
            {
                DataTable previousKeyActionsDT = (commandList[commandList.Count - 1] as ISendAdvancedKeystrokesCommand).v_KeyActions;
                int       keyCount             = previousKeyActionsDT.Rows.Count;
                var       lastPressedKeyName   = previousKeyActionsDT.Rows[keyCount - 1].ItemArray[0].ToString().Split('[', ']')[1];
                Keys      lastPressedKey       = (Keys)Enum.Parse(typeof(Keys), lastPressedKeyName);

                //check that another key is down and that it isn't a shift + letter combination
                if (IsKeyDown(lastPressedKey) && !(IsKeyDown(Keys.ShiftKey) && key.ToString().Length == 1))
                {
                    DataRow newKeyStrokeRow = previousKeyActionsDT.NewRow();
                    newKeyStrokeRow["Key"]    = $"{CommonMethods.GetKeyDescription(key)} [{key}]";
                    newKeyStrokeRow["Action"] = "Key Down";
                    previousKeyActionsDT.Rows.Add(newKeyStrokeRow);
                    return(true);
                }
                else
                {
                    bool result = BuildSendAdvancedKeystrokesCommand(key, commandList, windowName, true);
                    return(result);
                }
            }
            else if (key.ToString().Length > 1)
            {
                dynamic sendAdvancedKeystrokesCommand = TypeMethods.CreateTypeInstance(_container, "SendAdvancedKeystrokesCommand");
                sendAdvancedKeystrokesCommand.v_WindowName   = windowName;
                sendAdvancedKeystrokesCommand.v_KeyUpDefault = "Yes";
                sendAdvancedKeystrokesCommand.v_Comment      = "Typed in Window: " + windowName;

                DataTable newkeyActionaDT = sendAdvancedKeystrokesCommand.v_KeyActions;
                DataRow   newKeyStrokeRow = newkeyActionaDT.NewRow();
                newKeyStrokeRow["Key"]    = $"{CommonMethods.GetKeyDescription(key)} [{key}]";
                newKeyStrokeRow["Action"] = "Key Down";
                newkeyActionaDT.Rows.Add(newKeyStrokeRow);

                commandList.Add(sendAdvancedKeystrokesCommand);

                return(true);
            }
            else
            {
                return(false);
            }
        }
예제 #11
0
        private void BuildElementClickActionCommand(string clickType)
        {
            dynamic clickElementActionCommand = TypeMethods.CreateTypeInstance(_container, "UIAutomationCommand");

            clickElementActionCommand.v_WindowName          = WindowName;
            clickElementActionCommand.v_UIASearchParameters = SearchParameters;
            clickElementActionCommand.v_AutomationType      = "Click Element";

            DataTable webActionDT  = clickElementActionCommand.v_UIAActionParameters;
            DataRow   clickTypeRow = webActionDT.NewRow();

            clickTypeRow["Parameter Name"]  = "Click Type";
            clickTypeRow["Parameter Value"] = clickType;
            webActionDT.Rows.Add(clickTypeRow);

            _sequenceCommandList.Add(clickElementActionCommand);

            _stopwatch.Restart();
        }
예제 #12
0
        private void pbRecord_Click(object sender, EventArgs e)
        {
            // this.WindowState = FormWindowState.Minimized;
            if (!_isRecording)
            {
                _isRecording = true;

                SearchParameters = NewSearchParameterDataTable();

                //clear all
                SearchParameters.Rows.Clear();

                //get window name and find window
                WindowName = cboWindowTitle.Text;
                IntPtr hWnd = User32Functions.FindWindow(WindowName);

                if (IsRecordingSequence && _isFirstRecordClick)
                {
                    _isFirstRecordClick  = false;
                    _sequenceCommandList = new List <ScriptCommand>();

                    frmThickAppElementRecorderSettings settingsForm = new frmThickAppElementRecorderSettings();
                    settingsForm.ShowDialog();

                    if (settingsForm.DialogResult == DialogResult.OK)
                    {
                        _parameterSettings = settingsForm.ParameterSettingsDT;
                        settingsForm.Dispose();
                    }
                    else
                    {
                        _isRecording        = false;
                        _isFirstRecordClick = true;

                        lblDescription.Text = "Instructions: Select the target window name from the drop-down " +
                                              "list and click the record button. Once recording has started, click " +
                                              "the element in the target application that you want to capture.";

                        //remove wait for left mouse down event
                        GlobalHook.MouseEvent   -= GlobalHook_MouseEvent;
                        GlobalHook.KeyDownEvent -= GlobalHook_KeyDownEvent;
                        GlobalHook.HookStopped  -= GlobalHook_HookStopped;

                        settingsForm.Dispose();
                        return;
                    }

                    dynamic activateWindowCommand = TypeMethods.CreateTypeInstance(_container, "ActivateWindowCommand");
                    activateWindowCommand.v_WindowName = WindowName;
                    _sequenceCommandList.Add(activateWindowCommand);
                }

                //check if window is found
                if (hWnd != IntPtr.Zero)
                {
                    //set window state and move to 0,0
                    User32Functions.ActivateWindow(WindowName);
                    User32Functions.SetWindowPosition(hWnd, 0, 0);

                    //start global hook and wait for left mouse down event
                    GlobalHook.StartEngineCancellationHook(Keys.F2);
                    GlobalHook.HookStopped += GlobalHook_HookStopped;
                    GlobalHook.StartElementCaptureHook(chkStopOnClick.Checked, _container);
                    GlobalHook.MouseEvent   += GlobalHook_MouseEvent;
                    GlobalHook.KeyDownEvent += GlobalHook_KeyDownEvent;
                }

                if (!chkStopOnClick.Checked)
                {
                    lblDescription.Text = _recordingMessage;
                    MoveFormToBottomRight(this);
                }
                else
                {
                    WindowState = FormWindowState.Minimized;
                }
            }
            else
            {
                _isRecording = false;
                if (!chkStopOnClick.Checked)
                {
                    lblDescription.Text = "Recording has stopped. Press F2 to save and close.";
                }
            }
        }
예제 #13
0
        private void BuildElementSetTextActionCommand(Keys key)
        {
            bool toUpperCase = false;

            //determine if casing is needed
            if (GlobalHook.IsKeyDown(Keys.ShiftKey) && GlobalHook.IsKeyToggled(Keys.Capital))
            {
                toUpperCase = false;
            }
            else if (!GlobalHook.IsKeyDown(Keys.ShiftKey) && GlobalHook.IsKeyToggled(Keys.Capital))
            {
                toUpperCase = true;
            }
            else if (GlobalHook.IsKeyDown(Keys.ShiftKey) && !GlobalHook.IsKeyToggled(Keys.Capital))
            {
                toUpperCase = true;
            }
            else if (!GlobalHook.IsKeyDown(Keys.ShiftKey) && !GlobalHook.IsKeyToggled(Keys.Capital))
            {
                toUpperCase = false;
            }

            var buf           = new StringBuilder(256);
            var keyboardState = new byte[256];

            if (toUpperCase)
            {
                keyboardState[(int)Keys.ShiftKey] = 0xff;
            }

            GlobalHook.ToUnicode((uint)key, 0, keyboardState, buf, 256, 0);
            var selectedKey = buf.ToString();

            //translate key press to sendkeys identifier
            if (key.ToString() == GlobalHook.StopHookKey)
            {
                //STOP HOOK
                GlobalHook.StopHook();
                GlobalHook.HookStopped  -= GlobalHook_HookStopped;
                GlobalHook.MouseEvent   -= GlobalHook_MouseEvent;
                GlobalHook.KeyDownEvent -= GlobalHook_KeyDownEvent;
                return;
            }
            else
            {
                bool result = GlobalHook.BuildSendAdvancedKeystrokesCommand(key, _sequenceCommandList, WindowName);
                if (result)
                {
                    return;
                }
            }

            //generate sendkeys together
            if ((_sequenceCommandList.Count > 1) && (_sequenceCommandList[_sequenceCommandList.Count - 1] is IUIAutomationCommand) &&
                (_sequenceCommandList[_sequenceCommandList.Count - 1] as IUIAutomationCommand).v_AutomationType == "Set Text")
            {
                var lastCreatedSendKeysCommand = (IUIAutomationCommand)_sequenceCommandList[_sequenceCommandList.Count - 1];

                //append chars to previously created command
                //this makes editing easier for the user because only 1 command is issued rather than multiples
                var previouslyInputChars = lastCreatedSendKeysCommand.v_UIAActionParameters.Rows[0][1].ToString();
                lastCreatedSendKeysCommand.v_UIAActionParameters.Rows[0][1] = previouslyInputChars + selectedKey;
            }
            else
            {
                //build keyboard command
                dynamic setTextElementActionCommand = TypeMethods.CreateTypeInstance(_container, "UIAutomationCommand");
                setTextElementActionCommand.v_WindowName          = WindowName;
                setTextElementActionCommand.v_UIASearchParameters = SearchParameters;
                setTextElementActionCommand.v_AutomationType      = "Set Text";

                DataTable webActionDT  = setTextElementActionCommand.v_UIAActionParameters;
                DataRow   textToSetRow = webActionDT.NewRow();
                textToSetRow["Parameter Name"]  = "Text To Set";
                textToSetRow["Parameter Value"] = selectedKey;
                webActionDT.Rows.Add(textToSetRow);

                _sequenceCommandList.Add(setTextElementActionCommand);
            }
        }
        private void tsmiNewScriptFile_Click(object sender, EventArgs e)
        {
            try
            {
                string newName     = "";
                var    newNameForm = new frmInputBox("Enter the name of the new file WITH extension", "New File");

                switch (ScriptProject.ProjectType)
                {
                case ProjectType.OpenBots:
                    newNameForm.txtInput.Text = ".obscript";
                    break;

                case ProjectType.Python:
                    newNameForm.txtInput.Text = ".py";
                    break;

                case ProjectType.TagUI:
                    newNameForm.txtInput.Text = ".tag";
                    break;

                case ProjectType.CSScript:
                    newNameForm.txtInput.Text = ".cs";
                    break;
                }

                newNameForm.ShowDialog();

                if (newNameForm.DialogResult == DialogResult.OK)
                {
                    newName = newNameForm.txtInput.Text;
                    newNameForm.Dispose();
                }
                else if (newNameForm.DialogResult == DialogResult.Cancel)
                {
                    newNameForm.Dispose();
                    return;
                }

                if (!Path.HasExtension(newName))
                {
                    throw new FileFormatException($"No extension provided for '{newName}'");
                }

                string selectedNodePath = tvProject.SelectedNode.Tag.ToString();
                string newFilePath      = Path.Combine(selectedNodePath, newName);
                string extension        = Path.GetExtension(newFilePath);

                if (File.Exists(newFilePath))
                {
                    int    count         = 1;
                    string newerFilePath = newFilePath;
                    while (File.Exists(newerFilePath))
                    {
                        string newDirectoryPath            = Path.GetDirectoryName(newFilePath);
                        string newFileNameWithoutExtension = Path.GetFileNameWithoutExtension(newFilePath);
                        newerFilePath = Path.Combine(newDirectoryPath, $"{newFileNameWithoutExtension} ({count}){extension}");
                        count        += 1;
                    }

                    newFilePath = newerFilePath;
                }

                switch (extension.ToLower())
                {
                case ".obscript":
                    UIListView            newScriptActions   = NewLstScriptActions();
                    List <ScriptVariable> newScriptVariables = new List <ScriptVariable>();
                    List <ScriptArgument> newScriptArguments = new List <ScriptArgument>();
                    List <ScriptElement>  newScriptElements  = new List <ScriptElement>();

                    try
                    {
                        dynamic helloWorldCommand = TypeMethods.CreateTypeInstance(AContainer, "ShowMessageCommand");
                        helloWorldCommand.v_Message = "Hello World";
                        newScriptActions.Items.Insert(0, CreateScriptCommandListViewItem(helloWorldCommand));
                    }
                    catch (Exception)
                    {
                        var brokenHelloWorldCommand = new BrokenCodeCommentCommand();
                        brokenHelloWorldCommand.v_Comment = "Hello World";
                        newScriptActions.Items.Insert(0, CreateScriptCommandListViewItem(brokenHelloWorldCommand));
                    }

                    EngineContext engineContext = new EngineContext
                    {
                        Variables = newScriptVariables,
                        Arguments = newScriptArguments,
                        Elements  = newScriptElements,
                        FilePath  = newFilePath,
                        Container = AContainer
                    };

                    Script.SerializeScript(newScriptActions.Items, engineContext);
                    NewNode(tvProject.SelectedNode, newFilePath, "file");
                    OpenOpenBotsFile(newFilePath);
                    break;

                case ".py":
                    File.WriteAllText(newFilePath, _helloWorldTextPython);
                    NewNode(tvProject.SelectedNode, newFilePath, "file");
                    OpenTextEditorFile(newFilePath, ProjectType.Python);
                    break;

                case ".tag":
                    File.WriteAllText(newFilePath, _helloWorldTextTagUI);
                    NewNode(tvProject.SelectedNode, newFilePath, "file");
                    OpenTextEditorFile(newFilePath, ProjectType.TagUI);
                    break;

                case ".cs":
                    File.WriteAllText(newFilePath, _helloWorldTextCSScript);
                    NewNode(tvProject.SelectedNode, newFilePath, "file");
                    OpenTextEditorFile(newFilePath, ProjectType.CSScript);
                    break;

                default:
                    File.Create(newFilePath).Close();
                    NewNode(tvProject.SelectedNode, newFilePath, "file");
                    return;
                }
            }
            catch (Exception ex)
            {
                Notify("An Error Occured: " + ex.Message, Color.Red);
            }
        }
        private void lstScriptActions_DragDrop(object sender, DragEventArgs e)
        {
            //returns the location of the mouse pointer in the ListView control
            Point cp = SelectedTabScriptActions.PointToClient(new Point(e.X, e.Y));

            //obtain the item that is located at the specified location of the mouse pointer
            ListViewItem dragToItem = SelectedTabScriptActions.GetItemAt(cp.X, cp.Y);

            if (e.Data.GetDataPresent("System.Windows.Forms.TreeNode", false))
            {
                TreeNode commandNode = ((TreeNode)e.Data.GetData("System.Windows.Forms.TreeNode"));

                if (commandNode.Nodes.Count != 0)
                {
                    return;
                }

                var commandName      = commandNode.Text;
                var commandGroupName = commandNode.Parent.Text;

                var newCommandName = _automationCommands.Where(x => x.ShortName == commandName && x.DisplayGroup == commandGroupName)
                                     .Select(x => x.Command).FirstOrDefault().GetType();

                dynamic newCommandInstance = TypeMethods.CreateTypeInstance(AContainer, newCommandName.Name);

                CreateUndoSnapshot();
                if (dragToItem != null)
                {
                    AddCommandToListView(newCommandInstance, dragToItem.Index);
                }
                else
                {
                    AddCommandToListView(newCommandInstance, SelectedTabScriptActions.Items.Count);
                }
            }
            else
            {
                //return if the items are not selected in the ListView control
                if (SelectedTabScriptActions.SelectedItems.Count == 0)
                {
                    return;
                }

                CreateUndoSnapshot();

                if (dragToItem == null)
                {
                    return;
                }

                List <ScriptCommand> commandsToMove = new List <ScriptCommand>();

                for (int i = 0; i <= SelectedTabScriptActions.SelectedItems.Count - 1; i++)
                {
                    var command = (ScriptCommand)SelectedTabScriptActions.SelectedItems[i].Tag;
                    commandsToMove.Add(command);
                }

                //obtain the index of the item at the mouse pointer
                int dragIndex = dragToItem.Index;

                ListViewItem[] sel = new ListViewItem[SelectedTabScriptActions.SelectedItems.Count];
                for (int i = 0; i <= SelectedTabScriptActions.SelectedItems.Count - 1; i++)
                {
                    sel[i] = SelectedTabScriptActions.SelectedItems[i];
                }
                for (int i = 0; i < sel.GetLength(0); i++)
                {
                    //obtain the ListViewItem to be dragged to the target location
                    ListViewItem dragItem  = sel[i];
                    int          itemIndex = dragIndex;
                    if (itemIndex == dragItem.Index)
                    {
                        return;
                    }
                    if (dragItem.Index < itemIndex)
                    {
                        itemIndex++;
                    }
                    else
                    {
                        itemIndex = dragIndex + i;
                    }

                    //insert the item at the mouse pointer
                    ListViewItem insertItem = (ListViewItem)dragItem.Clone();
                    SelectedTabScriptActions.Items.Insert(itemIndex, insertItem);

                    //removes the item from the initial location while the item is moved to the new location
                    SelectedTabScriptActions.Items.Remove(dragItem);
                    SelectedTabScriptActions.Invalidate();
                }
            }
        }
        public void AddCommandToListView(ScriptCommand selectedCommand, int index = -1)
        {
            if (!uiScriptTabControl.SelectedTab.Controls[0].Visible)
            {
                uiScriptTabControl.SelectedTab.Controls[0].Show();
            }

            ListViewItem command;

            //valid command verification for drag/dropped commands
            if (selectedCommand != null)
            {
                command = CreateScriptCommandListViewItem(selectedCommand);
            }
            else
            {
                return;
            }

            int insertionIndex;

            if (index == -1)
            {
                //insert to end by default
                insertionIndex = SelectedTabScriptActions.Items.Count;

                //verify setting to insert inline is selected and if an item is currently selected
                if ((_appSettings.ClientSettings.InsertCommandsInline) && (SelectedTabScriptActions.SelectedItems.Count > 0))
                {
                    //insert inline
                    insertionIndex = SelectedTabScriptActions.SelectedItems[0].Index + 1;
                }
            }
            else
            {
                insertionIndex = index;
            }

            //insert command
            SelectedTabScriptActions.Items.Insert(insertionIndex, command);
            ClearSelectedListViewItems();
            command.Selected = true;

            //special types also get a following command and comment
            if ((selectedCommand.CommandName == "LoopCollectionCommand") || (selectedCommand.CommandName == "LoopContinuouslyCommand") ||
                (selectedCommand.CommandName == "LoopNumberOfTimesCommand") || (selectedCommand.CommandName == "BeginLoopCommand") ||
                (selectedCommand.CommandName == "BeginMultiLoopCommand"))
            {
                dynamic addCodeCommentCommand = TypeMethods.CreateTypeInstance(AContainer, "AddCodeCommentCommand");
                addCodeCommentCommand.v_Comment = "Items in this section will run within the loop";
                SelectedTabScriptActions.Items.Insert(insertionIndex + 1, CreateScriptCommandListViewItem(addCodeCommentCommand));

                dynamic endLoopCommand = TypeMethods.CreateTypeInstance(AContainer, "EndLoopCommand");
                SelectedTabScriptActions.Items.Insert(insertionIndex + 2, CreateScriptCommandListViewItem(endLoopCommand));
            }
            else if ((selectedCommand.CommandName == "BeginIfCommand") || (selectedCommand.CommandName == "BeginMultiIfCommand"))
            {
                dynamic addCodeCommentCommand = TypeMethods.CreateTypeInstance(AContainer, "AddCodeCommentCommand");
                addCodeCommentCommand.v_Comment = "Items in this section will run if the statement is true";
                SelectedTabScriptActions.Items.Insert(insertionIndex + 1, CreateScriptCommandListViewItem(addCodeCommentCommand));

                dynamic endIfCommand = TypeMethods.CreateTypeInstance(AContainer, "EndIfCommand");
                SelectedTabScriptActions.Items.Insert(insertionIndex + 2, CreateScriptCommandListViewItem(endIfCommand));
            }
            else if (selectedCommand.CommandName == "BeginTryCommand")
            {
                dynamic addCodeCommentCommand = TypeMethods.CreateTypeInstance(AContainer, "AddCodeCommentCommand");
                addCodeCommentCommand.v_Comment = "Items in this section will be handled if error occurs";
                SelectedTabScriptActions.Items.Insert(insertionIndex + 1, CreateScriptCommandListViewItem(addCodeCommentCommand));

                dynamic catchCommand = TypeMethods.CreateTypeInstance(AContainer, "CatchCommand");
                SelectedTabScriptActions.Items.Insert(insertionIndex + 2, CreateScriptCommandListViewItem(catchCommand));

                dynamic codeCommentCommand = TypeMethods.CreateTypeInstance(AContainer, "AddCodeCommentCommand");
                codeCommentCommand.v_Comment = "This section executes if error occurs above";
                SelectedTabScriptActions.Items.Insert(insertionIndex + 3, CreateScriptCommandListViewItem(codeCommentCommand));

                dynamic endTryCommand = TypeMethods.CreateTypeInstance(AContainer, "EndTryCommand");
                SelectedTabScriptActions.Items.Insert(insertionIndex + 4, CreateScriptCommandListViewItem(endTryCommand));
            }
            else if (selectedCommand.CommandName == "BeginRetryCommand")
            {
                dynamic addCodeCommentCommand = TypeMethods.CreateTypeInstance(AContainer, "AddCodeCommentCommand");
                addCodeCommentCommand.v_Comment = "Items in this section will be retried as long as the condition is not met or an error is thrown";
                SelectedTabScriptActions.Items.Insert(insertionIndex + 1, CreateScriptCommandListViewItem(addCodeCommentCommand));

                dynamic endRetryCommand = TypeMethods.CreateTypeInstance(AContainer, "EndRetryCommand");
                SelectedTabScriptActions.Items.Insert(insertionIndex + 2, CreateScriptCommandListViewItem(endRetryCommand));
            }
            else if (selectedCommand.CommandName == "BeginSwitchCommand")
            {
                dynamic caseCommand = TypeMethods.CreateTypeInstance(AContainer, "CaseCommand");
                caseCommand.v_CaseValue = "Default";
                SelectedTabScriptActions.Items.Insert(insertionIndex + 1, CreateScriptCommandListViewItem(caseCommand));

                dynamic addCodeCommentCommand = TypeMethods.CreateTypeInstance(AContainer, "AddCodeCommentCommand");
                addCodeCommentCommand.v_Comment = "Items in this section will run if no case statements match";
                SelectedTabScriptActions.Items.Insert(insertionIndex + 2, CreateScriptCommandListViewItem(addCodeCommentCommand));

                dynamic endSwitchCommand = TypeMethods.CreateTypeInstance(AContainer, "EndSwitchCommand");
                SelectedTabScriptActions.Items.Insert(insertionIndex + 3, CreateScriptCommandListViewItem(endSwitchCommand));
            }

            CreateUndoSnapshot();
            SelectedTabScriptActions.Invalidate();
            AutoSizeLineNumberColumn();
        }
예제 #17
0
        private void pbRecord_Click(object sender, EventArgs e)
        {
            if (!_isRecording)
            {
                _isRecording = true;
                TopMost      = true;
                if (!chkStopOnClick.Checked)
                {
                    lblDescription.Text = _recordingMessage;
                }

                SearchParameters = NewSearchParameterDataTable();

                //clear all
                SearchParameters.Rows.Clear();

                //start global hook and wait for left mouse down event
                GlobalHook.StartEngineCancellationHook(Keys.F2);
                GlobalHook.HookStopped += GlobalHook_HookStopped;
                GlobalHook.StartElementCaptureHook(chkStopOnClick.Checked, _container);
                wbElementRecorder.DomClick       += wbElementRecorder_DomClick;
                wbElementRecorder.DomDoubleClick += wbElementRecorder_DomDoubleClick;
                wbElementRecorder.DomKeyDown     += WbElementRecorder_DomKeyDown;

                if (IsRecordingSequence && _isFirstRecordClick)
                {
                    _isFirstRecordClick  = false;
                    _sequenceCommandList = new List <ScriptCommand>();

                    frmHTMLElementRecorderSettings settingsForm = new frmHTMLElementRecorderSettings();
                    settingsForm.txtBrowserInstanceName.Text        = "DefaultBrowser";
                    settingsForm.cbxBrowserEngineType.SelectedIndex = 0;
                    settingsForm.ShowDialog();

                    if (settingsForm.DialogResult == DialogResult.OK)
                    {
                        _browserInstanceName = settingsForm.txtBrowserInstanceName.Text;
                        _browserEngineType   = settingsForm.cbxBrowserEngineType.SelectedItem.ToString();
                        _parameterSettings   = settingsForm.ParameterSettingsDT;

                        settingsForm.Dispose();
                    }
                    else
                    {
                        _isRecording        = false;
                        _isFirstRecordClick = true;

                        lblDescription.Text = "Instructions: navigate to the target URL and click the record button. " +
                                              "Once recording has started, click the element that you want to capture.";

                        //remove wait for left mouse down event
                        wbElementRecorder.DomClick       -= wbElementRecorder_DomClick;
                        wbElementRecorder.DomDoubleClick -= wbElementRecorder_DomDoubleClick;
                        wbElementRecorder.DomKeyDown     -= WbElementRecorder_DomKeyDown;
                        GlobalHook.HookStopped           -= GlobalHook_HookStopped;

                        settingsForm.Dispose();
                        return;
                    }

                    if (_browserEngineType != "None")
                    {
                        dynamic seleniumCreateBrowserCommand = TypeMethods.CreateTypeInstance(_container, "SeleniumCreateBrowserCommand");
                        seleniumCreateBrowserCommand.v_InstanceName = _browserInstanceName;
                        seleniumCreateBrowserCommand.v_EngineType   = _browserEngineType;
                        seleniumCreateBrowserCommand.v_URL          = $"\"{wbElementRecorder.Url}\"";
                        _createBrowserCommand = seleniumCreateBrowserCommand;
                    }
                }
            }
            else
            {
                _isRecording = false;
                if (!chkStopOnClick.Checked)
                {
                    lblDescription.Text = "Recording has stopped. Press F2 to save and close.";
                }
            }
        }
예제 #18
0
        private void Import(string filePath)
        {
            try
            {
                //deserialize file
                EngineContext engineContext = new EngineContext()
                {
                    FilePath  = filePath,
                    Container = AContainer
                };
                Script deserializedScript = Script.DeserializeFile(engineContext);

                if (deserializedScript.Commands.Count == 0)
                {
                    Notify("Error Parsing File: Commands not found!", Color.Red);
                }

                //variables for comments
                var fileName    = new FileInfo(filePath).Name;
                var dateTimeNow = DateTime.Now.ToString();

                CreateUndoSnapshot();

                //comment
                dynamic addCodeCommentCommand = TypeMethods.CreateTypeInstance(AContainer, "AddCodeCommentCommand");
                addCodeCommentCommand.v_Comment = "Imported From " + fileName + " @ " + dateTimeNow;
                _selectedTabScriptActions.Items.Add(CreateScriptCommandListViewItem(addCodeCommentCommand));

                //import
                PopulateExecutionCommands(deserializedScript.Commands);
                foreach (ScriptVariable var in deserializedScript.Variables)
                {
                    if (_scriptVariables.Find(alreadyExists => alreadyExists.VariableName == var.VariableName) == null)
                    {
                        _scriptVariables.Add(var);
                    }
                }

                foreach (ScriptArgument arg in deserializedScript.Arguments)
                {
                    if (_scriptArguments.Find(alreadyExists => alreadyExists.ArgumentName == arg.ArgumentName) == null)
                    {
                        _scriptArguments.Add(arg);
                    }
                }

                foreach (ScriptElement elem in deserializedScript.Elements)
                {
                    if (_scriptElements.Find(alreadyExists => alreadyExists.ElementName == elem.ElementName) == null)
                    {
                        _scriptElements.Add(elem);
                    }
                }

                ResetVariableArgumentBindings();

                //comment
                dynamic codeCommentCommand = TypeMethods.CreateTypeInstance(AContainer, "AddCodeCommentCommand");
                codeCommentCommand.v_Comment = "End Import From " + fileName + " @ " + dateTimeNow;
                _selectedTabScriptActions.Items.Add(CreateScriptCommandListViewItem(codeCommentCommand));

                Notify("Script Imported Successfully!", Color.White);
            }
            catch (Exception ex)
            {
                //signal an error has happened
                Notify("An Error Occured: " + ex.Message, Color.Red);
            }
        }
예제 #19
0
        private void BuildElementSetTextActionCommand(uint key)
        {
            bool toUpperCase = false;

            //determine if casing is needed
            if (GlobalHook.IsKeyDown(Keys.ShiftKey) && GlobalHook.IsKeyToggled(Keys.Capital))
            {
                toUpperCase = false;
            }
            else if (!GlobalHook.IsKeyDown(Keys.ShiftKey) && GlobalHook.IsKeyToggled(Keys.Capital))
            {
                toUpperCase = true;
            }
            else if (GlobalHook.IsKeyDown(Keys.ShiftKey) && !GlobalHook.IsKeyToggled(Keys.Capital))
            {
                toUpperCase = true;
            }
            else if (!GlobalHook.IsKeyDown(Keys.ShiftKey) && !GlobalHook.IsKeyToggled(Keys.Capital))
            {
                toUpperCase = false;
            }

            var buf           = new StringBuilder(256);
            var keyboardState = new byte[256];

            if (toUpperCase)
            {
                keyboardState[(int)Keys.ShiftKey] = 0xff;
            }

            GlobalHook.ToUnicode(key, 0, keyboardState, buf, 256, 0);
            string selectedKey = buf.ToString();

            //translate key press to sendkeys identifier
            if ((Keys)Enum.ToObject(typeof(Keys), key) == GlobalHook.StopHookKey)
            {
                //STOP HOOK
                GlobalHook.StopHook();
                GlobalHook.HookStopped -= GlobalHook_HookStopped;
                return;
            }
            //check for a selenium compatible advanced key
            else if (_seleniumAdvancedKeyMap.TryGetValue(key, out string keyName))
            {
                selectedKey = $"[{keyName}]";
            }
            //return if key is neither character nor selenium compatible advanced key
            else if (selectedKey.Length > 1)
            {
                return;
            }

            //generate sendkeys together
            if ((_sequenceCommandList.Count > 1) && (_sequenceCommandList[_sequenceCommandList.Count - 1] is ISeleniumElementActionCommand) &&
                (_sequenceCommandList[_sequenceCommandList.Count - 1] as ISeleniumElementActionCommand).v_SeleniumElementAction == "Set Text")
            {
                var lastCreatedSendKeysCommand = (ISeleniumElementActionCommand)_sequenceCommandList[_sequenceCommandList.Count - 1];

                //append chars to previously created command
                //this makes editing easier for the user because only 1 command is issued rather than multiples
                var previouslyInputChars = lastCreatedSendKeysCommand.v_WebActionParameterTable.Rows[0][1].ToString();
                lastCreatedSendKeysCommand.v_WebActionParameterTable.Rows[0][1] = previouslyInputChars.Insert(previouslyInputChars.Length - 1, selectedKey);
            }
            else
            {
                dynamic setTextElementActionCommand = TypeMethods.CreateTypeInstance(_container, "SeleniumElementActionCommand");
                setTextElementActionCommand.v_InstanceName             = _browserInstanceName;
                setTextElementActionCommand.v_SeleniumSearchParameters = SearchParameters;
                setTextElementActionCommand.v_SeleniumElementAction    = "Set Text";

                DataTable webActionDT  = setTextElementActionCommand.v_WebActionParameterTable;
                DataRow   textToSetRow = webActionDT.NewRow();
                textToSetRow["Parameter Name"]  = "Text To Set";
                textToSetRow["Parameter Value"] = $"\"{selectedKey}\"";
                webActionDT.Rows.Add(textToSetRow);

                _sequenceCommandList.Add(setTextElementActionCommand);
            }
        }
예제 #20
0
        //build keyboard command
        private static void BuildKeyboardCommand(Keys key)
        {
            if (!_performKeyboardCapture)
            {
                return;
            }

            bool toUpperCase = false;

            //determine if casing is needed
            if (IsKeyDown(Keys.ShiftKey) && IsKeyToggled(Keys.Capital))
            {
                toUpperCase = false;
            }
            else if (!IsKeyDown(Keys.ShiftKey) && IsKeyToggled(Keys.Capital))
            {
                toUpperCase = true;
            }
            else if (IsKeyDown(Keys.ShiftKey) && !IsKeyToggled(Keys.Capital))
            {
                toUpperCase = true;
            }
            else if (!IsKeyDown(Keys.ShiftKey) && !IsKeyToggled(Keys.Capital))
            {
                toUpperCase = false;
            }

            var buf           = new StringBuilder(256);
            var keyboardState = new byte[256];

            if (toUpperCase)
            {
                keyboardState[(int)Keys.ShiftKey] = 0xff;
            }

            ToUnicode((uint)key, 0, keyboardState, buf, 256, 0);
            var selectedKey = buf.ToString();

            //translate key press to sendkeys identifier
            if (key.ToString() == StopHookKey)
            {
                //STOP HOOK
                StopHook();
                return;
            }
            else
            {
                bool result = BuildSendAdvancedKeystrokesCommand(key, GeneratedCommands, "Current Window");
                if (result)
                {
                    return;
                }
            }

            //generate sendkeys together
            if ((GeneratedCommands.Count > 1) && (GeneratedCommands[GeneratedCommands.Count - 1] is ISendKeystrokesCommand))
            {
                var lastCreatedSendKeysCommand = (ISendKeystrokesCommand)GeneratedCommands[GeneratedCommands.Count - 1];

                //append chars to previously created command
                //this makes editing easier for the user because only 1 command is issued rather than multiples
                var previouslyInputChars = lastCreatedSendKeysCommand.v_TextToSend;
                lastCreatedSendKeysCommand.v_TextToSend = previouslyInputChars + selectedKey;
            }
            else
            {
                //build a pause command to track pause since last command
                BuildPauseCommand();

                //build keyboard command
                dynamic keyboardCommand = TypeMethods.CreateTypeInstance(_container, "SendKeystrokesCommand");
                keyboardCommand.v_TextToSend = selectedKey;
                keyboardCommand.v_WindowName = "Current Window";
                GeneratedCommands.Add(keyboardCommand);
            }
        }
예제 #21
0
        private void FinalizeRecording()
        {
            string sequenceComment = $"UI Sequence Recorded {DateTime.Now}";

            _scriptCommandList = GlobalHook.GeneratedCommands;
            var outputList = new List <ScriptCommand>();

            if (chkGroupIntoSequence.Checked)
            {
                dynamic newSequence = TypeMethods.CreateTypeInstance(_container, "SequenceCommand");
                newSequence.v_Comment = sequenceComment;

                foreach (ScriptCommand cmd in _scriptCommandList)
                {
                    newSequence.ScriptActions.Add(cmd);
                }

                if (newSequence.ScriptActions.Count > 0)
                {
                    outputList.Add(newSequence);
                }
            }
            else if (chkGroupMovesIntoSequences.Checked)
            {
                dynamic newSequence = TypeMethods.CreateTypeInstance(_container, "SequenceCommand");
                newSequence.v_Comment = sequenceComment;

                foreach (ScriptCommand cmd in _scriptCommandList)
                {
                    if (cmd.CommandName == "SendMouseMoveCommand")
                    {
                        var sendMouseCmd = (ISendMouseMoveCommand)cmd;
                        if (sendMouseCmd.v_MouseClick != "None")
                        {
                            outputList.Add(newSequence);
                            newSequence           = TypeMethods.CreateTypeInstance(_container, "SequenceCommand");
                            newSequence.v_Comment = sequenceComment;
                            outputList.Add(cmd);
                        }
                        else
                        {
                            newSequence.ScriptActions.Add(cmd);
                        }
                    }
                    else if (cmd.CommandName == "SendKeystrokesCommand")
                    {
                        outputList.Add(newSequence);
                        newSequence           = TypeMethods.CreateTypeInstance(_container, "SequenceCommand");
                        newSequence.v_Comment = sequenceComment;
                        outputList.Add(cmd);
                    }
                    else
                    {
                        newSequence.ScriptActions.Add(cmd);
                    }
                }

                if (newSequence.ScriptActions.Count > 0)
                {
                    outputList.Add(newSequence);
                }
            }

            else
            {
                outputList = _scriptCommandList;
            }

            dynamic commentCommand = TypeMethods.CreateTypeInstance(_container, "AddCodeCommentCommand");

            commentCommand.v_Comment = sequenceComment;
            outputList.Insert(0, commentCommand);

            foreach (var cmd in outputList)
            {
                CallBackForm.AddCommandToListView(cmd);
            }

            Close();
        }
예제 #22
0
        //build window command
        private static void BuildWindowCommand(IntPtr hWinEventHook, _systemEvents @event,
                                               IntPtr hwnd, int idObject, int idChild,
                                               uint dwEventThread, uint dwmsEventTime)
        {
            switch (@event)
            {
            case _systemEvents.EventMin:
                return;

            case _systemEvents.EventMax:
                return;

            case _systemEvents.EventSystemForeGround:
                break;

            case _systemEvents.MinimizeEnd:
                return;

            case _systemEvents.MinimizeStart:
                return;

            default:
                return;
            }

            int length     = GetWindowText(hwnd, _buffer, _buffer.Capacity);
            var windowName = _buffer.ToString();

            //bypass screen recorder and Cortana (Win10) which throws errors
            if ((windowName == "Screen Recorder") || (windowName == "Cortana"))
            {
                return;
            }

            if (length > 0)
            {
                //wait additional for window to initialize
                //System.Threading.Thread.Sleep(250);
                windowName = _buffer.ToString();

                dynamic activateWindowCommand = TypeMethods.CreateTypeInstance(_container, "ActivateWindowCommand");
                activateWindowCommand.v_WindowName = windowName;
                GeneratedCommands.Add(activateWindowCommand);

                //detect if tracking window open location or activate windows to top left
                if (_trackWindowOpenLocations)
                {
                    User32Functions.GetWindowRect(hwnd, out Rect windowRect);

                    dynamic moveWindowCommand = TypeMethods.CreateTypeInstance(_container, "MoveWindowCommand");
                    moveWindowCommand.v_WindowName     = windowName;
                    moveWindowCommand.v_XMousePosition = windowRect.left.ToString();
                    moveWindowCommand.v_YMousePosition = windowRect.top.ToString();
                    GeneratedCommands.Add(moveWindowCommand);
                }
                else if (_activateWindowTopLeft)
                {
                    dynamic moveWindowCommand = TypeMethods.CreateTypeInstance(_container, "MoveWindowCommand");
                    moveWindowCommand.v_WindowName     = windowName;
                    moveWindowCommand.v_XMousePosition = "0";
                    moveWindowCommand.v_YMousePosition = "0";
                    User32Functions.SetWindowPosition(hwnd, 0, 0);
                    GeneratedCommands.Add(moveWindowCommand);
                }

                //if tracking window sizes is set
                if (_trackActivatedWindowSizes)
                {
                    //create rectangle from hwnd
                    User32Functions.GetWindowRect(hwnd, out Rect windowRect);

                    //do math to get height, etc
                    var width  = windowRect.right - windowRect.left;
                    var height = windowRect.bottom - windowRect.top;

                    //generate command to set window position
                    dynamic resizeWindowCommand = TypeMethods.CreateTypeInstance(_container, "ResizeWindowCommand");
                    resizeWindowCommand.v_WindowName  = windowName;
                    resizeWindowCommand.v_XWindowSize = width.ToString();
                    resizeWindowCommand.v_YWindowSize = height.ToString();

                    //add to list
                    GeneratedCommands.Add(resizeWindowCommand);
                }
            }
        }
예제 #23
0
        //build mouse command
        private static void BuildMouseCommand(IntPtr lParam, MouseMessages mouseMessage)
        {
            MsLlHookStruct hookStruct = (MsLlHookStruct)Marshal.PtrToStructure(lParam, typeof(MsLlHookStruct));

            string mouseEventClickType;

            switch (mouseMessage)
            {
            case MouseMessages.WmLButtonDown:
                mouseEventClickType = "Left Down";
                break;

            case MouseMessages.WmLButtonUp:
                mouseEventClickType = "Left Up";
                break;

            case MouseMessages.WmMButtonDown:
                mouseEventClickType = "Middle Down";
                break;

            case MouseMessages.WmMButtonUp:
                mouseEventClickType = "Middle Up";
                break;

            case MouseMessages.WmMouseMove:
                mouseEventClickType = "None";

                if (_lastMouseMove.ElapsedMilliseconds >= _msResolution)
                {
                    _lastMouseMove.Restart();
                }
                else
                {
                    return;
                }
                break;

            case MouseMessages.WmRButtonDown:
                mouseEventClickType = "Right Down";
                break;

            case MouseMessages.WmRButtonUp:
                mouseEventClickType = "Right Up";
                break;

            default:
                return;
            }

            //return if we do not want to capture mouse moves
            if ((!_performMouseMoveCapture) && (mouseEventClickType == "None"))
            {
                return;
            }

            //return if we do not want to capture mouse clicks
            if ((!_performMouseClickCapture) && (mouseEventClickType != "None"))
            {
                return;
            }

            if ((GeneratedCommands.Count > 1) && (GeneratedCommands[GeneratedCommands.Count - 1] is ISendMouseMoveCommand) &&
                mouseEventClickType != "None" && _stopWatch.ElapsedMilliseconds <= 500 &&
                hookStruct.Pt.X == _lastClickHookStruct.Pt.X && hookStruct.Pt.Y == _lastClickHookStruct.Pt.Y)
            {
                var lastCreatedMouseCommand = (ISendMouseMoveCommand)GeneratedCommands[GeneratedCommands.Count - 1];

                switch ((GeneratedCommands[GeneratedCommands.Count - 1] as ISendMouseMoveCommand).v_MouseClick)
                {
                case "Left Down":
                    if (mouseEventClickType == "Left Up")
                    {
                        lastCreatedMouseCommand.v_MouseClick = "Left Click";
                    }
                    break;

                case "Middle Down":
                    if (mouseEventClickType == "Middle Up")
                    {
                        lastCreatedMouseCommand.v_MouseClick = "Middle Click";
                    }
                    break;

                case "Right Down":
                    if (mouseEventClickType == "Right Up")
                    {
                        lastCreatedMouseCommand.v_MouseClick = "Right Click";
                    }
                    break;

                case "Left Click":
                    if (mouseEventClickType == "Left Down")
                    {
                        lastCreatedMouseCommand.v_MouseClick = "Left Double Click";
                    }
                    break;

                default:
                    break;
                }
            }
            else
            {
                //build a pause command to track pause since last command
                BuildPauseCommand();

                //define new mouse command
                dynamic mouseMove = TypeMethods.CreateTypeInstance(_container, "SendMouseMoveCommand");
                mouseMove.v_XMousePosition = hookStruct.Pt.X.ToString();
                mouseMove.v_YMousePosition = hookStruct.Pt.Y.ToString();
                mouseMove.v_MouseClick     = mouseEventClickType;

                if (mouseEventClickType != "None")
                {
                    IntPtr winHandle = WindowFromPoint(hookStruct.Pt);
                    _ = GetWindowText(winHandle, _buffer, _buffer.Capacity);
                    var windowName = _buffer.ToString();

                    mouseMove.v_Comment = "Clicked in Window: " + windowName;
                }

                GeneratedCommands.Add(mouseMove);
            }

            _lastClickHookStruct = hookStruct;
        }