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
또한 프로그램 이 시 작 된 후 PPT 의 조작 인터페이스 를 표시 하기 위해 WEB 서버 를 만 들 기 때문에 일부 보안 소프트웨어 는 마 약 을 보고 할 수 있 습 니 다.하지만 프로그램 자 체 는 문제 가 없다.
캡 처
구체 적 실현
Win Form 프로젝트 에 Kestrel 웹 서버 를 삽입 하면 브 라 우 저 를 통 해 웹 서버 에 원 격 조작 명령 을 받 을 수 있 습 니 다.이후 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 작업 을 알 게 된 후에 우 리 는 웹 서버 의 설정 을 보완 해 야 합 니 다.
사용 자 는 해당 주 소 를 방문 한 후 위의 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" 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 리모컨 을 실현 하 는 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 세 요.앞으로 많은 응원 부 탁 드 리 겠 습 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
WebView2를 Visual Studio 2017 Express에서 사용할 수 있을 때까지Evergreen .Net Framework SDK 4.8 VisualStudio2017에서 NuGet을 사용하기 때문에 패키지 관리 방법을 packages.config 대신 PackageReference를 사용해야...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.