服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C# - 使用C#实现一个PPT遥控器

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

2022-11-17 13:56陕西颜值扛把子 C#

由于本人需要参加的讨论会比较多,每次都会涉及到PPT,有时候坐在电脑旁讲会比较不生动,前人就发明了PPT遥控器,今天就给大家介绍下基于C#实现ppt遥控器,感兴趣的朋友一起看看吧

说明

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

完整代码可以到 https://github.com/PuZhiweizuishuai/PPT-Remote-controlhttps://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服务器

?
1
2
3
4
5
6
7
8
this.webHost = new WebHostBuilder()
                .UseKestrel()
                .Configure(ConfigureWebApp)
                .UseUrls("http://*:" + port)
                .Build();
 
            // 异步运行服务器
            this.webHost.RunAsync();

然后对其进行配置

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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方法进行资源回收。

?
1
2
3
4
private dynamic T(dynamic comObj)
        {
            return this.comReference.T(comObj);
        }

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

打开一个PPT的操作实现

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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上一个动画操作实现

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

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

 

获取注释

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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();
        }

之后通过

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

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

 

完善服务器

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
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了。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
<!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" style="width:100vw;height:100vh;">
        <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遥控器的文章就介绍到这了,更多相关C#实现PPT遥控器内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://www.cnblogs.com/puzhiwei/p/14769391.html

延伸 · 阅读

精彩推荐
  • C#Unity实现虚拟摇杆效果

    Unity实现虚拟摇杆效果

    这篇文章主要为大家详细介绍了Unity实现虚拟摇杆效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    糟糕点师7522022-08-31
  • C#深入分析c# 继承

    深入分析c# 继承

    这篇文章主要介绍了c# 继承的相关资料,文中讲解的非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下...

    菜鸟教程7372022-09-27
  • C#C#操作LINQ to SQL组件进行数据库建模的基本教程

    C#操作LINQ to SQL组件进行数据库建模的基本教程

    这篇文章主要介绍了C#操作LINQ to SQL组件进行数据库建模的基本教程,LINQ to SQL被集成在.NET框架之中,需要的朋友可以参考下...

    DebugLZQ9992021-11-15
  • C#unity实现虚拟摇杆控制Virtual Joystick

    unity实现虚拟摇杆控制Virtual Joystick

    这篇文章主要为大家详细介绍了unity实现虚拟摇杆控制Virtual Joystick,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    代码黑洞_9892022-09-01
  • C#Unity3D实现相机跟随控制

    Unity3D实现相机跟随控制

    这篇文章主要为大家详细介绍了Unity3D实现相机跟随控制,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    c罗天下第一10642022-09-22
  • C#C#求点集的最小包围矩形

    C#求点集的最小包围矩形

    这篇文章主要为大家详细介绍了C#求点集的最小包围矩形,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    侠客行江湖5932022-10-09
  • C#C#实现简单的登录界面

    C#实现简单的登录界面

    我们在使用C#做项目的时候,基本上都需要制作登录界面,那么今天我们就来一步步看看,如果简单的实现登录界面呢,本文给出2个例子,由简入难,希望...

    C#教程网10122021-11-03
  • C#C#如何动态设置屏幕分辨率

    C#如何动态设置屏幕分辨率

    这篇文章主要为大家详细介绍了C#动态设置屏幕分辨率的方法,我们可以使用Screen类设置屏幕分辨率,感兴趣的小伙伴们可以参考一下...

    Learning hard8272021-11-17