Author Topic: AppActivate event  (Read 4612 times)

0 Members and 1 Guest are viewing this topic.

Bryco

  • Water Moccasin
  • Posts: 1883
AppActivate event
« on: January 17, 2009, 05:34:30 PM »
For some reason I can't figure out how to do this without using com.
http://msdn.microsoft.com/en-us/library/system.windows.application.deactivated(VS.85).aspx has something that looks like it should work, but the Application in public partial class App : Application defaults to cad instead of the app in System.Windows, and I can't figure out how to do it.

The main reason I want the activate and deactivate events are to set caps lock to on for cad.
I have looked at the David's post http://www.theswamp.org/index.php?topic=11681.msg146222#msg146222 and noticed he used a timer.
This seems to be inefficient compared to an event but after reading other posts, I'm not sure what an event really means.
Is each event no different from a timer and merely looks for the event every few milliseconds or is it something that actually is triggered?

MickD

  • King Gator
  • Posts: 3636
  • (x-in)->[process]->(y-out) ... simples!
Re: AppActivate event
« Reply #1 on: January 17, 2009, 05:47:20 PM »
In win32 (which at this stage at least I think .net wraps it or MFC) all events get passed to the windows manager that finds the window's ID then passes the event to the window's winproc (windows procedure) where it's put through a switch case scenario. If you have written a handler for a particular event in the switch (each event has an enum ID such as 'WM_PAINT') then your code gets called, else it goes to the default win proc where it's handled and the 'pump' continues.

In C#'s case you need to write a delegate that gets added to the underlying winproc to process to be handled, so for any event the window exposes you need to do something like write a delegate procedure and add it to the event handler using something like -

AppActivate.handler += myEventHandler();

not too accurate but I hope it helps.
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

Bryco

  • Water Moccasin
  • Posts: 1883
Re: AppActivate event
« Reply #2 on: January 17, 2009, 06:09:15 PM »
Nice reply Mick, I can understand that.
So cad is passing every event it has all the time. It seems that exposing all the com events aren't going to slow anything down then, as they they aren't doing anything extra till  you use them specifically.


Bryco

  • Water Moccasin
  • Posts: 1883
Re: AppActivate event
« Reply #3 on: January 17, 2009, 06:39:52 PM »
Perhaps the event AppActivate comes directly from windows. How you get it from net?

MickD

  • King Gator
  • Posts: 3636
  • (x-in)->[process]->(y-out) ... simples!
Re: AppActivate event
« Reply #4 on: January 17, 2009, 09:30:15 PM »
Yes, when you click the mouse say, windows sends the event to the winproc of the window that the mouse was clicked in, this could be a button or the editor and it's how the event code is written that decides the behaviour.

I'd be looking a bit closer at the main application window's events such as 'isactive' or something like that. I don't have access to an ide at the moment but someone will have an idea to work with.
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

TonyT

  • Guest
Re: AppActivate event
« Reply #5 on: January 17, 2009, 11:29:48 PM »
This is how I do it:

Code: [Select]

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autodesk.AutoCAD.Runtime;

using Acad = Autodesk.AutoCAD.ApplicationServices.Application;

[assembly: ExtensionApplication(typeof(Namespace1.MyApplication))]

namespace Namespace1
{
   public class MyApplication: IExtensionApplication
   {
      public void Initialize()
      {
         AppActivateListener.AppActivate += OnAppActivate;
      }

      public void Terminate()
      {
         AppActivateListener.AppActivate -= OnAppActivate;
      }
     
      void OnAppActivate( object sender, AppActivateEventArgs e )
      {
         string msg = e.Activating ? "\n ---> Activated" : "\n ---> Deactivated";
         Acad.DocumentManager.MdiActiveDocument.Editor.WriteMessage( msg );
      }
     
   }

   public class AppActivateEventArgs : EventArgs
   {
      public AppActivateEventArgs( bool activating )
      {
         this.activating = activating;
      }
      private bool activating = false;
      public bool Activating
      {
         get
         {
            return activating;
         }
      }
   }

   public class AppActivateListener : AcadWindowHook
   {
      public const int WM_ACTIVATEAPP = 28;

      private AppActivateListener()
      {
      }

