initial oogynize check in _ this actually used to work!

This commit is contained in:
2016-02-14 21:16:31 -08:00
parent b183af5d55
commit 532ea133bc
337 changed files with 30692 additions and 0 deletions

View File

@@ -0,0 +1,19 @@
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" x:Class="Foo.ClientServices.ButtonWPForm.ButtonForm"
Title="ButtonForm" Closed="Window_Closed" Height="419" Width="538" WindowStyle="None" AllowsTransparency="True" Background="Transparent" ShowInTaskbar="False" Loaded="OnLoad" ResizeMode="NoResize" ShowActivated="False" mc:Ignorable="d">
<Grid>
<Rectangle x:Name="recGradiant" Stroke="Black" RadiusY="7.5" RadiusX="7.5" >
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0" Opacity="1.0">
<GradientStop Color="#FF000000" Offset="0.238"/>
<GradientStop Color="#FE333333" Offset="0.778"/>
<GradientStop Color="#FE202020" Offset="0.613"/>
<GradientStop Color="#FE333333" Offset="0.87"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Frame x:Name="frmButtonForm" Margin="0,40,0,0" VerticalAlignment="Top" Height="371" />
</Grid>
</Window>

View File

@@ -0,0 +1,211 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Reflection;
using SnapshotImage = System.Drawing.Image;
// Ooganizer namespaces
using Foo.ClientServices.ButtonWPForm.ButtonFormPages;
using Foo.Platform;
using Foo.Platform.Win32;
using Foo.Platform.ErrorReporting;
using Foo.Platform.Interacters;
using System.Windows.Interop;
namespace Foo.ClientServices.ButtonWPForm
{
/// <summary>
/// Interaction logic for ButtonWindow Form
/// </summary>
[ComVisible(false)]
public partial class ButtonForm : Window
{
////
// Public Properties
////
public IntPtr HookedWindow { get { return _hHookedWnd; } set { _hHookedWnd = value; } } // Passed in by FormMgr
public System.Drawing.Image SnapShot { get { return _SnapShot; } set { _SnapShot = value; } } // Passed in by FormMgr
//public Artifact Artifact { get { return _Artifact; } }
//public string ArtifactTitle { get { return _ArtifactTitle; } }
//public string ArtifactLocation { get { return _ArtifactLocation; } }
//public string CurrentWorkspaceName { get { return _CurrentWorkspaceName; } }
////
// Private Member Variables
////
private IntPtr _hHookedWnd = IntPtr.Zero;
private System.Drawing.Image _SnapShot = null;
private bool _PerformanceCache = false;
private static ButtonForm s_PerfCacheButtonFormObj = null;
private bool _PerfCacheLoadedHidden = false;
//private Artifact _Artifact;
//private string _ArtifactTitle;
//private string _ArtifactLocation;
//private string _CurrentWorkspaceName;
////
// ButtonFormPages
////
IButtonFormPage[] m_ButtonFormPages = new IButtonFormPage[1];
// Declare the Log4net Variable
private static log4net.ILog Log = Logger.GetLog4NetInterface(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// Construct WPF ButtonForm :)
/// </summary>
public ButtonForm()
{
InitializeComponent();
}
/// <summary>
/// Construct WPF ButtonForm (Performance Cache)
/// </summary>
public ButtonForm(bool bPerformanceCache)
{
if (bPerformanceCache && (s_PerfCacheButtonFormObj == null))
{
_PerformanceCache = bPerformanceCache;
s_PerfCacheButtonFormObj = this;
}
InitializeComponent();
}
/// <summary>
/// As part of Performance Caching (load one instance of this form
/// hidden and not visible to the user (called by FormMgr) ~also
/// allows to hide and existing one
/// ~Should only be called by FormMgr when creating the first object
/// </summary>
public void LoadHideButtonFormPerfCache()
{
if (!_PerfCacheLoadedHidden && _PerformanceCache && (s_PerfCacheButtonFormObj != null))
{
s_PerfCacheButtonFormObj.Opacity = 0;
s_PerfCacheButtonFormObj.WindowState = WindowState.Minimized;
s_PerfCacheButtonFormObj.ShowInTaskbar = false;
s_PerfCacheButtonFormObj.Show();
s_PerfCacheButtonFormObj.Hide();
_PerfCacheLoadedHidden = true;
}
}
/// <summary>
/// Window Load Event. We want all object loading to happen in the Load Event,
/// because we construct the WPFForm and show it right away, so this is called right at
/// start up, so put all the object loading in here to be cleaner and simplify FormObject Creator
/// </summary>
private void OnLoad(object sender, RoutedEventArgs args)
{
try
{
if (_PerformanceCache && (this == s_PerfCacheButtonFormObj)) // Preload child pages
{
PreloadAllChildPages();
// Add Message Hook for performance WPForm * To make sure it is always invisible *
HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
source.AddHook(new HwndSourceHook(MessageHook));
}
else if (!_PerformanceCache && (HookedWindow != IntPtr.Zero) && (this != s_PerfCacheButtonFormObj))
{
////
// Resolve the Window and set the properties accordingly,
// our child pages depend on this information
////
//ResolverDispatch resolver = new ResolverDispatch();
//ArtifactGroup artifacts = resolver.GetArtifacts(HookedWindow);
//if (artifacts.Length > 0)
//{
// _Artifact = artifacts.GetPrimary;
// _ArtifactTitle = _Artifact.Name;
// _ArtifactLocation = _Artifact.Location;
// // Workspace
// _CurrentWorkspaceName = SrvrCommon.GetCurrentWorkspaceName();
// // Now Load the Page
// LoadPageAccordingToState();
//}
//else
//{
// // Somemething went wrong Resolving
// UserError.Show("Document not Found", "Failed to accurately find the document for the Window");
// Close(); //~imp, we must close this Form
//}
}
}
catch (Exception e)
{
Log.Error(string.Format("{0}() - A fatal error occured loading ButtonForm", MethodBase.GetCurrentMethod().Name), e);
Close(); //~imp, we must close this Form
}
}
/// <summary>
/// This Message Hook is for the Hidden WPForm that we use for better performance,
/// We want to make sure that it is never displayed *It can occur that explore can show it, without this*
/// </summary>
private IntPtr MessageHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
// force opacity at all times
if (Opacity == 1.0)
Opacity = 0.0;
// force minimized at all times
if (WindowState != WindowState.Minimized)
WindowState = WindowState.Minimized;
// force Not to be seen in taskbar
if (ShowInTaskbar == true)
ShowInTaskbar = false;
return System.IntPtr.Zero;
}
/// <summary>
/// For Performance, we need to preload all Child Pages
/// </summary>
private void PreloadAllChildPages()
{
m_ButtonFormPages[0] = (IButtonFormPage) new Page_AddEdit();
m_ButtonFormPages[0].ParentWPFContainer = this;
}
/// <summary>
/// Show different pages depending on the state we are in. (Currently only 1 state)
/// </summary>
private void LoadPageAccordingToState()
{
m_ButtonFormPages[0] = (IButtonFormPage) new Page_AddEdit();
m_ButtonFormPages[0].ParentWPFContainer = this;
if (!frmButtonForm.Navigate((Page) m_ButtonFormPages[0]))
Log.Info(string.Format("{0}() - ButtonForm could not navigate to Page_AddEdit", MethodBase.GetCurrentMethod().Name));
}
/// <summary>
/// When this window closes position the Hooked Window back to it's original position
/// </summary>
private void Window_Closed(object sender, EventArgs e)
{
// GUICommon.PositionWindowBackToWhereItWas(HookedWindow, true);
BHInteracter.SetAsActiveWindow(HookedWindow);
}
}
}

