using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Drawing; using System.Threading; using System.Windows.Interop; using System.EnterpriseServices; using System.Windows; using System.IO; using System.Windows.Threading; using System.Collections; using System.Reflection; // Ooganizer Namespaces using Foo.Platform; using Foo.Platform.Win32; namespace Foo.ClientServices.ButtonWPForm { /// /// This class manages the creation/deletion and actions of (1 - n) ButtonForms /// [ComVisible(false)] internal class ButtonFormMgr { private const int INITIAL_OBJECT_CAPACITY = 30; private Hashtable m_ObjectList = null; private Dispatcher m_Dispatcher = null; // we have one btnForm loaded (hidden) always, as a performance cache private ButtonForm m_btnForm = null; private bool m_IsBtnFormCached = false; // Imp! - allows external caller to run any action on a ButtonForm public delegate void _Action(ButtonForm btnForm); //custom private delegates private delegate void delegate_Create(int hParentWND, Image snapshot); private delegate void delegate_Delete(int hParentWND); private delegate int delegate_CreateWindow(int hParentWND); private delegate void delegate_Action(int hParentWND, _Action action); // Declare the Log4net Variable private static log4net.ILog Log = Logger.GetLog4NetInterface(MethodBase.GetCurrentMethod().DeclaringType); public ButtonFormMgr(Dispatcher disp) { m_ObjectList = new Hashtable(); m_Dispatcher = disp; if (!m_IsBtnFormCached) BetterPerformance(); } /// /// Calls Create_ButtonForm via Dispatcher if neccessary /// /// handle to Parent/Owner Window public void Create_ButtonFormDISP(int hParentWND, Image snapshot) { if (hParentWND != 0) { if (m_Dispatcher.Thread == Thread.CurrentThread) { Create_ButtonForm(hParentWND, snapshot); } else { object[] parameters = new object[] { hParentWND, snapshot }; m_Dispatcher.Invoke((delegate_Create)Create_ButtonFormDISP, System.Windows.Threading.DispatcherPriority.Normal, parameters); } } } /// /// Calls Create_ButtonFormWindow via Dispatcher if neccessary /// /// handle to Parent/Owner Window public int Create_ButtonFormWindowDISP(int hParentWND) { if (hParentWND != 0) { if (m_Dispatcher.Thread == Thread.CurrentThread) { return Create_ButtonFormWindow(hParentWND); } else { object[] parameters = new object[] { hParentWND }; return (int)m_Dispatcher.Invoke((delegate_CreateWindow)Create_ButtonFormWindowDISP, System.Windows.Threading.DispatcherPriority.Normal, parameters); } } return 0; } /// /// Calls Delete_ButtonForm via Dispatcher if neccessary /// /// handle to Parent/Owner Window public void Delete_ButtonFormDISP(int hParentWND) { if (hParentWND != 0) { if (m_Dispatcher.Thread == Thread.CurrentThread) { Delete_ButtonForm(hParentWND); } else { object[] parameters = new object[] { hParentWND }; m_Dispatcher.Invoke((delegate_Delete)Delete_ButtonFormDISP, System.Windows.Threading.DispatcherPriority.Normal, parameters); } } } /// /// Use this Dispatching Action Function to run any _Action on the ButtonForm /// /// handle to Parent/Owner Window public void RunAction_ButtonFormDISP(int hParentWND, _Action action) { if (hParentWND != 0) { if (m_Dispatcher.Thread == Thread.CurrentThread) { RunAction_ButtonForm(hParentWND, action); } else { object[] parameters = new object[] { hParentWND, action }; m_Dispatcher.Invoke((delegate_Action)RunAction_ButtonFormDISP, System.Windows.Threading.DispatcherPriority.Normal, parameters); } } } /// /// Calls Terminate via Dispatcher if neccessary /// /// handle to Parent/Owner Window public void TerminateDISP() { if (m_Dispatcher.Thread == Thread.CurrentThread) { Terminate(); } else { m_Dispatcher.Invoke((Action)TerminateDISP, System.Windows.Threading.DispatcherPriority.Normal, null); } } /// /// Creates a new ButtonForm object into the ObjectList /// /// handle to Parent/Owner Window private void Create_ButtonForm(int hParentWND, Image snapshot) { try { if (!m_IsBtnFormCached) BetterPerformance(); m_ObjectList[hParentWND] = new ButtonForm(); ButtonForm btnForm = (ButtonForm)m_ObjectList[hParentWND]; if (btnForm != null) { // We use the InteropHelper to set the Owner Property WindowInteropHelper InteropHelper = new WindowInteropHelper(btnForm); InteropHelper.Owner = (IntPtr)hParentWND; // Set the important Fields into the Button Form btnForm.HookedWindow = (IntPtr)hParentWND; // give it the handle to the hooked window btnForm.SnapShot = snapshot; // give it the snapshot of the window RECT ParentWndRect = new RECT(); Win32Functions.GetWindowRect((IntPtr)hParentWND, out ParentWndRect); // Get Initial Location for the form btnForm.Top = ParentWndRect.top; btnForm.Left = ParentWndRect.left; // Get Initial Height and Width of the form btnForm.Height = (ParentWndRect.bottom - ParentWndRect.top); btnForm.Width = (ParentWndRect.right - ParentWndRect.left); } } catch (Exception e) { Log.Error(string.Format("{0}() - error thrown", MethodBase.GetCurrentMethod().Name), e); } } /// /// Use this function to delete the ButtonForm Object /// /// handle to Parent/Owner Window private void Delete_ButtonForm(int hParentWND) { try { if (m_ObjectList.ContainsKey(hParentWND)) { ButtonForm btnForm = (ButtonForm)m_ObjectList[hParentWND]; if (btnForm != null) { m_ObjectList.Remove(hParentWND); btnForm.Close(); } } } catch (Exception e) { Log.Error(string.Format("{0}() - error thrown", MethodBase.GetCurrentMethod().Name), e); } } /// /// Use this to run void() function actions on the specified buttonform /// /// handle to Parent/Owner Window /// a pointer to a delegate (action function) to run private void RunAction_ButtonForm(int hParentWND, _Action action) { try { if (m_ObjectList.ContainsKey(hParentWND)) { ButtonForm btnForm = (ButtonForm)m_ObjectList[hParentWND]; if (btnForm != null) action(btnForm); } } catch (Exception e) { Log.Error(string.Format("{0}() - error thrown", MethodBase.GetCurrentMethod().Name), e); } } /// /// Use this to actually create the Window, call this after calling Create_ButtonForm /// This will create the window by calling Show(), this will also show the window /// /// handle to Parent/Owner Window /// the Handle to the newly created window object private int Create_ButtonFormWindow(int hParentWND) { try { if (m_ObjectList.ContainsKey(hParentWND)) { ButtonForm btnForm = (ButtonForm)m_ObjectList[hParentWND]; // We use the InteropHelper to see if this WPFForm has been created previously WindowInteropHelper InteropHelper = new WindowInteropHelper(btnForm); if (InteropHelper.Handle == IntPtr.Zero) { btnForm.Show(); } return (int)InteropHelper.Handle; } } catch (Exception e) { Log.Error(string.Format("{0}() - error thrown", MethodBase.GetCurrentMethod().Name), e); } return 0; } /// /// Kills all ButtonForm Instances (STOPS ALL) /// private void Terminate() { try { foreach (object o in m_ObjectList) { if ((o != null) && (o is ButtonForm)) { ButtonForm btnForm = (ButtonForm)o; btnForm.Close(); } } m_ObjectList.Clear(); if (m_IsBtnFormCached) { m_btnForm.Close(); m_IsBtnFormCached = false; } } catch (Exception e) { Log.Error(string.Format("{0}() - error thrown", MethodBase.GetCurrentMethod().Name), e); } } /// /// In order to improve first WPForm performance we have one /// WPForm ButtonForm loaded at all times. (opacity set to 0). /// ~it has no parent setting so it is just a form of the desktop /// private void BetterPerformance() { if (!m_IsBtnFormCached) { try { // Performance Cache (keeps a window loaded always) m_btnForm = new ButtonForm(true); m_btnForm.LoadHideButtonFormPerfCache(); m_IsBtnFormCached = true; } catch (Exception e) { Log.Error(string.Format("{0}() - error thrown", MethodBase.GetCurrentMethod().Name), e); } } } } }