      protected override void WndProc( ref Message m )
      {
         if( m.Msg == WM_ACTIVATEAPP && appActivate != null )
         {
            // if the handler throws an exception that is not handled, it will
            // likely crash AutoCAD, so we have to break a rule here, and
            // catch/surpress any exception that's thrown:

            try
            {
               appActivate( this, new AppActivateEventArgs( m.WParam != IntPtr.Zero ) );
            }
            catch
            {
            }
         }
         base.WndProc( ref m );
      }

      private static AppActivateListener instance = null;

      public static event EventHandler<AppActivateEventArgs> AppActivate
      {
         add
         {
            if( instance == null )
               instance = new AppActivateListener();
            appActivate += value;
         }
         remove    // if there are no handlers listening, we can unhook the window:
         {
            appActivate -= value;
            if( instance != null && appActivate.GetInvocationList().Length == 0 )
            {
               instance.Dispose();
               instance = null;
            }
         }
      }

      private static event EventHandler<AppActivateEventArgs> appActivate = null;

   }

   public abstract class AcadWindowHook : NativeWindow, IDisposable
   {
      public AcadWindowHook()
         : this( Acad.MainWindow.Handle )
      {
      }

      public AcadWindowHook( IntPtr handle )
      {
         this.AssignHandle( handle );
      }

      ~AcadWindowHook()
      {
         Dispose( false );
      }

      private void Dispose( bool disposing )
      {
         if( !disposed )
         {
            GC.SuppressFinalize( this );
            this.ReleaseHandle();
            disposed = true;
         }
      }

      private bool disposed = false;

      public void Dispose()
      {
         Dispose( true );
      }
   }

}




For some reason I can't figure out how to do this without using com.
http://msdn.microsoft.com/en-us/library/system.windows.application.deactivated(VS.85).aspx has something that looks like it should work, but the Application in public partial class App : Application defaults to cad instead of the app in System.Windows, and I can't figure out how to do it.

The main reason I want the activate and deactivate events are to set caps lock to on for cad.
I have looked at the David's post http://www.theswamp.org/index.php?topic=11681.msg146222#msg146222 and noticed he used a timer.
This seems to be inefficient compared to an event but after reading other posts, I'm not sure what an event really means.
Is each event no different from a timer and merely looks for the event every few milliseconds or is it something that actually is triggered?

« Last Edit: January 18, 2009, 12:00:45 AM by TonyT »

MickD

  • King Gator
  • Posts: 3636
  • (x-in)->[process]->(y-out) ... simples!
Re: AppActivate event
« Reply #6 on: January 18, 2009, 02:31:57 AM »
Not to take anything at all away from what you have done Tony, you definitely know your sh1t :kewl:, but that makes win32 look easy  :laugh:

"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

TonyT

  • Guest
Re: AppActivate event
« Reply #7 on: January 18, 2009, 04:47:20 AM »
Not to take anything at all away from what you have done Tony, you definitely know your sh1t :kewl:, but that makes win32 look easy  :laugh:



Mick. No kidding :o

Care to demonstrate?

Bryco

  • Water Moccasin
  • Posts: 1883
Re: AppActivate event
« Reply #8 on: January 18, 2009, 12:29:21 PM »
Thanks Tony, it works a treat.
Odd that when  substituting
MessageBox.Show(msg);  for
Acad.DocumentManager.MdiActiveDocument.Editor.WriteMessage( msg );
You get a new instance of cad every time, but other than that it's working fine.
I could never figure out that on my own, sometimes it seems like the learning curve is never ending.

TonyT

  • Guest
Re: AppActivate event
« Reply #9 on: January 23, 2009, 12:24:41 AM »
Thanks Tony, it works a treat.
Odd that when  substituting
MessageBox.Show(msg);  for
Acad.DocumentManager.MdiActiveDocument.Editor.WriteMessage( msg );
You get a new instance of cad every time

 :lmao:

I'm not all that suprised, because when you show a modal
dialog or message box, that causes the AutoCAD window to
be deactivated, and activated again when the modal dialog 
or message box is dismissed.

In other words, what you are doing in the handler of the
event, is causing the event to fire again, and again, and
again....