Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.Runtime.InteropServices;
- using Autodesk.AutoCAD.ApplicationServices;
- using Autodesk.AutoCAD.Runtime;
- using AcadApp = Autodesk.AutoCAD.ApplicationServices.Application;
- using System.Windows.Forms;
- /// PaletteUtils.cs Copyright(c) 2008 Tony Tanzillo / www.caddzone.com
- /// UnComment this if you are using ExecuteInDocumentContext, and
- /// also using the CommandClass attribute elswhere in the same assembly.
- ///
- /// [assembly: CommandClass(typeof(CaddZone.Windows.PaletteUtils))]
- namespace CaddZone.AutoCAD.Windows
- {
- /// <summary>
- /// Utility functions for use from Palettes and Modeless dialogs.
- /// </summary>
- public static class PaletteUtils
- {
- /// <summary>
- ///
- /// Activates the AutoCAD Editor Window when a palette has focus.
- /// This should be called immediately before calling a GetXxxxx()
- /// method of the Editor to acquire graphical/command line input.
- ///
- /// </summary>
- public static void ActivateEditor()
- {
- PostMessage( ActiveDocument.Window.Handle, WM_SETFOCUS, IntPtr.Zero, IntPtr.Zero );
- System.Windows.Forms.Application.DoEvents();
- }
- class Thunk : IDisposable
- {
- private EventHandler handler;
- public Thunk( EventHandler handler )
- {
- if( handler == null )
- throw new ArgumentNullException( "handler" );
- this.handler = handler;
- System.Windows.Forms.Application.Idle += Application_Idle;
- }
- void Application_Idle( object sender, EventArgs e )
- {
- System.Windows.Forms.Application.Idle -= Application_Idle;
- ActivateEditor();
- try
- {
- handler( null, e );
- }
- finally
- {
- Dispose();
- }
- }
- ~Thunk()
- {
- Dispose();
- }
- public void Dispose()
- {
- GC.SuppressFinalize( this );
- if( handler != null )
- System.Windows.Forms.Application.Idle -= Application_Idle;
- handler = null;
- }
- }
- public static void OnEditorActivated( object sender, EventHandler handler )
- {
- if( AcadApp.DocumentManager.IsApplicationContext )
- {
- new Thunk( handler );
- }
- }
- /// <summary>
- /// The currently active document
- /// </summary>
- public static Document ActiveDocument
- {
- get
- {
- return AcadApp.DocumentManager.MdiActiveDocument;
- }
- }
- /// <summary>
- ///
- /// Executes code in the document context (the inverse of the
- /// DocumentCollection's ExecuteInApplicationContext() method).
- ///
- /// Call this method from the Application context when there is
- /// no command active, and pass a delegate that returns void and
- /// takes no parameters, and the code in the delegate will be
- /// executed in the document context, as if it were being called
- /// from the handler of a registered command (well, that's because
- /// it actually is called from the handler of a registered command :)
- ///
- /// If you execute AutoCAD commands from the handler, you must
- /// be extremely careful, and must ensure AutoCAD has returned
- /// to a quiescent state (e.g., at the Command: prompt, waiting
- /// for input), at the point when the delegate returns.
- ///
- /// If you call this API from the handler of a UI element, like
- /// a button on a palette or modeless dialog, you should always
- /// disable that UI element while the handler executes. You can
- /// disable the UI before calling this, and enable it from the
- /// handler passed as the argument, just before it returns.
- ///
- /// </summary>
- public static void ExecuteInDocumentContext( ExecuteInDocumentContextDelegate handler )
- {
- if( handler == null )
- return;
- ActivateEditor();
- if( !AcadApp.DocumentManager.IsApplicationContext )
- handler();
- else
- {
- if( !ActiveDocument.Editor.IsQuiescent )
- throw new InvalidOperationException( "AutoCAD is busy" );
- documentContextHandler = handler;
- ActiveDocument.SendStringToExecute( commandName + "\n", true, false, false );
- acedPostCommand( "" );
- }
- }
- [System.Security.SuppressUnmanagedCodeSecurity]
- [DllImport( "user32.dll", CharSet = CharSet.Auto )]
- public static extern int PostMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam );
- [DllImport( "user32.dll", CharSet = CharSet.Auto )]
- public static extern IntPtr SendMessage( IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam );
- private const int WM_SETFOCUS = 7;
- private const string commandName = "DOCUMENT_COMMAND";
- private const CommandFlags CommandFlagsSilent = CommandFlags.NoHistory | CommandFlags.NoMultiple;
- private const CommandFlags CommandFlagsSilentNoUndo = CommandFlagsSilent | CommandFlags.NoUndoMarker;
- public delegate void ExecuteInDocumentContextDelegate();
- private static ExecuteInDocumentContextDelegate documentContextHandler = null;
- [CommandMethod( commandName, CommandFlagsSilent )]
- public static void OnCommandExecute()
- {
- if( documentContextHandler != null )
- {
- bool flag = AcadApp.DocumentManager.DocumentActivationEnabled;
- AcadApp.DocumentManager.DocumentActivationEnabled = false;
- try
- {
- documentContextHandler();
- }
- finally
- {
- documentContextHandler = null;
- AcadApp.DocumentManager.DocumentActivationEnabled = flag;
- }
- }
- }
- [System.Security.SuppressUnmanagedCodeSecurity]
- [DllImport( "acad.exe", CallingConvention = CallingConvention.Cdecl,
- EntryPoint = "?acedPostCommand@@YAHPB_W@Z" )]
- extern static public int acedPostCommand( string cmd );
- }
- /// <summary>
- /// The ActivateEditor() method works for simple Button controls, but
- /// does not always work for ToolStrip buttons or menu items.
- ///
- /// To solve that you can use this class instead of the ToolStrip class,
- /// and it will ensure that the AutoCAD editor gets the focus when you
- /// call a getxxxxx() method.
- ///
- /// </summary>
- public class PaletteToolStrip : ToolStrip
- {
- protected override void OnMouseDown( MouseEventArgs mea )
- {
- if( !base.DesignMode )
- {
- ToolStripItem item = this.GetItemAt( mea.X, mea.Y );
- if( item != null && ( item is ToolStripButton || item is ToolStripMenuItem ) )
- {
- PaletteUtils.OnEditorActivated( item,
- delegate( object sender, EventArgs e )
- {
- item.PerformClick();
- }
- );
- return;
- }
- }
- base.OnMouseDown( mea );
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement