Author Topic: Using ESC to exit a while loop?  (Read 2072 times)

0 Members and 1 Guest are viewing this topic.

sonny3g

  • Newt
  • Posts: 27
Using ESC to exit a while loop?
« on: June 01, 2018, 05:37:50 AM »
I have a program that once you establish the configuration in a dialog box you need, it asks you to select multiple points, then determines the correct block based on your configuration and the points you selected and then inserts the block.  It repeats the insert command, but not the dialog box as the configuration does not change during this session.

I need to be able to press the ESC key, or right click the mouse, to exit out of the while loop that repeats the point selection and insert portion of the routine.  At this point there is no keyboard input, just selecting points as prompted.

How do I get my program to recognize that the ESC key, or right click the mouse, has been pressed and use that to exit my while loop?

Thanks for your suggestions.

Partial code shown here:

            try
            {
                using (DBSvc.Transaction tr1 = rfmlDB.TransactionManager.StartTransaction())
                {
                    curOsmode = System.Convert.ToInt32(App.GetSystemVariable("OSMODE"));
                    curOrtho = System.Convert.ToInt32(App.GetSystemVariable("ORTHOMODE"));

                    App.SetSystemVariable("OSMODE", 2815);
                    App.SetSystemVariable("ORTHOMODE", 1);
                    tr1.Commit();
                }

                Application.EnableVisualStyles();
                App.ShowModalDialog(new frmRFML());
                cfg = frmRFML.cfgArray;
                // GetPoints and insert block until ESC or Enter selected
                while (true)
                {
                    GetPointsRFML(cfg.Levels);
                    //RFMLKeyCalc(xmHt); (future)
                    RFML_BlockName BlockNameRFML = new RFML_BlockName();
                    BlockInsert GetSupport = new BlockInsert();
                    bName = BlockNameRFML.BuildBlockName(xmHt, cfg, TGDVer);
                    GetSupport.InsertBlock(bsPoint, BlockNameRFML.BuildBlockName(xmHt, cfg, TGDVer));
                    try
                    {
                        using (DBSvc.Transaction tr2 = rfmlDB.TransactionManager.StartTransaction())
                        {
                            DBSvc.BlockTable blkTable = (DBSvc.BlockTable)tr2.GetObject(rfmlDB.BlockTableId, DBSvc.OpenMode.ForRead) as DBSvc.BlockTable;
                            if (blkTable.Has(bName))
                            {
                                Random rnd = new Random();
                                int stamp = rnd.Next();
                                string nbname = "z_" + bName + System.Convert.ToString(stamp);
                                var btr = (DBSvc.BlockTableRecord)tr2.GetObject(blkTable[bName], DBSvc.OpenMode.ForWrite);
                                btr.Name = nbname;
                            }
                            tr2.Commit();
                        }
                    }
                    catch (ArgumentException e)
                    {
                        MessageBox.Show(e.Message);
                    }

                    App.SetSystemVariable("OSMODE", curOsmode);
                    App.SetSystemVariable("ORTHOMODE", curOrtho);

                    //RFML_XmPositions.UpDateXmPosition(bName, ref xmHeight, ref xmSpread);

 

                }
            }
            catch (ArgumentException e)
            {
                MessageBox.Show(e.Message);             
            }
        }

ChrisCarlson

  • Guest
Re: Using ESC to exit a while loop?
« Reply #1 on: June 01, 2018, 09:49:50 AM »
Code - C#: [Select]
  1. HostApplicationServices.UserBreak

http://help.autodesk.com/view/OARX/2018/ENU/?guid=OREFNET-Autodesk_AutoCAD_DatabaseServices_HostApplicationServices_UserBreak

Base your loop on the value from this method

sonny3g

  • Newt
  • Posts: 27
Re: Using ESC to exit a while loop?
« Reply #2 on: June 04, 2018, 08:30:55 AM »
Thanks for the input.  I have gone to the posted sites, but I am struggling to figure out how to implement it in my code.

Jeff H

  • Needs a day job
  • Posts: 6144
Re: Using ESC to exit a while loop?
« Reply #3 on: June 04, 2018, 03:23:37 PM »
This is how I used it and also to treat a right click as an escape.
Do not show all code required for this to work but a couple notes
  • I have a system that allows mapping block names to layer names and sets it to that layer before insert(will clone it in from another drawing if needed)
  • TemporarySystemVariables  is just a class that allows setting system variables then changes them back to orginal setting when disposed
  • PerDocData(DocData) is a class that gets created with command classes that allows for storing perdoc data and gives acces to standard drawings(drawing containg layers, linetypes, textstyles, etc.) and some other thing, etc...
  • For right click escape have to watch for right click then use SendCancel to escape
Basic Insert command
Code - C#: [Select]
  1.         [CommandMethod("-INSBLK")]
  2.         public void IBCommandLine()
  3.         {
  4.             Settings.Variables.ATTDIA = false;
  5.             PromptStringOptions pso = new PromptStringOptions("\nEnter BlockName");
  6.             pso.AllowSpaces = false;
  7.             pso.UseDefaultValue = true;
  8.             pso.DefaultValue = blockName;
  9.             PromptResult pr = Ed.GetString(pso);
  10.             if (pr.Status != PromptStatus.OK) return;
  11.             blockName = pr.StringResult.ToUpper();
  12.  
  13.             try
  14.             {
  15.                 InsertBlock(blockName);
  16.             }
  17.             catch (Autodesk.AutoCAD.Runtime.Exception ex)
  18.             {
  19.                 if (ex.ErrorStatus != ErrorStatus.UserBreak)
  20.                 {
  21.                     throw;
  22.                 }
  23.             }
  24.         }
  25.  

