일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 무료 동영상 강의
- 소스 코드
- Windows Forms
- 동영상
- 산책하기 좋은 곳
- 언제나 휴일
- 유튜브 동영상 강의
- 프로젝트
- 강의
- 표준 라이브러리 함수
- 실습
- 네트워크 프로그래밍
- c언어
- 언제나휴일
- 졸업 작품
- 실습으로 다지는 c#
- 표준 입출력
- C++
- 클래스 다이어그램
- 충남 천안
- 추천
- 원격 제어 프로그램
- 알고리즘
- c#
- 동영상 강의
- 소켓 통신
- 파이썬
- 캡슐화
- 졸업 작품 소재
- 안드로이드 앱 개발
- Today
- Total
프로그래밍 언어 및 기술 [언제나휴일]
[C#] 원격 제어 프로그램 19. MainForm 본문
1. 유튜브 동영상 강의
2. MainForm
가상 커서와 원격 제어 화면과 상대 IP와 포트를 멤버를 선언합니다.
string sip; //상대 IP
int sport; //상대 port
RemoteCleintForm rcf = null;//원격 호스트 화면(제어 화면)
VirtualCursorForm vcf = null;//가상 커서
속성 창을 이용해서 Load 이벤트 핸들러를 등록하세요.
private void MainForm_Load(object sender, EventArgs e)
{
가상 커서 폼과 원격 제어 호스트 화면을 표시할 폼을 생성합니다.
vcf = new VirtualCursorForm(); //가상 커서 생성
rcf = new RemoteCleintForm(); //원격 호스트 화면 폼 생성
원격 제어 요청을 수신하였을 때의 처리 이벤트 핸들러를 등록합니다.
//원격 제어 요청 수신 이벤트 핸들러 등록
Remote.Singleton.RecvedRCInfo += new RecvRCInfoEventHandler(Remote_RecvedRCInfo);
}
크로스 스레드 문제가 발생할 수 있으니 다음처럼 문제를 해결하세요. Windows Forms 응용에서는 컨트롤을 소유하고 있는 스레드가 아닌 다른 스레드에서 컨트롤의 상태를 변경하려고 할 때 크로스 스레드 문제가 발생합니다.
이를 확인하려면 컨트롤의 InvokeRequired 속성을 확인합니다. 만약 InvokeRequired 속성이 true라면 현재 수행하는 스레드는 컨트롤을 소유하지 않은 스레드라는 의미입니다. 이 때 컨트롤의 Invoke 메서드를 호출하면 .NET 프레임워크에서는 컨트롤을 소유한 스레드가 대행하게 해 줍니다.
다음은 수신한 상대 정보를 컨트롤을 통해 표시하는 부분으로 크로스 스레드 문제를 해결하는 코드로 작성하였습니다.
delegate void Remote_Dele(object sender, RecvRCInfoEventArgs e);
void Remote_RecvedRCInfo(object sender, RecvRCInfoEventArgs e)
{
if (this.InvokeRequired)
{
object[] objs = new object[2]{sender,e};
this.Invoke(new Remote_Dele(Remote_RecvedRCInfo), objs);
}
else
{
상대 IP 주소를 텍스트 박스에 표시하고 IP와 포트 정보를 멤버에 설정합니다.
tbox_controller_ip.Text = e.IPAddressStr;// 요청 IP 주소를 표시
sip = e.IPAddressStr; //요청 IP 주소 설정
sport = e.Port; //요청 포트 설정
요청 수락할 수 있게 버튼을 활성화합니다.
btn_ok.Enabled = true; //요청 수락 버튼 활성화
}
}
속성 창을 이용하여 FormClosed 이벤트 핸들러를 등록하세요.
private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
{
원격 호스트와 컨트롤러를 멈춥니다.
Remote.Singleton.Stop();//원격 호스트 멈춤
Controller.Singleton.Stop();//원격 컨트롤러 멈춤
응용을 종료합니다.
Application.Exit();
}
btn_setting 컨트롤의 Click 이벤트 핸들러를 등록하세요.
private void btn_setting_Click(object sender, EventArgs e)
{
원격 제어 요청한 IP 주소가 로컬 IP 주소와 같으면 메시지 창으로 통보하고 이벤트 핸들러를 끝냅니다.
if (tbox_ip.Text == NetworkInfo.DefaultIP) //자신의 아이피와 같을 때
{
MessageBox.Show("같은 호스트를 원격 제어할 수 없습니다.");
tbox_ip.Text = string.Empty;
return;
}
입력한 IP 주소를 얻어옵니다.
string host_ip = tbox_ip.Text;
사각 영역을 구합니다.
Rectangle rect = Remote.Singleton.Rect;
원격 제어 컨트롤러를 가동합니다.
Controller.Singleton.Start(host_ip);//컨트롤러 가동
테두리를 고려하여 영역 크기를 조정한 후에 원격 제어 화면 폼을 시각화하세요.
rcf.ClientSize = new Size(rect.Width - 40, rect.Height - 80);
rcf.Show();//원격 제어 화면 폼 시각화
}
btn_ok 컨트롤의 Click 이벤트 핸들러를 등록하세요.
private void btn_ok_Click(object sender, EventArgs e)
{
MainForm을 숨깁니다.
this.Hide(); //자신의 화면을 숨기기
원격 제어 이벤트 수신 서버를 가동하여 원격 제어 컨트롤러의 제어 메시지를 수신합니다.
Remote.Singleton.RecvEventStart();//원격 제어 이벤트 수신 서버 가동
이미지 전송 타이머를 가동하여 주기적으로 데스크 톱 화면을 전송할 수 있게 합니다.
timer_send_img.Start(); //이미지 전송 타이머 가동
가상 커서를 시각화하여 원격 제어 컨트롤러가 제어하기 쉽게 해 줍니다.
vcf.Show(); //가상 커서 시각화
}
noti 컨트롤의 MouseDoubleClick 이벤트 핸들러를 등록하세요.
private void noti_MouseDoubleClick(object sender, MouseEventArgs e)
{
숨겼던 자신을 시각화합니다.
this.Show(); //자신을 시각화
}
이미지 전송 타이머인 timer_send_img 컨트롤의 Tick 이벤트 핸들러를 등록하세요.
private void timer_send_img_Tick(object sender, EventArgs e)
{
사각 영역을 구하여 비트맵 개체를 생성하고 Graphics 개체를 생성합니다.
Rectangle rect = Remote.Singleton.Rect; //사각 영역 구함
Bitmap bitmap = new Bitmap(rect.Width, rect.Height); //비트맵 생성
Graphics gp = Graphics.FromImage(bitmap);//비트맵에서 Graphics 개체 생성
Size size2 = new Size(rect.Width, rect.Height);
Graphics 개체로 화면을 복사합니다.
gp.CopyFromScreen(new Point(0, 0), new Point(0, 0), size2);//화면 복사
gp.Dispose();
try
{
복사한 이미지를 비동기로 전송합니다.
ImageClient ic = new ImageClient(sip, NetworkInfo.ImgPort);
ic.SendImageAsync(bitmap, null);//이미지를 비동기로 전송
}
예외가 발생하면 프로그램을 닫습니다.
catch
{
timer_send_img.Stop();
MessageBox.Show("서버에 연결 실패");
this.Close();
}
}
이상으로 원격 제어 프로그램 만들기가 끝났습니다. 테스트를 해 보시고 보다 나은 프로그램으로 수정해 보세요.
다음은 이번 실습에서 작성한 소스 코드입니다.
//MainForm.cs
using System;
using System.Drawing;
using System.Windows.Forms;
namespace 원격제어기
{
public partial class MainForm : Form
{
string sip; //상대 IP
int sport; //상대 port
RemoteCleintForm rcf = null;//원격 호스트 화면(제어 화면)
VirtualCursorForm vcf = null;//가상 커서
public MainForm()
{
InitializeComponent();
}
private void MainForm_Load(object sender, EventArgs e)
{
vcf = new VirtualCursorForm(); //가상 커서 생성
rcf = new RemoteCleintForm(); //원격 호스트 화면 폼 생성
//원격 제어 요청 수신 이벤트 핸들러 등록
Remote.Singleton.RecvedRCInfo += new RecvRCInfoEventHandler(
Remote_RecvedRCInfo);
}
delegate void Remote_Dele(object sender, RecvRCInfoEventArgs e);
void Remote_RecvedRCInfo(object sender, RecvRCInfoEventArgs e)
{
if (this.InvokeRequired)
{
object[] objs = new object[2]{sender,e};
this.Invoke(new Remote_Dele(Remote_RecvedRCInfo), objs);
}
else
{
tbox_controller_ip.Text = e.IPAddressStr;// 요청 IP 주소를 표시
sip = e.IPAddressStr; //요청 IP 주소 설정
sport = e.Port; //요청 포트 설정
btn_ok.Enabled = true; //요청 수락 버튼 활성화
}
}
private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
{
Remote.Singleton.Stop();//원격 호스트 멈춤
Controller.Singleton.Stop();//원격 컨트롤러 멈춤
Application.Exit();
}
private void btn_setting_Click(object sender, EventArgs e)
{
if (tbox_ip.Text == NetworkInfo.DefaultIP) //자신의 아이피와 같을 때
{
MessageBox.Show("같은 호스트를 원격 제어할 수 없습니다.");
tbox_ip.Text = string.Empty;
return;
}
string host_ip = tbox_ip.Text;
Rectangle rect = Remote.Singleton.Rect;
Controller.Singleton.Start(host_ip);//컨트롤러 가동
rcf.ClientSize = new Size(rect.Width - 40, rect.Height - 80);
rcf.Show();//원격 제어 화면 폼 시각화
}
private void btn_ok_Click(object sender, EventArgs e)
{
this.Hide(); //자신의 화면을 숨기기
Remote.Singleton.RecvEventStart();//원격 제어 이벤트 수신 서버 가동
timer_send_img.Start(); //이미지 전송 타이머 가동
vcf.Show(); //가상 커서 시각화
}
private void noti_MouseDoubleClick(object sender, MouseEventArgs e)
{
this.Show(); //자신을 시각화
}
private void timer_send_img_Tick(object sender, EventArgs e)
{
Rectangle rect = Remote.Singleton.Rect; //사각 영역 구함
Bitmap bitmap = new Bitmap(rect.Width, rect.Height); //비트맵 생성
Graphics gp = Graphics.FromImage(bitmap);//비트맵에서 Graphics 개체 생성
Size size2 = new Size(rect.Width, rect.Height);
gp.CopyFromScreen(new Point(0, 0), new Point(0, 0), size2);//화면 복사
gp.Dispose();
try
{
ImageClient ic = new ImageClient(sip, NetworkInfo.ImgPort);
ic.SendImageAsync(bitmap, null);//이미지를 비동기로 전송
}
catch
{
timer_send_img.Stop();
MessageBox.Show("서버에 연결 실패");
this.Close();
}
}
}
}
이상으로 원격 제어 프로그램에 관한 소개를 마칠게요. 여러분께서는 비동기 소켓 통신으로 버그를 개선하고 다른 기술과 융합하여 보다 나은 프로그램을 작성할 수 있기를 기대합니다.
'프로젝트 > C# 원격제어 프로그램' 카테고리의 다른 글
[C#] 원격 제어 프로그램 14. 원격 제어 컨트롤러 (0) | 2024.01.08 |
---|---|
[C#] 원격 제어 프로그램 15. 키보드, 마우스 이벤트 래퍼 (1) | 2024.01.08 |
[C#] 원격 제어 프로그램 16. 원격 제어 호스트 (0) | 2024.01.08 |
[C#] 원격 제어 프로그램 17. 가상 커서 (0) | 2024.01.08 |
[C#] 원격 제어 프로그램 18. 원격 클라이언트 폼 (0) | 2024.01.08 |
[C#] 원격 제어 프로그램 - 보너스 트랙 1. 화면 캡쳐/이미지 송수신 (1) | 2024.01.08 |
[C#] 원격 제어 프로그램 - 보너스 트랙 2. 오토 키보드 구현 (1) | 2024.01.08 |
[C#] 원격 제어 프로그램 - 보너스 트랙 3. 키보드 마우스 이벤트 송수신 (0) | 2024.01.08 |