Browse Source
git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@47 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61shortcuts
95 changed files with 21209 additions and 5 deletions
@ -0,0 +1,63 @@
@@ -0,0 +1,63 @@
|
||||
<AddIn name="SharpDevelop Debugger" author="David Srbecký" copyright="GPL" url="" description="SharpDevelop Managed Debugger" version="0.1.0.0"> |
||||
<Runtime> |
||||
<Import assembly="Debugger.AddIn.dll"/> |
||||
</Runtime> |
||||
|
||||
<Path name="/SharpDevelop/Services/DebuggerService/Debugger"> |
||||
<Class id="DefaultDebugger" class="ICSharpCode.SharpDevelop.Services.WindowsDebugger"/> |
||||
</Path> |
||||
|
||||
<!--<Path name = "/SharpDevelop/Workbench/MainMenu/View"> |
||||
<MenuItem id = "Debugger" label = "${res:XML.MainMenu.ViewMenu.DebugMenu}"> |
||||
<MenuItem id = "DebugViewMenuBuilder" |
||||
type = "Builder" |
||||
class = "ICSharpCode.SharpDevelop.Commands.DebugSelectionMenuBuilder" /> |
||||
</MenuItem> |
||||
</Path>--> |
||||
|
||||
<!--<Path name = "/SharpDevelop/Workbench/MainMenu/Debug"> |
||||
<MenuItem id = "CatchHandledExceptionsSeparator" |
||||
type = "Separator" |
||||
insertafter = "Step out" /> |
||||
<MenuItem id = "CatchHandledExceptions" |
||||
label = "" |
||||
class = "ICSharpCode.SharpDevelop.Services.DebbugerExceptionMenuBuilder"/> |
||||
</Path>--> |
||||
|
||||
<Path name = "/SharpDevelop/Workbench/Pads"> |
||||
<Pad id = "BreakPointsPad3" |
||||
category = "Main" |
||||
title = "Breakpoints" |
||||
icon = "PadIcons.ProjectBrowser" |
||||
shortcut = "Control|Alt|B" |
||||
class = "ICSharpCode.SharpDevelop.Gui.Pads.BreakPointsPad"/> |
||||
|
||||
<Pad id = "CallStackPad3" |
||||
category = "Main" |
||||
title = "Callstack" |
||||
icon = "PadIcons.ProjectBrowser" |
||||
shortcut = "Control|Alt|C" |
||||
class = "ICSharpCode.SharpDevelop.Gui.Pads.CallStackPad"/> |
||||
|
||||
<Pad id = "LoadedModulesPad3" |
||||
category = "Main" |
||||
title = "Loaded modules" |
||||
icon = "PadIcons.ProjectBrowser" |
||||
shortcut = "Control|Alt|U" |
||||
class = "ICSharpCode.SharpDevelop.Gui.Pads.LoadedModulesPad"/> |
||||
|
||||
<Pad id = "RunningThreadsPad3" |
||||
category = "Main" |
||||
title = "Threads" |
||||
icon = "PadIcons.ProjectBrowser" |
||||
shortcut = "Control|Alt|H" |
||||
class = "ICSharpCode.SharpDevelop.Gui.Pads.RunningThreadsPad"/> |
||||
|
||||
<Pad id = "LocalVarPad3" |
||||
category = "Main" |
||||
title = "Local variables" |
||||
icon = "PadIcons.ProjectBrowser" |
||||
shortcut = "Control|Alt|V" |
||||
class = "ICSharpCode.SharpDevelop.Gui.Pads.LocalVarPad"/> |
||||
</Path> |
||||
</AddIn> |
@ -0,0 +1,74 @@
@@ -0,0 +1,74 @@
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
<PropertyGroup> |
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> |
||||
<ProductVersion>8.0.41115</ProductVersion> |
||||
<SchemaVersion>2.0</SchemaVersion> |
||||
<ProjectGuid>{EC06F96A-AEEC-49D6-B03D-AB87C6EB674C}</ProjectGuid> |
||||
<OutputType>Library</OutputType> |
||||
<RootNamespace>Debugger.AddIn</RootNamespace> |
||||
<AssemblyName>Debugger.AddIn</AssemblyName> |
||||
<WarningLevel>4</WarningLevel> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> |
||||
<DebugSymbols>true</DebugSymbols> |
||||
<DebugType>full</DebugType> |
||||
<Optimize>false</Optimize> |
||||
<OutputPath>..\..\..\..\..\..\AddIns\AddIns\Misc\Debugger\</OutputPath> |
||||
<DefineConstants>DEBUG;TRACE</DefineConstants> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> |
||||
<DebugType>pdbonly</DebugType> |
||||
<Optimize>true</Optimize> |
||||
<OutputPath>..\..\..\..\..\..\AddIns\AddIns\Misc\Debugger\</OutputPath> |
||||
<DefineConstants>TRACE</DefineConstants> |
||||
</PropertyGroup> |
||||
<ItemGroup> |
||||
<Reference Include="System" /> |
||||
<Reference Include="System.Data" /> |
||||
<Reference Include="System.Drawing" /> |
||||
<Reference Include="System.Windows.Forms" /> |
||||
<Reference Include="System.Xml" /> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<None Include="Debugger.AddIn.addin"> |
||||
<CopyToOutputDirectory>True</CopyToOutputDirectory> |
||||
</None> |
||||
<Compile Include="Src\AssemblyInfo.cs" /> |
||||
<Compile Include="Src\Pads\BreakPointsPad.cs" /> |
||||
<Compile Include="Src\Pads\CallStackPad.cs" /> |
||||
<Compile Include="Src\Pads\LoadedModulesPad.cs" /> |
||||
<Compile Include="Src\Pads\LocalVarPad.cs" /> |
||||
<Compile Include="Src\Pads\RunningThreadsPad.cs" /> |
||||
<Compile Include="Src\Service\WindowsDebugger.cs" /> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<ProjectReference Include="..\..\..\..\..\Libraries\ICSharpCode.TextEditor\Project\ICSharpCode.TextEditor.csproj"> |
||||
<Project>{2D18BE89-D210-49EB-A9DD-2246FBB3DF6D}</Project> |
||||
<Name>ICSharpCode.TextEditor</Name> |
||||
<Private>False</Private> |
||||
</ProjectReference> |
||||
<ProjectReference Include="..\..\..\..\..\Main\Base\Project\ICSharpCode.SharpDevelop.csproj"> |
||||
<Project>{2748AD25-9C63-4E12-877B-4DCE96FBED54}</Project> |
||||
<Name>ICSharpCode.SharpDevelop</Name> |
||||
<Private>False</Private> |
||||
</ProjectReference> |
||||
<ProjectReference Include="..\..\..\..\..\Main\Core\Project\ICSharpCode.Core.csproj"> |
||||
<Project>{35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}</Project> |
||||
<Name>ICSharpCode.Core</Name> |
||||
<Private>False</Private> |
||||
</ProjectReference> |
||||
<ProjectReference Include="..\..\Debugger.Core\Project\Debugger.Core.csproj"> |
||||
<Project>{1D18D788-F7EE-4585-A23B-34DC8EC63CB8}</Project> |
||||
<Name>Debugger.Core</Name> |
||||
<Private>True</Private> |
||||
</ProjectReference> |
||||
<ProjectReference Include="..\..\TreeListView\Project\TreeListView.csproj"> |
||||
<Project>{B08385CD-F0CC-488C-B4F4-EEB34B6D2688}</Project> |
||||
<Name>TreeListView</Name> |
||||
<Private>False</Private> |
||||
</ProjectReference> |
||||
<Folder Include="Configuration\" /> |
||||
</ItemGroup> |
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" /> |
||||
</Project> |
@ -0,0 +1,7 @@
@@ -0,0 +1,7 @@
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
<PropertyGroup> |
||||
<LastOpenVersion>8.0.41115</LastOpenVersion> |
||||
<ProjectView>ShowAllFiles</ProjectView> |
||||
<ProjectTrust>0</ProjectTrust> |
||||
</PropertyGroup> |
||||
</Project> |
@ -0,0 +1,58 @@
@@ -0,0 +1,58 @@
|
||||
using System.Reflection; |
||||
using System.Runtime.CompilerServices; |
||||
|
||||
//
|
||||
// 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("")] |
||||
[assembly: AssemblyDescription("")] |
||||
[assembly: AssemblyConfiguration("")] |
||||
[assembly: AssemblyCompany("")] |
||||
[assembly: AssemblyProduct("")] |
||||
[assembly: AssemblyCopyright("")] |
||||
[assembly: AssemblyTrademark("")] |
||||
[assembly: AssemblyCulture("")] |
||||
|
||||
//
|
||||
// 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 Revision and Build Numbers
|
||||
// by using the '*' as shown below:
|
||||
|
||||
[assembly: AssemblyVersion("1.0.*")] |
||||
|
||||
//
|
||||
// In order to sign your assembly you must specify a key to use. Refer to the
|
||||
// Microsoft .NET Framework documentation for more information on assembly signing.
|
||||
//
|
||||
// Use the attributes below to control which key is used for signing.
|
||||
//
|
||||
// Notes:
|
||||
// (*) If no key is specified, the assembly is not signed.
|
||||
// (*) KeyName refers to a key that has been installed in the Crypto Service
|
||||
// Provider (CSP) on your machine. KeyFile refers to a file which contains
|
||||
// a key.
|
||||
// (*) If the KeyFile and the KeyName values are both specified, the
|
||||
// following processing occurs:
|
||||
// (1) If the KeyName can be found in the CSP, that key is used.
|
||||
// (2) If the KeyName does not exist and the KeyFile does exist, the key
|
||||
// in the KeyFile is installed into the CSP and used.
|
||||
// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
|
||||
// When specifying the KeyFile, the location of the KeyFile should be
|
||||
// relative to the project output directory which is
|
||||
// %Project Directory%\obj\<configuration>. For example, if your KeyFile is
|
||||
// located in the project directory, you would specify the AssemblyKeyFile
|
||||
// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
|
||||
// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
|
||||
// documentation for more information on this.
|
||||
//
|
||||
[assembly: AssemblyDelaySign(false)] |
||||
[assembly: AssemblyKeyFile("")] |
||||
[assembly: AssemblyKeyName("")] |
@ -0,0 +1,146 @@
@@ -0,0 +1,146 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// <owner name="Mike Krueger" email="mike@icsharpcode.net"/>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Windows.Forms; |
||||
using System.Drawing; |
||||
using System.CodeDom.Compiler; |
||||
using System.Collections; |
||||
using System.IO; |
||||
using System.Diagnostics; |
||||
using ICSharpCode.Core; |
||||
//using ICSharpCode.Core.Services;
|
||||
using ICSharpCode.SharpDevelop.Services; |
||||
|
||||
//using ICSharpCode.Core.Properties;
|
||||
|
||||
using DebuggerLibrary; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Gui.Pads |
||||
{ |
||||
public class BreakPointsPad : AbstractPadContent |
||||
{ |
||||
ListView breakpointsList; |
||||
|
||||
ColumnHeader name = new ColumnHeader(); |
||||
ColumnHeader path = new ColumnHeader(); |
||||
|
||||
public override Control Control { |
||||
get { |
||||
return breakpointsList; |
||||
} |
||||
} |
||||
|
||||
public BreakPointsPad() //: base("${res:MainWindow.Windows.Debug.Breakpoints}", null)
|
||||
{ |
||||
InitializeComponents(); |
||||
} |
||||
|
||||
void InitializeComponents() |
||||
{ |
||||
breakpointsList = new ListView(); |
||||
breakpointsList.FullRowSelect = true; |
||||
breakpointsList.AutoArrange = true; |
||||
breakpointsList.Alignment = ListViewAlignment.Left; |
||||
breakpointsList.View = View.Details; |
||||
breakpointsList.Dock = DockStyle.Fill; |
||||
breakpointsList.GridLines = false; |
||||
breakpointsList.Activation = ItemActivation.OneClick; |
||||
breakpointsList.CheckBoxes = true; |
||||
breakpointsList.Columns.AddRange(new ColumnHeader[] {name, path} ); |
||||
breakpointsList.ItemCheck += new ItemCheckEventHandler(BreakpointsListItemCheck); |
||||
|
||||
name.Width = 300; |
||||
path.Width = 400; |
||||
|
||||
NDebugger.DebuggingResumed += new DebuggerEventHandler(debuggerService_OnDebuggingResumed); |
||||
NDebugger.Breakpoints.BreakpointAdded += new DebuggerLibrary.BreakpointEventHandler(AddBreakpoint); |
||||
NDebugger.Breakpoints.BreakpointStateChanged += new DebuggerLibrary.BreakpointEventHandler(RefreshBreakpoint); |
||||
NDebugger.Breakpoints.BreakpointRemoved += new DebuggerLibrary.BreakpointEventHandler(RemoveBreakpoint); |
||||
NDebugger.Breakpoints.BreakpointHit += new DebuggerLibrary.BreakpointEventHandler(Breakpoints_OnBreakpointHit); |
||||
|
||||
RedrawContent(); |
||||
} |
||||
|
||||
public override void RedrawContent() |
||||
{ |
||||
name.Text = "Name"; |
||||
path.Text = "Path"; |
||||
} |
||||
|
||||
void BreakpointsListItemCheck(object sender, ItemCheckEventArgs e) |
||||
{ |
||||
DebuggerLibrary.Breakpoint breakpoint = breakpointsList.Items[e.Index].Tag as DebuggerLibrary.Breakpoint; |
||||
if (breakpoint != null) { |
||||
breakpoint.Enabled = (e.NewValue == CheckState.Checked); |
||||
} |
||||
if (WorkbenchSingleton.Workbench.ActiveWorkbenchWindow != null) { |
||||
WorkbenchSingleton.Workbench.ActiveWorkbenchWindow.ActiveViewContent.RedrawContent(); |
||||
} |
||||
} |
||||
|
||||
void FillList() |
||||
{ |
||||
|
||||
|
||||
breakpointsList.ItemCheck -= new ItemCheckEventHandler(BreakpointsListItemCheck); |
||||
breakpointsList.BeginUpdate(); |
||||
breakpointsList.Items.Clear(); |
||||
foreach(DebuggerLibrary.Breakpoint b in NDebugger.Breakpoints) { |
||||
AddBreakpoint(this, new BreakpointEventArgs(b)); |
||||
} |
||||
breakpointsList.EndUpdate(); |
||||
breakpointsList.ItemCheck += new ItemCheckEventHandler(BreakpointsListItemCheck); |
||||
} |
||||
|
||||
void AddBreakpoint(object sender, BreakpointEventArgs e) |
||||
{ |
||||
ListViewItem item = new ListViewItem(); |
||||
item.Tag = e.Breakpoint; |
||||
breakpointsList.Items.Add(item); |
||||
RefreshBreakpoint(this, e); |
||||
} |
||||
|
||||
void RefreshBreakpoint(object sender, BreakpointEventArgs e) |
||||
{ |
||||
foreach (ListViewItem item in breakpointsList.Items) { |
||||
if (e.Breakpoint == item.Tag) { |
||||
item.SubItems.Clear(); |
||||
item.Checked = e.Breakpoint.Enabled; |
||||
item.Text = Path.GetFileName(e.Breakpoint.SourcecodeSegment.SourceFilename) + ", Line = " + e.Breakpoint.SourcecodeSegment.StartLine.ToString(); |
||||
item.ForeColor = e.Breakpoint.HadBeenSet ? Color.Black : Color.Gray; |
||||
item.SubItems.AddRange(new string[] {Path.GetDirectoryName(e.Breakpoint.SourcecodeSegment.SourceFilename)}); |
||||
} |
||||
} |
||||
} |
||||
|
||||
void RemoveBreakpoint(object sender, BreakpointEventArgs e) |
||||
{ |
||||
foreach (ListViewItem item in breakpointsList.Items) { |
||||
if (e.Breakpoint == item.Tag) { |
||||
item.Remove(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
void Breakpoints_OnBreakpointHit(object sender, BreakpointEventArgs e) |
||||
{ |
||||
foreach (ListViewItem item in breakpointsList.Items) { |
||||
if (e.Breakpoint == item.Tag) { |
||||
item.BackColor = System.Drawing.Color.DarkRed; |
||||
item.ForeColor = System.Drawing.Color.White; |
||||
} |
||||
} |
||||
} |
||||
|
||||
void debuggerService_OnDebuggingResumed(object sender, DebuggerEventArgs e) |
||||
{ |
||||
breakpointsList.BeginUpdate(); |
||||
foreach(DebuggerLibrary.Breakpoint b in NDebugger.Breakpoints) |
||||
RefreshBreakpoint(this, new BreakpointEventArgs(b)); |
||||
breakpointsList.EndUpdate(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,99 @@
@@ -0,0 +1,99 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// <owner name="Mike Krueger" email="mike@icsharpcode.net"/>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Windows.Forms; |
||||
using System.Drawing; |
||||
using System.CodeDom.Compiler; |
||||
using System.Collections; |
||||
using System.IO; |
||||
using System.Diagnostics; |
||||
using ICSharpCode.Core; |
||||
//using ICSharpCode.Core.Services;
|
||||
using ICSharpCode.SharpDevelop.Services; |
||||
|
||||
//using ICSharpCode.Core.Properties;
|
||||
|
||||
using DebuggerLibrary; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Gui.Pads |
||||
{ |
||||
public class CallStackPad : AbstractPadContent |
||||
{ |
||||
ListView callStackList; |
||||
|
||||
//
|
||||
//WindowsDebugger DebuggerService = (WindowsDebugger)((DebuggerService)ServiceManager.Services.GetService(typeof(DebuggerService))).CurrentDebugger;
|
||||
WindowsDebugger debugger; |
||||
|
||||
ColumnHeader name = new ColumnHeader(); |
||||
ColumnHeader language = new ColumnHeader(); |
||||
|
||||
public override Control Control { |
||||
get { |
||||
return callStackList; |
||||
} |
||||
} |
||||
|
||||
public CallStackPad()// : base("${res:MainWindow.Windows.Debug.CallStack}", null)
|
||||
{ |
||||
InitializeComponents(); |
||||
} |
||||
|
||||
void InitializeComponents() |
||||
{ |
||||
debugger = (WindowsDebugger)DebuggerService.CurrentDebugger; |
||||
callStackList = new ListView(); |
||||
callStackList.FullRowSelect = true; |
||||
callStackList.AutoArrange = true; |
||||
callStackList.Alignment = ListViewAlignment.Left; |
||||
callStackList.View = View.Details; |
||||
callStackList.Dock = DockStyle.Fill; |
||||
callStackList.GridLines = false; |
||||
callStackList.Activation = ItemActivation.OneClick; |
||||
callStackList.Columns.AddRange(new ColumnHeader[] {name, language} ); |
||||
callStackList.ItemActivate += new EventHandler(CallStackListItemActivate); |
||||
name.Width = 300; |
||||
language.Width = 400; |
||||
|
||||
NDebugger.IsDebuggingChanged += new DebuggerEventHandler(DebuggerStateChanged); |
||||
NDebugger.IsProcessRunningChanged += new DebuggerEventHandler(DebuggerStateChanged); |
||||
|
||||
RedrawContent(); |
||||
} |
||||
|
||||
public override void RedrawContent() |
||||
{ |
||||
name.Text = "Name"; |
||||
language.Text = "Language"; |
||||
} |
||||
|
||||
void CallStackListItemActivate(object sender, EventArgs e) |
||||
{ |
||||
debugger.selectedFunction = (Function)(callStackList.SelectedItems[0].Tag); |
||||
debugger.JumpToCurrentLine(); |
||||
} |
||||
|
||||
public void DebuggerStateChanged(object sender, DebuggerEventArgs e) |
||||
{ |
||||
RefreshList(); |
||||
} |
||||
|
||||
public void RefreshList() |
||||
{ |
||||
callStackList.BeginUpdate(); |
||||
callStackList.Items.Clear(); |
||||
if (debugger.IsProcessRunning == false && debugger.selectedThread != null) { |
||||
foreach (Function f in debugger.selectedThread.Callstack) { |
||||
ListViewItem item = new ListViewItem(new string[] { f.Name, "" }); |
||||
item.Tag = f; |
||||
item.ForeColor = f.Module.SymbolsLoaded ? Color.Black : Color.Gray; |
||||
callStackList.Items.Add(item); |
||||
} |
||||
} |
||||
callStackList.EndUpdate(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,110 @@
@@ -0,0 +1,110 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// <owner name="Mike Krueger" email="mike@icsharpcode.net"/>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Windows.Forms; |
||||
using System.Drawing; |
||||
using System.CodeDom.Compiler; |
||||
using System.Collections; |
||||
using System.IO; |
||||
using System.Diagnostics; |
||||
//using ICSharpCode.Core.Services;
|
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.SharpDevelop.Services; |
||||
//using ICSharpCode.Core.Properties;
|
||||
|
||||
using DebuggerLibrary; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Gui.Pads |
||||
{ |
||||
public class LoadedModulesPad : AbstractPadContent |
||||
{ |
||||
ListView loadedModulesList; |
||||
|
||||
ColumnHeader name = new ColumnHeader(); |
||||
ColumnHeader address = new ColumnHeader(); |
||||
ColumnHeader path = new ColumnHeader(); |
||||
ColumnHeader order = new ColumnHeader(); |
||||
ColumnHeader version = new ColumnHeader(); |
||||
ColumnHeader program = new ColumnHeader(); |
||||
ColumnHeader timestamp = new ColumnHeader(); |
||||
ColumnHeader information = new ColumnHeader(); |
||||
|
||||
|
||||
public override Control Control { |
||||
get { |
||||
return loadedModulesList; |
||||
} |
||||
} |
||||
|
||||
public LoadedModulesPad() //: base("${res:MainWindow.Windows.Debug.Modules}", null)
|
||||
{ |
||||
InitializeComponents(); |
||||
} |
||||
|
||||
void InitializeComponents() |
||||
{ |
||||
loadedModulesList = new ListView(); |
||||
loadedModulesList.FullRowSelect = true; |
||||
loadedModulesList.AutoArrange = true; |
||||
loadedModulesList.Alignment = ListViewAlignment.Left; |
||||
loadedModulesList.View = View.Details; |
||||
loadedModulesList.Dock = DockStyle.Fill; |
||||
loadedModulesList.GridLines = false; |
||||
loadedModulesList.Activation = ItemActivation.OneClick; |
||||
loadedModulesList.Columns.AddRange(new ColumnHeader[] {name, address, path, order, version, program, timestamp, information} ); |
||||
name.Width = 250; |
||||
address.Width = 100; |
||||
path.Width = 250; |
||||
order.Width = 80; |
||||
version.Width = 0;//50;
|
||||
program.Width = 0;//90;
|
||||
timestamp.Width = 0;//80;
|
||||
information.Width = 130; |
||||
|
||||
NDebugger.Modules.ModuleAdded += new DebuggerLibrary.ModuleEventHandler(AddModule); |
||||
NDebugger.Modules.ModuleRemoved += new DebuggerLibrary.ModuleEventHandler(RemoveModule); |
||||
|
||||
RedrawContent(); |
||||
} |
||||
|
||||
public override void RedrawContent() |
||||
{ |
||||
|
||||
name.Text = StringParser.Parse("${res:MainWindow.Windows.Debug.NameColumn}"); |
||||
address.Text = StringParser.Parse("${res:MainWindow.Windows.Debug.AddressColumn}"); |
||||
path.Text = StringParser.Parse("${res:MainWindow.Windows.Debug.PathColumn}"); |
||||
order.Text = StringParser.Parse("${res:MainWindow.Windows.Debug.OrderColumn}"); |
||||
version.Text = StringParser.Parse("${res:MainWindow.Windows.Debug.VersionColumn}"); |
||||
program.Text = StringParser.Parse("${res:MainWindow.Windows.Debug.ProgramColumn}"); |
||||
timestamp.Text = StringParser.Parse("${res:MainWindow.Windows.Debug.TimestampColumn}"); |
||||
information.Text = StringParser.Parse("${res:MainWindow.Windows.Debug.InformationColumn}"); |
||||
} |
||||
|
||||
void AddModule(object sender, ModuleEventArgs e) |
||||
{ |
||||
ListViewItem newItem = new ListViewItem(new string[] {e.Module.Filename, |
||||
String.Format("{0:X8}", e.Module.BaseAdress), |
||||
e.Module.DirectoryName, |
||||
e.Module.OrderOfLoading.ToString(), |
||||
"", |
||||
"", |
||||
"", |
||||
e.Module.SymbolsLoaded.ToString(), //StringParser.Parse(m.symbolsLoaded ? "${res:MainWindow.Windows.Debug.HasSymbols}" : "${res:MainWindow.Windows.Debug.HasNoSymbols}")
|
||||
}); |
||||
newItem.Tag = e.Module; |
||||
loadedModulesList.Items.Add(newItem); |
||||
} |
||||
|
||||
void RemoveModule(object sender, ModuleEventArgs e) |
||||
{ |
||||
foreach (ListViewItem item in loadedModulesList.Items) { |
||||
if (item.Tag == e.Module) { |
||||
item.Remove(); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,142 @@
@@ -0,0 +1,142 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// <owner name="Mike Krueger" email="mike@icsharpcode.net"/>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Windows.Forms; |
||||
using System.Drawing; |
||||
using System.CodeDom.Compiler; |
||||
using System.Collections; |
||||
using System.IO; |
||||
using System.Diagnostics; |
||||
//using ICSharpCode.Core.Services;
|
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.SharpDevelop.Services; |
||||
|
||||
//using ICSharpCode.Core.Properties;
|
||||
|
||||
using DebuggerLibrary; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Gui.Pads |
||||
{ |
||||
public class LocalVarPad : AbstractPadContent |
||||
{ |
||||
TreeListView localVarList; |
||||
|
||||
//ClassBrowserIconsService iconsService;
|
||||
|
||||
ColumnHeader name = new ColumnHeader(); |
||||
ColumnHeader val = new ColumnHeader(); |
||||
ColumnHeader type = new ColumnHeader(); |
||||
|
||||
public override Control Control { |
||||
get { |
||||
return localVarList; |
||||
} |
||||
} |
||||
|
||||
public LocalVarPad() //: base("${res:MainWindow.Windows.Debug.Local}", null)
|
||||
{ |
||||
InitializeComponents(); |
||||
} |
||||
|
||||
void InitializeComponents() |
||||
{ |
||||
//iconsService = (ClassBrowserIconsService)ServiceManager.Services.GetService(typeof(ClassBrowserIconsService));
|
||||
localVarList = new TreeListView(); |
||||
localVarList.SmallImageList = null;//iconsService.ImageList;
|
||||
localVarList.ShowPlusMinus = true; |
||||
localVarList.FullRowSelect = true; |
||||
localVarList.Dock = DockStyle.Fill; |
||||
//localVarList.GridLines = false;
|
||||
//localVarList.Activation = ItemActivation.OneClick;
|
||||
localVarList.Columns.AddRange(new ColumnHeader[] {name, val, type} ); |
||||
name.Width = 250; |
||||
val.Width = 300; |
||||
type.Width = 250; |
||||
|
||||
localVarList.BeforeExpand += new TreeListViewCancelEventHandler(localVarList_BeforeExpand); |
||||
|
||||
NDebugger.DebuggingPaused += new DebuggingPausedEventHandler(debuggerService_OnDebuggingPaused); |
||||
|
||||
RedrawContent(); |
||||
} |
||||
|
||||
public override void RedrawContent() |
||||
{ |
||||
name.Text = "Name"; |
||||
val.Text = "Value"; |
||||
type.Text = "Type"; |
||||
} |
||||
|
||||
private void debuggerService_OnDebuggingPaused(object sender, DebuggingPausedEventArgs e) |
||||
{ |
||||
localVarList.BeginUpdate(); |
||||
localVarList.Items.Clear(); |
||||
|
||||
AddVariables(localVarList.Items, NDebugger.LocalVariables); |
||||
|
||||
localVarList.EndUpdate(); |
||||
} |
||||
|
||||
private void localVarList_BeforeExpand(object sender, TreeListViewCancelEventArgs e) |
||||
{ |
||||
localVarList.BeginUpdate(); |
||||
e.Item.Items.Clear(); |
||||
|
||||
ObjectVariable var = e.Item.Tag as ObjectVariable; |
||||
if (var != null && var.HasBaseClass && var.BaseClass.Type != "System.Object") |
||||
{ |
||||
TreeListViewItem newItem = new TreeListViewItem(); |
||||
newItem.Text = "<Base class>"; |
||||
newItem.SubItems.Add(var.BaseClass.Value.ToString()); |
||||
newItem.SubItems.Add(var.BaseClass.Type); |
||||
newItem.Tag = var.BaseClass; |
||||
newItem.ImageIndex = 0;//iconsService.ClassIndex;
|
||||
newItem.Items.Add(""); // Show plus icon
|
||||
e.Item.Items.Add(newItem); |
||||
} |
||||
AddVariables(e.Item.Items, ((Variable)e.Item.Tag).SubVariables); |
||||
|
||||
localVarList.EndUpdate(); |
||||
} |
||||
|
||||
void AddVariables (TreeListViewItemCollection items, VariableCollection vars) |
||||
{ |
||||
foreach (Variable var in vars) { |
||||
TreeListViewItem newItem = new TreeListViewItem(); |
||||
newItem.Tag = var; |
||||
newItem.Text = var.Name; |
||||
newItem.SubItems.Add(var.Value.ToString()); |
||||
newItem.SubItems.Add(var.Type); |
||||
items.Add(newItem); |
||||
RefreshVariable(var); |
||||
|
||||
if (var is PropertyVariable) { |
||||
((PropertyVariable)var).ValueEvaluated += new EventHandler(PropertyEvaluated); |
||||
} |
||||
} |
||||
} |
||||
|
||||
void PropertyEvaluated (object sender, EventArgs args) |
||||
{ |
||||
RefreshVariable((Variable)sender); |
||||
} |
||||
|
||||
void RefreshVariable (Variable var) |
||||
{ |
||||
foreach (TreeListViewItem item in localVarList.Items) { |
||||
if (item.Tag == var) { |
||||
item.SubItems[1].Text = var.Value.ToString(); |
||||
item.SubItems[2].Text = var.Type; |
||||
item.Items.Clear(); |
||||
if (var is ObjectVariable && ((ObjectVariable)var).HasBaseClass) { |
||||
item.Items.Add(""); // Show plus icon
|
||||
} |
||||
//item.ImageIndex = iconsService.FieldIndex;
|
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,139 @@
@@ -0,0 +1,139 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// <owner name="Mike Krueger" email="mike@icsharpcode.net"/>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Windows.Forms; |
||||
using System.Drawing; |
||||
using System.CodeDom.Compiler; |
||||
using System.Collections; |
||||
using System.IO; |
||||
using System.Diagnostics; |
||||
using ICSharpCode.Core; |
||||
//using ICSharpCode.Core.Services;
|
||||
using ICSharpCode.SharpDevelop.Services; |
||||
|
||||
//using ICSharpCode.Core.Properties;
|
||||
|
||||
using DebuggerLibrary; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Gui.Pads |
||||
{ |
||||
public class RunningThreadsPad : AbstractPadContent |
||||
{ |
||||
ListView runningThreadsList; |
||||
|
||||
//
|
||||
//WindowsDebugger DebuggerService = (WindowsDebugger)((DebuggerService)ServiceManager.Services.GetService(typeof(DebuggerService))).CurrentDebugger;
|
||||
WindowsDebugger debugger; |
||||
|
||||
ColumnHeader id = new ColumnHeader(); |
||||
ColumnHeader name = new ColumnHeader(); |
||||
ColumnHeader location = new ColumnHeader(); |
||||
ColumnHeader priority = new ColumnHeader(); |
||||
ColumnHeader breaked = new ColumnHeader(); |
||||
|
||||
public override Control Control { |
||||
get { |
||||
return runningThreadsList; |
||||
} |
||||
} |
||||
|
||||
public RunningThreadsPad() //: base("${res:MainWindow.Windows.Debug.Threads}", null)
|
||||
{ |
||||
InitializeComponents(); |
||||
} |
||||
|
||||
void InitializeComponents() |
||||
{ |
||||
debugger = (WindowsDebugger)DebuggerService.CurrentDebugger; |
||||
runningThreadsList = new ListView(); |
||||
runningThreadsList.FullRowSelect = true; |
||||
runningThreadsList.AutoArrange = true; |
||||
runningThreadsList.Alignment = ListViewAlignment.Left; |
||||
runningThreadsList.View = View.Details; |
||||
runningThreadsList.Dock = DockStyle.Fill; |
||||
runningThreadsList.GridLines = false; |
||||
runningThreadsList.Activation = ItemActivation.OneClick; |
||||
runningThreadsList.Columns.AddRange(new ColumnHeader[] {id, name, location, priority, breaked} ); |
||||
runningThreadsList.ItemActivate += new EventHandler(RunningThreadsListItemActivate); |
||||
id.Width = 100; |
||||
name.Width = 300; |
||||
location.Width = 250; |
||||
priority.Width = 120; |
||||
breaked.Width = 80; |
||||
|
||||
|
||||
NDebugger.Threads.ThreadAdded += new ThreadEventHandler(AddThread); |
||||
NDebugger.Threads.ThreadStateChanged += new ThreadEventHandler(RefreshThread); |
||||
NDebugger.Threads.ThreadRemoved += new ThreadEventHandler(RemoveThread); |
||||
NDebugger.IsProcessRunningChanged += new DebuggerEventHandler(DebuggerStateChanged); |
||||
|
||||
RedrawContent(); |
||||
} |
||||
|
||||
public override void RedrawContent() |
||||
{ |
||||
id.Text = "ID"; |
||||
name.Text = "Name"; |
||||
location.Text = "Location"; |
||||
priority.Text = "Priority"; |
||||
breaked.Text = "Breaked"; |
||||
} |
||||
|
||||
void RunningThreadsListItemActivate(object sender, EventArgs e) |
||||
{ |
||||
debugger.SelectThread((Thread)(runningThreadsList.SelectedItems[0].Tag)); |
||||
debugger.JumpToCurrentLine(); |
||||
CallStackPad callStackPad = (CallStackPad)WorkbenchSingleton.Workbench.GetPad(typeof(CallStackPad)).PadContent; |
||||
callStackPad.RefreshList(); |
||||
} |
||||
|
||||
|
||||
private void AddThread(object sender, ThreadEventArgs e) |
||||
{ |
||||
runningThreadsList.Items.Add(new ListViewItem(e.Thread.ID.ToString())); |
||||
RefreshThread(this, e); |
||||
} |
||||
|
||||
private void RefreshThread(object sender, ThreadEventArgs e) |
||||
{ |
||||
foreach (ListViewItem item in runningThreadsList.Items) { |
||||
if (e.Thread.ID.ToString() == item.Text) { |
||||
item.SubItems.Clear(); |
||||
item.Text = e.Thread.ID.ToString(); |
||||
item.Tag = e.Thread; |
||||
item.SubItems.Add(e.Thread.Name); |
||||
try { |
||||
item.SubItems.Add(e.Thread.CurrentFunction.Name); |
||||
} catch (CurrentFunctionNotAviableException) { |
||||
item.SubItems.Add("<unaviable>"); |
||||
} |
||||
item.SubItems.Add(e.Thread.Priority.ToString()); |
||||
item.SubItems.Add(e.Thread.Suspended.ToString()); |
||||
} |
||||
} |
||||
} |
||||
|
||||
private void RemoveThread(object sender, ThreadEventArgs e) |
||||
{ |
||||
foreach (ListViewItem item in runningThreadsList.Items) { |
||||
if (e.Thread.ID.ToString() == item.Text) |
||||
item.Remove(); |
||||
} |
||||
} |
||||
|
||||
public void DebuggerStateChanged(object sender, DebuggerEventArgs e) |
||||
{ |
||||
RefreshAllItems(); |
||||
} |
||||
|
||||
private void RefreshAllItems() |
||||
{ |
||||
foreach (Thread t in NDebugger.Threads) { |
||||
RefreshThread(this, new ThreadEventArgs(t)); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,514 @@
@@ -0,0 +1,514 @@
|
||||
// <file>
|
||||
// <owner name="David Srbeck" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections; |
||||
using System.Drawing; |
||||
using System.IO; |
||||
using System.Windows.Forms; |
||||
|
||||
using DebuggerLibrary; |
||||
|
||||
using ICSharpCode.Core; |
||||
//using ICSharpCode.Core.Services;
|
||||
//using ICSharpCode.Core.AddIns;
|
||||
|
||||
//using ICSharpCode.Core.Properties;
|
||||
//using ICSharpCode.Core.AddIns.Codons;
|
||||
//using ICSharpCode.Core.AddIns.Conditions;
|
||||
using System.CodeDom.Compiler; |
||||
|
||||
using ICSharpCode.TextEditor; |
||||
using ICSharpCode.TextEditor.Document; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
//using ICSharpCode.SharpDevelop.Gui.Components;
|
||||
//using ICSharpCode.SharpDevelop.Gui.Pads;
|
||||
using ICSharpCode.SharpDevelop.Project; |
||||
//using ICSharpCode.SharpDevelop.Internal.Project;
|
||||
//using ICSharpCode.SharpDevelop.Gui.Dialogs;
|
||||
using ICSharpCode.SharpDevelop.Services; |
||||
|
||||
//using Reflector.UserInterface;
|
||||
|
||||
namespace ICSharpCode.SharpDevelop.Services |
||||
{ |
||||
public class WindowsDebugger:IDebugger //, IService
|
||||
{ |
||||
public event EventHandler DebugStopped; // FIX: unused
|
||||
|
||||
protected virtual void OnDebugStopped(EventArgs e) |
||||
{ |
||||
if (DebugStopped != null) { |
||||
DebugStopped(this, e); |
||||
} |
||||
} |
||||
|
||||
public void Dispose()// FIX: unused
|
||||
{ |
||||
|
||||
} |
||||
|
||||
class BreakpointMarker: TextMarker |
||||
{ |
||||
public BreakpointMarker(int offset, int length, TextMarkerType textMarkerType, Color color):base(offset, length, textMarkerType, color) |
||||
{ |
||||
} |
||||
} |
||||
|
||||
MessageViewCategory messageViewCategoryDebug; |
||||
MessageViewCategory messageViewCategoryDebuggerLog; |
||||
public Thread selectedThread; |
||||
public Function selectedFunction; |
||||
|
||||
public bool CanDebug(IProject project) |
||||
{ |
||||
return true; |
||||
} |
||||
|
||||
public bool SupportsStepping { |
||||
get { |
||||
return true; |
||||
} |
||||
} |
||||
|
||||
public WindowsDebugger() |
||||
{ |
||||
InitializeService(); |
||||
} |
||||
|
||||
#region ICSharpCode.Core.Services.IService interface implementation
|
||||
public event System.EventHandler Initialize; |
||||
|
||||
public event System.EventHandler Unload; |
||||
|
||||
public void InitializeService() |
||||
{ |
||||
NDebugger.DebuggerTraceMessage += new MessageEventHandler(DebuggerTraceMessage); |
||||
NDebugger.LogMessage += new MessageEventHandler(LogMessage); |
||||
NDebugger.DebuggingStarted += new DebuggerEventHandler(DebuggingStarted); |
||||
NDebugger.DebuggingPaused += new DebuggingPausedEventHandler(DebuggingPaused); |
||||
NDebugger.DebuggingResumed += new DebuggerEventHandler(DebuggingResumed); |
||||
NDebugger.DebuggingStopped += new DebuggerEventHandler(DebuggingStopped); |
||||
NDebugger.IsProcessRunningChanged += new DebuggerEventHandler(DebuggerStateChanged); |
||||
|
||||
WorkbenchSingleton.WorkbenchCreated += new EventHandler(WorkspaceCreated); |
||||
|
||||
if (Initialize != null) { |
||||
Initialize(this, null); |
||||
} |
||||
} |
||||
|
||||
public void UnloadService() |
||||
{ |
||||
NDebugger.DebuggerTraceMessage -= new MessageEventHandler(DebuggerTraceMessage); |
||||
NDebugger.LogMessage -= new MessageEventHandler(LogMessage); |
||||
NDebugger.DebuggingStarted -= new DebuggerEventHandler(DebuggingStarted); |
||||
NDebugger.DebuggingPaused -= new DebuggingPausedEventHandler(DebuggingPaused); |
||||
NDebugger.IsProcessRunningChanged -= new DebuggerEventHandler(DebuggerStateChanged); |
||||
|
||||
if (Unload != null) { |
||||
Unload(this, null); |
||||
} |
||||
} |
||||
#endregion
|
||||
|
||||
#region ICSharpCode.SharpDevelop.Services.IDebugger interface implementation
|
||||
public bool IsDebugging { |
||||
get { |
||||
return NDebugger.IsDebugging; |
||||
} |
||||
} |
||||
|
||||
public bool IsProcessRunning { |
||||
get { |
||||
return NDebugger.IsProcessRunning; |
||||
} |
||||
} |
||||
|
||||
public bool SupportsStartStop { |
||||
get { |
||||
return true; |
||||
} |
||||
} |
||||
|
||||
public bool SupportsExecutionControl { |
||||
get { |
||||
return true; |
||||
} |
||||
} |
||||
|
||||
public void StartWithoutDebugging(System.Diagnostics.ProcessStartInfo psi) |
||||
{ |
||||
NDebugger.StartWithoutDebugging(psi); |
||||
} |
||||
|
||||
public void Start(string fileName, string workingDirectory, string arguments) |
||||
{ |
||||
NDebugger.Start(fileName, workingDirectory, arguments); |
||||
} |
||||
|
||||
public void Stop() |
||||
{ |
||||
NDebugger.Terminate(); |
||||
} |
||||
|
||||
public void Break() |
||||
{ |
||||
NDebugger.Break(); |
||||
} |
||||
|
||||
public void StepInto() |
||||
{ |
||||
NDebugger.StepInto(); |
||||
} |
||||
|
||||
public void StepOver() |
||||
{ |
||||
NDebugger.StepOver(); |
||||
} |
||||
|
||||
public void StepOut() |
||||
{ |
||||
NDebugger.StepOut(); |
||||
} |
||||
|
||||
public void Continue() |
||||
{ |
||||
NDebugger.Continue(); |
||||
} |
||||
#endregion
|
||||
|
||||
void WorkspaceCreated(object sender, EventArgs args) |
||||
{ |
||||
WorkbenchSingleton.Workbench.ViewOpened += new ViewContentEventHandler(ViewContentOpened); |
||||
WorkbenchSingleton.Workbench.ViewClosed += new ViewContentEventHandler(ViewContentClosed); |
||||
} |
||||
|
||||
void ViewContentOpened(object sender, ViewContentEventArgs e) |
||||
{ |
||||
if (e.Content.Control is TextEditor.TextEditorControl) { |
||||
TextArea textArea = ((TextEditor.TextEditorControl)e.Content.Control).ActiveTextAreaControl.TextArea; |
||||
|
||||
textArea.IconBarMargin.MouseDown += new MarginMouseEventHandler(IconBarMouseDown); |
||||
textArea.IconBarMargin.Painted += new MarginPaintEventHandler(PaintIconBar); |
||||
textArea.MouseMove += new MouseEventHandler(TextAreaMouseMove); |
||||
|
||||
RefreshBreakpointMarkersInEditor(textArea.MotherTextEditorControl); |
||||
} |
||||
} |
||||
|
||||
void ViewContentClosed(object sender, ViewContentEventArgs e) |
||||
{ |
||||
if (e.Content.Control is TextEditor.TextEditorControl) { |
||||
TextArea textArea = ((TextEditor.TextEditorControl)e.Content.Control).ActiveTextAreaControl.TextArea; |
||||
|
||||
textArea.IconBarMargin.MouseDown -= new MarginMouseEventHandler(IconBarMouseDown); |
||||
textArea.IconBarMargin.Painted -= new MarginPaintEventHandler(PaintIconBar); |
||||
textArea.MouseMove -= new MouseEventHandler(TextAreaMouseMove); |
||||
} |
||||
} |
||||
|
||||
// Output messages that report status of debugger
|
||||
void DebuggerTraceMessage(object sender, MessageEventArgs e) |
||||
{ |
||||
if (messageViewCategoryDebuggerLog != null) { |
||||
messageViewCategoryDebuggerLog.AppendText(e.Message + "\n"); |
||||
System.Console.WriteLine(e.Message); |
||||
} |
||||
} |
||||
|
||||
// Output messages form debuged program that are caused by System.Diagnostics.Trace.WriteLine(), etc...
|
||||
void LogMessage(object sender, MessageEventArgs e) |
||||
{ |
||||
DebuggerTraceMessage(this, e); |
||||
if (messageViewCategoryDebug != null) { |
||||
messageViewCategoryDebug.AppendText(e.Message + "\n"); |
||||
} |
||||
} |
||||
|
||||
void DebuggingStarted(object sender, DebuggerEventArgs e) |
||||
{ |
||||
// Initialize
|
||||
/*PadDescriptor cmv = (CompilerMessageView)WorkbenchSingleton.Workbench.GetPad(typeof(CompilerMessageView)); |
||||
if (messageViewCategoryDebug == null) { |
||||
messageViewCategoryDebug = cmv.GetCategory("Debug"); |
||||
} |
||||
messageViewCategoryDebug.ClearText(); |
||||
if (messageViewCategoryDebuggerLog == null) { |
||||
messageViewCategoryDebuggerLog = new MessageViewCategory("DebuggerLog", "Debugger log"); |
||||
//cmv.AddCategory(messageViewCategoryDebuggerLog);
|
||||
} |
||||
messageViewCategoryDebuggerLog.ClearText();*/ |
||||
} |
||||
|
||||
void DebuggingPaused(object sender, DebuggingPausedEventArgs e) |
||||
{ |
||||
if (e.Reason == PausedReason.Exception) { |
||||
if (NDebugger.CurrentThread.CurrentException.IsHandled && (NDebugger.CatchHandledExceptions == false)) { |
||||
// Ignore the exception
|
||||
Continue(); |
||||
return; |
||||
} |
||||
|
||||
|
||||
//MessageBox.Show("Exception was thrown in debugee:\n" + NDebugger.CurrentThread.CurrentException.ToString());
|
||||
/*ExceptionForm form = new ExceptionForm(); |
||||
form.label.Text = "Exception " + |
||||
NDebugger.CurrentThread.CurrentException.Type + |
||||
" was thrown in debugee:\n" + |
||||
NDebugger.CurrentThread.CurrentException.Message; |
||||
form.pictureBox.Image = ResourceService.GetBitmap((NDebugger.CurrentThread.CurrentException.IsHandled)?"Icons.32x32.Warning":"Icons.32x32.Error"); |
||||
form.ShowDialog(ICSharpCode.SharpDevelop.Gui.WorkbenchSingleton.MainForm); |
||||
switch (form.result) { |
||||
case ExceptionForm.Result.Break: |
||||
break; |
||||
case ExceptionForm.Result.Continue: |
||||
Continue(); |
||||
return; |
||||
case ExceptionForm.Result.Ignore: |
||||
NDebugger.CurrentThread.ClearCurrentException(); |
||||
Continue(); |
||||
return; |
||||
}*/ |
||||
} |
||||
|
||||
try { |
||||
SelectThread(NDebugger.CurrentThread); |
||||
} catch (CurrentThreadNotAviableException) {} |
||||
JumpToCurrentLine(); |
||||
} |
||||
|
||||
void DebuggingResumed(object sender, DebuggerEventArgs e) |
||||
{ |
||||
selectedThread = null; |
||||
selectedFunction = null; |
||||
RemoveCurrentLineMarker(); |
||||
} |
||||
|
||||
void DebuggingStopped(object sender, DebuggerEventArgs e) |
||||
{ |
||||
|
||||
//DebuggerService.Stop();//TODO: delete
|
||||
} |
||||
|
||||
public void SelectThread(Thread thread) |
||||
{ |
||||
selectedThread = thread; |
||||
try { |
||||
selectedFunction = thread.CurrentFunction; |
||||
// Prefer first function on callstack that has symbols (source code)
|
||||
if (selectedFunction.Module.SymbolsLoaded == false) { |
||||
foreach (Function f in thread.Callstack) { |
||||
if (f.Module.SymbolsLoaded) { |
||||
selectedFunction = f; |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
} catch (CurrentFunctionNotAviableException) {} |
||||
} |
||||
|
||||
TextMarker currentLineMarker; |
||||
IDocument currentLineMarkerParent; |
||||
|
||||
void RemoveCurrentLineMarker() |
||||
{ |
||||
if (currentLineMarker != null) { |
||||
currentLineMarkerParent.MarkerStrategy.TextMarker.Remove(currentLineMarker); |
||||
currentLineMarkerParent.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.WholeTextArea)); |
||||
currentLineMarkerParent.CommitUpdate(); |
||||
currentLineMarkerParent = null; |
||||
currentLineMarker = null; |
||||
} |
||||
} |
||||
|
||||
public void JumpToCurrentLine() |
||||
{ |
||||
RemoveCurrentLineMarker(); |
||||
|
||||
|
||||
|
||||
try { |
||||
if (selectedFunction == null) { |
||||
return; |
||||
} |
||||
SourcecodeSegment nextStatement = selectedFunction.NextStatement; |
||||
|
||||
FileService.OpenFile(nextStatement.SourceFilename); |
||||
IWorkbenchWindow window = FileService.GetOpenFile(nextStatement.SourceFilename); |
||||
if (window != null) { |
||||
IViewContent content = window.ViewContent; |
||||
|
||||
if (content is IPositionable) { |
||||
((IPositionable)content).JumpTo((int)nextStatement.StartLine - 1, (int)nextStatement.StartColumn - 1); |
||||
} |
||||
|
||||
if (content.Control is TextEditorControl) { |
||||
IDocument document = ((TextEditorControl)content.Control).Document; |
||||
LineSegment line = document.GetLineSegment((int)nextStatement.StartLine - 1); |
||||
int offset = line.Offset + (int)nextStatement.StartColumn; |
||||
currentLineMarker = new TextMarker(offset, (int)nextStatement.EndColumn - (int)nextStatement.StartColumn, TextMarkerType.SolidBlock, Color.Yellow); |
||||
currentLineMarkerParent = document; |
||||
currentLineMarkerParent.MarkerStrategy.TextMarker.Add(currentLineMarker); |
||||
document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.WholeTextArea)); |
||||
document.CommitUpdate(); |
||||
} |
||||
} |
||||
} catch (NextStatementNotAviableException) { |
||||
//System.Windows.Forms.MessageBox.Show("Source code not aviable!");
|
||||
} |
||||
} |
||||
|
||||
public void DebuggerStateChanged(object sender, DebuggerEventArgs e) |
||||
{ |
||||
UpdateToolbars(); |
||||
} |
||||
|
||||
void UpdateToolbars() |
||||
{ |
||||
((DefaultWorkbench)WorkbenchSingleton.Workbench).Update(); |
||||
//if (WorkbenchSingleton.Workbench.ActiveWorkbenchWindow != null) {
|
||||
// WorkbenchSingleton.Workbench.ActiveWorkbenchWindow.ActiveViewContent.RedrawContent();
|
||||
//}
|
||||
} |
||||
|
||||
void IconBarMouseDown(AbstractMargin iconBar, Point mousepos, MouseButtons mouseButtons) |
||||
{ |
||||
Rectangle viewRect = iconBar.TextArea.TextView.DrawingPosition; |
||||
Point logicPos = iconBar.TextArea.TextView.GetLogicalPosition(0, mousepos.Y - viewRect.Top); |
||||
|
||||
if (logicPos.Y >= 0 && logicPos.Y < iconBar.TextArea.Document.TotalNumberOfLines) { |
||||
NDebugger.ToggleBreakpointAt(iconBar.TextArea.MotherTextEditorControl.FileName , logicPos.Y + 1, 0); |
||||
RefreshBreakpointMarkersInEditor(iconBar.TextArea.MotherTextEditorControl); |
||||
iconBar.TextArea.Refresh(iconBar); |
||||
} |
||||
} |
||||
|
||||
|
||||
public void RefreshBreakpointMarkersInEditor(TextEditorControl textEditor) |
||||
{ |
||||
IDocument document = textEditor.Document; |
||||
System.Collections.Generic.List<ICSharpCode.TextEditor.Document.TextMarker> markers = textEditor.Document.MarkerStrategy.TextMarker; |
||||
// Remove all breakpoint markers
|
||||
for (int i = 0; i < markers.Count;) { |
||||
if (markers[i] is BreakpointMarker) { |
||||
markers.RemoveAt(i); |
||||
} else { |
||||
i++; // Check next one
|
||||
} |
||||
} |
||||
// Add breakpoint markers
|
||||
foreach (DebuggerLibrary.Breakpoint b in NDebugger.Breakpoints) { |
||||
if (b.SourcecodeSegment.SourceFilename.ToLower() == textEditor.FileName.ToLower()) { |
||||
LineSegment lineSeg = document.GetLineSegment((int)b.SourcecodeSegment.StartLine - 1); |
||||
document.MarkerStrategy.TextMarker.Add(new BreakpointMarker(lineSeg.Offset, lineSeg.Length , TextMarkerType.SolidBlock, Color.Red)); |
||||
} |
||||
} |
||||
// Perform editor update
|
||||
document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.WholeTextArea)); |
||||
document.CommitUpdate(); |
||||
} |
||||
|
||||
|
||||
TextMarker variableMarker; |
||||
IDocument variableMarkerParent; |
||||
|
||||
/// <summary>
|
||||
/// This function shows variable values as tooltips
|
||||
/// </summary>
|
||||
void TextAreaMouseMove(object sender, MouseEventArgs args) |
||||
{ |
||||
if (!IsDebugging) return; |
||||
if (IsProcessRunning) return; |
||||
|
||||
TextArea textArea = (TextArea)sender; |
||||
|
||||
Point mousepos = textArea.PointToClient(Control.MousePosition); |
||||
Rectangle viewRect = textArea.TextView.DrawingPosition; |
||||
if (viewRect.Contains(mousepos)) { |
||||
Point logicPos = textArea.TextView.GetLogicalPosition(mousepos.X - viewRect.Left, |
||||
mousepos.Y - viewRect.Top); |
||||
if (logicPos.Y >= 0 && logicPos.Y < textArea.Document.TotalNumberOfLines) { |
||||
IDocument doc = textArea.Document; |
||||
LineSegment seg = doc.GetLineSegment(logicPos.Y); |
||||
string line = doc.GetText(seg.Offset, seg.Length); |
||||
int startIndex = 0; |
||||
int length = 0; |
||||
string expresion = String.Empty; |
||||
for(int index = 0; index < seg.Length; index++) { |
||||
char chr = line[index]; |
||||
if ((Char.IsLetterOrDigit(chr) || chr == '_' || chr == '.') == false || // invalid character
|
||||
(chr == '.' && logicPos.X <= index)) { // Start of sub-expresion at the right side of cursor
|
||||
// End of expresion...
|
||||
if ((startIndex <= logicPos.X && logicPos.X <= index) && // Correct position
|
||||
(startIndex != index)) { // Actualy something
|
||||
length = index - startIndex; |
||||
expresion = line.Substring(startIndex, length); |
||||
break; |
||||
} else { |
||||
// Let's try next one...
|
||||
startIndex = index + 1; |
||||
} |
||||
} |
||||
} |
||||
//Console.WriteLine("MouseMove@" + logicPos + ":" + expresion);
|
||||
if (variableMarker == null || variableMarker.Offset != (seg.Offset + startIndex) || variableMarker.Length != length) { |
||||
// Needs update
|
||||
if (variableMarker != null) { |
||||
// Remove old marker
|
||||
variableMarkerParent.MarkerStrategy.TextMarker.Remove(variableMarker); |
||||
variableMarkerParent.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.WholeTextArea)); |
||||
variableMarkerParent.CommitUpdate(); |
||||
variableMarkerParent = null; |
||||
variableMarker = null; |
||||
} |
||||
if (expresion != String.Empty) { |
||||
// Look if it is variable
|
||||
try { |
||||
string value; |
||||
value = selectedThread.LocalVariables[expresion].Value.ToString(); |
||||
variableMarker = new TextMarker(seg.Offset + startIndex, length, TextMarkerType.Underlined, Color.Blue); |
||||
variableMarker.ToolTip = value; |
||||
variableMarkerParent = doc; |
||||
variableMarkerParent.MarkerStrategy.TextMarker.Add(variableMarker); |
||||
variableMarkerParent.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.WholeTextArea)); |
||||
variableMarkerParent.CommitUpdate(); |
||||
} catch {} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Draw Breakpoint icon and the yellow arrow in the margin
|
||||
/// </summary>
|
||||
void PaintIconBar(AbstractMargin iconBar, Graphics g, Rectangle rect) |
||||
{ |
||||
foreach (DebuggerLibrary.Breakpoint breakpoint in NDebugger.Breakpoints) { |
||||
if (Path.GetFullPath(breakpoint.SourcecodeSegment.SourceFilename) == Path.GetFullPath(iconBar.TextArea.MotherTextEditorControl.FileName)) { |
||||
int lineNumber = iconBar.TextArea.Document.GetVisibleLine((int)breakpoint.SourcecodeSegment.StartLine - 1); |
||||
int yPos = (int)(lineNumber * iconBar.TextArea.TextView.FontHeight) - iconBar.TextArea.VirtualTop.Y; |
||||
if (yPos >= rect.Y && yPos <= rect.Bottom) { |
||||
((IconBarMargin)iconBar).DrawBreakpoint(g, yPos, breakpoint.Enabled); |
||||
} |
||||
} |
||||
} |
||||
|
||||
if (IsDebugging && !IsProcessRunning) { |
||||
try { |
||||
SourcecodeSegment nextStatement = selectedFunction.NextStatement;//cache
|
||||
|
||||
if (Path.GetFullPath(nextStatement.SourceFilename).ToLower() == Path.GetFullPath(iconBar.TextArea.MotherTextEditorControl.FileName).ToLower()) { |
||||
int lineNumber = iconBar.TextArea.Document.GetVisibleLine((int)nextStatement.StartLine - 1); |
||||
int yPos = (int)(lineNumber * iconBar.TextArea.TextView.FontHeight) - iconBar.TextArea.VirtualTop.Y; |
||||
if (yPos >= rect.Y && yPos <= rect.Bottom) { |
||||
((IconBarMargin)iconBar).DrawArrow(g, yPos); |
||||
} |
||||
} |
||||
} catch (NextStatementNotAviableException) {} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,88 @@
@@ -0,0 +1,88 @@
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
<PropertyGroup> |
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> |
||||
<ProductVersion>8.0.41115</ProductVersion> |
||||
<SchemaVersion>2.0</SchemaVersion> |
||||
<ProjectGuid>{1D18D788-F7EE-4585-A23B-34DC8EC63CB8}</ProjectGuid> |
||||
<OutputType>Library</OutputType> |
||||
<RootNamespace>Debugger.Core</RootNamespace> |
||||
<AssemblyName>Debugger.Core</AssemblyName> |
||||
<WarningLevel>4</WarningLevel> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> |
||||
<DebugSymbols>true</DebugSymbols> |
||||
<DebugType>full</DebugType> |
||||
<Optimize>false</Optimize> |
||||
<OutputPath>..\..\..\..\..\..\AddIns\AddIns\Misc\Debugger\</OutputPath> |
||||
<DefineConstants>DEBUG;TRACE</DefineConstants> |
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> |
||||
<DebugType>pdbonly</DebugType> |
||||
<Optimize>true</Optimize> |
||||
<OutputPath>..\..\..\..\..\..\AddIns\AddIns\Misc\Debugger\</OutputPath> |
||||
<DefineConstants>TRACE</DefineConstants> |
||||
</PropertyGroup> |
||||
<ItemGroup> |
||||
<Reference Include="Debugger.Interop, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> |
||||
<HintPath>..\RequiredLibraries\Debugger.Interop.dll</HintPath> |
||||
<SpecificVersion>False</SpecificVersion> |
||||
</Reference> |
||||
<Reference Include="System" /> |
||||
<Reference Include="System.Data" /> |
||||
<Reference Include="System.Windows.Forms" /> |
||||
<Reference Include="System.Xml" /> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<Compile Include="Src\AssemblyInfo.cs" /> |
||||
<Compile Include="Src\Enums\ClassFieldAttribute.cs" /> |
||||
<Compile Include="Src\Enums\CorCallingConvention.cs" /> |
||||
<Compile Include="Src\Enums\CorElementType.cs" /> |
||||
<Compile Include="Src\Enums\CorMethodAttr.cs" /> |
||||
<Compile Include="Src\Enums\CorTokenType.cs" /> |
||||
<Compile Include="Src\Enums\PausedReason.cs" /> |
||||
<Compile Include="Src\EventHandlers\BreakpointEventHandler.cs" /> |
||||
<Compile Include="Src\EventHandlers\DebuggerEventHandler.cs" /> |
||||
<Compile Include="Src\EventHandlers\DebuggingIsResumingEventHandler.cs" /> |
||||
<Compile Include="Src\EventHandlers\DebuggingPausedEventHandler.cs" /> |
||||
<Compile Include="Src\EventHandlers\MessageEventHandler.cs" /> |
||||
<Compile Include="Src\EventHandlers\ModuleEventHandler.cs" /> |
||||
<Compile Include="Src\EventHandlers\ThreadEventHandler.cs" /> |
||||
<Compile Include="Src\NativeMethods.cs" /> |
||||
<Compile Include="Src\NDebugger.cs" /> |
||||
<Compile Include="Src\Private Classes\Eval.cs" /> |
||||
<Compile Include="Src\Private Classes\EvalQueue.cs" /> |
||||
<Compile Include="Src\Private Classes\ManagedCallback.cs" /> |
||||
<Compile Include="Src\Private Classes\ManagedCallbackProxy.cs" /> |
||||
<Compile Include="Src\Private Classes\MTA2STA.cs" /> |
||||
<Compile Include="Src\Private Classes\SignatureStream.cs" /> |
||||
<Compile Include="Src\Public Classes\Breakpoint.cs" /> |
||||
<Compile Include="Src\Public Classes\BreakpointCollection.cs" /> |
||||
<Compile Include="Src\Public Classes\Exception.cs" /> |
||||
<Compile Include="Src\Public Classes\Exceptions.cs" /> |
||||
<Compile Include="Src\Public Classes\Function.cs" /> |
||||
<Compile Include="Src\Public Classes\FunctionCollection.cs" /> |
||||
<Compile Include="Src\Public Classes\Module.cs" /> |
||||
<Compile Include="Src\Public Classes\ModuleCollection.cs" /> |
||||
<Compile Include="Src\Public Classes\SourcecodeSegment.cs" /> |
||||
<Compile Include="Src\Public Classes\Thread.cs" /> |
||||
<Compile Include="Src\Public Classes\ThreadCollection.cs" /> |
||||
<Compile Include="Src\Variables\ArrayVariable.cs" /> |
||||
<Compile Include="Src\Variables\BuiltInVariable.cs" /> |
||||
<Compile Include="Src\Variables\NullRefVariable.cs" /> |
||||
<Compile Include="Src\Variables\ObjectVariable.cs" /> |
||||
<Compile Include="Src\Variables\PropertyVariable.cs" /> |
||||
<Compile Include="Src\Variables\UnknownVariable.cs" /> |
||||
<Compile Include="Src\Variables\Variable.cs" /> |
||||
<Compile Include="Src\Variables\VariableCollection.cs" /> |
||||
<Compile Include="Src\Variables\VariableFactory.cs" /> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<Content Include="README.TXT" /> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<Folder Include="Configuration\" /> |
||||
</ItemGroup> |
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" /> |
||||
</Project> |
@ -0,0 +1,7 @@
@@ -0,0 +1,7 @@
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
<PropertyGroup> |
||||
<LastOpenVersion>8.0.41115</LastOpenVersion> |
||||
<ProjectView>ShowAllFiles</ProjectView> |
||||
<ProjectTrust>0</ProjectTrust> |
||||
</PropertyGroup> |
||||
</Project> |
@ -0,0 +1,7 @@
@@ -0,0 +1,7 @@
|
||||
Debugger.Core and Debugger.Interop are the two libraries that hold most core debugging functionality. |
||||
|
||||
The vast majority of the code of these libraries was written by me without any modifications made by other people. If you could preserve this ratio by not making any modifications, I would be extremely pleased and I would be indebted to you. |
||||
|
||||
However, if you find a bug or if you have an idea or suggestion, please do send me an e-mail to dsrbecky at post.cz |
||||
|
||||
Thank you very much, David Srbecky |
@ -0,0 +1,58 @@
@@ -0,0 +1,58 @@
|
||||
using System.Reflection; |
||||
using System.Runtime.CompilerServices; |
||||
|
||||
//
|
||||
// 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("")] |
||||
[assembly: AssemblyDescription("")] |
||||
[assembly: AssemblyConfiguration("")] |
||||
[assembly: AssemblyCompany("")] |
||||
[assembly: AssemblyProduct("")] |
||||
[assembly: AssemblyCopyright("")] |
||||
[assembly: AssemblyTrademark("")] |
||||
[assembly: AssemblyCulture("")] |
||||
|
||||
//
|
||||
// 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 Revision and Build Numbers
|
||||
// by using the '*' as shown below:
|
||||
|
||||
[assembly: AssemblyVersion("1.0.*")] |
||||
|
||||
//
|
||||
// In order to sign your assembly you must specify a key to use. Refer to the
|
||||
// Microsoft .NET Framework documentation for more information on assembly signing.
|
||||
//
|
||||
// Use the attributes below to control which key is used for signing.
|
||||
//
|
||||
// Notes:
|
||||
// (*) If no key is specified, the assembly is not signed.
|
||||
// (*) KeyName refers to a key that has been installed in the Crypto Service
|
||||
// Provider (CSP) on your machine. KeyFile refers to a file which contains
|
||||
// a key.
|
||||
// (*) If the KeyFile and the KeyName values are both specified, the
|
||||
// following processing occurs:
|
||||
// (1) If the KeyName can be found in the CSP, that key is used.
|
||||
// (2) If the KeyName does not exist and the KeyFile does exist, the key
|
||||
// in the KeyFile is installed into the CSP and used.
|
||||
// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
|
||||
// When specifying the KeyFile, the location of the KeyFile should be
|
||||
// relative to the project output directory which is
|
||||
// %Project Directory%\obj\<configuration>. For example, if your KeyFile is
|
||||
// located in the project directory, you would specify the AssemblyKeyFile
|
||||
// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
|
||||
// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
|
||||
// documentation for more information on this.
|
||||
//
|
||||
[assembly: AssemblyDelaySign(false)] |
||||
//[assembly: AssemblyKeyFile(@"..\..\key.snk")]
|
||||
[assembly: AssemblyKeyName("")] |
@ -0,0 +1,38 @@
@@ -0,0 +1,38 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
namespace DebuggerLibrary |
||||
{ |
||||
[System.Flags()] enum ClassFieldAttribute: uint |
||||
{ |
||||
// member access mask - Use this mask to retrieve accessibility information.
|
||||
fdFieldAccessMask = 0x0007, |
||||
fdPrivateScope = 0x0000, // Member not referenceable.
|
||||
fdPrivate = 0x0001, // Accessible only by the parent type.
|
||||
fdFamANDAssem = 0x0002, // Accessible by sub-types only in this Assembly.
|
||||
fdAssembly = 0x0003, // Accessibly by anyone in the Assembly.
|
||||
fdFamily = 0x0004, // Accessible only by type and sub-types.
|
||||
fdFamORAssem = 0x0005, // Accessibly by sub-types anywhere, plus anyone in assembly.
|
||||
fdPublic = 0x0006, // Accessibly by anyone who has visibility to this scope.
|
||||
// end member access mask
|
||||
|
||||
// field contract attributes.
|
||||
fdStatic = 0x0010, // Defined on type, else per instance.
|
||||
fdInitOnly = 0x0020, // Field may only be initialized, not written to after init.
|
||||
fdLiteral = 0x0040, // Value is compile time constant.
|
||||
fdNotSerialized = 0x0080, // Field does not have to be serialized when type is remoted.
|
||||
|
||||
fdSpecialName = 0x0200, // field is special. Name describes how.
|
||||
|
||||
// interop attributes
|
||||
fdPinvokeImpl = 0x2000, // Implementation is forwarded through pinvoke.
|
||||
|
||||
// Reserved flags for runtime use only.
|
||||
fdReservedMask = 0x9500, |
||||
fdRTSpecialName = 0x0400, // Runtime(metadata internal APIs) should check name encoding.
|
||||
fdHasFieldMarshal = 0x1000, // Field has marshalling information.
|
||||
fdHasDefault = 0x8000, // Field has default.
|
||||
fdHasFieldRVA = 0x0100, // Field has RVA.
|
||||
} |
||||
} |
@ -0,0 +1,24 @@
@@ -0,0 +1,24 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
namespace DebuggerLibrary |
||||
{ |
||||
enum CorCallingConvention: uint |
||||
{ |
||||
IMAGE_CEE_CS_CALLCONV_DEFAULT = 0x0, |
||||
|
||||
IMAGE_CEE_CS_CALLCONV_VARARG = 0x5, |
||||
IMAGE_CEE_CS_CALLCONV_FIELD = 0x6, |
||||
IMAGE_CEE_CS_CALLCONV_LOCAL_SIG = 0x7, |
||||
IMAGE_CEE_CS_CALLCONV_PROPERTY = 0x8, |
||||
IMAGE_CEE_CS_CALLCONV_UNMGD = 0x9, |
||||
IMAGE_CEE_CS_CALLCONV_MAX = 0x10, // first invalid calling convention
|
||||
|
||||
|
||||
// The high bits of the calling convention convey additional info
|
||||
IMAGE_CEE_CS_CALLCONV_MASK = 0x0f, // Calling convention is bottom 4 bits
|
||||
IMAGE_CEE_CS_CALLCONV_HASTHIS = 0x20, // Top bit indicates a 'this' parameter
|
||||
IMAGE_CEE_CS_CALLCONV_EXPLICITTHIS = 0x40, // This parameter is explicitly in the signature
|
||||
} |
||||
} |
@ -0,0 +1,60 @@
@@ -0,0 +1,60 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
namespace DebuggerLibrary |
||||
{ |
||||
enum CorElementType: uint |
||||
{ |
||||
END = 0x0, |
||||
VOID = 0x1, |
||||
BOOLEAN = 0x2, |
||||
CHAR = 0x3, |
||||
I1 = 0x4, |
||||
U1 = 0x5, |
||||
I2 = 0x6, |
||||
U2 = 0x7, |
||||
I4 = 0x8, |
||||
U4 = 0x9, |
||||
I8 = 0xa, |
||||
U8 = 0xb, |
||||
R4 = 0xc, |
||||
R8 = 0xd, |
||||
STRING = 0xe, |
||||
|
||||
// every type above PTR will be simple type
|
||||
PTR = 0xf, // PTR <type>
|
||||
BYREF = 0x10, // BYREF <type>
|
||||
|
||||
// Please use VALUETYPE. VALUECLASS is deprecated.
|
||||
VALUETYPE = 0x11, // VALUETYPE <class Token>
|
||||
CLASS = 0x12, // CLASS <class Token>
|
||||
|
||||
ARRAY = 0x14, // MDARRAY <type> <rank> <bcount> <bound1> ... <lbcount> <lb1> ...
|
||||
|
||||
TYPEDBYREF = 0x16, // This is a simple type.
|
||||
|
||||
I = 0x18, // native integer size
|
||||
U = 0x19, // native unsigned integer size
|
||||
FNPTR = 0x1B, // FNPTR <complete sig for the corFunction including calling convention>
|
||||
OBJECT = 0x1C, // Shortcut for System.Object
|
||||
SZARRAY = 0x1D, // Shortcut for single dimension zero lower bound array
|
||||
// SZARRAY <type>
|
||||
|
||||
// This is only for binding
|
||||
CMOD_REQD = 0x1F, // required C modifier : E_T_CMOD_REQD <mdTypeRef/mdTypeDef>
|
||||
CMOD_OPT = 0x20, // optional C modifier : E_T_CMOD_OPT <mdTypeRef/mdTypeDef>
|
||||
|
||||
// This is for signatures generated internally (which will not be persisted in any way).
|
||||
INTERNAL = 0x21, // INTERNAL <typehandle>
|
||||
|
||||
// Note that this is the max of base type excluding modifiers
|
||||
MAX = 0x22, // first invalid element type
|
||||
|
||||
|
||||
MODIFIER = 0x40, |
||||
SENTINEL = 0x01 | MODIFIER, // sentinel for varargs
|
||||
PINNED = 0x05 | MODIFIER, |
||||
|
||||
} |
||||
} |
@ -0,0 +1,48 @@
@@ -0,0 +1,48 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
namespace DebuggerLibrary |
||||
{ |
||||
enum CorMethodAttr: uint |
||||
{ |
||||
// member access mask - Use this mask to retrieve accessibility information.
|
||||
mdMemberAccessMask = 0x0007, |
||||
mdPrivateScope = 0x0000, // Member not referenceable.
|
||||
mdPrivate = 0x0001, // Accessible only by the parent type.
|
||||
mdFamANDAssem = 0x0002, // Accessible by sub-types only in this Assembly.
|
||||
mdAssem = 0x0003, // Accessibly by anyone in the Assembly.
|
||||
mdFamily = 0x0004, // Accessible only by type and sub-types.
|
||||
mdFamORAssem = 0x0005, // Accessibly by sub-types anywhere, plus anyone in assembly.
|
||||
mdPublic = 0x0006, // Accessibly by anyone who has visibility to this scope.
|
||||
// end member access mask
|
||||
|
||||
// method contract attributes.
|
||||
mdStatic = 0x0010, // Defined on type, else per instance.
|
||||
mdFinal = 0x0020, // Method may not be overridden.
|
||||
mdVirtual = 0x0040, // Method virtual.
|
||||
mdHideBySig = 0x0080, // Method hides by name+sig, else just by name.
|
||||
|
||||
// vtable layout mask - Use this mask to retrieve vtable attributes.
|
||||
mdVtableLayoutMask = 0x0100, |
||||
mdReuseSlot = 0x0000, // The default.
|
||||
mdNewSlot = 0x0100, // Method always gets a new slot in the vtable.
|
||||
// end vtable layout mask
|
||||
|
||||
// method implementation attributes.
|
||||
mdCheckAccessOnOverride = 0x0200, // Overridability is the same as the visibility.
|
||||
mdAbstract = 0x0400, // Method does not provide an implementation.
|
||||
mdSpecialName = 0x0800, // Method is special. Name describes how.
|
||||
|
||||
// interop attributes
|
||||
mdPinvokeImpl = 0x2000, // Implementation is forwarded through pinvoke.
|
||||
mdUnmanagedExport = 0x0008, // Managed method exported via thunk to unmanaged code.
|
||||
|
||||
// Reserved flags for runtime use only.
|
||||
mdReservedMask = 0xd000, |
||||
mdRTSpecialName = 0x1000, // Runtime should check name encoding.
|
||||
mdHasSecurity = 0x4000, // Method has security associate with it.
|
||||
mdRequireSecObject = 0x8000, // Method calls another method containing security code.
|
||||
|
||||
} |
||||
} |
@ -0,0 +1,34 @@
@@ -0,0 +1,34 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
namespace DebuggerLibrary |
||||
{ |
||||
enum CorTokenType: uint |
||||
{ |
||||
mdtModule = 0x00000000, //
|
||||
mdtTypeRef = 0x01000000, //
|
||||
mdtTypeDef = 0x02000000, //
|
||||
mdtFieldDef = 0x04000000, //
|
||||
mdtMethodDef = 0x06000000, //
|
||||
mdtParamDef = 0x08000000, //
|
||||
mdtInterfaceImpl = 0x09000000, //
|
||||
mdtMemberRef = 0x0a000000, //
|
||||
mdtCustomAttribute = 0x0c000000, //
|
||||
mdtPermission = 0x0e000000, //
|
||||
mdtSignature = 0x11000000, //
|
||||
mdtEvent = 0x14000000, //
|
||||
mdtProperty = 0x17000000, //
|
||||
mdtModuleRef = 0x1a000000, //
|
||||
mdtTypeSpec = 0x1b000000, //
|
||||
mdtAssembly = 0x20000000, //
|
||||
mdtAssemblyRef = 0x23000000, //
|
||||
mdtFile = 0x26000000, //
|
||||
mdtExportedType = 0x27000000, //
|
||||
mdtManifestResource = 0x28000000, //
|
||||
|
||||
mdtString = 0x70000000, //
|
||||
mdtName = 0x71000000, //
|
||||
mdtBaseType = 0x72000000, // Leave this on the high end value. This does not correspond to metadata table
|
||||
} |
||||
} |
@ -0,0 +1,17 @@
@@ -0,0 +1,17 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
namespace DebuggerLibrary |
||||
{ |
||||
public enum PausedReason:int |
||||
{ |
||||
StepComplete, |
||||
Breakpoint, |
||||
Break, |
||||
ControlCTrap, |
||||
Exception, |
||||
DebuggerError, |
||||
CurrentThreadChanged |
||||
} |
||||
} |
@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
|
||||
namespace DebuggerLibrary |
||||
{ |
||||
public delegate void BreakpointEventHandler (object sender, BreakpointEventArgs e); |
||||
|
||||
public class BreakpointEventArgs : System.EventArgs |
||||
{ |
||||
Breakpoint breakpoint; |
||||
|
||||
public Breakpoint Breakpoint { |
||||
get { |
||||
return breakpoint; |
||||
} |
||||
} |
||||
|
||||
public BreakpointEventArgs(Breakpoint breakpoint) |
||||
{ |
||||
this.breakpoint = breakpoint; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,15 @@
@@ -0,0 +1,15 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
|
||||
namespace DebuggerLibrary |
||||
{ |
||||
public delegate void DebuggerEventHandler (object sender, DebuggerEventArgs e); |
||||
|
||||
public class DebuggerEventArgs : System.EventArgs |
||||
{ |
||||
// Some parameters are expected in the furture
|
||||
} |
||||
} |
@ -0,0 +1,29 @@
@@ -0,0 +1,29 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
|
||||
namespace DebuggerLibrary |
||||
{ |
||||
public delegate void DebuggingIsResumingEventHandler (object sender, DebuggingIsResumingEventArgs e); |
||||
|
||||
public class DebuggingIsResumingEventArgs : System.EventArgs |
||||
{ |
||||
bool abort; |
||||
|
||||
public bool Abort { |
||||
get { |
||||
return abort; |
||||
} |
||||
set { |
||||
abort = value; |
||||
} |
||||
} |
||||
|
||||
public DebuggingIsResumingEventArgs() |
||||
{ |
||||
this.abort = false; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
|
||||
namespace DebuggerLibrary |
||||
{ |
||||
public delegate void DebuggingPausedEventHandler (object sender, DebuggingPausedEventArgs e); |
||||
|
||||
public class DebuggingPausedEventArgs : System.EventArgs |
||||
{ |
||||
PausedReason reason; |
||||
|
||||
public PausedReason Reason { |
||||
get { |
||||
return reason; |
||||
} |
||||
} |
||||
|
||||
public DebuggingPausedEventArgs(PausedReason reason) |
||||
{ |
||||
this.reason = reason; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
|
||||
namespace DebuggerLibrary |
||||
{ |
||||
public delegate void MessageEventHandler (object sender, MessageEventArgs e); |
||||
|
||||
public class MessageEventArgs : System.EventArgs |
||||
{ |
||||
string message; |
||||
|
||||
public string Message { |
||||
get { |
||||
return message; |
||||
} |
||||
} |
||||
|
||||
public MessageEventArgs(string message) |
||||
{ |
||||
this.message = message; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
|
||||
namespace DebuggerLibrary |
||||
{ |
||||
public delegate void ModuleEventHandler (object sender, ModuleEventArgs e); |
||||
|
||||
public class ModuleEventArgs : System.EventArgs |
||||
{ |
||||
Module module; |
||||
|
||||
public Module Module { |
||||
get { |
||||
return module; |
||||
} |
||||
} |
||||
|
||||
public ModuleEventArgs(Module module) |
||||
{ |
||||
this.module = module; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
|
||||
namespace DebuggerLibrary |
||||
{ |
||||
public delegate void ThreadEventHandler (object sender, ThreadEventArgs e); |
||||
|
||||
public class ThreadEventArgs : System.EventArgs |
||||
{ |
||||
Thread thread; |
||||
|
||||
public Thread Thread { |
||||
get { |
||||
return thread; |
||||
} |
||||
} |
||||
|
||||
public ThreadEventArgs(Thread thread) |
||||
{ |
||||
this.thread = thread; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,501 @@
@@ -0,0 +1,501 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Diagnostics; |
||||
using System.Collections; |
||||
using System.Runtime.InteropServices; |
||||
using System.Text; |
||||
|
||||
using DebuggerInterop.Core; |
||||
using DebuggerInterop.Symbols; |
||||
using DebuggerInterop.MetaData; |
||||
|
||||
namespace DebuggerLibrary |
||||
{ |
||||
public class NDebugger |
||||
{ |
||||
// Some variables that are used to get strings
|
||||
// They are used all over the library and
|
||||
// they are here so I don't have to decare them every time I need them
|
||||
static internal uint unused; |
||||
static internal IntPtr unusedPtr = IntPtr.Zero; |
||||
internal const int pStringLen = 65536; |
||||
static internal IntPtr pString = Marshal.AllocHGlobal(pStringLen*2); |
||||
static internal string pStringAsUnicode { |
||||
get { |
||||
return Marshal.PtrToStringUni(pString); |
||||
} |
||||
} |
||||
|
||||
|
||||
static ICorDebug corDebug; |
||||
static ManagedCallback managedCallback; |
||||
static ManagedCallbackProxy managedCallbackProxy; |
||||
|
||||
static bool isProcessRunning; |
||||
static ICorDebugProcess mainProcess; |
||||
static Thread mainThread; |
||||
static Thread currentThread; |
||||
|
||||
static BreakpointCollection breakpoints; |
||||
static ThreadCollection threads; |
||||
static ModuleCollection modules; |
||||
|
||||
public static bool CatchHandledExceptions = false; |
||||
|
||||
#region Public propeties
|
||||
|
||||
static public BreakpointCollection Breakpoints { |
||||
get{ |
||||
return breakpoints; |
||||
} |
||||
} |
||||
|
||||
static public ThreadCollection Threads { |
||||
get{ |
||||
return threads; |
||||
} |
||||
} |
||||
|
||||
static public ModuleCollection Modules { |
||||
get{ |
||||
return modules; |
||||
} |
||||
} |
||||
|
||||
static public SourcecodeSegment NextStatement { |
||||
get{ |
||||
try { |
||||
return CurrentThread.NextStatement; |
||||
} catch (CurrentThreadNotAviableException) { |
||||
throw new NextStatementNotAviableException(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
static public VariableCollection LocalVariables { |
||||
get{ |
||||
Thread thread; |
||||
try { |
||||
thread = CurrentThread; |
||||
} |
||||
catch (CurrentThreadNotAviableException) { |
||||
return new VariableCollection (); |
||||
} |
||||
return thread.LocalVariables; |
||||
} |
||||
} |
||||
|
||||
#endregion
|
||||
|
||||
static internal ICorDebugProcess MainProcess { |
||||
get { |
||||
return mainProcess; |
||||
} |
||||
set { |
||||
if (mainProcess == value) return; |
||||
|
||||
mainProcess = value; |
||||
if (value != null) { |
||||
OnDebuggingStarted(); |
||||
OnIsDebuggingChanged(); |
||||
OnIsProcessRunningChanged(); |
||||
} else { |
||||
//OnDebuggingPaused(PausedReason.ProcessExited);
|
||||
OnIsProcessRunningChanged(); |
||||
OnDebuggingStopped(); |
||||
OnIsDebuggingChanged(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
public static Thread MainThread { |
||||
get { |
||||
return mainThread; |
||||
} |
||||
set { |
||||
mainThread = value; |
||||
} |
||||
} |
||||
|
||||
static public Thread CurrentThread { |
||||
get { |
||||
if (!IsDebugging) throw new CurrentThreadNotAviableException(); |
||||
if (IsProcessRunning) throw new CurrentThreadNotAviableException(); |
||||
if (currentThread != null) return currentThread; |
||||
if (mainThread != null) return mainThread; |
||||
throw new CurrentThreadNotAviableException(); |
||||
} |
||||
set { |
||||
currentThread = value; |
||||
if (mainThread == null) { |
||||
mainThread = value; |
||||
} |
||||
if (managedCallback.HandlingCallback == false) { |
||||
OnDebuggingPaused(PausedReason.CurrentThreadChanged); |
||||
} |
||||
} |
||||
} |
||||
|
||||
static internal ICorDebugProcess corProcess { |
||||
get { |
||||
if (MainProcess != null) return MainProcess; |
||||
throw new UnableToGetPropertyException(null, "corProcess", "Make sure debuger is attached to process"); |
||||
} |
||||
} |
||||
|
||||
#region Basic functions
|
||||
|
||||
static NDebugger() |
||||
{ |
||||
InitDebugger(); |
||||
ResetEnvironment(); |
||||
} |
||||
|
||||
~NDebugger() //TODO
|
||||
{ |
||||
corDebug.Terminate(); |
||||
Marshal.FreeHGlobal(pString); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// It is not possible to implicitly create instance
|
||||
/// </summary>
|
||||
private NDebugger() |
||||
{ |
||||
|
||||
} |
||||
|
||||
static internal void InitDebugger() |
||||
{ |
||||
int size; |
||||
NativeMethods.GetCORVersion(null, 0, out size); |
||||
StringBuilder sb = new StringBuilder(size); |
||||
int hr = NativeMethods.GetCORVersion(sb, sb.Capacity, out size); |
||||
|
||||
NativeMethods.CreateDebuggingInterfaceFromVersion(3, sb.ToString(), out corDebug); |
||||
|
||||
//corDebug = new CorDebugClass();
|
||||
managedCallback = new ManagedCallback(); |
||||
managedCallbackProxy = new ManagedCallbackProxy(managedCallback); |
||||
|
||||
corDebug.Initialize(); |
||||
corDebug.SetManagedHandler(managedCallbackProxy); |
||||
} |
||||
|
||||
static internal void ResetEnvironment() |
||||
{ |
||||
if (modules == null) { |
||||
modules = new ModuleCollection(); |
||||
} else { |
||||
modules.Clear(); |
||||
} |
||||
|
||||
if (breakpoints == null) { |
||||
breakpoints = new BreakpointCollection(); |
||||
} else { |
||||
foreach (Breakpoint b in breakpoints) { |
||||
b.ResetBreakpoint(); |
||||
} |
||||
} |
||||
|
||||
if (threads == null) { |
||||
threads = new ThreadCollection(); |
||||
} else { |
||||
threads.Clear(); |
||||
} |
||||
|
||||
MainProcess = null; |
||||
mainThread = null; |
||||
currentThread = null; |
||||
isProcessRunning = false; |
||||
|
||||
GC.Collect(GC.MaxGeneration); |
||||
GC.WaitForPendingFinalizers(); |
||||
TraceMessage("Reset done"); |
||||
} |
||||
|
||||
#endregion
|
||||
|
||||
#region Public events
|
||||
|
||||
static public event DebuggerEventHandler DebuggingStarted; |
||||
|
||||
static internal void OnDebuggingStarted() |
||||
{ |
||||
TraceMessage ("Debugger event: OnDebuggingStarted()"); |
||||
if (DebuggingStarted != null) |
||||
DebuggingStarted(null, new DebuggerEventArgs()); |
||||
} |
||||
|
||||
|
||||
static public event DebuggingPausedEventHandler DebuggingPaused; |
||||
|
||||
static internal void OnDebuggingPaused(PausedReason reason) |
||||
{ |
||||
TraceMessage ("Debugger event: OnDebuggingPaused(" + reason.ToString() + ")"); |
||||
if (DebuggingPaused != null) |
||||
DebuggingPaused(null, new DebuggingPausedEventArgs(reason)); |
||||
} |
||||
|
||||
|
||||
static public event DebuggingIsResumingEventHandler DebuggingIsResuming; |
||||
|
||||
static internal void OnDebuggingIsResuming(ref bool abort) |
||||
{ |
||||
if (DebuggingIsResuming != null) { |
||||
TraceMessage ("Debugger event: OnDebuggingIsResuming(" + abort.ToString() + ")"); |
||||
foreach(Delegate d in DebuggingIsResuming.GetInvocationList()) { |
||||
DebuggingIsResumingEventArgs eventHandler = new DebuggingIsResumingEventArgs(); |
||||
d.DynamicInvoke(new object[] {null, eventHandler}); |
||||
if (eventHandler.Abort == true) { |
||||
abort = true; |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
static public event DebuggerEventHandler DebuggingResumed; |
||||
|
||||
static internal void OnDebuggingResumed() |
||||
{ |
||||
TraceMessage ("Debugger event: OnDebuggingResumed()"); |
||||
if (DebuggingResumed != null) |
||||
DebuggingResumed(null, new DebuggerEventArgs()); |
||||
} |
||||
|
||||
|
||||
static public event DebuggerEventHandler DebuggingStopped; |
||||
|
||||
static internal void OnDebuggingStopped() |
||||
{ |
||||
TraceMessage ("Debugger event: OnDebuggingStopped()"); |
||||
if (DebuggingStopped != null) |
||||
DebuggingStopped(null, new DebuggerEventArgs()); |
||||
} |
||||
|
||||
|
||||
static public event DebuggerEventHandler IsProcessRunningChanged; |
||||
|
||||
static internal void OnIsProcessRunningChanged() |
||||
{ |
||||
TraceMessage ("Debugger event: OnIsProcessRunningChanged()"); |
||||
if (IsProcessRunningChanged != null) |
||||
IsProcessRunningChanged(null, new DebuggerEventArgs()); |
||||
} |
||||
|
||||
|
||||
static public event DebuggerEventHandler IsDebuggingChanged; |
||||
|
||||
static internal void OnIsDebuggingChanged() |
||||
{ |
||||
TraceMessage ("Debugger event: OnIsDebuggingChanged()"); |
||||
if (IsDebuggingChanged != null) |
||||
IsDebuggingChanged(null, new DebuggerEventArgs()); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Fired when System.Diagnostics.Trace.WriteLine() is called in debuged process
|
||||
/// </summary>
|
||||
static public event MessageEventHandler LogMessage; |
||||
|
||||
static internal void OnLogMessage(string message) |
||||
{ |
||||
TraceMessage ("Debugger event: OnLogMessage(\"" + message + "\")"); |
||||
if (LogMessage != null) |
||||
LogMessage(null, new MessageEventArgs(message)); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Internal: Used to debug the debugger library.
|
||||
/// </summary>
|
||||
static public event MessageEventHandler DebuggerTraceMessage; |
||||
|
||||
static internal void TraceMessage(string message) |
||||
{ |
||||
if (DebuggerTraceMessage != null) |
||||
DebuggerTraceMessage(null, new MessageEventArgs(message)); |
||||
} |
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Execution control
|
||||
|
||||
static public void StartWithoutDebugging(System.Diagnostics.ProcessStartInfo psi) |
||||
{ |
||||
System.Diagnostics.Process process; |
||||
process = new System.Diagnostics.Process(); |
||||
process.StartInfo = psi; |
||||
process.Start(); |
||||
} |
||||
|
||||
static MTA2STA m2s = new MTA2STA(); |
||||
|
||||
static public void Start(string filename, string workingDirectory, string arguments) |
||||
{ |
||||
if (IsDebugging) return; |
||||
m2s.CallInSTA(typeof(NDebugger), "StartInternal", new Object[] {filename, workingDirectory, arguments}); |
||||
return; |
||||
} |
||||
|
||||
static public unsafe void StartInternal(string filename, string workingDirectory, string arguments) |
||||
{ |
||||
TraceMessage("Executing " + filename); |
||||
|
||||
_SECURITY_ATTRIBUTES secAttr = new _SECURITY_ATTRIBUTES(); |
||||
secAttr.bInheritHandle = 0; |
||||
secAttr.lpSecurityDescriptor = IntPtr.Zero; |
||||
secAttr.nLength = (uint)sizeof(_SECURITY_ATTRIBUTES); //=12?
|
||||
|
||||
uint[] processStartupInfo = new uint[17]; |
||||
processStartupInfo[0] = sizeof(uint) * 17; |
||||
uint[] processInfo = new uint[4]; |
||||
|
||||
ICorDebugProcess outProcess; |
||||
|
||||
fixed (uint* pprocessStartupInfo = processStartupInfo) |
||||
fixed (uint* pprocessInfo = processInfo) |
||||
corDebug.CreateProcess( |
||||
filename, // lpApplicationName
|
||||
null, // lpCommandLine
|
||||
ref secAttr, // lpProcessAttributes
|
||||
ref secAttr, // lpThreadAttributes
|
||||
1,//TRUE // bInheritHandles
|
||||
0, // dwCreationFlags
|
||||
IntPtr.Zero, // lpEnvironment
|
||||
null, // lpCurrentDirectory
|
||||
(uint)pprocessStartupInfo, // lpStartupInfo
|
||||
(uint)pprocessInfo, // lpProcessInformation,
|
||||
CorDebugCreateProcessFlags.DEBUG_NO_SPECIAL_OPTIONS, // debuggingFlags
|
||||
out outProcess // ppProcess
|
||||
); |
||||
|
||||
isProcessRunning = true; |
||||
MainProcess = outProcess; |
||||
} |
||||
|
||||
static public void Break() |
||||
{ |
||||
if (!IsDebugging) return; |
||||
if (!IsProcessRunning) return; |
||||
|
||||
corProcess.Stop(5000); // TODO: Hardcoded value
|
||||
|
||||
isProcessRunning = false; |
||||
OnDebuggingPaused(PausedReason.Break); |
||||
OnIsProcessRunningChanged(); |
||||
} |
||||
|
||||
static public void StepInto() |
||||
{ |
||||
try { |
||||
CurrentThread.StepInto(); |
||||
} catch (CurrentThreadNotAviableException) {} |
||||
} |
||||
|
||||
static public void StepOver() |
||||
{ |
||||
try { |
||||
CurrentThread.StepOver(); |
||||
} catch (CurrentThreadNotAviableException) {} |
||||
} |
||||
|
||||
static public void StepOut() |
||||
{ |
||||
try { |
||||
CurrentThread.StepOut(); |
||||
} catch (CurrentThreadNotAviableException) {} |
||||
} |
||||
|
||||
static internal void Continue(ICorDebugAppDomain pAppDomain) |
||||
{ |
||||
ICorDebugProcess outProcess; |
||||
pAppDomain.GetProcess(out outProcess); |
||||
if (MainProcess != outProcess) throw new DebuggerException("Request to continue AppDomain that does not belog to current process"); |
||||
Continue(); |
||||
} |
||||
|
||||
static public void Continue() |
||||
{ |
||||
if (!IsDebugging) return; |
||||
if (IsProcessRunning) return; |
||||
|
||||
bool abort = false; |
||||
OnDebuggingIsResuming(ref abort); |
||||
if (abort == true) return; |
||||
|
||||
isProcessRunning = true; |
||||
if (managedCallback.HandlingCallback == false) { |
||||
OnDebuggingResumed(); |
||||
OnIsProcessRunningChanged(); |
||||
} |
||||
|
||||
corProcess.Continue(0); |
||||
} |
||||
|
||||
static public void Terminate() |
||||
{ |
||||
if (!IsDebugging) return; |
||||
|
||||
int running; |
||||
corProcess.IsRunning(out running); |
||||
// Resume stoped tread
|
||||
if (running == 0) { |
||||
Continue(); // TODO: Remove this...
|
||||
} |
||||
// Stop&terminate - both must be called
|
||||
corProcess.Stop(5000); // TODO: ...and this
|
||||
corProcess.Terminate(0); |
||||
} |
||||
|
||||
static public bool IsProcessRunning { |
||||
get { |
||||
if (!IsDebugging) return false; |
||||
return isProcessRunning; |
||||
} |
||||
set { |
||||
isProcessRunning = value; |
||||
} |
||||
} |
||||
|
||||
static public bool IsDebugging { |
||||
get { |
||||
return (MainProcess != null); |
||||
} |
||||
} |
||||
|
||||
#endregion
|
||||
|
||||
static public void ToggleBreakpointAt(string fileName, int line, int column) |
||||
{ |
||||
// Check if there is breakpoint on that line
|
||||
foreach (Breakpoint breakpoint in Breakpoints) { |
||||
// TODO check filename too
|
||||
if (breakpoint.SourcecodeSegment.StartLine == (uint)line) { |
||||
Breakpoints.Remove(breakpoint); |
||||
return; |
||||
} |
||||
} |
||||
|
||||
// Add the breakpoint
|
||||
int index = Breakpoints.Add(fileName, (uint)line, (uint)column); |
||||
Breakpoint addedBreakpoint = breakpoints[index]; |
||||
|
||||
// Check if it wasn't forced to move to different line with breakpoint
|
||||
foreach (Breakpoint breakpoint in Breakpoints) { |
||||
if (breakpoint != addedBreakpoint) { // Only the old ones
|
||||
if (breakpoint.SourcecodeSegment.StartLine == addedBreakpoint.SourcecodeSegment.StartLine) { |
||||
// Whops! We have two breakpoint on signle line, delete one
|
||||
Breakpoints.Remove(addedBreakpoint); |
||||
return; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,25 @@
@@ -0,0 +1,25 @@
|
||||
using System; |
||||
using System.Diagnostics; |
||||
using System.Collections; |
||||
using System.Runtime.InteropServices; |
||||
using System.Text; |
||||
|
||||
using DebuggerInterop.Core; |
||||
using DebuggerInterop.Symbols; |
||||
using DebuggerInterop.MetaData; |
||||
|
||||
namespace DebuggerLibrary |
||||
{ |
||||
internal static class NativeMethods |
||||
{ |
||||
[System.Runtime.ConstrainedExecution.ReliabilityContract(System.Runtime.ConstrainedExecution.Consistency.WillNotCorruptState, System.Runtime.ConstrainedExecution.CER.Success), |
||||
DllImport("kernel32.dll")] |
||||
public static extern bool CloseHandle(IntPtr handle); |
||||
|
||||
[DllImport("mscoree.dll", CharSet=CharSet.Unicode, PreserveSig=false)] |
||||
public static extern int CreateDebuggingInterfaceFromVersion(int debuggerVersion, string debuggeeVersion, out ICorDebug cordbg); |
||||
|
||||
[DllImport("mscoree.dll", CharSet=CharSet.Unicode)] |
||||
public static extern int GetCORVersion([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder szName, Int32 cchBuffer, out Int32 dwLength); |
||||
} |
||||
} |
@ -0,0 +1,50 @@
@@ -0,0 +1,50 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Diagnostics; |
||||
using System.Collections; |
||||
using System.Runtime.InteropServices; |
||||
|
||||
using DebuggerInterop.Core; |
||||
using DebuggerInterop.Symbols; |
||||
using DebuggerInterop.MetaData; |
||||
|
||||
namespace DebuggerLibrary |
||||
{ |
||||
class Eval |
||||
{ |
||||
ICorDebugEval corEval; |
||||
ICorDebugFunction corFunction; |
||||
ICorDebugValue[] args; |
||||
|
||||
public event EventHandler EvalComplete; |
||||
|
||||
void OnEvalComplete() |
||||
{ |
||||
if (EvalComplete != null) { |
||||
EvalComplete(this, EventArgs.Empty); |
||||
} |
||||
} |
||||
|
||||
public Eval(ICorDebugFunction corFunction, ICorDebugValue[] args) |
||||
{ |
||||
this.corFunction = corFunction; |
||||
this.args = args; |
||||
} |
||||
|
||||
public void PerformEval() |
||||
{ |
||||
if (NDebugger.IsProcessRunning) { |
||||
throw new DebuggerException("Debugger must be paused"); |
||||
} |
||||
|
||||
NDebugger.CurrentThread.CorThread.CreateEval(out corEval); |
||||
|
||||
corEval.CallFunction(corFunction, (uint)args.Length, args); |
||||
|
||||
NDebugger.Continue(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,53 @@
@@ -0,0 +1,53 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Diagnostics; |
||||
using System.Collections; |
||||
using System.Runtime.InteropServices; |
||||
|
||||
using DebuggerInterop.Core; |
||||
using DebuggerInterop.Symbols; |
||||
using DebuggerInterop.MetaData; |
||||
|
||||
namespace DebuggerLibrary |
||||
{ |
||||
class EvalQueue |
||||
{ |
||||
static ArrayList waitingEvals = new ArrayList(); |
||||
|
||||
public static event EventHandler AllEvalsComplete; |
||||
|
||||
static public void AddEval(Eval eval) |
||||
{ |
||||
waitingEvals.Add(eval); |
||||
} |
||||
|
||||
static public void PerformAllEvals() |
||||
{ |
||||
while (waitingEvals.Count > 0) { |
||||
PerformNextEval(); |
||||
} |
||||
} |
||||
|
||||
static public void PerformNextEval() |
||||
{ |
||||
if (NDebugger.IsProcessRunning) { |
||||
return; |
||||
} |
||||
if (waitingEvals.Count == 0) { |
||||
return; |
||||
} |
||||
Eval eval = (Eval)waitingEvals[0]; |
||||
waitingEvals.Remove(eval); |
||||
eval.PerformEval(); |
||||
|
||||
if (waitingEvals.Count == 0) { |
||||
if (AllEvalsComplete != null) { |
||||
AllEvalsComplete(null, EventArgs.Empty); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,121 @@
@@ -0,0 +1,121 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Reflection; |
||||
using System.Runtime.InteropServices; |
||||
using System.Threading; |
||||
using System.Windows.Forms; |
||||
|
||||
using DebuggerInterop.Core; |
||||
using DebuggerInterop.Symbols; |
||||
|
||||
namespace DebuggerInterop.Core |
||||
{ |
||||
class MTA2STA |
||||
{ |
||||
Form hiddenForm; |
||||
IntPtr hiddenFormHandle; |
||||
|
||||
object targetObject = null; |
||||
string functionName = null; |
||||
Object[] functionParameters = null; |
||||
|
||||
Thread MTAThread; |
||||
|
||||
static object OnlyOneAtTimeLock = new Object(); |
||||
static object DataLock = new Object(); |
||||
|
||||
public MTA2STA() |
||||
{ |
||||
hiddenForm = new Form(); |
||||
hiddenFormHandle = hiddenForm.Handle; |
||||
} |
||||
|
||||
void TraceMsg(string msg) |
||||
{ |
||||
System.Console.WriteLine("MTA2STA: " + msg); |
||||
} |
||||
|
||||
void ErrorMsg(string msg) |
||||
{ |
||||
System.Console.WriteLine("MTA2STA: ERROR: " + msg); |
||||
MessageBox.Show(msg); |
||||
} |
||||
|
||||
public void CallInSTA (object targetObject, string functionName, object[] functionParameters) |
||||
{ |
||||
lock (OnlyOneAtTimeLock) { |
||||
TraceMsg("call to process: " + functionName + " {"); |
||||
|
||||
lock (DataLock) { |
||||
this.targetObject = targetObject; |
||||
this.functionName = functionName; |
||||
this.functionParameters = functionParameters; |
||||
} |
||||
|
||||
MTAThread = Thread.CurrentThread; |
||||
if (hiddenForm.InvokeRequired == true) { |
||||
IAsyncResult async = hiddenForm.BeginInvoke(new EventHandler(PerformCall)); |
||||
//while (async.AsyncWaitHandle.WaitOne(1000,true) == false) {
|
||||
// System.Console.WriteLine("Waiting for callback...");
|
||||
//}
|
||||
if (async.AsyncWaitHandle.WaitOne(1000,true) == false) { |
||||
System.Console.WriteLine("Callback time out! Unleashing debugger thread."); |
||||
} |
||||
} else { |
||||
PerformCall(hiddenForm, EventArgs.Empty); |
||||
} |
||||
|
||||
TraceMsg("} // MTA2STA: call processed: " + functionName); |
||||
} |
||||
} |
||||
|
||||
void PerformCall(object sender, EventArgs e) |
||||
{ |
||||
MethodInfo method; |
||||
object[] outputParams; |
||||
lock (DataLock) { |
||||
object[] inputParams = functionParameters; |
||||
if (targetObject is Type) { |
||||
method = ((Type)targetObject).GetMethod(functionName); |
||||
} else { |
||||
method = targetObject.GetType().GetMethod(functionName); |
||||
} |
||||
ParameterInfo[] outputParamsInfo = method.GetParameters(); |
||||
outputParams = null; |
||||
if (outputParamsInfo != null) { |
||||
outputParams = new object[outputParamsInfo.Length]; |
||||
for (int i = 0; i < outputParams.Length; i++) { |
||||
if (inputParams[i] == null) { |
||||
outputParams[i] = null; |
||||
} else if (inputParams[i] is IntPtr) { |
||||
if (outputParamsInfo[i].ParameterType == typeof(IntPtr)) { |
||||
outputParams[i] = inputParams[i]; |
||||
} else if ((IntPtr)inputParams[i] == IntPtr.Zero) { |
||||
outputParams[i] = null; |
||||
} else if (outputParamsInfo[i].ParameterType == typeof(string)) { |
||||
outputParams[i] = Marshal.PtrToStringAuto((IntPtr)inputParams[i]); |
||||
} else { |
||||
try{ |
||||
outputParams[i] = null; |
||||
outputParams[i] = Marshal.GetTypedObjectForIUnknown((IntPtr)inputParams[i], outputParamsInfo[i].ParameterType); |
||||
}catch {} // TODO: Walkaround
|
||||
} |
||||
} else { |
||||
outputParams[i] = inputParams[i]; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
TraceMsg ("Invoke " + functionName + "{"); |
||||
if (targetObject is Type) { |
||||
method.Invoke(null, outputParams); |
||||
} else { |
||||
method.Invoke(targetObject, outputParams); |
||||
} |
||||
TraceMsg ("} \\\\ Invoke"); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,327 @@
@@ -0,0 +1,327 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Runtime.InteropServices; |
||||
|
||||
using DebuggerInterop.Core; |
||||
using DebuggerInterop.Symbols; |
||||
|
||||
namespace DebuggerLibrary |
||||
{ |
||||
class ManagedCallback |
||||
{ |
||||
bool handlingCallback = false; |
||||
|
||||
public bool HandlingCallback { |
||||
get { |
||||
return handlingCallback; |
||||
} |
||||
} |
||||
|
||||
void EnterCallback(string name) |
||||
{ |
||||
handlingCallback = true; |
||||
NDebugger.IsProcessRunning = false; |
||||
NDebugger.CurrentThread = null; |
||||
NDebugger.TraceMessage("Callback: " + name); |
||||
} |
||||
|
||||
void ExitCallback_Continue(ICorDebugAppDomain pAppDomain) |
||||
{ |
||||
NDebugger.Continue(pAppDomain); |
||||
handlingCallback = false; |
||||
} |
||||
|
||||
void ExitCallback_Continue() |
||||
{ |
||||
NDebugger.Continue(); |
||||
handlingCallback = false; |
||||
} |
||||
|
||||
void ExitCallback_Paused(PausedReason reason) |
||||
{ |
||||
NDebugger.OnDebuggingPaused(reason); |
||||
NDebugger.OnIsProcessRunningChanged(); |
||||
handlingCallback = false; |
||||
} |
||||
|
||||
|
||||
#region Program folow control
|
||||
|
||||
public void StepComplete(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugStepper pStepper, CorDebugStepReason reason) |
||||
{ |
||||
EnterCallback("StepComplete"); |
||||
|
||||
NDebugger.CurrentThread = NDebugger.Threads[pThread]; |
||||
|
||||
if (NDebugger.CurrentThread.CurrentFunction.Module.SymbolsLoaded == false) { |
||||
NDebugger.TraceMessage(" - stepping out of code without symbols"); |
||||
NDebugger.StepOut(); |
||||
return; |
||||
} |
||||
|
||||
ExitCallback_Paused(PausedReason.StepComplete); |
||||
} |
||||
|
||||
public void Breakpoint(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, IntPtr pBreakpoint) |
||||
{ |
||||
EnterCallback("Breakpoint"); |
||||
|
||||
NDebugger.CurrentThread = NDebugger.Threads[pThread]; |
||||
|
||||
ExitCallback_Paused(PausedReason.Breakpoint); |
||||
|
||||
foreach (Breakpoint b in NDebugger.Breakpoints) { |
||||
if (b.Equals(pBreakpoint)) { |
||||
b.OnBreakpointHit(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
public void BreakpointSetError(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugBreakpoint pBreakpoint, uint dwError) |
||||
{ |
||||
EnterCallback("BreakpointSetError"); |
||||
|
||||
ExitCallback_Continue(pAppDomain); |
||||
} |
||||
|
||||
public unsafe void Break(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread) |
||||
{ |
||||
EnterCallback("Break"); |
||||
|
||||
NDebugger.CurrentThread = NDebugger.Threads[pThread]; |
||||
|
||||
ExitCallback_Paused(PausedReason.Break); |
||||
} |
||||
|
||||
public void ControlCTrap(ICorDebugProcess pProcess) |
||||
{ |
||||
EnterCallback("ControlCTrap"); |
||||
|
||||
ExitCallback_Paused(PausedReason.ControlCTrap); |
||||
} |
||||
|
||||
public unsafe void Exception(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, int unhandled) |
||||
{ |
||||
EnterCallback("Exception"); |
||||
|
||||
//if (!NDebugger.CatchHandledExceptions && (unhandled == 0)) {
|
||||
// ExitCallback_Continue();
|
||||
// return;
|
||||
//}
|
||||
|
||||
NDebugger.CurrentThread = NDebugger.Threads[pThread]; |
||||
NDebugger.CurrentThread.CurrentExceptionIsHandled = (unhandled == 0); |
||||
|
||||
ExitCallback_Paused(PausedReason.Exception); |
||||
} |
||||
|
||||
#endregion
|
||||
|
||||
#region Various
|
||||
|
||||
public void LogSwitch(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, int lLevel, uint ulReason, string pLogSwitchName, string pParentName) |
||||
{ |
||||
EnterCallback("LogSwitch"); |
||||
|
||||
ExitCallback_Continue(pAppDomain); |
||||
} |
||||
|
||||
public void EvalException(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugEval pEval) |
||||
{ |
||||
EnterCallback("EvalException"); |
||||
|
||||
ExitCallback_Continue(pAppDomain); |
||||
} |
||||
|
||||
public void LogMessage(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, int lLevel, string pLogSwitchName, string pMessage) |
||||
{ |
||||
EnterCallback("LogMessage"); |
||||
|
||||
NDebugger.OnLogMessage(pMessage); |
||||
|
||||
ExitCallback_Continue(pAppDomain); |
||||
} |
||||
|
||||
public void EditAndContinueRemap(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugFunction pFunction, int fAccurate) |
||||
{ |
||||
EnterCallback("EditAndContinueRemap"); |
||||
|
||||
ExitCallback_Continue(pAppDomain); |
||||
} |
||||
|
||||
public void EvalComplete(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugEval eval) |
||||
{ |
||||
EnterCallback("EvalComplete"); |
||||
/* |
||||
foreach (Eval e in Eval.waitingEvals) { |
||||
if (e.corEval == eval) { |
||||
Eval.waitingEvals.Remove(e); |
||||
e.OnEvalComplete(); |
||||
break; |
||||
} |
||||
} |
||||
|
||||
NDebugger.OnIsProcessRunningChanged(); |
||||
handlingCallback = false; |
||||
Eval.PerformNextEval();*/ |
||||
|
||||
ExitCallback_Continue(pAppDomain); |
||||
} |
||||
|
||||
public void DebuggerError(ICorDebugProcess pProcess, int errorHR, uint errorCode) |
||||
{ |
||||
EnterCallback("DebuggerError"); |
||||
|
||||
System.Windows.Forms.MessageBox.Show("Debugger error: \nHR = " + errorHR.ToString() + "\nCode = " + errorCode.ToString()); |
||||
|
||||
ExitCallback_Paused(PausedReason.DebuggerError); |
||||
} |
||||
|
||||
public void UpdateModuleSymbols(ICorDebugAppDomain pAppDomain, ICorDebugModule pModule, DebuggerInterop.Core.IStream pSymbolStream) |
||||
{ |
||||
EnterCallback("UpdateModuleSymbols"); |
||||
|
||||
ExitCallback_Continue(pAppDomain); |
||||
} |
||||
|
||||
#endregion
|
||||
|
||||
#region Start of Application
|
||||
|
||||
public void CreateProcess(ICorDebugProcess pProcess) |
||||
{ |
||||
EnterCallback("CreateProcess"); |
||||
|
||||
ExitCallback_Continue(); |
||||
} |
||||
|
||||
public void CreateAppDomain(ICorDebugProcess pProcess, ICorDebugAppDomain pAppDomain) |
||||
{ |
||||
EnterCallback("CreateAppDomain"); |
||||
|
||||
pAppDomain.Attach(); |
||||
|
||||
ExitCallback_Continue(pAppDomain); |
||||
} |
||||
|
||||
public void LoadAssembly(ICorDebugAppDomain pAppDomain, ICorDebugAssembly pAssembly) |
||||
{ |
||||
EnterCallback("LoadAssembly"); |
||||
|
||||
ExitCallback_Continue(pAppDomain); |
||||
} |
||||
|
||||
public unsafe void LoadModule(ICorDebugAppDomain pAppDomain, ICorDebugModule pModule) |
||||
{ |
||||
EnterCallback("LoadModule"); |
||||
|
||||
NDebugger.Modules.Add(pModule); |
||||
|
||||
ExitCallback_Continue(pAppDomain); |
||||
} |
||||
|
||||
public void NameChange(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread) |
||||
{ |
||||
if (pAppDomain != null) |
||||
{ |
||||
EnterCallback("NameChange: pAppDomain"); |
||||
ExitCallback_Continue(pAppDomain); |
||||
return; |
||||
} |
||||
if (pThread != null) |
||||
{ |
||||
EnterCallback("NameChange: pThread"); |
||||
NDebugger.Threads[pThread].OnThreadStateChanged(); |
||||
ExitCallback_Continue(); |
||||
return; |
||||
} |
||||
} |
||||
|
||||
public void CreateThread(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread) |
||||
{ |
||||
EnterCallback("CreateThread"); |
||||
|
||||
NDebugger.Threads.Add(pThread); |
||||
|
||||
if (NDebugger.MainThread == null) { |
||||
NDebugger.MainThread = NDebugger.Threads[pThread]; |
||||
} |
||||
|
||||
ExitCallback_Continue(pAppDomain); |
||||
} |
||||
|
||||
public void LoadClass(ICorDebugAppDomain pAppDomain, ICorDebugClass c) |
||||
{ |
||||
EnterCallback("LoadClass"); |
||||
|
||||
ExitCallback_Continue(pAppDomain); |
||||
} |
||||
|
||||
#endregion
|
||||
|
||||
#region Exit of Application
|
||||
|
||||
public void UnloadClass(ICorDebugAppDomain pAppDomain, ICorDebugClass c) |
||||
{ |
||||
EnterCallback("UnloadClass"); |
||||
|
||||
ExitCallback_Continue(pAppDomain); |
||||
} |
||||
|
||||
public void UnloadModule(ICorDebugAppDomain pAppDomain, ICorDebugModule pModule) |
||||
{ |
||||
EnterCallback("UnloadModule"); |
||||
|
||||
NDebugger.Modules.Remove(pModule); |
||||
|
||||
ExitCallback_Continue(pAppDomain); |
||||
} |
||||
|
||||
public void UnloadAssembly(ICorDebugAppDomain pAppDomain, ICorDebugAssembly pAssembly) |
||||
{ |
||||
EnterCallback("UnloadAssembly"); |
||||
|
||||
ExitCallback_Continue(pAppDomain); |
||||
} |
||||
|
||||
public void ExitThread(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread) |
||||
{ |
||||
EnterCallback("ExitThread"); |
||||
|
||||
Thread thread = NDebugger.Threads[pThread]; |
||||
|
||||
if (NDebugger.CurrentThread == thread) |
||||
NDebugger.CurrentThread = null; |
||||
|
||||
if (NDebugger.MainThread == thread) |
||||
NDebugger.MainThread = null; |
||||
|
||||
NDebugger.Threads.Remove(thread); |
||||
|
||||
try { // TODO
|
||||
ExitCallback_Continue(pAppDomain); |
||||
} catch {} |
||||
} |
||||
|
||||
public void ExitAppDomain(ICorDebugProcess pProcess, ICorDebugAppDomain pAppDomain) |
||||
{ |
||||
EnterCallback("ExitAppDomain"); |
||||
|
||||
ExitCallback_Continue(); |
||||
} |
||||
|
||||
public void ExitProcess(ICorDebugProcess pProcess) |
||||
{ |
||||
EnterCallback("ExitProcess"); |
||||
|
||||
NDebugger.ResetEnvironment(); |
||||
|
||||
pProcess.Continue(0); //TODO
|
||||
} |
||||
|
||||
#endregion
|
||||
} |
||||
} |
@ -0,0 +1,215 @@
@@ -0,0 +1,215 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Reflection; |
||||
using System.Runtime.InteropServices; |
||||
using System.Threading; |
||||
using System.Windows.Forms; |
||||
|
||||
using DebuggerInterop.Core; |
||||
using DebuggerInterop.Symbols; |
||||
|
||||
// Function finding regular expresion:
|
||||
// ^{\t*}{(:Ll| )*{:i} *\(((.# {:i}, |\))|())^6\)*}\n\t*\{(.|\n)@\}
|
||||
// Output: \1 - intention \2 - declaration \3 - function name \4-9 parameters
|
||||
|
||||
// \1\2\n\1{\n\1\tCallbackReceived("\3", new object[] {\4, \5, \6, \7, \8, \9});\n\1}
|
||||
|
||||
namespace DebuggerLibrary |
||||
{ |
||||
class ManagedCallbackProxy :ICorDebugManagedCallback, ICorDebugManagedCallback2 |
||||
{ |
||||
MTA2STA mta2sta; |
||||
ManagedCallback realCallback; |
||||
|
||||
public ManagedCallbackProxy(ManagedCallback realCallback) |
||||
{ |
||||
this.realCallback = realCallback; |
||||
mta2sta = new MTA2STA(); |
||||
} |
||||
|
||||
private void CallbackReceived (string function, object[] parameters) |
||||
{ |
||||
mta2sta.CallInSTA(realCallback, function, parameters); |
||||
} |
||||
|
||||
|
||||
|
||||
public void StepComplete(System.IntPtr pAppDomain, System.IntPtr pThread, System.IntPtr pStepper, DebuggerInterop.Core.CorDebugStepReason reason) |
||||
{ |
||||
CallbackReceived("StepComplete", new object[] {pAppDomain, pThread, pStepper, reason}); |
||||
} |
||||
|
||||
public void Break(System.IntPtr pAppDomain, System.IntPtr pThread) |
||||
{ |
||||
CallbackReceived("Break", new object[] {pAppDomain, pThread}); |
||||
} |
||||
|
||||
public void ControlCTrap(System.IntPtr pProcess) |
||||
{ |
||||
CallbackReceived("ControlCTrap", new object[] {pProcess}); |
||||
} |
||||
|
||||
public void Exception(System.IntPtr pAppDomain, System.IntPtr pThread, int unhandled) |
||||
{ |
||||
CallbackReceived("Exception", new object[] {pAppDomain, pThread, unhandled}); |
||||
} |
||||
|
||||
public void Breakpoint(System.IntPtr pAppDomain, System.IntPtr pThread, System.IntPtr pBreakpoint) |
||||
{ |
||||
CallbackReceived("Breakpoint", new object[] {pAppDomain, pThread, pBreakpoint}); |
||||
} |
||||
|
||||
public void CreateProcess(System.IntPtr pProcess) |
||||
{ |
||||
CallbackReceived("CreateProcess", new object[] {pProcess}); |
||||
} |
||||
|
||||
public void CreateAppDomain(System.IntPtr pProcess, System.IntPtr pAppDomain) |
||||
{ |
||||
CallbackReceived("CreateAppDomain", new object[] {pProcess, pAppDomain}); |
||||
} |
||||
|
||||
public void CreateThread(System.IntPtr pAppDomain, System.IntPtr pThread) |
||||
{ |
||||
CallbackReceived("CreateThread", new object[] {pAppDomain, pThread}); |
||||
} |
||||
|
||||
public void LoadAssembly(System.IntPtr pAppDomain, System.IntPtr pAssembly) |
||||
{ |
||||
CallbackReceived("LoadAssembly", new object[] {pAppDomain, pAssembly}); |
||||
} |
||||
|
||||
public void LoadModule(System.IntPtr pAppDomain, System.IntPtr pModule) |
||||
{ |
||||
CallbackReceived("LoadModule", new object[] {pAppDomain, pModule}); |
||||
} |
||||
|
||||
public void NameChange(System.IntPtr pAppDomain, System.IntPtr pThread) |
||||
{ |
||||
CallbackReceived("NameChange", new object[] {pAppDomain, pThread}); |
||||
} |
||||
|
||||
public void LoadClass(System.IntPtr pAppDomain, System.IntPtr c) |
||||
{ |
||||
CallbackReceived("LoadClass", new object[] {pAppDomain, c}); |
||||
} |
||||
|
||||
public void UnloadClass(System.IntPtr pAppDomain, System.IntPtr c) |
||||
{ |
||||
CallbackReceived("UnloadClass", new object[] {pAppDomain, c}); |
||||
} |
||||
|
||||
public void ExitThread(System.IntPtr pAppDomain, System.IntPtr pThread) |
||||
{ |
||||
CallbackReceived("ExitThread", new object[] {pAppDomain, pThread}); |
||||
} |
||||
|
||||
public void UnloadModule(System.IntPtr pAppDomain, System.IntPtr pModule) |
||||
{ |
||||
CallbackReceived("UnloadModule", new object[] {pAppDomain, pModule}); |
||||
} |
||||
|
||||
public void UnloadAssembly(System.IntPtr pAppDomain, System.IntPtr pAssembly) |
||||
{ |
||||
CallbackReceived("UnloadAssembly", new object[] {pAppDomain, pAssembly}); |
||||
} |
||||
|
||||
public void ExitAppDomain(System.IntPtr pProcess, System.IntPtr pAppDomain) |
||||
{ |
||||
CallbackReceived("ExitAppDomain", new object[] {pProcess, pAppDomain}); |
||||
} |
||||
|
||||
public void ExitProcess(System.IntPtr pProcess) |
||||
{ |
||||
CallbackReceived("ExitProcess", new object[] {pProcess}); |
||||
} |
||||
|
||||
public void BreakpointSetError(System.IntPtr pAppDomain, System.IntPtr pThread, System.IntPtr pBreakpoint, uint dwError) |
||||
{ |
||||
CallbackReceived("BreakpointSetError", new object[] {pAppDomain, pThread, pBreakpoint, dwError}); |
||||
} |
||||
|
||||
public void LogSwitch(System.IntPtr pAppDomain, System.IntPtr pThread, int lLevel, uint ulReason, System.IntPtr pLogSwitchName, System.IntPtr pParentName) |
||||
{ |
||||
CallbackReceived("LogSwitch", new object[] {pAppDomain, pThread, lLevel, ulReason, pLogSwitchName}); |
||||
} |
||||
|
||||
public void EvalException(System.IntPtr pAppDomain, System.IntPtr pThread, System.IntPtr pEval) |
||||
{ |
||||
CallbackReceived("EvalException", new object[] {pAppDomain, pThread, pEval}); |
||||
} |
||||
|
||||
public void LogMessage(System.IntPtr pAppDomain, System.IntPtr pThread, int lLevel, System.IntPtr pLogSwitchName, System.IntPtr pMessage) |
||||
{ |
||||
CallbackReceived("LogMessage", new object[] {pAppDomain, pThread, lLevel, pLogSwitchName, pMessage}); |
||||
} |
||||
|
||||
public void EditAndContinueRemap(System.IntPtr pAppDomain, System.IntPtr pThread, System.IntPtr pFunction, int fAccurate) |
||||
{ |
||||
CallbackReceived("EditAndContinueRemap", new object[] {pAppDomain, pThread, pFunction, fAccurate}); |
||||
} |
||||
|
||||
public void EvalComplete(System.IntPtr pAppDomain, System.IntPtr pThread, System.IntPtr pEval) |
||||
{ |
||||
CallbackReceived("EvalComplete", new object[] {pAppDomain, pThread, pEval}); |
||||
} |
||||
|
||||
public void DebuggerError(System.IntPtr pProcess, int errorHR, uint errorCode) |
||||
{ |
||||
CallbackReceived("DebuggerError", new object[] {pProcess, errorHR, errorCode}); |
||||
} |
||||
|
||||
public void UpdateModuleSymbols(System.IntPtr pAppDomain, System.IntPtr pModule, System.IntPtr pSymbolStream) |
||||
{ |
||||
CallbackReceived("UpdateModuleSymbols", new object[] {pAppDomain, pModule, pSymbolStream}); |
||||
} |
||||
|
||||
#region ICorDebugManagedCallback2 Members
|
||||
|
||||
public void ChangeConnection(ICorDebugProcess pProcess, uint dwConnectionId) |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
|
||||
public void CreateConnection(ICorDebugProcess pProcess, uint dwConnectionId, ref ushort pConnName) |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
|
||||
public void DestroyConnection(ICorDebugProcess pProcess, uint dwConnectionId) |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
|
||||
public void Exception(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugFrame pFrame, uint nOffset, CorDebugExceptionCallbackType dwEventType, uint dwFlags) |
||||
{ |
||||
pAppDomain.Continue(0); |
||||
} |
||||
|
||||
public void ExceptionUnwind(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, CorDebugExceptionUnwindCallbackType dwEventType, uint dwFlags) |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
|
||||
public void FunctionRemapComplete(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugFunction pFunction) |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
|
||||
public void FunctionRemapOpportunity(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugFunction pOldFunction, ICorDebugFunction pNewFunction, uint oldILOffset) |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
|
||||
public void MDANotification(ICorDebugController c, ICorDebugThread t, ICorDebugMDA mda) |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
|
||||
#endregion
|
||||
} |
||||
|
||||
} |
@ -0,0 +1,293 @@
@@ -0,0 +1,293 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Runtime.InteropServices; |
||||
|
||||
namespace DebuggerLibrary { |
||||
|
||||
unsafe class SignatureStream { |
||||
byte[] signature; |
||||
int currentPos; |
||||
|
||||
public SignatureStream (byte[] signature) |
||||
{ |
||||
this.signature = signature; |
||||
currentPos = 0; |
||||
} |
||||
|
||||
public SignatureStream (IntPtr pSigBlob, uint sigBlobSize) |
||||
{ |
||||
signature = new Byte[sigBlobSize]; |
||||
Marshal.Copy(pSigBlob, signature, 0, (int)sigBlobSize); |
||||
currentPos = 0; |
||||
} |
||||
|
||||
public bool EndOfStream { |
||||
get { |
||||
return currentPos >= signature.Length; |
||||
} |
||||
} |
||||
|
||||
byte PeekByte { |
||||
get { |
||||
if (EndOfStream) throw new BadSignatureException(); |
||||
return signature[currentPos]; |
||||
} |
||||
} |
||||
|
||||
byte ReadByte { |
||||
get { |
||||
byte value = PeekByte; |
||||
currentPos++; |
||||
return value; |
||||
} |
||||
} |
||||
|
||||
|
||||
uint ReadData(out int compressedSize) |
||||
{ |
||||
if ((PeekByte & 0x80) == 0x00) { |
||||
compressedSize = 1; |
||||
return ReadByte; |
||||
} |
||||
if ((PeekByte & 0xC0) == 0x80) { |
||||
compressedSize = 2; |
||||
return (uint)( |
||||
(ReadByte & 0x3F) * 0x100 + |
||||
ReadByte |
||||
); |
||||
} |
||||
if ((PeekByte & 0xE0) == 0xC0) { |
||||
compressedSize = 4; |
||||
return (uint)( |
||||
(ReadByte & 0x1F) * 0x1000000 + |
||||
ReadByte * 0x10000 + |
||||
ReadByte * 0x100 + |
||||
ReadByte |
||||
); |
||||
} |
||||
throw new BadSignatureException(); |
||||
} |
||||
|
||||
|
||||
public uint PeekData() |
||||
{ |
||||
int oldPos = currentPos; |
||||
uint res = ReadData(); |
||||
currentPos = oldPos; |
||||
return res; |
||||
} |
||||
|
||||
public uint ReadData() |
||||
{ |
||||
int compressedSize; |
||||
return ReadData(out compressedSize); |
||||
} |
||||
|
||||
|
||||
CorTokenType[] encodeTokenType = new CorTokenType[] {CorTokenType.mdtTypeDef, CorTokenType.mdtTypeRef, CorTokenType.mdtTypeSpec, CorTokenType.mdtBaseType}; |
||||
|
||||
public uint PeekToken() |
||||
{ |
||||
int oldPos = currentPos; |
||||
uint res = ReadToken(); |
||||
currentPos = oldPos; |
||||
return res; |
||||
} |
||||
|
||||
public uint ReadToken() |
||||
{ |
||||
uint data; |
||||
uint tokenType; |
||||
|
||||
data = ReadData(); |
||||
tokenType = (uint)encodeTokenType[data & 0x3]; |
||||
return (data >> 2) | tokenType; |
||||
} |
||||
|
||||
|
||||
public uint PeekSignedInt() |
||||
{ |
||||
int oldPos = currentPos; |
||||
uint res = ReadSignedInt(); |
||||
currentPos = oldPos; |
||||
return res; |
||||
} |
||||
|
||||
public uint ReadSignedInt() |
||||
{ |
||||
int compressedSize; |
||||
bool signed; |
||||
uint data; |
||||
|
||||
data = ReadData(out compressedSize); |
||||
signed = (data & 0x1) == 1; |
||||
data = data >> 1; |
||||
if (signed) { |
||||
switch (compressedSize) { |
||||
case 1: |
||||
data |= 0xffffffc0; |
||||
break; |
||||
case 2: |
||||
data |= 0xffffe000; |
||||
break; |
||||
case 4: |
||||
data |= 0xf0000000; |
||||
break; |
||||
default: |
||||
throw new BadSignatureException(); |
||||
} |
||||
} |
||||
return data; |
||||
} |
||||
|
||||
|
||||
public uint PeekCallingConv() |
||||
{ |
||||
int oldPos = currentPos; |
||||
uint res = ReadCallingConv(); |
||||
currentPos = oldPos; |
||||
return res; |
||||
} |
||||
|
||||
public uint ReadCallingConv() |
||||
{ |
||||
return ReadData(); |
||||
} |
||||
|
||||
|
||||
public CorElementType PeekElementType() |
||||
{ |
||||
int oldPos = currentPos; |
||||
CorElementType res = ReadElementType(); |
||||
currentPos = oldPos; |
||||
return res; |
||||
} |
||||
|
||||
public CorElementType ReadElementType() |
||||
{ |
||||
return (CorElementType)ReadData(); |
||||
} |
||||
|
||||
|
||||
|
||||
public void ReadCustomMod() |
||||
{ |
||||
while (PeekElementType() == CorElementType.CMOD_OPT || |
||||
PeekElementType() == CorElementType.CMOD_REQD) { |
||||
ReadElementType(); |
||||
ReadToken(); |
||||
} |
||||
} |
||||
|
||||
public string ReadType() |
||||
{ |
||||
CorElementType type = ReadElementType(); |
||||
switch(type) |
||||
{ |
||||
case CorElementType.BOOLEAN: |
||||
case CorElementType.CHAR: |
||||
case CorElementType.I1: |
||||
case CorElementType.U1: |
||||
case CorElementType.I2: |
||||
case CorElementType.U2: |
||||
case CorElementType.I4: |
||||
case CorElementType.U4: |
||||
case CorElementType.I8: |
||||
case CorElementType.U8: |
||||
case CorElementType.R4: |
||||
case CorElementType.R8: |
||||
case CorElementType.I: |
||||
case CorElementType.U: |
||||
case CorElementType.STRING: |
||||
case CorElementType.OBJECT: |
||||
return type.ToString(); |
||||
|
||||
case CorElementType.VALUETYPE: |
||||
case CorElementType.CLASS: |
||||
ReadToken(); |
||||
return type.ToString(); |
||||
|
||||
case CorElementType.PTR: |
||||
ReadCustomMod(); |
||||
if (PeekElementType() == CorElementType.VOID) { |
||||
ReadElementType(); |
||||
break; |
||||
} else { |
||||
return "Pointer:" + ReadType(); |
||||
} |
||||
|
||||
case CorElementType.FNPTR: |
||||
ReadFunction(); |
||||
break; |
||||
|
||||
case CorElementType.ARRAY: |
||||
ReadType(); |
||||
ReadArrayShape(); |
||||
break; |
||||
|
||||
case CorElementType.SZARRAY: // Short-cut for single dimension zero lower bound array
|
||||
ReadCustomMod(); |
||||
ReadType(); |
||||
break; |
||||
|
||||
default: |
||||
throw new BadSignatureException(); |
||||
} |
||||
return ""; |
||||
} |
||||
|
||||
public void ReadArrayShape() |
||||
{ |
||||
ReadData(); //rank
|
||||
uint numSizes = ReadData(); |
||||
for (int i = 0; i < numSizes; i++) { |
||||
ReadData(); //size
|
||||
} |
||||
if (numSizes > 0) { |
||||
uint numLoBounds = ReadData(); |
||||
for (int i = 0; i < numLoBounds; i++) { |
||||
ReadData(); //LoBound
|
||||
} |
||||
} |
||||
} |
||||
|
||||
public void ReadFunction() |
||||
{ |
||||
uint callConv = ReadCallingConv(); |
||||
uint paramCount = ReadData(); |
||||
|
||||
// Read return type
|
||||
switch (ReadElementType()) { |
||||
case CorElementType.BYREF: |
||||
ReadType(); |
||||
break; |
||||
case CorElementType.TYPEDBYREF: |
||||
break; |
||||
case CorElementType.VOID: |
||||
break; |
||||
default: |
||||
throw new BadSignatureException(); |
||||
} |
||||
|
||||
// Read params
|
||||
for (int i = 0; i < paramCount; i++) { |
||||
ReadCustomMod(); |
||||
switch (PeekElementType()) { |
||||
case CorElementType.BYREF: |
||||
ReadElementType(); |
||||
ReadType(); |
||||
break; |
||||
case CorElementType.TYPEDBYREF: |
||||
ReadElementType(); |
||||
break; |
||||
default: |
||||
ReadType(); |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,199 @@
@@ -0,0 +1,199 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections; |
||||
using System.Runtime.InteropServices; |
||||
|
||||
using DebuggerInterop.Core; |
||||
using DebuggerInterop.Symbols; |
||||
|
||||
namespace DebuggerLibrary |
||||
{ |
||||
public class Breakpoint |
||||
{ |
||||
readonly SourcecodeSegment sourcecodeSegment; |
||||
|
||||
bool hadBeenSet = false; |
||||
bool enabled = true; |
||||
ICorDebugFunctionBreakpoint corBreakpoint; |
||||
IntPtr pBreakpoint; |
||||
|
||||
public SourcecodeSegment SourcecodeSegment { |
||||
get { |
||||
return sourcecodeSegment; |
||||
} |
||||
} |
||||
|
||||
public bool HadBeenSet { |
||||
get { |
||||
return hadBeenSet; |
||||
} |
||||
} |
||||
|
||||
public bool Enabled { |
||||
get { |
||||
if (HadBeenSet) |
||||
{ |
||||
int active; |
||||
corBreakpoint.IsActive(out active); |
||||
enabled = (active == 1); |
||||
} |
||||
return enabled; |
||||
} |
||||
set { |
||||
enabled = value; |
||||
if (HadBeenSet) |
||||
{ |
||||
corBreakpoint.Activate(enabled?1:0); |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
public event BreakpointEventHandler BreakpointStateChanged; |
||||
|
||||
internal void OnBreakpointStateChanged() |
||||
{ |
||||
if (BreakpointStateChanged != null) |
||||
BreakpointStateChanged(this, new BreakpointEventArgs(this)); |
||||
} |
||||
|
||||
public event BreakpointEventHandler BreakpointHit; |
||||
|
||||
internal void OnBreakpointHit() |
||||
{ |
||||
if (BreakpointHit != null) |
||||
BreakpointHit(this, new BreakpointEventArgs(this)); |
||||
} |
||||
|
||||
public Breakpoint(SourcecodeSegment segment) |
||||
{ |
||||
sourcecodeSegment = segment; |
||||
} |
||||
|
||||
public Breakpoint(uint line) |
||||
{ |
||||
sourcecodeSegment = new SourcecodeSegment(); |
||||
sourcecodeSegment.StartLine = line; |
||||
} |
||||
|
||||
public Breakpoint(string sourceFilename, uint line) |
||||
{ |
||||
sourcecodeSegment = new SourcecodeSegment(); |
||||
sourcecodeSegment.SourceFilename = sourceFilename; |
||||
sourcecodeSegment.StartLine = line; |
||||
} |
||||
|
||||
public Breakpoint(string sourceFilename, uint line, uint column) |
||||
{ |
||||
sourcecodeSegment = new SourcecodeSegment(); |
||||
sourcecodeSegment.SourceFilename = sourceFilename; |
||||
sourcecodeSegment.StartLine = line; |
||||
sourcecodeSegment.StartColumn = column; |
||||
} |
||||
|
||||
internal bool Equals(IntPtr ptr) |
||||
{ |
||||
return pBreakpoint == ptr; |
||||
} |
||||
|
||||
internal bool Equals(ICorDebugFunctionBreakpoint obj) |
||||
{ |
||||
return corBreakpoint == obj; |
||||
} |
||||
|
||||
public override bool Equals(object obj) |
||||
{ |
||||
return base.Equals(obj) || corBreakpoint == obj; |
||||
} |
||||
|
||||
public override int GetHashCode() |
||||
{ |
||||
return base.GetHashCode(); |
||||
} |
||||
|
||||
internal unsafe void ResetBreakpoint() //TODO
|
||||
{ |
||||
hadBeenSet = false; |
||||
OnBreakpointStateChanged(); |
||||
} |
||||
|
||||
|
||||
internal unsafe void SetBreakpoint() |
||||
{ |
||||
if (hadBeenSet) { |
||||
return; |
||||
} |
||||
|
||||
SourcecodeSegment seg = sourcecodeSegment; |
||||
|
||||
Module module = null; |
||||
ISymUnmanagedReader symReader = null; |
||||
ISymUnmanagedDocument symDoc = null; |
||||
|
||||
// Try to get doc from seg.moduleFilename
|
||||
if (seg.ModuleFilename != null) |
||||
{ |
||||
try |
||||
{ |
||||
module = NDebugger.Modules[seg.ModuleFilename]; |
||||
symReader = NDebugger.Modules[seg.ModuleFilename].SymReader; |
||||
symDoc = symReader.GetDocument(seg.SourceFilename,Guid.Empty,Guid.Empty,Guid.Empty); |
||||
} |
||||
catch {} |
||||
} |
||||
|
||||
// search all modules
|
||||
if (symDoc == null) { |
||||
foreach (Module m in NDebugger.Modules) { |
||||
module = m; |
||||
symReader = m.SymReader; |
||||
if (symReader == null) { |
||||
continue; |
||||
} |
||||
|
||||
symDoc = symReader.GetDocument(seg.SourceFilename,Guid.Empty,Guid.Empty,Guid.Empty); |
||||
|
||||
if (symDoc != null) { |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
|
||||
if (symDoc == null) { |
||||
//throw new Exception("Failed to add breakpoint - (module not loaded? wrong sourceFilename?)");
|
||||
return; |
||||
} |
||||
|
||||
uint validStartLine; |
||||
validStartLine = symDoc.FindClosestLine(seg.StartLine); |
||||
if (validStartLine != seg.StartLine) { |
||||
seg.StartLine = validStartLine; |
||||
seg.EndLine = validStartLine; |
||||
seg.StartColumn = 0; |
||||
seg.EndColumn = 0; |
||||
} |
||||
|
||||
ISymUnmanagedMethod symMethod; |
||||
symMethod = symReader.GetMethodFromDocumentPosition(symDoc, seg.StartLine, seg.StartColumn); |
||||
|
||||
uint corInstructionPtr = symMethod.GetOffset(symDoc, seg.StartLine, seg.StartColumn); |
||||
|
||||
ICorDebugFunction corFunction; |
||||
module.CorModule.GetFunctionFromToken(symMethod.GetToken(), out corFunction); |
||||
|
||||
ICorDebugCode code; |
||||
corFunction.GetILCode(out code); |
||||
|
||||
code.CreateBreakpoint(corInstructionPtr, out corBreakpoint); |
||||
|
||||
hadBeenSet = true; |
||||
corBreakpoint.Activate(enabled?1:0); |
||||
pBreakpoint = Marshal.GetComInterfaceForObject(corBreakpoint, typeof(ICorDebugFunctionBreakpoint)); |
||||
OnBreakpointStateChanged(); |
||||
|
||||
} |
||||
} |
||||
} |
@ -0,0 +1,157 @@
@@ -0,0 +1,157 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Runtime.InteropServices; |
||||
using System.Collections; |
||||
|
||||
using DebuggerInterop.Core; |
||||
using DebuggerInterop.Symbols; |
||||
using DebuggerInterop.MetaData; |
||||
|
||||
namespace DebuggerLibrary |
||||
{ |
||||
public class BreakpointCollection: CollectionBase |
||||
{ |
||||
internal BreakpointCollection() |
||||
{ |
||||
NDebugger.Modules.ModuleAdded += new ModuleEventHandler(SetBreakpointsInModule); |
||||
} |
||||
|
||||
public event BreakpointEventHandler BreakpointAdded; |
||||
|
||||
private void OnBreakpointAdded(Breakpoint breakpoint) |
||||
{ |
||||
breakpoint.BreakpointStateChanged += new BreakpointEventHandler(OnBreakpointStateChanged); |
||||
breakpoint.BreakpointHit += new BreakpointEventHandler(OnBreakpointHit); |
||||
if (BreakpointAdded != null) |
||||
BreakpointAdded(this, new BreakpointEventArgs(breakpoint)); |
||||
} |
||||
|
||||
|
||||
public event BreakpointEventHandler BreakpointRemoved; |
||||
|
||||
private void OnBreakpointRemoved(Breakpoint breakpoint) |
||||
{ |
||||
breakpoint.BreakpointStateChanged -= new BreakpointEventHandler(OnBreakpointStateChanged); |
||||
breakpoint.BreakpointHit -= new BreakpointEventHandler(OnBreakpointHit); |
||||
if (BreakpointRemoved != null) |
||||
BreakpointRemoved(this, new BreakpointEventArgs(breakpoint)); |
||||
} |
||||
|
||||
|
||||
public event BreakpointEventHandler BreakpointStateChanged; |
||||
|
||||
private void OnBreakpointStateChanged(object sender, BreakpointEventArgs e) |
||||
{ |
||||
if (BreakpointStateChanged != null) |
||||
BreakpointStateChanged(this, new BreakpointEventArgs(e.Breakpoint)); |
||||
} |
||||
|
||||
|
||||
public event BreakpointEventHandler BreakpointHit; |
||||
|
||||
private void OnBreakpointHit(object sender, BreakpointEventArgs e) |
||||
{ |
||||
if (BreakpointHit != null) |
||||
BreakpointHit(this, new BreakpointEventArgs(e.Breakpoint)); |
||||
} |
||||
|
||||
|
||||
public Breakpoint this[int index] |
||||
{ |
||||
get |
||||
{ |
||||
return( (Breakpoint) List[index] ); |
||||
} |
||||
set |
||||
{ |
||||
Breakpoint oldValue = (Breakpoint)List[index]; |
||||
List[index] = value; |
||||
OnBreakpointRemoved( oldValue ); |
||||
OnBreakpointAdded( value ); |
||||
} |
||||
} |
||||
|
||||
internal Breakpoint this[ICorDebugBreakpoint corBreakpoint] |
||||
{ |
||||
get |
||||
{ |
||||
foreach(Breakpoint breakpoint in InnerList) |
||||
if (breakpoint == corBreakpoint) |
||||
return breakpoint; |
||||
|
||||
throw new UnableToGetPropertyException(this, "this[ICorDebugBreakpoint]", "Breakpoint is not in collection"); |
||||
} |
||||
} |
||||
|
||||
public int Add(Breakpoint breakpoint) |
||||
{ |
||||
System.Diagnostics.Trace.Assert(breakpoint != null); |
||||
if (breakpoint != null) |
||||
{ |
||||
int retVal = List.Add(breakpoint); |
||||
breakpoint.SetBreakpoint(); |
||||
OnBreakpointAdded(breakpoint); |
||||
return retVal; |
||||
} else { |
||||
return -1; |
||||
} |
||||
} |
||||
|
||||
public int Add(SourcecodeSegment segment) |
||||
{ |
||||
return Add(new Breakpoint(segment)); |
||||
} |
||||
|
||||
public int Add(uint line) |
||||
{ |
||||
return Add(new Breakpoint(line)); |
||||
} |
||||
|
||||
public int Add(string sourceFilename, uint line) |
||||
{ |
||||
return Add(new Breakpoint(sourceFilename, line)); |
||||
} |
||||
|
||||
public int Add(string sourceFilename, uint line, uint column) |
||||
{ |
||||
return Add(new Breakpoint(sourceFilename, line, column)); |
||||
} |
||||
|
||||
public int IndexOf( Breakpoint breakpoint ) |
||||
{ |
||||
return( List.IndexOf( breakpoint ) ); |
||||
} |
||||
|
||||
public void Insert( int index, Breakpoint breakpoint ) |
||||
{ |
||||
System.Diagnostics.Trace.Assert(breakpoint != null); |
||||
if (breakpoint != null) |
||||
{ |
||||
List.Insert( index, breakpoint ); |
||||
OnBreakpointAdded(breakpoint); |
||||
} |
||||
} |
||||
|
||||
public void Remove( Breakpoint breakpoint ) |
||||
{ |
||||
breakpoint.Enabled = false; |
||||
List.Remove( breakpoint ); |
||||
OnBreakpointRemoved( breakpoint); |
||||
} |
||||
|
||||
public bool Contains( Breakpoint breakpoint ) |
||||
{ |
||||
return( List.Contains( breakpoint ) ); |
||||
} |
||||
|
||||
private void SetBreakpointsInModule(object sender, ModuleEventArgs e) |
||||
{ |
||||
foreach (Breakpoint b in InnerList) { |
||||
b.SetBreakpoint(); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,61 @@
@@ -0,0 +1,61 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Runtime.InteropServices; |
||||
using System.Threading; |
||||
|
||||
using DebuggerInterop.Core; |
||||
using DebuggerInterop.Symbols; |
||||
using DebuggerInterop.MetaData; |
||||
|
||||
namespace DebuggerLibrary |
||||
{ |
||||
public class Exception |
||||
{ |
||||
Thread thread; |
||||
ICorDebugValue corValue; |
||||
Variable runtimeVariable; |
||||
ObjectVariable runtimeVariableException; |
||||
|
||||
internal Exception(Thread thread) |
||||
{ |
||||
this.thread = thread; |
||||
thread.CorThread.GetCurrentException(out corValue); |
||||
runtimeVariable = VariableFactory.CreateVariable(corValue, "$exception"); |
||||
runtimeVariableException = (ObjectVariable)runtimeVariable; |
||||
while (runtimeVariableException.Type != "System.Exception") { |
||||
if (runtimeVariableException.HasBaseClass == false) { |
||||
runtimeVariableException = null; |
||||
break; |
||||
} |
||||
runtimeVariableException = runtimeVariableException.BaseClass; |
||||
} |
||||
} |
||||
|
||||
public override string ToString() { |
||||
return "Exception data:\n" + runtimeVariable.ToString() + "\n" + |
||||
"---------------\n" + |
||||
runtimeVariableException.SubVariables.ToString(); |
||||
} |
||||
|
||||
public string Type { |
||||
get { |
||||
return runtimeVariable.Type; |
||||
} |
||||
} |
||||
|
||||
public string Message { |
||||
get { |
||||
return runtimeVariableException.SubVariables["_message"].Value.ToString(); |
||||
} |
||||
} |
||||
|
||||
public bool IsHandled { |
||||
get { |
||||
return thread.CurrentExceptionIsHandled; |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,51 @@
@@ -0,0 +1,51 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
|
||||
namespace DebuggerLibrary |
||||
{ |
||||
public class DebuggerException: System.Exception |
||||
{ |
||||
public DebuggerException() {} |
||||
public DebuggerException(string message): base(message) {} |
||||
public DebuggerException(string message, System.Exception inner): base(message, inner) {} |
||||
} |
||||
|
||||
public class UnableToGetPropertyException: DebuggerException |
||||
{ |
||||
public object sender; |
||||
public string property; |
||||
public string hint; |
||||
|
||||
public UnableToGetPropertyException(object sender, string property): this(sender, property, null) |
||||
{ |
||||
} |
||||
|
||||
public UnableToGetPropertyException(object sender, string property, string hint): base() |
||||
{ |
||||
this.sender = sender; |
||||
this.property = property; |
||||
this.hint = hint; |
||||
} |
||||
|
||||
public override string Message { |
||||
get { |
||||
return "Sender of exception: " + sender.GetType().ToString() + "\n" + |
||||
"Description of sender: " + sender.ToString() + "\n" + |
||||
"Unable to get property: " + property.ToString() + "\n" + |
||||
((hint != null)?("Comment: " + hint + "\n"):""); |
||||
} |
||||
} |
||||
} |
||||
|
||||
public class BadSignatureException: DebuggerException {} |
||||
|
||||
public class NotAviableException: DebuggerException {} |
||||
public class FrameNotAviableException: NotAviableException {} |
||||
public class SymbolsNotAviableException: NotAviableException {} |
||||
public class CurrentFunctionNotAviableException: NotAviableException {} |
||||
public class CurrentThreadNotAviableException: NotAviableException {} |
||||
public class NextStatementNotAviableException: NotAviableException {} |
||||
} |
@ -0,0 +1,365 @@
@@ -0,0 +1,365 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Runtime.InteropServices; |
||||
using System.Threading; |
||||
|
||||
using DebuggerInterop.Core; |
||||
using DebuggerInterop.Symbols; |
||||
using DebuggerInterop.MetaData; |
||||
|
||||
|
||||
namespace DebuggerLibrary |
||||
{ |
||||
public class Function |
||||
{ |
||||
string name; |
||||
Module module; |
||||
uint token; |
||||
uint parentClassToken = 0; |
||||
uint attributes; |
||||
ICorDebugFrame corFrame; |
||||
ICorDebugFunction corFunction; |
||||
|
||||
public string Name { |
||||
get { |
||||
return name; |
||||
} |
||||
} |
||||
|
||||
public Module Module { |
||||
get { |
||||
return module; |
||||
} |
||||
} |
||||
|
||||
internal unsafe Function(ICorDebugFrame corFrame) |
||||
{ |
||||
this.corFrame = corFrame; |
||||
corFrame.GetFunction(out corFunction); |
||||
corFunction.GetToken(out token); |
||||
ICorDebugModule corModule; |
||||
corFunction.GetModule(out corModule); |
||||
module = NDebugger.Modules[corModule]; |
||||
|
||||
Init(); |
||||
} |
||||
|
||||
unsafe void Init() |
||||
{ |
||||
uint codeRVA; |
||||
uint implFlags; |
||||
IntPtr pSigBlob; |
||||
uint sigBlobSize; |
||||
module.MetaDataInterface.GetMethodProps( |
||||
token, |
||||
out parentClassToken, |
||||
NDebugger.pString, |
||||
NDebugger.pStringLen, |
||||
out NDebugger.unused, // real string lenght
|
||||
out attributes, |
||||
new IntPtr(&pSigBlob), |
||||
out sigBlobSize, |
||||
out codeRVA, |
||||
out implFlags); |
||||
name = NDebugger.pStringAsUnicode; |
||||
|
||||
SignatureStream sig = new SignatureStream(pSigBlob, sigBlobSize); |
||||
|
||||
//Marshal.FreeCoTaskMem(pSigBlob);
|
||||
} |
||||
|
||||
|
||||
#region Helpping proprerties
|
||||
|
||||
internal ICorDebugILFrame corILFrame { |
||||
get { |
||||
return (ICorDebugILFrame) corFrame; |
||||
} |
||||
} |
||||
|
||||
internal uint corInstructionPtr { |
||||
get { |
||||
uint corInstructionPtr; |
||||
CorDebugMappingResult MappingResult; |
||||
corILFrame.GetIP(out corInstructionPtr,out MappingResult); |
||||
return corInstructionPtr; |
||||
} |
||||
} |
||||
|
||||
// Helpping properties for symbols
|
||||
|
||||
internal ISymUnmanagedReader symReader { |
||||
get { |
||||
if (module.SymbolsLoaded == false) throw new SymbolsNotAviableException(); |
||||
if (module.SymReader == null) throw new SymbolsNotAviableException(); |
||||
return module.SymReader; |
||||
} |
||||
} |
||||
|
||||
internal ISymUnmanagedMethod symMethod { |
||||
get { |
||||
return symReader.GetMethod(token); |
||||
} |
||||
} |
||||
|
||||
#endregion
|
||||
|
||||
public void StepInto() |
||||
{ |
||||
Step(true); |
||||
} |
||||
|
||||
public void StepOver() |
||||
{ |
||||
Step(false); |
||||
} |
||||
|
||||
public void StepOut() |
||||
{ |
||||
ICorDebugStepper stepper; |
||||
corFrame.CreateStepper(out stepper); |
||||
stepper.StepOut(); |
||||
|
||||
NDebugger.Continue(); |
||||
} |
||||
|
||||
private unsafe void Step(bool stepIn) |
||||
{ |
||||
if (Module.SymbolsLoaded == false) return; |
||||
|
||||
SourcecodeSegment nextSt; |
||||
try { |
||||
nextSt = NextStatement;// Cache
|
||||
} catch (NextStatementNotAviableException) { |
||||
return; |
||||
} |
||||
|
||||
ICorDebugStepper stepper; |
||||
corFrame.CreateStepper(out stepper); |
||||
|
||||
uint rangeCount; |
||||
symMethod.GetRanges(nextSt.SymUnmanagedDocument, nextSt.StartLine, 0, 0, out rangeCount, IntPtr.Zero); |
||||
IntPtr pRanges = Marshal.AllocHGlobal(4*(int)rangeCount); |
||||
symMethod.GetRanges(nextSt.SymUnmanagedDocument, nextSt.StartLine, 0, rangeCount, out rangeCount, pRanges); |
||||
stepper.StepRange(stepIn?1:0, pRanges, rangeCount); |
||||
Marshal.FreeHGlobal(pRanges); |
||||
|
||||
NDebugger.Continue(); |
||||
} |
||||
|
||||
|
||||
public SourcecodeSegment NextStatement { |
||||
get { |
||||
SourcecodeSegment retVal = new SourcecodeSegment(); |
||||
|
||||
ISymUnmanagedMethod symMethod; |
||||
try { |
||||
symMethod = this.symMethod; |
||||
} |
||||
catch (FrameNotAviableException) { |
||||
throw new NextStatementNotAviableException(); |
||||
} |
||||
catch (SymbolsNotAviableException) { |
||||
throw new NextStatementNotAviableException(); |
||||
} |
||||
|
||||
uint sequencePointCount = symMethod.GetSequencePointCount(); |
||||
|
||||
uint[] offsets = new uint[sequencePointCount]; |
||||
uint[] startLine = new uint[sequencePointCount]; |
||||
uint[] startColumn = new uint[sequencePointCount]; |
||||
uint[] endLine = new uint[sequencePointCount]; |
||||
uint[] endColumn = new uint[sequencePointCount]; |
||||
|
||||
ISymUnmanagedDocument[] Doc = new ISymUnmanagedDocument[sequencePointCount]; |
||||
|
||||
symMethod.GetSequencePoints( |
||||
sequencePointCount, |
||||
out sequencePointCount, |
||||
offsets, |
||||
Doc, |
||||
startLine, |
||||
startColumn, |
||||
endLine, |
||||
endColumn |
||||
); |
||||
|
||||
uint corInstructionPtr = this.corInstructionPtr; // cache
|
||||
|
||||
for (uint i = sequencePointCount-1 ; i >= 0; i--) // backwards
|
||||
if (offsets[i] <= corInstructionPtr) |
||||
{ |
||||
// 0xFeeFee means "code generated by compiler"
|
||||
if (startLine[i] == 0xFeeFee) throw new NextStatementNotAviableException(); |
||||
|
||||
retVal.SymUnmanagedDocument = Doc[i]; |
||||
|
||||
retVal.SymUnmanagedDocument.GetURL(NDebugger.pStringLen, |
||||
out NDebugger.unused, // real string lenght
|
||||
NDebugger.pString); |
||||
retVal.SourceFilename = NDebugger.pStringAsUnicode; |
||||
|
||||
retVal.ModuleFilename = module.FullPath; |
||||
|
||||
retVal.StartLine = startLine[i]; |
||||
retVal.StartColumn = startColumn[i]; |
||||
retVal.EndLine = endLine[i]; |
||||
retVal.EndColumn = endColumn[i]; |
||||
return retVal; |
||||
} |
||||
throw new NextStatementNotAviableException(); |
||||
} |
||||
} |
||||
|
||||
public VariableCollection LocalVariables { |
||||
get{ |
||||
return GetLocalVariables(); |
||||
} |
||||
} |
||||
|
||||
private unsafe VariableCollection GetLocalVariables() |
||||
{ |
||||
VariableCollection collection = new VariableCollection(); |
||||
try { |
||||
// parent class variables
|
||||
ICorDebugClass corClass; |
||||
corFunction.GetClass(out corClass); |
||||
bool isStatic = (attributes&(uint)CorMethodAttr.mdStatic) != 0; |
||||
ICorDebugValue argThis = null; |
||||
if (!isStatic) { |
||||
corILFrame.GetArgument(0, out argThis); |
||||
} |
||||
collection = new ObjectVariable(argThis, "this", corClass).SubVariables; |
||||
|
||||
// arguments
|
||||
ICorDebugValueEnum corValueEnum; |
||||
corILFrame.EnumerateArguments(out corValueEnum); |
||||
uint argCount; |
||||
corValueEnum.GetCount(out argCount); |
||||
|
||||
IntPtr paramEnumPtr = IntPtr.Zero; |
||||
uint paramsFetched; |
||||
for (uint i = (uint)(isStatic?0:1); i < argCount; i++) { |
||||
uint paramToken; |
||||
Module.MetaDataInterface.EnumParams(ref paramEnumPtr , token, out paramToken, 1, out paramsFetched); |
||||
if (paramsFetched == 0) break; |
||||
|
||||
ICorDebugValue arg; |
||||
corILFrame.GetArgument(i, out arg); |
||||
|
||||
uint argPos, attr, type; |
||||
Module.MetaDataInterface.GetParamProps( |
||||
paramToken, |
||||
out NDebugger.unused, |
||||
out argPos, |
||||
NDebugger.pString, |
||||
NDebugger.pStringLen, |
||||
out NDebugger.unused, // real string lenght
|
||||
out attr, |
||||
out type, |
||||
IntPtr.Zero, |
||||
out NDebugger.unused); |
||||
|
||||
|
||||
collection.Add(VariableFactory.CreateVariable(arg, NDebugger.pStringAsUnicode)); |
||||
} |
||||
|
||||
// local variables
|
||||
ISymUnmanagedScope symRootScope; |
||||
symRootScope = symMethod.GetRootScope(); |
||||
AddScopeToVariableCollection(symRootScope, ref collection); |
||||
|
||||
// Properties
|
||||
/*IntPtr methodEnumPtr = IntPtr.Zero; |
||||
uint methodsFetched; |
||||
while(true) { |
||||
uint methodToken; |
||||
Module.MetaDataInterface.EnumMethods(ref methodEnumPtr, parentClassToken, out methodToken, 1, out methodsFetched); |
||||
if (methodsFetched == 0) break; |
||||
|
||||
uint attrib; |
||||
module.MetaDataInterface.GetMethodProps( |
||||
methodToken, |
||||
out NDebugger.unused, |
||||
NDebugger.pString, |
||||
NDebugger.pStringLen, |
||||
out NDebugger.unused, // real string lenght
|
||||
out attrib, |
||||
IntPtr.Zero, |
||||
out NDebugger.unused, |
||||
out NDebugger.unused, |
||||
out NDebugger.unused); |
||||
string name = NDebugger.pStringAsUnicode; |
||||
if (name.StartsWith("get_") && (attrib & (uint)CorMethodAttr.mdSpecialName) != 0) { |
||||
name = "Prop:" + name; |
||||
|
||||
ICorDebugValue[] evalArgs; |
||||
ICorFunction evalCorFunction; |
||||
Module.CorModule.GetFunctionFromToken(methodToken, out corFunction); |
||||
if (!isStatic) { |
||||
evalArgs = new ICorDebugValue[] {argThis}; |
||||
} else { |
||||
evalArgs = new ICorDebugValue[0]; |
||||
} |
||||
EvalQueue.AddEval(new Eval(evalCorFunction, evalArgs)); |
||||
collection.Add(new PropertyVariable(eval, name)); |
||||
} |
||||
}*/ |
||||
} |
||||
catch (FrameNotAviableException) {} |
||||
catch (SymbolsNotAviableException) {} |
||||
return collection; |
||||
} |
||||
|
||||
private unsafe void AddScopeToVariableCollection(ISymUnmanagedScope symScope, ref VariableCollection collection) |
||||
{ |
||||
uint childScopesCount; |
||||
symScope.GetChildren(0, out childScopesCount, null); |
||||
|
||||
if (childScopesCount > 0) { |
||||
ISymUnmanagedScope[] childScopes = new ISymUnmanagedScope[childScopesCount]; |
||||
|
||||
symScope.GetChildren(childScopesCount, out childScopesCount, childScopes); |
||||
|
||||
foreach(ISymUnmanagedScope childScope in childScopes) { |
||||
AddScopeToVariableCollection(childScope, ref collection); |
||||
} |
||||
} |
||||
|
||||
AddVariablesToVariableCollection(symScope, ref collection); |
||||
} |
||||
|
||||
private unsafe void AddVariablesToVariableCollection(ISymUnmanagedScope symScope, ref VariableCollection collection) |
||||
{ |
||||
uint varCount; |
||||
varCount = symScope.GetLocalCount(); |
||||
|
||||
if (varCount > 0) { |
||||
ISymUnmanagedVariable[] symVars = new ISymUnmanagedVariable[varCount]; |
||||
|
||||
symScope.GetLocals(varCount, out varCount, symVars); |
||||
|
||||
foreach (ISymUnmanagedVariable symVar in symVars) { |
||||
AddVariableToVariableCollection(symVar , ref collection); |
||||
} |
||||
} |
||||
} |
||||
|
||||
private unsafe void AddVariableToVariableCollection(ISymUnmanagedVariable symVar, ref VariableCollection collection) |
||||
{ |
||||
ICorDebugValue runtimeVar; |
||||
uint address; |
||||
address = symVar.GetAddressField1(); |
||||
corILFrame.GetLocalVariable(address, out runtimeVar); |
||||
|
||||
symVar.GetName(NDebugger.pStringLen, |
||||
out NDebugger.unused, // real string name
|
||||
NDebugger.pString); |
||||
|
||||
collection.Add(VariableFactory.CreateVariable(runtimeVar, NDebugger.pStringAsUnicode)); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,39 @@
@@ -0,0 +1,39 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections; |
||||
using System.Diagnostics; |
||||
|
||||
using DebuggerInterop.Core; |
||||
|
||||
namespace DebuggerLibrary |
||||
{ |
||||
public class FunctionCollection: ReadOnlyCollectionBase |
||||
{ |
||||
internal void Add(Function function) |
||||
{ |
||||
System.Diagnostics.Trace.Assert(function != null); |
||||
if (function != null) |
||||
InnerList.Add(function); |
||||
} |
||||
|
||||
public Function this[int index] { |
||||
get { |
||||
return (Function) InnerList[index]; |
||||
} |
||||
} |
||||
|
||||
public Function this[string functionName] |
||||
{ |
||||
get { |
||||
foreach (Function f in InnerList) |
||||
if (f.Name == functionName) |
||||
return f; |
||||
|
||||
throw new UnableToGetPropertyException(this, "this[string]", "Function \"" + functionName + "\" is not in collection"); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,124 @@
@@ -0,0 +1,124 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Runtime.InteropServices; |
||||
|
||||
using DebuggerInterop.Core; |
||||
using DebuggerInterop.Symbols; |
||||
using DebuggerInterop.MetaData; |
||||
|
||||
namespace DebuggerLibrary |
||||
{ |
||||
public class Module |
||||
{ |
||||
string fullPath; |
||||
ulong baseAdress; |
||||
int isDynamic; |
||||
int isInMemory; |
||||
|
||||
int orderOfLoading = 0; |
||||
readonly ICorDebugModule corModule; |
||||
ISymUnmanagedReader symReader; |
||||
object pMetaDataInterface; |
||||
IMetaDataImport metaDataInterface; |
||||
|
||||
public IMetaDataImport MetaDataInterface { |
||||
get { |
||||
return metaDataInterface; |
||||
} |
||||
} |
||||
public ISymUnmanagedReader SymReader { |
||||
get { |
||||
return symReader; |
||||
} |
||||
} |
||||
|
||||
public ICorDebugModule CorModule { |
||||
get { |
||||
return corModule; |
||||
} |
||||
} |
||||
|
||||
public ulong BaseAdress { |
||||
get { |
||||
return baseAdress; |
||||
} |
||||
} |
||||
|
||||
public bool IsDynamic { |
||||
get { |
||||
return isDynamic == 1; |
||||
} |
||||
} |
||||
|
||||
public bool IsInMemory { |
||||
get { |
||||
return isInMemory == 1; |
||||
} |
||||
} |
||||
|
||||
public string FullPath { |
||||
get { |
||||
return fullPath; |
||||
} |
||||
} |
||||
|
||||
public string Filename { |
||||
get { |
||||
if (IsDynamic || IsInMemory) return String.Empty; |
||||
return System.IO.Path.GetFileName(FullPath); |
||||
} |
||||
} |
||||
|
||||
public string DirectoryName { |
||||
get { |
||||
if (IsDynamic || IsInMemory) return String.Empty; |
||||
return System.IO.Path.GetDirectoryName(FullPath); |
||||
} |
||||
} |
||||
|
||||
public bool SymbolsLoaded { |
||||
get { |
||||
return symReader != null; |
||||
} |
||||
} |
||||
|
||||
public int OrderOfLoading { |
||||
get { |
||||
return orderOfLoading; |
||||
} |
||||
set { |
||||
orderOfLoading = value; |
||||
} |
||||
} |
||||
|
||||
internal Module(ICorDebugModule pModule) |
||||
{ |
||||
corModule = pModule; |
||||
|
||||
pModule.GetBaseAddress(out baseAdress); |
||||
|
||||
pModule.IsDynamic(out isDynamic); |
||||
|
||||
pModule.IsInMemory(out isInMemory); |
||||
|
||||
Guid metaDataInterfaceGuid = new Guid("{ 0x7dac8207, 0xd3ae, 0x4c75, { 0x9b, 0x67, 0x92, 0x80, 0x1a, 0x49, 0x7d, 0x44 } }"); |
||||
pModule.GetMetaDataInterface(ref metaDataInterfaceGuid, out pMetaDataInterface); |
||||
|
||||
metaDataInterface = (IMetaDataImport) pMetaDataInterface; |
||||
|
||||
pModule.GetName(NDebugger.pStringLen, |
||||
out NDebugger.unused, // real string lenght
|
||||
NDebugger.pString); |
||||
fullPath = NDebugger.pStringAsUnicode; |
||||
|
||||
ISymUnmanagedBinder symBinder = new CorSymBinder_SxSClass(); |
||||
int hr = symBinder.GetReaderForFile (pMetaDataInterface, NDebugger.pString, IntPtr.Zero, out symReader); |
||||
if (hr != 0) { |
||||
symReader = null; |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,101 @@
@@ -0,0 +1,101 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections; |
||||
|
||||
using DebuggerInterop.Core; |
||||
|
||||
namespace DebuggerLibrary |
||||
{ |
||||
public class ModuleCollection: ReadOnlyCollectionBase |
||||
{ |
||||
int lastAssignedOrderOfLoading= 0; |
||||
|
||||
public event ModuleEventHandler ModuleAdded; |
||||
|
||||
private void OnModuleAdded(Module module) |
||||
{ |
||||
if (ModuleAdded != null) |
||||
ModuleAdded(this, new ModuleEventArgs(module)); |
||||
} |
||||
|
||||
|
||||
public event ModuleEventHandler ModuleRemoved; |
||||
|
||||
private void OnModuleRemoved(Module module) |
||||
{ |
||||
if (ModuleRemoved != null) |
||||
ModuleRemoved(this, new ModuleEventArgs(module)); |
||||
} |
||||
|
||||
|
||||
public Module this[int index] { |
||||
get { |
||||
return (Module) InnerList[index]; |
||||
} |
||||
} |
||||
|
||||
public Module this[string filename] { |
||||
get { |
||||
foreach(Module module in InnerList) |
||||
if (module.Filename == filename) |
||||
return module; |
||||
|
||||
throw new UnableToGetPropertyException(this, "this[string]", "Module \"" + filename + "\" is not in collection"); |
||||
} |
||||
} |
||||
|
||||
internal Module this[ICorDebugModule corModule] |
||||
{ |
||||
get |
||||
{ |
||||
foreach(Module module in InnerList) |
||||
if (module.CorModule == corModule) |
||||
return module; |
||||
|
||||
throw new UnableToGetPropertyException(this, "this[ICorDebugModule]", "Module is not in collection"); |
||||
} |
||||
} |
||||
|
||||
internal void Clear() |
||||
{ |
||||
foreach (Module m in InnerList) { |
||||
OnModuleRemoved(m); |
||||
} |
||||
InnerList.Clear(); |
||||
lastAssignedOrderOfLoading = 0; |
||||
} |
||||
|
||||
internal void Add(Module module) |
||||
{ |
||||
System.Diagnostics.Trace.Assert(module != null); |
||||
if (module != null) |
||||
{ |
||||
module.OrderOfLoading = lastAssignedOrderOfLoading; |
||||
lastAssignedOrderOfLoading++; |
||||
InnerList.Add(module); |
||||
OnModuleAdded(module); |
||||
} |
||||
} |
||||
|
||||
internal void Add(ICorDebugModule corModule) |
||||
{ |
||||
System.Diagnostics.Trace.Assert(corModule != null); |
||||
if (corModule != null) |
||||
Add(new Module(corModule)); |
||||
} |
||||
|
||||
internal void Remove(Module module) |
||||
{ |
||||
InnerList.Remove(module); |
||||
OnModuleRemoved (module); |
||||
} |
||||
|
||||
internal void Remove(ICorDebugModule corModule) |
||||
{ |
||||
Remove(this[corModule]); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,84 @@
@@ -0,0 +1,84 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
|
||||
using DebuggerInterop.Symbols; |
||||
|
||||
namespace DebuggerLibrary |
||||
{ |
||||
public class SourcecodeSegment |
||||
{ |
||||
string moduleFilename; |
||||
string sourceFilename; |
||||
uint startLine; |
||||
uint startColumn; |
||||
uint endLine; |
||||
uint endColumn; |
||||
ISymUnmanagedDocument symUnmanagedDocument; |
||||
|
||||
public string ModuleFilename { |
||||
get { |
||||
return moduleFilename; |
||||
} |
||||
set { |
||||
moduleFilename = value; |
||||
} |
||||
} |
||||
|
||||
public string SourceFilename { |
||||
get { |
||||
return sourceFilename; |
||||
} |
||||
set { |
||||
sourceFilename = value; |
||||
} |
||||
} |
||||
|
||||
public uint StartLine { |
||||
get { |
||||
return startLine; |
||||
} |
||||
set { |
||||
startLine = value; |
||||
} |
||||
} |
||||
|
||||
public uint StartColumn { |
||||
get { |
||||
return startColumn; |
||||
} |
||||
set { |
||||
startColumn = value; |
||||
} |
||||
} |
||||
|
||||
public uint EndLine { |
||||
get { |
||||
return endLine; |
||||
} |
||||
set { |
||||
endLine = value; |
||||
} |
||||
} |
||||
|
||||
public uint EndColumn { |
||||
get { |
||||
return endColumn; |
||||
} |
||||
set { |
||||
endColumn = value; |
||||
} |
||||
} |
||||
|
||||
public ISymUnmanagedDocument SymUnmanagedDocument { |
||||
get { |
||||
return symUnmanagedDocument; |
||||
} |
||||
set { |
||||
symUnmanagedDocument = value; |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,223 @@
@@ -0,0 +1,223 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Runtime.InteropServices; |
||||
using System.Threading; |
||||
|
||||
using DebuggerInterop.Core; |
||||
using DebuggerInterop.Symbols; |
||||
using DebuggerInterop.MetaData; |
||||
|
||||
namespace DebuggerLibrary |
||||
{ |
||||
public class Thread |
||||
{ |
||||
internal bool currentExceptionIsHandled; |
||||
|
||||
uint id; |
||||
bool lastSuspendedState = false; |
||||
ThreadPriority lastPriority = ThreadPriority.Normal; |
||||
string lastName = string.Empty; |
||||
|
||||
readonly ICorDebugThread corThread; |
||||
|
||||
public uint ID { |
||||
get{ |
||||
return id; |
||||
} |
||||
} |
||||
|
||||
public bool CurrentExceptionIsHandled { |
||||
get { |
||||
return currentExceptionIsHandled; |
||||
} |
||||
set { |
||||
currentExceptionIsHandled = value; |
||||
} |
||||
} |
||||
|
||||
public ICorDebugThread CorThread { |
||||
get { |
||||
return corThread; |
||||
} |
||||
} |
||||
|
||||
internal Thread(ICorDebugThread corThread) |
||||
{ |
||||
this.corThread = corThread; |
||||
corThread.GetID(out id); |
||||
} |
||||
|
||||
public bool Suspended { |
||||
get { |
||||
if (NDebugger.IsProcessRunning) return lastSuspendedState; |
||||
|
||||
CorDebugThreadState state; |
||||
corThread.GetDebugState(out state); |
||||
lastSuspendedState = (state == CorDebugThreadState.THREAD_SUSPEND); |
||||
return lastSuspendedState; |
||||
} |
||||
set { |
||||
corThread.SetDebugState((value==true)?CorDebugThreadState.THREAD_SUSPEND:CorDebugThreadState.THREAD_RUN); |
||||
} |
||||
} |
||||
|
||||
public ThreadPriority Priority { |
||||
get { |
||||
if (NDebugger.IsProcessRunning) return lastPriority; |
||||
|
||||
Variable runTimeVar = runtimeVariable; |
||||
if (runTimeVar is NullRefVariable) return ThreadPriority.Normal; |
||||
lastPriority = (ThreadPriority)(int)(runtimeVariable.SubVariables["m_Priority"] as BuiltInVariable).Value; |
||||
return lastPriority; |
||||
} |
||||
} |
||||
|
||||
|
||||
public Variable runtimeVariable { |
||||
get { |
||||
if (NDebugger.IsProcessRunning) throw new UnableToGetPropertyException(this, "runtimeVariable", "Process is running"); |
||||
ICorDebugValue corValue; |
||||
corThread.GetObject(out corValue); |
||||
return VariableFactory.CreateVariable(corValue, "Thread" + ID); |
||||
} |
||||
} |
||||
|
||||
|
||||
public string Name { |
||||
get { |
||||
if (NDebugger.IsProcessRunning) return lastName; |
||||
Variable runtimeVar = runtimeVariable; |
||||
if (runtimeVar is NullRefVariable) return lastName; |
||||
Variable runtimeName = runtimeVar.SubVariables["m_Name"]; |
||||
if (runtimeName is NullRefVariable) return string.Empty; |
||||
lastName = runtimeName.Value.ToString(); |
||||
return lastName; |
||||
} |
||||
} |
||||
|
||||
|
||||
public event ThreadEventHandler ThreadStateChanged; |
||||
|
||||
internal void OnThreadStateChanged() |
||||
{ |
||||
if (ThreadStateChanged != null) |
||||
ThreadStateChanged(this, new ThreadEventArgs(this)); |
||||
} |
||||
|
||||
|
||||
public override string ToString() |
||||
{ |
||||
return String.Format("ID = {0,-10} Name = {1,-20} Suspended = {2,-8}", ID, Name, Suspended); |
||||
} |
||||
|
||||
|
||||
|
||||
public void ClearCurrentException() |
||||
{ |
||||
corThread.ClearCurrentException(); |
||||
} |
||||
|
||||
public Exception CurrentException { |
||||
get { |
||||
return new Exception(this); |
||||
} |
||||
} |
||||
|
||||
public unsafe FunctionCollection Callstack { |
||||
get { |
||||
FunctionCollection callstack = new FunctionCollection(); |
||||
|
||||
if (!NDebugger.IsDebugging) return callstack; |
||||
if (NDebugger.IsProcessRunning) return callstack; |
||||
|
||||
ICorDebugChainEnum corChainEnum; |
||||
corThread.EnumerateChains(out corChainEnum); |
||||
|
||||
while (true) { |
||||
uint chainsFetched; |
||||
ICorDebugChain[] corChains = new ICorDebugChain[1]; // One at time
|
||||
corChainEnum.Next(1, corChains, out chainsFetched); |
||||
if (chainsFetched == 0) break; // We are done
|
||||
|
||||
int isManaged; |
||||
corChains[0].IsManaged(out isManaged); |
||||
if (isManaged == 0) continue; // Only managed ones
|
||||
|
||||
ICorDebugFrameEnum corFrameEnum; |
||||
corChains[0].EnumerateFrames(out corFrameEnum); |
||||
|
||||
for(;;) |
||||
{ |
||||
uint framesFetched; |
||||
ICorDebugFrame[] corFrames = new ICorDebugFrame[1]; // Only one at time
|
||||
corFrameEnum.Next(1, corFrames, out framesFetched); |
||||
if (framesFetched == 0) break; // We are done
|
||||
|
||||
try { |
||||
callstack.Add(new Function(corFrames[0])); |
||||
} |
||||
catch (COMException) {}; |
||||
} |
||||
} // for(;;)
|
||||
return callstack; |
||||
} // get
|
||||
} // End of public FunctionCollection Callstack
|
||||
|
||||
public Function CurrentFunction { |
||||
get { |
||||
if (NDebugger.IsProcessRunning) throw new CurrentFunctionNotAviableException(); |
||||
ICorDebugFrame corFrame; |
||||
corThread.GetActiveFrame(out corFrame); |
||||
if (corFrame == null) { |
||||
FunctionCollection callstack = Callstack; |
||||
if (callstack.Count > 0) { |
||||
return callstack[0]; |
||||
} else { |
||||
throw new CurrentFunctionNotAviableException(); |
||||
} |
||||
} |
||||
return new Function(corFrame); |
||||
} |
||||
} |
||||
|
||||
public void StepInto() |
||||
{ |
||||
try { |
||||
CurrentFunction.StepInto(); |
||||
} catch (CurrentFunctionNotAviableException) {} |
||||
} |
||||
|
||||
public void StepOver() |
||||
{ |
||||
try { |
||||
CurrentFunction.StepOver(); |
||||
} catch (CurrentFunctionNotAviableException) {} |
||||
} |
||||
|
||||
public void StepOut() |
||||
{ |
||||
try { |
||||
CurrentFunction.StepOut(); |
||||
} catch (CurrentFunctionNotAviableException) {} |
||||
} |
||||
|
||||
public SourcecodeSegment NextStatement { |
||||
get { |
||||
return CurrentFunction.NextStatement; |
||||
} |
||||
} |
||||
|
||||
public VariableCollection LocalVariables { |
||||
get { |
||||
try { |
||||
return CurrentFunction.LocalVariables; |
||||
} catch (NotAviableException) { |
||||
return new VariableCollection(); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,103 @@
@@ -0,0 +1,103 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections; |
||||
|
||||
using DebuggerInterop.Core; |
||||
|
||||
namespace DebuggerLibrary |
||||
{ |
||||
public class ThreadCollection: ReadOnlyCollectionBase |
||||
{ |
||||
internal ThreadCollection() |
||||
{ |
||||
|
||||
} |
||||
|
||||
public event ThreadEventHandler ThreadAdded; |
||||
|
||||
private void OnThreadAdded(Thread thread) |
||||
{ |
||||
thread.ThreadStateChanged += new ThreadEventHandler(OnThreadStateChanged); |
||||
if (ThreadAdded != null) |
||||
ThreadAdded(this, new ThreadEventArgs(thread)); |
||||
} |
||||
|
||||
|
||||
public event ThreadEventHandler ThreadRemoved; |
||||
|
||||
private void OnThreadRemoved(Thread thread) |
||||
{ |
||||
thread.ThreadStateChanged -= new ThreadEventHandler(OnThreadStateChanged); |
||||
if (ThreadRemoved != null) |
||||
ThreadRemoved(this, new ThreadEventArgs(thread)); |
||||
} |
||||
|
||||
|
||||
public event ThreadEventHandler ThreadStateChanged; |
||||
|
||||
private void OnThreadStateChanged(object sender, ThreadEventArgs e) |
||||
{ |
||||
if (ThreadStateChanged != null) |
||||
ThreadStateChanged(this, new ThreadEventArgs(e.Thread)); |
||||
} |
||||
|
||||
|
||||
public Thread this[int index] { |
||||
get { |
||||
return (Thread) InnerList[index]; |
||||
} |
||||
} |
||||
|
||||
internal Thread this[ICorDebugThread corThread] |
||||
{ |
||||
get |
||||
{ |
||||
foreach(Thread thread in InnerList) |
||||
if (thread.CorThread == corThread) |
||||
return thread; |
||||
|
||||
throw new UnableToGetPropertyException(this, "this[ICorDebugThread]", "Thread is not in collection"); |
||||
} |
||||
} |
||||
|
||||
|
||||
internal void Clear() |
||||
{ |
||||
foreach (Thread t in InnerList) { |
||||
OnThreadRemoved(t); |
||||
} |
||||
InnerList.Clear(); |
||||
} |
||||
|
||||
internal void Add(Thread thread) |
||||
{ |
||||
System.Diagnostics.Trace.Assert(thread != null); |
||||
if (thread != null) |
||||
{ |
||||
InnerList.Add(thread); |
||||
OnThreadAdded(thread); |
||||
} |
||||
} |
||||
|
||||
internal void Add(ICorDebugThread corThread) |
||||
{ |
||||
System.Diagnostics.Trace.Assert(corThread != null); |
||||
if (corThread != null) |
||||
Add(new Thread(corThread)); |
||||
} |
||||
|
||||
internal void Remove(Thread thread) |
||||
{ |
||||
InnerList.Remove(thread); |
||||
OnThreadRemoved(thread); |
||||
} |
||||
|
||||
internal void Remove(ICorDebugThread corThread) |
||||
{ |
||||
Remove(this[corThread]); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,131 @@
@@ -0,0 +1,131 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections.Specialized; |
||||
using System.Runtime.InteropServices; |
||||
|
||||
using DebuggerInterop.Core; |
||||
using DebuggerInterop.Symbols; |
||||
|
||||
//TODO: Support for lower bound
|
||||
|
||||
namespace DebuggerLibrary |
||||
{ |
||||
public class ArrayVariable: Variable |
||||
{ |
||||
ICorDebugArrayValue corArrayValue; |
||||
uint[] dimensions; |
||||
|
||||
|
||||
uint lenght; |
||||
CorElementType corElementType; |
||||
readonly uint rank; |
||||
|
||||
public uint Lenght { |
||||
get { |
||||
return lenght; |
||||
} |
||||
} |
||||
|
||||
public string ElementsType { |
||||
get { |
||||
return CorTypeToString(corElementType); |
||||
} |
||||
} |
||||
|
||||
public uint Rank { |
||||
get { |
||||
return rank; |
||||
} |
||||
} |
||||
|
||||
public override object Value { |
||||
get { |
||||
string txt = "{" + ElementsType + "["; |
||||
for (int i = 0; i < rank; i++) |
||||
txt += dimensions[i].ToString() + ","; |
||||
txt = txt.TrimEnd(new char[] {','}) + "]}"; |
||||
return txt; |
||||
} |
||||
} |
||||
|
||||
|
||||
internal unsafe ArrayVariable(ICorDebugValue corValue, string name):base(corValue, name) |
||||
{ |
||||
corArrayValue = (ICorDebugArrayValue)this.corValue; |
||||
uint corElementTypeRaw; |
||||
corArrayValue.GetElementType(out corElementTypeRaw); |
||||
corElementType = (CorElementType)corElementTypeRaw; |
||||
|
||||
corArrayValue.GetRank(out rank); |
||||
corArrayValue.GetCount(out lenght); |
||||
|
||||
dimensions = new uint[rank]; |
||||
fixed (void* pDimensions = dimensions) |
||||
corArrayValue.GetDimensions(rank, new IntPtr(pDimensions)); |
||||
} |
||||
|
||||
|
||||
public Variable this[uint index] { |
||||
get { |
||||
return this[new uint[] {index}]; |
||||
} |
||||
} |
||||
|
||||
public Variable this[uint index1, uint index2] { |
||||
get { |
||||
return this[new uint[] {index1, index2}]; |
||||
} |
||||
} |
||||
|
||||
public Variable this[uint index1, uint index2, uint index3] { |
||||
get { |
||||
return this[new uint[] {index1, index2, index3}]; |
||||
} |
||||
} |
||||
|
||||
public unsafe Variable this[uint[] indices] { |
||||
get { |
||||
if (indices.Length != rank) throw new DebuggerException("Given indicies does not match array size."); |
||||
|
||||
string elementName = "["; |
||||
for (int i = 0; i < indices.Length; i++) |
||||
elementName += indices[i].ToString() + ","; |
||||
elementName = elementName.TrimEnd(new char[] {','}) + "]"; |
||||
|
||||
ICorDebugValue element; |
||||
fixed (void* pIndices = indices) |
||||
corArrayValue.GetElement(rank, new IntPtr(pIndices), out element); |
||||
|
||||
return VariableFactory.CreateVariable(element, elementName); |
||||
} |
||||
} |
||||
|
||||
|
||||
protected override VariableCollection GetSubVariables() |
||||
{ |
||||
VariableCollection subVariables = new VariableCollection(); |
||||
|
||||
uint[] indices = new uint[rank]; |
||||
|
||||
for(;;) // Go thought all combinations
|
||||
{ |
||||
for (uint i = rank - 1; i >= 1; i--) |
||||
if (indices[i] >= dimensions[i]) |
||||
{ |
||||
indices[i] = 0; |
||||
indices[i-1]++; |
||||
} |
||||
if (indices[0] >= dimensions[0]) break; // We are done
|
||||
|
||||
subVariables.Add(this[indices]); |
||||
|
||||
indices[rank - 1]++; |
||||
} |
||||
|
||||
return subVariables; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,57 @@
@@ -0,0 +1,57 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Runtime.InteropServices; |
||||
|
||||
using DebuggerInterop.Core; |
||||
using DebuggerInterop.Symbols; |
||||
|
||||
namespace DebuggerLibrary |
||||
{ |
||||
public class BuiltInVariable: Variable |
||||
{ |
||||
public override unsafe object Value |
||||
{ |
||||
get |
||||
{ |
||||
if (corType == CorElementType.STRING) |
||||
{ |
||||
((ICorDebugStringValue)corValue).GetString(NDebugger.pStringLen, |
||||
out NDebugger.unused, |
||||
NDebugger.pString); |
||||
return NDebugger.pStringAsUnicode; |
||||
} |
||||
|
||||
object retValue; |
||||
IntPtr pValue = Marshal.AllocHGlobal(8); |
||||
((ICorDebugGenericValue)corValue).GetValue(pValue); |
||||
switch(corType) |
||||
{ |
||||
case CorElementType.BOOLEAN: retValue = *((System.Boolean*)pValue); break; |
||||
case CorElementType.CHAR: retValue = *((System.Char*)pValue); break; |
||||
case CorElementType.I1: retValue = *((System.SByte*)pValue); break; |
||||
case CorElementType.U1: retValue = *((System.Byte*)pValue); break; |
||||
case CorElementType.I2: retValue = *((System.Int16*)pValue); break; |
||||
case CorElementType.U2: retValue = *((System.UInt16*)pValue); break; |
||||
case CorElementType.I4: retValue = *((System.Int32*)pValue); break; |
||||
case CorElementType.U4: retValue = *((System.UInt32*)pValue); break; |
||||
case CorElementType.I8: retValue = *((System.Int64*)pValue); break; |
||||
case CorElementType.U8: retValue = *((System.UInt64*)pValue); break; |
||||
case CorElementType.R4: retValue = *((System.Single*)pValue); break; |
||||
case CorElementType.R8: retValue = *((System.Double*)pValue); break; |
||||
case CorElementType.I: retValue = *((int*)pValue); break; |
||||
case CorElementType.U: retValue = *((uint*)pValue); break; |
||||
default: retValue = null; break; |
||||
} |
||||
Marshal.FreeHGlobal(pValue); |
||||
return retValue; |
||||
} |
||||
} |
||||
|
||||
internal BuiltInVariable(ICorDebugValue corValue, string name):base(corValue, name) |
||||
{ |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,43 @@
@@ -0,0 +1,43 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Runtime.InteropServices; |
||||
|
||||
using DebuggerInterop.Core; |
||||
using DebuggerInterop.Symbols; |
||||
|
||||
namespace DebuggerLibrary |
||||
{ |
||||
public class NullRefVariable: Variable |
||||
{ |
||||
public override object Value { |
||||
get { |
||||
return "<null reference>"; |
||||
} |
||||
} |
||||
|
||||
public override string Type |
||||
{ |
||||
get |
||||
{ |
||||
switch (corType) |
||||
{ |
||||
case CorElementType.SZARRAY: |
||||
case CorElementType.ARRAY: return typeof(System.Array).ToString(); |
||||
case CorElementType.OBJECT: return typeof(System.Object).ToString(); |
||||
case CorElementType.STRING: return typeof(System.String).ToString(); |
||||
case CorElementType.CLASS: return "<class>"; |
||||
default: return string.Empty; |
||||
} |
||||
} |
||||
} |
||||
|
||||
internal unsafe NullRefVariable(ICorDebugValue corValue, string name):base(corValue, name) |
||||
{ |
||||
|
||||
} |
||||
} |
||||
} |
||||
|
@ -0,0 +1,179 @@
@@ -0,0 +1,179 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections; |
||||
using System.Diagnostics; |
||||
using System.Collections.Specialized; |
||||
using System.Runtime.InteropServices; |
||||
|
||||
using DebuggerInterop.Core; |
||||
using DebuggerInterop.Symbols; |
||||
using DebuggerInterop.MetaData; |
||||
|
||||
namespace DebuggerLibrary |
||||
{ |
||||
public class ObjectVariable: Variable |
||||
{ |
||||
ICorDebugClass corClass; |
||||
ICorDebugModule corModule; |
||||
IMetaDataImport metaData; |
||||
uint classToken; |
||||
uint superCallsToken; |
||||
ICorDebugModule corModuleSuperclass; |
||||
ObjectVariable baseClass; |
||||
string type; |
||||
|
||||
public override object Value { |
||||
get{ |
||||
return "{" + type + "}"; |
||||
} |
||||
} |
||||
|
||||
public override string Type { |
||||
get{ |
||||
return type; |
||||
} |
||||
} |
||||
|
||||
|
||||
internal unsafe ObjectVariable(ICorDebugValue corValue, string name):base(corValue, name) |
||||
{ |
||||
((ICorDebugObjectValue)this.corValue).GetClass(out corClass); |
||||
InitObjectVariable(); |
||||
} |
||||
|
||||
internal unsafe ObjectVariable(ICorDebugValue corValue, string name, ICorDebugClass corClass):base(corValue, name) |
||||
{ |
||||
this.corClass = corClass; |
||||
InitObjectVariable(); |
||||
} |
||||
|
||||
void InitObjectVariable () |
||||
{ |
||||
corClass.GetToken(out classToken); |
||||
corClass.GetModule(out corModule); |
||||
metaData = new Module(corModule).MetaDataInterface; //TODO
|
||||
|
||||
metaData.GetTypeDefProps(classToken, |
||||
NDebugger.pString, |
||||
NDebugger.pStringLen, |
||||
out NDebugger.unused, // real string lenght
|
||||
out NDebugger.unused, |
||||
out superCallsToken); |
||||
type = NDebugger.pStringAsUnicode; |
||||
corModuleSuperclass = corModule; |
||||
} |
||||
|
||||
|
||||
protected override unsafe VariableCollection GetSubVariables() |
||||
{ |
||||
VariableCollection subVariables = new VariableCollection(); |
||||
|
||||
IntPtr fieldsEnumPtr = IntPtr.Zero; |
||||
for(;;) |
||||
{ |
||||
uint fieldToken; |
||||
uint fieldCount; |
||||
metaData.EnumFields(ref fieldsEnumPtr, classToken, out fieldToken, 1, out fieldCount); |
||||
if (fieldCount == 0) |
||||
{ |
||||
metaData.CloseEnum(fieldsEnumPtr); |
||||
break; |
||||
} |
||||
|
||||
uint attrib; |
||||
metaData.GetFieldProps(fieldToken, |
||||
out NDebugger.unused, |
||||
NDebugger.pString, |
||||
NDebugger.pStringLen, |
||||
out NDebugger.unused, // real string lenght
|
||||
out attrib, |
||||
IntPtr.Zero, |
||||
out NDebugger.unused, |
||||
out NDebugger.unused, |
||||
out NDebugger.unusedPtr, |
||||
out NDebugger.unused); |
||||
string name = NDebugger.pStringAsUnicode; |
||||
|
||||
ICorDebugValue innerValue; |
||||
if ((attrib & (uint)ClassFieldAttribute.fdStatic)!=0) |
||||
{ |
||||
if ((attrib & (uint)ClassFieldAttribute.fdLiteral)!=0) continue; // Get next field
|
||||
corClass.GetStaticFieldValue(fieldToken, null, out innerValue); |
||||
} |
||||
else |
||||
{ |
||||
if (corValue == null) continue; // Try next field
|
||||
|
||||
((ICorDebugObjectValue)corValue).GetFieldValue(corClass, fieldToken, out innerValue); |
||||
} |
||||
|
||||
subVariables.Add(VariableFactory.CreateVariable(innerValue, name)); |
||||
} |
||||
|
||||
return subVariables; |
||||
} |
||||
|
||||
public unsafe ObjectVariable BaseClass { |
||||
get { |
||||
if (baseClass == null) baseClass = GetBaseClass(); |
||||
if (baseClass == null) throw new UnableToGetPropertyException(this, "BaseClass", "Object doesn't have a base class"); |
||||
return baseClass; |
||||
} |
||||
} |
||||
|
||||
public bool HasBaseClass { |
||||
get { |
||||
if (baseClass == null) baseClass = GetBaseClass(); |
||||
return (baseClass != null); |
||||
} |
||||
} |
||||
|
||||
protected ObjectVariable GetBaseClass() |
||||
{ |
||||
string fullTypeName = "<>"; |
||||
|
||||
// If referencing to external assembly
|
||||
if ((superCallsToken & 0x01000000) != 0) |
||||
{ |
||||
metaData.GetTypeRefProps(superCallsToken, |
||||
out NDebugger.unused, |
||||
NDebugger.pString, |
||||
NDebugger.pStringLen, |
||||
out NDebugger.unused); // real string lenght
|
||||
fullTypeName = NDebugger.pStringAsUnicode; |
||||
|
||||
superCallsToken = 0; |
||||
foreach (Module m in NDebugger.Modules) |
||||
{ |
||||
// TODO: Does not work for nested
|
||||
// see FindTypeDefByName in dshell.cpp
|
||||
// TODO: preservesig
|
||||
try { |
||||
m.MetaDataInterface.FindTypeDefByName(fullTypeName, 0, out superCallsToken); |
||||
} |
||||
catch { |
||||
continue; |
||||
} |
||||
corModuleSuperclass = m.CorModule; |
||||
break; |
||||
} |
||||
if (superCallsToken == 0) throw new DebuggerException("Unable to get base class: " + fullTypeName); |
||||
} |
||||
|
||||
// If it has no base class
|
||||
if ((superCallsToken & 0x00FFFFFF) == 0) |
||||
{ |
||||
return null; |
||||
} |
||||
else |
||||
{ |
||||
ICorDebugClass superClass; |
||||
corModuleSuperclass.GetClassFromToken(superCallsToken, out superClass); |
||||
return new ObjectVariable(corValue, Name, superClass); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,66 @@
@@ -0,0 +1,66 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
|
||||
using DebuggerInterop.Core; |
||||
using DebuggerInterop.Symbols; |
||||
|
||||
namespace DebuggerLibrary |
||||
{ |
||||
public class PropertyVariable: Variable |
||||
{ |
||||
Eval eval; |
||||
Variable currentValue; |
||||
public event EventHandler ValueEvaluated; |
||||
|
||||
internal PropertyVariable(Eval eval, string name):base(null, name) |
||||
{ |
||||
this.eval = eval; |
||||
eval.EvalComplete += new EventHandler(EvalComplete); |
||||
} |
||||
|
||||
public override object Value { |
||||
get { |
||||
if (currentValue == null) { |
||||
return String.Empty; |
||||
} |
||||
return currentValue.Value; |
||||
} |
||||
} |
||||
|
||||
public override string Type { |
||||
get { |
||||
if (currentValue == null) { |
||||
return String.Empty; |
||||
} |
||||
return currentValue.Type; |
||||
} |
||||
} |
||||
|
||||
public override VariableCollection SubVariables { |
||||
get { |
||||
if (currentValue == null) { |
||||
return new VariableCollection(); |
||||
} |
||||
return currentValue.SubVariables; |
||||
} |
||||
} |
||||
|
||||
internal void EvalComplete(object sender, EventArgs args) |
||||
{ |
||||
/*ICorDebugValue corValue; |
||||
eval.corEval.GetResult(out corValue); |
||||
currentValue = VariableFactory.CreateVariable(corValue, Name); |
||||
OnValueEvaluated();*/ |
||||
} |
||||
|
||||
internal void OnValueEvaluated() |
||||
{ |
||||
if (ValueEvaluated != null) { |
||||
ValueEvaluated(this, EventArgs.Empty); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,33 @@
@@ -0,0 +1,33 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Runtime.InteropServices; |
||||
|
||||
using DebuggerInterop.Core; |
||||
using DebuggerInterop.Symbols; |
||||
|
||||
namespace DebuggerLibrary |
||||
{ |
||||
public class UnknownVariable: Variable |
||||
{ |
||||
public override object Value { |
||||
get { |
||||
return "<unknown>"; |
||||
} |
||||
} |
||||
|
||||
public override string Type { |
||||
get { |
||||
return "<unknown>"; |
||||
} |
||||
} |
||||
|
||||
internal unsafe UnknownVariable(ICorDebugValue corValue, string name):base(corValue, name) |
||||
{ |
||||
|
||||
} |
||||
} |
||||
} |
||||
|
@ -0,0 +1,137 @@
@@ -0,0 +1,137 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Diagnostics; |
||||
using System.Runtime.InteropServices; |
||||
|
||||
using DebuggerInterop.Core; |
||||
using DebuggerInterop.Symbols; |
||||
|
||||
namespace DebuggerLibrary |
||||
{ |
||||
public abstract class Variable |
||||
{ |
||||
readonly string name; |
||||
protected ICorDebugValue corValue; |
||||
VariableCollection subVariables; |
||||
|
||||
|
||||
public string Name { |
||||
get{ |
||||
return name; |
||||
} |
||||
} |
||||
|
||||
public abstract object Value { |
||||
get; |
||||
} |
||||
|
||||
internal CorElementType corType { |
||||
get { |
||||
return GetCorType(corValue); |
||||
} |
||||
} |
||||
|
||||
public virtual string Type { |
||||
get{ |
||||
return CorTypeToString(corType); |
||||
} |
||||
} |
||||
|
||||
public virtual VariableCollection SubVariables { |
||||
get{ |
||||
if (subVariables == null) subVariables = GetSubVariables(); |
||||
return subVariables; |
||||
} |
||||
} |
||||
|
||||
internal Variable(ICorDebugValue corValue, string name) |
||||
{ |
||||
if (corValue != null) { |
||||
this.corValue = DereferenceUnbox(corValue); |
||||
} |
||||
this.name = name; |
||||
} |
||||
|
||||
protected virtual VariableCollection GetSubVariables() |
||||
{ |
||||
return new VariableCollection(); |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return String.Format("Name = {0,-25} Value = {1,-30} Type = {2,-30}", Name, Value, Type); |
||||
} |
||||
|
||||
|
||||
|
||||
internal static CorElementType GetCorType(ICorDebugValue corValue) |
||||
{ |
||||
if (corValue == null) { |
||||
return (CorElementType)0; |
||||
} |
||||
uint typeRaw; |
||||
corValue.GetType(out typeRaw); |
||||
return (CorElementType)typeRaw; |
||||
} |
||||
|
||||
internal static System.Type CorTypeToManagedType(CorElementType corType) |
||||
{ |
||||
switch(corType) |
||||
{ |
||||
case CorElementType.BOOLEAN: return typeof(System.Boolean); |
||||
case CorElementType.CHAR: return typeof(System.Char); |
||||
case CorElementType.I1: return typeof(System.SByte); |
||||
case CorElementType.U1: return typeof(System.Byte); |
||||
case CorElementType.I2: return typeof(System.Int16); |
||||
case CorElementType.U2: return typeof(System.UInt16); |
||||
case CorElementType.I4: return typeof(System.Int32); |
||||
case CorElementType.U4: return typeof(System.UInt32); |
||||
case CorElementType.I8: return typeof(System.Int64); |
||||
case CorElementType.U8: return typeof(System.UInt64); |
||||
case CorElementType.R4: return typeof(System.Single); |
||||
case CorElementType.R8: return typeof(System.Double); |
||||
case CorElementType.I: return typeof(int); |
||||
case CorElementType.U: return typeof(uint); |
||||
case CorElementType.SZARRAY: |
||||
case CorElementType.ARRAY: return typeof(System.Array); |
||||
case CorElementType.OBJECT: return typeof(System.Object); |
||||
case CorElementType.STRING: return typeof(System.String); |
||||
default: return null; |
||||
} |
||||
} |
||||
|
||||
internal static string CorTypeToString(CorElementType corType) |
||||
{ |
||||
Type manType = CorTypeToManagedType(corType); |
||||
if (manType == null) return "<unknown>"; |
||||
return manType.ToString(); |
||||
} |
||||
|
||||
|
||||
internal static ICorDebugValue DereferenceUnbox(ICorDebugValue corValue) |
||||
{ |
||||
if (corValue is ICorDebugReferenceValue) { |
||||
int isNull; |
||||
((ICorDebugReferenceValue)corValue).IsNull(out isNull); |
||||
if (isNull == 0) { |
||||
ICorDebugValue dereferencedValue; |
||||
((ICorDebugReferenceValue)corValue).Dereference(out dereferencedValue); |
||||
return DereferenceUnbox(dereferencedValue); // Try again
|
||||
} else { |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
if (corValue is ICorDebugBoxValue) { |
||||
ICorDebugObjectValue corUnboxedValue; |
||||
((ICorDebugBoxValue)corValue).GetObject(out corUnboxedValue); |
||||
return DereferenceUnbox(corUnboxedValue); // Try again
|
||||
} |
||||
|
||||
return corValue; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,48 @@
@@ -0,0 +1,48 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections; |
||||
using System.Diagnostics; |
||||
|
||||
using DebuggerInterop.Core; |
||||
|
||||
namespace DebuggerLibrary |
||||
{ |
||||
public class VariableCollection: ReadOnlyCollectionBase |
||||
{ |
||||
internal void Add(Variable variable) |
||||
{ |
||||
System.Diagnostics.Trace.Assert(variable != null); |
||||
if (variable != null) |
||||
InnerList.Add(variable); |
||||
} |
||||
|
||||
public Variable this[int index] { |
||||
get { |
||||
return (Variable) InnerList[index]; |
||||
} |
||||
} |
||||
|
||||
public Variable this[string variableName] |
||||
{ |
||||
get { |
||||
foreach (Variable v in InnerList) |
||||
if (v.Name == variableName) |
||||
return v; |
||||
|
||||
throw new UnableToGetPropertyException(this, "this[string]", "Variable \"" + variableName + "\" is not in collection"); |
||||
} |
||||
} |
||||
|
||||
public override string ToString() { |
||||
string txt = ""; |
||||
foreach(Variable v in this) { |
||||
txt += v.ToString() + "\n"; |
||||
} |
||||
return txt; |
||||
} |
||||
|
||||
} |
||||
} |
@ -0,0 +1,56 @@
@@ -0,0 +1,56 @@
|
||||
// <file>
|
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
|
||||
using DebuggerInterop.Core; |
||||
using DebuggerInterop.Symbols; |
||||
|
||||
namespace DebuggerLibrary |
||||
{ |
||||
internal class VariableFactory |
||||
{ |
||||
public static Variable CreateVariable(ICorDebugValue corValue, string name) |
||||
{ |
||||
CorElementType type = Variable.GetCorType(corValue); |
||||
|
||||
if (Variable.DereferenceUnbox(corValue) == null) |
||||
{ |
||||
return new NullRefVariable(corValue, name); |
||||
} |
||||
|
||||
switch(type) |
||||
{ |
||||
case CorElementType.BOOLEAN: |
||||
case CorElementType.CHAR: |
||||
case CorElementType.I1: |
||||
case CorElementType.U1: |
||||
case CorElementType.I2: |
||||
case CorElementType.U2: |
||||
case CorElementType.I4: |
||||
case CorElementType.U4: |
||||
case CorElementType.I8: |
||||
case CorElementType.U8: |
||||
case CorElementType.R4: |
||||
case CorElementType.R8: |
||||
case CorElementType.I: |
||||
case CorElementType.U: |
||||
case CorElementType.STRING: |
||||
return new BuiltInVariable(corValue, name); |
||||
|
||||
case CorElementType.ARRAY: |
||||
case CorElementType.SZARRAY: // Short-cut for single dimension zero lower bound array
|
||||
return new ArrayVariable(corValue, name); |
||||
|
||||
case CorElementType.VALUETYPE: |
||||
case CorElementType.CLASS: |
||||
case CorElementType.OBJECT: // Short-cut for Class "System.Object"
|
||||
return new ObjectVariable(corValue, name); |
||||
|
||||
default: // Unknown type
|
||||
return new UnknownVariable(corValue, name); |
||||
} |
||||
} |
||||
} |
||||
} |
Binary file not shown.
@ -0,0 +1,7 @@
@@ -0,0 +1,7 @@
|
||||
Debugger.Core and Debugger.Interop are the two libraries that hold most core debugging functionality. |
||||
|
||||
The vast majority of the code of these libraries was written by me without any modifications made by other people. If you could preserve this ratio by not making any modifications, I would be extremely pleased and I would be indebted to you. |
||||
|
||||
However, if you find a bug or if you have an idea or suggestion, please do send me an e-mail to dsrbecky at post.cz |
||||
|
||||
Thank you very much, David Srbecky |
@ -0,0 +1,21 @@
@@ -0,0 +1,21 @@
|
||||
// <file> |
||||
// <owner name="David Srbecký" email="dsrbecky@post.cz"/> |
||||
// </file> |
||||
|
||||
.assembly extern mscorlib |
||||
{ |
||||
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. |
||||
.ver 1:0:5000:0 |
||||
} |
||||
|
||||
.assembly Debugger.Interop |
||||
{ |
||||
.ver 1:0:0:0 |
||||
} |
||||
|
||||
.module Debugger.Interop |
||||
// MVID: {D99DDAB7-C9D5-462D-9019-F632E9BAF060} |
||||
.imagebase 0x00400000 |
||||
.subsystem 0x00000003 |
||||
.file alignment 4096 |
||||
.corflags 0x00000001 |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,609 @@
@@ -0,0 +1,609 @@
|
||||
// |
||||
// ============== CLASS STRUCTURE DECLARATION ================== |
||||
// |
||||
.namespace DebuggerInterop.MetaData |
||||
{ |
||||
.class interface public abstract auto ansi import IMetaDataImport |
||||
{ |
||||
} // end of class IMetaDataImport |
||||
|
||||
.class public sequential ansi sealed beforefieldinit COR_FIELD_OFFSET |
||||
extends [mscorlib]System.ValueType |
||||
{ |
||||
} // end of class COR_FIELD_OFFSET |
||||
|
||||
} // end of namespace MetaData |
||||
|
||||
|
||||
// ============================================================= |
||||
|
||||
|
||||
// =============== GLOBAL FIELDS AND METHODS =================== |
||||
|
||||
|
||||
// ============================================================= |
||||
|
||||
|
||||
// =============== CLASS MEMBERS DECLARATION =================== |
||||
// note that class flags, 'extends' and 'implements' clauses |
||||
// are provided here for information only |
||||
|
||||
.namespace DebuggerInterop.MetaData |
||||
{ |
||||
.class interface public abstract auto ansi import IMetaDataImport |
||||
{ |
||||
.custom instance void [mscorlib]System.Runtime.InteropServices.GuidAttribute::.ctor(string) = ( 01 00 24 37 44 41 43 38 32 30 37 2D 44 33 41 45 // ..$7DAC8207-D3AE |
||||
2D 34 43 37 35 2D 39 42 36 37 2D 39 32 38 30 31 // -4C75-9B67-92801 |
||||
41 34 39 37 44 34 34 00 00 ) // A497D44.. |
||||
.custom instance void [mscorlib]System.Runtime.InteropServices.InterfaceTypeAttribute::.ctor(int16) = ( 01 00 01 00 00 00 ) |
||||
.custom instance void [mscorlib]System.Runtime.InteropServices.ComConversionLossAttribute::.ctor() = ( 01 00 00 00 ) |
||||
.method public hidebysig newslot abstract virtual |
||||
instance void CloseEnum(native int hEnum) runtime managed preservesig internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::CloseEnum |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void CountEnum(native int hEnum, |
||||
unsigned int32& pulCount) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::CountEnum |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void ResetEnum(native int hEnum, |
||||
unsigned int32 ulPos) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::ResetEnum |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void EnumTypeDefs(native int& phEnum, |
||||
unsigned int32& rTypeDefs, |
||||
unsigned int32 cMax, |
||||
unsigned int32& pcTypeDefs) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::EnumTypeDefs |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void EnumInterfaceImpls(native int& phEnum, |
||||
unsigned int32 td, |
||||
unsigned int32& rImpls, |
||||
unsigned int32 cMax, |
||||
unsigned int32& pcImpls) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::EnumInterfaceImpls |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void EnumTypeRefs(native int& phEnum, |
||||
unsigned int32& rTypeRefs, |
||||
unsigned int32 cMax, |
||||
unsigned int32& pcTypeRefs) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::EnumTypeRefs |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void FindTypeDefByName([in] string marshal( lpwstr) szTypeDef, |
||||
[in] unsigned int32 tkEnclosingClass, |
||||
[out] unsigned int32& ptd) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::FindTypeDefByName |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void GetScopeProps([out] string marshal( lpwstr) szName, |
||||
[in] unsigned int32 cchName, |
||||
[out] unsigned int32& pchName, |
||||
[out] valuetype [mscorlib]System.Guid& pmvid) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::GetScopeProps |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void GetModuleFromScope([out] unsigned int32& pmd) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::GetModuleFromScope |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void GetTypeDefProps([in] unsigned int32 td, |
||||
[out] native int szTypeDef, |
||||
[in] unsigned int32 cchTypeDef, |
||||
[out] unsigned int32& pchTypeDef, |
||||
[out] unsigned int32& pdwTypeDefFlags, |
||||
[out] unsigned int32& ptkExtends) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::GetTypeDefProps |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void GetInterfaceImplProps([in] unsigned int32 iiImpl, |
||||
[out] unsigned int32& pClass, |
||||
[out] unsigned int32& ptkIface) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::GetInterfaceImplProps |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void GetTypeRefProps([in] unsigned int32 tr, |
||||
[out] unsigned int32& ptkResolutionScope, |
||||
[out] native int szName, |
||||
[in] unsigned int32 cchName, |
||||
[out] unsigned int32& pchName) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::GetTypeRefProps |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void ResolveTypeRef(unsigned int32 tr, |
||||
valuetype [mscorlib]System.Guid& riid, |
||||
object& marshal( iunknown) ppIScope, |
||||
unsigned int32& ptd) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::ResolveTypeRef |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void EnumMembers([in] native int& phEnum, |
||||
[in] unsigned int32 cl, |
||||
[out] unsigned int32& rMembers, |
||||
[in] unsigned int32 cMax, |
||||
[out] unsigned int32& pcTokens) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::EnumMembers |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void EnumMembersWithName([in][out] native int& phEnum, |
||||
[in] unsigned int32 cl, |
||||
[in] string marshal( lpwstr) szName, |
||||
[out] unsigned int32& rMembers, |
||||
[in] unsigned int32 cMax, |
||||
[out] unsigned int32& pcTokens) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::EnumMembersWithName |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void EnumMethods([in] native int& phEnum, |
||||
[in] unsigned int32 cl, |
||||
[out] unsigned int32& rMethods, |
||||
[in] unsigned int32 cMax, |
||||
[out] unsigned int32& pcTokens) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::EnumMethods |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void EnumMethodsWithName([in] native int& phEnum, |
||||
[in] unsigned int32 cl, |
||||
[in] string marshal( lpwstr) szName, |
||||
[out] unsigned int32& rMethods, |
||||
[in] unsigned int32 cMax, |
||||
[out] unsigned int32& pcTokens) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::EnumMethodsWithName |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void EnumFields([in][out] native int& phEnum, |
||||
[in] unsigned int32 cl, |
||||
[out] unsigned int32& rFields, |
||||
[in] unsigned int32 cMax, |
||||
[out] unsigned int32& pcTokens) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::EnumFields |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void EnumFieldsWithName([in][out] native int& phEnum, |
||||
[in] unsigned int32 cl, |
||||
[in] string marshal( lpwstr) szName, |
||||
[out] unsigned int32& rFields, |
||||
[in] unsigned int32 cMax, |
||||
[out] unsigned int32& pcTokens) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::EnumFieldsWithName |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void EnumParams([in] native int& phEnum, |
||||
[in] unsigned int32 mb, |
||||
[out] unsigned int32& rParams, |
||||
[in] unsigned int32 cMax, |
||||
[out] unsigned int32& pcTokens) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::EnumParams |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void EnumMemberRefs([in] native int& phEnum, |
||||
[in] unsigned int32 tkParent, |
||||
[out] unsigned int32& rMemberRefs, |
||||
[in] unsigned int32 cMax, |
||||
[out] unsigned int32& pcTokens) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::EnumMemberRefs |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void EnumMethodImpls([in][out] native int& phEnum, |
||||
[in] unsigned int32 td, |
||||
[out] unsigned int32& rMethodBody, |
||||
[out] unsigned int32& rMethodDecl, |
||||
[in] unsigned int32 cMax, |
||||
[out] unsigned int32& pcTokens) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::EnumMethodImpls |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void EnumPermissionSets([in][out] native int& phEnum, |
||||
[in] unsigned int32 tk, |
||||
[in] unsigned int32 dwActions, |
||||
[out] unsigned int32& rPermission, |
||||
[in] unsigned int32 cMax, |
||||
[out] unsigned int32& pcTokens) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::EnumPermissionSets |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void FindMember([in] unsigned int32 td, |
||||
[in] string marshal( lpwstr) szName, |
||||
[in] unsigned int8& pvSigBlob, |
||||
[in] unsigned int32 cbSigBlob, |
||||
[out] unsigned int32& pmb) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::FindMember |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void FindMethod([in] unsigned int32 td, |
||||
[in] string marshal( lpwstr) szName, |
||||
[in] unsigned int8& pvSigBlob, |
||||
[in] unsigned int32 cbSigBlob, |
||||
[out] unsigned int32& pmb) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::FindMethod |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void FindField([in] unsigned int32 td, |
||||
[in] string marshal( lpwstr) szName, |
||||
[in] unsigned int8& pvSigBlob, |
||||
[in] unsigned int32 cbSigBlob, |
||||
[out] unsigned int32& pmb) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::FindField |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void FindMemberRef([in] unsigned int32 td, |
||||
[in] string marshal( lpwstr) szName, |
||||
[in] unsigned int8& pvSigBlob, |
||||
[in] unsigned int32 cbSigBlob, |
||||
[out] unsigned int32& pmr) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::FindMemberRef |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void GetMethodProps([in] unsigned int32 mb, |
||||
[out] unsigned int32& pClass, |
||||
[out] native int szMethod, |
||||
[in] unsigned int32 cchMethod, |
||||
[out] unsigned int32& pchMethod, |
||||
[out] unsigned int32& pdwAttr, |
||||
[out] native int ppvSigBlob, |
||||
[out] unsigned int32& pcbSigBlob, |
||||
[out] unsigned int32& pulCodeRVA, |
||||
[out] unsigned int32& pdwImplFlags) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::GetMethodProps |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void GetMemberRefProps([in] unsigned int32 mr, |
||||
[out] unsigned int32& ptk, |
||||
[out] string marshal( lpwstr) szMember, |
||||
[in] unsigned int32 cchMember, |
||||
[out] unsigned int32& pchMember, |
||||
[out] native int ppvSigBlob, |
||||
[out] unsigned int32& pbSig) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::GetMemberRefProps |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void EnumProperties([in] native int& phEnum, |
||||
[in] unsigned int32 td, |
||||
[out] unsigned int32& rProperties, |
||||
[in] unsigned int32 cMax, |
||||
[out] unsigned int32& pcProperties) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::EnumProperties |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void EnumEvents([in][out] native int& phEnum, |
||||
[in] unsigned int32 td, |
||||
[out] unsigned int32& rEvents, |
||||
[in] unsigned int32 cMax, |
||||
[out] unsigned int32& pcEvents) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::EnumEvents |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void GetEventProps([in] unsigned int32 ev, |
||||
[out] unsigned int32& pClass, |
||||
[out] string marshal( lpwstr) szEvent, |
||||
[in] unsigned int32 cchEvent, |
||||
[out] unsigned int32& pchEvent, |
||||
[out] unsigned int32& pdwEventFlags, |
||||
[out] unsigned int32& ptkEventType, |
||||
[out] unsigned int32& pmdAddOn, |
||||
[out] unsigned int32& pmdRemoveOn, |
||||
[out] unsigned int32& pmdFire, |
||||
[out] unsigned int32& rmdOtherMethod, |
||||
[in] unsigned int32 cMax, |
||||
[out] unsigned int32& pcOtherMethod) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::GetEventProps |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void EnumMethodSemantics([in][out] native int& phEnum, |
||||
[in] unsigned int32 mb, |
||||
[out] unsigned int32& rEventProp, |
||||
[in] unsigned int32 cMax, |
||||
[out] unsigned int32& pcEventProp) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::EnumMethodSemantics |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void GetMethodSemantics([in] unsigned int32 mb, |
||||
[in] unsigned int32 tkEventProp, |
||||
[out] unsigned int32& pdwSemanticsFlags) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::GetMethodSemantics |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void GetClassLayout([in] unsigned int32 td, |
||||
[out] unsigned int32& pdwPackSize, |
||||
[out] valuetype DebuggerInterop.MetaData.COR_FIELD_OFFSET& rFieldOffset, |
||||
[in] unsigned int32 cMax, |
||||
[out] unsigned int32& pcFieldOffset, |
||||
[out] unsigned int32& pulClassSize) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::GetClassLayout |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void GetFieldMarshal([in] unsigned int32 tk, |
||||
[out] native int ppvNativeType, |
||||
[out] unsigned int32& pcbNativeType) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::GetFieldMarshal |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void GetRVA([in] unsigned int32 tk, |
||||
[out] unsigned int32& pulCodeRVA, |
||||
[out] unsigned int32& pdwImplFlags) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::GetRVA |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void GetPermissionSetProps([in] unsigned int32 pm, |
||||
[out] unsigned int32& pdwAction, |
||||
[out] native int& ppvPermission, |
||||
[out] unsigned int32& pcbPermission) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::GetPermissionSetProps |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void GetSigFromToken([in] unsigned int32 mdSig, |
||||
[out] native int ppvSig, |
||||
[out] unsigned int32& pcbSig) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::GetSigFromToken |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void GetModuleRefProps([in] unsigned int32 mur, |
||||
[out] string marshal( lpwstr) szName, |
||||
[in] unsigned int32 cchName, |
||||
[out] unsigned int32& pchName) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::GetModuleRefProps |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void EnumModuleRefs([in][out] native int& phEnum, |
||||
[out] unsigned int32& rModuleRefs, |
||||
[in] unsigned int32 cMax, |
||||
[out] unsigned int32& pcModuleRefs) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::EnumModuleRefs |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void GetTypeSpecFromToken([in] unsigned int32 typespec, |
||||
[out] native int ppvSig, |
||||
[out] unsigned int32& pcbSig) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::GetTypeSpecFromToken |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void GetNameFromToken([in] unsigned int32 tk, |
||||
[out] native int pszUtf8NamePtr) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::GetNameFromToken |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void EnumUnresolvedMethods([in][out] native int& phEnum, |
||||
[out] unsigned int32& rMethods, |
||||
[in] unsigned int32 cMax, |
||||
[out] unsigned int32& pcTokens) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::EnumUnresolvedMethods |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void GetUserString([in] unsigned int32 stk, |
||||
[out] string marshal( lpwstr) szString, |
||||
[in] unsigned int32 cchString, |
||||
[out] unsigned int32& pchString) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::GetUserString |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void GetPinvokeMap([in] unsigned int32 tk, |
||||
[out] unsigned int32& pdwMappingFlags, |
||||
[out] string marshal( lpwstr) szImportName, |
||||
[in] unsigned int32 cchImportName, |
||||
[out] unsigned int32& pchImportName, |
||||
[out] unsigned int32& pmrImportDLL) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::GetPinvokeMap |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void EnumSignatures([in][out] native int& phEnum, |
||||
[out] unsigned int32& rSignatures, |
||||
[in] unsigned int32 cMax, |
||||
[out] unsigned int32& pcSignatures) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::EnumSignatures |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void EnumTypeSpecs([in][out] native int& phEnum, |
||||
[out] unsigned int32& rTypeSpecs, |
||||
[in] unsigned int32 cMax, |
||||
[out] unsigned int32& pcTypeSpecs) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::EnumTypeSpecs |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void EnumUserStrings([in][out] native int& phEnum, |
||||
[out] unsigned int32& rStrings, |
||||
[in] unsigned int32 cMax, |
||||
[out] unsigned int32& pcStrings) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::EnumUserStrings |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void GetParamForMethodIndex([in] unsigned int32 md, |
||||
[in] unsigned int32 ulParamSeq, |
||||
[in] unsigned int32& ppd) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::GetParamForMethodIndex |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void EnumCustomAttributes([in][out] native int& phEnum, |
||||
[in] unsigned int32 tk, |
||||
[in] unsigned int32 tkType, |
||||
[out] unsigned int32& rCustomAttributes, |
||||
[in] unsigned int32 cMax, |
||||
[out] unsigned int32& pcCustomAttributes) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::EnumCustomAttributes |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void GetCustomAttributeProps([in] unsigned int32 cv, |
||||
[out] unsigned int32& ptkObj, |
||||
[out] unsigned int32& ptkType, |
||||
[out] native int& ppBlob, |
||||
[out] unsigned int32& pcbSize) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::GetCustomAttributeProps |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void FindTypeRef([in] unsigned int32 tkResolutionScope, |
||||
[in] string marshal( lpwstr) szName, |
||||
[out] unsigned int32& ptr) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::FindTypeRef |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void GetMemberProps([in] unsigned int32 mb, |
||||
[out] unsigned int32& pClass, |
||||
[in] string marshal( lpwstr) szMember, |
||||
[in] unsigned int32 cchMember, |
||||
[out] unsigned int32& pchMember, |
||||
[out] unsigned int32& pdwAttr, |
||||
[out] native int ppvSigBlob, |
||||
[out] unsigned int32& pcbSigBlob, |
||||
[out] unsigned int32& pulCodeRVA, |
||||
[out] unsigned int32& pdwImplFlags, |
||||
[out] unsigned int32& pdwCPlusTypeFlag, |
||||
[out] native int& ppValue, |
||||
[out] unsigned int32& pcchValue) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::GetMemberProps |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void GetFieldProps([in] unsigned int32 mb, |
||||
[out] unsigned int32& pClass, |
||||
[in] native int szField, |
||||
[in] unsigned int32 cchField, |
||||
[out] unsigned int32& pchField, |
||||
[out] unsigned int32& pdwAttr, |
||||
[out] native int ppvSigBlob, |
||||
[out] unsigned int32& pcbSigBlob, |
||||
[out] unsigned int32& pdwCPlusTypeFlag, |
||||
[out] native int& ppValue, |
||||
[out] unsigned int32& pcchValue) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::GetFieldProps |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void GetPropertyProps([in] unsigned int32 prop, |
||||
[out] unsigned int32& pClass, |
||||
[out] string marshal( lpwstr) szProperty, |
||||
[in] unsigned int32 cchProperty, |
||||
[out] unsigned int32& pchProperty, |
||||
[out] unsigned int32& pdwPropFlags, |
||||
[out] native int ppvSig, |
||||
[out] unsigned int32& pbSig, |
||||
[out] unsigned int32& pdwCPlusTypeFlag, |
||||
[out] native int& ppDefaultValue, |
||||
[out] unsigned int32& pcchDefaultValue, |
||||
[out] unsigned int32& pmdSetter, |
||||
[out] unsigned int32& pmdGetter, |
||||
[out] unsigned int32& rmdOtherMethod, |
||||
[in] unsigned int32 cMax, |
||||
[out] unsigned int32& pcOtherMethod) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::GetPropertyProps |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void GetParamProps([in] unsigned int32 tk, |
||||
[out] unsigned int32& pmd, |
||||
[out] unsigned int32& pulSequence, |
||||
[out] native int szName, |
||||
[in] unsigned int32 cchName, |
||||
[out] unsigned int32& pchName, |
||||
[out] unsigned int32& pdwAttr, |
||||
[out] unsigned int32& pdwCPlusTypeFlag, |
||||
[out] native int ppValue, |
||||
[out] unsigned int32& pcchValue) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::GetParamProps |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void GetCustomAttributeByName([in] unsigned int32 tkObj, |
||||
[in] string marshal( lpwstr) szName, |
||||
[out] native int& ppData, |
||||
[out] unsigned int32& pcbData) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::GetCustomAttributeByName |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance int32 IsValidToken(unsigned int32 tk) runtime managed preservesig internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::IsValidToken |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void GetNestedClassProps([in] unsigned int32 tdNestedClass, |
||||
[out] unsigned int32& ptdEnclosingClass) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::GetNestedClassProps |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void GetNativeCallConvFromSig([in] native int pvSig, |
||||
[in] unsigned int32 cbSig, |
||||
[out] unsigned int32& pCallConv) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::GetNativeCallConvFromSig |
||||
|
||||
.method public hidebysig newslot abstract virtual |
||||
instance void IsGlobal([in] unsigned int32 pd, |
||||
[out] int32& pbGlobal) runtime managed internalcall |
||||
{ |
||||
} // end of method IMetaDataImport::IsGlobal |
||||
|
||||
} // end of class IMetaDataImport |
||||
|
||||
.class public sequential ansi sealed beforefieldinit COR_FIELD_OFFSET |
||||
extends [mscorlib]System.ValueType |
||||
{ |
||||
.pack 4 |
||||
.size 0 |
||||
.field public unsigned int32 ridOfField |
||||
.field public unsigned int32 ulOffset |
||||
} // end of class COR_FIELD_OFFSET |
||||
|
||||
|
||||
// ============================================================= |
||||
|
||||
} // end of namespace MetaData |
||||
|
||||
//*********** DISASSEMBLY COMPLETE *********************** |
||||
// WARNING: Created Win32 resource file DebuggerInterop.MetaData.res |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,7 @@
@@ -0,0 +1,7 @@
|
||||
This Controls comes from: |
||||
|
||||
http://www.codeproject.com/cs/miscctrl/treelistview.asp |
||||
|
||||
I want to thank Thomas Caudal for his efforts. |
||||
|
||||
|
Binary file not shown.
@ -0,0 +1,27 @@
@@ -0,0 +1,27 @@
|
||||
using System; |
||||
|
||||
namespace System.Runtime.InteropServices.APIs |
||||
{ |
||||
/// <summary>
|
||||
/// Summary description for Clipboard.
|
||||
/// </summary>
|
||||
public class APIsClipboard |
||||
{ |
||||
public static bool ClearClipboard(IntPtr hWnd) |
||||
{ |
||||
if(!OpenClipboard(hWnd)) return false; |
||||
bool res = EmptyClipboard(); |
||||
CloseClipboard(); |
||||
return res; |
||||
} |
||||
|
||||
[DllImport("user32.dll")] |
||||
protected static extern bool EmptyClipboard(); |
||||
|
||||
[DllImport("user32.dll")] |
||||
protected static extern bool OpenClipboard(IntPtr hWnd); |
||||
|
||||
[DllImport("user32.dll")] |
||||
protected static extern bool CloseClipboard(); |
||||
} |
||||
} |
@ -0,0 +1,23 @@
@@ -0,0 +1,23 @@
|
||||
using System; |
||||
using System.Runtime.InteropServices; |
||||
|
||||
namespace System.Runtime.InteropServices.APIs |
||||
{ |
||||
public class APIsComctl32 |
||||
{ |
||||
#region GetMajorVersion
|
||||
public static int GetMajorVersion() |
||||
{ |
||||
APIsStructs.DLLVERSIONINFO2 pdvi = new APIsStructs.DLLVERSIONINFO2(); |
||||
pdvi.info1.cbSize = Marshal.SizeOf(typeof(APIsStructs.DLLVERSIONINFO2)); |
||||
DllGetVersion(ref pdvi); |
||||
return pdvi.info1.dwMajorVersion; |
||||
} |
||||
#endregion
|
||||
#region DllGetVersion
|
||||
[DllImport("Comctl32.dll", CharSet=CharSet.Auto)] |
||||
static private extern int DllGetVersion( |
||||
ref APIsStructs.DLLVERSIONINFO2 pdvi); |
||||
#endregion
|
||||
} |
||||
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,64 @@
@@ -0,0 +1,64 @@
|
||||
using System; |
||||
|
||||
namespace System.Runtime.InteropServices.APIs |
||||
{ |
||||
public class APIsGdi |
||||
{ |
||||
[DllImport("gdi32.dll", CharSet=CharSet.Auto)] |
||||
static public extern bool TransparentBlt( |
||||
IntPtr hdcDest, int nXOriginDest, int nYOriginDest, int nWidthDest, int hHeightDest, |
||||
IntPtr hdcSrc, int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int hHeightSrc, |
||||
int crTransparent); |
||||
[DllImport("gdi32.dll", CharSet=CharSet.Auto)] |
||||
static public extern IntPtr GetDC(IntPtr hWnd); |
||||
[DllImport("gdi32.dll")] |
||||
static public extern bool StretchBlt(IntPtr hDCDest, int XOriginDest, int YOriginDest, int WidthDest, int HeightDest, |
||||
IntPtr hDCSrc, int XOriginScr, int YOriginSrc, int WidthScr, int HeightScr, APIsEnums.PatBltTypes Rop); |
||||
[DllImport("gdi32.dll")] |
||||
static public extern IntPtr CreateCompatibleDC(IntPtr hDC); |
||||
[DllImport("gdi32.dll")] |
||||
static public extern IntPtr CreateCompatibleBitmap(IntPtr hDC, int Width, int Heigth); |
||||
[DllImport("gdi32.dll")] |
||||
static public extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject); |
||||
[DllImport("gdi32.dll")] |
||||
static public extern bool BitBlt(IntPtr hDCDest, int XOriginDest, int YOriginDest, int WidthDest, int HeightDest, |
||||
IntPtr hDCSrc, int XOriginScr, int YOriginSrc, APIsEnums.PatBltTypes flags); |
||||
[DllImport("gdi32.dll")] |
||||
static public extern IntPtr DeleteDC(IntPtr hDC); |
||||
[DllImport("gdi32.dll")] |
||||
static public extern bool PatBlt(IntPtr hDC, int XLeft, int YLeft, int Width, int Height, uint Rop); |
||||
[DllImport("gdi32.dll")] |
||||
static public extern bool DeleteObject(IntPtr hObject); |
||||
[DllImport("gdi32.dll")] |
||||
static public extern uint GetPixel(IntPtr hDC, int XPos, int YPos); |
||||
[DllImport("gdi32.dll")] |
||||
static public extern int SetMapMode(IntPtr hDC, int fnMapMode); |
||||
[DllImport("gdi32.dll")] |
||||
static public extern int GetObjectType(IntPtr handle); |
||||
[DllImport("gdi32")] |
||||
public static extern IntPtr CreateDIBSection(IntPtr hdc, ref APIsStructs.BITMAPINFO_FLAT bmi, |
||||
int iUsage, ref int ppvBits, IntPtr hSection, int dwOffset); |
||||
[DllImport("gdi32")] |
||||
public static extern int GetDIBits(IntPtr hDC, IntPtr hbm, int StartScan, int ScanLines, int lpBits, APIsStructs.BITMAPINFOHEADER bmi, int usage); |
||||
[DllImport("gdi32")] |
||||
public static extern int GetDIBits(IntPtr hdc, IntPtr hbm, int StartScan, int ScanLines, int lpBits, ref APIsStructs.BITMAPINFO_FLAT bmi, int usage); |
||||
[DllImport("gdi32")] |
||||
public static extern IntPtr GetPaletteEntries(IntPtr hpal, int iStartIndex, int nEntries, byte[] lppe); |
||||
[DllImport("gdi32")] |
||||
public static extern IntPtr GetSystemPaletteEntries(IntPtr hdc, int iStartIndex, int nEntries, byte[] lppe); |
||||
[DllImport("gdi32")] |
||||
public static extern uint SetDCBrushColor(IntPtr hdc, uint crColor); |
||||
[DllImport("gdi32")] |
||||
public static extern IntPtr CreateSolidBrush(uint crColor); |
||||
[DllImport("gdi32")] |
||||
public static extern int SetBkMode(IntPtr hDC, APIsEnums.BackgroundMode mode); |
||||
[DllImport("gdi32")] |
||||
public static extern int SetViewportOrgEx(IntPtr hdc, int x, int y, int param); |
||||
[DllImport("gdi32")] |
||||
public static extern uint SetTextColor(IntPtr hDC, uint colorRef); |
||||
[DllImport("gdi32")] |
||||
public static extern int SetStretchBltMode(IntPtr hDC, APIsEnums.StrechModeFlags StrechMode); |
||||
[DllImport("gdi32")] |
||||
public static extern uint SetPixel(IntPtr hDC, int x, int y, uint color); |
||||
} |
||||
} |
@ -0,0 +1,44 @@
@@ -0,0 +1,44 @@
|
||||
using System; |
||||
using System.Runtime.InteropServices; |
||||
|
||||
namespace System.Runtime.InteropServices.APIs |
||||
{ |
||||
public class APIsMenu |
||||
{ |
||||
[DllImport("user32.dll")] |
||||
public static extern APIsEnums.MenuItemFlags GetMenuState( |
||||
IntPtr hMenu, int itemID, APIsEnums.MenuItemFlags uFlag); |
||||
[DllImport("user32.dll")] |
||||
public static extern bool GetMenuString( |
||||
IntPtr hMenu, int itemID, System.Text.StringBuilder lpString, int maxlen, APIsEnums.MenuItemFlags uFlag); |
||||
[DllImport("user32.dll")] |
||||
public static extern int GetMenuItemInfo( |
||||
IntPtr hMenu, int itemindex, bool fByPosition, ref APIsStructs.MENUITMEINFO infos); |
||||
[DllImport("user32.dll")] |
||||
public static extern int GetMenuItemID( |
||||
IntPtr hMenu, int index); |
||||
[DllImport("user32.dll")] |
||||
public static extern bool InsertMenuItem( |
||||
IntPtr hMenu, int itemindex, bool fByPosition, ref APIsStructs.MENUITMEINFO infos); |
||||
[DllImport("user32.dll")] |
||||
public static extern int GetMenuItemCount(IntPtr hMenu); |
||||
[DllImport("user32.dll")] |
||||
public static extern IntPtr CreatePopupMenu(); |
||||
[DllImport("user32.dll")] |
||||
public static extern bool DestroyMenu(IntPtr hMenu); |
||||
[DllImport("user32.dll")] |
||||
public static extern bool DeleteMenu( |
||||
IntPtr hMenu, |
||||
int index, |
||||
APIsEnums.MenuItemFlags uFlag); |
||||
[DllImport("user32.dll", SetLastError=true)] |
||||
public static extern int TrackPopupMenu( |
||||
IntPtr hmenu, |
||||
APIsEnums.TrackPopupMenuFlags fuFlags, |
||||
int x, |
||||
int y, |
||||
int res, |
||||
IntPtr hwnd, |
||||
IntPtr rect); |
||||
} |
||||
} |
@ -0,0 +1,254 @@
@@ -0,0 +1,254 @@
|
||||
using System; |
||||
using System.Runtime.InteropServices; |
||||
using System.IO; |
||||
|
||||
namespace System.Runtime.InteropServices.APIs |
||||
{ |
||||
public class APIsShell |
||||
{ |
||||
#region GetShellFolder function
|
||||
public static COMInterfaces.IShellFolder GetShellFolder(IntPtr handle, string path, out IntPtr FolderID) |
||||
{ |
||||
string tempPath = path; |
||||
|
||||
// Get the desktop folder
|
||||
COMInterfaces.IShellFolder returnedShellFolder = null; |
||||
APIsShell.SHGetDesktopFolder(out returnedShellFolder); |
||||
|
||||
System.Guid IID_IShellFolder = new System.Guid("000214E6-0000-0000-C000-000000000046"); |
||||
IntPtr Pidl = IntPtr.Zero; |
||||
uint i,j=0; |
||||
// Connect to "My Computer"
|
||||
APIsShell.SHGetSpecialFolderLocation(handle, APIsEnums.ShellSpecialFolders.DRIVES, out Pidl); |
||||
COMInterfaces.IShellFolder tempfolder; |
||||
returnedShellFolder.BindToObject(Pidl, IntPtr.Zero, ref IID_IShellFolder, out tempfolder); |
||||
Marshal.ReleaseComObject(returnedShellFolder); |
||||
returnedShellFolder = tempfolder; |
||||
int lastindexposition = 0; |
||||
while(lastindexposition != -1) |
||||
{ |
||||
lastindexposition = tempPath.IndexOf('\\'); |
||||
if(lastindexposition == -1) break; |
||||
string foldername = tempPath.Remove(lastindexposition, tempPath.Length - lastindexposition) + @"\"; |
||||
returnedShellFolder.ParseDisplayName(handle, IntPtr.Zero, foldername, out i, out Pidl, ref j); |
||||
returnedShellFolder.BindToObject(Pidl, IntPtr.Zero, ref IID_IShellFolder, out tempfolder); |
||||
Marshal.ReleaseComObject(returnedShellFolder); |
||||
returnedShellFolder = tempfolder; |
||||
tempPath = tempPath.Substring(++lastindexposition); |
||||
} |
||||
FolderID = Pidl; |
||||
return(returnedShellFolder); |
||||
} |
||||
#endregion
|
||||
#region Copy, Delete, Move, Rename
|
||||
public static bool DoOperation(IntPtr Handle, string[] source, string dest, APIsEnums.FileOperations operation) |
||||
{ |
||||
APIsStructs.SHFILEOPSTRUCT fileop = new APIsStructs.SHFILEOPSTRUCT(); |
||||
fileop.hwnd = Handle; |
||||
fileop.lpszProgressTitle = Enum.GetName(typeof(APIsEnums.FileOperations), operation); |
||||
fileop.wFunc = (uint) operation; |
||||
fileop.pFrom = Marshal.StringToHGlobalUni(StringArrayToMultiString(source)); |
||||
fileop.pTo = Marshal.StringToHGlobalUni(dest); |
||||
fileop.fAnyOperationsAborted = 0; |
||||
fileop.hNameMappings = IntPtr.Zero; |
||||
|
||||
return SHFileOperation(ref fileop) == 0; |
||||
} |
||||
private static String StringArrayToMultiString(String[] stringArray) |
||||
{ |
||||
String multiString = ""; |
||||
|
||||
if (stringArray == null) |
||||
return ""; |
||||
|
||||
for (int i=0 ; i<stringArray.Length ; i++) |
||||
multiString += stringArray[i] + '\0'; |
||||
|
||||
multiString += '\0'; |
||||
|
||||
return multiString; |
||||
} |
||||
#endregion
|
||||
#region Properties Launch
|
||||
public static int ViewFileProperties(string path) |
||||
{ |
||||
if(!File.Exists(path)) return(-1); |
||||
APIsStructs.SHELLEXECUTEINFO info = new APIsStructs.SHELLEXECUTEINFO(); |
||||
info.cbSize = Marshal.SizeOf(typeof(APIsStructs.SHELLEXECUTEINFO)); |
||||
info.fMask = APIsEnums.ShellExecuteFlags.INVOKEIDLIST; |
||||
info.hWnd = IntPtr.Zero; |
||||
info.lpVerb = "properties"; |
||||
info.lpFile = Path.GetFileName(path); |
||||
info.lpParameters = ""; |
||||
info.lpDirectory = Path.GetDirectoryName(path); |
||||
info.nShow = APIsEnums.ShowWindowStyles.SHOW; |
||||
info.hInstApp = IntPtr.Zero; |
||||
IntPtr ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(APIsStructs.SHELLEXECUTEINFO))); |
||||
Marshal.StructureToPtr(info, ptr, false); |
||||
return(ShellExecuteEx(ptr)); |
||||
} |
||||
public static int ViewDirectoryProperties(string path) |
||||
{ |
||||
if(!Directory.Exists(path)) return(-1); |
||||
APIsStructs.SHELLEXECUTEINFO info = new APIsStructs.SHELLEXECUTEINFO(); |
||||
info.cbSize = Marshal.SizeOf(typeof(APIsStructs.SHELLEXECUTEINFO)); |
||||
info.fMask = APIsEnums.ShellExecuteFlags.INVOKEIDLIST; |
||||
info.hWnd = IntPtr.Zero; |
||||
info.lpVerb = "properties"; |
||||
info.lpFile = ""; |
||||
info.lpParameters = ""; |
||||
info.lpDirectory = path; |
||||
info.nShow = APIsEnums.ShowWindowStyles.SHOW; |
||||
info.hInstApp = IntPtr.Zero; |
||||
IntPtr ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(APIsStructs.SHELLEXECUTEINFO))); |
||||
Marshal.StructureToPtr(info, ptr, false); |
||||
return(ShellExecuteEx(ptr)); |
||||
} |
||||
#endregion
|
||||
#region GetIcon
|
||||
static uint FILE_ATTRIBUTE_DIRECTORY = 0x00000010; |
||||
static uint FILE_ATTRIBUTE_NORMAL = 0x00000080; |
||||
public static System.Drawing.Icon GetFileIcon(string strPath, bool bSmall) |
||||
{ |
||||
APIsStructs.SHFILEINFO info = new APIsStructs.SHFILEINFO(true); |
||||
APIsEnums.ShellGetFileInformationFlags flags = |
||||
APIsEnums.ShellGetFileInformationFlags.Icon | |
||||
(File.Exists(strPath) ? 0 : APIsEnums.ShellGetFileInformationFlags.UseFileAttributes) | |
||||
(bSmall ? APIsEnums.ShellGetFileInformationFlags.SmallIcon : APIsEnums.ShellGetFileInformationFlags.LargeIcon); |
||||
SHGetFileInfo(strPath, |
||||
FILE_ATTRIBUTE_NORMAL, |
||||
out info, |
||||
(uint)Marshal.SizeOf(info), |
||||
flags); |
||||
System.Drawing.Icon icon = System.Drawing.Icon.FromHandle(info.hIcon); |
||||
return icon; |
||||
} |
||||
public static System.Drawing.Icon GetFolderIcon(string strPath, bool bSmall, bool bOpen) |
||||
{ |
||||
APIsStructs.SHFILEINFO info = new APIsStructs.SHFILEINFO(true); |
||||
APIsEnums.ShellGetFileInformationFlags flags = |
||||
APIsEnums.ShellGetFileInformationFlags.Icon | |
||||
(bSmall ? APIsEnums.ShellGetFileInformationFlags.SmallIcon : APIsEnums.ShellGetFileInformationFlags.LargeIcon) | |
||||
(bOpen ? APIsEnums.ShellGetFileInformationFlags.OpenIcon : 0) | |
||||
(Directory.Exists(strPath) ? 0 : APIsEnums.ShellGetFileInformationFlags.UseFileAttributes); |
||||
SHGetFileInfo(strPath, |
||||
FILE_ATTRIBUTE_DIRECTORY, |
||||
out info, |
||||
(uint)Marshal.SizeOf(info), |
||||
flags); |
||||
System.Drawing.Icon icon = System.Drawing.Icon.FromHandle(info.hIcon); |
||||
return icon; |
||||
} |
||||
#endregion
|
||||
|
||||
#region SHParseDisplayName
|
||||
[DllImport("shell32.dll")] |
||||
public static extern Int32 SHParseDisplayName( |
||||
[MarshalAs(UnmanagedType.LPWStr)] |
||||
String pszName, |
||||
IntPtr pbc, |
||||
out IntPtr ppidl, |
||||
UInt32 sfgaoIn, |
||||
out UInt32 psfgaoOut); |
||||
#endregion
|
||||
#region SHGetDataFromIDList
|
||||
[DllImport("shell32.dll", CharSet=CharSet.Auto)] |
||||
public static extern uint SHGetDataFromIDList( |
||||
COMInterfaces.IShellFolder psf, |
||||
IntPtr pidl, |
||||
APIsEnums.ShellFolderGetaFromIDList nFormat, |
||||
out APIsStructs.WIN32_FIND_DATA pv, |
||||
int cb); |
||||
#endregion
|
||||
#region SHGetPathFromIDList
|
||||
[DllImport("Shell32.Dll", CharSet=CharSet.Auto)] |
||||
[return:MarshalAs(UnmanagedType.Bool)] |
||||
public static extern Boolean SHGetPathFromIDList( |
||||
IntPtr pidl, |
||||
[In,Out,MarshalAs(UnmanagedType.LPTStr)] String pszPath); |
||||
#endregion
|
||||
#region SHGetSpecialFolderPath
|
||||
[DllImport("Shell32.Dll", CharSet=CharSet.Auto)] |
||||
[return:MarshalAs(UnmanagedType.Bool)] |
||||
public static extern Boolean SHGetSpecialFolderPath( |
||||
IntPtr hwndOwner, |
||||
[In,Out,MarshalAs(UnmanagedType.LPTStr)] String pszPath, |
||||
APIsEnums.ShellSpecialFolders nFolder, |
||||
[In,MarshalAs(UnmanagedType.Bool)] Boolean fCreate); |
||||
#endregion
|
||||
#region SHGetDesktopFolder
|
||||
/// <summary>
|
||||
/// Retrieves the IShellFolder interface for the desktop folder, which is the root of the Shell's namespace.
|
||||
/// </summary>
|
||||
[DllImport("shell32.dll")] |
||||
public static extern int SHGetDesktopFolder(out COMInterfaces.IShellFolder folder); |
||||
#endregion
|
||||
#region SHGetSpecialFolderLocation
|
||||
/// <summary>
|
||||
/// Retrieves a pointer to the ITEMIDLIST structure of a special folder.
|
||||
/// </summary>
|
||||
[DllImport("shell32.dll")] |
||||
public static extern int SHGetSpecialFolderLocation( |
||||
IntPtr handle, |
||||
APIsEnums.ShellSpecialFolders nFolder, |
||||
out IntPtr ppidl); |
||||
#endregion
|
||||
#region SHBindToParent
|
||||
/// <summary>
|
||||
/// This function takes the fully-qualified PIDL of a namespace object, and returns a specified interface pointer on the parent object.
|
||||
/// </summary>
|
||||
[DllImport("shell32.dll")] |
||||
public static extern int SHBindToParent( |
||||
IntPtr pidl, |
||||
Guid iid, |
||||
out COMInterfaces.IShellFolder folder, |
||||
out IntPtr pidlRelative); |
||||
#endregion
|
||||
#region SHFileOperation
|
||||
/// <summary>
|
||||
/// Copies, moves, renames, or deletes a file system object.
|
||||
/// </summary>
|
||||
[DllImport("shell32.dll", CharSet=CharSet.Unicode)] |
||||
public static extern Int32 SHFileOperation( |
||||
ref APIsStructs.SHFILEOPSTRUCT FileOp); |
||||
#endregion
|
||||
#region SHGetFileInfo
|
||||
[DllImport("Shell32.dll")] |
||||
public static extern int SHGetFileInfo( |
||||
string pszPath, |
||||
uint dwFileAttributes, |
||||
out APIsStructs.SHFILEINFO psfi, |
||||
uint cbfileInfo, |
||||
APIsEnums.ShellGetFileInformationFlags uFlags); |
||||
#endregion
|
||||
#region ShellExecute
|
||||
/// <summary>
|
||||
/// Execute the file
|
||||
/// </summary>
|
||||
[DllImport("Shell32.dll")] |
||||
public static extern int ShellExecute |
||||
(IntPtr Hwnd, |
||||
string strOperation, |
||||
string strFile, |
||||
string strParametres, |
||||
string strDirectory, |
||||
int ShowCmd); |
||||
#endregion
|
||||
#region ShellExecuteEx
|
||||
[DllImport("Shell32.dll")] |
||||
public static extern int ShellExecuteEx(IntPtr infos); |
||||
#endregion
|
||||
|
||||
#region StrRetToBuf
|
||||
/// <summary>
|
||||
/// Takes a STRRET structure returned by IShellFolder::GetDisplayNameOf, converts it to a string, and places the result in a buffer.
|
||||
/// </summary>
|
||||
[DllImport("Shlwapi.Dll", CharSet=CharSet.Auto)] |
||||
public static extern uint StrRetToBuf( |
||||
APIsStructs.STRRET pstr, |
||||
IntPtr pidl, |
||||
[In,Out,MarshalAs(UnmanagedType.LPTStr)] String pszBuf, |
||||
uint cchBuf); |
||||
#endregion
|
||||
} |
||||
} |
@ -0,0 +1,215 @@
@@ -0,0 +1,215 @@
|
||||
using System; |
||||
|
||||
namespace System.Runtime.InteropServices.APIs |
||||
{ |
||||
public class APIsShlwapi |
||||
{ |
||||
#region PathCompactPath
|
||||
/// <summary>
|
||||
/// Truncates a file path to fit within a given pixel width by replacing path components with ellipses.
|
||||
/// </summary>
|
||||
/// <param name="hDC"></param>
|
||||
/// <param name="lpszPath"></param>
|
||||
/// <param name="dx"></param>
|
||||
/// <returns>Returns TRUE if the path was successfully compacted to the specified width. Returns FALSE on failure, or if the base portion of the path would not fit the specified width</returns>
|
||||
[DllImport("shlwapi.dll", CharSet=CharSet.Auto)] |
||||
static public extern bool PathCompactPath( |
||||
IntPtr hDC, |
||||
System.Text.StringBuilder lpszPath, |
||||
int dx); |
||||
#endregion
|
||||
#region PathCompactPathEx
|
||||
/// <summary>
|
||||
/// Truncates a path to fit within a certain number of characters by replacing path components with ellipses
|
||||
/// </summary>
|
||||
/// <param name="pszOut"></param>
|
||||
/// <param name="pszSrc"></param>
|
||||
/// <param name="cchMax"></param>
|
||||
/// <param name="dwFlags"></param>
|
||||
/// <returns>Returns TRUE if successful, or FALSE otherwise</returns>
|
||||
[DllImport("shlwapi.dll", CharSet=CharSet.Auto)] |
||||
static public extern bool PathCompactPathEx( |
||||
System.Text.StringBuilder pszOut, |
||||
System.Text.StringBuilder pszSrc, |
||||
int cchMax, |
||||
int dwFlags); |
||||
#endregion
|
||||
#region PathIsFileSpec
|
||||
/// <summary>
|
||||
/// Searches a path for any path delimiting characters (for example, ':' or '\' ). If there are no path delimiting characters present, the path is considered to be a File Spec path
|
||||
/// </summary>
|
||||
/// <param name="path">Path searched</param>
|
||||
/// <returns>Returns TRUE if there are no path delimiting characters within the path, or FALSE if there are path delimiting characters</returns>
|
||||
[DllImport("shlwapi.dll", CharSet=CharSet.Auto)] |
||||
static public extern bool PathIsFileSpec( |
||||
string path); |
||||
#endregion
|
||||
#region PathIsPrefix
|
||||
/// <summary>
|
||||
/// Searches a path to determine if it contains a valid prefix of the type passed by pszPrefix. A prefix is one of these types: "C:\\", ".", "..", "..\\"
|
||||
/// </summary>
|
||||
/// <param name="prefix"></param>
|
||||
/// <param name="path"></param>
|
||||
/// <returns>Returns TRUE if the compared path is the full prefix for the path, or FALSE otherwise</returns>
|
||||
[DllImport("shlwapi.dll", CharSet=CharSet.Auto)] |
||||
static public extern bool PathIsPrefix( |
||||
string prefix, |
||||
string path); |
||||
#endregion
|
||||
#region PathIsRelative
|
||||
/// <summary>
|
||||
/// Searches a path and determines if it is relative
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <returns>Returns TRUE if the path is relative, or FALSE if it is absolute</returns>
|
||||
[DllImport("shlwapi.dll", CharSet=CharSet.Auto)] |
||||
static public extern bool PathIsRelative( |
||||
string path); |
||||
#endregion
|
||||
#region PathIsRoot
|
||||
/// <summary>
|
||||
/// Parses a path to determine if it is a directory root
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <returns>Returns TRUE if the specified path is a root, or FALSE otherwise</returns>
|
||||
[DllImport("shlwapi.dll", CharSet=CharSet.Auto)] |
||||
static public extern bool PathIsRoot( |
||||
string path); |
||||
#endregion
|
||||
#region PathIsSameRoot
|
||||
/// <summary>
|
||||
/// Compares two paths to determine if they have a common root component
|
||||
/// </summary>
|
||||
/// <param name="path1"></param>
|
||||
/// <param name="path2"></param>
|
||||
/// <returns>Returns TRUE if both strings have the same root component, or FALSE otherwise</returns>
|
||||
[DllImport("shlwapi.dll", CharSet=CharSet.Auto)] |
||||
static public extern bool PathIsSameRoot( |
||||
string path1, |
||||
string path2); |
||||
#endregion
|
||||
#region PathIsUNC
|
||||
/// <summary>
|
||||
/// Determines if the string is a valid UNC (universal naming convention) for a server and share path
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <returns>Returns TRUE if the string is a valid UNC path, or FALSE otherwise</returns>
|
||||
[DllImport("shlwapi.dll", CharSet=CharSet.Auto)] |
||||
static public extern bool PathIsUNC( |
||||
string path); |
||||
#endregion
|
||||
#region PathIsUNCServer
|
||||
/// <summary>
|
||||
/// Determines if a string is a valid UNC (universal naming convention) for a server path only
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <returns>Returns TRUE if the string is a valid UNC path for a server only (no share name), or FALSE otherwise</returns>
|
||||
[DllImport("shlwapi.dll", CharSet=CharSet.Auto)] |
||||
static public extern bool PathIsUNCServer( |
||||
string path); |
||||
#endregion
|
||||
#region PathIsUNCServerShare
|
||||
/// <summary>
|
||||
/// Determines if a string is a valid universal naming convention (UNC) share path, \\server\share
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <returns>Returns TRUE if the string is in the form \\server\share, or FALSE otherwise</returns>
|
||||
[DllImport("shlwapi.dll", CharSet=CharSet.Auto)] |
||||
static public extern bool PathIsUNCServerShare( |
||||
string path); |
||||
#endregion
|
||||
#region PathIsURL
|
||||
/// <summary>
|
||||
/// Tests a given string to determine if it conforms to a valid URL format
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <returns>Returns TRUE if pszPath has a valid URL format, or FALSE otherwise</returns>
|
||||
[DllImport("shlwapi.dll", CharSet=CharSet.Auto)] |
||||
static public extern bool PathIsURL( |
||||
string path); |
||||
#endregion
|
||||
#region PathMakePretty
|
||||
/// <summary>
|
||||
/// Converts a path to all lowercase characters to give the path a consistent appearance
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <returns>Returns TRUE if the path has been converted, or FALSE otherwise</returns>
|
||||
[DllImport("shlwapi.dll", CharSet=CharSet.Auto)] |
||||
static public extern bool PathMakePretty( |
||||
System.Text.StringBuilder path); |
||||
#endregion
|
||||
#region PathMatchSpec
|
||||
/// <summary>
|
||||
/// Searches a string using a DOS wild card match type
|
||||
/// </summary>
|
||||
/// <param name="fileparam">Contains the path to be searched</param>
|
||||
/// <param name="spec">Contains the file type for which to search. For example, to test whether or not pszFileParam is a DOC file, pszSpec should be set to "*.doc"</param>
|
||||
/// <returns>Returns TRUE if the string matches, or FALSE otherwise</returns>
|
||||
[DllImport("shlwapi.dll", CharSet=CharSet.Auto)] |
||||
static public extern bool PathMatchSpec( |
||||
string fileparam, |
||||
string spec); |
||||
#endregion
|
||||
#region PathParseIconLocation
|
||||
/// <summary>
|
||||
/// Parses a file location string containing a file location and icon index, and returns separate values
|
||||
/// </summary>
|
||||
/// <param name="IconFile">Contains a file location string. It should be in the form "pathname,iconindex". When the function returns, pszIconFile will point to the file's pathname</param>
|
||||
/// <returns>Returns the valid icon index value</returns>
|
||||
[DllImport("shlwapi.dll", CharSet=CharSet.Auto)] |
||||
static public extern int PathParseIconLocation( |
||||
System.Text.StringBuilder IconFile); |
||||
#endregion
|
||||
#region PathQuoteSpaces
|
||||
/// <summary>
|
||||
/// Searches a path for spaces. If spaces are found, the entire path is enclosed in quotation marks
|
||||
/// </summary>
|
||||
/// <param name="lpsz">Path to search</param>
|
||||
[DllImport("shlwapi.dll", CharSet=CharSet.Auto)] |
||||
static public extern void PathQuoteSpaces( |
||||
System.Text.StringBuilder lpsz); |
||||
#endregion
|
||||
#region PathRelativePathTo
|
||||
/// <summary>
|
||||
/// Creates a relative path from one file or folder to another
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="from"></param>
|
||||
/// <param name="attrFrom"></param>
|
||||
/// <param name="to"></param>
|
||||
/// <param name="attrTo"></param>
|
||||
/// <returns>Returns TRUE if successful, or FALSE otherwise</returns>
|
||||
[DllImport("shlwapi.dll", CharSet=CharSet.Auto)] |
||||
static public extern bool PathRelativePathTo( |
||||
System.Text.StringBuilder path, |
||||
string from, |
||||
int attrFrom, |
||||
string to, |
||||
int attrTo); |
||||
#endregion
|
||||
#region PathRemoveArgs
|
||||
/// <summary>
|
||||
/// Removes any arguments from a given path
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
[DllImport("shlwapi.dll", CharSet=CharSet.Auto)] |
||||
static public extern void PathRemoveArgs( |
||||
System.Text.StringBuilder path); |
||||
#endregion
|
||||
#region PathRemoveBackslash
|
||||
/// <summary>
|
||||
/// Removes the trailing backslash from a given path
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <returns>Returns the address of the NULL that replaced the backslash, or the address of the last character if it's not a backslash</returns>
|
||||
[DllImport("shlwapi.dll", CharSet=CharSet.Auto)] |
||||
static public extern string PathRemoveBackslash( |
||||
string path); |
||||
#endregion
|
||||
#region DllGetVersion
|
||||
[DllImport("shlwapi.dll", CharSet=CharSet.Auto)] |
||||
static public extern int DllGetVersion( |
||||
ref APIsStructs.DLLVERSIONINFO2 path); |
||||
#endregion
|
||||
} |
||||
} |
@ -0,0 +1,694 @@
@@ -0,0 +1,694 @@
|
||||
using System; |
||||
using System.Runtime.InteropServices; |
||||
|
||||
namespace System.Runtime.InteropServices.APIs |
||||
{ |
||||
public class APIsStructs |
||||
{ |
||||
#region DLLVERSIONINFO
|
||||
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)] |
||||
public struct DLLVERSIONINFO |
||||
{ |
||||
public int cbSize; |
||||
public int dwMajorVersion; |
||||
public int dwMinorVersion; |
||||
public int dwBuildNumber; |
||||
public int dwPlatformID; |
||||
} |
||||
#endregion
|
||||
#region DLLVERSIONINFO2
|
||||
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)] |
||||
public struct DLLVERSIONINFO2 |
||||
{ |
||||
public DLLVERSIONINFO info1; |
||||
public int dwFlags; |
||||
ulong ullVersion; |
||||
} |
||||
#endregion
|
||||
#region WIN32_FIND_DATA
|
||||
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)] |
||||
public struct WIN32_FIND_DATA |
||||
{ |
||||
public uint fileAttributes; |
||||
public FILETIME creationTime; |
||||
public FILETIME lastAccessTime; |
||||
public FILETIME lastWriteTime; |
||||
public uint fileSizeHigh; |
||||
public uint fileSizeLow; |
||||
public uint reserved0; |
||||
public uint reserved1; |
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=260)] |
||||
public string fileName; |
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=14)] |
||||
public string alternateFileName; |
||||
} |
||||
#endregion
|
||||
|
||||
#region SHITEMIDLIST
|
||||
[StructLayout(LayoutKind.Sequential)] |
||||
public struct SHITEMIDLIST |
||||
{ |
||||
public SHITEMID[] mkid; |
||||
} |
||||
#endregion
|
||||
#region SHITEMID
|
||||
[StructLayout(LayoutKind.Sequential)] |
||||
public struct SHITEMID |
||||
{ |
||||
public ushort cb; |
||||
public byte abID; |
||||
} |
||||
#endregion
|
||||
#region SHFILEOPSTRUCT
|
||||
/// <summary>
|
||||
/// Contains information that the SHFileOperation function uses to perform file operations.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)] |
||||
public struct SHFILEOPSTRUCT |
||||
{ |
||||
/// <summary>
|
||||
/// Window handle to the dialog box to display information about the status of the file operation.
|
||||
/// </summary>
|
||||
public IntPtr hwnd; |
||||
/// <summary>
|
||||
/// Value that indicates which operation to perform.
|
||||
/// </summary>
|
||||
public UInt32 wFunc; |
||||
/// <summary>
|
||||
/// Address of a buffer to specify one or more source file names.
|
||||
/// </summary>
|
||||
public IntPtr pFrom; |
||||
/// <summary>
|
||||
/// Address of a buffer to contain the name of the destination file or directory.
|
||||
/// </summary>
|
||||
public IntPtr pTo; |
||||
/// <summary>
|
||||
/// Flags that control the file operation (should use APISEnums.FOF).
|
||||
/// </summary>
|
||||
public UInt16 fFlags; |
||||
/// <summary>
|
||||
/// Value that receives TRUE if the user aborted any file operations before they were completed, or FALSE otherwise.
|
||||
/// </summary>
|
||||
public Int32 fAnyOperationsAborted; |
||||
/// <summary>
|
||||
/// A handle to a name mapping object containing the old and new names of the renamed files.
|
||||
/// </summary>
|
||||
public IntPtr hNameMappings; |
||||
/// <summary>
|
||||
/// Address of a string to use as the title of a progress dialog box.
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.LPWStr)] public string lpszProgressTitle; |
||||
} |
||||
#endregion
|
||||
#region SHELLEXECUTEINFO
|
||||
[StructLayoutAttribute(LayoutKind.Sequential)] |
||||
public struct SHELLEXECUTEINFO |
||||
{ |
||||
public int cbSize; |
||||
public APIsEnums.ShellExecuteFlags fMask; |
||||
public IntPtr hWnd; |
||||
public string lpVerb; |
||||
public string lpFile; |
||||
public string lpParameters; |
||||
public string lpDirectory; |
||||
public APIsEnums.ShowWindowStyles nShow; |
||||
public IntPtr hInstApp; |
||||
public IntPtr lpIDList; |
||||
public int lpClass; |
||||
public int hkeyClass; |
||||
public int dwHotKey; |
||||
public IntPtr hIcon; |
||||
public IntPtr hProcess; |
||||
} |
||||
#endregion
|
||||
#region SHFILEINFO
|
||||
[StructLayout(LayoutKind.Sequential)] |
||||
public struct SHFILEINFO |
||||
{ |
||||
public SHFILEINFO(bool b) |
||||
{ |
||||
hIcon=IntPtr.Zero;iIcon=0;dwAttributes=0;szDisplayName="";szTypeName=""; |
||||
} |
||||
public IntPtr hIcon; |
||||
public int iIcon; |
||||
public uint dwAttributes; |
||||
[MarshalAs(UnmanagedType.LPStr, SizeConst=260)] |
||||
public string szDisplayName; |
||||
[MarshalAs(UnmanagedType.LPStr, SizeConst=80)] |
||||
public string szTypeName; |
||||
}; |
||||
#endregion
|
||||
|
||||
#region STRRET
|
||||
[StructLayout(LayoutKind.Sequential)] |
||||
public struct STRRET |
||||
{ |
||||
public int uType; |
||||
// IntPtr pOleStr;
|
||||
// uint uOffset;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst=260)] public byte[] cStr; |
||||
} |
||||
#endregion
|
||||
#region MENUITMEINFO
|
||||
[StructLayoutAttribute(LayoutKind.Sequential)] |
||||
public struct MENUITMEINFO |
||||
{ |
||||
public int cbSize; |
||||
public APIsEnums.MenuItemMasks fMask; |
||||
public APIsEnums.MenuItemTypes fType; |
||||
public APIsEnums.MenuItemStates fState; |
||||
public int wID; |
||||
public IntPtr hSubMenu; |
||||
public IntPtr hbmpChecked; |
||||
public IntPtr hbmpUnchecked; |
||||
public int dwItemData; |
||||
public IntPtr dwTypeData; |
||||
public int cch; |
||||
public IntPtr hbmpItem; |
||||
} |
||||
#endregion
|
||||
#region StartupInfo
|
||||
[StructLayout(LayoutKind.Sequential)] |
||||
public class StartupInfo |
||||
{ |
||||
public int cb; |
||||
public String lpReserved; |
||||
public String lpDesktop; |
||||
public String lpTitle; |
||||
public int dwX; |
||||
public int dwY; |
||||
public int dwXSize; |
||||
public int dwYSize; |
||||
public int dwXCountChars; |
||||
public int dwYCountChars; |
||||
public int dwFillAttribute; |
||||
public int dwFlags; |
||||
public UInt16 wShowWindow; |
||||
public UInt16 cbReserved2; |
||||
public Byte lpReserved2; |
||||
public int hStdInput; |
||||
public int hStdOutput; |
||||
public int hStdError; |
||||
} |
||||
#endregion
|
||||
#region ProcessInformation
|
||||
[StructLayout(LayoutKind.Sequential)] |
||||
public class ProcessInformation |
||||
{ |
||||
public int hProcess; |
||||
public int hThread; |
||||
public int dwProcessId; |
||||
public int dwThreadId; |
||||
} |
||||
#endregion
|
||||
#region MENUITEMINFO
|
||||
[StructLayout(LayoutKind.Sequential)] |
||||
public struct MENUITEMINFO |
||||
{ |
||||
public uint cbSize; |
||||
public uint fMask; |
||||
public uint fType; |
||||
public uint fState; |
||||
public int wID; |
||||
public int /*HMENU*/ hSubMenu; |
||||
public int /*HBITMAP*/ hbmpChecked; |
||||
public int /*HBITMAP*/ hbmpUnchecked; |
||||
public int /*ULONG_PTR*/ dwItemData; |
||||
public String dwTypeData; |
||||
public uint cch; |
||||
public int /*HBITMAP*/ hbmpItem; |
||||
} |
||||
#endregion
|
||||
#region FORMATETC
|
||||
[StructLayout(LayoutKind.Sequential)] |
||||
public struct FORMATETC |
||||
{ |
||||
public APIsEnums.ClipboardFormats cfFormat; |
||||
public uint ptd; |
||||
public APIsEnums.TargetDevices dwAspect; |
||||
public int lindex; |
||||
public APIsEnums.StorageMediumTypes tymed; |
||||
} |
||||
#endregion
|
||||
#region STGMEDIUM
|
||||
[StructLayout(LayoutKind.Sequential)] |
||||
public struct STGMEDIUM |
||||
{ |
||||
public uint tymed; |
||||
public uint hGlobal; |
||||
public uint pUnkForRelease; |
||||
} |
||||
#endregion
|
||||
#region CMINVOKECOMMANDINFO
|
||||
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)] |
||||
public struct CMINVOKECOMMANDINFO |
||||
{ |
||||
public int cbSize; // sizeof(CMINVOKECOMMANDINFO)
|
||||
public int fMask; // any combination of CMIC_MASK_*
|
||||
public IntPtr hwnd; // might be NULL (indicating no owner window)
|
||||
public IntPtr lpVerb; // either a string or MAKEINTRESOURCE(idOffset)
|
||||
public IntPtr lpParameters; // might be NULL (indicating no parameter)
|
||||
public IntPtr lpDirectory; // might be NULL (indicating no specific directory)
|
||||
public int nShow; // one of SW_ values for ShowWindow() API
|
||||
public int dwHotKey; |
||||
public IntPtr hIcon; |
||||
} |
||||
#endregion
|
||||
|
||||
#region LV_ITEM
|
||||
[StructLayoutAttribute(LayoutKind.Sequential)] |
||||
public struct LV_ITEM |
||||
{ |
||||
public APIsEnums.ListViewItemFlags mask; |
||||
public Int32 iItem; |
||||
public Int32 iSubItem; |
||||
public APIsEnums.ListViewItemStates state; |
||||
public APIsEnums.ListViewItemStates stateMask; |
||||
public String pszText; |
||||
public Int32 cchTextMax; |
||||
public Int32 iImage; |
||||
public IntPtr lParam; |
||||
public Int32 iIndent; |
||||
} |
||||
#endregion
|
||||
#region LVCOLUMN
|
||||
[StructLayoutAttribute(LayoutKind.Sequential)] |
||||
public struct LVCOLUMN |
||||
{ |
||||
public Int32 mask; |
||||
public Int32 fmt; |
||||
public Int32 cx; |
||||
public string pszText; |
||||
public Int32 cchTextMax; |
||||
public Int32 iSubItem; |
||||
public Int32 iImage; |
||||
public Int32 iOrder; |
||||
} |
||||
#endregion
|
||||
#region LVHITTESTINFO
|
||||
[StructLayoutAttribute(LayoutKind.Sequential)] |
||||
public struct LVHITTESTINFO |
||||
{ |
||||
public POINTAPI pt; |
||||
public int flags; |
||||
public Int32 iItem; |
||||
public Int32 iSubItem; |
||||
} |
||||
#endregion
|
||||
#region NMLVDISPINFO
|
||||
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)] |
||||
public struct NMLVDISPINFO |
||||
{ |
||||
public NMHDR hdr; |
||||
public LV_ITEM lvitem; |
||||
} |
||||
#endregion
|
||||
#region NMLISTVIEW
|
||||
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)] |
||||
public struct NMLISTVIEW |
||||
{ |
||||
public NMHDR nmhdr; |
||||
public int iItem; |
||||
public int iSubItem; |
||||
public uint uNewState; |
||||
public uint uOldState; |
||||
public uint uChanged; |
||||
public POINTAPI ptAction; |
||||
public IntPtr lParam; |
||||
public bool NewSelected |
||||
{ |
||||
get |
||||
{ |
||||
return ((APIsEnums.ListViewItemStates)uNewState & APIsEnums.ListViewItemStates.SELECTED) == APIsEnums.ListViewItemStates.SELECTED; |
||||
} |
||||
} |
||||
public bool OldSelected |
||||
{ |
||||
get |
||||
{ |
||||
return ((APIsEnums.ListViewItemStates)uOldState & APIsEnums.ListViewItemStates.SELECTED) == APIsEnums.ListViewItemStates.SELECTED; |
||||
} |
||||
} |
||||
public bool NewCheck |
||||
{ |
||||
get |
||||
{ |
||||
try |
||||
{ |
||||
return uNewState >= 0x1000 ? ((uNewState & (uint)APIsEnums.ListViewItemStates.STATEIMAGEMASK) >> 12) - 1 > 0 : false; |
||||
} |
||||
catch |
||||
{ |
||||
return false; |
||||
} |
||||
} |
||||
} |
||||
public bool OldCheck |
||||
{ |
||||
get |
||||
{ |
||||
try |
||||
{ |
||||
return uOldState >= 0x1000 ? ((uOldState & (uint)APIsEnums.ListViewItemStates.STATEIMAGEMASK) >> 12) - 1 > 0 : false; |
||||
} |
||||
catch |
||||
{ |
||||
return false; |
||||
} |
||||
} |
||||
} |
||||
public bool NewFocused |
||||
{ |
||||
get |
||||
{ |
||||
return ((APIsEnums.ListViewItemStates)uNewState & APIsEnums.ListViewItemStates.FOCUSED) == APIsEnums.ListViewItemStates.FOCUSED; |
||||
} |
||||
} |
||||
public bool OldFocused |
||||
{ |
||||
get |
||||
{ |
||||
return ((APIsEnums.ListViewItemStates)uOldState & APIsEnums.ListViewItemStates.FOCUSED) == APIsEnums.ListViewItemStates.FOCUSED; |
||||
} |
||||
} |
||||
public bool Select |
||||
{ |
||||
get |
||||
{ |
||||
return !OldSelected && NewSelected; |
||||
} |
||||
} |
||||
public bool UnSelect |
||||
{ |
||||
get |
||||
{ |
||||
return OldSelected && !NewSelected; |
||||
} |
||||
} |
||||
public bool Focus |
||||
{ |
||||
get |
||||
{ |
||||
return !OldFocused && NewFocused; |
||||
} |
||||
} |
||||
public bool UnFocus |
||||
{ |
||||
get |
||||
{ |
||||
return OldFocused && !NewFocused; |
||||
} |
||||
} |
||||
public bool Check |
||||
{ |
||||
get |
||||
{ |
||||
return !OldCheck && NewCheck; |
||||
} |
||||
} |
||||
public bool UnCheck |
||||
{ |
||||
get |
||||
{ |
||||
return OldCheck && !NewCheck; |
||||
} |
||||
} |
||||
} |
||||
#endregion
|
||||
#region HDITEM
|
||||
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)] |
||||
public struct HDITEM |
||||
{ |
||||
public APIsEnums.HeaderItemFlags mask; |
||||
public int cxy; |
||||
public IntPtr pszText; |
||||
public IntPtr hbm; |
||||
public int cchTextMax; |
||||
public int fmt; |
||||
public int lParam; |
||||
public int iImage; |
||||
public int iOrder; |
||||
} |
||||
#endregion
|
||||
#region HD_HITTESTINFO
|
||||
[StructLayout(LayoutKind.Sequential)] |
||||
public struct HD_HITTESTINFO |
||||
{ |
||||
public POINTAPI pt; |
||||
public APIsEnums.HeaderControlHitTestFlags flags; |
||||
public int iItem; |
||||
} |
||||
#endregion
|
||||
|
||||
#region POINTAPI
|
||||
[StructLayoutAttribute(LayoutKind.Sequential)] |
||||
public struct POINTAPI |
||||
{ |
||||
public POINTAPI(System.Drawing.Point p) {x = p.X; y = p.Y;} |
||||
public POINTAPI(Int32 X, Int32 Y) {x = X; y = Y;} |
||||
public Int32 x; |
||||
public Int32 y; |
||||
} |
||||
#endregion
|
||||
#region RECT
|
||||
[StructLayout(LayoutKind.Sequential)] |
||||
public struct RECT |
||||
{ |
||||
public RECT(Drawing.Rectangle rectangle) |
||||
{ left = rectangle.Left; top = rectangle.Top; |
||||
right = rectangle.Right; bottom = rectangle.Bottom;} |
||||
public int left; |
||||
public int top; |
||||
public int right; |
||||
public int bottom; |
||||
} |
||||
#endregion
|
||||
#region SIZE
|
||||
[StructLayout(LayoutKind.Sequential)] |
||||
public struct SIZE |
||||
{ |
||||
public int cx; |
||||
public int cy; |
||||
} |
||||
#endregion
|
||||
|
||||
#region NMHDR
|
||||
// [StructLayout(LayoutKind.Sequential)]
|
||||
public struct NMHDR |
||||
{ |
||||
public IntPtr hwndFrom; |
||||
public int idFrom; |
||||
public int code; |
||||
} |
||||
#endregion
|
||||
#region NMCUSTOMDRAW
|
||||
[StructLayout(LayoutKind.Sequential)] |
||||
public struct NMCUSTOMDRAW |
||||
{ |
||||
public NMHDR hdr; |
||||
public int dwDrawStage; |
||||
public IntPtr hdc; |
||||
public RECT rc; |
||||
public uint dwItemSpec; |
||||
public uint uItemState; |
||||
public IntPtr lItemlParam; |
||||
} |
||||
#endregion
|
||||
#region NMLVCUSTOMDRAW
|
||||
[StructLayout(LayoutKind.Sequential)] |
||||
public struct NMLVCUSTOMDRAW |
||||
{ |
||||
public NMCUSTOMDRAW nmcd; |
||||
public int clrText; |
||||
public int clrTextBk; |
||||
public int iSubItem; |
||||
public int dwItemType; |
||||
public int clrFace; |
||||
public int iIconEffect; |
||||
public int iIconPhase; |
||||
public int iPartId; |
||||
public int iStateId; |
||||
public RECT rcText; |
||||
public uint uAlign; |
||||
} |
||||
#endregion
|
||||
#region NMTVCUSTOMDRAW
|
||||
[StructLayout(LayoutKind.Sequential)] |
||||
public struct NMTVCUSTOMDRAW |
||||
{ |
||||
public NMCUSTOMDRAW nmcd; |
||||
public uint clrText; |
||||
public uint clrTextBk; |
||||
public int iLevel; |
||||
} |
||||
#endregion
|
||||
|
||||
#region BITMAPINFO_FLAT
|
||||
[StructLayout(LayoutKind.Sequential)] |
||||
public struct BITMAPINFO_FLAT |
||||
{ |
||||
public int bmiHeader_biSize; |
||||
public int bmiHeader_biWidth; |
||||
public int bmiHeader_biHeight; |
||||
public short bmiHeader_biPlanes; |
||||
public short bmiHeader_biBitCount; |
||||
public int bmiHeader_biCompression; |
||||
public int bmiHeader_biSizeImage; |
||||
public int bmiHeader_biXPelsPerMeter; |
||||
public int bmiHeader_biYPelsPerMeter; |
||||
public int bmiHeader_biClrUsed; |
||||
public int bmiHeader_biClrImportant; |
||||
[MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=1024)] |
||||
public byte[] bmiColors; |
||||
} |
||||
#endregion
|
||||
#region BITMAPINFOHEADER
|
||||
[StructLayout(LayoutKind.Sequential)] |
||||
public class BITMAPINFOHEADER |
||||
{ |
||||
public int biSize = Marshal.SizeOf(typeof(BITMAPINFOHEADER)); |
||||
public int biWidth; |
||||
public int biHeight; |
||||
public short biPlanes; |
||||
public short biBitCount; |
||||
public int biCompression; |
||||
public int biSizeImage; |
||||
public int biXPelsPerMeter; |
||||
public int biYPelsPerMeter; |
||||
public int biClrUsed; |
||||
public int biClrImportant; |
||||
} |
||||
#endregion
|
||||
|
||||
#region MSG
|
||||
[StructLayout(LayoutKind.Sequential)] |
||||
public struct MSG |
||||
{ |
||||
public IntPtr hwnd; |
||||
public int message; |
||||
public IntPtr wParam; |
||||
public IntPtr lParam; |
||||
public int time; |
||||
public int pt_x; |
||||
public int pt_y; |
||||
} |
||||
#endregion
|
||||
#region PAINTSTRUCT
|
||||
[StructLayout(LayoutKind.Sequential)] |
||||
public struct PAINTSTRUCT |
||||
{ |
||||
public IntPtr hdc; |
||||
public int fErase; |
||||
public System.Drawing.Rectangle rcPaint; |
||||
public int fRestore; |
||||
public int fIncUpdate; |
||||
public int Reserved1; |
||||
public int Reserved2; |
||||
public int Reserved3; |
||||
public int Reserved4; |
||||
public int Reserved5; |
||||
public int Reserved6; |
||||
public int Reserved7; |
||||
public int Reserved8; |
||||
} |
||||
#endregion
|
||||
#region TRACKMOUSEEVENTS
|
||||
[StructLayout(LayoutKind.Sequential)] |
||||
public struct TRACKMOUSEEVENTS |
||||
{ |
||||
public uint cbSize; |
||||
public APIsEnums.TrackerEventFlags dwFlags; |
||||
public IntPtr hWnd; |
||||
public uint dwHoverTime; |
||||
} |
||||
#endregion
|
||||
#region WINDOWPLACEMENT
|
||||
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)] |
||||
public struct WINDOWPLACEMENT |
||||
{ |
||||
public uint length; |
||||
public uint flags; |
||||
public uint showCmd; |
||||
public APIsStructs.POINTAPI ptMinPosition; |
||||
public APIsStructs.POINTAPI ptMaxPosition; |
||||
public APIsStructs.RECT rcNormalPosition; |
||||
} |
||||
#endregion
|
||||
|
||||
#region SCROLLINFO
|
||||
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)] |
||||
public struct SCROLLINFO |
||||
{ |
||||
public uint cbSize; |
||||
public uint fMask; |
||||
public int nMin; |
||||
public int nMax; |
||||
public uint nPage; |
||||
public int nPos; |
||||
public int nTrackPos; |
||||
} |
||||
#endregion
|
||||
#region SCROLLBARINFO
|
||||
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)] |
||||
public struct SCROLLBARINFO |
||||
{ |
||||
public uint cbSize; |
||||
public APIsStructs.RECT rcScrollBar; |
||||
public int dxyLineButton; |
||||
public int xyThumbTop; |
||||
public int xyThumbBottom; |
||||
public int reserved; |
||||
[MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=6)] |
||||
public uint[] rgstate; |
||||
} |
||||
#endregion
|
||||
|
||||
#region PCOMBOBOXINFO
|
||||
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)] |
||||
public struct PCOMBOBOXINFO |
||||
{ |
||||
public uint cbSize; |
||||
public APIsStructs.RECT rcItem; |
||||
public APIsStructs.RECT rcButton; |
||||
public int stateButton; |
||||
public IntPtr hwndCombo; |
||||
public IntPtr hwndItem; |
||||
public IntPtr hwndList; |
||||
} |
||||
#endregion
|
||||
|
||||
#region BLENDFUNCTION
|
||||
[StructLayout(LayoutKind.Sequential, Pack=1)] |
||||
public struct BLENDFUNCTION |
||||
{ |
||||
public byte BlendOp; |
||||
public byte BlendFlags; |
||||
public byte SourceConstantAlpha; |
||||
public byte AlphaFormat; |
||||
} |
||||
#endregion
|
||||
|
||||
#region NMHEADER
|
||||
[StructLayout(LayoutKind.Sequential, Pack=1)] |
||||
public struct NMHEADER |
||||
{ |
||||
public NMHDR nmhdr; |
||||
public int iItem; |
||||
public int iButton; |
||||
public HDITEM pItem; |
||||
} |
||||
#endregion
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack=1)] |
||||
public struct INPUT |
||||
{ |
||||
public uint type; |
||||
public int dx; |
||||
public int dy; |
||||
public uint mouseData; |
||||
public uint dwFlags; |
||||
public uint time; |
||||
public uint dwExtra; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,181 @@
@@ -0,0 +1,181 @@
|
||||
using System; |
||||
|
||||
namespace System.Runtime.InteropServices.APIs |
||||
{ |
||||
public class APIsUser32 |
||||
{ |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
static public extern uint SendInput(uint nInputs, APIsStructs.INPUT[] inputs, int cbSize); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
static public extern bool ScreenToClient(IntPtr hWnd, ref APIsStructs.POINTAPI point); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
static public extern int DrawFrameControl(IntPtr hDc, APIsStructs.RECT rect, APIsEnums.DrawFrameControlFlags nType, APIsEnums.DrawFrameControlStateFlags nState); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
static public extern int GetSysColor(APIsEnums.SystemColors nIndex); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
static public extern bool DestroyIcon(IntPtr hIcon); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
static public extern bool GetComboBoxInfo(IntPtr hWnd, ref APIsStructs.PCOMBOBOXINFO cbi); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
static public extern bool DestroyWindow(IntPtr hWnd); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
static public extern IntPtr GetDC(IntPtr hWnd); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
static public extern int ReleaseDC(IntPtr hWnd, IntPtr hDC); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
static public extern IntPtr GetDesktopWindow(); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
static public extern bool ShowWindow(IntPtr hWnd, APIsEnums.ShowWindowStyles State); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
static public extern bool UpdateWindow(IntPtr hWnd); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
static public extern bool SetForegroundWindow(IntPtr hWnd); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
static public extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int Width, int Height, uint flags); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
static public extern bool OpenClipboard(IntPtr hWndNewOwner); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
static public extern bool CloseClipboard(); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
static public extern bool EmptyClipboard(); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
static public extern IntPtr SetClipboardData( uint Format, IntPtr hData); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
static public extern bool GetMenuItemRect(IntPtr hWnd, IntPtr hMenu, uint Item, ref APIsStructs.RECT rc); |
||||
[DllImport("user32.dll", ExactSpelling=true, CharSet=CharSet.Auto)] |
||||
public static extern IntPtr GetParent(IntPtr hWnd); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
public static extern int SendMessage(IntPtr hWnd, APIsEnums.HeaderControlMessages msg, int wParam, ref APIsStructs.HDITEM lParam); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
public static extern int SendMessage(IntPtr hWnd, int msg, int wParam, int lParam); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
public static extern int SendMessage(IntPtr hWnd, APIsEnums.HeaderControlMessages msg, IntPtr wParam, ref APIsStructs.HD_HITTESTINFO hd_hittestinfo); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
public static extern int SendMessage(IntPtr hWnd, APIsEnums.WindowMessages msg, int wParam, int lParam); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, IntPtr lParam); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
public static extern void SendMessage(IntPtr hWnd, int msg, IntPtr wParam, ref APIsStructs.NMHDR lParam); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
public static extern void SendMessage(IntPtr hWnd, int msg, IntPtr wParam, ref APIsStructs.NMLVDISPINFO lParam); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
public static extern void SendMessage(IntPtr hWnd, int msg, int wParam, ref APIsStructs.RECT lParam); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
public static extern int SendMessage(IntPtr hWnd, int msg, int wParam, ref APIsStructs.POINTAPI lParam); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
public static extern IntPtr PostMessage(IntPtr hWnd, int msg, int wParam, int lParam); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
public static extern IntPtr PostMessage(IntPtr hWnd, APIsEnums.WindowMessages msg, int wParam, int lParam); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
public static extern IntPtr SetFocus(IntPtr hWnd); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
public extern static int DrawText(IntPtr hdc, string lpString, int nCount, ref APIsStructs.RECT lpRect, APIsEnums.DrawTextFormatFlags flags); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
public extern static IntPtr SetParent(IntPtr hChild, IntPtr hParent); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
public extern static IntPtr GetDlgItem(IntPtr hDlg, int nControlID); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
public extern static int GetClientRect(IntPtr hWnd, ref APIsStructs.RECT rc); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
public extern static int InvalidateRect(IntPtr hWnd, ref APIsStructs.RECT rc, int bErase); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
public extern static int InvalidateRect(IntPtr hWnd, IntPtr rc, int bErase); |
||||
[DllImport("User32.dll", CharSet=CharSet.Auto)] |
||||
public static extern bool WaitMessage(); |
||||
[DllImport("User32.dll", CharSet=CharSet.Auto)] |
||||
public static extern bool PeekMessage(ref APIsStructs.MSG msg, int hWnd, uint wFilterMin, uint wFilterMax, APIsEnums.PeekMessageFlags flags); |
||||
[DllImport("User32.dll", CharSet=CharSet.Auto)] |
||||
public static extern bool GetMessage(ref APIsStructs.MSG msg, int hWnd, uint wFilterMin, uint wFilterMax); |
||||
[DllImport("User32.dll", CharSet=CharSet.Auto)] |
||||
public static extern bool TranslateMessage(ref APIsStructs.MSG msg); |
||||
[DllImport("User32.dll", CharSet=CharSet.Auto)] |
||||
public static extern bool DispatchMessage(ref APIsStructs.MSG msg); |
||||
[DllImport("User32.dll", CharSet=CharSet.Auto)] |
||||
public static extern IntPtr LoadCursor(IntPtr hInstance, APIsEnums.CursorTypes cursor); |
||||
[DllImport("User32.dll", CharSet=CharSet.Auto)] |
||||
public static extern IntPtr SetCursor(IntPtr hCursor); |
||||
[DllImport("User32.dll", CharSet=CharSet.Auto)] |
||||
public static extern IntPtr GetFocus(); |
||||
[DllImport("User32.dll", CharSet=CharSet.Auto)] |
||||
public static extern bool ReleaseCapture(); |
||||
[DllImport("User32.dll", CharSet=CharSet.Auto)] |
||||
public static extern IntPtr SetCapture(IntPtr hWnd); |
||||
[DllImport("User32.dll", CharSet=CharSet.Auto)] |
||||
public static extern IntPtr BeginPaint(IntPtr hWnd, ref APIsStructs.PAINTSTRUCT ps); |
||||
[DllImport("User32.dll", CharSet=CharSet.Auto)] |
||||
public static extern bool EndPaint(IntPtr hWnd, ref APIsStructs.PAINTSTRUCT ps); |
||||
[DllImport("User32.dll", CharSet=CharSet.Auto)] |
||||
public static extern bool UpdateLayeredWindow(IntPtr hwnd, IntPtr hdcDst, ref APIsStructs.POINTAPI pptDst, ref APIsStructs.SIZE psize, |
||||
IntPtr hdcSrc, ref APIsStructs.POINTAPI pprSrc, Int32 crKey, ref APIsStructs.BLENDFUNCTION pblend, APIsEnums.UpdateLayeredWindowFlags dwFlags); |
||||
[DllImport("User32.dll", CharSet=CharSet.Auto)] |
||||
public static extern bool GetWindowRect(IntPtr hWnd, ref APIsStructs.RECT rect); |
||||
[DllImport("User32.dll", CharSet=CharSet.Auto)] |
||||
public static extern bool ClientToScreen(IntPtr hWnd, ref APIsStructs.POINTAPI pt); |
||||
[DllImport("User32.dll", CharSet=CharSet.Auto)] |
||||
public static extern bool TrackMouseEvent(ref APIsStructs.TRACKMOUSEEVENTS tme); |
||||
[DllImport("User32.dll", CharSet=CharSet.Auto)] |
||||
public static extern bool SetWindowRgn(IntPtr hWnd, IntPtr hRgn, bool redraw); |
||||
[DllImport("User32.dll", CharSet=CharSet.Auto)] |
||||
public static extern ushort GetKeyState(int virtKey); |
||||
[DllImport("User32.dll", CharSet=CharSet.Auto)] |
||||
public static extern bool MoveWindow(IntPtr hWnd, int x, int y, int width, int height, bool repaint); |
||||
[DllImport("User32.dll", CharSet=CharSet.Auto)] |
||||
public static extern int GetClassName(IntPtr hWnd, System.Text.StringBuilder ClassName, int nMaxCount); |
||||
[DllImport("User32.dll", CharSet=CharSet.Auto)] |
||||
public static extern IntPtr GetDCEx(IntPtr hWnd, IntPtr hRegion, uint flags); |
||||
[DllImport("User32.dll", CharSet=CharSet.Auto)] |
||||
public static extern IntPtr GetWindowDC(IntPtr hWnd); |
||||
[DllImport("User32.dll", CharSet=CharSet.Auto)] |
||||
public static extern int FillRect(IntPtr hDC, ref APIsStructs.RECT rect, IntPtr hBrush); |
||||
[DllImport("User32.dll", CharSet=CharSet.Auto)] |
||||
public static extern int GetWindowPlacement(IntPtr hWnd, ref APIsStructs.WINDOWPLACEMENT wp); |
||||
[DllImport("User32.dll", CharSet=CharSet.Auto)] |
||||
public static extern int SetWindowText(IntPtr hWnd, string text); |
||||
[DllImport("User32.dll", CharSet=CharSet.Auto)] |
||||
public static extern int GetWindowText(IntPtr hWnd, System.Text.StringBuilder text, int maxCount); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
static public extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
static public extern IntPtr SetClipboardViewer(IntPtr hWndNewViewer); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
static public extern int ChangeClipboardChain(IntPtr hWndRemove, IntPtr hWndNewNext); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
static public extern int GetSystemMetrics(APIsEnums.SystemMetricsCodes code); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
static public extern int SetScrollInfo(IntPtr hwnd, int bar, ref APIsStructs.SCROLLINFO si, int fRedraw); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
static public extern int ShowScrollBar(IntPtr hWnd, int bar, int show); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
static public extern int EnableScrollBar(IntPtr hWnd, uint flags, uint arrows); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
static public extern int BringWindowToTop(IntPtr hWnd); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
static public extern int GetScrollInfo(IntPtr hwnd, int bar, ref APIsStructs.SCROLLINFO si); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
static public extern int ScrollWindowEx(IntPtr hWnd, int dx, int dy, |
||||
ref APIsStructs.RECT rcScroll, ref APIsStructs.RECT rcClip, IntPtr UpdateRegion, ref APIsStructs.RECT rcInvalidated, uint flags); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
static public extern bool IsWindow(IntPtr hWnd); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
static public extern int LockWindowUpdate(IntPtr hWnd); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
static public extern bool ValidateRect(IntPtr hWnd, ref APIsStructs.RECT rcInvalidated); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
static public extern bool ValidateRect(IntPtr hWnd, IntPtr rc); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
static public extern int GetScrollBarInfo(IntPtr hWnd, APIsEnums.SystemObjects id, ref APIsStructs.SCROLLBARINFO sbi); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
static public extern int SetProp(IntPtr hWnd, IntPtr atom, IntPtr hData); |
||||
[DllImport("user32.dll", CharSet=CharSet.Auto)] |
||||
static public extern int CallWindowProc(IntPtr hOldProc, IntPtr hWnd, uint message, int wParam, int lParam); |
||||
[DllImport("user32.dll")] |
||||
public static extern bool SendMessage(IntPtr hWnd, APIsEnums.ListViewMessages msg, |
||||
Int32 wParam, ref APIsStructs.LV_ITEM lParam); |
||||
[DllImport("user32.dll")] |
||||
public static extern int SendMessage(IntPtr hWnd, Int32 msg, Int32 wParam, ref |
||||
APIsStructs.LVHITTESTINFO lParam); |
||||
[DllImport("user32.dll")] |
||||
public static extern bool SendMessage(IntPtr hWnd, int msg, |
||||
IntPtr wParam, ref IntPtr lParam); |
||||
} |
||||
} |
@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
|
||||
using System; |
||||
|
||||
namespace System.Runtime.InteropServices.APIs |
||||
{ |
||||
public class APIsUxTheme |
||||
{ |
||||
[DllImport("UxTheme.dll", CharSet=CharSet.Auto)] |
||||
static public extern IntPtr OpenThemeData( |
||||
IntPtr hWnd, string pszClassList); |
||||
[DllImport("UxTheme.dll", CharSet=CharSet.Auto)] |
||||
static public extern int CloseThemeData(IntPtr hTheme); |
||||
[DllImport("UxTheme.dll", CharSet=CharSet.Auto)] |
||||
static public extern bool IsThemeActive(); |
||||
[DllImport("UxTheme.dll", CharSet=CharSet.Auto)] |
||||
static public extern bool IsAppThemed(); |
||||
[DllImport("UxTheme.dll", CharSet=CharSet.Auto)] |
||||
static public extern int DrawThemeBackground( |
||||
IntPtr hWnd, IntPtr hDc, int iPartId, int iStateId, |
||||
APIsStructs.RECT pRect, APIsStructs.RECT pClipRect); |
||||
[DllImport("UxTheme.dll", CharSet=CharSet.Auto)] |
||||
static public extern int GetCurrentThemeName( |
||||
Text.StringBuilder pszThemeFileName, int dwMaxNameChars, |
||||
Text.StringBuilder pszColorBuff, int cchMaxColorChars, |
||||
Text.StringBuilder pszSizeBuff, int cchMaxSizeChars); |
||||
} |
||||
} |
@ -0,0 +1,49 @@
@@ -0,0 +1,49 @@
|
||||
using System; |
||||
using System.Runtime.InteropServices; |
||||
|
||||
namespace System.Runtime.InteropServices.APIs |
||||
{ |
||||
public class APIsWndProc |
||||
{ |
||||
[DllImport("user32.dll")] |
||||
public static extern IntPtr SetWindowLong( |
||||
IntPtr window, |
||||
int index, |
||||
WndProc value); |
||||
|
||||
[DllImport("user32.dll")] |
||||
public static extern IntPtr SetWindowLong( |
||||
IntPtr window, |
||||
int index, |
||||
GetWndProc value); |
||||
|
||||
[DllImport("user32.dll")] |
||||
public static extern IntPtr SetWindowLong( |
||||
IntPtr window, |
||||
int index, |
||||
IntPtr value); |
||||
|
||||
[DllImport("user32.dll")] |
||||
public static extern int GetWindowLong( |
||||
IntPtr window, |
||||
int index); |
||||
|
||||
[DllImport("user32.dll")] |
||||
public static extern int CallWindowProc( |
||||
IntPtr value, |
||||
IntPtr Handle, |
||||
int Msg, |
||||
IntPtr WParam, |
||||
IntPtr LParam); |
||||
|
||||
[DllImport("user32.dll")] |
||||
public static extern int DefWindowProc( |
||||
IntPtr Handle, |
||||
int Msg, |
||||
IntPtr WParam, |
||||
IntPtr LParam); |
||||
|
||||
public delegate int GetWndProc(IntPtr hWnd, int Msg, IntPtr WParam, IntPtr LParam); |
||||
public delegate void WndProc(ref System.Windows.Forms.Message m); |
||||
} |
||||
} |
@ -0,0 +1,167 @@
@@ -0,0 +1,167 @@
|
||||
using System; |
||||
using System.Runtime.InteropServices; |
||||
using System.Text; |
||||
|
||||
namespace System.Runtime.InteropServices.APIs |
||||
{ |
||||
public class COMInterfaces |
||||
{ |
||||
#region IShellFolder
|
||||
[ComImport, |
||||
Guid("000214E6-0000-0000-C000-000000000046"), |
||||
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] |
||||
public interface IShellFolder |
||||
{ |
||||
void ParseDisplayName( |
||||
IntPtr hwnd, |
||||
IntPtr pbc, |
||||
[MarshalAs(UnmanagedType.LPWStr)] string pszDisplayName, |
||||
out uint pchEaten, |
||||
out IntPtr ppidl, |
||||
ref uint pdwAttributes); |
||||
|
||||
[PreserveSig] |
||||
int EnumObjects(IntPtr hWnd, APIsEnums.ShellFolderEnumObjectsTypes flags, ref IEnumIDList enumList); |
||||
|
||||
void BindToObject( |
||||
IntPtr pidl, |
||||
IntPtr pbc, |
||||
[In()] ref Guid riid, |
||||
out IShellFolder ppv); |
||||
//[MarshalAs(UnmanagedType.Interface)] out object ppv);
|
||||
|
||||
void BindToStorage( |
||||
IntPtr pidl, |
||||
IntPtr pbc, |
||||
[In()] ref Guid riid, |
||||
[MarshalAs(UnmanagedType.Interface)] out object ppv); |
||||
|
||||
[PreserveSig()] |
||||
uint CompareIDs( |
||||
int lParam, |
||||
IntPtr pidl1, |
||||
IntPtr pidl2); |
||||
|
||||
void CreateViewObject( |
||||
IntPtr hwndOwner, |
||||
[In()] ref Guid riid, |
||||
[MarshalAs(UnmanagedType.Interface)] out object ppv); |
||||
|
||||
void GetAttributesOf( |
||||
uint cidl, |
||||
[In(), MarshalAs(UnmanagedType.LPArray)] IntPtr[] apidl, |
||||
ref APIsEnums.ShellFolderAttributes rgfInOut); |
||||
|
||||
[return: MarshalAs(UnmanagedType.Interface)] |
||||
object GetUIObjectOf( |
||||
IntPtr hwndOwner, |
||||
uint cidl, |
||||
[MarshalAs(UnmanagedType.LPArray)] IntPtr[] apidl, |
||||
[In()] ref Guid riid, |
||||
IntPtr rgfReserved); |
||||
|
||||
void GetDisplayNameOf( |
||||
IntPtr pidl, |
||||
APIsEnums.ShellFolderDisplayNames uFlags, |
||||
out APIsStructs.STRRET pName); |
||||
|
||||
IntPtr SetNameOf( |
||||
IntPtr hwnd, |
||||
IntPtr pidl, |
||||
[MarshalAs(UnmanagedType.LPWStr)] string pszName, |
||||
APIsEnums.ShellFolderDisplayNames uFlags); |
||||
} |
||||
#endregion
|
||||
#region IEnumIDList
|
||||
[ComImport(), |
||||
Guid("000214F2-0000-0000-C000-000000000046"), |
||||
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] |
||||
public interface IEnumIDList |
||||
{ |
||||
[PreserveSig()] |
||||
uint Next( |
||||
uint celt, |
||||
[In(), Out(), MarshalAs(UnmanagedType.LPArray)] IntPtr[] rgelt, |
||||
out uint pceltFetched); |
||||
|
||||
void Skip( |
||||
uint celt); |
||||
|
||||
void Reset(); |
||||
|
||||
IEnumIDList Clone(); |
||||
} |
||||
#endregion
|
||||
#region IDataObject
|
||||
[ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), GuidAttribute("0000010e-0000-0000-C000-000000000046")] |
||||
public interface IDataObject |
||||
{ |
||||
[PreserveSig()] |
||||
int GetData(ref APIsStructs.FORMATETC a, ref APIsStructs.STGMEDIUM b); |
||||
[PreserveSig()] |
||||
void GetDataHere(int a, ref APIsStructs.STGMEDIUM b); |
||||
[PreserveSig()] |
||||
int QueryGetData(int a); |
||||
[PreserveSig()] |
||||
int GetCanonicalFormatEtc(int a, ref int b); |
||||
[PreserveSig()] |
||||
int SetData(int a, int b, int c); |
||||
[PreserveSig()] |
||||
int EnumFormatEtc(uint a, ref Object b); |
||||
[PreserveSig()] |
||||
int DAdvise(int a, uint b, Object c, ref uint d); |
||||
[PreserveSig()] |
||||
int DUnadvise(uint a); |
||||
[PreserveSig()] |
||||
int EnumDAdvise(ref Object a); |
||||
} |
||||
#endregion
|
||||
#region IShellExtInit
|
||||
[ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), GuidAttribute("000214e8-0000-0000-c000-000000000046")] |
||||
public interface IShellExtInit |
||||
{ |
||||
[PreserveSig()] |
||||
int Initialize (IntPtr pidlFolder, IntPtr lpdobj, uint /*HKEY*/ hKeyProgID); |
||||
} |
||||
#endregion
|
||||
|
||||
#region IContextMenu
|
||||
[ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), GuidAttribute("000214e4-0000-0000-c000-000000000046")] |
||||
public interface IContextMenu |
||||
{ |
||||
// IContextMenu methods
|
||||
[PreserveSig()] |
||||
int QueryContextMenu(uint hmenu, uint iMenu, int idCmdFirst, int idCmdLast, uint uFlags); |
||||
[PreserveSig()] |
||||
void InvokeCommand (ref APIsStructs.CMINVOKECOMMANDINFO pici); |
||||
[PreserveSig()] |
||||
void GetCommandString( |
||||
int idcmd, |
||||
APIsEnums.GetCommandStringInformations uflags, |
||||
int reserved, |
||||
StringBuilder commandstring, |
||||
int cch); |
||||
} |
||||
#endregion
|
||||
#region IContextMenu2
|
||||
[ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), GuidAttribute("000214f4-0000-0000-c000-000000000046")] |
||||
public interface IContextMenu2 |
||||
{ |
||||
// IContextMenu methods
|
||||
[PreserveSig()] |
||||
int QueryContextMenu(uint hmenu, uint iMenu, int idCmdFirst, int idCmdLast, uint uFlags); |
||||
[PreserveSig()] |
||||
void InvokeCommand (ref APIsStructs.CMINVOKECOMMANDINFO pici); |
||||
[PreserveSig()] |
||||
void GetCommandString(int idcmd, |
||||
APIsEnums.GetCommandStringInformations uflags, |
||||
int reserved, |
||||
StringBuilder commandstring, |
||||
int cch); |
||||
// IContextMenu2 methods
|
||||
[PreserveSig()] |
||||
uint HandleMenuMsg(uint uMsg,IntPtr wParam,IntPtr lParam); |
||||
} |
||||
#endregion
|
||||
} |
||||
} |
@ -0,0 +1,559 @@
@@ -0,0 +1,559 @@
|
||||
using System; |
||||
using System.Drawing; |
||||
|
||||
namespace System.Runtime.InteropServices.APIs |
||||
{ |
||||
/// <summary>
|
||||
/// Summary description for ColorConvert.
|
||||
/// </summary>
|
||||
public class ColorUtil |
||||
{ |
||||
|
||||
#region Class Variables
|
||||
static Color backgroundColor = Color.Empty; |
||||
static Color selectionColor = Color.Empty; |
||||
static Color selectionUnfocusedColor = Color.Empty; |
||||
static Color controlColor = Color.Empty; |
||||
static Color pressedColor = Color.Empty; |
||||
static Color checkedColor = Color.Empty; |
||||
static Color borderColor = Color.Empty; |
||||
static bool useCustomColor = false; |
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
// No need to construct this object
|
||||
private ColorUtil() |
||||
{ |
||||
} |
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
static public bool UsingCustomColor |
||||
{ |
||||
get { return useCustomColor;} |
||||
} |
||||
#endregion
|
||||
|
||||
#region Knowncolor names
|
||||
static public string[] KnownColorNames = |
||||
{ "Transparent", "Black", "DimGray", "Gray", "DarkGray", "Silver", "LightGray", "Gainsboro", "WhiteSmoke", "White", |
||||
"RosyBrown", "IndianRed", "Brown", "Firebrick", "LightCoral", "Maroon", "DarkRed", "Red", "Snow", "MistyRose", |
||||
"Salmon", "Tomato", "DarkSalmon", "Coral", "OrangeRed", "LightSalmon", "Sienna", "SeaShell", "Chocalate", |
||||
"SaddleBrown", "SandyBrown", "PeachPuff", "Peru", "Linen", "Bisque", "DarkOrange", "BurlyWood", "Tan", "AntiqueWhite", |
||||
"NavajoWhite", "BlanchedAlmond", "PapayaWhip", "Mocassin", "Orange", "Wheat", "OldLace", "FloralWhite", "DarkGoldenrod", |
||||
"Cornsilk", "Gold", "Khaki", "LemonChiffon", "PaleGoldenrod", "DarkKhaki", "Beige", "LightGoldenrod", "Olive", |
||||
"Yellow", "LightYellow", "Ivory", "OliveDrab", "YellowGreen", "DarkOliveGreen", "GreenYellow", "Chartreuse", "LawnGreen", |
||||
"DarkSeaGreen", "ForestGreen", "LimeGreen", "PaleGreen", "DarkGreen", "Green", "Lime", "Honeydew", "SeaGreen", "MediumSeaGreen", |
||||
"SpringGreen", "MintCream", "MediumSpringGreen", "MediumAquaMarine", "YellowAquaMarine", "Turquoise", "LightSeaGreen", |
||||
"MediumTurquoise", "DarkSlateGray", "PaleTurquoise", "Teal", "DarkCyan", "Aqua", "Cyan", "LightCyan", "Azure", "DarkTurquoise", |
||||
"CadetBlue", "PowderBlue", "LightBlue", "DeepSkyBlue", "SkyBlue", "LightSkyBlue", "SteelBlue", "AliceBlue", "DodgerBlue", |
||||
"SlateGray", "LightSlateGray", "LightSteelBlue", "CornflowerBlue", "RoyalBlue", "MidnightBlue", "Lavender", "Navy", |
||||
"DarkBlue", "MediumBlue", "Blue", "GhostWhite", "SlateBlue", "DarkSlateBlue", "MediumSlateBlue", "MediumPurple", |
||||
"BlueViolet", "Indigo", "DarkOrchid", "DarkViolet", "MediumOrchid", "Thistle", "Plum", "Violet", "Purple", "DarkMagenta", |
||||
"Magenta", "Fuchsia", "Orchid", "MediumVioletRed", "DeepPink", "HotPink", "LavenderBlush", "PaleVioletRed", "Crimson", |
||||
"Pink", "LightPink" }; |
||||
#endregion
|
||||
|
||||
#region Systemcolors names
|
||||
static public string[] SystemColorNames = |
||||
{ |
||||
"ActiveBorder", "ActiveCaption", "ActiveCaptionText", "AppWorkspace", "Control", "ControlDark", "ControlDarkDark", |
||||
"ControlLight", "ControlLightLight", "ControlText", "Desktop", "GrayText", "HighLight", "HighLightText", |
||||
"HotTrack", "InactiveBorder", "InactiveCaption", "InactiveCaptionText", "Info", "InfoText", "Menu", "MenuText", |
||||
"ScrollBar", "Window", "WindowFrame", "WindowText" }; |
||||
#endregion
|
||||
|
||||
#region Conversion between RGB and Hue, Saturation and Luminosity function helpers
|
||||
static public void HSLToRGB(float h, float s, float l, ref float r, ref float g, ref float b) |
||||
{ |
||||
// given h,s,l,[240 and r,g,b [0-255]
|
||||
// convert h [0-360], s,l,r,g,b [0-1]
|
||||
h=(h/240)*360; |
||||
s /= 240; |
||||
l /= 240; |
||||
r /= 255; |
||||
g /= 255; |
||||
b /= 255; |
||||
|
||||
// Begin Foley
|
||||
float m1,m2; |
||||
|
||||
// Calc m2
|
||||
if (l<=0.5f) |
||||
{ |
||||
//m2=(l*(l+s)); seems to be typo in Foley??, replace l for 1
|
||||
m2=(l*(1+s)); |
||||
} |
||||
else |
||||
{ |
||||
m2=(l+s-l*s); |
||||
} |
||||
|
||||
//calc m1
|
||||
m1=2.0f*l-m2; |
||||
|
||||
//calc r,g,b in [0-1]
|
||||
if (s==0.0f) |
||||
{ // Achromatic: There is no hue
|
||||
// leave out the UNDEFINED part, h will always have value
|
||||
r=g=b=l; |
||||
} |
||||
else |
||||
{ // Chromatic: There is a hue
|
||||
r= getRGBValue(m1,m2,h+120.0f); |
||||
g= getRGBValue(m1,m2,h); |
||||
b= getRGBValue(m1,m2,h-120.0f); |
||||
} |
||||
|
||||
// End Foley
|
||||
// convert to 0-255 ranges
|
||||
r*=255; |
||||
g*=255; |
||||
b*=255; |
||||
|
||||
} |
||||
|
||||
static private float getRGBValue(float n1, float n2, float hue) |
||||
{ |
||||
// Helper function for the HSLToRGB function above
|
||||
if (hue>360.0f) |
||||
{ |
||||
hue-=360.0f; |
||||
} |
||||
else if (hue<0.0f) |
||||
{ |
||||
hue+=360.0f; |
||||
} |
||||
|
||||
if (hue<60.0) |
||||
{ |
||||
return n1+(n2-n1)*hue/60.0f; |
||||
} |
||||
else if (hue<180.0f) |
||||
{ |
||||
return n2; |
||||
} |
||||
else if (hue<240.0f) |
||||
{ |
||||
return n1+(n2-n1)*(240.0f-hue)/60.0f; |
||||
} |
||||
else |
||||
{ |
||||
return n1; |
||||
} |
||||
} |
||||
|
||||
static public void RGBToHSL(int r, int g, int b, ref float h, ref float s, ref float l) |
||||
{ |
||||
|
||||
float delta; |
||||
float fr = (float)r/255; |
||||
float fg = (float)g/255; |
||||
float fb = (float)b/255; |
||||
float max = Math.Max(fr,Math.Max(fg,fb)); |
||||
float min = Math.Min(fr,Math.Min(fg,fb)); |
||||
|
||||
//calc the lightness
|
||||
l = (max+min)/2; |
||||
|
||||
if (max==min) |
||||
{ |
||||
//should be undefined but this works for what we need
|
||||
s = 0; |
||||
h = 240.0f; |
||||
} |
||||
else |
||||
{ |
||||
|
||||
delta = max-min; |
||||
|
||||
//calc the Saturation
|
||||
if (l < 0.5) |
||||
{ |
||||
s = delta/(max+min); |
||||
} |
||||
else |
||||
{ |
||||
s = delta/(2.0f-(max+min)); |
||||
} |
||||
|
||||
//calc the hue
|
||||
if (fr==max) |
||||
{ |
||||
h = (fg-fb)/delta; |
||||
} |
||||
else if (fg==max) |
||||
{ |
||||
h = 2.0f + (fb-fr)/delta; |
||||
} |
||||
else if (fb==max) |
||||
{ |
||||
h = 4.0f + (fr-fg)/delta; |
||||
} |
||||
|
||||
//convert hue to degrees
|
||||
h*=60.0f; |
||||
if (h<0.0f) |
||||
{ |
||||
h+=360.0f; |
||||
} |
||||
} |
||||
|
||||
//convert to 0-255 ranges
|
||||
//h [0-360], h,l [0-1]
|
||||
l*=240; |
||||
s*=240; |
||||
h=(h/360)*240; |
||||
|
||||
} |
||||
#endregion
|
||||
|
||||
#region Visual Studio .NET colors calculation helpers
|
||||
|
||||
static public Color VSNetBackgroundColor |
||||
{ |
||||
get |
||||
{ |
||||
if ( useCustomColor && backgroundColor != Color.Empty ) |
||||
return backgroundColor; |
||||
else |
||||
return CalculateColor(SystemColors.Window, SystemColors.Control, 220); |
||||
} |
||||
set |
||||
{ |
||||
// Flag that we are going to use custom colors instead
|
||||
// of calculating the color based on the system colors
|
||||
// -- this is a way of hooking up into the VSNetColors that I use throughout
|
||||
// the UtilityLibrary
|
||||
useCustomColor = true; |
||||
backgroundColor = value; |
||||
} |
||||
} |
||||
|
||||
static public Color VSNetSelectionUnfocusedColor |
||||
{ |
||||
get |
||||
{ |
||||
if ( useCustomColor && selectionColor != Color.Empty ) |
||||
return selectionUnfocusedColor; |
||||
else |
||||
return CalculateColor(SystemColors.Highlight, SystemColors.Window, 25); |
||||
} |
||||
set |
||||
{ |
||||
// Flag that we are going to use custom colors instead
|
||||
// of calculating the color based on the system colors
|
||||
// -- this is a way of hooking up into the VSNetColor that I use throughout
|
||||
// the UtilityLibrary
|
||||
useCustomColor = true; |
||||
selectionUnfocusedColor = value; |
||||
} |
||||
} |
||||
|
||||
static public Color VSNetSelectionColor |
||||
{ |
||||
get |
||||
{ |
||||
if ( useCustomColor && selectionColor != Color.Empty ) |
||||
return selectionColor; |
||||
else |
||||
return CalculateColor(SystemColors.Highlight, SystemColors.Window, 70); |
||||
} |
||||
set |
||||
{ |
||||
// Flag that we are going to use custom colors instead
|
||||
// of calculating the color based on the system colors
|
||||
// -- this is a way of hooking up into the VSNetColor that I use throughout
|
||||
// the UtilityLibrary
|
||||
useCustomColor = true; |
||||
selectionColor = value; |
||||
} |
||||
} |
||||
|
||||
|
||||
static public Color VSNetControlColor |
||||
{ |
||||
get |
||||
{ if ( useCustomColor && controlColor != Color.Empty ) |
||||
return controlColor; |
||||
else |
||||
return CalculateColor(SystemColors.Control, VSNetBackgroundColor, 195); |
||||
} |
||||
set |
||||
{ |
||||
// Flag that we are going to use custom colors instead
|
||||
// of calculating the color based on the system colors
|
||||
// -- this is a way of hooking up into the VSNetColors that I use throughout
|
||||
// the UtilityLibrary
|
||||
useCustomColor = true; |
||||
controlColor = value; |
||||
} |
||||
|
||||
} |
||||
|
||||
static public Color VSNetPressedColor |
||||
{ |
||||
get |
||||
{ |
||||
if ( useCustomColor && pressedColor != Color.Empty ) |
||||
return pressedColor; |
||||
else |
||||
return CalculateColor(SystemColors.Highlight, ColorUtil.VSNetSelectionColor, 70); |
||||
} |
||||
set |
||||
{ |
||||
// Flag that we are going to use custom colors instead
|
||||
// of calculating the color based on the system colors
|
||||
// -- this is a way of hooking up into the VSNetColors that I use throughout
|
||||
// the UtilityLibrary
|
||||
useCustomColor = true; |
||||
pressedColor = value; |
||||
} |
||||
} |
||||
|
||||
|
||||
static public Color VSNetCheckedColor |
||||
{ |
||||
get |
||||
{ |
||||
if ( useCustomColor && pressedColor != Color.Empty ) |
||||
return checkedColor; |
||||
else |
||||
return CalculateColor(SystemColors.Highlight, SystemColors.Window, 30); |
||||
} |
||||
set |
||||
{ |
||||
// Flag that we are going to use custom colors instead
|
||||
// of calculating the color based on the system colors
|
||||
// -- this is a way of hooking up into the VSNetColors that I use throughout
|
||||
// the UtilityLibrary
|
||||
useCustomColor = true; |
||||
checkedColor = value; |
||||
} |
||||
} |
||||
|
||||
static public Color VSNetBorderColor |
||||
{ |
||||
get |
||||
{ |
||||
if ( useCustomColor && borderColor != Color.Empty ) |
||||
return borderColor; |
||||
else |
||||
{ |
||||
// This color is the default color unless we are using
|
||||
// custom colors
|
||||
return SystemColors.Highlight; |
||||
} |
||||
} |
||||
set |
||||
{ |
||||
// Flag that we are going to use custom colors instead
|
||||
// of calculating the color based on the system colors
|
||||
// -- this is a way of hooking up into the VSNetColors that I use throughout
|
||||
// the UtilityLibrary
|
||||
useCustomColor = true; |
||||
borderColor = value; |
||||
} |
||||
} |
||||
|
||||
public static Color CalculateColor(Color front, Color back, int alpha) |
||||
{ |
||||
|
||||
// Use alpha blending to brigthen the colors but don't use it
|
||||
// directly. Instead derive an opaque color that we can use.
|
||||
// -- if we use a color with alpha blending directly we won't be able
|
||||
// to paint over whatever color was in the background and there
|
||||
// would be shadows of that color showing through
|
||||
Color frontColor = Color.FromArgb(255, front); |
||||
Color backColor = Color.FromArgb(255, back); |
||||
|
||||
float frontRed = frontColor.R; |
||||
float frontGreen = frontColor.G; |
||||
float frontBlue = frontColor.B; |
||||
float backRed = backColor.R; |
||||
float backGreen = backColor.G; |
||||
float backBlue = backColor.B; |
||||
|
||||
float fRed = frontRed*alpha/255 + backRed*((float)(255-alpha)/255); |
||||
byte newRed = (byte)fRed; |
||||
float fGreen = frontGreen*alpha/255 + backGreen*((float)(255-alpha)/255); |
||||
byte newGreen = (byte)fGreen; |
||||
float fBlue = frontBlue*alpha/255 + backBlue*((float)(255-alpha)/255); |
||||
byte newBlue = (byte)fBlue; |
||||
|
||||
return Color.FromArgb(255, newRed, newGreen, newBlue); |
||||
|
||||
} |
||||
#endregion
|
||||
|
||||
#region General functions
|
||||
static public Color ColorFromPoint(Graphics g, int x, int y) |
||||
{ |
||||
IntPtr hDC = g.GetHdc(); |
||||
// Get the color of the pixel first
|
||||
uint colorref = APIsGdi.GetPixel(hDC, x, y); |
||||
byte Red = GetRValue(colorref); |
||||
byte Green = GetGValue(colorref); |
||||
byte Blue = GetBValue(colorref); |
||||
g.ReleaseHdc(hDC); |
||||
return Color.FromArgb(Red, Green, Blue); |
||||
} |
||||
|
||||
static public bool IsKnownColor(Color color, ref Color knownColor, bool useTransparent) |
||||
{ |
||||
|
||||
// Using the Color structrure "FromKnowColor" does not work if
|
||||
// we did not create the color as a known color to begin with
|
||||
// we need to compare the rgbs of both color
|
||||
Color currentColor = Color.Empty; |
||||
bool badColor = false; |
||||
for (KnownColor enumValue = 0; enumValue <= KnownColor.YellowGreen; enumValue++) |
||||
{ |
||||
currentColor = Color.FromKnownColor(enumValue); |
||||
string colorName = currentColor.Name; |
||||
if ( !useTransparent ) |
||||
badColor = (colorName == "Transparent"); |
||||
if ( color.A == currentColor.A && color.R == currentColor.R && color.G == currentColor.G |
||||
&& color.B == currentColor.B && !currentColor.IsSystemColor |
||||
&& !badColor ) |
||||
{ |
||||
knownColor = currentColor; |
||||
return true; |
||||
} |
||||
|
||||
} |
||||
return false; |
||||
|
||||
} |
||||
|
||||
static public bool IsSystemColor(Color color, ref Color knownColor) |
||||
{ |
||||
|
||||
// Using the Color structrure "FromKnowColor" does not work if
|
||||
// we did not create the color as a known color to begin with
|
||||
// we need to compare the rgbs of both color
|
||||
Color currentColor = Color.Empty; |
||||
for (KnownColor enumValue = 0; enumValue <= KnownColor.YellowGreen; enumValue++) |
||||
{ |
||||
currentColor = Color.FromKnownColor(enumValue); |
||||
string colorName = currentColor.Name; |
||||
if ( color.R == currentColor.R && color.G == currentColor.G |
||||
&& color.B == currentColor.B && currentColor.IsSystemColor ) |
||||
{ |
||||
knownColor = currentColor; |
||||
return true; |
||||
} |
||||
|
||||
} |
||||
return false; |
||||
} |
||||
|
||||
static public uint GetCOLORREF(Color color) |
||||
{ |
||||
return RGB(color.R, color.G, color.B); |
||||
} |
||||
|
||||
static public Color ColorFromRGBString(string text) |
||||
{ |
||||
|
||||
Color rgbColor = Color.Empty; |
||||
string[] RGBs = text.Split(','); |
||||
if ( RGBs.Length != 3 ) |
||||
{ |
||||
// If we don't have three pieces of information, then the
|
||||
// string is not properly formatted, inform the use
|
||||
throw new Exception("RGB color string is not well formed"); |
||||
} |
||||
|
||||
string stringR = RGBs[0]; |
||||
string stringG = RGBs[1]; |
||||
string stringB = RGBs[2]; |
||||
int R, G, B; |
||||
|
||||
try |
||||
{ |
||||
R = Convert.ToInt32(stringR); |
||||
G = Convert.ToInt32(stringG); |
||||
B = Convert.ToInt32(stringB); |
||||
if ( ( R < 0 || R > 255 ) || ( G < 0 || G > 255 ) || ( B < 0 || B > 255 ) ) |
||||
{ |
||||
throw new Exception("Out of bounds RGB value"); |
||||
} |
||||
else |
||||
{ |
||||
// Convert to color
|
||||
rgbColor = Color.FromArgb(R, G, B); |
||||
// See if we have either a web color or a systgem color
|
||||
Color knownColor = Color.Empty; |
||||
bool isKnown = ColorUtil.IsKnownColor( rgbColor, ref knownColor, true); |
||||
if ( !isKnown ) |
||||
isKnown = ColorUtil.IsSystemColor(rgbColor, ref knownColor); |
||||
if ( isKnown ) |
||||
rgbColor = knownColor; |
||||
} |
||||
} |
||||
catch ( InvalidCastException ) |
||||
{ |
||||
throw new Exception("Invalid RGB value"); |
||||
} |
||||
|
||||
return rgbColor; |
||||
} |
||||
static public Color LightColor(Color color, int inc) |
||||
{ |
||||
int red = color.R; |
||||
int green = color.G; |
||||
int blue = color.B; |
||||
|
||||
if ( red + inc <= 255 ) |
||||
red += inc; |
||||
if ( green + inc <= 255 ) |
||||
green += inc; |
||||
if ( blue + inc <= 255 ) |
||||
blue += inc; |
||||
|
||||
return Color.FromArgb(red, green, blue); |
||||
} |
||||
static public Color DarkColor(Color color, int inc) |
||||
{ |
||||
int red = color.R; |
||||
int green = color.G; |
||||
int blue = color.B; |
||||
|
||||
if ( red >= inc ) |
||||
red -= inc; |
||||
if ( green >= inc ) |
||||
green -= inc; |
||||
if ( blue >= inc ) |
||||
blue -= inc; |
||||
|
||||
return Color.FromArgb(red, green, blue); |
||||
|
||||
} |
||||
#endregion
|
||||
|
||||
#region Windows RGB related macros
|
||||
static public byte GetRValue(uint color) |
||||
{ |
||||
return (byte)color; |
||||
} |
||||
|
||||
static public byte GetGValue(uint color) |
||||
{ |
||||
return ((byte)(((short)(color)) >> 8)); |
||||
} |
||||
|
||||
static public byte GetBValue(uint color) |
||||
{ |
||||
return ((byte)((color)>>16)); |
||||
} |
||||
|
||||
static public uint RGB(int r, int g, int b) |
||||
{ |
||||
return ((uint)(((byte)(r)|((short)((byte)(g))<<8))|(((short)(byte)(b))<<16))); |
||||
|
||||
} |
||||
#endregion
|
||||
|
||||
} |
||||
} |
@ -0,0 +1,161 @@
@@ -0,0 +1,161 @@
|
||||
using System; |
||||
using System.Drawing; |
||||
using System.Drawing.Drawing2D; |
||||
|
||||
namespace System.Runtime.InteropServices.APIs |
||||
{ |
||||
/// <summary>
|
||||
/// Summary description for TextUtil.
|
||||
/// </summary>
|
||||
public class TextUtil |
||||
{ |
||||
#region Constructor
|
||||
// No need to construct this object
|
||||
private TextUtil() |
||||
{ |
||||
} |
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
public static Size GetTextSize(Graphics graphics, string text, Font font) |
||||
{ |
||||
IntPtr hdc = IntPtr.Zero; |
||||
if ( graphics != null ) |
||||
{ |
||||
// Get device context from the graphics passed in
|
||||
hdc = graphics.GetHdc(); |
||||
} |
||||
else |
||||
{ |
||||
// Get screen device context
|
||||
hdc = APIsGdi.GetDC(IntPtr.Zero); |
||||
} |
||||
|
||||
IntPtr fontHandle = font.ToHfont(); |
||||
IntPtr currentFontHandle = APIsGdi.SelectObject(hdc, fontHandle); |
||||
|
||||
APIsStructs.RECT rect = new APIsStructs.RECT(); |
||||
rect.left = 0; |
||||
rect.right = 0; |
||||
rect.top = 0; |
||||
rect.bottom = 0; |
||||
|
||||
APIsUser32.DrawText(hdc, text, text.Length, ref rect, |
||||
APIsEnums.DrawTextFormatFlags.SINGLELINE | APIsEnums.DrawTextFormatFlags.LEFT | APIsEnums.DrawTextFormatFlags.CALCRECT); |
||||
APIsGdi.SelectObject(hdc, currentFontHandle); |
||||
APIsGdi.DeleteObject(fontHandle); |
||||
|
||||
if(graphics != null) |
||||
graphics.ReleaseHdc(hdc); |
||||
else |
||||
APIsUser32.ReleaseDC(IntPtr.Zero, hdc); |
||||
|
||||
return new Size(rect.right - rect.left, rect.bottom - rect.top); |
||||
} |
||||
|
||||
public static Size GetTextSize(Graphics graphics, string text, Font font, ref Rectangle rc, APIsEnums.DrawTextFormatFlags drawFlags) |
||||
{ |
||||
IntPtr hdc = IntPtr.Zero; |
||||
if ( graphics != null ) |
||||
{ |
||||
// Get device context from the graphics passed in
|
||||
hdc = graphics.GetHdc(); |
||||
} |
||||
else |
||||
{ |
||||
// Get screen device context
|
||||
hdc = APIsGdi.GetDC(IntPtr.Zero); |
||||
} |
||||
|
||||
IntPtr fontHandle = font.ToHfont(); |
||||
IntPtr currentFontHandle = APIsGdi.SelectObject(hdc, fontHandle); |
||||
|
||||
APIsStructs.RECT rect = new APIsStructs.RECT(); |
||||
rect.left = rc.Left; |
||||
rect.right = rc.Right; |
||||
rect.top = rc.Top; |
||||
rect.bottom = rc.Bottom; |
||||
|
||||
APIsUser32.DrawText(hdc, text, text.Length, ref rect, drawFlags); |
||||
APIsGdi.SelectObject(hdc, currentFontHandle); |
||||
APIsGdi.DeleteObject(fontHandle); |
||||
|
||||
if(graphics != null) |
||||
graphics.ReleaseHdc(hdc); |
||||
else |
||||
APIsUser32.ReleaseDC(IntPtr.Zero, hdc); |
||||
|
||||
return new Size(rect.right - rect.left, rect.bottom - rect.top); |
||||
|
||||
} |
||||
|
||||
public static void DrawText(Graphics graphics, string text, Font font, Rectangle rect) |
||||
{ |
||||
IntPtr hdc = graphics.GetHdc(); |
||||
IntPtr fontHandle = font.ToHfont(); |
||||
IntPtr currentFontHandle = APIsGdi.SelectObject(hdc, fontHandle); |
||||
APIsGdi.SetBkMode(hdc, APIsEnums.BackgroundMode.TRANSPARENT); |
||||
|
||||
APIsStructs.RECT rc = new APIsStructs.RECT(); |
||||
rc.left = rect.Left; |
||||
rc.top = rect.Top; |
||||
rc.right = rc.left + rect.Width; |
||||
rc.bottom = rc.top + rect.Height; |
||||
|
||||
APIsUser32.DrawText(hdc, text, text.Length, ref rc, |
||||
APIsEnums.DrawTextFormatFlags.SINGLELINE | APIsEnums.DrawTextFormatFlags.LEFT |
||||
| APIsEnums.DrawTextFormatFlags.MODIFYSTRING | APIsEnums.DrawTextFormatFlags.WORD_ELLIPSIS); |
||||
APIsGdi.SelectObject(hdc, currentFontHandle); |
||||
APIsGdi.DeleteObject(fontHandle); |
||||
graphics.ReleaseHdc(hdc); |
||||
} |
||||
|
||||
public static void DrawText(Graphics graphics, string text, Font font, Rectangle rect, Color textColor) |
||||
{ |
||||
IntPtr hdc = graphics.GetHdc(); |
||||
IntPtr fontHandle = font.ToHfont(); |
||||
IntPtr currentFontHandle = APIsGdi.SelectObject(hdc, fontHandle); |
||||
uint colorRef = ColorUtil.GetCOLORREF(textColor); |
||||
APIsGdi.SetTextColor(hdc, colorRef); |
||||
APIsGdi.SetBkMode(hdc, APIsEnums.BackgroundMode.TRANSPARENT); |
||||
|
||||
APIsStructs.RECT rc = new APIsStructs.RECT(); |
||||
rc.left = rect.Left; |
||||
rc.top = rect.Top; |
||||
rc.right = rc.left + rect.Width; |
||||
rc.bottom = rc.top + rect.Height; |
||||
|
||||
APIsUser32.DrawText(hdc, text, text.Length, ref rc, |
||||
APIsEnums.DrawTextFormatFlags.SINGLELINE | APIsEnums.DrawTextFormatFlags.LEFT |
||||
| APIsEnums.DrawTextFormatFlags.MODIFYSTRING| APIsEnums.DrawTextFormatFlags.WORD_ELLIPSIS); |
||||
APIsGdi.SelectObject(hdc, currentFontHandle); |
||||
APIsGdi.DeleteObject(fontHandle); |
||||
graphics.ReleaseHdc(hdc); |
||||
} |
||||
|
||||
public static void DrawReverseString(Graphics g, |
||||
String drawText, |
||||
Font drawFont, |
||||
Rectangle drawRect, |
||||
Brush drawBrush, |
||||
StringFormat drawFormat) |
||||
{ |
||||
GraphicsContainer container = g.BeginContainer(); |
||||
|
||||
// The text will be rotated around the origin (0,0) and so needs moving
|
||||
// back into position by using a transform
|
||||
g.TranslateTransform(drawRect.Left * 2 + drawRect.Width, |
||||
drawRect.Top * 2 + drawRect.Height); |
||||
|
||||
// Rotate the text by 180 degress to reverse the direction
|
||||
g.RotateTransform(180); |
||||
|
||||
// Draw the string as normal and let then transforms do the work
|
||||
g.DrawString(drawText, drawFont, drawBrush, drawRect, drawFormat); |
||||
|
||||
g.EndContainer(container); |
||||
} |
||||
|
||||
#endregion
|
||||
} |
||||
} |
@ -0,0 +1,284 @@
@@ -0,0 +1,284 @@
|
||||
using System; |
||||
using System.Drawing; |
||||
using System.Drawing.Design; |
||||
using System.Collections; |
||||
using System.ComponentModel; |
||||
using System.Windows.Forms; |
||||
using System.Windows.Forms.Design; |
||||
|
||||
namespace System.Windows.Forms |
||||
{ |
||||
/// <summary>
|
||||
/// Editor for the TreeListView.Items property
|
||||
/// </summary>
|
||||
public class TreeListViewItemsEditorForm : System.Windows.Forms.Form |
||||
{ |
||||
private TreeListViewItemCollection _items; |
||||
/// <summary>
|
||||
/// Get the items that are edited in this form
|
||||
/// </summary>
|
||||
public TreeListViewItemCollection Items{get{return(_items);}} |
||||
private System.Windows.Forms.Button buttonOk; |
||||
private System.Windows.Forms.GroupBox groupBox1; |
||||
private System.Windows.Forms.TreeView treeView1; |
||||
private System.Windows.Forms.Splitter splitter1; |
||||
private System.Windows.Forms.PropertyGrid propertyGrid1; |
||||
private System.Windows.Forms.Button buttonRemove; |
||||
private System.Windows.Forms.Button buttonAdd; |
||||
private System.ComponentModel.Container components = null; |
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="collection"></param>
|
||||
public TreeListViewItemsEditorForm(TreeListViewItemCollection collection) |
||||
{ |
||||
InitializeComponent(); |
||||
_items = collection; |
||||
treeView1.SelectedNode = null; |
||||
foreach(TreeListViewItem item in _items) |
||||
{ |
||||
TreeNode node = new TreeNode(item.Text); |
||||
node.Tag = item; |
||||
treeView1.Nodes.Add(node); |
||||
AddChildren(node); |
||||
node.Expand(); |
||||
} |
||||
} |
||||
private void AddChildren(TreeNode node) |
||||
{ |
||||
TreeListViewItem tlvitem = (TreeListViewItem) node.Tag; |
||||
foreach(TreeListViewItem item in tlvitem.Items) |
||||
{ |
||||
TreeNode child = new TreeNode(item.Text); |
||||
child.Tag = item; |
||||
node.Nodes.Add(child); |
||||
AddChildren(child); |
||||
child.Expand(); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Nettoyage des ressources utilisées.
|
||||
/// </summary>
|
||||
protected override void Dispose( bool disposing ) |
||||
{ |
||||
if( disposing ) |
||||
{ |
||||
if(components != null) |
||||
{ |
||||
components.Dispose(); |
||||
} |
||||
} |
||||
base.Dispose( disposing ); |
||||
} |
||||
|
||||
#region Windows Form Designer generated code
|
||||
/// <summary>
|
||||
/// Méthode requise pour la prise en charge du concepteur - ne modifiez pas
|
||||
/// le contenu de cette méthode avec l'éditeur de code.
|
||||
/// </summary>
|
||||
private void InitializeComponent() |
||||
{ |
||||
this.buttonOk = new System.Windows.Forms.Button(); |
||||
this.groupBox1 = new System.Windows.Forms.GroupBox(); |
||||
this.propertyGrid1 = new System.Windows.Forms.PropertyGrid(); |
||||
this.buttonRemove = new System.Windows.Forms.Button(); |
||||
this.buttonAdd = new System.Windows.Forms.Button(); |
||||
this.splitter1 = new System.Windows.Forms.Splitter(); |
||||
this.treeView1 = new System.Windows.Forms.TreeView(); |
||||
this.groupBox1.SuspendLayout(); |
||||
this.SuspendLayout(); |
||||
//
|
||||
// buttonOk
|
||||
//
|
||||
this.buttonOk.Anchor = (System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right); |
||||
this.buttonOk.Location = new System.Drawing.Point(360, 344); |
||||
this.buttonOk.Name = "buttonOk"; |
||||
this.buttonOk.TabIndex = 0; |
||||
this.buttonOk.Text = "Ok"; |
||||
this.buttonOk.Click += new System.EventHandler(this.buttonOk_Click); |
||||
//
|
||||
// groupBox1
|
||||
//
|
||||
this.groupBox1.Anchor = (((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) |
||||
| System.Windows.Forms.AnchorStyles.Left) |
||||
| System.Windows.Forms.AnchorStyles.Right); |
||||
this.groupBox1.Controls.AddRange(new System.Windows.Forms.Control[] { |
||||
this.propertyGrid1, |
||||
this.buttonRemove, |
||||
this.buttonAdd, |
||||
this.splitter1, |
||||
this.treeView1}); |
||||
this.groupBox1.FlatStyle = System.Windows.Forms.FlatStyle.System; |
||||
this.groupBox1.Location = new System.Drawing.Point(8, 8); |
||||
this.groupBox1.Name = "groupBox1"; |
||||
this.groupBox1.Size = new System.Drawing.Size(428, 328); |
||||
this.groupBox1.TabIndex = 2; |
||||
this.groupBox1.TabStop = false; |
||||
//
|
||||
// propertyGrid1
|
||||
//
|
||||
this.propertyGrid1.Anchor = (((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) |
||||
| System.Windows.Forms.AnchorStyles.Left) |
||||
| System.Windows.Forms.AnchorStyles.Right); |
||||
this.propertyGrid1.CommandsVisibleIfAvailable = true; |
||||
this.propertyGrid1.LargeButtons = false; |
||||
this.propertyGrid1.LineColor = System.Drawing.SystemColors.ScrollBar; |
||||
this.propertyGrid1.Location = new System.Drawing.Point(192, 16); |
||||
this.propertyGrid1.Name = "propertyGrid1"; |
||||
this.propertyGrid1.Size = new System.Drawing.Size(232, 272); |
||||
this.propertyGrid1.TabIndex = 7; |
||||
this.propertyGrid1.Text = "propertyGrid1"; |
||||
this.propertyGrid1.ViewBackColor = System.Drawing.SystemColors.Window; |
||||
this.propertyGrid1.ViewForeColor = System.Drawing.SystemColors.WindowText; |
||||
this.propertyGrid1.PropertyValueChanged += new System.Windows.Forms.PropertyValueChangedEventHandler(this.propertyGrid1_PropertyValueChanged); |
||||
//
|
||||
// buttonRemove
|
||||
//
|
||||
this.buttonRemove.Anchor = (System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right); |
||||
this.buttonRemove.Location = new System.Drawing.Point(344, 296); |
||||
this.buttonRemove.Name = "buttonRemove"; |
||||
this.buttonRemove.TabIndex = 6; |
||||
this.buttonRemove.Text = "Remove"; |
||||
this.buttonRemove.Click += new System.EventHandler(this.buttonRemove_Click); |
||||
//
|
||||
// buttonAdd
|
||||
//
|
||||
this.buttonAdd.Anchor = (System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left); |
||||
this.buttonAdd.Location = new System.Drawing.Point(192, 296); |
||||
this.buttonAdd.Name = "buttonAdd"; |
||||
this.buttonAdd.TabIndex = 5; |
||||
this.buttonAdd.Text = "Add"; |
||||
this.buttonAdd.Click += new System.EventHandler(this.buttonAdd_Click); |
||||
//
|
||||
// splitter1
|
||||
//
|
||||
this.splitter1.Location = new System.Drawing.Point(184, 16); |
||||
this.splitter1.Name = "splitter1"; |
||||
this.splitter1.Size = new System.Drawing.Size(3, 309); |
||||
this.splitter1.TabIndex = 4; |
||||
this.splitter1.TabStop = false; |
||||
//
|
||||
// treeView1
|
||||
//
|
||||
this.treeView1.Dock = System.Windows.Forms.DockStyle.Left; |
||||
this.treeView1.ImageIndex = -1; |
||||
this.treeView1.Location = new System.Drawing.Point(3, 16); |
||||
this.treeView1.Name = "treeView1"; |
||||
this.treeView1.SelectedImageIndex = -1; |
||||
this.treeView1.Size = new System.Drawing.Size(181, 309); |
||||
this.treeView1.TabIndex = 3; |
||||
this.treeView1.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeView1_AfterSelect); |
||||
//
|
||||
// TreeListViewItemsEditorForm
|
||||
//
|
||||
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); |
||||
this.ClientSize = new System.Drawing.Size(444, 375); |
||||
this.Controls.AddRange(new System.Windows.Forms.Control[] { |
||||
this.groupBox1, |
||||
this.buttonOk}); |
||||
this.MinimumSize = new System.Drawing.Size(384, 384); |
||||
this.Name = "TreeListViewItemsEditorForm"; |
||||
this.Text = "TreeListViewItemsEditorForm"; |
||||
this.groupBox1.ResumeLayout(false); |
||||
this.ResumeLayout(false); |
||||
|
||||
} |
||||
#endregion
|
||||
|
||||
private void buttonOk_Click(object sender, System.EventArgs e) |
||||
{ |
||||
DialogResult = DialogResult.OK; |
||||
Close(); |
||||
} |
||||
|
||||
private void treeView1_AfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e) |
||||
{ |
||||
propertyGrid1.SelectedObject = (TreeListViewItem) e.Node.Tag; |
||||
} |
||||
|
||||
private void buttonRemove_Click(object sender, System.EventArgs e) |
||||
{ |
||||
if(treeView1.SelectedNode == null) return; |
||||
TreeListViewItem item = (TreeListViewItem) treeView1.SelectedNode.Tag; |
||||
item.Remove(); |
||||
treeView1.SelectedNode.Remove(); |
||||
} |
||||
|
||||
private void buttonAdd_Click(object sender, System.EventArgs e) |
||||
{ |
||||
try |
||||
{ |
||||
TreeListViewItem newitem = new TreeListViewItem("treeListView" + _items.Owner.ItemsCount.ToString()); |
||||
TreeNode node = new TreeNode(newitem.Text); |
||||
node.Tag = newitem; |
||||
if(treeView1.SelectedNode != null) |
||||
{ |
||||
TreeListViewItem item = (TreeListViewItem) treeView1.SelectedNode.Tag; |
||||
if(item.Items.Add(newitem) > -1) treeView1.SelectedNode.Nodes.Add(node); |
||||
} |
||||
else |
||||
if(_items.Add(newitem) > -1) treeView1.Nodes.Add(node); |
||||
if(node.Index > -1) treeView1.SelectedNode = node; |
||||
} |
||||
catch(Exception ex){MessageBox.Show(ex.Message);} |
||||
} |
||||
|
||||
private void propertyGrid1_PropertyValueChanged(object s, System.Windows.Forms.PropertyValueChangedEventArgs e) |
||||
{ |
||||
if(treeView1.SelectedNode == null) return; |
||||
if(e.ChangedItem.Label == "Text") |
||||
treeView1.SelectedNode.Text = (string) e.ChangedItem.Value; |
||||
} |
||||
} |
||||
/// <summary>
|
||||
/// UITypeEditor for the TreeListView.Items property
|
||||
/// </summary>
|
||||
public class TreeListViewItemsEditor : UITypeEditor |
||||
{ |
||||
private IWindowsFormsEditorService edSvc = null; |
||||
private TreeListViewItemsEditorForm editor = null; |
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
public TreeListViewItemsEditor() |
||||
{ |
||||
} |
||||
/// <summary>
|
||||
/// Shows a dropdown icon in the property editor
|
||||
/// </summary>
|
||||
/// <param name="context">The context of the editing control</param>
|
||||
/// <returns>Returns <c>UITypeEditorEditStyle.DropDown</c></returns>
|
||||
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) |
||||
{ |
||||
return UITypeEditorEditStyle.Modal; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Overrides the method used to provide basic behaviour for selecting editor.
|
||||
/// Shows our custom control for editing the value.
|
||||
/// </summary>
|
||||
/// <param name="context">The context of the editing control</param>
|
||||
/// <param name="provider">A valid service provider</param>
|
||||
/// <param name="value">The current value of the object to edit</param>
|
||||
/// <returns>The new value of the object</returns>
|
||||
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) |
||||
{ |
||||
if (context != null |
||||
&& context.Instance != null |
||||
&& provider != null) |
||||
{ |
||||
edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService)); |
||||
if(edSvc != null) |
||||
{ |
||||
editor = new TreeListViewItemsEditorForm((TreeListViewItemCollection) value); |
||||
edSvc.ShowDialog(editor); |
||||
if(editor.DialogResult == DialogResult.OK) |
||||
return(editor.Items); |
||||
} |
||||
} |
||||
return(value); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,105 @@
@@ -0,0 +1,105 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<root> |
||||
<!-- |
||||
Microsoft ResX Schema |
||||
|
||||
Version 1.3 |
||||
|
||||
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">1.3</resheader> |
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> |
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> |
||||
<data name="Name1">this is my long string</data> |
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> |
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> |
||||
[base64 mime encoded serialized .NET Framework object] |
||||
</data> |
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> |
||||
[base64 mime encoded string representing a byte array form of the .NET Framework object] |
||||
</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="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>1.3</value> |
||||
</resheader> |
||||
<resheader name="reader"> |
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> |
||||
</resheader> |
||||
<resheader name="writer"> |
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> |
||||
</resheader> |
||||
<data name="$this.GridSize" type="System.Drawing.Size, System.Drawing, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> |
||||
<value>8, 8</value> |
||||
</data> |
||||
<data name="$this.Name"> |
||||
<value>TreeListViewItemsEditorForm</value> |
||||
</data> |
||||
</root> |
@ -0,0 +1,27 @@
@@ -0,0 +1,27 @@
|
||||
using System; |
||||
|
||||
namespace System.Windows.Forms |
||||
{ |
||||
/// <summary>
|
||||
/// Interface ITreeListViewItemComparer
|
||||
/// </summary>
|
||||
public interface ITreeListViewItemComparer : System.Collections.IComparer |
||||
{ |
||||
/// <summary>
|
||||
/// Sort order
|
||||
/// </summary>
|
||||
SortOrder SortOrder |
||||
{ |
||||
get; |
||||
set; |
||||
} |
||||
/// <summary>
|
||||
/// Column for the comparison
|
||||
/// </summary>
|
||||
int Column |
||||
{ |
||||
get; |
||||
set; |
||||
} |
||||
} |
||||
} |
After Width: | Height: | Size: 894 B |
After Width: | Height: | Size: 897 B |
@ -0,0 +1,49 @@
@@ -0,0 +1,49 @@
|
||||
using System; |
||||
|
||||
namespace System.Windows.Forms |
||||
{ |
||||
/// <summary>
|
||||
/// Collection of selected items in a TreeListView
|
||||
/// </summary>
|
||||
public class SelectedTreeListViewItemCollection : ListView.SelectedListViewItemCollection |
||||
{ |
||||
#region Properties
|
||||
/// <summary>
|
||||
/// Gets a TreeListViewItem at the specified index
|
||||
/// </summary>
|
||||
new public TreeListViewItem this[int index] |
||||
{ |
||||
get{return((TreeListViewItem) base[index]);} |
||||
} |
||||
#endregion
|
||||
#region Constructor
|
||||
/// <summary>
|
||||
/// Create a new instance of a SelectedTreeListViewItemCollection
|
||||
/// </summary>
|
||||
/// <param name="TreeListView"></param>
|
||||
public SelectedTreeListViewItemCollection(TreeListView TreeListView) : base((ListView) TreeListView) |
||||
{ |
||||
} |
||||
#endregion
|
||||
#region Functions
|
||||
/// <summary>
|
||||
/// Returns true if the specified item is in the collection
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
/// <returns></returns>
|
||||
public bool Contains(TreeListViewItem item) |
||||
{ |
||||
return(base.Contains((ListViewItem) item)); |
||||
} |
||||
/// <summary>
|
||||
/// Index of an item
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
/// <returns></returns>
|
||||
public int IndexOf(TreeListViewItem item) |
||||
{ |
||||
return(base.IndexOf((ListViewItem) item)); |
||||
} |
||||
#endregion
|
||||
} |
||||
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,137 @@
@@ -0,0 +1,137 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<root> |
||||
<!-- |
||||
Microsoft ResX Schema |
||||
|
||||
Version 1.3 |
||||
|
||||
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">1.3</resheader> |
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> |
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> |
||||
<data name="Name1">this is my long string</data> |
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> |
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> |
||||
[base64 mime encoded serialized .NET Framework object] |
||||
</data> |
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> |
||||
[base64 mime encoded string representing a byte array form of the .NET Framework object] |
||||
</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="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>1.3</value> |
||||
</resheader> |
||||
<resheader name="reader"> |
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> |
||||
</resheader> |
||||
<resheader name="writer"> |
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> |
||||
</resheader> |
||||
<data name="imageList1.Location" type="System.Drawing.Point, System.Drawing, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> |
||||
<value>17, 17</value> |
||||
</data> |
||||
<data name="plusMinusImageList.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> |
||||
<value>Assembly</value> |
||||
</data> |
||||
<data name="plusMinusImageList.Location" type="System.Drawing.Point, System.Drawing, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> |
||||
<value>122, 17</value> |
||||
</data> |
||||
<data name="plusMinusImageList.ImageStream" mimetype="application/x-microsoft.net.object.binary.base64"> |
||||
<value> |
||||
AAEAAAD/////AQAAAAAAAAAMAgAAAFpTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0xLjAuMzMw |
||||
MC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZT |
||||
eXN0ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMA |
||||
AACoAwAAAk1TRnQBSQFMAgEBAgEAAQUBAAEEAQABEAEAARABAAT/ASEBEAj/AUIBTQE2BwABNgMAASgD |
||||
AAFAAwABIAMAAQEBAAEgBgABIP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8AIgCA/4AAgP+A |
||||
AID/gACA/4AADP8D6gH/A+MB/wPXAf8D1wH/A9cB/wPXAf8D1wH/A9cB/wPqHf8D6gH/A+MB/wPXAf8D |
||||
1wH/A9cB/wPXAf8D1wH/A9cB/wPxEf+AAAz/AswBmQH/A9cB/wPAAf8DsgH/A7IB/wGZAswB/wOyAf8D |
||||
sgH/A8wd/wLMAZkB/wPXAf8DwAH/A7IB/wPAAf8DsgH/A7IB/wPAAf8CzAGZEf+AAAz/AswBmQH/A+MB |
||||
/wPXAf8DzAH/AwAB/wPMAf8DzAH/A8sB/wLMAZkd/wLMAZkB/wPjAf8D1wH/A8wB/wPMAf8DzAH/A8wB |
||||
/wPLAf8CzAGZEf+AAAz/AswBmQH/A/EB/wPqAf8D6gH/AwAB/wPjAf8D1wH/A9cB/wPMAf8B8AH7Gv8C |
||||
zAGZAf8D8QH/A+oB/wPqAf8D4wH/A+MB/wPjAf8DzAH/A8wB/wPxDf+AAAz/AswBmQH/A/EB/wMAAf8D |
||||
AAH/AwAB/wMAAf8DAAH/A9cB/wPMHf8CzAGZAf8D8QH/AwAB/wMAAf8DAAH/AwAB/wMAAf8D1wH/A8wR |
||||
/4AADP8CzAGZAf8D8QH/A/EB/wPxAf8DAAH/A/EB/wPqAf8D4wH/AswBmR3/AswBmQH/A/EB/wPxAf8D |
||||
8QH/A/EB/wPxAf8D6gH/A+MB/wPMAf8B8AH7Dv+AAAz/AswBmQH/AfAB+wL/A/EF/wMAAf8B8AH7Av8D |
||||
8QH/A/EB/wPMAf8D8Rn/AswBmQH/AfAB+wL/A/EF/wHwAfsC/wPxBf8D8QH/AswBmRH/gAAM/wLMAZkB |
||||
/wHwAfsG/wHwAfsG/wHwAfsG/wHwAfsC/wPXHf8CzAGZAf8B8AH7Bv8B8AH7Bv8B8AH7Bv8B8AH7Av8D |
||||
1xH/gAAM/wPjAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8D4x3/A+MB |
||||
/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wPjEf+AAID/gACA/4AAgP+A |
||||
AAFCAU0BPgcAAT4DAAEoAwABQAMAASADAAEBAQABAQYAAQEWAAP//wAYAAs= |
||||
</value> |
||||
</data> |
||||
<data name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> |
||||
<value>False</value> |
||||
</data> |
||||
<data name="$this.Name"> |
||||
<value>TreeListView</value> |
||||
</data> |
||||
</root> |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,570 @@
@@ -0,0 +1,570 @@
|
||||
using System; |
||||
using System.Collections; |
||||
using System.ComponentModel; |
||||
|
||||
namespace System.Windows.Forms |
||||
{ |
||||
/// <summary>
|
||||
/// Represents the collection of items in a TreeListView control or in a TreeListViewItem
|
||||
/// </summary>
|
||||
public class TreeListViewItemCollection : CollectionBase |
||||
{ |
||||
/// <summary>
|
||||
/// Comparer for TreeListViewItem
|
||||
/// </summary>
|
||||
public class TreeListViewItemCollectionComparer : ITreeListViewItemComparer |
||||
{ |
||||
#region Order Property
|
||||
private SortOrder _sortorder = SortOrder.Ascending; |
||||
/// <summary>
|
||||
/// Sort order
|
||||
/// </summary>
|
||||
public SortOrder SortOrder |
||||
{ |
||||
get{return(_sortorder);} |
||||
set{_sortorder = value;} |
||||
} |
||||
private int _column; |
||||
/// <summary>
|
||||
/// Column for the comparison
|
||||
/// </summary>
|
||||
public int Column |
||||
{ |
||||
get{return(_column);} |
||||
set{_column = value;} |
||||
} |
||||
#endregion
|
||||
#region Constructor
|
||||
/// <summary>
|
||||
/// Create a new instance of Comparer
|
||||
/// </summary>
|
||||
public TreeListViewItemCollectionComparer() : this(SortOrder.Ascending, 0) |
||||
{} |
||||
/// <summary>
|
||||
/// Create a new instance of Comparer
|
||||
/// </summary>
|
||||
/// <param name="order"></param>
|
||||
public TreeListViewItemCollectionComparer(SortOrder order) : this(order, 0) |
||||
{ |
||||
SortOrder = order; |
||||
} |
||||
/// <summary>
|
||||
/// Create a new instance of Comparer
|
||||
/// </summary>
|
||||
/// <param name="order"></param>
|
||||
/// <param name="column"></param>
|
||||
public TreeListViewItemCollectionComparer(SortOrder order, int column) |
||||
{ |
||||
SortOrder = order; |
||||
_column = column; |
||||
} |
||||
#endregion
|
||||
#region Compare
|
||||
/// <summary>
|
||||
/// Compare two TreeListViewItems
|
||||
/// </summary>
|
||||
/// <param name="x"></param>
|
||||
/// <param name="y"></param>
|
||||
/// <returns></returns>
|
||||
public int Compare(object x, object y) |
||||
{ |
||||
TreeListViewItem a = (TreeListViewItem) x; |
||||
TreeListViewItem b = (TreeListViewItem) y; |
||||
int res = 1; |
||||
if(Column < a.SubItems.Count && Column < b.SubItems.Count) |
||||
res = string.CompareOrdinal(a.SubItems[Column].Text.ToUpper(), b.SubItems[Column].Text.ToUpper()); |
||||
switch(SortOrder) |
||||
{ |
||||
case SortOrder.Ascending: |
||||
return(res); |
||||
case SortOrder.Descending: |
||||
return(-res); |
||||
default: |
||||
return(1); |
||||
} |
||||
} |
||||
#endregion
|
||||
} |
||||
#region Private delegates
|
||||
private delegate void VoidHandlerSortOrder(SortOrder value); |
||||
private delegate void VoidHandler(); |
||||
private delegate void ChangeChildrenCheckStateRecursivelyHandler(CheckState state); |
||||
private delegate TreeListViewItemCollection GetCollectionHandler(); |
||||
private delegate string GetStringHandler(); |
||||
private delegate int GetIntHandler(); |
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
#region Sortable
|
||||
private bool _sortable = true; |
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the items of the collection can be reorder while the sort function is being called
|
||||
/// </summary>
|
||||
public bool Sortable |
||||
{ |
||||
get |
||||
{ |
||||
return _sortable; |
||||
} |
||||
set |
||||
{ |
||||
_sortable = value; |
||||
} |
||||
} |
||||
#endregion
|
||||
#region SortOrder
|
||||
/// <summary>
|
||||
/// Get or set the new sortorder (apply automatically the sort function
|
||||
/// if the sortorder value is changed)
|
||||
/// </summary>
|
||||
public SortOrder SortOrder |
||||
{ |
||||
get{return(Comparer.SortOrder);} |
||||
set{Comparer.SortOrder = value; |
||||
Sort(false);} |
||||
} |
||||
#endregion
|
||||
#region Comparer
|
||||
private ITreeListViewItemComparer _comparer = new TreeListViewItemCollectionComparer(SortOrder.Ascending); |
||||
/// <summary>
|
||||
/// Gets the comparer used in the Sort and Add functions
|
||||
/// </summary>
|
||||
public ITreeListViewItemComparer Comparer |
||||
{ |
||||
get{return(_comparer);} |
||||
set{_comparer = value;} |
||||
} |
||||
#endregion
|
||||
#region SortOrderRecursively
|
||||
/// <summary>
|
||||
/// Set the new sortorder (apply automatically the sort function
|
||||
/// if the sortorder value is changed) for each collection recursively
|
||||
/// </summary>
|
||||
public SortOrder SortOrderRecursively |
||||
{ |
||||
set |
||||
{ |
||||
if(TreeListView != null) |
||||
if(TreeListView.InvokeRequired) |
||||
{ |
||||
TreeListView.Invoke(new VoidHandlerSortOrder(SetSortOrderRecursively), new object[] {value}); |
||||
return; |
||||
} |
||||
SetSortOrderRecursively(value); |
||||
} |
||||
} |
||||
private void SetSortOrderRecursively(SortOrder value) |
||||
{ |
||||
SortOrder = value; |
||||
foreach(TreeListViewItem item in this) |
||||
item.Items.SortOrderRecursively = value; |
||||
} |
||||
internal SortOrder SortOrderRecursivelyWithoutSort |
||||
{ |
||||
set{if(TreeListView != null) |
||||
if(TreeListView.InvokeRequired) |
||||
throw(new Exception("Invoke Required")); |
||||
Comparer.SortOrder = value; |
||||
foreach(TreeListViewItem item in this) |
||||
item.Items.SortOrderRecursivelyWithoutSort = value;} |
||||
} |
||||
#endregion
|
||||
#region Owner
|
||||
private TreeListView _owner; |
||||
/// <summary>
|
||||
/// TreeListView control that directly contains this collection
|
||||
/// </summary>
|
||||
public TreeListView Owner{get{return(_owner);}} |
||||
#endregion
|
||||
#region Parent
|
||||
private TreeListViewItem _parent; |
||||
/// <summary>
|
||||
/// TreeListViewItem that contains this collection
|
||||
/// </summary>
|
||||
public TreeListViewItem Parent{get{return(_parent);}} |
||||
#endregion
|
||||
#region TreeListView
|
||||
/// <summary>
|
||||
/// Returns the TreeListView set in Owner or in Parent
|
||||
/// </summary>
|
||||
private TreeListView TreeListView |
||||
{ |
||||
get |
||||
{ |
||||
if(Owner != null) return(Owner); |
||||
if(Parent != null) return(Parent.ListView); |
||||
return(null); |
||||
} |
||||
} |
||||
#endregion
|
||||
#region this[]
|
||||
/// <summary>
|
||||
/// Get an item in the collection
|
||||
/// </summary>
|
||||
public virtual TreeListViewItem this[int index] |
||||
{ |
||||
get |
||||
{ |
||||
return((TreeListViewItem) this.List[index]);} |
||||
} |
||||
#endregion
|
||||
#endregion
|
||||
#region Events, Delegates, and internal calls
|
||||
#region Events
|
||||
/// <summary>
|
||||
/// Occurs when an item is added to the collection
|
||||
/// </summary>
|
||||
[Description("Occurs when an item is added to the collection.")] |
||||
public TreeListViewEventHandler ItemAdded; |
||||
/// <summary>
|
||||
/// Occurs when an item is removed from the collection
|
||||
/// </summary>
|
||||
[Description("Occurs when an item is removed from the collection.")] |
||||
public TreeListViewEventHandler ItemRemoved; |
||||
#endregion
|
||||
#region On???
|
||||
/// <summary>
|
||||
/// Raises the ItemAdded event
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
protected virtual void OnItemAdded(TreeListViewEventArgs e) |
||||
{ |
||||
if(ItemAdded != null) ItemAdded(this, e); |
||||
} |
||||
/// <summary>
|
||||
/// Raises the ItemRemoved event
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
protected virtual void OnItemRemoved(TreeListViewEventArgs e) |
||||
{ |
||||
if(ItemRemoved != null) ItemRemoved(this, e); |
||||
} |
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
/// <summary>
|
||||
/// Create a collection in the root of a TreeListView (first level items)
|
||||
/// </summary>
|
||||
/// <param name="owner"></param>
|
||||
public TreeListViewItemCollection(TreeListView owner) |
||||
{ |
||||
_owner = owner; |
||||
} |
||||
/// <summary>
|
||||
/// Create a collection within a TreeListViewItem
|
||||
/// </summary>
|
||||
/// <param name="parent"></param>
|
||||
public TreeListViewItemCollection(TreeListViewItem parent) |
||||
{ |
||||
_parent = parent; |
||||
} |
||||
/// <summary>
|
||||
/// Create a free TreeListViewItemCollection (items will not be
|
||||
/// displayed in a TreeListView
|
||||
/// </summary>
|
||||
public TreeListViewItemCollection() |
||||
{ |
||||
} |
||||
#endregion
|
||||
|
||||
#region Sort Functions
|
||||
/// <summary>
|
||||
/// Transforms the collection to an array
|
||||
/// </summary>
|
||||
public TreeListViewItem[] ToArray() |
||||
{ |
||||
if(TreeListView != null) |
||||
if(TreeListView.InvokeRequired) |
||||
throw(new Exception("Invoke required")); |
||||
int size = this.Count; |
||||
TreeListViewItem[] eltsArray = new TreeListViewItem[size]; |
||||
for(int i = 0 ; i < size ; i++) |
||||
eltsArray[i] = this[i]; |
||||
return(eltsArray); |
||||
} |
||||
/// <summary>
|
||||
/// Sort the items in this collection (recursively or not)
|
||||
/// </summary>
|
||||
/// <param name="recursively">Recursively</param>
|
||||
public void Sort(bool recursively) |
||||
{ |
||||
if(TreeListView != null) TreeListView.BeginUpdate(); |
||||
SortInternal(recursively); |
||||
if(TreeListView != null) TreeListView.EndUpdate(); |
||||
} |
||||
internal void SortInternal(bool recursively) |
||||
{ |
||||
if(TreeListView != null) |
||||
if(TreeListView.InvokeRequired) |
||||
throw(new Exception("Invoke required")); |
||||
if(_sortable) |
||||
{ |
||||
// Gets an array of the items
|
||||
TreeListViewItem[] thisarray = ToArray(); |
||||
// Removes the items
|
||||
ClearInternal(); |
||||
// Adds the items
|
||||
foreach(TreeListViewItem item in thisarray) |
||||
Add(item); |
||||
} |
||||
if(recursively) |
||||
foreach(TreeListViewItem item in this) |
||||
item.Items.SortInternal(true); |
||||
} |
||||
#endregion
|
||||
#region Add Function
|
||||
/// <summary>
|
||||
/// Returns true if this collection contains an item
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
/// <returns></returns>
|
||||
public virtual bool Contains(TreeListViewItem item) |
||||
{ |
||||
if(TreeListView != null) |
||||
if(TreeListView.InvokeRequired) |
||||
throw(new Exception("Invoke required")); |
||||
bool res = false; |
||||
foreach(TreeListViewItem elt in this) |
||||
if(item == elt) |
||||
{ |
||||
res = true; |
||||
break; |
||||
} |
||||
return(res); |
||||
} |
||||
private bool ListViewContains(TreeListViewItem item) |
||||
{ |
||||
if(TreeListView == null) return(false); |
||||
if(TreeListView.InvokeRequired) |
||||
throw(new Exception("Invoke required")); |
||||
ListView listview = (ListView) TreeListView; |
||||
ListViewItem listviewitem = (ListViewItem) item; |
||||
try{ |
||||
foreach(ListViewItem temp in listview.Items) |
||||
if(temp == listviewitem) return(true);} |
||||
catch{} |
||||
return(false); |
||||
} |
||||
/// <summary>
|
||||
/// Adds an item in the collection and in the TreeListView
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
/// <returns>Index of the item in the collection</returns>
|
||||
public virtual int Add(TreeListViewItem item) |
||||
{ |
||||
if(TreeListView != null) |
||||
if(TreeListView.InvokeRequired) |
||||
throw(new Exception("Invoke required")); |
||||
// Do not add the item if the collection owns a TreeListView recursively
|
||||
// and the item already owns a TreeListView
|
||||
if(TreeListView != null && item.ListView != null) |
||||
throw(new Exception("The Item is already in a TreeListView")); |
||||
int index = GetInsertCollectionIndex(item); |
||||
if(index == -1) return(-1); |
||||
if(Parent != null) item.SetParent(Parent); |
||||
item.Items.Comparer = this.Comparer; |
||||
int treelistviewindex = GetInsertTreeListViewIndex(item, index); |
||||
// Insert in the ListView
|
||||
if(treelistviewindex > -1) |
||||
{ |
||||
ListView listview = (ListView) TreeListView; |
||||
listview.Items.Insert(treelistviewindex, (ListViewItem) item); |
||||
if(item.IsExpanded) item.Expand(); |
||||
item.SetIndentation(); |
||||
} |
||||
// Insert in this collection
|
||||
if(index > -1) List.Insert(index, item); |
||||
if(index > -1) OnItemAdded(new TreeListViewEventArgs(item, TreeListViewAction.Unknown)); |
||||
if(Count == 1 && TreeListView != null && Parent != null) |
||||
if(Parent.Visible) Parent.Redraw(); |
||||
return(index); |
||||
} |
||||
/// <summary>
|
||||
/// Adds an item in the collection and in the TreeListView
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="imageindex"></param>
|
||||
/// <returns></returns>
|
||||
public virtual TreeListViewItem Add(string value, int imageindex) |
||||
{ |
||||
TreeListViewItem item = new TreeListViewItem(value, imageindex); |
||||
Add(item); |
||||
return(item); |
||||
} |
||||
/// <summary>
|
||||
/// Adds an item in the collection and in the TreeListView
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public virtual TreeListViewItem Add(string value) |
||||
{ |
||||
TreeListViewItem item = new TreeListViewItem(value); |
||||
Add(item); |
||||
return(item); |
||||
} |
||||
/// <summary>
|
||||
/// Adds a collection to this collection
|
||||
/// </summary>
|
||||
/// <param name="collection"></param>
|
||||
public void AddRange(TreeListViewItemCollection collection) |
||||
{ |
||||
if(TreeListView != null) TreeListView.BeginUpdate(); |
||||
AddRangeInternal(collection); |
||||
if(TreeListView != null) TreeListView.BeginUpdate(); |
||||
} |
||||
internal void AddRangeInternal(TreeListViewItemCollection collection) |
||||
{ |
||||
foreach(TreeListViewItem item in collection) |
||||
Add(item); |
||||
} |
||||
#endregion
|
||||
#region Remove & Clear Functions
|
||||
/// <summary>
|
||||
/// Removes each node of the collection
|
||||
/// </summary>
|
||||
public new void Clear() |
||||
{ |
||||
TreeListView treelistview = this.TreeListView; |
||||
if(treelistview != null) treelistview.BeginUpdate(); |
||||
ClearInternal(); |
||||
if(treelistview != null) treelistview.EndUpdate(); |
||||
} |
||||
internal void ClearInternal() |
||||
{ |
||||
if(TreeListView != null) |
||||
if(TreeListView.InvokeRequired) |
||||
throw(new Exception("Invoke required")); |
||||
while(this.Count > 0) this.RemoveAtInternal(0); |
||||
} |
||||
/// <summary>
|
||||
/// Remove an item from the collection and the TreeListView
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
public virtual void Remove(TreeListViewItem item) |
||||
{ |
||||
TreeListView treelistview = this.TreeListView; |
||||
if(treelistview != null) treelistview.BeginUpdate(); |
||||
RemoveInternal(item); |
||||
if(treelistview != null) treelistview.EndUpdate(); |
||||
} |
||||
internal void RemoveInternal(TreeListViewItem item) |
||||
{ |
||||
if(TreeListView != null) |
||||
if(TreeListView.InvokeRequired) |
||||
throw(new Exception("Invoke required")); |
||||
int index = GetIndexOf(item); |
||||
if(index == -1) return; |
||||
RemoveAtInternal(index); |
||||
} |
||||
/// <summary>
|
||||
/// Gets the index of an item in the collection
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
/// <returns></returns>
|
||||
public int GetIndexOf(TreeListViewItem item) |
||||
{ |
||||
if(TreeListView != null) |
||||
if(TreeListView.InvokeRequired) |
||||
throw(new Exception("Invoke required")); |
||||
int index = -1; |
||||
for(int i = 0 ; i < this.Count ; i++) |
||||
if(this[i] == item) {index = i; break;} |
||||
return(index); |
||||
} |
||||
/// <summary>
|
||||
/// Remove an item from the collection and the TreeListView
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
public new void RemoveAt(int index) |
||||
{ |
||||
TreeListView treelistview = this.TreeListView; |
||||
if(treelistview != null) treelistview.BeginUpdate(); |
||||
RemoveAtInternal(index); |
||||
if(treelistview != null) treelistview.EndUpdate(); |
||||
} |
||||
internal void RemoveAtInternal(int index) |
||||
{ |
||||
if(TreeListView != null) |
||||
if(TreeListView.InvokeRequired) |
||||
throw(new Exception("Invoke required")); |
||||
TreeListViewItem item = this[index]; |
||||
if(this[index].Visible && this.TreeListView != null) item.Hide(); |
||||
List.RemoveAt(index); |
||||
item.SetParent(null); |
||||
// Redraw parent if no more children
|
||||
if(Count == 0 && TreeListView != null && Parent != null) |
||||
Parent.Redraw(); |
||||
// Redraw new last item
|
||||
if(Count > 0 && TreeListView != null && index == Count) |
||||
this[index-1].Redraw(); |
||||
OnItemRemoved(new TreeListViewEventArgs(item, TreeListViewAction.Unknown)); |
||||
} |
||||
#endregion
|
||||
#region Internal Functions
|
||||
private int GetInsertTreeListViewIndex(TreeListViewItem item, int collectionindex) |
||||
{ |
||||
if(TreeListView == null) return(-1); |
||||
if(TreeListView.InvokeRequired) |
||||
throw(new Exception("Invoke required")); |
||||
if(Owner != null) |
||||
{ |
||||
int a = 0; |
||||
a++; |
||||
} |
||||
int index = -1; |
||||
// First level item (no parent)
|
||||
if(Owner != null && collectionindex != -1) |
||||
{ |
||||
if(collectionindex == 0) index = 0; |
||||
else index = |
||||
this[collectionindex - 1].LastChildIndexInListView + 1; |
||||
} |
||||
else if(Parent != null && collectionindex != -1) |
||||
{ |
||||
if(!Parent.Visible || !Parent.IsExpanded) index = -1; |
||||
else |
||||
{ |
||||
if(collectionindex == 0) index = Parent.Index + 1; |
||||
else index = |
||||
Parent.Items[collectionindex - 1].LastChildIndexInListView + 1; |
||||
} |
||||
} |
||||
return(index); |
||||
} |
||||
private int GetInsertCollectionIndex(TreeListViewItem item) |
||||
{ |
||||
if(TreeListView != null) |
||||
if(TreeListView.InvokeRequired) |
||||
throw(new Exception("Invoke required")); |
||||
int index = -1; |
||||
if(!_sortable) index = Count; |
||||
else if(!Contains(item) && !ListViewContains(item)) |
||||
{ |
||||
switch(SortOrder) |
||||
{ |
||||
// No sortorder -> at the end of the collection
|
||||
case System.Windows.Forms.SortOrder.None: |
||||
index = this.Count; |
||||
break; |
||||
default: |
||||
for(int i = 0 ; i < this.Count ; i++) |
||||
{ |
||||
// Change the index for the compare if the order is descending
|
||||
int indexcompare = i; |
||||
int comp = Comparer.Compare(item, this[indexcompare]); |
||||
if(comp <= 0) |
||||
{ |
||||
index = indexcompare; |
||||
break; |
||||
} |
||||
} |
||||
index = index == -1 ? this.Count : index; |
||||
break; |
||||
} |
||||
} |
||||
return(index); |
||||
} |
||||
#endregion
|
||||
} |
||||
} |
@ -0,0 +1,161 @@
@@ -0,0 +1,161 @@
|
||||
using System; |
||||
using System.Collections; |
||||
using System.ComponentModel; |
||||
using System.Drawing; |
||||
using System.Data; |
||||
using System.Windows.Forms; |
||||
using System.Runtime.InteropServices.APIs; |
||||
using System.Runtime.InteropServices; |
||||
|
||||
namespace System.Windows.Forms |
||||
{ |
||||
internal class CustomEdit : NativeWindow, IWin32Window |
||||
{ |
||||
#region Properties
|
||||
private TreeListViewItemEditControlHandle _editorhandle; |
||||
private EditItemInformations _informations; |
||||
private Control _editor; |
||||
new public IntPtr Handle |
||||
{ |
||||
get{return base.Handle;} |
||||
} |
||||
private TreeListView _treelistview; |
||||
#endregion
|
||||
#region Constructor & Destructor
|
||||
private CustomEdit(){} |
||||
public CustomEdit(IntPtr handle, TreeListView treelistview, Control editor) |
||||
{ |
||||
_treelistview = treelistview; |
||||
_informations = _treelistview.EditedItem; |
||||
if(editor == null) _editor = new TextBox(); |
||||
else _editor = editor; |
||||
_editor.Hide(); |
||||
if(!_treelistview.Controls.Contains(_editor)) |
||||
_treelistview.Controls.Add(_editor); |
||||
_editorhandle = new TreeListViewItemEditControlHandle(_treelistview, _editor, this); |
||||
AssignHandle(handle); |
||||
} |
||||
#endregion
|
||||
|
||||
#region Functions
|
||||
public void ShowEditControl() |
||||
{ |
||||
if(_treelistview.FocusedItem == null) return; |
||||
ListViewItem item = (ListViewItem) _treelistview.EditedItem.Item; |
||||
Rectangle rec = _treelistview.EditedItem.ColumnIndex > 0 ? |
||||
_treelistview.GetSubItemRect(item.Index, _treelistview.EditedItem.ColumnIndex) : |
||||
_treelistview.GetItemRect(item.Index, ItemBoundsPortion.Label); |
||||
_editor.Size = rec.Size; |
||||
_editor.Location = rec.Location; |
||||
_editor.Top--; |
||||
_editor.Show(); |
||||
_editor.Text = item.SubItems[_treelistview.EditedItem.ColumnIndex].Text; |
||||
_editor.Focus(); |
||||
} |
||||
public void HideEditControl() |
||||
{ |
||||
_editor.Hide(); |
||||
ReleaseHandle(); |
||||
_editorhandle.ReleaseHandle(); |
||||
} |
||||
#endregion
|
||||
|
||||
#region WndProc
|
||||
public void SendMessage(ref Message m) |
||||
{ |
||||
WndProc(ref m); |
||||
} |
||||
protected override void WndProc(ref Message m) |
||||
{ |
||||
switch(m.Msg) |
||||
{ |
||||
case (int)APIsEnums.WindowMessages.SHOWWINDOW: |
||||
bool show = m.WParam != IntPtr.Zero; |
||||
if(show) ShowEditControl(); |
||||
else HideEditControl(); |
||||
return; |
||||
} |
||||
} |
||||
#endregion
|
||||
} |
||||
internal class TreeListViewItemEditControlHandle : NativeWindow, IWin32Window |
||||
{ |
||||
#region Properties
|
||||
private CustomEdit _customedit; |
||||
private Control _control; |
||||
private TreeListView _treelistview; |
||||
new public IntPtr Handle |
||||
{ |
||||
get{return base.Handle;} |
||||
} |
||||
#endregion
|
||||
#region Constructor / Destructor
|
||||
public TreeListViewItemEditControlHandle(TreeListView treelistview, Control control, CustomEdit customedit) |
||||
{ |
||||
_control = control; |
||||
_treelistview = treelistview; |
||||
_customedit = customedit; |
||||
if(!control.Created) control.CreateControl(); |
||||
AssignHandle(control.Handle); |
||||
} |
||||
#endregion
|
||||
|
||||
#region End edit
|
||||
private void EndEdit(bool Cancel) |
||||
{ |
||||
if(!_treelistview.InEdit) return; |
||||
_treelistview.ExitEdit(Cancel, _control.Text); |
||||
} |
||||
#endregion
|
||||
#region OnKillFocus
|
||||
private bool OnKillFocus(Message m) |
||||
{ |
||||
// If the control is a combobox don't end edit if the handle is a handle
|
||||
// of one of the sub controls of the combobox
|
||||
if(!(_control is ComboBox)) return true; |
||||
APIsStructs.PCOMBOBOXINFO info = new APIsStructs.PCOMBOBOXINFO(); |
||||
info.cbSize = (uint)Marshal.SizeOf(typeof(APIsStructs.PCOMBOBOXINFO)); |
||||
if(!APIsUser32.GetComboBoxInfo(_control.Handle, ref info)) return true; |
||||
if(m.WParam == info.hwndCombo || m.WParam == info.hwndItem || m.WParam == info.hwndList) |
||||
{ |
||||
ReleaseHandle(); |
||||
AssignHandle(m.WParam); |
||||
return false; |
||||
} |
||||
return true; |
||||
} |
||||
#endregion
|
||||
#region Wndproc
|
||||
protected override void WndProc(ref Message m) |
||||
{ |
||||
switch(m.Msg) |
||||
{ |
||||
case (int) APIsEnums.WindowMessages.KEYDOWN: |
||||
Keys key = (Keys)(int) m.WParam; |
||||
if(key != Keys.Return && key != Keys.Escape) break; |
||||
bool Cancel = key != Keys.Enter; |
||||
EndEdit(Cancel); |
||||
return; |
||||
case (int) APIsEnums.WindowMessages.KILLFOCUS: |
||||
if(OnKillFocus(m)) |
||||
{ |
||||
EndEdit(!(_control is ComboBox && _treelistview.EditedItem.Label != _control.Text)); |
||||
return; |
||||
} |
||||
break; |
||||
} |
||||
base.WndProc(ref m); |
||||
} |
||||
private int HighOrder(IntPtr Param) |
||||
{ |
||||
int intparam = Param.ToInt32(); |
||||
return (intparam >> 16) & 0x0000ffff; |
||||
} |
||||
private int LowOrder(IntPtr Param) |
||||
{ |
||||
int intparam = Param.ToInt32(); |
||||
return intparam & 0x0000ffff; |
||||
} |
||||
#endregion
|
||||
} |
||||
} |
@ -0,0 +1,42 @@
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?> |
||||
<root> |
||||
<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="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" /> |
||||
<xsd:attribute name="type" type="xsd:string" /> |
||||
<xsd:attribute name="mimetype" type="xsd:string" /> |
||||
</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>1.0.0.0</value> |
||||
</resheader> |
||||
<resheader name="Reader"> |
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> |
||||
</resheader> |
||||
<resheader name="Writer"> |
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3102.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> |
||||
</resheader> |
||||
</root> |
@ -0,0 +1,77 @@
@@ -0,0 +1,77 @@
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
<PropertyGroup> |
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> |
||||
<ProductVersion>8.0.41115</ProductVersion> |
||||
<SchemaVersion>2.0</SchemaVersion> |
||||
<ProjectGuid>{B08385CD-F0CC-488C-B4F4-EEB34B6D2688}</ProjectGuid> |
||||
<OutputType>Library</OutputType> |
||||
<RootNamespace>TreeListView</RootNamespace> |
||||
<AssemblyName>TreeListView</AssemblyName> |
||||
<WarningLevel>4</WarningLevel> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> |
||||
<DebugSymbols>true</DebugSymbols> |
||||
<DebugType>full</DebugType> |
||||
<Optimize>false</Optimize> |
||||
<OutputPath>..\..\..\..\..\..\AddIns\AddIns\Misc\Debugger\</OutputPath> |
||||
<DefineConstants>DEBUG;TRACE</DefineConstants> |
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> |
||||
<DebugType>pdbonly</DebugType> |
||||
<Optimize>true</Optimize> |
||||
<OutputPath>..\..\..\..\..\..\AddIns\AddIns\Misc\Debugger\</OutputPath> |
||||
<DefineConstants>TRACE</DefineConstants> |
||||
</PropertyGroup> |
||||
<ItemGroup> |
||||
<Reference Include="System" /> |
||||
<Reference Include="System.Data" /> |
||||
<Reference Include="System.Drawing" /> |
||||
<Reference Include="System.Windows.Forms" /> |
||||
<Reference Include="System.Xml" /> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<Compile Include="Src\APIs\APIsClipboard.cs" /> |
||||
<Compile Include="Src\APIs\APIsComctl32.cs" /> |
||||
<Compile Include="Src\APIs\APIsEnums.cs" /> |
||||
<Compile Include="Src\APIs\APIsGdi.cs" /> |
||||
<Compile Include="Src\APIs\APIsMenu.cs" /> |
||||
<Compile Include="Src\APIs\APIsShell.cs" /> |
||||
<Compile Include="Src\APIs\APIsShlwapi.cs" /> |
||||
<Compile Include="Src\APIs\APIsStructs.cs" /> |
||||
<Compile Include="Src\APIs\APIsUser32.cs" /> |
||||
<Compile Include="Src\APIs\APIsUxTheme.cs" /> |
||||
<Compile Include="Src\APIs\APIsWndProc.cs" /> |
||||
<Compile Include="Src\APIs\ColorUtil.cs" /> |
||||
<Compile Include="Src\APIs\COMInterfaces.cs" /> |
||||
<Compile Include="Src\APIs\TextUtil.cs" /> |
||||
<Compile Include="Src\TreeListView\AssemblyInfo.cs" /> |
||||
<Compile Include="Src\TreeListView\Forms\TreeListViewItemsEditor.cs"> |
||||
<SubType>Form</SubType> |
||||
</Compile> |
||||
<Compile Include="Src\TreeListView\ITreeListViewItemComparer.cs" /> |
||||
<Compile Include="Src\TreeListView\SelectedTreeListViewItemCollection.cs" /> |
||||
<Compile Include="Src\TreeListView\TreeListView.cs" /> |
||||
<Compile Include="Src\TreeListView\TreeListViewItem.cs" /> |
||||
<Compile Include="Src\TreeListView\TreeListViewItemCollection.cs" /> |
||||
<Compile Include="Src\TreeListView\TreeListViewSubItemEdit.cs" /> |
||||
<EmbeddedResource Include="Resources\System.Windows.Forms.TreeListView.resources" /> |
||||
<EmbeddedResource Include="Src\TreeListView\Forms\TreeListViewItemsEditor.resx"> |
||||
<DependentUpon>TreeListViewItemsEditor.cs</DependentUpon> |
||||
</EmbeddedResource> |
||||
<EmbeddedResource Include="Src\TreeListView\TreeListView.resx"> |
||||
<DependentUpon>TreeListView.cs</DependentUpon> |
||||
</EmbeddedResource> |
||||
<EmbeddedResource Include="Src\TreeListView\TreeListViewSubItemEdit.resx"> |
||||
<DependentUpon>TreeListViewSubItemEdit.cs</DependentUpon> |
||||
</EmbeddedResource> |
||||
<None Include="Doc\Readme.txt" /> |
||||
<EmbeddedResource Include="Src\TreeListView\Icons\Minus.gif" /> |
||||
<EmbeddedResource Include="Src\TreeListView\Icons\Plus.gif" /> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<Folder Include="Configuration\" /> |
||||
</ItemGroup> |
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" /> |
||||
</Project> |
@ -0,0 +1,7 @@
@@ -0,0 +1,7 @@
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
<PropertyGroup> |
||||
<LastOpenVersion>8.0.41115</LastOpenVersion> |
||||
<ProjectView>ShowAllFiles</ProjectView> |
||||
<ProjectTrust>0</ProjectTrust> |
||||
</PropertyGroup> |
||||
</Project> |
Loading…
Reference in new issue