View File

@@ -0,0 +1,324 @@
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
{
/// <summary>
/// This class manages the creation/deletion and actions of (1 - n) ButtonForms
/// </summary>
[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();
}
/// <summary>
/// Calls Create_ButtonForm via Dispatcher if neccessary
/// </summary>
/// <param name="hParentWND">handle to Parent/Owner Window</param>
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);
}
}
}
/// <summary>
/// Calls Create_ButtonFormWindow via Dispatcher if neccessary
/// </summary>
/// <param name="hParentWND">handle to Parent/Owner Window</param>
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;
}
/// <summary>
/// Calls Delete_ButtonForm via Dispatcher if neccessary
/// </summary>
/// <param name="hParentWND">handle to Parent/Owner Window</param>
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);
}
}
}
/// <summary>
/// Use this Dispatching Action Function to run any _Action on the ButtonForm
/// </summary>
/// <param name="hParentWND">handle to Parent/Owner Window</param>
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);
}
}
}
/// <summary>
/// Calls Terminate via Dispatcher if neccessary
/// </summary>
/// <param name="hParentWND">handle to Parent/Owner Window</param>
public void TerminateDISP()
{
if (m_Dispatcher.Thread == Thread.CurrentThread)
{
Terminate();
}
else
{
m_Dispatcher.Invoke((Action)TerminateDISP, System.Windows.Threading.DispatcherPriority.Normal, null);
}
}
/// <summary>
/// Creates a new ButtonForm object into the ObjectList
/// </summary>
/// <param name="hParentWND">handle to Parent/Owner Window</param>
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);
}
}
/// <summary>
/// Use this function to delete the ButtonForm Object
/// </summary>
/// <param name="hParentWND">handle to Parent/Owner Window</param>
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);
}
}
/// <summary>
/// Use this to run void() function actions on the specified buttonform
/// </summary>
/// <param name="hParentWND">handle to Parent/Owner Window</param>
/// <param name="action">a pointer to a delegate (action function) to run</param>
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);
}
}
/// <summary>
/// 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
/// </summary>
/// <param name="hParentWND">handle to Parent/Owner Window</param>
/// <returns>the Handle to the newly created window object</returns>
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;
}
/// <summary>
/// Kills all ButtonForm Instances (STOPS ALL)
/// </summary>
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);
}
}
/// <summary>
/// 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
/// </summary>
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);
}
}
}
}
}

View File

