zoukankan      html  css  js  c++  java
  • C#生成CHM文件(应用篇)之代码库编辑器(3)【附源代码下载】

    在这篇文章中,我将介绍AlexisEditor项目下主要Form的实现,即MainForm、EditForm。

    MainForm


    MainForm包含的主要变量如下 

     

    以frm开头的都是对应的窗体变量,chmDocument表示当前的电子书,dockPanel是MainForm上的Panel,负责实现Visual Studio风格的面板。

    下图是MainForm的主要方法。

     

    在一开始是实例化Form窗体的时候会调自身的构造器,在构造器中我们其他的窗体,主要代码如下

     frmIndex.Show(dockPanel);//显示目录窗体
     frmIndex.DockTo(dockPanel, DockStyle.Left);
     frmList.Show(dockPanel);//显示搜索窗体
     frmList.DockTo(dockPanel, DockStyle.Fill);
     this.frmIndex.TreeIndex.NodeMouseDoubleClick += new TreeNodeMouseClickEventHandler(TreeIndex_NodeMouseDoubleClick);//注册编辑文章事件


    加载界面的时候会触发MainForm_Load事件,我们在这个方法里面加载电子书的目录,代码如下:

     chmDocument.Load("index.xml");//加载目录
     RefreshView(chmDocument, frmIndex.TreeIndex);

     RefreshView是同步TreeView和CHMDocument的方法,很重要

    代码
    private void RefreshView(CHMDocument doc, System.Windows.Forms.TreeView tvw)
    {
                tvw.BeginUpdate();
                tvw.Nodes.Clear();
                System.Windows.Forms.TreeNode node 
    = tvw.Nodes.Add(doc.Title);
                node.Tag 
    = doc;
                node.ImageIndex 
    = 0;
                node.SelectedImageIndex 
    = 0;
                AddNodes(doc.Nodes, node);
                tvw.EndUpdate();
                tvw.SelectedNode 
    = node;
                node.Expand();

     } 


     RefreshView会调用AddNodes方法添加节点,方法明细如下

    代码
    private void AddNodes(CHMNodeList list, System.Windows.Forms.TreeNode RootNode)
    {
                
    if (list == null || list.Count == 0)
                    
    return;

                
    foreach (CHMNode node in list)
                {
                    System.Windows.Forms.TreeNode n 
    = new TreeNode(node.Name);
                    n.Tag 
    = node;
                    
    if (node.Nodes.Count > 0)
                        n.ImageIndex 
    = 0;
                    
    else
                        n.ImageIndex 
    = 1;
                    n.SelectedImageIndex 
    = n.ImageIndex;
                    RootNode.Nodes.Add(n);
                    
    if (node.Nodes.Count > 0)
                        AddNodes(node.Nodes, n);
                }
    }


     New方法是新建文章方法,当我们选中目录节点,右击的时候会出现一些菜单,其中就有新建文章

    方法体很简单,其他的事情都交给EditForm去完成

    EditForm frmEdit = EditForm.CreateEditForm();               

    frmEdit.Show();

    Compile方法是编译方法,负责将目录中的文章编译为对应的CHM电子书,并且在编译的时候主页面下方的状态栏会显示编译过程,虽然是比较简陋的编译过程。

    代码
    //编译方法
    private void Compile()
    {
                frmOutPut.Show(dockPanel);
                frmOutPut.DockTo(dockPanel, DockStyle.Bottom);
                chmDocument.FileName 
    = "index.xml";
                chmDocument.Compile();
                
    //frmOutPut.RtbOutput.Text = chmDocument.OutPutText;
                frmOutPut.TxtOutput.Text = chmDocument.OutPutText;


    AddPage对应着程序工具栏上的IE图标,添加HMTL页面的功能,主要代码如下:

    代码
    //添加页面,此处只是将路径存入,并没有将文件考到相应的路径下(可用性待分析)
            private void AddPage()
            {
                TreeNode node 
    = this.frmIndex.TreeIndex.SelectedNode;//选中的节点
                
    //查看是否是根节点或是目录节点
                CHMNodeList list = this.GetNodeList(node);
                
    if (list == null)
                {
                    MessageBox.Show(
    "请选择根节点或是目录节点");
                    
    return;
                }
                
    using (OpenFileDialog ofd = new OpenFileDialog())//可以批量选择
                {
                    ofd.Filter 
    = "HTML Files|*.html;*.htm";
                    ofd.Multiselect 
    = true;//设置可以选择多个文件
                    ofd.ShowDialog();
                    
                    
                    
    if (ofd.FileNames.Length > 0)
                    {
                        
    for (int i = 0; i < ofd.FileNames.Length; i++)
                        {
                            CHMNode newNode 
    = new CHMNode();//创建新的节点
                            newNode.Name = ofd.SafeFileNames[i].ToString();
                            newNode.ImageNo 
    = "1";                        
                            newNode.Local 
    = ofd.FileNames[i].ToString();
                            newNode.Nodes 
    = null;
                            list.Add(newNode);
                            System.Windows.Forms.TreeNode node2 
    = new TreeNode(newNode.Name);
                            node2.Tag 
    = newNode;
                            node2.ImageIndex 
    = 1;
                            node2.SelectedImageIndex 
    = 1;
                            node.Nodes.Add(node2);
    //将新节点添加到树中
                            node.ImageIndex = 0;
                            node.SelectedImageIndex 
    = 0;
                        }
                    }
                }
            }


    保存方法是将目录上的信息保存到xml 文件中,是调用CHMDocument类中的Save方法。

     //保存方法
     private void Save()
    {
                chmDocument.Save("index.xml");
    }

     EditForm窗体

     

     startPath:程序的开始路径,有重要用处

    node属性:负责和其他页面的交互

    wbEditor:WebBrowser控件的实例,负责加载HTML编辑器,保存文章等功能

    txtName:文章的标题

    txtKeyWords:文章的关键字,用于Lucene.NET搜索

    下面来看看他的一些主要方法及其实现:


     

    EditForm_Load方法:加载编辑器,实现如下:

    代码
    /// <summary>
            
    /// 窗体加载事件
            
    /// </summary>
            
    /// <param name="sender"></param>
            
    /// <param name="e"></param>
            private void EditForm_Load(object sender, EventArgs e)
            {
                startPath 
    = Application.StartupPath;//起始路径
                
    //这边可以做成从配置文件中读取选择什么编辑器
                
    //Uri u = new Uri(startPath + @"\ckeditor\index.html");
                this.wbEditor.Navigating += new WebBrowserNavigatingEventHandler(wbEditor_Navigating);//为了获取前台的点击事件
                Uri u = new Uri(startPath + @"\CSDN_UBB\normal.htm");
                
    this.wbEditor.Url = u;
            } 


    WebBrowser控件中的html事件,是通过Navigating方法来实现的,WebBrowser导航发生改变时就会触发如下的方法,我们可以自己写js事件,让WebBrowser的导航发生改变

    如这边

     <script type="text/javascript">
            function getValue(){
                document.getElementById("content").value=document.getElementById("tb_ReplyBody___Editor").innerHTML;
                this.location.href="loading.htm";
            }
            </script>

    具体的实现可以参考源代码

    代码
    void wbEditor_Navigating(object sender, WebBrowserNavigatingEventArgs e)
            {
                
    if (e.Url.AbsolutePath.ToString().Replace('/''\\'== startPath + @"\CSDN_UBB\loading.htm")
                {
                    HtmlDocument hd 
    = this.wbEditor.Document;//获取文档信息
                    HtmlElement he = hd.GetElementById("content");
                    IHTMLDocument2 doc 
    = (IHTMLDocument2)this.wbEditor.Document.DomDocument;
                    mshtml.HTMLInputElement text1 
    = (HTMLInputElement)doc.all.item("content");//获取隐藏域中的值
                    string rr = text1.value;
                    
    if (this.txtName.Text == "")
                    {
                        MessageBox.Show(
    "文章标题不能为空!");
                        
    return;
                    }

                    
    string filename = GetFileName();
                    
    if (filePathEdit != "")
                    {
                        filename 
    = filePathEdit.Substring(filePathEdit.LastIndexOf('\\'+ 1);
                        filename 
    = filename.Substring(0, filename.LastIndexOf('.'));
                        File.Delete(filePathEdit);
                    }
                    
    //将内容存入到html模板中,并生产html文件
                    if (rr != "")
                    {
                        FileStream fs 
    = new FileStream("html_files\\" + filename + ".htm", FileMode.Create);//文件名
                        StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.GetEncoding("UTF-8"));
                        sw.WriteLine(
    "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");
                        sw.WriteLine("<html xmlns=\"http://www.w3.org/1999/xhtml\">");
                        sw.WriteLine("<head>");
                        sw.WriteLine(
    "<title>" + this.txtName.Text + "</title>");//文章名
                        sw.WriteLine("<meta content=\"text/html; charset=utf-8\" http-equiv=\"content-type\"/>");
                        sw.WriteLine(
    "<link type=\"text/css\" rel=\"stylesheet\" href=\"Styles/SyntaxHighlighter.css\"></link>");
                        sw.WriteLine(
    "<script type=\"text/javascript\" src=\"Scripts/shCore.js\"></script>");
                        sw.WriteLine(
    "<script type=\"text/javascript\" src=\"Scripts/shBrushCSharp.js\"></script>");
                        sw.WriteLine(
    "<script type=\"text/javascript\" src=\"Scripts/shBrushXml.js\"></script>");
                        sw.WriteLine(
    "<script type=\"text/javascript\"> window.onload = function () {");
                        sw.WriteLine(
    "dp.SyntaxHighlighter.ClipboardSwf = 'Scripts/clipboard.swf';");
                        sw.WriteLine(
    "dp.SyntaxHighlighter.HighlightAll('code');}");
                        sw.WriteLine(
    "</script>");
                        sw.WriteLine(
    "</head>");
                        sw.WriteLine(
    "<body>");
                        rr 
    = ChangeString(rr);
                        sw.WriteLine(rr);
                        sw.WriteLine(
    "</body>");
                        sw.WriteLine(
    "</html>");
                        sw.Close();
                    }
                    
    //将节点返回给目录,暂不做保存操作
                    node = new CHMNode();
                    node.Local 
    = startPath + "\\html_files\\" + filename + ".htm";
                    node.Name 
    = this.txtName.Text;
                    node.Nodes 
    = null;
                    node.ImageNo 
    = "1";

                    
    //TODO: 使用Lucene.Net存储索引,方便以后的搜索

                    
    this.Close();
                    
    //this.wbEditor.Url = new Uri(startPath + @"\success.htm");
                }
            }
            
    #endregion


    ok,至此,主要的部分都已经讲解了(还有一个BookIndexForm,在下篇中和其他的一起讲解),还有许多细节的地方可参考我的源代码

     源代码下载(简陋版)

    PS:不是最新版的源代码,最新版的源代码还在开发中, 恕不提供,嘿嘿

  • 相关阅读:
    Go语言操作etcd
    grafana使用
    Java整理
    Go操作MySQL
    Go语言操作Redis
    es
    influxDB
    gopsutil
    Java基础之(三):IDEA的安装及破解 lyl
    ClojureScript 点访问格式
  • 原文地址:https://www.cnblogs.com/alexis/p/1858018.html
Copyright © 2011-2022 走看看