文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

怎么使用C#实现一个PPT遥控器

2023-06-15 02:07

关注

这篇文章给大家分享的是有关怎么使用C#实现一个PPT遥控器的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

说明

本项目参考了 https://github.com/yangzhongke/PhoneAsPrompter 项目来完成实现,并对其进行了一些修改完善。

完整代码可以到 https://github.com/PuZhiweizuishuai/PPT-Remote-control 与 https://gitee.com/puzhiweizuishuai/PPT-Remote-control 查看。

软件下载地址: https://gitee.com/puzhiweizuishuai/PPT-Remote-control/releases/v1.0.0

另外,由于程序启动后会创建一个WEB服务器,用来显示PPT的操控界面,所以某些安全软件可能会报毒。但是程序本身是没有问题的。

截图

怎么使用C#实现一个PPT遥控器

具体实现

通过在Win Form项目中内嵌一个Kestrel Web服务器,我们就可以通过浏览器向web服务器发送请求来接收远程操作指令。之后通过Late Binding的方式去操作PPT。

1、在 Win Form项目中内嵌HTTP服务器

在Form窗口启动时,我们新建一个Kestrel服务器

this.webHost = new WebHostBuilder()                .UseKestrel()                .Configure(ConfigureWebApp)                .UseUrls("http://*:" + port)                .Build();            // 异步运行服务器            this.webHost.RunAsync();

然后对其进行配置