@@ -0,0 +1,18 @@
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" x:Class="Foo.ClientServices.ButtonWPForm.ButtonFormPages.Page_AddEdit"
Title="Page_AddEdit" Loaded="Page_Loaded" mc:Ignorable="d" Height="255" Width="550">
<Grid d:LayoutOverrides="VerticalMargin">
<Border CornerRadius="6" Background="Gray" Opacity="0.325" HorizontalAlignment="Left" Width="550"/>
<TextBox Margin="90,33,39,0" x:Name="txtTitle" Height="22" VerticalAlignment="Top" />
<Label Height="28" HorizontalAlignment="Left" Margin="48,30.667,0,0" x:Name="lblTitle" VerticalAlignment="Top" Width="36" Foreground="White" Content="Title" RenderTransformOrigin="-1.028,1.036"/>
<TextBox TextAlignment="Left" VerticalScrollBarVisibility="Auto" TextWrapping="Wrap" Margin="90,0,39,77.671" x:Name="txtLocation" Background="Transparent" Foreground="White" BorderBrush="{x:Null}" Focusable="False" IsTabStop="False" VerticalAlignment="Bottom" Height="40" />
<ComboBox Margin="90,85,39,0" x:Name="comboWorkspaces" Height="24" VerticalAlignment="Top" d:LayoutOverrides="VerticalAlignment" />
<Label HorizontalAlignment="Left" Margin="12,83.334,0,0" x:Name="label1" Width="74" Foreground="White" Height="27" VerticalAlignment="Top" Content="Workspace" d:LayoutOverrides="VerticalAlignment"/>
<Label Height="24" HorizontalAlignment="Right" Margin="0,55,29,0" x:Name="lblRequired" VerticalAlignment="Top" Width="54" Foreground="White" FontSize="10" FontStyle="Italic" Content="Required" RenderTransformOrigin="1.963,0.542"/>
<Label FontSize="10" FontStyle="Italic" Foreground="White" Height="24" HorizontalAlignment="Right" Margin="0,108.331,29,0" x:Name="lblRequired3" VerticalAlignment="Top" Width="54" Content="Required"/>
<Button HorizontalAlignment="Left" Margin="90,201.649,0,0" x:Name="btnCancel" Width="75" Click="btnCancel_Click" Content="Cancel" VerticalAlignment="Top" Height="23"/>
<Button HorizontalAlignment="Right" Margin="0,201.649,39,0" x:Name="btnAdd" Width="75" Click="btnAdd_Click" Content="Add" VerticalAlignment="Top" Height="23"/>
</Grid>
</Page>

View File

@@ -0,0 +1,81 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Reflection;
// Ooganizer Namespaces
using Foo.Platform;
using Foo.Platform.Interacters;
namespace Foo.ClientServices.ButtonWPForm.ButtonFormPages
{
/// <summary>
/// Interaction logic for ButtonFormPage_AddEdit.xaml
/// </summary>
public partial class Page_AddEdit : Page, IButtonFormPage
{
#region IButtonFormPage
public ButtonForm ParentWPFContainer { get { return _ButtonForm; } set { _ButtonForm = value; } }
private ButtonForm _ButtonForm = null;
#endregion
// Declare the Log4net Variable
private static log4net.ILog Log = Logger.GetLog4NetInterface(MethodBase.GetCurrentMethod().DeclaringType);
public Page_AddEdit()
{
InitializeComponent();
}
private void Page_Loaded(object sender, RoutedEventArgs e)
{
if (ParentWPFContainer == null)
{
Log.Debug(string.Format("{0}() - ParentWPFContainer is null this should never happen", MethodBase.GetCurrentMethod().Name));
return;
}
// Set the Artifact Properties
//txtTitle.Text = ParentWPFContainer.ArtifactTitle;
// se
//txtLocation.Text = ParentWPFContainer.ArtifactLocation;
//txtLocation.ScrollToEnd();
// Add all workspaces to the combo selection
//foreach (Ooganizer.API.Workspace wspace in SrvrCommon.Workspaces)
// comboWorkspaces.Items.Add(wspace.Name);
////
// Default to the current Workspace or 0 if none are loaded
////
//if (ParentWPFContainer.CurrentWorkspaceName == "")
// comboWorkspaces.SelectedIndex = 0;
//else
// comboWorkspaces.SelectedValue = ParentWPFContainer.CurrentWorkspaceName;
}
private void btnCancel_Click(object sender, RoutedEventArgs e)
{
BHInteracter.SetW32ButtonToNewState(ParentWPFContainer.HookedWindow, BHInteracter.BUTTON_HOOK_STATE.BUTTON_ADD);
ParentWPFContainer.Close();
}
private void btnAdd_Click(object sender, RoutedEventArgs e)
{
//SrvrCommon.AddArtifactToWorkspace(txtTitle.Text, txtLocation.Text, ParentWPFContainer.SnapShot, ParentWPFContainer.CurrentWorkspaceName);
//BHInteracter.SetW32ButtonToNewState(ParentWPFContainer.HookedWindow, BHInteracter.BUTTON_HOOK_STATE.BUTTON_DELETE);
ParentWPFContainer.Close();
}
}
}

View File

