CodeProject 离线文章编辑器






4.97/5 (78投票s)
一个离线 WYSIWYG 编辑器,用于备份、编辑或创建新的 CodeProject 文章。
目录
引言
CP 文章 编辑器允许您在无需互联网连接的情况下创建/编辑 CodeProject 的文章。您还可以使用此程序登录以备份(您的文章和相关图片)并编辑您已发布的文章。它体积小巧且便携。
背景
让我们学习或回忆一些理解源代码所需的内容。
异步操作
异步操作是独立工作的,它们有自己的线程。如果我们想在它们完成工作后执行代码,我们不能将这些代码写在启动它们的方法下方。因为它们不会阻塞调用它们的方法。我们必须知道的另一件事是,一个线程不能访问在不同线程上创建的对象...
通常,我们使用event
s 来处理在异步方法完成任务后必须执行的操作或发生的事件。但我为此目的使用了不同的方法,我认为它相对更容易理解。
假设我们有一个线程,并且我们想在我们的线程完成工作后调用一个函数
class Example
{
private Action after_MyThreadFinished;
private Form invoker;
public Example(Action after_MyThreadFinished, Form invoker)
{
this.after_MyThreadFinished = after_MyThreadFinished;
this.invoker = invoker;
}
public void doSomeWorksAsynchronously()
{
new Thread(() =>
{
// some codes that take long time...
Thread.Sleep(2000);
if (after_MyThreadFinished != null)
invoker.Invoke(after_MyThreadFinished);
}).Start();
}
}
线程无法直接修改由 UI 线程拥有的可视对象。而且,我们无法确定用户是否会在我们的新线程中使用代码来访问 UI 线程创建的控件。这就是为什么我们需要一个调用者对象。
用法
private void button1_Click(object sender, EventArgs e)
{
Action myAction = new Action(() =>
{
MessageBox.Show("Finished.");
this.Text = "I can access all the objects without any trouble." +
"Because I will be invoked by the thread of this form.";
});
Example example = new Example(myAction, this);
example.doSomeWorksAsynchronously(); // It doesn't block the current thread.
}
CKEditor
CKEditor 是一个开源的所见即所得编辑器,可以轻松集成到网页中。在这个项目中,我在 WebBrowser 中使用了它。
我自定义了工具栏,并移除了不必要的插件以减小总体积。此外,我还修改了 image.js 插件,使其可以使用相对 URL。
// Original code: B.preview.setAttribute('src',s.$.src);
// Modified for CP Article Editor
// The modification has been made to convert a relative image src to an
// absolute src in preview window.
// begin
if(s.$.src.substring(0,7)=='http://' || s.$.src.substring(0,8)=='https://')
B.preview.setAttribute('src',s.$.src);
else
{
var kok=(document.getElementsByTagName('base')[0]==null?'**biseyyapma**':
document.getElementsByTagName('base')[0].getAttribute('href'));
var verilenAdres=C;
var tamAdres=kok+C;
B.preview.setAttribute('src',tamAdres);
}
// end
// Original code: --
// Modified for CP Article Editor
// The modification has been made to convert an absolute image src to a relative src.
// begin
kok=(document.getElementsByTagName('base')[0]==null?'**biseyyapma**':
document.getElementsByTagName('base')[0].getAttribute('href')),
D=(D.indexOf(kok)>-1?D.replace(kok,''):D),
// end
// Original code: C.data('cke-saved-src',D.getValue()); C.setAttribute('src',D.getValue());
// Modified for CP Article Editor
// The modification has been made to convert a relative image src to an absolute src.
// begin
var verilenAdres=D.getValue();
if(verilenAdres.substring(0,7)=='http://' || verilenAdres.substring(0,8)=='https://')
{
C.data('cke-saved-src',D.getValue());
C.setAttribute('src',D.getValue());
}
else
{
var kok=(document.getElementsByTagName('base')[0]==null?'**biseyyapma**':
document.getElementsByTagName('base')[0].getAttribute('href'));
var tamAdres=(verilenAdres.indexOf(kok)<0?kok+verilenAdres:verilenAdres)
C.data('cke-saved-src',tamAdres);
C.setAttribute('src',tamAdres);
}
// end
使用的配置
fullPage : false // We are not editing a full page
language : 'en' // I removed all other language files to decrease the size.
resize_enabled : false // Prevent resizing the editor.
uiColor : '#CCC' // Grey
tabSpaces : 4 // Each tab character is replaced with 4 spaces.
contentsCss : 'CodeProject.css' // CSS stylesheet file of codeproject template.
removePlugins : 'contextmenu,liststyle,tabletools' // For hiding ckeditor's context menu
docType : '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"' +
'"http://www.w3.org/TR/html4/loose.dtd">' // Document type of CodeProject.
访问和修改 HTML 文档元素
我使用 WebBrowser
来登录并提取所需数据。以下是一些重要的方法。
读取元素的属性
webBrowser.Document.GetElementById("IdOfTheElement").GetAttribute("attribute");
更改元素的属性
webBrowser.Document.GetElementById("IdOfTheElement").SetAttribute("attribute", "new value");
从 c# 调用 WebBrowser 对象中的 Javascript 函数
object[] args = new object[] { ... };
object returned = webBrowser.Document.InvokeScript("functionName", args);
从网站下载文件
有一个非常简单的方法可以从网站下载文件。我用这个方法下载了与文章相关的图片。
WebClient webClient = new WebClient();
webClient.DownloadFile("http://www.site.com/file.extension", "C:\file.extension");
禁用 WebBrowser 中的点击声音
WebBrowser 没有禁用点击声音的属性。但有一个方法可以使用 CoInternetSetFeatureEnabled API 来实现。
static class ClickSoundDisabler
{
// ---------------------------------------------------
// CodeProjectArticleEditor > ClickSoundDisabler.cs
// ---------------------------------------------------
// CodeProject Article Editor
// Huseyin Atasoy
// September 2012
// ---------------------------------------------------
private const int FEATURE_DISABLE_NAVIGATION_SOUNDS = 21;
private const int SET_FEATURE_ON_PROCESS = 0x00000002;
[DllImport("urlmon.dll")]
[PreserveSig]
[return: MarshalAs(UnmanagedType.Error)]
private static extern int CoInternetSetFeatureEnabled(int FeatureEntry,
[MarshalAs(UnmanagedType.U4)] int dwFlags, bool fEnable);
public static void disableClickSound()
{
try
{
CoInternetSetFeatureEnabled(FEATURE_DISABLE_NAVIGATION_SOUNDS,
SET_FEATURE_ON_PROCESS, true);
}
catch{}
}
}
截图
这是程序的主窗口
如果您想备份已发布的文章进行编辑或仅保存它们,可以输入您的电子邮件和密码进行登录。登录后,您的文章将列出:
当您选择其中一个时,将显示有关它的某些信息
即使您没有连接到互联网,也可以撰写新文章或编辑现有文章
将文章传输到 CodeProject 的在线编辑器
- 从右键菜单中选择“将源代码复制到剪贴板”。
(请注意,所有绝对图片路径都已转换为相对路径。因此,您无需更改复制的 HTML 代码中的任何内容。) - 打开 codeproject 在线编辑器。
- 点击“HTML”按钮切换到 HTML 模式
- 粘贴您的内容。(CTRL+V)
- 再次点击“HTML”按钮切换回设计模式...
值得关注的点
让我们在查看源代码时列出可以学习到的内容
- .NET 中的 WYSIWYG HTML 编辑器。
- 如何在 .NET 中使用 ckeditor?
- 如何在 c# 的 WebBrowser 中调用 Javascript 函数?
- 自动登录和数据提取。
- 在 c# 中使用
Action
s 而不是Event
s 来处理异步函数。 - 禁用 WebBrowser 控件中的点击声音。
- 在 c# 中从 internet 下载文件。
历史
- 2013 年 12 月 15 日 (v1.0.4)
- 在 CodeProject 进行一些更改后,文章列表和登录方法已修复。
- 2013 年 4 月 4 日 (v1.0.3)
- 由于 CodeProject 进行了一些更新,登录最近失败了。已修复。
- 在 URL 末尾附加了随机字符串,以强制 WebBrowser 重新加载缓存的页面。
- 2012 年 10 月 17 日 (v1.0.2)
- 新的代码来记住最后浏览的路径
- 对
extractMemberId()
函数的小更改 - “打开方式”支持
(您可以使用“打开方式”菜单,或者将 cpa 文件拖放到程序的图标上。) - 唯一的 文件头,用于验证 CPA (CodeProject Article) 文件
(因此,旧的 cpa 文件无法用此版本打开。)
- 2012 年 10 月 5 日 (v1.0.1)
- codeproject 的登录页面上的“ctl00”变成了“ctl01”。因此,编写了一个新函数 (
getElementId()
) 来使用 Regex 类获取元素的 ID,并使用此函数代替所有可能在未来被 codeproject 更改的旧常量。
- codeproject 的登录页面上的“ctl00”变成了“ctl01”。因此,编写了一个新函数 (
- 2012 年 10 月 1 日 (v1.0.0)
- 首次发布。