65.9K
CodeProject 正在变化。 阅读更多。
Home

文档预览应用程序

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.74/5 (23投票s)

2009 年 7 月 2 日

CPOL

2分钟阅读

viewsIcon

137115

downloadIcon

12667

一个可以预览你的文档和文件的应用程序,例如 PDF、Doc、JPG、PPT、XSL。

引言

文档预览是一个应用程序,它允许用户在浏览时预览文件,例如 PDF、Doc、XLS、JPG、MP3、AVI,界面类似于 Windows 资源管理器,但无需打开额外的应用程序。它还允许用户移动、复制和删除文件夹或文件。

开发这个软件的想法来自于我试图找到一个包含特定信息的 PDF 文档。我的目标是使用抽象类、继承、接口和 LINQ 等技术来开发这个应用程序,并提供关于这些技术用法的社区示例。

背景

这里有一些我用来提供预览功能的控件。

预览类型 文件类型 使用的组件和控件 执行原理
Excel 预览 *.Xlsx, *.Xls WebBrowser 和 Excel 互操作性 原理是使用互操作性打开文档,并将其作为 HTML 保存在Temporary Internet Files下,然后使用 WebBrowser 控件显示该 HTML。
HTML 预览 *.Html, *.Htm WebBrowser 原理是将路径分配给 WebBrowser 控件的 URL 属性。
图像预览 *.Jpeg, *.Jpg, *.Tif, *.Gif, *.Bmp, *.Png PictureBox 原理是将一个 Image 分配给 PictureBox 控件的 Image 属性。
媒体预览 *.Mp3, *.Wav, *.Wma, *.Mid, *.Avi, *.Mpg, *.Wmv AxWMPLib.AxWindowsMediaPlayer 原理是将文件的路径添加到播放列表中,并执行 WindowsMediaPlayer 控件的 Play 命令。
PDF 预览 *.Pdf AxAcroPDFLib.AxAcroPDF 原理是将文件的路径分配给控件的 src 属性。
Power Point 预览 *.Pptx, *.Ppt, *.Ppsx, *.Pps WebBrowser 和 PowerPoint 互操作性 原理是使用互操作性打开文档,并将其作为 HTML 保存在Temporary Internet Files下,然后使用 WebBrowser 控件显示该 HTML。
文本预览 *.Txt, *.Rtf RichTextBox 原理是简单地使用 StreamReader 读取文本文件的内容,然后将内容分配给 RichTextBoxText 属性。
Word 预览 *.Docx, *.Doc WebBrowser 和 Word 互操作性 原理是使用互操作性打开文档,并将其作为 HTML 保存在Temporary Internet Files下,然后使用 WebBrowser 控件显示该 HTML。

Using the Code

正如我所提到的,所有操作都应该派生自 Action 抽象类。 可以在下面找到 Action 类的代码。 最重要的一点是,每个子类都应该以不同的方式实现 DoAction 方法。 动作的代码应该写在这个方法中。

public abstract class Action
{
    public abstract void DoAction(string path, FileType parFileType, frmMain frm);
    public void ShowError(string errorMessage)
    {
        MessageBox.Show(errorMessage,"Error", 
                   MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
    public bool FileExists(string path)
    {
        if (File.Exists(path))
        {
            return true;
        }
        else
        {
            ShowError("File is not accessable");
            return false;
        }
    }
    public bool DirectoryExists(string path)
    {
        if (Directory.Exists(path))
        {
            return true;
        }
        else
        {
            ShowError("Directory is not accessable");
            return false;
        }
    }
}

所有预览控件都应该实现 IPreview 接口; 这个接口包含应该实现的 Preview 方法。 预览控件的执行原理代码应该写在这个方法中。

public interface IPreview
{
    void Preview(string path);
}

在这里,我提供了一个继承了 Action 类的 Preview Action 类的示例。

[ActionAttributes(ActionName ="Preview", IsDefaultAction =true, 
   ActionsGroupTypes =new GroupTypes[] { GroupTypes.File })]
public class Preview : DocExp.AbstractClasses.Action
{
    public override void DoAction(string path, FileType parFileType, frmMain frm)
    {
        try
        {
            if (FileExists(path))
            {
                if (parFileType.PreviewType ==null)
                {
                    ShowError("Preview not available");
                }
                else
                {
                    Type t = parFileType.PreviewType;
                    SplitContainer sc=(SplitContainer)frm.Controls.Find("sc",true)[0];
                    Panel pnl=(Panel)sc.Panel2.Controls.Find("pnlPreview",true)[0];
                    if (pnl.Controls.Count > 0)
                    {
                        Control pOld = pnl.Controls[0];
                        pOld.Dispose();
                    }
                    pnl.Controls.Clear();
                    sc.Panel2Collapsed = false;
                    IPreview p = (IPreview)Activator.CreateInstance(t);
                    pnl.Controls.Add((Control)p);
                    ((Control)p).Dock =DockStyle.Fill;
                    p.Preview(path);
                    frm.SetPreviewPanelButtonsVisibility();
                }
            }
        }
        catch (Exception ex)
        {
            ShowError("An error occured while loading preview control");
            frm.SetPreviewPanelButtonsVisibility();
        }
    }
}

这是我用来添加文件类型作为搜索条件,并将动作作为上下文菜单项的代码

fileTypes.Add(new FileType("PDF Files", "*.Pdf", 
              typeof(PdfPreview), pdfFileTypeGroup));
fileTypes.Add(new FileType("JPG Files", "*.Jpg", 
              typeof(ImagePreview), imageFileTypeGroup));
fileTypes.Add(new FileType("JPEG Files", "*.Jpeg", 
              typeof(ImagePreview), imageFileTypeGroup));
fileTypes.Add(new FileType("TIFF Files", "*.Tif", 
              typeof(ImagePreview), imageFileTypeGroup));
fileTypes.Add(new FileType("GIF Files", "*.Gif", 
              typeof(ImagePreview), imageFileTypeGroup));
fileTypes.Add(new FileType("BMP Files", "*.Bmp", 
              typeof(ImagePreview), imageFileTypeGroup));
fileTypes.Add(new FileType("PNG Files", "*.Png", 
              typeof(ImagePreview), imageFileTypeGroup));
fileTypes.Add(new FileType("MP3 Files", "*.Mp3", 
              typeof(MediaPreview), musicFileTypeGroup));
......

           
foreach (Type t in System.Reflection.Assembly.GetExecutingAssembly().GetTypes())
{
    if (t.BaseType == typeof(DocExp.AbstractClasses.Action))
    {
        string actionName = ((ActionAttributes)
          t.GetCustomAttributes(typeof(ActionAttributes), true)[0]).ActionName;
        bool isDefault = ((ActionAttributes)
          t.GetCustomAttributes(typeof(ActionAttributes),true)[0]).IsDefaultAction;
        GroupTypes[] gt = ((ActionAttributes)
          t.GetCustomAttributes(typeof(ActionAttributes),true)[0]).ActionsGroupTypes;
        ActionType at = new ActionType(actionName, t, isDefault);
        foreach (GroupTypes g in gt)
        {
            at.ActionsGroupTypes.Add(g);
        }
        actionTypes.Add(at);
    }
}

联系方式

有关错误报告和建议,请随时通过 oztamer@hotmail.com 与我联系。

© . All rights reserved.