@@ -0,0 +1,156 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{E179DF39-539A-407F-94DE-C21F690E02C4}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Foo.ClientServices.ButtonWPForm</RootNamespace>
<AssemblyName>ButtonWPForm</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel>
<SccProjectName>
</SccProjectName>
<SccLocalPath>
</SccLocalPath>
<SccAuxPath>
</SccAuxPath>
<SccProvider>
</SccProvider>
<StartupObject>
</StartupObject>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>MyKeyFile.SNK</AssemblyOriginatorKeyFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\Target\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\..\Target\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\Components\log4net.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Drawing" />
<Reference Include="System.EnterpriseServices" />
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data.DataSetExtensions">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="UIAutomationProvider">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
<Reference Include="WindowsBase">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
<Reference Include="PresentationCore">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
<Reference Include="PresentationFramework">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
</ItemGroup>
<ItemGroup>
<Page Include="ButtonForm.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="ButtonFormPages\Page_AddEdit.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Compile Include="ButtonForm.xaml.cs">
<DependentUpon>ButtonForm.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="ButtonFormMgr.cs" />
<Compile Include="ButtonFormPages\Page_AddEdit.xaml.cs">
<DependentUpon>Page_AddEdit.xaml</DependentUpon>
</Compile>
<Compile Include="ButtonWPFormCCW.cs" />
<Compile Include="CaptionButtonStarter.cs" />
<Compile Include="IButtonFormPage.cs" />
<Compile Include="IClientEvents.cs" />
<Compile Include="ComponentState.cs" />
<Compile Include="DispatcherThread.cs" />
<Compile Include="IButtonForm.cs" />
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<None Include="MyKeyFile.SNK" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<AppDesigner Include="Properties\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\DataAccessLayer\DataAccessLayer.csproj">
<Project>{C7E4B4C1-64D4-45FF-AAFD-C4B9AE216618}</Project>
<Name>DataAccessLayer</Name>
</ProjectReference>
<ProjectReference Include="..\..\GUILib\GUILib.csproj">
<Project>{C1282050-455B-44F4-8520-1C005E38EFB2}</Project>
<Name>GUILib</Name>
</ProjectReference>
<ProjectReference Include="..\..\Platform\Platform.csproj">
<Project>{F6929AFC-BF61-43A0-BABD-F807B65FFFA1}</Project>
<Name>Platform</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
<PropertyGroup>
<PostBuildEvent>$(FrameworkDir)\regasm.exe "$(SolutionDir)target\$(ConfigurationName)\$(TargetFileName)" /unregister
$(FrameworkDir)\regasm.exe "$(SolutionDir)target\$(ConfigurationName)\$(TargetFileName)" /tlb:$(TargetName).tlb /codebase
REM $(FrameworkDir)\regsvcs.exe /reconfig "$(SolutionDir)target\$(ConfigurationName)\$(TargetFileName)" /appdir:"$(SolutionDir)target\$(ConfigurationName)"</PostBuildEvent>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,249 @@
// For GUIDebugStepExe Debugging Only - Uncomment this #define
#define GUIDEBUGSTEPEXE
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.GUILib;
using Foo.Platform;
using Foo.Platform.Win32;
using Foo.Platform.Interacters;
using Foo.Platform.ErrorReporting;
namespace Foo.ClientServices.ButtonWPForm
{
/// <summary>
/// ButtonWPFormCCW - Com Callable Wrapper Class exposed to ButtonHook.
/// This class is responsible for creating the ButtonWPForm (a form created in response to a ButtonHook W32 Click)
/// </summary>
[Guid("6F108F0B-9CEB-4d3d-B1D9-7685F9F39E50")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("Foo.ClientServices.ButtonWPFormCCW")]
[ComVisible(true)]
[ObjectPooling(Enabled = true, MinPoolSize = 1, MaxPoolSize = 2500, CreationTimeout = 5000)]
#if GUIDEBUGSTEPEXE
public class ButtonWPFormCCW : IButtonForm, IClientEvents
#else
public class ButtonWPFormCCW : ServicedComponent, IButtonForm, IClientEvents, IProcessInitializer
#endif
{
////
// Member Variables
////
private IntPtr m_hWnd = IntPtr.Zero;
private IntPtr m_hWndParent = IntPtr.Zero;
private IntPtr m_hWndButton = IntPtr.Zero;
BHInteracter.BUTTON_HOOK_STATE m_ButtonState = BHInteracter.BUTTON_HOOK_STATE.BUTTON_NONE;
// Declare the Log4net Variable
private static log4net.ILog Log = Logger.GetLog4NetInterface(MethodBase.GetCurrentMethod().DeclaringType);
#region Construction / Destruction
public ButtonWPFormCCW() {}
~ButtonWPFormCCW() {}
#endregion
#if GUIDEBUGSTEPEXE
#region GuiDebugStepCustomStarterStopers
public void Start()
{
Log.Info(string.Format("{0}() - ComponentState Application Is being started", MethodBase.GetCurrentMethod().Name));
ComponentState.ApplicationIsRunning = true;
}
public void Stop()
{
Log.Info(string.Format("{0}() - ComponentState Application Is being stopped", MethodBase.GetCurrentMethod().Name));
ComponentState.ApplicationIsRunning = false;
}
#endregion
#else
#region IProcessInitializer Members
public void Startup(object punkProcessControl)
{
Log.Info(string.Format("{0}() - ComponentState Application Is being started", MethodBase.GetCurrentMethod().Name));
ComponentState.ApplicationIsRunning = true;
}
public void Shutdown()
{
Log.Info(string.Format("{0}() - ComponentState Application Is being stopped", MethodBase.GetCurrentMethod().Name));
ComponentState.ApplicationIsRunning = false;
}
#endregion
#endif
#region ButtonHook Activation/Deactivation
/// <summary>
/// This is called first time when the buttonhook is attaching into a Window. It passes us
/// important handle information that we need or may need to communicate back state information.
/// </summary>
/// <param name="hParentWND">the handle to the window the buttonhook is hooked into</param>
/// <param name="hButtonWND">the handle to the button Window (we need it if we want to communicat with it)</param>
public void WPFThreadProc_ButtonWPForm_Activated(int hParentWND, int hButtonWND)
{
// Store the handle information for later use
m_hWndParent = (IntPtr)hParentWND;
m_hWndButton = (IntPtr)hButtonWND;
}
/// <summary>
/// Called when the buttonhook is unattaching itself from a Window.
/// Here, we can do any cleanup that we may have to do.
/// </summary>
public void WPFThreadProc_ButtonWPForm_Deactivated()
{
try
{
if ((m_hWndParent != IntPtr.Zero) && (ComponentState.ButtonFormMgr != null))
ComponentState.ButtonFormMgr.Delete_ButtonFormDISP((int)m_hWndParent);
}
catch (Exception e)
{
Log.Error(string.Format("{0}() - error thrown", MethodBase.GetCurrentMethod().Name), e);
}
}
#endregion
#region Custom Events
/// <summary>
/// This function is called when the Win32 button is clicked. This function should
/// handle the creation of the wpfform and display it over the window
/// </summary>
/// <returns>the window handle to the newly created wpfform to be stored by the caller</returns>
public int W32BUTTONCLICKED()
{
try
{
// Let's Position the Window and snapshot it...
Image snapshot = null;
try
{
BHInteracter.SetW32ButtonToNewState(m_hWndParent, BHInteracter.BUTTON_HOOK_STATE.BUTTON_NONE);
System.Threading.Thread.Sleep(100);
snapshot = GUICommon.PositionWindowToGoldenPosAndTakeSnapshot(m_hWndParent, true);
}
catch (Exception e)
{
UserError.Show("Snapshot Failed", "Obtaining a Snaphot for the Window Failed.");
Log.Error(string.Format("{0}() - error thrown", MethodBase.GetCurrentMethod().Name), e);
return 0;
}
if (snapshot != null)
{
// Create the WpfForm object and then create the wpfform window and show it.
ComponentState.ButtonFormMgr.Create_ButtonFormDISP((int)m_hWndParent, snapshot);
m_hWnd = (IntPtr) ComponentState.ButtonFormMgr.Create_ButtonFormWindowDISP((int)m_hWndParent);
return (int)m_hWnd;
}
else
{
UserError.Show("Snapshot Failed", "Obtaining a Snaphot for the Window Failed.");
Log.Error(string.Format("{0}() - UserError.Show() - Obtaining a Snapshot Failed", MethodBase.GetCurrentMethod().Name));
return 0;
}
}
catch (Exception e)
{
UserError.Show("Snapshot Failed", "Obtaining a Snaphot for the Window Failed.");
Log.Error(string.Format("{0}() - error thrown", MethodBase.GetCurrentMethod().Name), e);
return 0;
}
}
#endregion
#region Window Events we can extend on
public void WindowEvent_MaximizeOccured(int nHeight, int nWidth)
{
}
public void WindowEvent_MinimizeOccured()
{
}
public void WindowEvent_WindowActivated()
{
}
public void WindowEvent_WindowDeactivated()
{
}
#endregion
#region Resolver Client Events
public void ReResolve(int pid, IntPtr hWnd)
{
Log.Debug(string.Format("{0}() - Debug - ReResolve is called for {0} and {1}", pid, hWnd));
}
public void hWndInitialActivate(int pid, IntPtr hWnd, string ProcessStartUpPrms)
{
try
{
m_ButtonState = BHInteracter.SetW32ButtonToNewState(m_hWndParent, BHInteracter.BUTTON_HOOK_STATE.BUTTON_ADD);
Log.Debug(string.Format("{0}() - --- TEST --- ProcessStartUpPrms", ProcessStartUpPrms));
//// We need to resolve the window here
//ResolverDispatch resolver = new Resolver.ResolverDispatch();
//ArtifactGroup artifacts = resolver.GetArtifacts((IntPtr)hWnd);
//// If we can resolve this window then we want to be checking
//if (artifacts.Length >= 1)
//{
// Artifact curArtifact = artifacts.GetPrimary;
// bool bFound = SrvrCommon.IsArtifactInCurrentWorkspace(curArtifact);
// if (bFound)
// m_ButtonState = BHInteracter.SetW32ButtonToNewState(m_hWndParent, BHInteracter.BUTTON_HOOK_STATE.BUTTON_DELETE);
// else
// m_ButtonState = BHInteracter.SetW32ButtonToNewState(m_hWndParent, BHInteracter.BUTTON_HOOK_STATE.BUTTON_ADD);
//}
//else
//{
// Log.Error(string.Format("{0}() - WPForm could not resolve this Window - disabling the Caption Button", MethodBase.GetCurrentMethod().Name));
// m_ButtonState = BHInteracter.SetW32ButtonToNewState(m_hWndParent, BHInteracter.BUTTON_HOOK_STATE.BUTTON_NONE);
//}
}
catch (Exception e)
{
Log.Error(string.Format("{0}() - WPForm could not resolve this Window - disabling the Caption Button", MethodBase.GetCurrentMethod().Name), e);
}
}
public void hWndLastDeactivate(int pid, IntPtr hWnd)
{
Log.Debug(string.Format("{0}() - Debug - hWndLastDeactivate is called for {0} and {1}", pid, hWnd));
}
public void DragNDropOccured(int pid, IntPtr hWnd, int nFiles, string SemiColonSepFileNames)
{
Log.Debug(string.Format("{0}() - Debug - DragNDropOccured is called with {0} and {1} and {2}", pid, hWnd, nFiles, SemiColonSepFileNames));
}
public void OpenOrSaveFileDialogOccured(int pid, IntPtr hWnd, string possibleLocAndFileName, string FileTypes)
{
Log.Debug(string.Format("{0}() - Debug - DragNDropOccured is called with {0} and {1} and {2}", pid, hWnd, possibleLocAndFileName, FileTypes));
}
#endregion
}
}