Sets layer and passes off to built-in command
Code - C#: [Select]
  1.         /// <summary>
  2.         /// The active
  3.         /// </summary>
  4.         private bool active = false;
  5.  
  6.         /// <summary>
  7.         /// Inserts the block.
  8.         /// </summary>
  9.         /// <param name="name">The name.</param>
  10.         /// <returns></returns>
  11.  private async Task<bool> InsertBlock(string name)
  12.         {
  13.             //string layerName = Settings.Variables.CLAYER;
  14.  
  15.             using (TemporarySystemVariables tsv = new TemporarySystemVariables() { })
  16.             {
  17.                 //double scale = 1;
  18.                 tsv.TEXTEVAL = true;
  19.                 //scale = 1.0 / Db.Cannoscale.Scale;
  20.  
  21.                 using (Transaction trx = Doc.TransactionManager.StartTransaction())
  22.                 {
  23.                     if (DocData.LayerMap.ContainsKey(name))
  24.                     {
  25.                         string tempLayerName = DocData.LayerMap[name];
  26.                         LayerTable lt = Db.LayerTable();
  27.  
  28.                         if (lt.Has(tempLayerName))
  29.                         {
  30.                             LayerTableRecord ltr = lt[tempLayerName].GetDBObject<LayerTableRecord>();
  31.                             if (ltr.IsFrozen)
  32.                             {
  33.                                 Application.ShowAlertDialog(String.Format("Unfreeze {0}", tempLayerName));
  34.                                 return false;
  35.                             }
  36.                             tsv.CLAYER = tempLayerName;
  37.                         }
  38.                         else if (DocData.StandardDwg.Layers.Has(tempLayerName))
  39.                         {
  40.                             DocData.StandardDwg.Layers.WblockCloneObject(tempLayerName);
  41.                             tsv.CLAYER = tempLayerName;
  42.                         }
  43.                     }
  44.  
  45.                     trx.Commit();
  46.                 }
  47.  
  48.                 try
  49.                 {
  50.                     Ed.InitCommandVersion(2);
  51.                     active = true;
  52.                     Application.PreTranslateMessage += Application_PreTranslateMessage;
  53.                     await Ed.CommandAsync("_.-INSERT", name, Editor.PauseToken);
  54.                     Application.PreTranslateMessage -= Application_PreTranslateMessage;
  55.                     //if (active)
  56.                     //{
  57.                     //    active = false;
  58.                     //}
  59.                     await Ed.CommandAsync(1);
  60.                     while (Ed.IsDragging || Settings.Variables.CMDNAMES.ToUpper().IndexOf("INSERT", System.StringComparison.Ordinal) >= 0)
  61.                     {
  62.                         await Ed.CommandAsync(Editor.PauseToken);
  63.                     }
  64.                 }
  65.                 catch (Autodesk.AutoCAD.Runtime.Exception ex)
  66.                 {
  67.                     if (ex.ErrorStatus != ErrorStatus.UserBreak)
  68.                     {
  69.                         throw;
  70.                     }
  71.                     Application.PreTranslateMessage -= Application_PreTranslateMessage;
  72.                
  73.                     return false;
  74.                 }
  75.             }
  76.          
  77.             return true;
  78.         }
  79.  
Part that watches for right click to escape
Code - C#: [Select]
  1.         /// <summary>
  2.         /// The m k_ shift
  3.         /// </summary>
  4.         private const int MK_SHIFT = 4;
  5.         /// <summary>
  6.         /// The w m_ rbuttonup
  7.         /// </summary>
  8.         private const int WM_RBUTTONUP = 517;
  9.         /// <summary>
  10.         /// The w m_ lbuttonup
  11.         /// </summary>
  12.         private const int WM_LBUTTONUP = 514;
  13.         /// <summary>
  14.         /// The w m_ lbuttondown
  15.         /// </summary>
  16.         private const int WM_LBUTTONDOWN = 513;
  17.         /// <summary>
  18.         /// The w m_ rbuttondown
  19.         /// </summary>
  20.         private const int WM_RBUTTONDOWN = 516;
  21.  
  22.         /// <summary>
  23.         /// Handles the PreTranslateMessage event of the Application control.
  24.         /// </summary>
  25.         /// <param name="sender">The source of the event.</param>
  26.         /// <param name="e">The <see cref="PreTranslateMessageEventArgs"/> instance containing the event data.</param>
  27.         private void Application_PreTranslateMessage(object sender, PreTranslateMessageEventArgs e)
  28.         {
  29.             var wp = e.Message.wParam.ToInt64();
  30.  
  31.             if (e.Message.message == WM_RBUTTONDOWN && (wp != 6 && wp != MK_SHIFT))
  32.             {
  33.                 e.Handled = true;
  34.             }
  35.             if (e.Message.message == WM_RBUTTONUP && wp != MK_SHIFT)
  36.             {
  37.                 Application.PreTranslateMessage -= Application_PreTranslateMessage;
  38.                 active = false;
  39.                 e.Handled = true;
  40.                 Application.DocumentManager.MdiActiveDocument.SendCancel();
  41.             }
  42.         }
  43.