├── .gitattributes
├── .gitignore
├── CodePreviewHandler.cs
├── CodePreviewHandler.csproj
├── CodePreviewHandler.sln
├── CodePreviewHandlerSetup
├── CodePreviewHandlerSetup.isl
├── CodePreviewHandlerSetup.isl.774
└── CodePreviewHandlerSetup.isproj
├── CppFormat.cs
├── CsharpFormat.cs
├── CssFormat.cs
├── HtmlViewer
├── Element.cs
├── FontUnit.cs
├── HtmlCommandInfo.cs
├── HtmlControl.cs
├── HtmlDocument.cs
├── HtmlEditor.cs
├── HtmlFontSize.cs
├── HtmlFormat.cs
├── HtmlSelection.cs
├── HtmlSelectionType.cs
├── HtmlTextFormatting.cs
├── Interop.cs
└── MSHTMLSite.cs
├── Installer.cs
├── Libraries
├── CSharpFormat.dll
└── TimHeuer.ManagedPreviewHandler.dll
├── Properties
├── AssemblyInfo.cs
├── Resources.Designer.cs
└── Resources.resx
├── README.md
├── Registration.cs
└── UpgradeLog.htm
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 | *.sln merge=union
7 | *.csproj merge=union
8 | *.vbproj merge=union
9 | *.fsproj merge=union
10 | *.dbproj merge=union
11 |
12 | # Standard to msysgit
13 | *.doc diff=astextplain
14 | *.DOC diff=astextplain
15 | *.docx diff=astextplain
16 | *.DOCX diff=astextplain
17 | *.dot diff=astextplain
18 | *.DOT diff=astextplain
19 | *.pdf diff=astextplain
20 | *.PDF diff=astextplain
21 | *.rtf diff=astextplain
22 | *.RTF diff=astextplain
23 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | #################
2 | ## THIS PROJECT SPECIFICS
3 | #################
4 | CodePreviewHandlerSetup/CodePreviewHandlerSetup/
5 |
6 | #################
7 | ## Eclipse
8 | #################
9 |
10 | *.pydevproject
11 | .project
12 | .metadata
13 | bin/
14 | tmp/
15 | *.tmp
16 | *.bak
17 | *.swp
18 | *~.nib
19 | local.properties
20 | .classpath
21 | .settings/
22 | .loadpath
23 |
24 | # External tool builders
25 | .externalToolBuilders/
26 |
27 | # Locally stored "Eclipse launch configurations"
28 | *.launch
29 |
30 | # CDT-specific
31 | .cproject
32 |
33 | # PDT-specific
34 | .buildpath
35 |
36 |
37 | #################
38 | ## Visual Studio
39 | #################
40 |
41 | ## Ignore Visual Studio temporary files, build results, and
42 | ## files generated by popular Visual Studio add-ons.
43 |
44 | # User-specific files
45 | *.suo
46 | *.user
47 | *.sln.docstates
48 |
49 | # Build results
50 | [Dd]ebug/
51 | [Rr]elease/
52 | *_i.c
53 | *_p.c
54 | *.ilk
55 | *.meta
56 | *.obj
57 | *.pch
58 | *.pdb
59 | *.pgc
60 | *.pgd
61 | *.rsp
62 | *.sbr
63 | *.tlb
64 | *.tli
65 | *.tlh
66 | *.tmp
67 | *.vspscc
68 | .builds
69 | *.dotCover
70 |
71 | ## TODO: If you have NuGet Package Restore enabled, uncomment this
72 | #packages/
73 |
74 | # Visual C++ cache files
75 | ipch/
76 | *.aps
77 | *.ncb
78 | *.opensdf
79 | *.sdf
80 |
81 | # Visual Studio profiler
82 | *.psess
83 | *.vsp
84 |
85 | # ReSharper is a .NET coding add-in
86 | _ReSharper*
87 |
88 | # Installshield output folder
89 | [Ee]xpress
90 |
91 | # DocProject is a documentation generator add-in
92 | DocProject/buildhelp/
93 | DocProject/Help/*.HxT
94 | DocProject/Help/*.HxC
95 | DocProject/Help/*.hhc
96 | DocProject/Help/*.hhk
97 | DocProject/Help/*.hhp
98 | DocProject/Help/Html2
99 | DocProject/Help/html
100 |
101 | # Click-Once directory
102 | publish
103 |
104 | # Others
105 | [Bb]in
106 | [Oo]bj
107 | sql
108 | TestResults
109 | *.Cache
110 | ClientBin
111 | stylecop.*
112 | ~$*
113 | *.dbmdl
114 | Generated_Code #added for RIA/Silverlight projects
115 |
116 | # Backup & report files from converting an old project file to a newer
117 | # Visual Studio version. Backup files are not needed, because we have git ;-)
118 | _UpgradeReport_Files/
119 | Backup*/
120 | UpgradeLog*.XML
121 |
122 |
123 |
124 | ############
125 | ## Windows
126 | ############
127 |
128 | # Windows image file caches
129 | Thumbs.db
130 |
131 | # Folder config file
132 | Desktop.ini
133 |
134 |
135 | #############
136 | ## Python
137 | #############
138 |
139 | *.py[co]
140 |
141 | # Packages
142 | *.egg
143 | *.egg-info
144 | dist
145 | build
146 | eggs
147 | parts
148 | bin
149 | var
150 | sdist
151 | develop-eggs
152 | .installed.cfg
153 |
154 | # Installer logs
155 | pip-log.txt
156 |
157 | # Unit test / coverage reports
158 | .coverage
159 | .tox
160 |
161 | #Translations
162 | *.mo
163 |
164 | #Mr Developer
165 | .mr.developer.cfg
166 |
167 | # Mac crap
168 | .DS_Store
169 |
--------------------------------------------------------------------------------
/CodePreviewHandler.cs:
--------------------------------------------------------------------------------
1 | // timheuer.com
2 | // adapted from the MSDN Magazine samples January 2007 VOL 22 NO 1 edition
3 |
4 | using System.IO;
5 | using System.Runtime.InteropServices;
6 | using System.Windows.Forms;
7 | using TimHeuer.ManagedPreviewHandler;
8 | using TimHeuer.PreviewHandlers.Properties;
9 |
10 | namespace TimHeuer.PreviewHandlers
11 | {
12 | [PreviewHandler("Source Code Preview Handler", ".json;.yml;.yaml;.cs;.vb;.sql;.js;.xaml;.xml;.uix;.htm;.html;.cpp;.h;.hpp;.targets;.target", "{93E38957-78C4-40e2-9B1D-E202B43C6D23}")]
13 | [ProgId("TimHeuer.PreviewHandlers.CodePreviewHandler")]
14 | [Guid("0E1B4233-AEB5-4c5b-BF31-21766492B301")]
15 | [ClassInterface(ClassInterfaceType.None)]
16 | [ComVisible(true)]
17 | public sealed class CodePreviewHandler : FileBasedPreviewHandler
18 | {
19 | protected override PreviewHandlerControl CreatePreviewHandlerControl()
20 | {
21 | return new CodePreviewHandlerControl();
22 | }
23 |
24 | private sealed class CodePreviewHandlerControl : FileBasedPreviewHandlerControl
25 | {
26 | public override void Load(FileInfo file)
27 | {
28 | StreamReader rdr = file.OpenText();
29 | string previewCode = rdr.ReadToEnd();
30 | string formattedCode = FormatCode(previewCode, file.Extension.ToLowerInvariant());
31 |
32 | HtmlApp.Html.HtmlControl html = new HtmlApp.Html.HtmlControl();
33 | html.LoadHtml(string.Format("
{1}", Resources.CssString, formattedCode));
34 | html.Dock = DockStyle.Fill;
35 |
36 | Controls.Add(html);
37 | }
38 |
39 | private string FormatCode(string sourceCode, string codeType)
40 | {
41 | string formatted = string.Empty;
42 |
43 | switch (codeType)
44 | {
45 | case ".h":
46 | case ".cpp":
47 | case ".hpp":
48 | CppFormat cpp = new CppFormat();
49 | formatted = cpp.FormatCode(sourceCode);
50 | break;
51 | case ".cs":
52 | CSharpFormat cs = new CSharpFormat();
53 | formatted = cs.FormatCode(sourceCode);
54 | break;
55 | case ".vb":
56 | Manoli.Utils.CSharpFormat.VisualBasicFormat vb = new Manoli.Utils.CSharpFormat.VisualBasicFormat();
57 | formatted = vb.FormatCode(sourceCode);
58 | break;
59 | case ".js":
60 | Manoli.Utils.CSharpFormat.JavaScriptFormat js = new Manoli.Utils.CSharpFormat.JavaScriptFormat();
61 | formatted = js.FormatCode(sourceCode);
62 | break;
63 | case ".sql":
64 | Manoli.Utils.CSharpFormat.TsqlFormat sql = new Manoli.Utils.CSharpFormat.TsqlFormat();
65 | formatted = sql.FormatCode(sourceCode);
66 | break;
67 | case ".xaml":
68 | case ".xml":
69 | case ".html":
70 | case ".htm":
71 | case ".target":
72 | case ".targets":
73 | case ".uix":
74 | Manoli.Utils.CSharpFormat.HtmlFormat xml = new Manoli.Utils.CSharpFormat.HtmlFormat();
75 | formatted = xml.FormatCode(sourceCode);
76 | break;
77 | case ".json":
78 | case ".yml":
79 | case ".yaml":
80 | Manoli.Utils.CSharpFormat.SourceFormat src = new Manoli.Utils.CSharpFormat.MshFormat();
81 | formatted = src.FormatCode(sourceCode);
82 | break;
83 | }
84 |
85 | return formatted;
86 | }
87 | }
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/CodePreviewHandler.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 8.0.50727
7 | 2.0
8 | {2B886813-EC35-476B-B14C-BC6F0459BEC6}
9 | Library
10 | Properties
11 | TimHeuer.PreviewHandlers
12 | TimHeuer.CodePreviewHandler
13 | false
14 |
15 |
16 | v2.0
17 |
18 |
19 |
20 |
21 | 2.0
22 | publish\
23 | true
24 | Disk
25 | false
26 | Foreground
27 | 7
28 | Days
29 | false
30 | false
31 | true
32 | 0
33 | 1.0.0.%2a
34 | false
35 | false
36 | true
37 |
38 |
39 | true
40 | full
41 | false
42 | bin\Debug\
43 | DEBUG;TRACE
44 | prompt
45 | 4
46 |
47 |
48 | pdbonly
49 | true
50 | bin\Release\
51 | TRACE
52 | prompt
53 | 4
54 |
55 |
56 |
57 | False
58 | Libraries\CSharpFormat.dll
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 | False
68 | Libraries\TimHeuer.ManagedPreviewHandler.dll
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 | Component
81 |
82 |
83 |
84 | Component
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 | Component
95 |
96 |
97 |
98 | True
99 | True
100 | Resources.resx
101 |
102 |
103 |
104 |
105 |
106 | Designer
107 | ResXFileCodeGenerator
108 | Resources.Designer.cs
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 | False
120 | .NET Framework 3.5 SP1 Client Profile
121 | false
122 |
123 |
124 | False
125 | .NET Framework 3.5 SP1
126 | true
127 |
128 |
129 |
130 |
137 |
--------------------------------------------------------------------------------
/CodePreviewHandler.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2012
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodePreviewHandler", "CodePreviewHandler.csproj", "{2B886813-EC35-476B-B14C-BC6F0459BEC6}"
5 | EndProject
6 | Project("{6141683F-8A12-4E36-9623-2EB02B2C2303}") = "CodePreviewHandlerSetup", "CodePreviewHandlerSetup\CodePreviewHandlerSetup.isproj", "{C641CC2B-1732-4654-A37E-2C0ADF11E491}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | CD_ROM|Any CPU = CD_ROM|Any CPU
11 | Debug|Any CPU = Debug|Any CPU
12 | DVD-5|Any CPU = DVD-5|Any CPU
13 | Release|Any CPU = Release|Any CPU
14 | SingleImage|Any CPU = SingleImage|Any CPU
15 | EndGlobalSection
16 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
17 | {2B886813-EC35-476B-B14C-BC6F0459BEC6}.CD_ROM|Any CPU.ActiveCfg = Release|Any CPU
18 | {2B886813-EC35-476B-B14C-BC6F0459BEC6}.CD_ROM|Any CPU.Build.0 = Release|Any CPU
19 | {2B886813-EC35-476B-B14C-BC6F0459BEC6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
20 | {2B886813-EC35-476B-B14C-BC6F0459BEC6}.Debug|Any CPU.Build.0 = Debug|Any CPU
21 | {2B886813-EC35-476B-B14C-BC6F0459BEC6}.DVD-5|Any CPU.ActiveCfg = Debug|Any CPU
22 | {2B886813-EC35-476B-B14C-BC6F0459BEC6}.DVD-5|Any CPU.Build.0 = Debug|Any CPU
23 | {2B886813-EC35-476B-B14C-BC6F0459BEC6}.Release|Any CPU.ActiveCfg = Release|Any CPU
24 | {2B886813-EC35-476B-B14C-BC6F0459BEC6}.Release|Any CPU.Build.0 = Release|Any CPU
25 | {2B886813-EC35-476B-B14C-BC6F0459BEC6}.SingleImage|Any CPU.ActiveCfg = Release|Any CPU
26 | {2B886813-EC35-476B-B14C-BC6F0459BEC6}.SingleImage|Any CPU.Build.0 = Release|Any CPU
27 | {C641CC2B-1732-4654-A37E-2C0ADF11E491}.CD_ROM|Any CPU.ActiveCfg = CD_ROM
28 | {C641CC2B-1732-4654-A37E-2C0ADF11E491}.CD_ROM|Any CPU.Build.0 = CD_ROM
29 | {C641CC2B-1732-4654-A37E-2C0ADF11E491}.Debug|Any CPU.ActiveCfg = DVD-5
30 | {C641CC2B-1732-4654-A37E-2C0ADF11E491}.Debug|Any CPU.Build.0 = DVD-5
31 | {C641CC2B-1732-4654-A37E-2C0ADF11E491}.DVD-5|Any CPU.ActiveCfg = DVD-5
32 | {C641CC2B-1732-4654-A37E-2C0ADF11E491}.DVD-5|Any CPU.Build.0 = DVD-5
33 | {C641CC2B-1732-4654-A37E-2C0ADF11E491}.Release|Any CPU.ActiveCfg = SingleImage
34 | {C641CC2B-1732-4654-A37E-2C0ADF11E491}.Release|Any CPU.Build.0 = SingleImage
35 | {C641CC2B-1732-4654-A37E-2C0ADF11E491}.SingleImage|Any CPU.ActiveCfg = SingleImage
36 | {C641CC2B-1732-4654-A37E-2C0ADF11E491}.SingleImage|Any CPU.Build.0 = SingleImage
37 | EndGlobalSection
38 | GlobalSection(SolutionProperties) = preSolution
39 | HideSolutionNode = FALSE
40 | EndGlobalSection
41 | EndGlobal
42 |
--------------------------------------------------------------------------------
/CodePreviewHandlerSetup/CodePreviewHandlerSetup.isproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Express
6 |
7 | Debug
8 | $(Configuration)
9 |
10 |
11 |
12 |
13 |
14 |
15 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
29 |
30 |
31 |
32 |
33 | CodePreviewHandler
34 | {2B886813-EC35-476B-B14C-BC6F0459BEC6}
35 |
36 |
37 |
--------------------------------------------------------------------------------
/CppFormat.cs:
--------------------------------------------------------------------------------
1 | namespace TimHeuer.PreviewHandlers
2 | {
3 | public class CppFormat : Manoli.Utils.CSharpFormat.CSharpFormat
4 | {
5 | protected override string Keywords
6 | {
7 | get
8 | {
9 | string str = base.Keywords + "auto static_cast reinterpret_cast dynamic_cast safe_cast nullptr";
10 | return str;
11 | }
12 | }
13 |
14 | protected override string Preprocessors
15 | {
16 | get
17 | {
18 | return "#if #else #elif #endif #define #undef #warning "
19 | + "#error #line #region #endregion #pragma #include";
20 | }
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/CsharpFormat.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace TimHeuer.PreviewHandlers
3 | {
4 | public class CSharpFormat : Manoli.Utils.CSharpFormat.CSharpFormat
5 | {
6 | protected override string Keywords
7 | {
8 | get
9 | {
10 | string str = base.Keywords + " await async";
11 | return str;
12 | }
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/CssFormat.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace TimHeuer.PreviewHandlers
6 | {
7 | public class CssFormat : Manoli.Utils.CSharpFormat.HtmlFormat
8 | {
9 |
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/HtmlViewer/Element.cs:
--------------------------------------------------------------------------------
1 | ///////////////////////////////////////////////////////////////////////////////
2 | // HTML Control and HTML Editor Sample
3 | // Copyright 2003, Nikhil Kothari. All Rights Reserved.
4 | //
5 | // Provided as is, in sample form with no associated warranties.
6 | // For more information on usage, see the accompanying
7 | // License.txt file.
8 | ///////////////////////////////////////////////////////////////////////////////
9 |
10 | namespace HtmlApp.Html {
11 | using System;
12 | using System.ComponentModel;
13 | using System.Diagnostics;
14 | using System.Drawing;
15 | using System.Globalization;
16 | using System.Collections;
17 | using System.Reflection;
18 |
19 | ///
20 | /// The base class for all element wrappers. These provide information for populating
21 | /// the property grid.
22 | ///
23 | [
24 | DesignOnly(true)
25 | ]
26 | public class Element {
27 | public static Element GetWrapperFor(Interop.IHTMLElement element, HtmlControl owner) {
28 | Element wrapperElement = new Element(element);
29 | wrapperElement.SetOwner(owner);
30 | return wrapperElement;
31 | }
32 |
33 | private Interop.IHTMLElement _peer;
34 | private HtmlControl _owner;
35 |
36 | internal Element(Interop.IHTMLElement peer) {
37 | Debug.Assert(peer != null);
38 | _peer = peer;
39 | }
40 |
41 | [Browsable(false)]
42 | public string InnerHtml {
43 | get {
44 | try {
45 | return _peer.GetInnerHTML();
46 | }
47 | catch (Exception e) {
48 | Debug.Fail(e.ToString(), "Could not get Element InnerHTML");
49 |
50 | return String.Empty;
51 | }
52 | }
53 | set {
54 | try {
55 | _peer.SetInnerHTML(value);
56 | }
57 | catch (Exception e) {
58 | Debug.Fail(e.ToString(), "Could not set Element InnerHTML");
59 | }
60 | }
61 | }
62 |
63 | [Browsable(false)]
64 | public string OuterHtml {
65 | get {
66 | try {
67 | return _peer.GetOuterHTML();
68 | }
69 | catch (Exception e) {
70 | Debug.Fail(e.ToString(), "Could not get Element OuterHTML");
71 |
72 | return String.Empty;
73 | }
74 | }
75 | set {
76 | try {
77 | _peer.SetOuterHTML(value);
78 | }
79 | catch (Exception e) {
80 | Debug.Fail(e.ToString(), "Could not set Element OuterHTML");
81 | }
82 | }
83 | }
84 |
85 | [Browsable(false)]
86 | public string TagName {
87 | get {
88 | try {
89 | return _peer.GetTagName();
90 | }
91 | catch (Exception e) {
92 | Debug.Fail(e.ToString(), "Could not get Element TagName" + e.ToString());
93 |
94 | return String.Empty;
95 | }
96 | }
97 | }
98 |
99 | internal Interop.IHTMLElement Peer {
100 | get {
101 | return _peer;
102 | }
103 | }
104 |
105 | public object GetAttribute(string attribute) {
106 | try {
107 | object[] obj = new object[1];
108 |
109 | _peer.GetAttribute(attribute, 0, obj);
110 |
111 | object o = obj[0];
112 | if (o is DBNull) {
113 | o = null;
114 | }
115 | return o;
116 | }
117 | catch (Exception e) {
118 | Debug.Fail(e.ToString(), "Call to IHTMLElement::GetAttribute failed in Element");
119 |
120 | return null;
121 | }
122 | }
123 |
124 | protected internal bool GetBooleanAttribute(string attribute) {
125 | object o = GetAttribute(attribute);
126 |
127 | if (o == null) {
128 | return false;
129 | }
130 |
131 | Debug.Assert(o is bool, "Attribute " + attribute + " is not of type Boolean");
132 | if (o is bool) {
133 | return (bool)o;
134 | }
135 |
136 | return false;
137 | }
138 |
139 | protected internal Color GetColorAttribute(string attribute) {
140 | string color = GetStringAttribute(attribute);
141 |
142 | if (color.Length == 0) {
143 | return Color.Empty;
144 | }
145 | else {
146 | return ColorTranslator.FromHtml(color);
147 | }
148 | }
149 |
150 | protected internal Enum GetEnumAttribute(string attribute, Enum defaultValue) {
151 | Type enumType = defaultValue.GetType();
152 |
153 | object o = GetAttribute(attribute);
154 | if (o == null) {
155 | return defaultValue;
156 | }
157 |
158 | Debug.Assert(o is string, "Attribute " + attribute + " is not of type String");
159 | string s = o as string;
160 | if ((s == null) || (s.Length == 0)) {
161 | return defaultValue;
162 | }
163 |
164 | try {
165 | return (Enum)Enum.Parse(enumType, s, true);
166 | }
167 | catch {
168 | return defaultValue;
169 | }
170 | }
171 |
172 | protected internal int GetIntegerAttribute(string attribute, int defaultValue) {
173 | object o = GetAttribute(attribute);
174 |
175 | if (o == null) {
176 | return defaultValue;
177 | }
178 | if (o is int) {
179 | return (int)o;
180 | }
181 | if (o is short) {
182 | return (short)o;
183 | }
184 | if (o is string) {
185 | string s = (string)o;
186 | if ((s.Length != 0) && (Char.IsDigit(s[0]))) {
187 | try {
188 | return Int32.Parse((string)o);
189 | }
190 | catch {
191 | }
192 | }
193 | }
194 |
195 | Debug.Fail("Attribute " + attribute + " is not an integer");
196 | return defaultValue;
197 | }
198 |
199 | public Element GetChild(int index) {
200 | Interop.IHTMLElementCollection children = (Interop.IHTMLElementCollection)_peer.GetChildren();
201 | Interop.IHTMLElement child = (Interop.IHTMLElement)children.Item(null, index);
202 |
203 | return Element.GetWrapperFor(child, _owner);
204 | }
205 |
206 | public Element GetChild(string name) {
207 | Interop.IHTMLElementCollection children = (Interop.IHTMLElementCollection)_peer.GetChildren();
208 | Interop.IHTMLElement child = (Interop.IHTMLElement)children.Item(name, null);
209 |
210 | return Element.GetWrapperFor(child, _owner);
211 | }
212 |
213 | public Element GetParent() {
214 | Interop.IHTMLElement parent = (Interop.IHTMLElement)_peer.GetParentElement();
215 | return Element.GetWrapperFor(parent, _owner);
216 | }
217 |
218 | protected string GetRelativeUrl(string absoluteUrl) {
219 | if ((absoluteUrl == null) || (absoluteUrl.Length == 0)) {
220 | return String.Empty;
221 | }
222 |
223 | string s = absoluteUrl;
224 | if (_owner != null) {
225 | string ownerUrl = _owner.Url;
226 |
227 | if (ownerUrl.Length != 0) {
228 | try {
229 | Uri ownerUri = new Uri(ownerUrl);
230 | Uri imageUri = new Uri(s);
231 |
232 | s = ownerUri.MakeRelative(imageUri);
233 | }
234 | catch {
235 | }
236 | }
237 | }
238 |
239 | return s;
240 | }
241 |
242 | protected internal string GetStringAttribute(string attribute) {
243 | return GetStringAttribute(attribute, String.Empty);
244 | }
245 |
246 | protected internal string GetStringAttribute(string attribute, string defaultValue) {
247 | object o = GetAttribute(attribute);
248 |
249 | if (o == null) {
250 | return defaultValue;
251 | }
252 | if (o is string) {
253 | return (string)o;
254 | }
255 |
256 | return defaultValue;
257 | }
258 |
259 | public void RemoveAttribute(string attribute) {
260 | try {
261 | _peer.RemoveAttribute(attribute, 0);
262 | }
263 | catch (Exception e) {
264 | Debug.Fail(e.ToString(), "Call to IHTMLElement::RemoveAttribute failed in Element");
265 | }
266 | }
267 |
268 | public void SetAttribute(string attribute, object value) {
269 | try {
270 | _peer.SetAttribute(attribute, value, 0);
271 | }
272 | catch (Exception e) {
273 | Debug.Fail(e.ToString(), "Call to IHTMLElement::SetAttribute failed in Element");
274 | }
275 | }
276 |
277 | protected internal void SetBooleanAttribute(string attribute, bool value) {
278 | if (value) {
279 | SetAttribute(attribute, true);
280 | }
281 | else {
282 | RemoveAttribute(attribute);
283 | }
284 | }
285 |
286 | protected internal void SetColorAttribute(string attribute, Color value) {
287 | if (value.IsEmpty) {
288 | RemoveAttribute(attribute);
289 | }
290 | else {
291 | SetAttribute(attribute, ColorTranslator.ToHtml(value));
292 | }
293 | }
294 |
295 | protected internal void SetEnumAttribute(string attribute, Enum value, Enum defaultValue) {
296 | Debug.Assert(value.GetType().Equals(defaultValue.GetType()));
297 |
298 | if (value.Equals(defaultValue)) {
299 | RemoveAttribute(attribute);
300 | }
301 | else {
302 | SetAttribute(attribute, value.ToString(CultureInfo.InvariantCulture));
303 | }
304 | }
305 |
306 | protected internal void SetIntegerAttribute(string attribute, int value, int defaultValue) {
307 | if (value == defaultValue) {
308 | RemoveAttribute(attribute);
309 | }
310 | else {
311 | SetAttribute(attribute, value);
312 | }
313 | }
314 |
315 | internal void SetOwner(HtmlControl owner) {
316 | _owner = owner;
317 | }
318 |
319 | protected internal void SetStringAttribute(string attribute, string value) {
320 | SetStringAttribute(attribute, value, String.Empty);
321 | }
322 |
323 | protected internal void SetStringAttribute(string attribute, string value, string defaultValue) {
324 | if ((value == null) || value.Equals(defaultValue)) {
325 | RemoveAttribute(attribute);
326 | }
327 | else {
328 | SetAttribute(attribute, value);
329 | }
330 | }
331 |
332 | public override string ToString() {
333 | if (_peer != null) {
334 | try {
335 | return "<" + _peer.GetTagName() + ">";
336 | }
337 | catch {
338 | }
339 | }
340 | return String.Empty;
341 | }
342 | }
343 | }
344 |
--------------------------------------------------------------------------------
/HtmlViewer/FontUnit.cs:
--------------------------------------------------------------------------------
1 | ///////////////////////////////////////////////////////////////////////////////
2 | // HTML Control and HTML Editor Sample
3 | // Copyright 2003, Nikhil Kothari. All Rights Reserved.
4 | //
5 | // Provided as is, in sample form with no associated warranties.
6 | // For more information on usage, see the accompanying
7 | // License.txt file.
8 | ///////////////////////////////////////////////////////////////////////////////
9 |
10 | namespace HtmlApp.Html {
11 | using System;
12 |
13 | public enum FontUnit {
14 | Empty,
15 | Smaller,
16 | Larger,
17 | Type,
18 | XXSmall,
19 | XSmall,
20 | Small,
21 | Medium,
22 | Large,
23 | XLarge,
24 | XXLarge,
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/HtmlViewer/HtmlCommandInfo.cs:
--------------------------------------------------------------------------------
1 | ///////////////////////////////////////////////////////////////////////////////
2 | // HTML Control and HTML Editor Sample
3 | // Copyright 2003, Nikhil Kothari. All Rights Reserved.
4 | //
5 | // Provided as is, in sample form with no associated warranties.
6 | // For more information on usage, see the accompanying
7 | // License.txt file.
8 | ///////////////////////////////////////////////////////////////////////////////
9 |
10 | namespace HtmlApp.Html {
11 |
12 | using System;
13 |
14 | [Flags]
15 | public enum HtmlCommandInfo {
16 | Enabled = 1,
17 | Checked = 2
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/HtmlViewer/HtmlControl.cs:
--------------------------------------------------------------------------------
1 | ///////////////////////////////////////////////////////////////////////////////
2 | // HTML Control and HTML Editor Sample
3 | // Copyright 2003, Nikhil Kothari. All Rights Reserved.
4 | //
5 | // Provided as is, in sample form with no associated warranties.
6 | // For more information on usage, see the accompanying
7 | // License.txt file.
8 | ///////////////////////////////////////////////////////////////////////////////
9 |
10 | namespace HtmlApp.Html {
11 |
12 | using System;
13 | using System.Collections;
14 | using System.Collections.Specialized;
15 | using System.Diagnostics;
16 | using System.Drawing;
17 | using System.IO;
18 | using System.Runtime.InteropServices;
19 | using System.Text;
20 | using System.Windows;
21 | using System.Windows.Forms;
22 |
23 | using STATSTG = Interop.STATSTG;
24 |
25 | ///
26 | /// An HTML rendering control based on MSHTML
27 | ///
28 | public class HtmlControl : Control {
29 |
30 | private static readonly object EventShowContextMenu = new object();
31 | private static readonly object _readyStateCompleteEvent = new object();
32 |
33 | private bool _scrollBarsEnabled;
34 | private bool _flatScrollBars;
35 | private bool _border3d;
36 | private bool _scriptEnabled;
37 | private bool _allowInPlaceNavigation;
38 | private bool _fullDocumentMode;
39 |
40 | private bool _firstActivation;
41 | private bool _isReady;
42 | private bool _isCreated;
43 |
44 | //These allow a user to load the document before displaying
45 | private bool _loadDesired;
46 | private string _desiredContent;
47 | private string _desiredUrl;
48 |
49 | private bool _focusDesired;
50 |
51 | private string _url;
52 | private object _scriptObject;
53 |
54 | private MSHTMLSite _site;
55 |
56 | private static IDictionary _urlMap;
57 |
58 | ///
59 | ///
60 | public HtmlControl() : this(true) {
61 | }
62 |
63 | ///
64 | ///
65 | ///
66 | public HtmlControl(bool fullDocumentMode) {
67 | _firstActivation = true;
68 | _fullDocumentMode = fullDocumentMode;
69 |
70 | // Scroll bars should be enabled by default
71 | _scrollBarsEnabled = true;
72 | }
73 |
74 | public bool AllowInPlaceNavigation {
75 | get {
76 | return _allowInPlaceNavigation;
77 | }
78 | set {
79 | _allowInPlaceNavigation = value;
80 | }
81 | }
82 |
83 | ///
84 | /// Indicates if the Interop.HTMLDocument2 is created
85 | ///
86 | protected bool IsCreated {
87 | get {
88 | return _isCreated;
89 | }
90 | }
91 |
92 | internal bool IsFullDocumentMode {
93 | get {
94 | return _fullDocumentMode;
95 | }
96 | }
97 |
98 | ///
99 | /// Indicates if the control is ready for use
100 | ///
101 | public bool IsReady {
102 | get {
103 | return _isReady;
104 | }
105 | }
106 |
107 | protected internal Interop.IHTMLDocument2 MSHTMLDocument {
108 | get {
109 | return _site.MSHTMLDocument;
110 | }
111 | }
112 |
113 | protected internal Interop.IOleCommandTarget CommandTarget {
114 | get {
115 | return _site.MSHTMLCommandTarget;
116 | }
117 | }
118 |
119 | public bool Border3d {
120 | get {
121 | return _border3d;
122 | }
123 | set {
124 | _border3d = value;
125 | }
126 | }
127 |
128 | ///
129 | /// Indicates if the current selection can be copied
130 | ///
131 | public bool CanCopy {
132 | get {
133 | return IsCommandEnabled(Interop.IDM_COPY);
134 | }
135 | }
136 |
137 | ///
138 | /// Indicates if the current selection can be cut
139 | ///
140 | public bool CanCut {
141 | get {
142 | return IsCommandEnabled(Interop.IDM_CUT);
143 | }
144 | }
145 |
146 | ///
147 | /// Indicates if the current selection can be pasted to
148 | ///
149 | public bool CanPaste {
150 | get {
151 | return IsCommandEnabled(Interop.IDM_PASTE);
152 | }
153 | }
154 |
155 | ///
156 | /// Indicates if the editor can redo
157 | ///
158 | public bool CanRedo {
159 | get {
160 | return IsCommandEnabled(Interop.IDM_REDO);
161 | }
162 | }
163 |
164 | ///
165 | /// Indicates if the editor can undo
166 | ///
167 | public bool CanUndo {
168 | get {
169 | return IsCommandEnabled(Interop.IDM_UNDO);
170 | }
171 | }
172 |
173 | public bool FlatScrollBars {
174 | get {
175 | return _flatScrollBars;
176 | }
177 | set {
178 | _flatScrollBars = value;
179 | }
180 | }
181 |
182 |
183 | public event EventHandler ReadyStateComplete {
184 | add {
185 | Events.AddHandler(_readyStateCompleteEvent, value);
186 | }
187 | remove {
188 | Events.RemoveHandler(_readyStateCompleteEvent, value);
189 | }
190 | }
191 |
192 | public bool ScriptEnabled {
193 | get {
194 | return _scriptEnabled;
195 | }
196 | set {
197 | _scriptEnabled = value;
198 | }
199 | }
200 |
201 | public object ScriptObject {
202 | get {
203 | return _scriptObject;
204 | }
205 | set {
206 | _scriptObject = value;
207 | }
208 | }
209 |
210 | public bool ScrollBarsEnabled {
211 | get {
212 | return _scrollBarsEnabled;
213 | }
214 | set {
215 | _scrollBarsEnabled = value;
216 | }
217 | }
218 |
219 | ///
220 | /// Gets the url of the document contained in the control
221 | ///
222 | public virtual string Url {
223 | get {
224 | return _url;
225 | }
226 | }
227 |
228 | internal static IDictionary UrlMap {
229 | get {
230 | if (_urlMap == null) {
231 | _urlMap = new HybridDictionary(true);
232 | }
233 | return _urlMap;
234 | }
235 | }
236 |
237 | ///
238 | /// Copy the current selection
239 | ///
240 | public void Copy() {
241 | if (!CanCopy) {
242 | throw new Exception("HtmlControl.Copy : Not in able to copy the current selection!");
243 | }
244 | Exec(Interop.IDM_COPY);
245 | }
246 |
247 | protected virtual string CreateHtmlContent(string content, string style) {
248 | return "" + style + "" + content + "";
249 | }
250 |
251 | ///
252 | /// Cut the current selection
253 | ///
254 | public void Cut() {
255 | if (!CanCut) {
256 | throw new Exception("HtmlControl.Cut : Not in able to cut the current selection!");
257 | }
258 | Exec(Interop.IDM_CUT);
259 | }
260 |
261 | ///
262 | protected override void Dispose(bool disposing) {
263 | if (disposing) {
264 | if (_url != null) {
265 | UrlMap[_url] = null;
266 | }
267 | }
268 | base.Dispose(disposing);
269 | }
270 |
271 | ///
272 | /// Executes the specified command in MSHTML
273 | ///
274 | ///
275 | protected internal void Exec(int command) {
276 | Exec(command, null);
277 | }
278 |
279 | ///
280 | /// Executes the specified command in MSHTML with the specified argument
281 | ///
282 | ///
283 | protected internal void Exec(int command, object argument) {
284 | object[] args = new object[] { argument };
285 |
286 | //Execute the command
287 | int hr = CommandTarget.Exec(ref Interop.Guid_MSHTML, command, Interop.OLECMDEXECOPT.OLECMDEXECOPT_DONTPROMPTUSER, args, null);
288 | if (hr != Interop.S_OK) {
289 | throw new Exception("MSHTMLHelper.Exec : Command "+command+" did not return S_OK");
290 | }
291 | }
292 |
293 | ///
294 | /// Executes the specified command in MSHTML with the specified argument
295 | ///
296 | ///
297 | protected internal void ExecPrompt(int command) {
298 | object[] args = new object[] { null };
299 |
300 | //Execute the command
301 | int hr = CommandTarget.Exec(ref Interop.Guid_MSHTML, command, Interop.OLECMDEXECOPT.OLECMDEXECOPT_PROMPTUSER, args, null);
302 | if (hr != Interop.S_OK) {
303 | throw new Exception("MSHTMLHelper.Exec : Command "+command+" did not return S_OK");
304 | }
305 | }
306 |
307 | ///
308 | /// Executes the specified command in MSHTML and returns the result
309 | ///
310 | ///
311 | /// object result - The result of the command
312 | protected internal object ExecResult(int command) {
313 | object[] retVal = new object[1];
314 |
315 | //Execute the command
316 | int hr = CommandTarget.Exec(ref Interop.Guid_MSHTML, command, Interop.OLECMDEXECOPT.OLECMDEXECOPT_DONTPROMPTUSER, null, retVal);
317 | if (hr != Interop.S_OK) {
318 | throw new Exception("MSHTMLHelper.ExecResult : Command "+command+" did not return S_OK");
319 | }
320 | return retVal[0];
321 | }
322 |
323 | ///
324 | /// Queries MSHTML for the command info (enabled and checked) for the specified command
325 | ///
326 | ///
327 | ///
328 | protected internal HtmlCommandInfo GetCommandInfo(int command) {
329 | //First query the command target for the command status
330 | int info;
331 | Interop.tagOLECMD oleCommand = new Interop.tagOLECMD();
332 |
333 | //Create an tagOLDCMD to store the command and receive the result
334 | oleCommand.cmdID = command;
335 | int hr = CommandTarget.QueryStatus(ref Interop.Guid_MSHTML, 1, oleCommand, 0);
336 | Debug.Assert(hr == Interop.S_OK,"IOleCommand.QueryStatus did not return S_OK");
337 |
338 | //Then translate the response from the command status
339 | //We can just right shift by one to eliminate the supported flag from OLECMDF
340 | info = oleCommand.cmdf;
341 | //REVIEW: Do we want to do a mapping instead of playing with the bits?
342 | return (HtmlCommandInfo)(info>>1) & (HtmlCommandInfo.Enabled | HtmlCommandInfo.Checked);
343 | }
344 |
345 | ///
346 | /// Indicates if the specified command is checked
347 | ///
348 | ///
349 | ///
350 | protected internal bool IsCommandChecked(int command) {
351 | return ((GetCommandInfo(command) & HtmlCommandInfo.Checked) != 0);
352 | }
353 |
354 | ///
355 | /// Indicates if the specified command is enabled
356 | ///
357 | ///
358 | ///
359 | protected internal bool IsCommandEnabled(int command) {
360 | return ((GetCommandInfo(command) & HtmlCommandInfo.Enabled) != 0);
361 | }
362 |
363 | ///
364 | /// Indicates if the specified command is enabled
365 | ///
366 | ///
367 | ///
368 | protected internal bool IsCommandEnabledAndChecked(int command) {
369 | HtmlCommandInfo info = GetCommandInfo(command);
370 | return (((info & HtmlCommandInfo.Enabled) != 0) && ((info & HtmlCommandInfo.Checked) != 0));
371 | }
372 |
373 | ///
374 | /// Loads HTML content from a stream into this control
375 | ///
376 | ///
377 | public void LoadHtml(Stream stream) {
378 | if (stream == null) {
379 | throw new ArgumentNullException("LoadHtml : You must specify a non-null stream for content");
380 | }
381 | StreamReader reader = new StreamReader(stream);
382 | LoadHtml(reader.ReadToEnd());
383 | }
384 |
385 | ///
386 | /// Loads HTML content from a string into this control
387 | ///
388 | ///
389 | public void LoadHtml(string content) {
390 | LoadHtml(content, null, null);
391 | }
392 |
393 | public void LoadHtml(string content, string url) {
394 | LoadHtml(content, url, null);
395 | }
396 |
397 | //REVIEW: Add a load method for stream and url
398 |
399 | ///
400 | /// Loads HTML content from a string into this control identified by the specified URL.
401 | /// If MSHTML has not yet been created, the loading is postponed until MSHTML has been created.
402 | ///
403 | ///
404 | ///
405 | public void LoadHtml(string content, string url, string style) {
406 | if (content == null) {
407 | content = "";
408 | }
409 |
410 | if (!_isCreated) {
411 | _desiredContent = content;
412 | _desiredUrl = url;
413 | _loadDesired = true;
414 | return;
415 | }
416 |
417 | if (_fullDocumentMode == false) {
418 | content = CreateHtmlContent(content, style);
419 | }
420 |
421 | OnBeforeLoad();
422 |
423 | Interop.IStream stream = null;
424 |
425 | //First we create a COM stream
426 | IntPtr hglobal = Marshal.StringToHGlobalUni(content);
427 | Interop.CreateStreamOnHGlobal(hglobal, true, out stream);
428 |
429 | // Initialize a new document if there is nothing to load
430 | if (stream == null) {
431 | Interop.IPersistStreamInit psi = (Interop.IPersistStreamInit)_site.MSHTMLDocument;
432 | Debug.Assert(psi != null, "Expected IPersistStreamInit");
433 | psi.InitNew();
434 | psi = null;
435 | }
436 | else {
437 | Interop.IHTMLDocument2 document = _site.MSHTMLDocument;
438 | //If there is no specified URL load the document from the stream
439 | if (url == null) {
440 | Interop.IPersistStreamInit psi = (Interop.IPersistStreamInit)document;
441 | Debug.Assert(psi != null, "Expected IPersistStreamInit");
442 | psi.Load(stream);
443 | psi = null;
444 | }
445 | else {
446 | //Otherwise we create a moniker and load the stream to that moniker
447 | }
448 | }
449 | _url = url;
450 |
451 | OnAfterLoad();
452 | }
453 |
454 | ///
455 | /// Allow editors to perform actions after HTML content is loaded to the control
456 | ///
457 | protected virtual void OnAfterLoad() {
458 | }
459 |
460 | ///
461 | ///
462 | protected virtual void OnAfterSave() {
463 | }
464 |
465 | ///
466 | /// Allow editors to perform actions before HTML content is loaded to the control
467 | ///
468 | protected virtual void OnBeforeLoad() {
469 | }
470 |
471 | ///
472 | ///
473 | protected virtual void OnBeforeSave() {
474 | }
475 |
476 | ///
477 | /// Allow editors to perform actions when the MSHTML document is created
478 | /// and before it's activated
479 | ///
480 | ///
481 | protected virtual void OnCreated(EventArgs args) {
482 | }
483 |
484 | ///
485 | /// On focus, we have to also return focus to MSHTML
486 | ///
487 | protected override void OnGotFocus(EventArgs e) {
488 | base.OnGotFocus(e);
489 |
490 | //TODO: Fill this in with the right code
491 | if (IsReady) {
492 | // REVIEW: Not sure if we need to do this... It seems to work without it.
493 | //_site.ActivateMSHTML();
494 | _site.SetFocus();
495 | }
496 | else {
497 | _focusDesired = true;
498 | }
499 | }
500 |
501 | ///
502 | /// We can only activate the MSHTML after our handle has been created,
503 | /// so upon creating the handle, we create and activate Interop.
504 | ///
505 | /// If LoadHtml was called prior to this, we do the loading now
506 | ///
507 | ///
508 | protected override void OnHandleCreated(EventArgs args) {
509 | base.OnHandleCreated(args);
510 | if (_firstActivation) {
511 | _site = new MSHTMLSite(this);
512 | _site.CreateMSHTML();
513 |
514 | _isCreated = true;
515 |
516 | OnCreated(new EventArgs());
517 |
518 | _site.ActivateMSHTML();
519 | _firstActivation = false;
520 |
521 | if (_loadDesired) {
522 | LoadHtml(_desiredContent, _desiredUrl);
523 | _loadDesired = false;
524 | }
525 | }
526 | }
527 |
528 | ///
529 | /// Called when the control has just become ready
530 | ///
531 | ///
532 | protected internal virtual void OnReadyStateComplete(EventArgs e) {
533 | _isReady = true;
534 |
535 | EventHandler handler = (EventHandler)Events[_readyStateCompleteEvent];
536 | if (handler != null) {
537 | handler(this, e);
538 | }
539 |
540 | if (_focusDesired) {
541 | _focusDesired = false;
542 | _site.ActivateMSHTML();
543 | _site.SetFocus();
544 | }
545 | }
546 |
547 | ///
548 | /// Cut the current selection
549 | ///
550 | public void Paste() {
551 | if (!CanPaste) {
552 | throw new Exception("HtmlControl.Paste : Not in able to paste the current selection!");
553 | }
554 | Exec(Interop.IDM_PASTE);
555 | }
556 |
557 | ///
558 | /// We need to process keystrokes in order to pass them to MSHTML
559 | ///
560 | public override bool PreProcessMessage(ref Message m) {
561 | bool handled = false;
562 | if ((m.Msg >= Interop.WM_KEYFIRST) && (m.Msg <= Interop.WM_KEYLAST)) {
563 | // If it's a key down, first see if the key combo is a command key
564 |
565 | if (m.Msg == Interop.WM_KEYDOWN) {
566 | handled = ProcessCmdKey(ref m, (Keys)(int)m.WParam | ModifierKeys);
567 | }
568 |
569 | if (!handled) {
570 | int keyCode = (int)m.WParam;
571 | // Don't let Trident eat Ctrl-PgUp/PgDn
572 | if (((keyCode != (int)Keys.PageUp) && (keyCode != (int)Keys.PageDown)) || ((ModifierKeys & Keys.Control) == 0)) {
573 | Interop.COMMSG cm = new Interop.COMMSG();
574 |
575 | cm.hwnd = m.HWnd;
576 | cm.message = m.Msg;
577 | cm.wParam = m.WParam;
578 | cm.lParam = m.LParam;
579 | handled = _site.TranslateAccelarator(cm);
580 | }
581 | else {
582 | // WndProc for Ctrl-PgUp/PgDn is never called so call it directly here
583 | WndProc(ref m);
584 | handled = true;
585 | }
586 | }
587 | }
588 |
589 | if (!handled) {
590 | handled = base.PreProcessMessage(ref m);
591 | }
592 |
593 | return handled;
594 | }
595 |
596 | public void Redo() {
597 | if (!CanRedo) {
598 | throw new Exception("HtmlControl.Redo : Not in able to redo!");
599 | }
600 | Exec(Interop.IDM_REDO);
601 | }
602 |
603 | ///
604 | /// Saves the HTML contained in control to a string and return it.
605 | ///
606 | /// string - The HTML in the control
607 | public string SaveHtml() {
608 | if (!IsCreated) {
609 | throw new Exception("HtmlControl.SaveHtml : No HTML to save!");
610 | }
611 |
612 | string content = String.Empty;
613 |
614 | try {
615 | OnBeforeSave();
616 |
617 | Interop.IHTMLDocument2 document = _site.MSHTMLDocument;
618 |
619 | if (_fullDocumentMode) {
620 | // First save the document to a stream
621 | Interop.IPersistStreamInit psi = (Interop.IPersistStreamInit)document;
622 | Debug.Assert(psi != null, "Expected IPersistStreamInit");
623 |
624 | Interop.IStream stream = null;
625 | Interop.CreateStreamOnHGlobal(Interop.NullIntPtr, true, out stream);
626 |
627 | psi.Save(stream, 1);
628 |
629 | // Now copy the stream to the string
630 | STATSTG stat = new STATSTG();
631 | stream.Stat(stat, 1);
632 | int length = (int)stat.cbSize;
633 | byte[] bytes = new byte[length];
634 |
635 | IntPtr hglobal;
636 | Interop.GetHGlobalFromStream(stream, out hglobal);
637 | Debug.Assert(hglobal != Interop.NullIntPtr, "Failed in GetHGlobalFromStream");
638 |
639 | // First copy the stream to a byte array
640 | IntPtr pointer = Interop.GlobalLock(hglobal);
641 | if (pointer != Interop.NullIntPtr) {
642 | Marshal.Copy(pointer, bytes, 0, length);
643 |
644 | Interop.GlobalUnlock(hglobal);
645 |
646 | // Then create the string from the byte array (use a StreamReader to eat the preamble in the UTF8 encoding case)
647 | StreamReader streamReader = null;
648 | try {
649 | streamReader = new StreamReader(new MemoryStream(bytes), Encoding.Default);
650 | content = streamReader.ReadToEnd();
651 | }
652 | finally {
653 | if (streamReader != null) {
654 | streamReader.Close();
655 | }
656 | }
657 | }
658 | }
659 | else {
660 | // Save only the contents of the tag
661 | Interop.IHTMLElement bodyElement = document.GetBody();
662 | Debug.Assert(bodyElement != null, "Could not get BODY element from document");
663 |
664 | if (bodyElement != null) {
665 | content = SavePartialHtml(Element.GetWrapperFor(bodyElement, this));
666 | }
667 | }
668 | }
669 | catch (Exception e) {
670 | Debug.Fail("HtmlControl.SaveHtml" + e.ToString());
671 | content = String.Empty;
672 | }
673 | finally {
674 | OnAfterSave();
675 | }
676 |
677 | if (content == null) {
678 | content = String.Empty;
679 | }
680 | return content;
681 | }
682 |
683 | // REVIEW: Come up with better names to unify _fullDocumentMode, CreateHtmlContent, and SavePartialHtml
684 | protected virtual string SavePartialHtml(Element bodyElement) {
685 | return bodyElement.InnerHtml;
686 | }
687 |
688 | ///
689 | /// Saves the HTML contained in the control to a stream
690 | ///
691 | ///
692 | public void SaveHtml(Stream stream) {
693 | if (stream == null) {
694 | throw new ArgumentNullException("SaveHtml : Must specify a non-null stream to which to save");
695 | }
696 |
697 | string content = SaveHtml();
698 |
699 | StreamWriter writer = new StreamWriter(stream, Encoding.UTF8);
700 | writer.Write(content);
701 | writer.Flush();
702 | }
703 |
704 | public void Undo() {
705 | if (!CanUndo) {
706 | throw new Exception("HtmlControl.Undo : Not in able to undo!");
707 | }
708 | Exec(Interop.IDM_UNDO);
709 | }
710 | }
711 | }
712 |
--------------------------------------------------------------------------------
/HtmlViewer/HtmlDocument.cs:
--------------------------------------------------------------------------------
1 | ///////////////////////////////////////////////////////////////////////////////
2 | // HTML Control and HTML Editor Sample
3 | // Copyright 2003, Nikhil Kothari. All Rights Reserved.
4 | //
5 | // Provided as is, in sample form with no associated warranties.
6 | // For more information on usage, see the accompanying
7 | // License.txt file.
8 | ///////////////////////////////////////////////////////////////////////////////
9 |
10 | namespace HtmlApp.Html {
11 | using System;
12 |
13 | ///
14 | /// Summary description for HtmlDocument.
15 | ///
16 | public class HtmlDocument {
17 |
18 | private HtmlEditor _editor;
19 |
20 | public HtmlDocument(HtmlEditor editor) {
21 | _editor = editor;
22 | }
23 |
24 | ///
25 | /// Indicates if a button can be inserted
26 | ///
27 | public bool CanInsertButton {
28 | get {
29 | return _editor.IsCommandEnabled(Interop.IDM_BUTTON);
30 | }
31 | }
32 |
33 | ///
34 | /// Indicates if a listbox can be inserted
35 | ///
36 | public bool CanInsertListBox {
37 | get {
38 | return _editor.IsCommandEnabled(Interop.IDM_LISTBOX);
39 | }
40 | }
41 |
42 | ///
43 | /// Indicates if HTML can be inserted
44 | ///
45 | public bool CanInsertHtml {
46 | get {
47 | if (Selection.Type == HtmlSelectionType.ElementSelection) {
48 | //If this is a control range, we can only insert HTML if we're in a div or span
49 | Interop.IHtmlControlRange controlRange = (Interop.IHtmlControlRange)Selection.MSHTMLSelection;
50 | int selectedItemCount = controlRange.GetLength();
51 | if (selectedItemCount == 1) {
52 | Interop.IHTMLElement element = controlRange.Item(0);
53 | if ((String.Compare(element.GetTagName(), "div", true) == 0) ||
54 | (String.Compare(element.GetTagName(), "td", true) == 0)) {
55 | return true;
56 | }
57 | }
58 | }
59 | else {
60 | //If this is a text range, we can definitely insert HTML
61 | return true;
62 | }
63 | return false;
64 | }
65 | }
66 |
67 | ///
68 | /// Indicates if an hyperlink can be inserted
69 | ///
70 | public bool CanInsertHyperlink {
71 | get {
72 | if (((Selection.Type == HtmlSelectionType.TextSelection) || (Selection.Type == HtmlSelectionType.Empty)) &&
73 | (Selection.Length == 0)) {
74 | return CanInsertHtml;
75 | }
76 | else {
77 | return _editor.IsCommandEnabled(Interop.IDM_HYPERLINK);
78 | }
79 | }
80 | }
81 |
82 | ///
83 | /// Indicates if a radio button can be inserted
84 | ///
85 | public bool CanInsertRadioButton {
86 | get {
87 |
88 | return _editor.IsCommandEnabled(Interop.IDM_RADIOBUTTON);
89 | }
90 | }
91 |
92 | ///
93 | /// Indicates if a text area can be inserted
94 | ///
95 | public bool CanInsertTextArea {
96 | get {
97 | return _editor.IsCommandEnabled(Interop.IDM_TEXTAREA);
98 | }
99 | }
100 |
101 | ///
102 | /// Indicates if a textbox can be inserted
103 | ///
104 | public bool CanInsertTextBox {
105 | get {
106 | return _editor.IsCommandEnabled(Interop.IDM_TEXTBOX);
107 | }
108 | }
109 |
110 | ///
111 | /// The current selection in the editor
112 | ///
113 | protected HtmlSelection Selection {
114 | get {
115 | return _editor.Selection;
116 | }
117 | }
118 |
119 | ///
120 | /// Inserts a button
121 | ///
122 | public void InsertButton() {
123 | _editor.Exec(Interop.IDM_BUTTON);
124 | }
125 |
126 | ///
127 | /// Inserts the specified string into the html over the current selection
128 | ///
129 | ///
130 | public void InsertHtml(string html) {
131 | Selection.SynchronizeSelection();
132 | if (Selection.Type == HtmlSelectionType.ElementSelection) {
133 | //If it's a control range, we can only insert if we are in a div or td
134 | Interop.IHtmlControlRange controlRange = (Interop.IHtmlControlRange)Selection.MSHTMLSelection;
135 | int selectedItemCount = controlRange.GetLength();
136 | if (selectedItemCount == 1) {
137 | Interop.IHTMLElement element = controlRange.Item(0);
138 | if ((String.Compare(element.GetTagName(), "div", true) == 0) ||
139 | (String.Compare(element.GetTagName(), "td", true) == 0)) {
140 | element.InsertAdjacentHTML("beforeEnd", html);
141 | }
142 | }
143 | }
144 | else {
145 | Interop.IHTMLTxtRange textRange = (Interop.IHTMLTxtRange)Selection.MSHTMLSelection;
146 | textRange.PasteHTML(html);
147 | }
148 | }
149 |
150 | ///
151 | /// Inserts a hyperlink with the specified URL and description
152 | ///
153 | ///
154 | ///
155 | public void InsertHyperlink(string url, string description) {
156 | Selection.SynchronizeSelection();
157 | if (url == null) {
158 | try {
159 | _editor.ExecPrompt(Interop.IDM_HYPERLINK);
160 | }
161 | catch {} // don't care if it fails!
162 | }
163 | else {
164 | if (((Selection.Type == HtmlSelectionType.TextSelection) || (Selection.Type == HtmlSelectionType.Empty)) &&
165 | (Selection.Length == 0)) {
166 | InsertHtml(""+description+"");
167 | /*Interop.IHTMLTxtRange textRange = (Interop.IHTMLTxtRange)Selection.MSHTMLSelection;
168 | textRange.PasteHTML(""+description+"");*/
169 | }
170 | else {
171 | _editor.Exec(Interop.IDM_HYPERLINK, url);
172 | }
173 | }
174 | }
175 |
176 | ///
177 | /// Inserts a list box
178 | ///
179 | public void InsertListBox() {
180 | _editor.Exec(Interop.IDM_LISTBOX);
181 | }
182 |
183 | ///
184 | /// Inserts a radio button
185 | ///
186 | public void InsertRadioButton() {
187 | _editor.Exec(Interop.IDM_RADIOBUTTON);
188 | }
189 |
190 | ///
191 | /// Inserts a text area
192 | ///
193 | public void InsertTextArea() {
194 | _editor.Exec(Interop.IDM_TEXTAREA);
195 | }
196 |
197 | ///
198 | /// Inserts a text box
199 | ///
200 | public void InsertTextBox() {
201 | _editor.Exec(Interop.IDM_TEXTBOX);
202 | }
203 | }
204 | }
205 |
--------------------------------------------------------------------------------
/HtmlViewer/HtmlEditor.cs:
--------------------------------------------------------------------------------
1 | ///////////////////////////////////////////////////////////////////////////////
2 | // HTML Control and HTML Editor Sample
3 | // Copyright 2003, Nikhil Kothari. All Rights Reserved.
4 | //
5 | // Provided as is, in sample form with no associated warranties.
6 | // For more information on usage, see the accompanying
7 | // License.txt file.
8 | ///////////////////////////////////////////////////////////////////////////////
9 |
10 | namespace HtmlApp.Html {
11 | using System;
12 | using System.Collections;
13 | using System.Diagnostics;
14 | using System.ComponentModel.Design;
15 | using System.Runtime.InteropServices;
16 | using System.Windows.Forms;
17 |
18 | ///
19 | /// Summary description for HtmlEditor.
20 | ///
21 | public class HtmlEditor : HtmlControl {
22 | private bool _absolutePositioningEnabled;
23 | private bool _absolutePositioningDesired;
24 |
25 | private bool _bordersVisible;
26 | private bool _bordersDesired;
27 |
28 | private bool _designModeEnabled;
29 | private bool _designModeDesired;
30 |
31 | private bool _multipleSelectionEnabled;
32 | private bool _multipleSelectionDesired;
33 |
34 | private HtmlTextFormatting textFormatting;
35 | private HtmlDocument document;
36 | private HtmlSelection _selection;
37 |
38 | Interop.IPersistStreamInit _persistStream;
39 |
40 | private Interop.IOleUndoManager _undoManager;
41 |
42 | private Interop.IHTMLEditServices _editServices;
43 |
44 | public HtmlEditor() : this(true) {
45 | }
46 |
47 | internal HtmlEditor(bool fullDocumentMode) : base(fullDocumentMode) {
48 | }
49 |
50 | ///
51 | /// Enables or disables absolute position for the entire editor
52 | ///
53 | public bool AbsolutePositioningEnabled {
54 | get {
55 | return _absolutePositioningEnabled;
56 | }
57 | set {
58 | //If the control isn't ready to be put into abs pos mode,
59 | //set a flag and put it in abs pos mode when it is ready
60 | _absolutePositioningDesired = value;
61 | if (!IsCreated) {
62 | return;
63 | }
64 | else {
65 | //Turn abs pos mode on or off depending on the new value
66 | _absolutePositioningEnabled = value;
67 | object[] args = new object[] { _absolutePositioningEnabled };
68 | Exec(Interop.IDM_2D_POSITION, args);
69 | }
70 | }
71 | }
72 |
73 | public bool BordersVisible {
74 | get {
75 | return _bordersVisible;
76 | }
77 | set {
78 | _bordersDesired = value;
79 | if (!IsReady) {
80 | return;
81 | }
82 | if (_bordersVisible != _bordersDesired) {
83 | _bordersVisible = value;
84 | object[] args = new object[] { _bordersVisible };
85 | Exec(Interop.IDM_SHOWZEROBORDERATDESIGNTIME,args);
86 | }
87 | }
88 | }
89 |
90 | ///
91 | /// Indicates if the editor is in design mode
92 | /// Also places MSHTML into design mode if set to true
93 | ///
94 | public bool DesignModeEnabled {
95 | get {
96 | return _designModeEnabled;
97 | }
98 | set {
99 | //Only execute this if we aren't already in design mode
100 | if (_designModeEnabled != value) {
101 | //If the control isn't ready to be put into design mode,
102 | //set a flag and put it in design mode when it is ready
103 | if (!IsCreated) {
104 | _designModeDesired = value;
105 | }
106 | else {
107 | //Turn design mode on or off depending on the new value
108 | _designModeEnabled = value;
109 | MSHTMLDocument.SetDesignMode((_designModeEnabled ? "on" : "off"));
110 | }
111 | }
112 | }
113 | }
114 |
115 | ///
116 | /// Returns the document object for doing insertions
117 | ///
118 | public HtmlDocument Document {
119 | get {
120 | if (!IsReady) {
121 | throw new Exception("HtmlDocument not ready yet!");
122 | }
123 | if (document == null) {
124 | document = new HtmlDocument(this);
125 | }
126 | return document;
127 | }
128 | }
129 |
130 | private Interop.IHTMLEditServices MSHTMLEditServices {
131 | get {
132 | if (_editServices==null) {
133 | Interop.IServiceProvider serviceProvider = MSHTMLDocument as Interop.IServiceProvider;
134 | Debug.Assert(serviceProvider != null);
135 | Guid shtmlGuid = new Guid(0x3050f7f9,0x98b5,0x11cf,0xbb,0x82,0x00,0xaa,0x00,0xbd,0xce,0x0b);
136 | Guid intGuid = (typeof(Interop.IHTMLEditServices)).GUID;
137 |
138 | IntPtr editServicePtr = Interop.NullIntPtr;
139 | int hr = serviceProvider.QueryService(ref shtmlGuid, ref intGuid, out editServicePtr);
140 | Debug.Assert((hr == Interop.S_OK) && (editServicePtr != Interop.NullIntPtr), "Did not get IHTMLEditService");
141 | if ((hr == Interop.S_OK) && (editServicePtr != Interop.NullIntPtr)) {
142 | _editServices = (Interop.IHTMLEditServices) Marshal.GetObjectForIUnknown(editServicePtr);
143 | Marshal.Release(editServicePtr);
144 | }
145 | }
146 | return _editServices;
147 | }
148 | }
149 | ///
150 | /// Indicates if the contents of the editor have been modified
151 | ///
152 | public virtual bool IsDirty {
153 | get {
154 | if (DesignModeEnabled && IsReady) {
155 | if (_persistStream != null) {
156 | //TODO: After a load, this is no longer true, what do we do???
157 | if (_persistStream.IsDirty() == Interop.S_OK) {
158 | return true;
159 | }
160 | }
161 | }
162 | return false;
163 | }
164 | }
165 |
166 | ///
167 | /// Indicates if multiple selection is enabled in the editor
168 | /// Also places MSHTML into multiple selection mode if set to true
169 | ///
170 | public bool MultipleSelectionEnabled {
171 | get {
172 | return _multipleSelectionEnabled;
173 | }
174 | set {
175 | //If the control isn't ready yet, postpone setting multiple selection
176 | _multipleSelectionDesired = value;
177 | if (!IsReady) {
178 | return;
179 | }
180 | else {
181 | //Create an objects array to pass parameters to the MSHTML command target
182 | _multipleSelectionEnabled = value;
183 | object[] args = new object[] { _multipleSelectionEnabled };
184 | int hr = CommandTarget.Exec(ref Interop.Guid_MSHTML, Interop.IDM_MULTIPLESELECTION, 0, args, null);
185 | Debug.Assert(hr == Interop.S_OK);
186 | }
187 | }
188 | }
189 |
190 | ///
191 | /// The current selection in the editor
192 | ///
193 | public HtmlSelection Selection {
194 | get {
195 | if (_selection == null) {
196 | _selection = CreateSelection();
197 | }
198 | return _selection;
199 | }
200 | }
201 |
202 | ///
203 | /// The text formatting element of the editor
204 | ///
205 | public HtmlTextFormatting TextFormatting {
206 | get {
207 | if (!IsReady) {
208 | throw new Exception("HtmlDocument not ready yet!");
209 | }
210 | if (textFormatting == null) {
211 | textFormatting = new HtmlTextFormatting(this);
212 | }
213 | return textFormatting;
214 | }
215 | }
216 |
217 | private Interop.IOleUndoManager UndoManager {
218 | get {
219 | if (_undoManager == null) {
220 | Interop.IServiceProvider serviceProvider = MSHTMLDocument as Interop.IServiceProvider;
221 | Debug.Assert(serviceProvider != null);
222 | Guid undoManagerGuid = typeof(Interop.IOleUndoManager).GUID;
223 | Guid undoManagerGuid2 = typeof(Interop.IOleUndoManager).GUID;
224 | IntPtr undoManagerPtr = Interop.NullIntPtr;
225 | int hr = serviceProvider.QueryService(ref undoManagerGuid2, ref undoManagerGuid, out undoManagerPtr);
226 | if ((hr == Interop.S_OK) && (undoManagerPtr != Interop.NullIntPtr)) {
227 | _undoManager = (Interop.IOleUndoManager)Marshal.GetObjectForIUnknown(undoManagerPtr);
228 | Marshal.Release(undoManagerPtr);
229 | }
230 | }
231 | return _undoManager;
232 | }
233 | }
234 |
235 | ///
236 | ///
237 | public void ClearDirtyState() {
238 | if (!IsReady)
239 | return;
240 | Exec(Interop.IDM_SETDIRTY,false);
241 | }
242 |
243 | ///
244 | ///
245 | protected virtual HtmlSelection CreateSelection() {
246 | return new HtmlSelection(this);
247 | }
248 |
249 | protected override void OnAfterSave() {
250 | // In non-full document mode, we don't actually save the IPersistInitStream, so
251 | // clear the dirty bit here
252 | if (!IsFullDocumentMode) {
253 | ClearDirtyState();
254 | }
255 | }
256 |
257 | ///
258 | /// Overridden to remove the grid behavior before loading
259 | ///
260 | protected override void OnBeforeLoad() {
261 | //are already visible
262 | if (BordersVisible) {
263 | BordersVisible = false;
264 | _bordersDesired = true;
265 | }
266 | }
267 | ///
268 | /// Overridden to activate design and multiple selection modes
269 | ///
270 | ///
271 | protected override void OnCreated(EventArgs args) {
272 | if (args == null) {
273 | throw new ArgumentNullException("You must specify a non-null EventArgs for OnCreated");
274 | }
275 |
276 | base.OnCreated(args);
277 |
278 | object[] mshtmlArgs = new object[1];
279 |
280 | mshtmlArgs[0] = true;
281 | CommandTarget.Exec(ref Interop.Guid_MSHTML, Interop.IDM_PERSISTDEFAULTVALUES, 0, mshtmlArgs, null);
282 |
283 | mshtmlArgs[0] = true;
284 | CommandTarget.Exec(ref Interop.Guid_MSHTML, Interop.IDM_PROTECTMETATAGS, 0, mshtmlArgs, null);
285 |
286 | mshtmlArgs[0] = true;
287 | CommandTarget.Exec(ref Interop.Guid_MSHTML, Interop.IDM_PRESERVEUNDOALWAYS, 0, mshtmlArgs, null);
288 |
289 | mshtmlArgs[0] = true;
290 | CommandTarget.Exec(ref Interop.Guid_MSHTML, Interop.IDM_NOACTIVATENORMALOLECONTROLS, 0, mshtmlArgs, null);
291 |
292 | mshtmlArgs[0] = true;
293 | CommandTarget.Exec(ref Interop.Guid_MSHTML, Interop.IDM_NOACTIVATEDESIGNTIMECONTROLS, 0, mshtmlArgs, null);
294 |
295 | mshtmlArgs[0] = true;
296 | CommandTarget.Exec(ref Interop.Guid_MSHTML, Interop.IDM_NOACTIVATEJAVAAPPLETS, 0, mshtmlArgs, null);
297 |
298 | mshtmlArgs[0] = true;
299 | CommandTarget.Exec(ref Interop.Guid_MSHTML, Interop.IDM_NOFIXUPURLSONPASTE, 0, mshtmlArgs, null);
300 |
301 | //Set the design mode to the last desired design mode
302 | if (_designModeDesired) {
303 | DesignModeEnabled = _designModeDesired;
304 | _designModeDesired = false;
305 | }
306 |
307 | }
308 |
309 | ///
310 | /// Overridden to set the design mode to the last desired design mode and multiple selection flag
311 | /// to the last desired multiple selection flag
312 | ///
313 | ///
314 | protected override internal void OnReadyStateComplete(EventArgs args) {
315 | base.OnReadyStateComplete(args);
316 |
317 | _persistStream = (Interop.IPersistStreamInit)MSHTMLDocument;
318 |
319 | Selection.SynchronizeSelection();
320 |
321 | //Set the mutiple selection mode to the last desired multiple selection mode
322 | if (_multipleSelectionDesired) {
323 | MultipleSelectionEnabled = _multipleSelectionDesired;
324 | }
325 |
326 | //Set the absolute positioning mode to the last desired absolute position mode
327 | if (_absolutePositioningDesired) {
328 | AbsolutePositioningEnabled = _absolutePositioningDesired;
329 | }
330 |
331 | //Set the absolute positioning mode to the last desired absolute position mode
332 | if (_bordersDesired) {
333 | BordersVisible = _bordersDesired;
334 | }
335 |
336 | }
337 | }
338 | }
339 |
--------------------------------------------------------------------------------
/HtmlViewer/HtmlFontSize.cs:
--------------------------------------------------------------------------------
1 | ///////////////////////////////////////////////////////////////////////////////
2 | // HTML Control and HTML Editor Sample
3 | // Copyright 2003, Nikhil Kothari. All Rights Reserved.
4 | //
5 | // Provided as is, in sample form with no associated warranties.
6 | // For more information on usage, see the accompanying
7 | // License.txt file.
8 | ///////////////////////////////////////////////////////////////////////////////
9 |
10 | namespace HtmlApp.Html {
11 |
12 | public enum HtmlFontSize {
13 | Smallest = 1,
14 | Smaller = 2,
15 | Small = 3,
16 | Medium = 4,
17 | Large = 5,
18 | Larger = 6,
19 | Largest = 7
20 | }
21 | }
--------------------------------------------------------------------------------
/HtmlViewer/HtmlFormat.cs:
--------------------------------------------------------------------------------
1 | ///////////////////////////////////////////////////////////////////////////////
2 | // HTML Control and HTML Editor Sample
3 | // Copyright 2003, Nikhil Kothari. All Rights Reserved.
4 | //
5 | // Provided as is, in sample form with no associated warranties.
6 | // For more information on usage, see the accompanying
7 | // License.txt file.
8 | ///////////////////////////////////////////////////////////////////////////////
9 |
10 | namespace HtmlApp.Html {
11 | using System;
12 |
13 | public enum HtmlFormat {
14 | Normal = 0,
15 | Formatted = 1,
16 | Heading1 = 2,
17 | Heading2 = 3,
18 | Heading3 = 4,
19 | Heading4 = 5,
20 | Heading5 = 6,
21 | Heading6 = 7,
22 | Paragraph = 8,
23 | OrderedList = 9,
24 | UnorderedList = 10
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/HtmlViewer/HtmlSelection.cs:
--------------------------------------------------------------------------------
1 | ///////////////////////////////////////////////////////////////////////////////
2 | // HTML Control and HTML Editor Sample
3 | // Copyright 2003, Nikhil Kothari. All Rights Reserved.
4 | //
5 | // Provided as is, in sample form with no associated warranties.
6 | // For more information on usage, see the accompanying
7 | // License.txt file.
8 | ///////////////////////////////////////////////////////////////////////////////
9 |
10 | namespace HtmlApp.Html {
11 | using System;
12 | using System.Diagnostics;
13 | using System.Collections;
14 | using System.Runtime.InteropServices;
15 |
16 | ///
17 | /// Summary description for HtmlSelection.
18 | ///
19 | public class HtmlSelection {
20 |
21 | public static readonly string DesignTimeLockAttribute = "Design_Time_Lock";
22 |
23 | private EventHandler _selectionChangedHandler;
24 |
25 | private HtmlEditor _editor;
26 | private Interop.IHTMLDocument2 _document;
27 | private HtmlSelectionType _type;
28 | private int _selectionLength;
29 | private string _text;
30 | private object _mshtmlSelection;
31 | private ArrayList _items;
32 | private ArrayList _elements;
33 | private bool _sameParentValid;
34 | private int _maxZIndex;
35 |
36 | public HtmlSelection(HtmlEditor editor) {
37 | _editor = editor;
38 | _maxZIndex = 99;
39 | }
40 |
41 | ///
42 | /// Indicates if the current selection can be aligned
43 | ///
44 | public bool CanAlign {
45 | get {
46 | if (_items.Count < 2) {
47 | return false;
48 | }
49 | if (_type == HtmlSelectionType.ElementSelection) {
50 | foreach (Interop.IHTMLElement elem in _items) {
51 | //First check if they are all absolutely positioned
52 | if (!IsElement2DPositioned(elem)) {
53 | return false;
54 | }
55 |
56 | //Then check if none of them are locked
57 | if (IsElementLocked(elem)) {
58 | return false;
59 | }
60 | }
61 | //Then check if they all have the same parent
62 | if (!SameParent) {
63 | return false;
64 | }
65 | return true;
66 | }
67 | return false;
68 | }
69 | }
70 |
71 | ///
72 | /// Indicates if the current selection can be size-matched
73 | ///
74 | public bool CanMatchSize {
75 | get {
76 | if (_items.Count < 2) {
77 | return false;
78 | }
79 | if (_type == HtmlSelectionType.ElementSelection) {
80 | foreach (Interop.IHTMLElement elem in _items) {
81 | //Then check if none of them are locked
82 | if (IsElementLocked(elem)) {
83 | return false;
84 | }
85 | }
86 | //Then check if they all have the same parent
87 | if (!SameParent) {
88 | return false;
89 | }
90 | return true;
91 | }
92 | return false;
93 | }
94 | }
95 |
96 | ///
97 | /// Indicates if the current selection can have it's hyperlink removed
98 | ///
99 | public bool CanRemoveHyperlink {
100 | get {
101 | return _editor.IsCommandEnabled(Interop.IDM_UNLINK);
102 | }
103 | }
104 |
105 | ///
106 | /// Indicates if the current selection have it's z-index modified
107 | ///
108 | public bool CanChangeZIndex {
109 | get {
110 | if (_items.Count == 0) {
111 | return false;
112 | }
113 | if (_type == HtmlSelectionType.ElementSelection) {
114 | foreach (Interop.IHTMLElement elem in _items) {
115 | //First check if they are all absolutely positioned
116 | if (!IsElement2DPositioned(elem)) {
117 | return false;
118 | }
119 | }
120 | //Then check if they all have the same parent
121 | if (!SameParent) {
122 | return false;
123 | }
124 | return true;
125 | }
126 | return false;
127 | }
128 | }
129 |
130 | ///
131 | /// Indicates if the current selection can be wrapped in HTML tags
132 | ///
133 | public bool CanWrapSelection {
134 | get {
135 | if ((_selectionLength != 0) && (Type == HtmlSelectionType.TextSelection)) {
136 | return true;
137 | }
138 | return false;
139 | }
140 | }
141 |
142 | protected HtmlEditor Editor {
143 | get {
144 | return _editor;
145 | }
146 | }
147 |
148 | public ICollection Elements {
149 | get {
150 | if (_elements == null) {
151 | _elements = new ArrayList();
152 | foreach (Interop.IHTMLElement element in _items) {
153 | object wrapper = CreateElementWrapper(element);
154 | if (wrapper != null) {
155 | _elements.Add(wrapper);
156 | }
157 | }
158 | }
159 | return _elements;
160 | }
161 | }
162 |
163 | ///
164 | /// All selected items
165 | ///
166 | internal ICollection Items {
167 | get {
168 | return _items;
169 | }
170 | }
171 |
172 | public int Length {
173 | get {
174 | return _selectionLength;
175 | }
176 | }
177 |
178 | ///
179 | /// Indicates if all items in the selection have the same parent element
180 | ///
181 | private bool SameParent {
182 | get {
183 | if (!_sameParentValid) {
184 | IntPtr primaryParentElementPtr = Interop.NullIntPtr;
185 |
186 | foreach (Interop.IHTMLElement elem in _items) {
187 | //Check if all items have the same parent by doing pointer equality
188 | Interop.IHTMLElement parentElement = elem.GetParentElement();
189 | IntPtr parentElementPtr = Marshal.GetIUnknownForObject(parentElement);
190 | //If we haven't gotten a primary parent element (ie, this is the first time through the loop)
191 | //Remember what the this parent element is
192 | if (primaryParentElementPtr == Interop.NullIntPtr) {
193 | primaryParentElementPtr = parentElementPtr;
194 | }
195 | else {
196 | //Check the pointers
197 | if (primaryParentElementPtr != parentElementPtr) {
198 | Marshal.Release(parentElementPtr);
199 | if (primaryParentElementPtr != Interop.NullIntPtr) {
200 | Marshal.Release(primaryParentElementPtr);
201 | }
202 | _sameParentValid = false;
203 | return _sameParentValid;
204 | }
205 | Marshal.Release(parentElementPtr);
206 | }
207 | }
208 | if (primaryParentElementPtr != Interop.NullIntPtr) {
209 | Marshal.Release(primaryParentElementPtr);
210 | }
211 | _sameParentValid = true;
212 | }
213 | return _sameParentValid;
214 | }
215 | }
216 |
217 | public event EventHandler SelectionChanged {
218 | add {
219 | _selectionChangedHandler = (EventHandler)Delegate.Combine(_selectionChangedHandler, value);
220 | }
221 | remove {
222 | if (_selectionChangedHandler != null) {
223 | _selectionChangedHandler = (EventHandler)Delegate.Remove(_selectionChangedHandler, value);
224 | }
225 | }
226 | }
227 |
228 | ///
229 | /// Returns the MSHTML selection object (IHTMLTxtRange or IHTMLControlRange)
230 | /// Does not synchronize the selection!!! Uses the selection from the last synchronization
231 | ///
232 | protected internal object MSHTMLSelection {
233 | get {
234 | return _mshtmlSelection;
235 | }
236 | }
237 |
238 | ///
239 | /// Returns the text contained in the selection if there is a text selection
240 | ///
241 | public string Text {
242 | get {
243 | if (_type == HtmlSelectionType.TextSelection) {
244 | return _text;
245 | }
246 | return null;
247 | }
248 | }
249 |
250 | ///
251 | /// The HtmlSelectionType of the selection
252 | ///
253 | public HtmlSelectionType Type {
254 | get {
255 | return _type;
256 | }
257 | }
258 |
259 | public void ClearSelection() {
260 | _editor.Exec(Interop.IDM_CLEARSELECTION);
261 | }
262 |
263 | protected virtual object CreateElementWrapper(Interop.IHTMLElement element) {
264 | return Element.GetWrapperFor(element, _editor);
265 | }
266 |
267 | ///
268 | /// Returns info about the absolute positioning of the selection
269 | ///
270 | ///
271 | public HtmlCommandInfo GetAbsolutePositionInfo() {
272 | return _editor.GetCommandInfo(Interop.IDM_ABSOLUTE_POSITION);
273 | }
274 |
275 | ///
276 | /// Returns info about the design time lock state of the selection
277 | ///
278 | ///
279 | public HtmlCommandInfo GetLockInfo() {
280 | if (_type == HtmlSelectionType.ElementSelection) {
281 | foreach (Interop.IHTMLElement elem in _items) {
282 | //We only need to check that all elements are absolutely positioned
283 | if (!IsElement2DPositioned(elem)) {
284 | return (HtmlCommandInfo)0;
285 | }
286 |
287 | if (IsElementLocked(elem)) {
288 | return HtmlCommandInfo.Checked | HtmlCommandInfo.Enabled;
289 | }
290 | return HtmlCommandInfo.Enabled;
291 | }
292 | }
293 | return (HtmlCommandInfo)0;
294 | }
295 |
296 | public string GetOuterHtml() {
297 | Debug.Assert(Items.Count == 1, "Can't get OuterHtml of more than one element");
298 |
299 | string outerHtml = String.Empty;
300 | try {
301 | outerHtml = ((Interop.IHTMLElement)_items[0]).GetOuterHTML();
302 |
303 | // Call this twice because, in the first call, Trident will call OnContentSave, which calls SetInnerHtml, but
304 | // the outer HTML it returns does not include that new inner HTML.
305 | outerHtml = ((Interop.IHTMLElement)_items[0]).GetOuterHTML();
306 | }
307 | catch {
308 | }
309 |
310 | return outerHtml;
311 | }
312 |
313 | public ArrayList GetParentHierarchy(object o) {
314 | Interop.IHTMLElement current = GetIHtmlElement(o);
315 | if (current == null) {
316 | return null;
317 | }
318 |
319 | string tagName = current.GetTagName().ToLower();
320 | if (tagName.Equals("body")) {
321 | return null;
322 | }
323 |
324 | ArrayList ancestors = new ArrayList();
325 |
326 | current = current.GetParentElement();
327 | while ((current != null) && (current.GetTagName().ToLower().Equals("body") == false)) {
328 | Element element = Element.GetWrapperFor(current, _editor);
329 | if (IsSelectableElement(element)) {
330 | ancestors.Add(element);
331 | }
332 | current = current.GetParentElement();
333 | }
334 |
335 | // Don't add the body tag to the hierarchy if we aren't in full document mode
336 | if (current != null) {
337 | Element element = Element.GetWrapperFor(current, _editor);
338 | if (IsSelectableElement(element)) {
339 | ancestors.Add(element);
340 | }
341 | }
342 |
343 | return ancestors;
344 | }
345 |
346 | protected virtual Interop.IHTMLElement GetIHtmlElement(object o) {
347 | if (o is Element) {
348 | return ((Element)o).Peer;
349 | }
350 | return null;
351 | }
352 |
353 | ///
354 | /// Convenience method for checking if the specified element is absolutely positioned
355 | ///
356 | ///
357 | ///
358 | private bool IsElement2DPositioned(Interop.IHTMLElement elem) {
359 | Interop.IHTMLElement2 elem2 = (Interop.IHTMLElement2) elem;
360 | Interop.IHTMLCurrentStyle style = elem2.GetCurrentStyle();
361 | string position = style.GetPosition();
362 | if ((position == null) || (String.Compare(position, "absolute", true) != 0)) {
363 | return false;
364 | }
365 | return true;
366 | }
367 |
368 | ///
369 | /// Convenience method for checking if the specified element has a design time lock
370 | ///
371 | ///
372 | ///
373 | private bool IsElementLocked(Interop.IHTMLElement elem) {
374 | object[] attribute = new object[1];
375 | elem.GetAttribute(DesignTimeLockAttribute,0,attribute);
376 | if (attribute[0] == null) {
377 | Interop.IHTMLStyle style = elem.GetStyle();
378 | attribute[0] = style.GetAttribute(DesignTimeLockAttribute,0);
379 | }
380 | if ((attribute[0] == null) || !(attribute[0] is string)) {
381 | return false;
382 | }
383 | return true;
384 | }
385 |
386 | protected virtual bool IsSelectableElement(Element element) {
387 | return (_editor.IsFullDocumentMode || (element.TagName.ToLower() != "body"));
388 | }
389 |
390 | protected virtual void OnSelectionChanged() {
391 | if (_selectionChangedHandler != null) {
392 | _selectionChangedHandler.Invoke(this, EventArgs.Empty);
393 | }
394 | }
395 |
396 | public bool SelectElement(object o) {
397 | ArrayList list = new ArrayList(1);
398 | list.Add(o);
399 | return SelectElements(list);
400 | }
401 |
402 | public bool SelectElements(ICollection elements) {
403 | Interop.IHTMLElement body = _editor.MSHTMLDocument.GetBody();
404 | Interop.IHTMLTextContainer container = body as Interop.IHTMLTextContainer;
405 | Debug.Assert(container != null);
406 | object controlRange = container.createControlRange();
407 |
408 | Interop.IHtmlControlRange htmlControlRange = controlRange as Interop.IHtmlControlRange;
409 | Debug.Assert(htmlControlRange != null);
410 | if (htmlControlRange == null) {
411 | return false;
412 | }
413 |
414 | Interop.IHtmlControlRange2 htmlControlRange2 = controlRange as Interop.IHtmlControlRange2;
415 | Debug.Assert(htmlControlRange2 != null);
416 | if (htmlControlRange2 == null) {
417 | return false;
418 | }
419 |
420 |
421 | int hr = 0;
422 | foreach (object o in elements) {
423 | Interop.IHTMLElement element = GetIHtmlElement(o);
424 | if (element == null) {
425 | return false;
426 | }
427 | hr = htmlControlRange2.addElement(element);
428 | if (hr != Interop.S_OK) {
429 | break;
430 | }
431 | }
432 | if (hr == Interop.S_OK) {
433 | //If it succeeded, simply select the control range
434 | htmlControlRange.Select();
435 | }
436 | else {
437 | // elements like DIV and SPAN, w/o layout, cannot be added to a control selelction.
438 | Interop.IHtmlBodyElement bodyElement = (Interop.IHtmlBodyElement)body;
439 | Interop.IHTMLTxtRange textRange = bodyElement.createTextRange();
440 | if (textRange != null) {
441 | foreach (object o in elements) {
442 | try {
443 | Interop.IHTMLElement element = GetIHtmlElement(o);
444 | if (element == null) {
445 | return false;
446 | }
447 | textRange.MoveToElementText(element);
448 | }
449 | catch {
450 | }
451 | }
452 | textRange.Select();
453 | }
454 | }
455 | return true;
456 | }
457 |
458 | // ///
459 | // /// Sends all selected items to the back
460 | // ///
461 | // public void SendToBack() {
462 | // //TODO: How do we compress the ZIndexes so they never go out of the range of an int
463 | // SynchronizeSelection();
464 | // if (_type == HtmlSelectionType.ElementSelection) {
465 | // if (_items.Count > 1) {
466 | // //We have to move all items to the back, and maintain their ordering, so
467 | // //Find the maximum ZIndex in the group
468 | // int max = _minZIndex;
469 | // int count = _items.Count;
470 | // Interop.IHTMLStyle[] styles = new Interop.IHTMLStyle[count];
471 | // int[] zIndexes = new int[count];
472 | // for (int i = 0; i < count; i++) {
473 | // Interop.IHTMLElement elem = (Interop.IHTMLElement)_items[i];
474 | // styles[i] = elem.GetStyle();
475 | // zIndexes[i] = (int)styles[i].GetZIndex();
476 | // if (zIndexes[i] > max) {
477 | // max = zIndexes[i];
478 | // }
479 | // }
480 | // //Calculate how far the first element has to be moved in order to be in the back
481 | // int offset = max - (_minZIndex - 1);
482 | // BatchedUndoUnit unit = _editor.OpenBatchUndo("Align Left");
483 | // try {
484 | // //Then send all items in the selection that far back
485 | // for (int i = 0; i < count; i++) {
486 | // int newPos = zIndexes[i] - offset;
487 | // if (zIndexes[i] == _maxZIndex) {
488 | // _maxZIndex--;
489 | // }
490 | // styles[i].SetZIndex(newPos);
491 | // if (newPos < _minZIndex) {
492 | // _minZIndex = newPos;
493 | // }
494 | // }
495 | // }
496 | // catch (Exception e) {
497 | // System.Windows.Forms.MessageBox.Show(e.ToString(),"Exception");
498 | // }
499 | // finally {
500 | // unit.Close();
501 | // }
502 | // }
503 | // else {
504 | // Interop.IHTMLElement elem = (Interop.IHTMLElement)_items[0];
505 | // object zIndex = elem.GetStyle().GetZIndex();
506 | // if ((zIndex != null) && !(zIndex is DBNull)) {
507 | // if ((int)zIndex == _minZIndex) {
508 | // // if the element is already in the back do nothing.
509 | // return;
510 | // }
511 | //
512 | // if ((int)zIndex == _maxZIndex) {
513 | // _maxZIndex--;
514 | // }
515 | // }
516 | // elem.GetStyle().SetZIndex(--_minZIndex);
517 | // }
518 | // }
519 | // }
520 |
521 | public void SetOuterHtml(string outerHtml) {
522 | Debug.Assert(Items.Count == 1, "Can't get OuterHtml of more than one element");
523 | ((Interop.IHTMLElement)_items[0]).SetOuterHTML(outerHtml);
524 | }
525 |
526 | ///
527 | /// Synchronizes the selection state held in this object with the selection state in MSHTML
528 | ///
529 | /// true if the selection has changed
530 | public bool SynchronizeSelection() {
531 | //Get the selection object from the MSHTML document
532 | if (_document == null) {
533 | _document = _editor.MSHTMLDocument;
534 | }
535 | Interop.IHTMLSelectionObject selectionObj = _document.GetSelection();
536 |
537 | //Get the current selection from that selection object
538 | object currentSelection = null;
539 | try {
540 | currentSelection = selectionObj.CreateRange();
541 | }
542 | catch {
543 | }
544 |
545 | ArrayList oldItems = _items;
546 | HtmlSelectionType oldType = _type;
547 | int oldLength = _selectionLength;
548 | //Default to an empty selection
549 | _type = HtmlSelectionType.Empty;
550 | _selectionLength = 0;
551 | if (currentSelection != null) {
552 | _mshtmlSelection = currentSelection;
553 | _items = new ArrayList();
554 | //If it's a text selection
555 | if (currentSelection is Interop.IHTMLTxtRange) {
556 | Interop.IHTMLTxtRange textRange = (Interop.IHTMLTxtRange) currentSelection;
557 | //IntPtr ptr = Marshal.GetIUnknownForObject(textRange);
558 | Interop.IHTMLElement parentElement = textRange.ParentElement();
559 | // If the document is in full document mode or we're selecting a non-body tag, allow it to select
560 | // otherwise, leave the selection as empty (since we don't want the body tag to be selectable on an ASP.NET
561 | // User Control
562 | if (IsSelectableElement(Element.GetWrapperFor(parentElement, _editor))) {
563 | //Add the parent of the text selection
564 | if (parentElement != null) {
565 | _text = textRange.GetText();
566 | if (_text != null) {
567 | _selectionLength = _text.Length;
568 | }
569 | else {
570 | _selectionLength = 0;
571 | }
572 | _type = HtmlSelectionType.TextSelection;
573 | _items.Add(parentElement);
574 | }
575 | }
576 | }
577 | //If it's a control selection
578 | else if (currentSelection is Interop.IHtmlControlRange) {
579 | Interop.IHtmlControlRange controlRange = (Interop.IHtmlControlRange) currentSelection;
580 | int selectedCount = controlRange.GetLength();
581 | //Add all elements selected
582 | if (selectedCount > 0) {
583 | _type = HtmlSelectionType.ElementSelection;
584 | for (int i = 0; i < selectedCount; i++) {
585 | Interop.IHTMLElement currentElement = controlRange.Item(i);
586 | _items.Add(currentElement);
587 | }
588 | _selectionLength = selectedCount;
589 | }
590 | }
591 | }
592 | _sameParentValid = false;
593 |
594 | bool selectionChanged = false;
595 | //Now check if there was a change of selection
596 | //If the two selections have different lengths, then the selection has changed
597 | if (_type != oldType) {
598 | selectionChanged = true;
599 | }
600 | else if (_selectionLength != oldLength) {
601 | selectionChanged = true;
602 | }
603 | else {
604 | if (_items != null) {
605 | //If the two selections have a different element, then the selection has changed
606 | for (int i = 0; i < _items.Count; i++) {
607 | if (_items[i] != oldItems[i]) {
608 | selectionChanged = true;
609 | break;
610 | }
611 | }
612 | }
613 | }
614 | if (selectionChanged) {
615 | //Set _elements to null so no one can retrieve a dirty copy of the selection element wrappers
616 | _elements = null;
617 |
618 | OnSelectionChanged();
619 | return true;
620 | }
621 |
622 | return false;
623 | }
624 | ///
625 | /// Toggle the absolute positioning state of the selected items
626 | ///
627 | public void ToggleAbsolutePosition() {
628 | _editor.Exec(Interop.IDM_ABSOLUTE_POSITION, !((GetAbsolutePositionInfo() & HtmlCommandInfo.Checked) != 0));
629 | SynchronizeSelection();
630 | if (_type == HtmlSelectionType.ElementSelection) {
631 | foreach (Interop.IHTMLElement elem in _items) {
632 | elem.GetStyle().SetZIndex(++_maxZIndex);
633 | }
634 | }
635 | }
636 |
637 | ///
638 | /// Toggle the design time lock state of the selected items
639 | ///
640 | public void ToggleLock() {
641 | //Switch the lock on each item
642 | foreach (Interop.IHTMLElement elem in _items) {
643 | Interop.IHTMLStyle style = elem.GetStyle();
644 | if (IsElementLocked(elem)) {
645 | //We need to remove attributes off the element and the style because of a bug in Trident
646 | elem.RemoveAttribute(DesignTimeLockAttribute,0);
647 | style.RemoveAttribute(DesignTimeLockAttribute,0);
648 | }
649 | else {
650 | //We need to add attributes to the element and the style because of a bug in Trident
651 | elem.SetAttribute(DesignTimeLockAttribute,"true",0);
652 | style.SetAttribute(DesignTimeLockAttribute,"true",0);
653 | }
654 | }
655 | }
656 |
657 | public void WrapSelection(string tag) {
658 | WrapSelection(tag, null);
659 | }
660 |
661 | public void WrapSelection(string tag, IDictionary attributes) {
662 | //Create a string for all the attributes
663 | string attributeString = String.Empty;
664 | if (attributes != null) {
665 | foreach (string key in attributes.Keys) {
666 | attributeString+=key+"=\""+attributes[key]+"\" ";
667 | }
668 | }
669 | SynchronizeSelection();
670 | if (_type == HtmlSelectionType.TextSelection) {
671 | Interop.IHTMLTxtRange textRange = (Interop.IHTMLTxtRange)MSHTMLSelection;
672 | string oldText = textRange.GetHtmlText();
673 | if (oldText == null) {
674 | oldText = String.Empty;
675 | }
676 | string newText = "<"+tag+" "+attributeString+">"+oldText+""+tag+">";
677 | textRange.PasteHTML(newText);
678 | }
679 | }
680 |
681 | public void WrapSelectionInDiv() {
682 | WrapSelection("div");
683 | }
684 |
685 | public void WrapSelectionInSpan() {
686 | WrapSelection("span");
687 | }
688 |
689 | public void WrapSelectionInBlockQuote() {
690 | WrapSelection("blockquote");
691 | }
692 |
693 | public void WrapSelectionInHyperlink(string url) {
694 | _editor.Exec(Interop.IDM_HYPERLINK,url);
695 | }
696 |
697 | public void RemoveHyperlink() {
698 | _editor.Exec(Interop.IDM_UNLINK);
699 | }
700 | }
701 | }
702 |
--------------------------------------------------------------------------------
/HtmlViewer/HtmlSelectionType.cs:
--------------------------------------------------------------------------------
1 | ///////////////////////////////////////////////////////////////////////////////
2 | // HTML Control and HTML Editor Sample
3 | // Copyright 2003, Nikhil Kothari. All Rights Reserved.
4 | //
5 | // Provided as is, in sample form with no associated warranties.
6 | // For more information on usage, see the accompanying
7 | // License.txt file.
8 | ///////////////////////////////////////////////////////////////////////////////
9 |
10 | namespace HtmlApp.Html {
11 | using System;
12 |
13 | public enum HtmlSelectionType {
14 | Empty = 0,
15 | TextSelection = 1,
16 | ElementSelection = 2
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/HtmlViewer/HtmlTextFormatting.cs:
--------------------------------------------------------------------------------
1 | ///////////////////////////////////////////////////////////////////////////////
2 | // HTML Control and HTML Editor Sample
3 | // Copyright 2003, Nikhil Kothari. All Rights Reserved.
4 | //
5 | // Provided as is, in sample form with no associated warranties.
6 | // For more information on usage, see the accompanying
7 | // License.txt file.
8 | ///////////////////////////////////////////////////////////////////////////////
9 |
10 | namespace HtmlApp.Html {
11 |
12 | using System;
13 | using System.ComponentModel;
14 | using System.Diagnostics;
15 | using System.Drawing;
16 |
17 | ///
18 | /// Summary description for HtmlTextFormatting.
19 | ///
20 | public class HtmlTextFormatting {
21 |
22 | ///
23 | /// Array of the names of HTML formats that MSHTML accepts
24 | /// These need to be in the same order as the enum HtmlFormat
25 | ///
26 | private static readonly string[] formats =
27 | new string[] {
28 | "Normal", // Normal
29 | "Formatted", // PreFormatted
30 | "Heading 1", // Heading1
31 | "Heading 2", // Heading2
32 | "Heading 3", // Heading3
33 | "Heading 4", // Heading4
34 | "Heading 5", // Heading5
35 | "Heading 6", // Heading6
36 | "Paragraph", // Paragraph
37 | "Numbered List", // OrderedList
38 | "Bulleted List" // UnorderedList
39 | };
40 |
41 | public HtmlEditor editor;
42 |
43 | ///
44 | /// Constructor which simply takes an HtmlEditor to interface with MSHTML
45 | ///
46 | ///
47 | public HtmlTextFormatting(HtmlEditor editor) {
48 | this.editor = editor;
49 | }
50 |
51 | ///
52 | /// The background color of the current text
53 | ///
54 | public Color BackColor {
55 | get {
56 | //Query MSHTML, convert the result, and return the color
57 | return ConvertMSHTMLColor(editor.ExecResult(Interop.IDM_BACKCOLOR));
58 | }
59 | set {
60 | //Translate the color and execute the command
61 | string color = ColorTranslator.ToHtml(value);
62 | editor.Exec(Interop.IDM_BACKCOLOR, color);
63 | }
64 | }
65 |
66 | ///
67 | /// Indicates if the current text can be indented
68 | ///
69 | public bool CanIndent {
70 | get {
71 | return editor.IsCommandEnabled(Interop.IDM_INDENT);
72 | }
73 | }
74 |
75 | ///
76 | /// Indicates if the background color can be set
77 | ///
78 | public bool CanSetBackColor {
79 | get {
80 | return editor.IsCommandEnabled(Interop.IDM_BACKCOLOR);
81 | }
82 | }
83 |
84 | ///
85 | /// Indicates if the font face can be set
86 | ///
87 | public bool CanSetFontName {
88 | get {
89 | return editor.IsCommandEnabled(Interop.IDM_FONTNAME);
90 | }
91 | }
92 |
93 | ///
94 | /// Indicates if the font size can get set
95 | ///
96 | public bool CanSetFontSize {
97 | get {
98 | return editor.IsCommandEnabled(Interop.IDM_FONTSIZE);
99 | }
100 | }
101 |
102 | ///
103 | /// Indicates if the foreground color can be set
104 | ///
105 | public bool CanSetForeColor {
106 | get {
107 | return editor.IsCommandEnabled(Interop.IDM_FORECOLOR);
108 | }
109 | }
110 |
111 | ///
112 | /// Indicates if the Html format (eg ordered lists, paragraph, heading) can be set
113 | ///
114 | public bool CanSetHtmlFormat {
115 | get {
116 | return editor.IsCommandEnabled(Interop.IDM_BLOCKFMT);
117 | }
118 | }
119 |
120 | ///
121 | /// Indicates if the current text can be unindented
122 | ///
123 | public bool CanUnindent {
124 | get {
125 | return editor.IsCommandEnabled(Interop.IDM_OUTDENT);
126 | }
127 | }
128 |
129 | ///
130 | /// Gets and sets the font name of the current text
131 | ///
132 | public string FontName {
133 | get {
134 | return (editor.ExecResult(Interop.IDM_FONTNAME) as string);
135 | }
136 | set {
137 | editor.Exec(Interop.IDM_FONTNAME, value);
138 | }
139 | }
140 |
141 | ///
142 | /// Gets and sets the font size of the current text
143 | ///
144 | public HtmlFontSize FontSize {
145 | get {
146 | object o = editor.ExecResult(Interop.IDM_FONTSIZE);
147 | if (o == null) {
148 | return HtmlFontSize.Medium;
149 | }
150 | else {
151 | return (HtmlFontSize)o;
152 | }
153 | }
154 | set {
155 | editor.Exec(Interop.IDM_FONTSIZE, (int)value);
156 | }
157 | }
158 |
159 | ///
160 | /// The foreground color of the current text
161 | ///
162 | public Color ForeColor {
163 | get {
164 | //Query MSHTML, convert the result, and return the color
165 | return ConvertMSHTMLColor(editor.ExecResult(Interop.IDM_FORECOLOR));
166 | }
167 | set {
168 | //Translate the color and execute the command
169 | string color = ColorTranslator.ToHtml(value);
170 | editor.Exec(Interop.IDM_FORECOLOR, color);
171 | }
172 | }
173 |
174 | ///
175 | /// Converts an MSHTML color to a Frameworks color
176 | ///
177 | /// object colorValue - The color value returned from MSHTML
178 | ///
179 | private Color ConvertMSHTMLColor(object colorValue) {
180 | if (colorValue != null) {
181 | Type colorType = colorValue.GetType();
182 | if (colorType == typeof(int)) {
183 | //If the colorValue is an int, it's a Win32 color
184 | return ColorTranslator.FromWin32((int)colorValue);
185 | }
186 | else if (colorType == typeof(string)) {
187 | //Otherwise, it's a string, so convert that
188 | return ColorTranslator.FromHtml((string)colorValue);
189 | }
190 | Debug.Fail("Unexpected color type : " + colorType.FullName);
191 | }
192 | return Color.Empty;
193 | }
194 |
195 | ///
196 | /// Gets the current state of the bold command (enabled and/or checked)
197 | ///
198 | ///
199 | public HtmlCommandInfo GetBoldInfo() {
200 | return editor.GetCommandInfo(Interop.IDM_BOLD);
201 | }
202 |
203 | public HtmlFormat GetHtmlFormat() {
204 | string formatString = editor.ExecResult(Interop.IDM_BLOCKFMT) as string;
205 | if (formatString != null) {
206 | for (int i = 0; i < formats.Length; i++) {
207 | if (formatString.Equals(formats[i])) {
208 | return (HtmlFormat)i;
209 | }
210 | }
211 | }
212 | return HtmlFormat.Normal;
213 | }
214 |
215 | ///
216 | /// Gets the current state of the italics command (enabled and/or checked)
217 | ///
218 | ///
219 | public HtmlCommandInfo GetItalicsInfo() {
220 | return editor.GetCommandInfo(Interop.IDM_ITALIC);
221 | }
222 |
223 | ///
224 | /// Gets the current state of the strikethrough command (enabled and/or checked)
225 | ///
226 | ///
227 | public HtmlCommandInfo GetStrikethroughInfo() {
228 | return editor.GetCommandInfo(Interop.IDM_STRIKETHROUGH);
229 | }
230 |
231 | ///
232 | /// Gets the current state of the Subscript command (enabled and/or checked)
233 | ///
234 | ///
235 | public HtmlCommandInfo GetSubscriptInfo() {
236 | return editor.GetCommandInfo(Interop.IDM_SUBSCRIPT);
237 | }
238 |
239 | ///
240 | /// Gets the current state of the Superscript command (enabled and/or checked)
241 | ///
242 | ///
243 | public HtmlCommandInfo GetSuperscriptInfo() {
244 | return editor.GetCommandInfo(Interop.IDM_SUPERSCRIPT);
245 | }
246 |
247 | ///
248 | /// Gets the current state of the Underline command (enabled and/or checked)
249 | ///
250 | ///
251 | public HtmlCommandInfo GetUnderlineInfo() {
252 | return editor.GetCommandInfo(Interop.IDM_UNDERLINE);
253 | }
254 |
255 | ///
256 | /// Indents the current text
257 | ///
258 | public void Indent() {
259 | editor.Exec(Interop.IDM_INDENT);
260 | }
261 | ///
262 | /// Sets the HTML format (eg ordered list, paragraph, etc.) of the current text
263 | ///
264 | ///
265 | public void SetHtmlFormat(HtmlFormat format) {
266 | editor.Exec(Interop.IDM_BLOCKFMT, formats[(int)format]);
267 | }
268 |
269 | ///
270 | /// Gets the current state of the bold command
271 | ///
272 | ///
273 | public void ToggleBold() {
274 | editor.Exec(Interop.IDM_BOLD);
275 | }
276 |
277 | ///
278 | /// Toggles the current state of the italics command
279 | ///
280 | ///
281 | public void ToggleItalics() {
282 | editor.Exec(Interop.IDM_ITALIC);
283 | }
284 |
285 | ///
286 | /// Toggles the current state of the strikethrough command
287 | ///
288 | ///
289 | public void ToggleStrikethrough() {
290 | editor.Exec(Interop.IDM_STRIKETHROUGH);
291 | }
292 |
293 | ///
294 | /// Toggles the current state of the Subscript command
295 | ///
296 | ///
297 | public void ToggleSubscript() {
298 | editor.Exec(Interop.IDM_SUBSCRIPT);
299 | }
300 |
301 | ///
302 | /// Toggles the current state of the Superscript command
303 | ///
304 | ///
305 | public void ToggleSuperscript() {
306 | editor.Exec(Interop.IDM_SUPERSCRIPT);
307 | }
308 |
309 | ///
310 | /// Toggles the current state of the Underline command
311 | ///
312 | ///
313 | public void ToggleUnderline() {
314 | editor.Exec(Interop.IDM_UNDERLINE);
315 | }
316 |
317 | ///
318 | /// Unindents the current text
319 | ///
320 | public void Unindent() {
321 | editor.Exec(Interop.IDM_OUTDENT);
322 | }
323 | }
324 | }
325 |
--------------------------------------------------------------------------------
/HtmlViewer/MSHTMLSite.cs:
--------------------------------------------------------------------------------
1 | ///////////////////////////////////////////////////////////////////////////////
2 | // HTML Control and HTML Editor Sample
3 | // Copyright 2003, Nikhil Kothari. All Rights Reserved.
4 | //
5 | // Provided as is, in sample form with no associated warranties.
6 | // For more information on usage, see the accompanying
7 | // License.txt file.
8 | ///////////////////////////////////////////////////////////////////////////////
9 |
10 | namespace HtmlApp.Html {
11 |
12 | using System;
13 | using System.ComponentModel;
14 | using System.Diagnostics;
15 | using System.Drawing;
16 | using System.Runtime.InteropServices;
17 | using System.Windows.Forms;
18 |
19 | [
20 | ClassInterface(ClassInterfaceType.None)
21 | ]
22 | internal class MSHTMLSite :
23 | Interop.IOleClientSite,
24 | Interop.IOleContainer,
25 | Interop.IOleDocumentSite,
26 | Interop.IOleInPlaceSite,
27 | Interop.IOleInPlaceFrame,
28 | Interop.IDocHostUIHandler,
29 | Interop.IPropertyNotifySink,
30 | Interop.IAdviseSink,
31 | Interop.IOleServiceProvider {
32 |
33 | /// the Control used to host (and parent) the mshtml window
34 | private HtmlControl hostControl;
35 |
36 | /// the mshtml instance and various related objects
37 | private Interop.IOleObject tridentOleObject;
38 | private Interop.IHTMLDocument2 tridentDocument;
39 | private Interop.IOleCommandTarget tridentCmdTarget;
40 | private Interop.IOleDocumentView tridentView;
41 | private Interop.IOleInPlaceActiveObject activeObject;
42 |
43 | // cookie representing our sink
44 | private Interop.ConnectionPointCookie propNotifyCookie;
45 | private int adviseSinkCookie;
46 |
47 | // private DropTarget _dropTarget;
48 |
49 | ///
50 | ///
51 | public MSHTMLSite(HtmlControl hostControl) {
52 | if ((hostControl == null) || (hostControl.IsHandleCreated == false)) {
53 | throw new ArgumentException();
54 | }
55 |
56 | this.hostControl = hostControl;
57 | hostControl.Resize += new EventHandler(this.OnParentResize);
58 | }
59 |
60 | ///
61 | ///
62 | public Interop.IOleCommandTarget MSHTMLCommandTarget {
63 | get {
64 | return tridentCmdTarget;
65 | }
66 | }
67 |
68 | ///
69 | ///
70 | public Interop.IHTMLDocument2 MSHTMLDocument {
71 | get {
72 | return tridentDocument;
73 | }
74 | }
75 |
76 | ///
77 | ///
78 | public void ActivateMSHTML() {
79 | Debug.Assert(tridentOleObject != null, "How'd we get here when trident is null!");
80 |
81 | try {
82 | Interop.COMRECT r = new Interop.COMRECT();
83 |
84 | Interop.GetClientRect(hostControl.Handle, r);
85 | tridentOleObject.DoVerb(Interop.OLEIVERB_UIACTIVATE, Interop.NullIntPtr, (Interop.IOleClientSite)this,
86 | 0, hostControl.Handle, r);
87 | }
88 | catch (Exception e) {
89 | Debug.Fail(e.ToString());
90 | }
91 | }
92 |
93 | ///
94 | ///
95 | public void CloseMSHTML() {
96 | hostControl.Resize -= new EventHandler(this.OnParentResize);
97 |
98 | try {
99 | if (propNotifyCookie != null) {
100 | propNotifyCookie.Disconnect();
101 | propNotifyCookie = null;
102 | }
103 |
104 | if (tridentDocument != null) {
105 | tridentView = null;
106 | tridentDocument = null;
107 | tridentCmdTarget = null;
108 | activeObject = null;
109 |
110 | if (adviseSinkCookie != 0) {
111 | tridentOleObject.Unadvise(adviseSinkCookie);
112 | adviseSinkCookie = 0;
113 | }
114 |
115 | tridentOleObject.Close(Interop.OLECLOSE_NOSAVE);
116 | tridentOleObject.SetClientSite(null);
117 | tridentOleObject = null;
118 | }
119 | }
120 | catch (Exception e) {
121 | Debug.Fail(e.ToString());
122 | }
123 | }
124 |
125 | ///
126 | ///
127 | public void CreateMSHTML() {
128 | Debug.Assert(tridentDocument == null, "Must call CloseMSHTML before recreating.");
129 |
130 | bool created = false;
131 | try {
132 | // create the trident instance
133 | tridentDocument = (Interop.IHTMLDocument2)new Interop.HTMLDocument();
134 | tridentOleObject = (Interop.IOleObject)tridentDocument;
135 |
136 | // hand it our Interop.IOleClientSite implementation
137 | tridentOleObject.SetClientSite((Interop.IOleClientSite)this);
138 |
139 | created = true;
140 |
141 | propNotifyCookie = new Interop.ConnectionPointCookie(tridentDocument, this, typeof(Interop.IPropertyNotifySink), false);
142 |
143 | tridentOleObject.Advise((Interop.IAdviseSink)this, out adviseSinkCookie);
144 | Debug.Assert(adviseSinkCookie != 0);
145 |
146 | tridentCmdTarget = (Interop.IOleCommandTarget)tridentDocument;
147 | }
148 | finally {
149 | if (created == false) {
150 | tridentDocument = null;
151 | tridentOleObject = null;
152 | tridentCmdTarget = null;
153 | }
154 | }
155 | }
156 |
157 | ///
158 | ///
159 | public void DeactivateMSHTML() {
160 | // TODO: Implement this... once I know how to do it!
161 | }
162 |
163 | ///
164 | ///
165 | private void OnParentResize(object src, EventArgs e) {
166 | if (tridentView != null) {
167 | Interop.COMRECT r = new Interop.COMRECT();
168 |
169 | Interop.GetClientRect(hostControl.Handle, r);
170 | tridentView.SetRect(r);
171 | }
172 | }
173 |
174 | ///
175 | ///
176 | private void OnReadyStateChanged() {
177 | string readyState = tridentDocument.GetReadyState();
178 | if (String.Compare(readyState, "complete", true) == 0) {
179 | OnReadyStateComplete();
180 | }
181 | }
182 |
183 | ///
184 | ///
185 | private void OnReadyStateComplete() {
186 | hostControl.OnReadyStateComplete(EventArgs.Empty);
187 | }
188 |
189 | internal void SetFocus() {
190 | if (activeObject != null) {
191 | IntPtr hWnd = IntPtr.Zero;
192 | if (activeObject.GetWindow(out hWnd) == Interop.S_OK) {
193 | Debug.Assert(hWnd != IntPtr.Zero);
194 | Interop.SetFocus(hWnd);
195 | }
196 | }
197 | }
198 |
199 | ///
200 | ///
201 | public bool TranslateAccelarator(Interop.COMMSG msg) {
202 | if (activeObject != null) {
203 | int hr = activeObject.TranslateAccelerator(msg);
204 | if (hr != Interop.S_FALSE) {
205 | return true;
206 | }
207 | }
208 | return false;
209 | }
210 |
211 |
212 | ///////////////////////////////////////////////////////////////////////////
213 | // Interop.IOleClientSite Implementation
214 |
215 | public int SaveObject() {
216 | return Interop.S_OK;
217 | }
218 |
219 | public int GetMoniker(int dwAssign, int dwWhichMoniker, out object ppmk) {
220 | ppmk = null;
221 | return Interop.E_NOTIMPL;
222 | }
223 |
224 | public int GetContainer(out Interop.IOleContainer ppContainer) {
225 | ppContainer = (Interop.IOleContainer)this;
226 | return Interop.S_OK;
227 | }
228 |
229 | public int ShowObject() {
230 | return Interop.S_OK;
231 | }
232 |
233 | public int OnShowWindow(int fShow) {
234 | return Interop.S_OK;
235 | }
236 |
237 | public int RequestNewObjectLayout() {
238 | return Interop.S_OK;
239 | }
240 |
241 |
242 | ///////////////////////////////////////////////////////////////////////////
243 | // Interop.IOleContainer Implementation
244 |
245 | public void ParseDisplayName(object pbc, string pszDisplayName, int[] pchEaten, object[] ppmkOut) {
246 | Debug.Fail("ParseDisplayName - " + pszDisplayName);
247 | throw new COMException(String.Empty, Interop.E_NOTIMPL);
248 | }
249 |
250 | public void EnumObjects(int grfFlags, object[] ppenum) {
251 | throw new COMException(String.Empty, Interop.E_NOTIMPL);
252 | }
253 |
254 | public void LockContainer(int fLock) {
255 | }
256 |
257 |
258 | ///////////////////////////////////////////////////////////////////////////
259 | // Interop.IOleDocumentSite Implementation
260 |
261 | public int ActivateMe(Interop.IOleDocumentView pViewToActivate) {
262 | Debug.Assert(pViewToActivate != null,
263 | "Expected the view to be non-null");
264 | if (pViewToActivate == null)
265 | return Interop.E_INVALIDARG;
266 |
267 | Interop.COMRECT r = new Interop.COMRECT();
268 |
269 | Interop.GetClientRect(hostControl.Handle, r);
270 |
271 | tridentView = pViewToActivate;
272 | tridentView.SetInPlaceSite((Interop.IOleInPlaceSite)this);
273 | tridentView.UIActivate(1);
274 | tridentView.SetRect(r);
275 | tridentView.Show(1);
276 |
277 | return Interop.S_OK;
278 | }
279 |
280 |
281 | ///////////////////////////////////////////////////////////////////////////
282 | // Interop.IOleInPlaceSite Implementation
283 |
284 | public IntPtr GetWindow() {
285 | return hostControl.Handle;
286 | }
287 |
288 | public void ContextSensitiveHelp(int fEnterMode) {
289 | throw new COMException(String.Empty, Interop.E_NOTIMPL);
290 | }
291 |
292 | public int CanInPlaceActivate() {
293 | return Interop.S_OK;
294 | }
295 |
296 | public void OnInPlaceActivate() {
297 | }
298 |
299 | public void OnUIActivate() {
300 | }
301 |
302 | public void GetWindowContext(out Interop.IOleInPlaceFrame ppFrame, out Interop.IOleInPlaceUIWindow ppDoc, Interop.COMRECT lprcPosRect, Interop.COMRECT lprcClipRect, Interop.tagOIFI lpFrameInfo) {
303 | ppFrame = (Interop.IOleInPlaceFrame)this;
304 | ppDoc = null;
305 |
306 | Interop.GetClientRect(hostControl.Handle, lprcPosRect);
307 | Interop.GetClientRect(hostControl.Handle, lprcClipRect);
308 |
309 | lpFrameInfo.cb = Marshal.SizeOf(typeof(Interop.tagOIFI));
310 | lpFrameInfo.fMDIApp = 0;
311 | lpFrameInfo.hwndFrame = hostControl.Handle;
312 | lpFrameInfo.hAccel = Interop.NullIntPtr;
313 | lpFrameInfo.cAccelEntries = 0;
314 | }
315 |
316 | public int Scroll(Interop.tagSIZE scrollExtant) {
317 | return Interop.E_NOTIMPL;
318 | }
319 |
320 | public void OnUIDeactivate(int fUndoable) {
321 | // NOTE, nikhilko, 7/99: Don't return E_NOTIMPL. Somehow doing nothing and returning S_OK
322 | // fixes trident hosting in Win2000.
323 | }
324 |
325 | public void OnInPlaceDeactivate() {
326 | }
327 |
328 | public void DiscardUndoState() {
329 | throw new COMException(String.Empty, Interop.E_NOTIMPL);
330 | }
331 |
332 | public void DeactivateAndUndo() {
333 | }
334 |
335 | public int OnPosRectChange(Interop.COMRECT lprcPosRect) {
336 | return Interop.S_OK;
337 | }
338 |
339 |
340 | ///////////////////////////////////////////////////////////////////////////
341 | // Interop.IOleInPlaceFrame Implementation
342 |
343 | public void GetBorder(Interop.COMRECT lprectBorder) {
344 | throw new COMException(String.Empty, Interop.E_NOTIMPL);
345 | }
346 |
347 | public void RequestBorderSpace(Interop.COMRECT pborderwidths) {
348 | throw new COMException(String.Empty, Interop.E_NOTIMPL);
349 | }
350 |
351 | public void SetBorderSpace(Interop.COMRECT pborderwidths) {
352 | throw new COMException(String.Empty, Interop.E_NOTIMPL);
353 | }
354 |
355 | public void SetActiveObject(Interop.IOleInPlaceActiveObject pActiveObject, string pszObjName) {
356 | this.activeObject = pActiveObject;
357 | }
358 |
359 | public void InsertMenus(IntPtr hmenuShared, Interop.tagOleMenuGroupWidths lpMenuWidths) {
360 | throw new COMException(String.Empty, Interop.E_NOTIMPL);
361 | }
362 |
363 | public void SetMenu(IntPtr hmenuShared, IntPtr holemenu, IntPtr hwndActiveObject) {
364 | throw new COMException(String.Empty, Interop.E_NOTIMPL);
365 | }
366 |
367 | public void RemoveMenus(IntPtr hmenuShared) {
368 | throw new COMException(String.Empty, Interop.E_NOTIMPL);
369 | }
370 |
371 | public void SetStatusText(string pszStatusText) {
372 | }
373 |
374 | public void EnableModeless(int fEnable) {
375 | }
376 |
377 | public int TranslateAccelerator(Interop.COMMSG lpmsg, short wID) {
378 | return Interop.S_FALSE;
379 | }
380 |
381 |
382 | ///////////////////////////////////////////////////////////////////////////
383 | // IDocHostUIHandler Implementation
384 |
385 | public int ShowContextMenu(int dwID, Interop.POINT pt, object pcmdtReserved, object pdispReserved) {
386 | // Point location = hostControl.PointToClient(new Point(pt.x, pt.y));
387 | //
388 | // ShowContextMenuEventArgs e = new ShowContextMenuEventArgs(location, false);
389 | //
390 | // try {
391 | // hostControl.OnShowContextMenu(e);
392 | // }
393 | // catch {
394 | // // Make sure we return Interop.S_OK
395 | // }
396 | //
397 | return Interop.S_OK;
398 | }
399 |
400 | public int GetHostInfo(Interop.DOCHOSTUIINFO info) {
401 | info.dwDoubleClick = Interop.DOCHOSTUIDBLCLICK_DEFAULT;
402 | int flags = 0;
403 | if (hostControl.AllowInPlaceNavigation) {
404 | flags |= Interop.DOCHOSTUIFLAG_ENABLE_INPLACE_NAVIGATION;
405 | }
406 | if (!hostControl.Border3d) {
407 | flags |= Interop.DOCHOSTUIFLAG_NO3DBORDER;
408 | }
409 | if (!hostControl.ScriptEnabled) {
410 | flags |= Interop.DOCHOSTUIFLAG_DISABLE_SCRIPT_INACTIVE;
411 | }
412 | if (!hostControl.ScrollBarsEnabled) {
413 | flags |= Interop.DOCHOSTUIFLAG_SCROLL_NO;
414 | }
415 | if (hostControl.FlatScrollBars) {
416 | flags |= Interop.DOCHOSTUIFLAG_FLAT_SCROLLBAR;
417 | }
418 | info.dwFlags = flags;
419 | return Interop.S_OK;
420 | }
421 |
422 | public int EnableModeless(bool fEnable) {
423 | return Interop.S_OK;
424 | }
425 |
426 | public int ShowUI(int dwID, Interop.IOleInPlaceActiveObject activeObject, Interop.IOleCommandTarget commandTarget, Interop.IOleInPlaceFrame frame, Interop.IOleInPlaceUIWindow doc) {
427 | return Interop.S_OK;
428 | }
429 |
430 | public int HideUI() {
431 | return Interop.S_OK;
432 | }
433 |
434 | public int UpdateUI() {
435 | return Interop.S_OK;
436 | }
437 |
438 | public int OnDocWindowActivate(bool fActivate) {
439 | return Interop.E_NOTIMPL;
440 | }
441 |
442 | public int OnFrameWindowActivate(bool fActivate) {
443 | return Interop.E_NOTIMPL;
444 | }
445 |
446 | public int ResizeBorder(Interop.COMRECT rect, Interop.IOleInPlaceUIWindow doc, bool fFrameWindow) {
447 | return Interop.E_NOTIMPL;
448 | }
449 |
450 | public int GetOptionKeyPath(string[] pbstrKey, int dw) {
451 | pbstrKey[0] = null;
452 | return Interop.S_OK;
453 | }
454 |
455 | public int GetDropTarget(Interop.IOleDropTarget pDropTarget, out Interop.IOleDropTarget ppDropTarget) {
456 | ppDropTarget = null;
457 | return Interop.E_NOTIMPL;
458 | }
459 |
460 | public int GetExternal(out object ppDispatch) {
461 | ppDispatch = hostControl.ScriptObject;
462 | if (ppDispatch != null) {
463 | return Interop.S_OK;
464 | }
465 | else {
466 | return Interop.E_NOTIMPL;
467 | }
468 | }
469 |
470 | public int TranslateAccelerator(Interop.COMMSG msg, ref Guid group, int nCmdID) {
471 | return Interop.S_FALSE;
472 | }
473 |
474 | public int TranslateUrl(int dwTranslate, string strURLIn, out string pstrURLOut) {
475 | pstrURLOut = null;
476 | return Interop.E_NOTIMPL;
477 | }
478 |
479 | public int FilterDataObject(Interop.IOleDataObject pDO, out Interop.IOleDataObject ppDORet) {
480 | ppDORet = null;
481 | return Interop.E_NOTIMPL;
482 | }
483 |
484 |
485 | ///////////////////////////////////////////////////////////////////////////
486 | // IPropertyNotifySink Implementation
487 |
488 | public void OnChanged(int dispID) {
489 | if (dispID == Interop.DISPID_READYSTATE) {
490 | OnReadyStateChanged();
491 | }
492 | }
493 |
494 | public void OnRequestEdit(int dispID) {
495 | }
496 |
497 |
498 | ///////////////////////////////////////////////////////////////////////////
499 | // IAdviseSink Implementation
500 |
501 | public void OnDataChange(Interop.FORMATETC pFormat, Interop.STGMEDIUM pStg) {
502 | }
503 |
504 | public void OnViewChange(int dwAspect, int index) {
505 | }
506 |
507 | public void OnRename(object pmk) {
508 | }
509 |
510 | public void OnSave() {
511 | }
512 |
513 | public void OnClose() {
514 | }
515 |
516 |
517 | ///////////////////////////////////////////////////////////////////////////
518 | // Interop.IOleServiceProvider
519 |
520 | public int QueryService(ref Guid sid, ref Guid iid, out IntPtr ppvObject) {
521 | int hr = Interop.E_NOINTERFACE;
522 | ppvObject = Interop.NullIntPtr;
523 |
524 | // object service = hostControl.GetService(ref sid);
525 | // if (service != null) {
526 | // if (iid.Equals(Interop.IID_IUnknown)) {
527 | // ppvObject = Marshal.GetIUnknownForObject(service);
528 | // }
529 | // else {
530 | // IntPtr pUnk = Marshal.GetIUnknownForObject(service);
531 | //
532 | // hr = Marshal.QueryInterface(pUnk, ref iid, out ppvObject);
533 | // Marshal.Release(pUnk);
534 | // }
535 | // }
536 |
537 | return hr;
538 | }
539 |
540 | }
541 | }
542 |
543 |
--------------------------------------------------------------------------------
/Installer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.ComponentModel;
4 | using System.Configuration.Install;
5 | using System.Runtime.InteropServices;
6 | using System.Diagnostics;
7 |
8 | namespace TimHeuer.PreviewHandlers
9 | {
10 | [RunInstaller(true)]
11 | public class ComInstaller : Installer
12 | {
13 | public override void Install(IDictionary stateSaver)
14 | {
15 | try
16 | {
17 | base.Install(stateSaver);
18 | RegistrationServices regsrv = new RegistrationServices();
19 | if (!regsrv.RegisterAssembly(this.GetType().Assembly, AssemblyRegistrationFlags.SetCodeBase))
20 | {
21 | throw new InstallException("Failed to register for COM interop.");
22 | }
23 | }
24 | catch (Exception exc)
25 | {
26 | Trace.WriteLine(exc.ToString());
27 | throw;
28 | }
29 | }
30 |
31 | public override void Uninstall(IDictionary savedState)
32 | {
33 | base.Uninstall(savedState);
34 | RegistrationServices regsrv = new RegistrationServices();
35 | if (!regsrv.UnregisterAssembly(this.GetType().Assembly))
36 | {
37 | throw new InstallException("Failed to unregister for COM interop.");
38 | }
39 | }
40 | }
41 | }
--------------------------------------------------------------------------------
/Libraries/CSharpFormat.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/timheuer/CodePreviewHandler/92c2b34e7f79255c3426d43ab6bce1c5c5541c2f/Libraries/CSharpFormat.dll
--------------------------------------------------------------------------------
/Libraries/TimHeuer.ManagedPreviewHandler.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/timheuer/CodePreviewHandler/92c2b34e7f79255c3426d43ab6bce1c5c5541c2f/Libraries/TimHeuer.ManagedPreviewHandler.dll
--------------------------------------------------------------------------------
/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("CodePreviewHandler")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("CodePreviewHandler")]
13 | [assembly: AssemblyCopyright("Copyright © 2006")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("1bc56a14-e380-4c1f-bc04-0cdce01593da")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Revision and Build Numbers
33 | // by using the '*' as shown below:
34 | [assembly: AssemblyVersion("1.0.0.0")]
35 | [assembly: AssemblyFileVersion("1.0.0.0")]
36 |
--------------------------------------------------------------------------------
/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.18033
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace TimHeuer.PreviewHandlers.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("TimHeuer.PreviewHandlers.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 |
63 | ///
64 | /// Looks up a localized string similar to .csharpcode, .csharpcode pre
65 | ///{
66 | /// font-size: small;
67 | /// color: black;
68 | /// font-family: Consolas, "Courier New", Courier, Monospace;
69 | /// background-color: #ffffff;
70 | /// /*white-space: pre;*/
71 | ///}
72 | ///
73 | ///.csharpcode pre { margin: 0em; }
74 | ///
75 | ///.csharpcode .rem { color: #008000; }
76 | ///
77 | ///.csharpcode .kwrd { color: #0000ff; }
78 | ///
79 | ///.csharpcode .str { color: #006080; }
80 | ///
81 | ///.csharpcode .op { color: #0000c0; }
82 | ///
83 | ///.csharpcode .preproc { color: #cc6633; }
84 | ///
85 | ///.csharpcode .asp { background-color: #ffff00; }
86 | ///
87 | ///.csharpcode .html { color: #800000 [rest of string was truncated]";.
88 | ///
89 | internal static string CssString {
90 | get {
91 | return ResourceManager.GetString("CssString", resourceCulture);
92 | }
93 | }
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | .csharpcode, .csharpcode pre
122 | {
123 | font-size: small;
124 | color: black;
125 | font-family: Consolas, "Courier New", Courier, Monospace;
126 | background-color: #ffffff;
127 | /*white-space: pre;*/
128 | }
129 |
130 | .csharpcode pre { margin: 0em; }
131 |
132 | .csharpcode .rem { color: #008000; }
133 |
134 | .csharpcode .kwrd { color: #0000ff; }
135 |
136 | .csharpcode .str { color: #006080; }
137 |
138 | .csharpcode .op { color: #0000c0; }
139 |
140 | .csharpcode .preproc { color: #cc6633; }
141 |
142 | .csharpcode .asp { background-color: #ffff00; }
143 |
144 | .csharpcode .html { color: #800000; }
145 |
146 | .csharpcode .attr { color: #ff0000; }
147 |
148 | .csharpcode .alt
149 | {
150 | background-color: #f4f4f4;
151 | width: 100%;
152 | margin: 0em;
153 | }
154 |
155 | .csharpcode .lnum { color: #606060; }
156 |
157 | Embedded CSS styles
158 |
159 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | CodePreviewHandler
2 | ==================
3 |
4 | [](http://ci.appveyor.com/project/TimHeuer/codepreviewhandler)
5 |
6 | This is code for a Windows PreviewHandler file association.
7 | This enables you to have a preview window in Explorer or Outlook when selecting a file and it will show code-highlighting for the file without opening into some editor.
8 |
9 | See http://timheuer.com/blog/archive/2006/12/13/13945.aspx for some history.
10 |
--------------------------------------------------------------------------------
/Registration.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 | using TimHeuer.ManagedPreviewHandler;
4 |
5 | namespace TimHeuer.PreviewHandlers
6 | {
7 | internal static class PreviewHandlerRegistration
8 | {
9 | [ComRegisterFunction]
10 | private static void Register(Type t) { PreviewHandler.Register(t); }
11 |
12 | [ComUnregisterFunction]
13 | private static void Unregister(Type t) { PreviewHandler.Unregister(t); }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/UpgradeLog.htm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/timheuer/CodePreviewHandler/92c2b34e7f79255c3426d43ab6bce1c5c5541c2f/UpgradeLog.htm
--------------------------------------------------------------------------------