View File

@@ -0,0 +1,131 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;
using System.Reflection;
// Ooganizer Namespaces
using Foo.Platform;
using Foo.Platform.Interacters;
namespace Foo.ClientServices.ButtonWPForm
{
/// <summary>
/// This class manages the creation/deletion of a Oogy CaptionButton Instance Exe.
/// A CaptionButton Instance hosts the ButtonHook.dll
/// </summary>
[ComVisible(false)]
internal class CaptionButtonStarter
{
// CaptionButton (ButtonHook.dll) Startup Delay
private const int CAPTIONBUTTON_STARTUP_DELAY_MILISECONDS = 4000;
// Member Variables
private static Thread s_ButtonHookKeepAliveThread = null;
private static bool s_ButtonHookKeepAliveThreadIsInitialized = false;
// Declare the Log4net Variable
private static log4net.ILog Log = Logger.GetLog4NetInterface(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// Constructor by default will launch the thread if needed
/// </summary>
static CaptionButtonStarter()
{
StartButtonHookKeepAliveThreadIfNeeded();
}
/// <summary>
/// Use this property to set the CaptionButton to running / not running
/// </summary>
public static bool Run
{
get { return s_ButtonHookKeepAliveThreadIsInitialized; }
set
{
if (!value)
TerminateButtonHookKeepAliveThreadIfNeeded();
s_ButtonHookKeepAliveThreadIsInitialized = value;
}
}
/// <summary>
/// ButtonHookKeepAliveThread Thread for ButtonHook.dll - handled internally
/// </summary>
private static void ButtonHookKeepAliveThreadProc()
{
Thread.Sleep(CAPTIONBUTTON_STARTUP_DELAY_MILISECONDS);
while (true) // Make Sure ButtonHook stays alive (No User kills it for any reason)
{
if (!BHInteracter.IsCaptionButtonRunning())
{
Log.Info(string.Format("{0}() - ButtonHookKeepAliveThread - About to call StartCaptionButton()", MethodBase.GetCurrentMethod().Name));
// Launch OogyCaptionButton Process EXE
BHInteracter.StartCaptionButton();
// wait a little before checking again...
Thread.Sleep(100);
if (BHInteracter.IsCaptionButtonRunning())
Log.Info(string.Format("{0}() - StartCaptionButton() Succeeded", MethodBase.GetCurrentMethod().Name));
else
Log.Error(string.Format("{0}() - StartCaptionButton() Failed", MethodBase.GetCurrentMethod().Name));
}
if (!s_ButtonHookKeepAliveThreadIsInitialized)
{
s_ButtonHookKeepAliveThreadIsInitialized = true;
Log.Info(string.Format("{0}() - ButtonWPForm ButtonHookKeepAliveThread is initialized s_ButtonHookKeepAliveThreadIsInitialized is True", MethodBase.GetCurrentMethod().Name));
}
// Checking every 30 seconds (quickly) should be more than enough
Thread.Sleep(30000);
}
}
/// <summary>
/// Use this function to start ThreadProc(above) if needed. COM+ can shutdown the thread anytime,
/// we need to make sure that the thread is alive BEFORE calling ButtonForms
/// </summary>
private static void StartButtonHookKeepAliveThreadIfNeeded()
{
if (s_ButtonHookKeepAliveThread != null && s_ButtonHookKeepAliveThread.IsAlive)
{
return;
}
else
{
s_ButtonHookKeepAliveThreadIsInitialized = false;
// Start a new Thread so it can become the Message Loop
s_ButtonHookKeepAliveThread = new Thread(new ThreadStart(CaptionButtonStarter.ButtonHookKeepAliveThreadProc));
// GUI components require the thread to be STA; otherwise throws an error
s_ButtonHookKeepAliveThread.SetApartmentState(ApartmentState.STA);
s_ButtonHookKeepAliveThread.Start();
}
}
/// <summary>
/// Terminate the ButtonHook.dll by killing the Process
/// </summary>
private static void TerminateButtonHookKeepAliveThreadIfNeeded()
{
if (s_ButtonHookKeepAliveThreadIsInitialized)
{
s_ButtonHookKeepAliveThread.Abort();
s_ButtonHookKeepAliveThreadIsInitialized = false;
Log.Info(string.Format("{0}() - ButtonWPForm is ButtonHookKeepAliveThread shutdown s_ButtonHookKeepAliveThreadIsInitialized is False", MethodBase.GetCurrentMethod().Name));
// Kill the OogyCaptionButton Process EXE
BHInteracter.StopCaptionButton();
}
}
}
}

View File

@@ -0,0 +1,90 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Threading;
// Ooganizer Namespaces
using Foo.Platform;
using Foo.DataAccessLayer;
using Foo.DataAccessLayer.DataTypes;
using System.Runtime.InteropServices;
namespace Foo.ClientServices.ButtonWPForm
{
/// <summary>
/// This class is responsible for launch all secondary threads required for this application as
/// well as hold any variables that are needed by all classes
/// created.
/// </summary>
[ComVisible(false)]
internal class ComponentState
{
// Declare the Log4net Variable
private static log4net.ILog Log = Logger.GetLog4NetInterface(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// This class manages the state / main variables of the COM+ that maybe needed by multiple classes.
/// It is responsible for starting and stopping any secondary threads.
/// </summary>
static ComponentState()
{
// We must subscribe to assembly resolver
Log.Info(string.Format("{0}() - ButtonWPFormCCW ComponentState() called. Application is starting...", MethodBase.GetCurrentMethod().Name));
// Let's Preload the Database *Right here, right now* that should be good for all of us
Data.Artifacts.DoesArtifactExistInSystem(DataTypeHelpers.CreateLocationOnlyArtifact("C:\\Dummy.file"));
// Start Dispatcher Thread
Log.Info(string.Format("{0}() - ButtonWPFormCCW ComponentState() called. Activating DispatcherThread", MethodBase.GetCurrentMethod().Name));
DispatcherThread.Run = true;
// Start ButtonHookKeepAlive Thread
if (!DebugSpec.SkipCaptionButtonStarter)
{
Log.Info(string.Format("{0}() - ButtonWPFormCCW ComponentState() called. Calling CaptionButtonStarter", MethodBase.GetCurrentMethod().Name));
CaptionButtonStarter.Run = true;
}
else
{
Log.Info(string.Format("{0}() - ButtonWPFormCCW ComponentState() called. Skipping CaptionButtonStarter due to DebugSpec Settings", MethodBase.GetCurrentMethod().Name));
}
}
/// <summary>
/// Private Variables
/// </summary>
private static bool s_bApplicationIsRunning = false;
/// <summary>
/// Use this to enable/disable all threads and variables for
/// the component states
/// </summary>
public static bool ApplicationIsRunning
{
get { return s_bApplicationIsRunning; }
set
{
if (!value)
{
Log.Info(string.Format("{0}() - ComponentState() sApplicationRunning set to False", MethodBase.GetCurrentMethod().Name));
DispatcherThread.Run = false;
CaptionButtonStarter.Run = false;
}
s_bApplicationIsRunning = value;
}
}
/// <summary>
/// Use this to access the ButtonFormMgr Object in order to
/// communicate to ButtonForms (Setter should only be called by
/// DispatcherThread)
/// </summary>
public static ButtonFormMgr ButtonFormMgr
{
get { return DispatcherThread.s_ButtonFormMgr; }
}
}
}

View File

@@ -0,0 +1,131 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;
using System.Reflection;
// Ooganizer Namespaces
using Foo.Platform;
using System.Windows.Threading;
namespace Foo.ClientServices.ButtonWPForm
{
/// <summary>
/// This class is responsible for creation and deltion of ButtonFormMgr.cs on a
/// Dispatcher Thread. ~The Dispatcher is responsible for all the messages being passed
/// for the Form Objects, it must be running at all times and created before any forms get
/// created.
/// </summary>
[ComVisible(false)]
class DispatcherThread
{
// Member Variables
private static Thread s_DispatcherThread = null;
private static bool s_DispatcherThreadIsInitialized = false;
internal static ButtonFormMgr s_ButtonFormMgr = null;
// Declare the Log4net Variable
private static log4net.ILog Log = Logger.GetLog4NetInterface(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// Constructor by default will launch the thread if needed
/// </summary>
static DispatcherThread()
{
Log.Info(string.Format("{0}() - DispatcherThread() called", MethodBase.GetCurrentMethod().Name));
StartDispatcherThreadIfNeeded();
}
/// <summary>
/// Use this property to set the Dispatcher to running / not running
/// </summary>
public static bool Run
{
get { return s_DispatcherThreadIsInitialized; }
set
{
if (!value)
TerminateDispatcherThreadIfNeeded();
s_DispatcherThreadIsInitialized = value;
}
}
/// <summary>
/// Message Loop Thread for ButtonForm
/// </summary>
private static void DispatcherThreadProc()
{
// Create ButtonFormMgr Object on this thread *Allow global access to the object*
Log.Info(string.Format("{0}() - About to new ButtonFormMgr via DispatcherThread", MethodBase.GetCurrentMethod().Name));
s_ButtonFormMgr = new ButtonFormMgr(Dispatcher.CurrentDispatcher);
Log.Info(string.Format("{0}() - ButtonWPForm DispatcherThread is initialized s_DispatcherThreadIsInitialized is True", MethodBase.GetCurrentMethod().Name));
s_DispatcherThreadIsInitialized = true; // always set to true to allow caller to exit out
if (s_ButtonFormMgr != null)
{
Log.Info(string.Format("{0}() - ButtonFormMgr Launched via DispatcherThread", MethodBase.GetCurrentMethod().Name));
//Enter Dispatcher Message Loop
System.Windows.Threading.Dispatcher.Run();
}
else
{
Log.Error(string.Format("{0}() - ButtonFormMgr Launch Failed! Exiting Thread - Major Error must have occured", MethodBase.GetCurrentMethod().Name));
// exit thread - no need to stay here
}
}
/// <summary>
/// Use this function to start ThreadProc(above) if needed. COM+ can shutdown the thread anytime,
/// we need to make sure that the thread is alive BEFORE calling ButtonForms
/// </summary>
private static void StartDispatcherThreadIfNeeded()
{
if (s_DispatcherThread != null && s_DispatcherThread.IsAlive)
{
return;
}
else
{
s_DispatcherThreadIsInitialized = false;
// Start a new Thread so it can become the Message Loop
s_DispatcherThread = new Thread(new ThreadStart(DispatcherThread.DispatcherThreadProc));
// GUI components require the thread to be STA; otherwise throws an error
s_DispatcherThread.SetApartmentState(ApartmentState.STA);
Log.Info(string.Format("{0}() - Starting DispatcherThread...", MethodBase.GetCurrentMethod().Name));
s_DispatcherThread.Start();
Log.Info(string.Format("{0}() - DispatcherThread Started.", MethodBase.GetCurrentMethod().Name));
// Make sure the Application Object is running
// (COM will eventually just time out otherwise)
//while (!s_DispatcherThreadIsInitialized)
// System.Threading.Thread.Sleep(20); // Syncronous call
}
}
/// <summary>
/// Terminates all ButtonForm Objects and the Message Dispatcher Thread *do this only on shutdown*
/// </summary>
private static void TerminateDispatcherThreadIfNeeded()
{
if (s_DispatcherThreadIsInitialized)
{
// Delete ButtonFormMgr and all ButtonForms from this thread
s_ButtonFormMgr.TerminateDISP();
s_ButtonFormMgr = null;
s_DispatcherThread.Abort();
s_DispatcherThreadIsInitialized = false;
Log.Info(string.Format("{0}() - ButtonWPForm is DispatcherThread shutdown s_DispatcherThreadIsInitialized is False", MethodBase.GetCurrentMethod().Name));
}
}
}
}

View File

@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace Foo.ClientServices.ButtonWPForm
{
/// <summary>
/// Button Hook uses the IButtonForm Interface to call into ButtonFormCCW.
/// This allows ButtonHook to communicate to us the state ButtonFormCCW should take.
/// ButtonForm will handle the methods/Events below and respond as needed.
/// ~We use the hParentWND to track which ButtonForm Instance we are talking with
/// (this is why all calls below have it in the method call ~it works better that way in COM+)
/// </summary>
[Guid("2CF9E641-57B7-436f-80E1-EF3127CB5C0A")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
[ComVisible(true)]
public interface IButtonForm
{
// Custom Events
int W32BUTTONCLICKED();
// Called when ButtonHook activates/deactivates the COM Object
void WPFThreadProc_ButtonWPForm_Activated(int hParentWND, int hButtonWND);
void WPFThreadProc_ButtonWPForm_Deactivated();
// Hooked Window Events
void WindowEvent_MaximizeOccured(int nHeight, int nWidth);
void WindowEvent_MinimizeOccured();
void WindowEvent_WindowActivated();
void WindowEvent_WindowDeactivated();
}
}

View File

@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace Foo.ClientServices.ButtonWPForm
{
/// <summary>
/// This interface defines the communication from ButtonForm to
/// it's ButtonFormPage Client
/// </summary>
[ComVisible(false)]
public interface IButtonFormPage
{
ButtonForm ParentWPFContainer { get; set; }
}
}

View File

@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace Foo.ClientServices.ButtonWPForm
{
/// <summary>
/// Button Hook uses the IClientEvents Interface to let us know of certain events
/// which may require us to re-resolve the Window.
/// ~This is an important feature we need to do be accurate with all our artifacts.
/// We are piggy-backing on ButtonWPForm in order to have less components
/// </summary>
[Guid("F1AF5CAD-B9AB-4a20-80F1-EB68C577ABC4")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
[ComVisible(true)]
public interface IClientEvents
{
// An Event occured that could potentially have made artifact changes
void ReResolve(int pid, IntPtr hWnd);
// First and Last Activation Events
void hWndInitialActivate(int pid, IntPtr hWnd, string ProcessStartUpPrms);
void hWndLastDeactivate(int pid, IntPtr hWnd);
// User File Events
void DragNDropOccured(int pid, IntPtr hWnd, int nFiles, string SemiColonSepFileNames);
void OpenOrSaveFileDialogOccured(int pid, IntPtr hWnd, string possibleLocAndFileName, string FileTypes);
}
}

Binary file not shown.

View File

@@ -0,0 +1,62 @@
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Windows;
using System.EnterpriseServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("ButtonWPForm")]
[assembly: AssemblyDescription("Performance Caching for ButtonWPForm")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Ooganizer Corporation")]
[assembly: AssemblyProduct("ButtonWPForm")]
[assembly: AssemblyCopyright("Copyright © Ooganizer Corporation 2009")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(true)]
[assembly: ApplicationID("E6A84616-5ED1-4679-B26D-64F80A5E41CD")]
[assembly: ApplicationActivation(ActivationOption.Server)]
[assembly: ApplicationAccessControl(Value = false, Authentication = AuthenticationOption.None)]
[assembly: ApplicationName("Foo.ClientServices")]
[assembly: Description("Provides Data Access and Performance Caching for Ooganizer Components")]
//In order to begin building localizable applications, set
//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file
//inside a <PropertyGroup>. For example, if you are using US english
//in your source files, set the <UICulture> to en-US. Then uncomment
//the NeutralResourceLanguage attribute below. Update the "en-US" in
//the line below to match the UICulture setting in the project file.
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,63 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:2.0.50727.4200
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Foo.ClientServices.ButtonWPForm.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Foo.ClientServices.ButtonWPForm.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}

View File

@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -0,0 +1,26 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:2.0.50727.4200
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Foo.ClientServices.ButtonWPForm.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "9.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
}
}

View File

@@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>