private void ConfigureWebApp(IApplicationBuilder app)        {            app.UseDefaultFiles();            app.UseStaticFiles();            app.Run(async (context) =>            {                // 处理非静态请求                 var request = context.Request;                var response = context.Response;                string path = request.Path.Value;                response.ContentType = "application/json; charset=UTF-8";                bool hasRun = true;                if (path == "/report")                {                    string value = request.Query["value"];                    this.BeginInvoke(new Action(() => {                        this.PageLabel.Text = value;                    }));                    response.StatusCode = 200;                    await response.WriteAsync("ok");                }                else                {                    response.StatusCode = 404;                }            });                    }

操作PPT

首先,由于涉及到了COM编程,我们需要注意内存回收与释放,所以需要用到COMReferenceTracker类进行应用管理。

每一步用到COM的地方,都要用T方法进行资源回收。

private dynamic T(dynamic comObj)        {            return this.comReference.T(comObj);        }

以下操作使用dynamic进行操作,所有操作需要去查询VBA文档了解具体用法,以下仅演示部分操作

打开一个PPT的操作实现

   private void button1_Click(object sender, EventArgs e)        {            // 文件选择框            openFileDialog.Filter = "ppt文件|*.ppt;*.pptx;*.pptm";            if (openFileDialog.ShowDialog() != DialogResult.OK)            {                return;            }                      string filename = openFileDialog.FileName;            this.ClearComRefs();            // 创建 PPT 对象            dynamic pptApp = T(PowerPointHelper.CreatePowerPointApplication());            // 显示 PPT            pptApp.Visible = true;            dynamic presentations = T(pptApp.Presentations);            // 打开 PPT            this.presentation = T(presentations.Open(filename));            // 全屏显示            T(this.presentation.SlideShowSettings).Run();        }

PPT上一个动画操作实现

T(T(presentation.SlideShowWindow).View).Previous();

下一步,与上一个操作类似,只需更换Previous()方法为Next()即可。

获取注释

首先我们需要一个方法去解析注释

private string GetInnerText(dynamic part)        {            StringBuilder sb = new StringBuilder();            dynamic shapes = T(T(part).Shapes);            int shapesCount = shapes.Count;            for (int i = 0; i < shapesCount; i++)            {                dynamic shape = T(shapes[i + 1]);                var textFrame = T(shape.TextFrame);                // MsoTriState.msoTrue==-1                if (textFrame.HasText == -1)                {                    string text = T(textFrame.TextRange).Text;                    sb.AppendLine(text);                }                sb.AppendLine();            }            return sb.ToString();        }

之后通过

dynamic notesPage = T(T(T(T(presentation.SlideShowWindow).View).Slide).NotesPage);string notesText = GetInnerText(notesPage);

我们就可以获取具体每页的注释信息。

完善服务器

了解了以上的PPT操作之后,我们就需要去完善我们的Web服务器端配置。

用户访问相应的地址,然后去执行上面PPT操作部分的代码即可。

   else if (path == "/getNote")                {                    string notesText = null;                    this.Invoke(new Action(() => {                        if (this.presentation == null)                        {                            return;                        }                        try                        {                            dynamic notesPage = T(T(T(T(presentation.SlideShowWindow).View).Slide).NotesPage);                            notesText = GetInnerText(notesPage);                        }                        catch (COMException ex)                        {                            notesText = "";                        }                    }));                    await response.WriteAsync(notesText);                }                else if (path == "/next")                {                    response.StatusCode = 200;                    this.Invoke(new Action(() => {                        if (this.presentation == null)                        {                            return;                        }                        try                        {                            T(T(this.presentation.SlideShowWindow).View).Next();                            hasRun = true;                        } catch (COMException e)                        {                            hasRun = false;                        }                                            }));                    if (hasRun)                    {                        await response.WriteAsync("OK");                    }                    else                    {                        await response.WriteAsync("NO");                    }                }                else if (path == "/previous")                {                    response.StatusCode = 200;                    this.Invoke(new Action(() => {                        if (this.presentation == null)                        {                            return;                        }                        try                        {                            T(T(this.presentation.SlideShowWindow).View).Previous();                            hasRun = true;                        }                        catch (COMException e)                        {                            hasRun = false;                        }                                            }));                    if (hasRun)                    {                        await response.WriteAsync("OK");                    }                    else                    {                        await response.WriteAsync("NO");                    }

完成前端

通过轮询的方式,不断的向服务端发送请求,获取最新的消息,这样我们就可以实现通过浏览器去操作PPT了。

<!DOCTYPE html><html lang="zh-cn"><head>    <meta charset="utf-8" />    <meta http-equiv="X-UA-Compatible" content="IE=edge">    <meta name="viewport" content="width=device-width, initial-scale=1.0">    <meta name="renderer" content="webkit" />    <title>操作你的PPT</title>    <link rel="icon" href="/logo.ico" rel="external nofollow" >    <style>        div {            font-size: 25px        }    </style></head><body>    <div id="main" >        <p id="note"></p>    </div>    <script src="hammer.min.js"></script>    <script>        function httpGet(url, cb) {            fetch(url, {                headers: {                    'Content-Type': 'application/json; charset=UTF-8'                },                method: 'GET'            }).then(response => response.text())                .then(text => {                    cb(text)                })                .catch(e => {                    return null                })        }        const note = document.querySelector("#note");        let hasRun = true        let getNotes = setInterval(() => {            httpGet('/getNote', (text) => {                note.innerText = text            })        }, 500)        function nextPage() {            httpGet('/next', (text) => {                if (text == 'NO') {                    clearInterval(getNotes)                    note.innerText = "幻灯片播放完毕!"                    hasRun = false                } else {                    if (!hasRun) {                        getNotes = setInterval(() => {                            httpGet('/getNote', (text) => {                                note.innerText = text                            })                        }, 500)                        hasRun = true                    }                }            })        }        function previousPage() {            httpGet('/previous', (text) => {                if (text == 'NO') {                    clearInterval(getNotes)                    note.innerText = "幻灯片播放完毕!"                    hasRun = false                } else {                    if (!hasRun) {                        getNotes = setInterval(() => {                            httpGet('/getNote', (text) => {                                note.innerText = text                            })                        }, 500)                        hasRun = true                    }                }            })        }        var hammer = new Hammer(document.querySelector("#main"));        hammer.on("swipeleft", function () {            nextPage();        });        hammer.on("swiperight", function () {            previousPage();        });    </script></body></html>

感谢各位的阅读!关于“怎么使用C#实现一个PPT遥控器”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