最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用C#實現(xiàn)一個PPT遙控器

 更新時間:2021年05月15日 09:04:28   作者:陜西顏值扛把子  
由于本人需要參加的討論會比較多,每次都會涉及到PPT,有時候坐在電腦旁講會比較不生動,前人就發(fā)明了PPT遙控器,今天就給大家介紹下基于C#實現(xiàn)ppt遙控器,感興趣的朋友一起看看吧

說明

本項目參考了 https://github.com/yangzhongke/PhoneAsPrompter 項目來完成實現(xiàn),并對其進行了一些修改完善。

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

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

另外,由于程序啟動后會創(chuàng)建一個WEB服務器,用來顯示PPT的操控界面,所以某些安全軟件可能會報毒。但是程序本身是沒有問題的。

截圖

具體實現(xiàn)

通過在Win Form項目中內(nèi)嵌一個Kestrel Web服務器,我們就可以通過瀏覽器向web服務器發(fā)送請求來接收遠程操作指令。之后通過Late Binding的方式去操作PPT。

1、在 Win Form項目中內(nèi)嵌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) =>
            {
                // 處理非靜態(tài)請求 
                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編程,我們需要注意內(nèi)存回收與釋放,所以需要用到COMReferenceTracker類進行應用管理。

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

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

以下操作使用dynamic進行操作,所有操作需要去查詢VBA文檔了解具體用法,以下僅演示部分操作

打開一個PPT的操作實現(xiàn)

   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();
            // 創(chuàng)建 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上一個動畫操作實現(xiàn)

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服務器端配置。

用戶訪問相應的地址,然后去執(zhí)行上面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");
                    }

完成前端

通過輪詢的方式,不斷的向服務端發(fā)送請求,獲取最新的消息,這樣我們就可以實現(xiàn)通過瀏覽器去操作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" 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>

到此這篇關(guān)于使用C#實現(xiàn)一個PPT遙控器的文章就介紹到這了,更多相關(guān)C#實現(xiàn)PPT遙控器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C#中科學繪圖庫ScottPlot的使用詳解

    C#中科學繪圖庫ScottPlot的使用詳解

    ScottPlot是基于.Net的一款開源免費的交互式可視化庫,支持Winform和WPF等UI框架,本文給大家介紹了C#中科學繪圖庫ScottPlot的使用方法,文中示例在WPF環(huán)境中運行,需要的朋友可以參考下
    2023-12-12
  • WinForm通過操作注冊表實現(xiàn)限制軟件使用次數(shù)的方法

    WinForm通過操作注冊表實現(xiàn)限制軟件使用次數(shù)的方法

    這篇文章主要介紹了WinForm通過操作注冊表實現(xiàn)限制軟件使用次數(shù)的方法,結(jié)合實例形式分析了WinForm操作注冊表的原理、步驟與相關(guān)實現(xiàn)技巧,需要的朋友可以參考下
    2017-06-06
  • C#委托與事件原理及實例解析

    C#委托與事件原理及實例解析

    這篇文章主要介紹了C#委托與事件原理及實例解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-12-12
  • C#?BitArray(點矩陣)轉(zhuǎn)換成int和string的方法實現(xiàn)

    C#?BitArray(點矩陣)轉(zhuǎn)換成int和string的方法實現(xiàn)

    BitArray?類管理一個緊湊型的位值數(shù)組,它使用布爾值來表示,本文主要介紹了C#?BitArray(點矩陣)轉(zhuǎn)換成int和string的方法實現(xiàn),具有一定的參考價值,感興趣的可以了解一下
    2022-05-05
  • C# 分支與循環(huán)介紹

    C# 分支與循環(huán)介紹

    在C# 程序中有三種結(jié)構(gòu): 順序結(jié)構(gòu),分支結(jié)構(gòu),循環(huán)結(jié)構(gòu)。
    2013-04-04
  • DevExpress實現(xiàn)自定義GridControl中按鈕文字內(nèi)容的方法

    DevExpress實現(xiàn)自定義GridControl中按鈕文字內(nèi)容的方法

    這篇文章主要介紹了DevExpress實現(xiàn)自定義GridControl中按鈕文字內(nèi)容的方法,需要的朋友可以參考下
    2014-08-08
  • asp.net實現(xiàn)遍歷Request的信息操作示例

    asp.net實現(xiàn)遍歷Request的信息操作示例

    這篇文章主要介紹了asp.net實現(xiàn)遍歷Request的信息操作,涉及asp.net針對請求信息相關(guān)操作打印操作技巧,需要的朋友可以參考下
    2020-03-03
  • C#實現(xiàn)搶紅包算法的示例代碼

    C#實現(xiàn)搶紅包算法的示例代碼

    很多商家都會使用紅包進行促銷,那么你知道紅包算法是怎么實現(xiàn)的嗎,本文主要介紹了C#實現(xiàn)搶紅包算法,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • VSCode配置C#運行環(huán)境的完整步驟

    VSCode配置C#運行環(huán)境的完整步驟

    這篇文章主要給大家介紹了關(guān)于VSCode配置C#運行環(huán)境的完整步驟,文中通過圖文介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-09-09
  • C# 刪除字符串中的中文(實例分享)

    C# 刪除字符串中的中文(實例分享)

    本文主要分享了C#刪除字符串中的中文的具體實例,具有一定的參考價值,需要的朋友一起來看下吧
    2016-12-12

最新評論

桦甸市| 杭锦后旗| 隆回县| 和田市| 桂阳县| 峡江县| 墨脱县| 桃园市| 马鞍山市| 张家港市| 石首市| 舒城县| 宣化县| 定边县| 甘洛县| 汉寿县| 句容市| 府谷县| 红原县| 大渡口区| 东源县| 祁东县| 兴海县| 长海县| 宜兰县| 大英县| 秭归县| 新源县| 广宁县| 泰兴市| 南溪县| 集贤县| 易门县| 晋宁县| 都兰县| 延津县| 太原市| 梅州市| 葵青区| 金寨县| 南宁市|