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

使用raphook.dll进行叠加

starIconstarIconstarIconstarIconemptyStarIcon

4.00/5 (3投票s)

2008年9月21日

CPOL

2分钟阅读

viewsIcon

42203

downloadIcon

1437

基于Ray Adam的raphook.dll的OverlayMgr

osdmgr_src

引言

如上所示,Overlay Mgr是一个围绕Ray Adam的raphook.dll(ATI Tray Tools)的托管包装器,支持D3D和OpenGL中的叠加。该应用程序只是让您可以使用自己的插件并在叠加层中显示您自己的数字/字符串,这在以前的Nvidia显卡上是不可能的。

s1EAB70.jpg

背景

你们中的一些人可能知道我之前关于Overlay Tools的文章。这些工具在我的ATI显卡上运行良好,但自从我获得Nvidia显卡后,它甚至不会创建叠加层(DirectDraw = 已弃用)。  

因此,我花了一些时间寻找替代方案,但没有找到任何令人满意的东西。所以我决定使用ATI Tray Tools/NVTray中提供的叠加DLL。

Using the Code

该程序分为三个部分。

I. OverlayWrapper

Overlay Wrapper库是一个围绕raphook.dll(顺便说一下,它似乎只支持32位Windows)的本地包装器,并提供了用于显示/隐藏叠加层以及编辑显示数据的基础方法。

可以在Overlay.Data属性中设置的数据通过共享内存/文件映射传输到raphook.dll

由于该库基于raphook库,因此它受到很大限制,但应该足以满足标准需求

[Flags]
public enum eItems {
	GPUClock = 1,
	MemClock = 2,
	GPUTemp = 4,
	EnvTemp = 8,
	FanSpeed = 16,
	FTM = 32,
	RenderAPI = 64,
	SMU = 128,
	FVM = 256,
	CustomString = 1024
}

II. OverlayMgr

Overlay Manager,主程序,使用包装器来显示所选插件。插件通过反射加载(检查plugins文件夹中的所有DLL)

/// <summary>
/// Load Plugins
/// </summary>
public static void LoadPlugins() {
    if (!Directory.Exists("plugins"))
        Directory.CreateDirectory("plugins");

    Evidence ev = new Evidence();
    ev.AddAssembly(typeof (MainForm).Assembly);
    ev.AddAssembly(typeof (Overlay).Assembly);

    foreach (string pl in Directory.GetFiles("plugins", "*.dll", 
         SearchOption.TopDirectoryOnly)) {
        try {
            Assembly a = Assembly.LoadFile(Path.GetFullPath(pl), ev);
 
            foreach (Type t in a.GetExportedTypes()) {
                if (typeof (IPlugin).IsAssignableFrom(t) && !t.IsAbstract) {
                    IPlugin plugin;

                    string data = Path.GetDirectoryName(pl) + "\\" + 
                    Path.GetFileNameWithoutExtension(pl) + ".cfg";
                    if (t.IsSerializable && File.Exists(data)) {
                        using (FileStream fs = new FileStream
                        (data, FileMode.Open, FileAccess.Read)) {
                            BinaryFormatter bf = new BinaryFormatter();
                            bf.Binder = new FixedBinder();
                            plugin = (IPlugin) bf.Deserialize(fs);
                        }
                    }
                    else plugin = (IPlugin) Activator.CreateInstance(t);
         
                    m_Plugins.Add(plugin);

                    if (plugin.Active)
                    plugin.Load();
                } 
            }
        }
        catch (Exception e) {
            Console.WriteLine(e);
            continue;
        }
    }
} 

在编写代码的这部分时,我不得不决定如何保存各个插件的设置。我决定使用标准序列化,因此只序列化插件的整个IPlugin实现,这意味着每个插件都应该使用[Serializable]属性标记。

III. 插件

插件系统非常简单:您只需要实现IPlugin接口并将您的内容放在那里(显而易见,嘿?)。该接口由这些基本方法组成

public interface IPlugin {
    string Name { get; }
    string Description { get; }
    bool Active { get; set; }
    bool Load();
    bool Unload();
    void ShowConfig();
    void Tick();
}

例如的Time插件(真的很简单)只是在每次Tick()时将当前时间附加到Overlay.Data.CustomString属性中,这意味着编写您自己的插件应该不会太难。

优点/缺点

这种方法的主要优点是,在自己完成所有操作/使用DirectDraw时,您实际上不必费心处理钩子、驱动程序和不同的制造商。但也有一个主要的缺点:您能做的非常有限;最后,您受到raphook.dll的限制,它只支持“一个”string和一些数字;因此您无法绘制真实的图像(除非您擅长单行ASCII艺术;))。

但总而言之,我想说,对于大多数用途,这种叠加层应该足够了,尤其是对于那些只想在玩游戏时显示一些小数据的人来说。

历史

  • 2008年9月21日:初始帖子
© . All rights reserved.