목표

- 여러개의 클라이언트 동작 상태를 확인합니다.

- 통신을 중계하는 서버의 역할과 클라이언트의 역할을 확인합니다.

 

폼구성

 

 

소스코드

 

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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
 
namespace ChatClient
{
    public partial class Form1 : Form
    {
        TcpClient clientSocket; // 소켓
        NetworkStream stream = default(NetworkStream);
        string stSendMessage = "";
        // 메시지는 개행으로 구분한다.
        private static char CR = (char)0x0D;
        private static char LF = (char)0x0A;
        bool bThreadExit = false;
 
        public Form1()
        {
            InitializeComponent();
        }
 
        private void btn_Login_Click(object sender, EventArgs e)
        {
            bThreadExit = false;
            int Port = Int32.Parse(txt_Port.Text);
            clientSocket = new TcpClient();
            stream = default(NetworkStream);
            try
            {
                clientSocket.Connect(txt_ServerIP.Text, Port); // 접속 IP 및 포트
                stream = clientSocket.GetStream();
            }
            catch (Exception e2)
            {
                MessageBox.Show("서버가 실행중이 아닙니다.""연결 실패!");
                return;
            }
            btn_Login.Enabled = false;
            txt_user.Enabled = false;
 
            byte[] buffer = Encoding.Unicode.GetBytes("Login$"+ txt_user.Text + CR + LF);
            stream.Write(buffer, 0, buffer.Length);
            stream.Flush();
 
            Thread t_handler = new Thread(GetMessage);
            t_handler.IsBackground = true;
            t_handler.Start();
        }
 
        private void GetMessage()
        {
            while (!bThreadExit)
            {
                stream = clientSocket.GetStream();
                int BUFFERSIZE = clientSocket.ReceiveBufferSize;
                byte[] buffer = new byte[BUFFERSIZE];
                int bytes = stream.Read(buffer, 0, buffer.Length);
                string message = Encoding.Unicode.GetString(buffer, 0, bytes);
                DisplayText(message);
            }
        }
 
        private void DisplayText(string message)
        {
            if (rt_Message.InvokeRequired) //다른 쓰레드에서 실행되어 Invoke가 필요한 상태라면 
            {
                rt_Message.BeginInvoke(new MethodInvoker(delegate   ///델리게이트로 넘겨서 실행
                {
                    rt_Message.AppendText(message + Environment.NewLine);
                }));
            }
            else
                rt_Message.AppendText(message + Environment.NewLine);
        }
 
        private void btn_Logout_Click(object sender, EventArgs e)
        {
            
            byte[] buffer = Encoding.Unicode.GetBytes("exit" + CR + LF);
            stream.Write(buffer, 0, buffer.Length);
            stream.Flush();
            bThreadExit = true;
            Thread.Sleep(1000);            
 
            Application.Exit();
            
        }
 
        private void btn_Send_Click(object sender, EventArgs e)
        {
            byte[] buffer = Encoding.Unicode.GetBytes(txt_user.Text + "$" + txt_message.Text + CR + LF);
            stream.Write(buffer, 0, buffer.Length);
            stream.Flush();
            txt_message.Text = "";
        }
 
        private void txt_message_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter) btn_Send_Click(sender, e);
        }
    }
}
 
cs

 

동작

 

클라이언트에서 메시지를 보내면 서버에서 중계 역할을 하여 현재 접속되어 있는 클라이언트에 같은 메시지를 모두 전송

ChatClient.zip
0.04MB
MultiChatServer.zip
0.06MB

활용

네트워크를 활용한 응용 프로그램 구현

 

 

=====================================================

이 자료는 학생들과 특강시간에 만들어 보는 프로그램입니다.

=====================================================

 

오늘도 최선을 다하는 우리 학생들을 응원합니다.

인천 서구 검단신도시 원당컴퓨터학원

 

 

원당컴퓨터학원에서는?

1. 4차 산업 시대의 흐름은 컴퓨터를 얼마나 이해하느냐에 따라 삶의 질이 틀려 질 수 있다는 것을 항상 염두에 두고 있습니다.

2. 알고리즘은 프로그래밍의 근원이 되는 문제해결 능력이며, 머신러닝은 IoT등에 의해 모여진 데이터를 활용하는 기법입니다.

3. 이에 따라 초,중,고 학생들이 알기 쉽게 이해하는 인공지능 부터 알고리즘까지 학생들의 실력에 맞춰 수업을 진행중에 있습니다.

4. 현재 초등학생이 고등학생이 되는 때에는 고교학점제 도입에 따라 자신이 전공하고자 하는 특기가 크게 부각 될것입니다.

5. IT 업체중 규모가 큰 곳에서는 코딩테스트(알고리즘테스트)로 블라인드 면접을 수행하는곳이 늘고 있습니다.

6. 미래 IT를 꿈꾸는 학생들의 산실이 되기 위해 항상 최선을 다하는 원당컴퓨터학원이 되겠습니다.

 

※ 정보영재 혹은 인공지능 관련 수업에 관해 궁금하신 분은 문의(032-565-5497) 주세요.

 

 

원당컴퓨터학원 커리큘럼

- OA : 학교 수행 평가에 꼭 필요한 컴퓨터 활용능력 향상

- IT 자격증 과정 : 취업대비,대학생인증제,승진을 위한 국가공인 자격증 취득과정

- 정보영재 : 정보올림피아드 및 알고리즘 대회/소프트웨어특기자전형/디미고 특별전형 대비/코딩테스트 대비를 위한 알고리즘 과정

- 프로젝트반 : 응용프로그래밍/웹프로그래밍/앱프로그래밍 등을 통해 직접 만들어 보면서 컴퓨터 프로그래밍 이해(소프트웨어 학생부종합전형/특성화고(디미고,선린고등) 특별전형대비)

- 인공지능 : 인공지능의 이해 및 실습을 통해 빅데이터 가공(4차 산업 시대의 축이 되는 인공지능 시대를 대비)

- 과고,영재고,컴퓨터학과(SW) 대학생을 위한 내신대비 : python,java,c++,자료구조,알고리즘 

사업자 정보 표시
원당컴퓨터학원 | 기희경 | 인천 서구 당하동 1028-2 장원프라자 502호 | 사업자 등록번호 : 301-96-83080 | TEL : 032-565-5497 | Mail : icon001@naver.com | 사이버몰의 이용약관 바로가기
  1. 핑구야날자 2021.04.03 07:59

    덕분에 c#을 배우고 싶다는 생각이 드네요

  2. Favicon of https://invitetour.tistory.com BlogIcon 휴식같은 친구 2021.04.03 22:05 신고

    채팅소스를 공유해 주셨군요.
    필요한 분들에게 큰 도움이 되겠습니다.

  3. Favicon of http://deborah.tistory.com BlogIcon 데보라 2021.04.03 23:02

    오 새로운 것 하나 배웠습니다.

  4. Favicon of http://pangyione.com/ BlogIcon 청결원 2021.04.04 06:54

    포스팅 잘 보고 갑니다
    휴일 잘 보내세요~

  5. Favicon of https://heysukim114.tistory.com BlogIcon *저녁노을* 2021.04.04 07:17 신고

    노을인 어려워요.ㅎㅎ

  6. Favicon of https://ramideunioni.tistory.com BlogIcon 라드온 2021.04.04 19:13 신고

    멀티채팅프로그램만들기 재밌겠는데요?!

  7. 2021.04.04 19:56

    비밀댓글입니다

  8. Favicon of https://lsmpkt.tistory.com BlogIcon 가족바라기 2021.04.04 20:44 신고

    어렵지만 새로운것 배울수 있어 좋네요

  9. Favicon of https://xuronghao.tistory.com BlogIcon 空空(공공) 2021.04.05 08:02 신고

    소스 필요하신 분들 도움이 되실듯 합니다

  10. Favicon of https://dragonphoto.tistory.com BlogIcon 드래곤포토 2021.04.05 18:53 신고

    저도 프로그래머출신이지만 C#이 있는 건 처음알고 갑니다.
    새로운 언어가 생기네요

목표

- 버튼을 생성하여 마우스 클릭하여 버튼을 해당 위치로 이동시켜 보자.

 

폼구성

폼에 테스트 할 버튼을 하나 올려 놓자.

 

소스코드

 

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
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
 
namespace ButtonMove
{
    public partial class Form1 : Form
    {
        private Boolean mouseDown = false;
        private Point startPos;
        private Point endPos;
        public Form1()
        {
            InitializeComponent();
        }
 
        private void Btn_Move_MouseDown(object sender, MouseEventArgs e)
        {
            mouseDown = true;
            startPos = ((Control)sender).PointToScreen(new Point(e.X, e.Y));
        }
 
        private void Btn_Move_MouseUp(object sender, MouseEventArgs e)
        {
            mouseDown = false;
        }
 
        private void Btn_Move_MouseMove(object sender, MouseEventArgs e)
        {
            if (mouseDown == falsereturn;
            endPos = ((Control)sender).PointToScreen(new Point(e.X, e.Y));
            Point temp = new Point((btn_Move.Location.X + (endPos.X - startPos.X)),
                            (btn_Move.Location.Y + (endPos.Y - startPos.Y)));
            startPos = endPos;
            btn_Move.Location = temp;
        }
    }
}
 
cs

 

ButtonMove.zip
0.18MB

활용

컴포넌트을 마우스로 이동하는 프로그램을 만들때 사용한다.

 

=====================================================

이 자료는 학생들과 특강시간에 만들어 보는 프로젝트입니다.

=====================================================

 

오늘도 최선을 다하는 우리 학생들을 응원합니다.

인천 서구 검단신도시 원당컴퓨터학원

 

사업자 정보 표시
원당컴퓨터학원 | 기희경 | 인천 서구 당하동 1028-2 장원프라자 502호 | 사업자 등록번호 : 301-96-83080 | TEL : 032-565-5497 | Mail : icon001@naver.com | 사이버몰의 이용약관 바로가기
  1. Favicon of https://invitetour.tistory.com BlogIcon 휴식같은 친구 2021.03.19 10:11 신고

    마우스 이벤트를 구현하는 코딩이군요.
    잘 보고 갑니다~ 즐거운 하루 보내세요.

  2. Favicon of http://pangyione.com/ BlogIcon 청결원 2021.03.19 15:00

    포스팅 잘 보고 갑니다
    오늘 하루도 즐거운 하루 보내세요~

  3. Favicon of https://xuronghao.tistory.com BlogIcon 空空(공공) 2021.03.20 07:31 신고

    이런 방법도 있군요^^
    주말 잘 보내시기 바랍니다.

  4. Favicon of https://dragonphoto.tistory.com BlogIcon 드래곤포토 2021.03.20 14:26 신고

    즐거운 주말 보내세요

  5. 핑구야날자 2021.03.20 20:00

    코딩은 요즘은 하려는 사람들이 많아서 인기가 많아요

  6. Favicon of https://lsmpkt.tistory.com BlogIcon 가족바라기 2021.03.20 23:34 신고

    유용한포스팅 잘보고 갑니다
    편안한밤되세요^^

  7. Favicon of http://pangyione.com/ BlogIcon 청결원 2021.03.21 06:50

    포스팅 잘 보고 갑니다
    즐거운 휴일 보내세요~

  8. Favicon of https://uhastory.tistory.com BlogIcon 유하v 2021.03.22 08:57 신고

    코딩 조금이라도할 줄 알면 머리속에 떠오르는 아이디어들을 만들어 낼 수 있어서 좋을것 같아요 ㅎ

  9. Favicon of https://bubleprice.tistory.com BlogIcon 버블프라이스 2021.03.22 16:14 신고

    오, 많은 도움이 되었습니다^^
    배울게 참 많네요

  10. 2021.03.22 16:14

    비밀댓글입니다

  11. Favicon of https://ramideunioni.tistory.com BlogIcon 라드온 2021.03.23 07:37 신고

    이런 재미난 예제 따라하면 실력이 금세 늘죠.ㅎㅎㅎ

목표

- 소켓통신 방법을 살펴 봅니다.

- 서버와 클라이언트 프로그램의 의미를 이해 합니다.

- 서버의 역할은 클라이언트의 중계역할을 담당하며 24시간 365일 구동 되는 것을 목표로 하며 안정성이 최우선됨(클라이언트 접속/해제 시에 메모리 생성 및 해제)

 

서버 소켓 프로그래밍 구현 방법 이해하기

1. 서버 소켓 생성하기 : Socket Create

2. 서버가 사용할 IP 주소와 포트번호를 결합 : Bind

3. 서버 소켓 시작 : Start

4. 클라이언트로 부터 연결요청이 들어 오는지 확인 : Listen

5. 연결요청 시 허용 : accept

6. 클라이언트로부터 정보 수신 : Received

7. 클라이언트 접속 해제 처리 : DisConnected

 

 

폼구성

panel : 1개 , Dock - Top

label : 1개 (접속대기포트)

textbox : 1개 (1004)

button : 1개 (연결대기)

richtextbox : 1개, Dock - Fill

 

 

SeverSocket 소스

 

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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
 
namespace MultiChatServer
{
    internal class Client : SocketAsyncEventArgs
    {
        // 메시지는 개행으로 구분한다.
        private static char CR = (char)0x0D;
        private static char LF = (char)0x0A;
        private Socket socket;
        // 메시지를 모으기 위한 버퍼
        private StringBuilder sb = new StringBuilder();
        private IPEndPoint remoteAddr;
 
        public delegate void ClientReceiveHandler(Socket sock, String msg); //수신 메시지 이벤트를 위한 델리게이트
        public event ClientReceiveHandler OnReceive;
        public delegate void ClientDisconnectHandler(Socket sock);
        public event ClientDisconnectHandler OnDisconnect;
 
        public Client(Socket socket)
        {
            try
            {
                this.socket = socket;
                // 메모리 버퍼를 초기화 한다. 크기는 1024이다
                base.SetBuffer(new byte[1024], 01024);
                base.UserToken = socket;
                // 메시지가 오면 이벤트를 발생시킨다. (IOCP로 꺼내는 것)
                base.Completed += Client_Completed;
                // 메시지가 오면 이벤트를 발생시킨다. (IOCP로 넣는 것)
                this.socket.ReceiveAsync(this);
                // 접속 환영 메시지
                remoteAddr = (IPEndPoint)socket.RemoteEndPoint;
                if(remoteAddr!=null)
                {
                    Console.WriteLine($"Client : (From: {remoteAddr.Address.ToString()}:{remoteAddr.Port}, Connection time: {DateTime.Now})");
                    this.Send("Welcome server!\r\n>");
                }
                
            }
            catch(Exception e)
            {
                return;
            }
            
        }
        ~Client()
        {
            socket = null;
        }
 
        public void Send(String msg)
        {
            byte[] sendData = Encoding.Unicode.GetBytes(msg);
            //sendArgs.SetBuffer(sendData, 0, sendData.Length);
            //socket.SendAsync(sendArgs);
            // Client로 메시지 전송
            if(socket != null)     socket.Send(sendData, sendData.Length, SocketFlags.None);
        }
 
        private void Client_Completed(object sender, SocketAsyncEventArgs e)
        {
            // 접속이 연결되어 있으면...
            if (socket.Connected && base.BytesTransferred > 0)
            {
                // 수신 데이터는 e.Buffer에 있다.
                byte[] data = e.Buffer;
                // 데이터를 string으로 변환한다.
                string msg = Encoding.Unicode.GetString(data);
                // 메모리 버퍼를 초기화 한다. 크기는 1024이다
                base.SetBuffer(new byte[1024], 01024);
                // 버퍼의 공백은 없앤다.
                sb.Append(msg.Trim('\0'));
                // 메시지의 끝이 이스케이프 \r\n의 형태이면 서버에 표시한다.
                if (sb.Length >= 2 && sb[sb.Length - 2== CR && sb[sb.Length - 1== LF)
                {
                    // 개행은 없애고..
                    sb.Length = sb.Length - 2;
                    // string으로 변환한다.
                    msg = sb.ToString();
                    if (OnReceive != null)
                        OnReceive(this.socket,msg); // 수신 이벤트 발생
 
                    
                    // 만약 메시지가 exit이면 접속을 끊는다.
                    if ("exit".Equals(msg, StringComparison.OrdinalIgnoreCase))
                    {
                        OnDisconnect(socket);
                        // 접속을 중단한다.
                        socket.DisconnectAsync(this);
                        return;
                    }
                    // 버퍼를 비운다.
                    sb.Clear();
                }
                // 메시지가 오면 이벤트를 발생시킨다. (IOCP로 넣는 것)
                this.socket.ReceiveAsync(this);
            }
            else
            {
                OnDisconnect(socket);
                
}
        }
 
    }
 
    // 서버 Event로 SocketAsyncEventArgs를 상속받았다.
    class Server : SocketAsyncEventArgs
    {
        public delegate void ClientReceiveHandler(Socket sock, String msg); //수신 메시지 이벤트를 위한 델리게이트
        public event ClientReceiveHandler OnReceive;
        public delegate void ClientDisconnectHandler(Socket sock);
        public event ClientDisconnectHandler OnDisconnect;
        public delegate void ClientConnectHandler(Socket sock);
        public event ClientConnectHandler OnConnect;
 
        private Socket socket;
        public List<Socket> clientSocketList = new List<Socket>();//클라이언트 소켓을 관리하는 리스트, 소켓과 접속 아이디를 관리하자.
        public Dictionary<Socket,Client> clientList = new Dictionary<Socket, Client>();//클라이언트 소켓을 관리하는 리스트, 소켓과 접속 아이디를 관리하자.
 
        public Server(Socket socket)
        {
            this.socket = socket;
            base.UserToken = socket;
            // Client로부터 Accept이 되면 이벤트를 발생시킨다. (IOCP로 꺼내는 것)
            base.Completed += Server_Completed; 
        }
 
        public void SocketClose()
        {
            foreach(var client in clientSocketList)
            {
                if (client.Connected) client.Disconnect(false);
                client.Dispose();
            }
            foreach (var client in clientList)
            {
                Client c = client.Value;
                c.Dispose();
            }
            clientSocketList.Clear();
            clientList.Clear();
        }
 
        // Client가 접속하면 이벤트를 발생한다.
        private void Server_Completed(object sender, SocketAsyncEventArgs e)
        {
            try
            {
                // 접속이 완료되면, Client Event를 생성하여 Receive이벤트를 생성한다.
                var client = new Client(e.AcceptSocket);
                client.OnReceive += ClientReceive;
                client.OnDisconnect += ClientDisconnect;
 
                clientSocketList.Add(e.AcceptSocket);
                clientList.Add(e.AcceptSocket, client);
                // 서버 Event에 cilent를 제거한다.
                e.AcceptSocket = null;
                // Client로부터 Accept이 되면 이벤트를 발생시킨다. (IOCP로 넣는 것)
                this.socket.AcceptAsync(e);
                if(OnConnect != null)
                {
                    OnConnect(this.socket);
                }
            }
            catch (Exception ex)
            {
                return;
            }
            
        }
 
        private void ClientDisconnect(Socket sock)
        {
            
            if (OnDisconnect != null)
                OnDisconnect(sock);
 
            clientList.Remove(sock);
            clientSocketList.Remove(sock);
        }
 
        private void ClientReceive(Socket sock, string msg)
        {
            if (OnReceive != null)
                OnReceive(sock, msg);
        }
        public void SendAllMessage(String msg)
        {
            foreach(var client in clientList)
            {
                Client c = client.Value;
                c.Send(msg);
            }
        }
    }
 
    class ServerProgram : Socket
    {
        public delegate void ClientReceiveHandler(Socket sock, String msg); //수신 메시지 이벤트를 위한 델리게이트
        public event ClientReceiveHandler OnReceive;
        public delegate void ClientDisconnectHandler(Socket sock);
        public event ClientDisconnectHandler OnDisconnect;
        public delegate void ClientConnectHandler(Socket sock);
        public event ClientConnectHandler OnConnect;
 
        private bool _disposed = false;
 
 
        public Server serverSocket;
        public IPEndPoint ipEndPoint;
        public ServerProgram(int port) : base(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
        {
            ipEndPoint = new IPEndPoint(IPAddress.Any, port);
            try
            {
                base.Bind(ipEndPoint);
                base.Listen(20);
                // 비동기 소켓으로 Server 클래스를 선언한다. (IOCP로 집어넣는것)
                serverSocket = new Server(this);
                serverSocket.OnConnect += ClientConnect;
                serverSocket.OnDisconnect += ClientDisConnect;
                serverSocket.OnReceive += ClientRecieve;
 
                base.AcceptAsync(serverSocket);
            }
            catch(Exception ex)
            {
                return;
            }
            
        }
        
        private void ClientRecieve(Socket sock, string msg)
        {
            if (OnReceive != null)
                OnReceive(sock, msg);
        }
 
        private void ClientDisConnect(Socket sock)
        {
            if (OnDisconnect != null)
                OnDisconnect(sock);
        }
 
        private void ClientConnect(Socket sock)
        {
            if (OnConnect != null)
                OnConnect(sock);
        }
 
        protected override void Dispose(bool disposing)
        {
            if (_disposed) return;
            try
            {
                if(serverSocket != null)
                {
                    serverSocket.SocketClose();
                    base.Disconnect(true);
                    
                    base.Shutdown(SocketShutdown.Both);
                    base.Close();
                    base.Dispose();
 
                    GC.SuppressFinalize(serverSocket);
                }
                //serverSocket = null;
            }
            catch(Exception ex)
            {
                //
            }
            finally
            {
                //base.Close(0);
            }
            _disposed = true;
        }
 
        public void SendMessage(String msg)
        {
            if (serverSocket != null)
                serverSocket.SendAllMessage(msg);
        }
    }
 
}
cs

 

 

Form1 소스코드

 

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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
 
namespace MultiChatServer
{
    public partial class Form1 : Form
    {
 
        public Dictionary<Socket, string> clientSocketList = new Dictionary<Socket, string>();//클라이언트 소켓을 관리하는 리스트, 소켓과 접속 아이디를 관리하자.
 
        ServerProgram multiServer;
        int serverPort;
 
        public Form1() 
        {
            InitializeComponent();
 
        }
 
 
        private void allClientSend(string message, string username, bool flag)
        {
            String curDate = DateTime.Now.ToString("yyyy.MM.dd. HH:mm:ss"); // 현재 날짜 받기
 
            String sendMsg;
 
            byte[] buffer = null;
            if (flag)
            {
                if (message.Equals("disConnect"))
                    sendMsg = username + " 님이 대화방을 나갔습니다.";
                else
                    sendMsg = "[ " + curDate + " ] " + username + " : " + message;
 
            }
            else
            {
 
                sendMsg = message;
 
            }
 
            multiServer.SendMessage(sendMsg);
 
 
        }
 
        private void displayMessage(string text)
        {
            if (txt_Message.InvokeRequired) //다른 쓰레드에서 실행되어 Invoke가 필요한 상태라면 
            {
                txt_Message.BeginInvoke(new MethodInvoker(delegate   ///델리게이트로 넘겨서 실행
                {
                    txt_Message.AppendText(text + Environment.NewLine);
                }));
            }
            else
                txt_Message.AppendText(text + Environment.NewLine);
 
        }
 
        private void button1_Click(object sender, EventArgs ev)
        {
            button1.Enabled = false;
            try
            {
                serverPort = Int32.Parse(txt_ServerPort.Text.ToString()); // 소켓 번호 설정
            }
            catch (FormatException e)
            {
                //textbox 에 숫자 외의 문자인 경우
                serverPort = 1004;
            }
 
            multiServer = new ServerProgram(serverPort);
            multiServer.OnConnect += clientConnected;
            multiServer.OnDisconnect += clientDisconncted;
            multiServer.OnReceive += clientReceive;               
            
        }
 
        private void clientReceive(Socket sock, String msg)
        {
            int index = msg.IndexOf("$");
            String curDate = DateTime.Now.ToString("HH:mm:ss"); // 현재 날짜 받기
            String stCmd="";
            String stData="";
            String sendMsg = "";
            if (index > 0)
            {
                stCmd = msg.Substring(0, index); //$를 기준으로 앞 부분을 cmd로 
                stData = msg.Substring(index + 1);
                
            }
            if(stCmd.ToUpper() =="Login".ToUpper())
            {
                clientSocketList[sock] = stData; // Login 사용자명 셋팅
                sendMsg = "[ " + curDate + " ] " + stData + "님이 입장하셨습니다.";
            }
            else
            {
                sendMsg = "[ " + curDate + " ] " + stCmd + " : " + stData;
            }
            displayMessage(sendMsg);
            if(multiServer!=null) multiServer.SendMessage(sendMsg);
 
        }
 
        private void clientDisconncted(Socket sock)
        {
            String userName;
            if (clientSocketList.ContainsKey(sock))
            {
                userName = clientSocketList[sock];
                allClientSend("disConnect", userName, true);
                clientSocketList.Remove(sock);
            }
        }
 
        private void clientConnected(Socket sock)
        {
            clientSocketList.Add(sock, "");
        }
    }
}
 
cs

 

활용

멀티 게임 서버 와 같이 중계 역할을 수행하는 서버 프로그램 구현

 

 

=====================================================

이 자료는 학생들과 특강시간에 만들어 보는 프로그램입니다.

=====================================================

 

오늘도 최선을 다하는 우리 학생들을 응원합니다.

인천 서구 검단신도시 원당컴퓨터학원

사업자 정보 표시
원당컴퓨터학원 | 기희경 | 인천 서구 당하동 1028-2 장원프라자 502호 | 사업자 등록번호 : 301-96-83080 | TEL : 032-565-5497 | Mail : icon001@naver.com | 사이버몰의 이용약관 바로가기
  1. 핑구야날자 2021.03.11 06:43

    멀티 기능을 코딩 하는 것은 참 재미있는 거 같아요 멀티 채팅 프로그램 잘 보고 갑니다

  2. Favicon of https://xuronghao.tistory.com BlogIcon 空空(공공) 2021.03.11 07:21 신고

    멀티채틴 프로그램의 코딩이로군요
    학생들 도움이 되겠습니다.

  3. Favicon of https://dragonphoto.tistory.com BlogIcon 드래곤포토 2021.03.11 07:49 신고

    좋은아침입니다.
    즐거운하루되세요

  4. Favicon of https://invitetour.tistory.com BlogIcon 휴식같은 친구 2021.03.11 09:11 신고

    채팅하는 프로그램이군요.
    잘 보고 갑니다~ 즐거운 하루 보내세요.

  5. Favicon of https://ramideunioni.tistory.com BlogIcon 라드온 2021.03.11 12:14 신고

    C#으로 만든 프로그램이군요. 소켓이며, 뭐며...슬쩍슬쩍 기억이 나네요.ㅋ
    잘봤습니다.

  6. Favicon of http://pangyione.com/ BlogIcon 청결원 2021.03.11 13:47

    포스팅 잘 보고 갑니다
    오늘도 즐거운 하루 보내세요~

  7. 2021.03.11 15:32

    비밀댓글입니다

  8. Favicon of https://heysukim114.tistory.com BlogIcon *저녁노을* 2021.03.12 06:34 신고

    다소 어려워요.ㅎㅎ
    잘 보고ㄱㅏ네요

목표

- 공공데이터 API를 활용하는 방법 알아보기

- XML 데이터를 파싱하는 방법 알아 보기

 

준비

- www.data.go.kr  에서 회원가입 후 공공데이터 오픈API 활용신청

- 데이터목록에서 인천 버스로 검색 하여 다음과 같은 4가지 서비스를 활용신청

 

 

 

폼구성

위와 같이 폼을 두개 구성

[Form1]

- panel : 1개 Dock-Top

- label,textbox,button : 각각 1개씩 panel 위에 올림

- listview : Dock-Fill, View-Details, Columns 의 열 6개 추가 하여 위와 같이 버스번호/차량번호/현재위치/남은좌석/남은정거장/노선번호로 Text를 변경

 

[Form2]

- listview : Columns 에 열 3개를 추가하여 지역/정류소명,정류소아이디 로 Text 변경

- 버튼 2개 -선택/취소

 

 

작업순서

1) 정류소 조회 API를 이용하여 정류소명으로 정류소 아이디를 가져온다.

2) 버스도착정보 조회 API를 이용하여 정류소아이디로 버스도착 정보를 가져온다.

3) 버스노선조회 API를 이용하여 버스도착정보의 노선번호로 버스번호를 가져온다.

 

 

소스코드

[Form1] - 소스코드

 

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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;
 
namespace JsonAPI
{
    public partial class Form1 : Form
    {
        
 
        String busStationID;
 
        public Form1()
        {
            InitializeComponent();
        }
 
        private void getBusStationList()
        {
            throw new NotImplementedException();
        }
 
        private void btn_BusStationSearch_Click(object sender, EventArgs e)
        {
            Form2 frm = new Form2();
            try
            {
                frm.setBusStationName(txt_BusStationName.Text);
                frm.ShowDialog();
                busStationID = frm.getBusStationID();
                txt_BusStationName.Text = frm.getBusStationName();
                Console.WriteLine(busStationID);
                ArrivalInformation(busStationID);
            }
            finally
            {
                if (frm != null) frm.Dispose();
                //if (frm != null) ((IDisposable)frm).Dispose(); //폼을 해제하자
            }           
            
        }
 
        private void ArrivalInformation(string busStationID)
        {
            WebClient wc = null;
            XmlDocument doc = null;
            XmlNode root = null;
 
            wc = new WebClient() { Encoding = Encoding.UTF8 };
            doc = new XmlDocument();
            String stBusPlate="";
            String stLastBusStationName="";
            String stRemaindSeat="";
            String stRestStopCount="";
            String stRouteID="";
            String stBusNo = "";
            this.lv_BusState.Items.Clear();
 
            try
            {
                List<string> ltReturn = new List<string>();
                String xmlData = wc.DownloadString(new Uri("http://apis.data.go.kr/6280000/busArrivalService/getAllRouteBusArrivalList?serviceKey=" + 승인번호 + "&pageNo=1&numOfRows=10&bstopId=" + busStationID ));
                doc.LoadXml(xmlData);
                root = doc.SelectSingleNode("ServiceResult");
                XmlNode msgHeader = root.SelectSingleNode("msgHeader");
                if (msgHeader.SelectSingleNode("resultCode").InnerText != "0")
                {
                    return//정상으로 들어 오지 않았으면 빠져 나가자
                }
 
                XmlNodeList itemList = doc.GetElementsByTagName("itemList");
                foreach (XmlNode nowItem in itemList)
                {
                    if (nowItem["BUS_NUM_PLATE"!= null)
                    {
                        Console.WriteLine(nowItem["BUS_NUM_PLATE"].InnerText.ToString());
                        stBusPlate = nowItem["BUS_NUM_PLATE"].InnerText.ToString();
                    }
                    if (nowItem["LATEST_STOP_NAME"!= null)
                    {
                        Console.WriteLine(nowItem["LATEST_STOP_NAME"].InnerText.ToString());
                        stLastBusStationName = nowItem["LATEST_STOP_NAME"].InnerText.ToString();
                    }
                    if (nowItem["REMAIND_SEAT"!= null)
                    {
                        Console.WriteLine(nowItem["REMAIND_SEAT"].InnerText.ToString());
                        stRemaindSeat = nowItem["REMAIND_SEAT"].InnerText.ToString();
                    }
                    if (nowItem["REST_STOP_COUNT"!= null)
                    {
                        Console.WriteLine(nowItem["REST_STOP_COUNT"].InnerText.ToString());
                        stRestStopCount = nowItem["REST_STOP_COUNT"].InnerText.ToString();
                        // this.lv_BusStation.Items.Add(new ListViewItem(new string[] { stPosition, stBusStationName, stBusStationID }));
                    }
                    if (nowItem["ROUTEID"!= null)
                    {
                        Console.WriteLine(nowItem["ROUTEID"].InnerText.ToString());
                        stRouteID = nowItem["ROUTEID"].InnerText.ToString();
                        stBusNo = getBusNo(stRouteID); //노선번호로 버스번호를 가져오자
                        this.lv_BusState.Items.Add(new ListViewItem(new string[] { stBusNo, stBusPlate, stLastBusStationName, stRemaindSeat, stRestStopCount, stRouteID }));
                    }
 
                }
            }
            catch (Exception e)
            {
                return;
            }
            finally
            {
                doc = null;
                root = null;
                wc.Dispose();
            }
 
            
        }
 
        private String getBusNo(String stRouteID)
        {
            WebClient wc = null;
            XmlDocument doc = null;
            XmlNode root = null;
 
            wc = new WebClient() { Encoding = Encoding.UTF8 };
            doc = new XmlDocument();
            String stBusNo = "";
            try
            {
                List<string> ltReturn = new List<string>();
                String xmlData = wc.DownloadString(new Uri("http://apis.data.go.kr/6280000/busRouteService/getBusRouteId?serviceKey=" + 승인번호 + "&pageNo=1&numOfRows=10&routeId=" + stRouteID));
                doc.LoadXml(xmlData);
                root = doc.SelectSingleNode("ServiceResult");
                XmlNode msgHeader = root.SelectSingleNode("msgHeader");
                if (msgHeader.SelectSingleNode("resultCode").InnerText != "0")
                {
                    return ""//정상으로 들어 오지 않았으면 빠져 나가자
                }
 
                XmlNodeList itemList = doc.GetElementsByTagName("itemList");
                foreach (XmlNode nowItem in itemList)
                {
                    if (nowItem["ROUTENO"!= null)
                    {
                        Console.WriteLine(nowItem["ROUTENO"].InnerText.ToString());
                        return stBusNo = nowItem["ROUTENO"].InnerText.ToString();
                    }
                    
 
                }
            }
            catch (Exception e)
            {
                return "";
            }
            finally
            {
                doc = null;
                root = null;
                wc.Dispose();
            }
 
            return stBusNo;
        }
    }
}
 
cs

 

 

 

 

[Form2] - 소스코드

 

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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;
 
namespace JsonAPI
{
    public partial class Form2 : Form
    {
        WebClient wc = null;
        XmlDocument doc = null;
        XmlNode root = null;
 
        public static String busStationName="";
        public static String busStationID="";
        public Form2()
        {
            InitializeComponent();
 
        }
 
        private void button2_Click(object sender, EventArgs e)
        {
            Close();
        }
 
        public void setBusStationName(String name)
        {
            busStationName = name;
        }
        public String getBusStationName()
        {
            return busStationName ;
        }
        public String getBusStationID()
        {
            return busStationID;
        }
 
        private void Form2_Load(object sender, EventArgs e)
        {
            getBusStaiontList(busStationName);
        }
 
        private void getBusStaiontList(string busStationName)
        {
            String stPosition = "";
            String stBusStationName = "";
            String stBusStationID = "";
            this.lv_BusStation.Items.Clear();
            wc = new WebClient() { Encoding = Encoding.UTF8 };
            doc = new XmlDocument();
            try
            {
                List<string> ltReturn = new List<string>();
                String xmlData = wc.DownloadString(new Uri("http://apis.data.go.kr/6280000/busStationService/getBusStationNmList?serviceKey=" + 승인번호 + "D&pageNo=1&numOfRows=10&bstopNm=" + busStationName ));
                doc.LoadXml(xmlData);
                root = doc.SelectSingleNode("ServiceResult");
                XmlNode msgHeader = root.SelectSingleNode("msgHeader");
                if (msgHeader.SelectSingleNode("resultCode").InnerText != "0" )
                {
                    return//정상으로 들어 오지 않았으면 빠져 나가자
                }
                
                XmlNodeList itemList = doc.GetElementsByTagName("itemList");
                foreach (XmlNode nowItem in itemList)
                {
                    if (nowItem["ADMINNM"!= null)
                    {
                        Console.WriteLine(nowItem["ADMINNM"].InnerText.ToString());
                        stPosition = nowItem["ADMINNM"].InnerText.ToString();
                    }
                    if (nowItem["BSTOPNM"!= null)
                    {
                        Console.WriteLine(nowItem["BSTOPNM"].InnerText.ToString());
                        stBusStationName = nowItem["BSTOPNM"].InnerText.ToString();
                    }
                    if (nowItem["BSTOPID"!= null)
                    {
                        Console.WriteLine(nowItem["BSTOPID"].InnerText.ToString());
                        stBusStationID = nowItem["BSTOPID"].InnerText.ToString();
                    }
                    if (nowItem["SHORT_BSTOPID"!= null)
                    {
                        Console.WriteLine(nowItem["SHORT_BSTOPID"].InnerText.ToString());
                        this.lv_BusStation.Items.Add(new ListViewItem(new string[] { stPosition, stBusStationName, stBusStationID }));
                    }
                    
                }
 
 
 
            }
            catch(Exception e)
            {
                return;
            }
            finally
            {
                doc = null;
                root = null;
                wc.Dispose();
            }
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            if(this.lv_BusStation.SelectedItems.Count>0)
            {
                int index = this.lv_BusStation.SelectedItems[0].Index;
                busStationID = this.lv_BusStation.Items[index].SubItems[2].Text;
                busStationName = this.lv_BusStation.Items[index].SubItems[1].Text;
                Close();
            }
        }
    }
}
 
cs

JsonAPI.zip
0.06MB

 

동작

 

정류소명을 입력하여 해당 정류소를 조회 하여 정류소의 아이디를 가져 온다.

정류소 아이디를 가져와서 버스 도착정보API를 사용하여 버스의 현재 위치와 남은정거장/남은좌석 정보를 가져온다.

버스노선을 이용하여 버스번호를 가져와서 현재 버스가 언제 도착할지 버스의 정보를 알려 준다.

 

활용

- 공공데이터를 분석하여 활용하여 편리한 프로그램을 만들어 볼 수가 있다.

- XML 파싱과 웹서비스와의 연동방법등을 살펴 봄으로 웹서비스와 연동에 활용될 수 있다.

 

 

=====================================================

이 자료는 학생들과 특강시간에 만들어 보는 프로젝트입니다.

=====================================================

 

오늘도 최선을 다하는 우리 학생들을 응원합니다.

인천 서구 검단신도시 원당컴퓨터학원

사업자 정보 표시
원당컴퓨터학원 | 기희경 | 인천 서구 당하동 1028-2 장원프라자 502호 | 사업자 등록번호 : 301-96-83080 | TEL : 032-565-5497 | Mail : icon001@naver.com | 사이버몰의 이용약관 바로가기
  1. Favicon of https://invitetour.tistory.com BlogIcon 휴식같은 친구 2021.02.25 16:26 신고

    실생활에 필요한 내용을 코딩해보면 흥미롭겠네요.
    잘 보고 갑니다~ 즐거운 하루 보내세요.

  2. Favicon of https://xuronghao.tistory.com BlogIcon 空空(공공) 2021.02.26 05:56 신고

    공공데이터 분석으로 이런 훌륭한 정보도 구현할수가 있군요^^

  3. Favicon of http://pangyione.com/ BlogIcon 청결원 2021.02.26 06:32

    포스팅 잘 보고 갑니다
    오늘도 좋은 하루 보내세요~

  4. 핑구야날자 2021.02.26 06:39

    공공 데이터를 활용해서 유용한 정보를 만들 수 있어 좋은 거 같아요

  5. Favicon of https://heysukim114.tistory.com BlogIcon *저녁노을* 2021.02.26 07:05 신고

    역시..다르네요.ㅎㅎ
    잘 보고 가요

  6. Favicon of http://deborah.tistory.com BlogIcon 데보라 2021.02.26 20:13

    와 정말 대단하네요. 전 이해하기 어려운 언어지만 공과 계열에 있는 분이라면 좋아할 언어네요

  7. Favicon of https://lsmpkt.tistory.com BlogIcon 가족바라기 2021.03.01 22:39 신고

    실생활에 필요한 정보로 분석하다니 대단한데요

목표

- 버튼을 동적으로 생성하는 방법에 대해 알아 보자

- 알고리즘 시간에 배운 DFS/BFS 알고리즘을 활용하여 주변으로 확장하는 방법에 대해 알아 보자.

 

 

폼구성

폼에 버튼을 생성할 panel을 하나 올리자.

 

 

 

소스코드

 

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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
 
namespace petardSearch
{
    public partial class Form1 : Form
    {
        public class DoubleClickButton : Button
        {
            public DoubleClickButton() : base()
            {
                // Set the style so a double click event occurs.
                SetStyle(ControlStyles.StandardClick |
                    ControlStyles.StandardDoubleClick , true);
            }
        }
 
        //private FormBorderStyle initialStyle;
 
        int[,] array = new int[1010];
        int[,] Pos = new int[1010];
        int[,] Visit = new int[1010];
        int[,] Cnt = new int[1010];
        DoubleClickButton[,] btnarr = new DoubleClickButton[10,10];
        bool GameOver;
 
        
 
        public Form1()
        {
            InitializeComponent();
            Width = 440;
            Height = 440;
            panel1.Top = 0;
            panel1.Left = 0;
            panel1.Width = Width;
            panel1.Height = Height;
 
            CreatePos();
            ButtonCreate();
            
        }
 
        private void CreatePos()
        {
            //throw new NotImplementedException();
            int i,j;
            Random r = new Random();
            r.Next();
            for (i=0;i<10;i++)
            {
                int y = r.Next(110);
                int x = r.Next(110);
                if (Pos[y, x] == 1)
                {
                    i--;
                    continue;
                }
                Pos[y, x] = 1;
            }
            for(i=0;i<10;i++)
            {
                for(j=0;j<10;j++)
                {
                    if (i > 0) Cnt[i, j] += Pos[i - 1, j];
                    if (i < 9) Cnt[i, j] += Pos[i + 1, j];
                    if (j > 0) Cnt[i, j] += Pos[i, j - 1];
                    if (j < 9) Cnt[i, j] += Pos[i , j + 1];
                    if (i > 0 && j > 0) Cnt[i, j] += Pos[i - 1, j - 1];
                    if (i > 0 && j < 9) Cnt[i, j] += Pos[i - 1, j + 1];
                    if (i < 9 && j > 0) Cnt[i, j] += Pos[i + 1, j - 1];
                    if (i < 9 && j < 9) Cnt[i, j] += Pos[i + 1, j + 1];
                    if (Pos[i, j] == 1) Cnt[i, j] = -1;
                }
            }
        }
 
        private void ButtonCreate()
        {
            int i, j;
            int num = 1;
            for(i=0;i<10;i++)
            {
                for(j=0;j<10;j++)
                {
                    //private DoubleClickButton button1;
                    DoubleClickButton btn = new DoubleClickButton();
                    btn.Width = 40;
                    btn.Height = 40;
                    btn.Top = i * 40;
                    btn.Left = j * 40;
                    btn.Tag = num;
                    btn.BackColor = Color.Black;// button1.BackColor;
                    array[i,j]=num;
                    //btn.Text = Cnt[i, j].ToString();
                    btn.Click += new EventHandler(btn_Click);
                    //this.AllowDrop = true;
                    btn.DoubleClick += new EventHandler(btn_DoubleClick);
                    btn.MouseDown += new MouseEventHandler(btn_MouseDown);
                    num++;
                    btnarr[i, j] = btn;
                    panel1.Controls.Add(btn);
 
                }
            }
        }
 
        private void btn_DoubleClick(object sender, EventArgs e)
        {
            // throw new NotImplementedException();
            //this.FormBorderStyle = initialStyle;
            if (GameOver) return;
            
 
            int x, y;
            int res = CheckVisit((sender as Button).Tag,out x,out y);
            if (res == -1)
            {
                GameOver = true;
                MessageBox.Show("게임오버");
            }
            else if (res == 1return;
 
            OpenButton(x, y);
            if (GameCheck())
            {
                MessageBox.Show("성공");
            }
 
 
        }
 
        private bool GameCheck()
        {
            int cnt = 0;
            int i, j;
            for(i=0;i<10;i++)
            {
                for(j=0;j<10;j++)
                {
                    if (Visit[i, j] == 2) cnt++;
                    else if (Visit[i, j] == 0return false;
                }
            }
            if (cnt == 10return true;
            else return false;
        }
 
        private void OpenButton(int x, int y)
        {
            //throw new NotImplementedException();
            if (x < 0 || y < 0 || x > 9 || y > 9return;
            if (Visit[y, x] != 0return;
            Visit[y, x] = 1;
            btnarr[y, x].BackColor = Color.White;
            btnarr[y, x].Text = Cnt[y, x].ToString();
            if (Cnt[y, x] > 0return;
            OpenButton(x + 1, y);
            OpenButton(x - 1, y);
            OpenButton(x , y + 1);
            OpenButton(x , y - 1);
            OpenButton(x - 1, y-1);
            OpenButton(x - 1, y+1);
            OpenButton(x + 1, y - 1);
            OpenButton(x + 1, y + 1);
        }
 
        private int CheckVisit(object tag, out int x, out int y)
        {
            int num = int.Parse(tag.ToString());
            int i, j;
            y = -1;
            x = -1;
            for (i = 0; i < 10; i++)
            {
                for (j = 0; j < 10; j++)
                {
                    if (array[i, j] == num)
                    {
                        y = i;
                        x = j;
                        if (Cnt[i, j] == -1return -1;
                        if (Visit[i, j] == 0return 0;
                        else return 1;
                    }
                }
            }
            return 1;
        }
 
        private void btn_Click(object sender, EventArgs e)
        {
            //throw new NotImplementedException();
            //this.FormBorderStyle = FormBorderStyle.FixedToolWindow;
 
        }
 
        private void Form1_Resize(object sender, EventArgs e)
        {
            panel1.Top = 0;
            panel1.Left = 0;
            panel1.Width = Width;
            panel1.Height = Height;
        }
 
        private void btn_MouseDown(object sender, MouseEventArgs e)
        {
            if (GameOver) return;
            //
            if (e.Button == MouseButtons.Right)
            {
                //MessageBox.Show((sender as Button).Tag + "번 우클릭");
                if ((sender as Button).BackColor == Color.Red) (sender as Button).BackColor = Color.Black;
                else (sender as Button).BackColor = Color.Red;
                RightClick((sender as Button).Tag);
            }
            
        }
 
        private void RightClick(object tag)
        {
            int num = int.Parse(tag.ToString());
            int i, j;
            for(i=0;i<10;i++)
            {
                for(j=0;j<10;j++)
                {
                    if(array[i,j]==num)
                    {
                        if (Visit[i, j] == 2) Visit[i, j] = 0;
                        else Visit[i, j] = 2;
                        return;
                    }
                }
            }
            if (GameCheck())
            {
                MessageBox.Show("성공");
            }
            //MessageBox.Show(num.ToString());
        }
    }
}
 
cs

 

 

 

 

동작

 

 

 

 

활용

- 폼을 꾸밀때 버튼이나 다른 객체를 입력값에 따라 동적으로 생성하는 경우등에 활용할 수 있다.

 

 

 

 

=====================================================

이 자료는 학생들과 특강시간에 만들어 보는 프로젝트입니다.

=====================================================

 

오늘도 최선을 다하는 우리 학생들을 응원합니다.

인천 서구 검단신도시 원당컴퓨터학원

 

 

 

사업자 정보 표시
원당컴퓨터학원 | 기희경 | 인천 서구 당하동 1028-2 장원프라자 502호 | 사업자 등록번호 : 301-96-83080 | TEL : 032-565-5497 | Mail : icon001@naver.com | 사이버몰의 이용약관 바로가기
  1. Favicon of https://invitetour.tistory.com BlogIcon 휴식같은 친구 2021.02.24 15:15 신고

    지뢰찾기게임 직접 만들어 하다보면 흥미롭게 다가갈것 같습니다.

  2. Favicon of http://deborah.tistory.com BlogIcon 데보라 2021.02.24 21:20

    오 아주 흥미롭게 문제에 접근하는 방식 좋네요

  3. Favicon of https://lsmpkt.tistory.com BlogIcon 가족바라기 2021.02.24 23:16 신고

    학생들이 직접 만들어 해봐도 좋겠어요

  4. Favicon of https://xuronghao.tistory.com BlogIcon 空空(공공) 2021.02.25 06:29 신고

    이런식으로 직접 만들수도 있군요^^

  5. BlogIcon 핑구야날자 2021.02.25 06:43

    재미있는 지뢰찾기 게임 직접 만들어 보면 더 재밌겠군요

  6. Favicon of https://dragonphoto.tistory.com BlogIcon 드래곤포토 2021.02.25 09:44 신고

    프로그램 짜보는게 재미있을 듯 하네요

목표

- MDB(Access DataBase) 파일이 없을때 생성해 보기

- MDB(Access DataBase) 를 이용해서 데이터베이스 명령어(Sql문 - insert,select,update 등)을 확인하기

 

 

 

준비

 

 

 

폼구성


panel - Dock : Bottom

label : 4개 - 아이디/이름/핸드폰/학교/학년

textbox : 4개 - 아이디/이름/핸드폰/학교/학년

ContextMenuStrip : 삽입/삭제 추가

datagridview - Dock : Fill / ContextMenuStrip : ContextMenuStrip1

 

소스코드

- 데이터베이스 생성

 

1
2
3
4
5
6
7
8
9
10
11
12
        private void mdbFileCreate(string strDBName)
        {
            String strDBCon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + strDBName + ";Jet OLEDB:Database Password=1234";
 
            ADOX.CatalogClass adoxCC = new ADOX.CatalogClass();
            adoxCC.Create(strDBCon);
 
            adoxCC.ActiveConnection = null;
            adoxCC = null;
 
            GC.Collect();
        }
cs

 

- 테이블 존재 유무

 

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
        private bool isMDBTable(string tableName)
        {
            Boolean res = false;            
            String strDBCon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="+ strDBName + ";Jet OLEDB:Database Password=1234";
            
            Conn.ConnectionString = strDBCon;
            Conn.Open();
 
            DataTable schemaTable = Conn.GetOleDbSchemaTable(
                                    OleDbSchemaGuid.Tables,
                                    new object[] { nullnullnull"TABLE" });
 
            foreach(DataRow row in schemaTable.Rows)
            {
                if (row["TABLE_NAME"].ToString() == tableName)
                {
                    res = true;
                    break;
                }
            }
            
 
            Conn.Close();
            return res;
           
cs

 

- 테이블 생성

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
        private void createMDBTable(string tableName)
        {
            String strDBCon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + strDBName + ";Jet OLEDB:Database Password=1234";
 
            Conn.ConnectionString = strDBCon;
            Conn.Open();
            String stSql="";
            if (tableName == "Test"// Test 테이블 생성하자.
            {
                stSql = "Create Table Test(id int,name nvarchar(50),handphone varchar(30),school nvarchar(100),grade int, Primary Key(id))";
                //아이디,이름,핸드폰,학교,학년 (키값은 아이디) 로 테이블 생성하자. 
            }
            if(stSql != "")
            {
                ExecSql(stSql);
            }
            Conn.Close();
        }
cs

 

- 테이블 로딩

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
        private void mdbTableLoad(string tableName)
        {
 
 
            String strSql = "Select * From " + tableName;
            OleDbDataAdapter m_daDataAdapter = new OleDbDataAdapter(strSql, Conn);
 
            OleDbCommandBuilder m_cbCommandBuilder = new OleDbCommandBuilder(m_daDataAdapter);
            DataTable m_dtStudent = new DataTable();
 
            m_daDataAdapter.Fill(m_dtStudent);
            dataGridView1.DataSource = m_dtStudent;
            dataGridView1.MultiSelect = false//한개의 열만 선택하자.
            dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect; //셀선택시 한행 전체 선택
            dataGridView1.AlternatingRowsDefaultCellStyle.BackColor = Color.WhiteSmoke;//행의 색상을 다르게
            dataGridView1.ReadOnly = true// 읽기 전용으로
        }
cs

 

- 전체코드

 

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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.OleDb;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
 
namespace MDBManager
{
   
    public partial class Form1 : Form
    {
        static String strDBName = "TEST.MDB";
        static int selectRowIndex = 0;
        OleDbConnection Conn;
        public Form1()
        {
            InitializeComponent();
            FileInfo fileInfo = new FileInfo(strDBName);
            if(!fileInfo.Exists)
            {
                //데이터 파일이 없으면 생성해 주자.
                mdbFileCreate(strDBName);
            }
            Conn = new OleDbConnection();
 
            if (!isMDBTable("Test"))
            {
                //Test 테이블이 있는지 체크해서 없으면 
                //엑셀에서는 Sheet 개념
                createMDBTable("Test"); // Test 테이블을 생성하자.
            }
 
            mdbConnect();
            
            mdbTableLoad("Test"); //Test Table을 DataGridView에 연결하자.
        }
 
        private void mdbConnect()
        {
            String strDBCon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + strDBName + ";Jet OLEDB:Database Password=1234";
 
            Conn.ConnectionString = strDBCon;
            Conn.Open();
        }
 
        private void mdbTableLoad(string tableName)
        {
 
 
            String strSql = "Select * From " + tableName;
            OleDbDataAdapter m_daDataAdapter = new OleDbDataAdapter(strSql, Conn);
 
            OleDbCommandBuilder m_cbCommandBuilder = new OleDbCommandBuilder(m_daDataAdapter);
            DataTable m_dtStudent = new DataTable();
 
            m_daDataAdapter.Fill(m_dtStudent);
            dataGridView1.DataSource = m_dtStudent;
            dataGridView1.MultiSelect = false//한개의 열만 선택하자.
            dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect; //셀선택시 한행 전체 선택
            dataGridView1.AlternatingRowsDefaultCellStyle.BackColor = Color.WhiteSmoke;//행의 색상을 다르게
            dataGridView1.ReadOnly = true// 읽기 전용으로
        }
 
        private void createMDBTable(string tableName)
        {
            String strDBCon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + strDBName + ";Jet OLEDB:Database Password=1234";
 
            Conn.ConnectionString = strDBCon;
            Conn.Open();
            String stSql="";
            if (tableName == "Test"// Test 테이블 생성하자.
            {
                stSql = "Create Table Test(id int,name nvarchar(50),handphone varchar(30),school nvarchar(100),grade int, Primary Key(id))";
                //아이디,이름,핸드폰,학교,학년 (키값은 아이디) 로 테이블 생성하자. 
            }
            if(stSql != "")
            {
                ExecSql(stSql);
            }
            Conn.Close();
        }
 
        private bool isMDBTable(string tableName)
        {
            Boolean res = false;            
            String strDBCon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="+ strDBName + ";Jet OLEDB:Database Password=1234";
            
            Conn.ConnectionString = strDBCon;
            Conn.Open();
 
            DataTable schemaTable = Conn.GetOleDbSchemaTable(
                                    OleDbSchemaGuid.Tables,
                                    new object[] { nullnullnull"TABLE" });
 
            foreach(DataRow row in schemaTable.Rows)
            {
                if (row["TABLE_NAME"].ToString() == tableName)
                {
                    res = true;
                    break;
                }
            }
            
 
            Conn.Close();
            return res;
           
        }
 
        private void mdbFileCreate(string strDBName)
        {
            String strDBCon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + strDBName + ";Jet OLEDB:Database Password=1234";
 
            ADOX.CatalogClass adoxCC = new ADOX.CatalogClass();
            adoxCC.Create(strDBCon);
 
            adoxCC.ActiveConnection = null;
            adoxCC = null;
 
            GC.Collect();
        }
 
        private void button2_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }
 
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            Conn.Close();
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            if(idCheck(txt_ID.Text))
            {
                updateTestTable(txt_ID.Text, txt_Name.Text, txt_HandPhone.Text, txt_School.Text, txt_Grade.Text);
            }
            else
            {
                InsertTestTable(txt_ID.Text, txt_Name.Text, txt_HandPhone.Text, txt_School.Text, txt_Grade.Text);
            }
            mdbTableLoad("Test");
        }
 
        private int InsertTestTable(string stID, string stName,string stHandphone, string stSchool, string stGrade)
        {
            //id int,name nvarchar(50),handphone varchar(30),school nvarchar(100),grade int
            
            String stSql = "insert into Test(id,name,handphone,school,grade) values( " + stID + ",'" + stName + "','" + stHandphone + "','" + stSchool + "'," + stGrade + ")";
            return ExecSql(stSql); //-1이면 롤백
 
        }
 
        private int ExecSql(string stSql)
        {
            OleDbCommand cmd = new OleDbCommand(stSql, Conn);
            
            return cmd.ExecuteNonQuery();
        }
 
        private int updateTestTable(string stID, string stName, string stHandphone, string stSchool, string stGrade)
        {
            String stSql = "update Test set name = '" + stName + "',handphone = '" + stHandphone + "',school = '" + stSchool + "',grade = " + stGrade + " where id = " + stID;
            return ExecSql(stSql); //-1이면 롤백
        }
 
        private bool idCheck(string stID)
        {
            String strSql = "Select * From Test where id = " + stID;
            OleDbCommand OLECmd = new OleDbCommand(strSql, Conn);
            OLECmd.CommandType = CommandType.Text;
            OleDbDataReader OLEReader = OLECmd.ExecuteReader(CommandBehavior.Default);
            bool res;
            res = OLEReader.Read();
            OLECmd.Dispose();
            OLEReader.Dispose();
            return res;
 
        }
 
        private void 삽입ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            txt_ID.Text = "";
            txt_Name.Text = "";
            txt_HandPhone.Text = "";
            txt_School.Text = "";
            txt_Grade.Text = "";
        }
 
        private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            selectRowIndex = e.RowIndex;
            txt_ID.Text = dataGridView1.Rows[e.RowIndex].Cells[0].FormattedValue.ToString();
            txt_Name.Text = dataGridView1.Rows[e.RowIndex].Cells[1].FormattedValue.ToString();
            txt_HandPhone.Text = dataGridView1.Rows[e.RowIndex].Cells[2].FormattedValue.ToString();
            txt_School.Text = dataGridView1.Rows[e.RowIndex].Cells[3].FormattedValue.ToString();
            txt_Grade.Text = dataGridView1.Rows[e.RowIndex].Cells[4].FormattedValue.ToString();
        }
 
        private void 삭제ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DeleteTestTable(dataGridView1.Rows[selectRowIndex].Cells[0].FormattedValue.ToString());
            mdbTableLoad("Test");
        }
 
        private int DeleteTestTable(string stID)
        {
            String stSql = "Delete from Test where id = " + stID;
            return ExecSql(stSql); //-1이면 롤백
        }
    }
}
 
cs

 

 

동작

 

 

 

활용

데이터베이스의 기본을 알고 데이터베이스를 활용하여 구현하는 응용프로그램 구현

 

 

 

=====================================================

이 자료는 학생들과 특강시간에 만들어 보는 프로젝트입니다.

=====================================================

 

오늘도 최선을 다하는 우리 학생들을 응원합니다.

인천 서구 검단신도시 원당컴퓨터학원

 

사업자 정보 표시
원당컴퓨터학원 | 기희경 | 인천 서구 당하동 1028-2 장원프라자 502호 | 사업자 등록번호 : 301-96-83080 | TEL : 032-565-5497 | Mail : icon001@naver.com | 사이버몰의 이용약관 바로가기
  1. Favicon of https://invitetour.tistory.com BlogIcon 휴식같은 친구 2021.02.17 11:23 신고

    씨샾에서 데이터베이스 처리하는 것이군요.
    잘 보고 갑니다~ 즐거운 하루 보내세요

  2. Favicon of https://heysukim114.tistory.com BlogIcon *저녁노을* 2021.02.18 09:15 신고

    잘 보고 가요.
    학생들을 응원합니다.ㅎㅎ

  3. Favicon of http://deborah.tistory.com BlogIcon 데보라 2021.02.18 09:54

    아주 좋은 내용을 알려 주셨네요. 관심 있는 분은 많은 도움을 받았을 겁니다. 행복한 하루가 되세요.

  4. Favicon of http://pangyione.com/ BlogIcon 청결원 2021.02.18 12:36

    포스팅 잘 보고 갑니다
    오늘도 좋은 하루 보내세요~

  5. Favicon of https://uhastory.tistory.com BlogIcon 유하v 2021.02.18 18:26 신고

    하핫... 꼼꼼히 봐도 잘 모르겠네요 ㅋㅋ;;;

  6. Favicon of https://xuronghao.tistory.com BlogIcon 空空(공공) 2021.02.19 05:44 신고

    학생들과의 좋은 프로젝트입니다 ㅎ

  7. 핑구야날자 2021.02.19 06:45

    엑세스를 안 쓴지도 참 오래 된 거 같네요

목표

- 보고서 를 엑셀파일로 저장하는 방법 등에 대해 다루어 봅니다.

- 엑셀 파일을 읽어 보고 저장 하는 방법등을 배웁니다.

- DataGridView 사용법을 확인합니다.

 

 

컴포넌트 설명

- DataGridView :  테이블 형태의 데이터를 화면에 뿌려 주는데 DB와 바인딩해서 사용이 가능하며 개발자가 수동으로 갱신할 수 있다.(이번 프로젝트에서는 수동으로 갱신하는 방법을 활용해 본다.)

 

 

준비

-  Office / SharePoint Developmen 를 추가 설치 합니다.

- 참조관리자에서 Microsoft Excel 16.0 Object Libray/Microsoft Office 16.0 Object Libary 추가

 

 

폼구성

- panel : Dock - Top

- Button : 2개 - Excel읽기/ Excel저장

- DataViewGrid : Dock - Fill

- OpenFileDialog/SaveFileDialog

 

 

소스코드

 

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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
using Microsoft.Office.Interop.Excel;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
 
namespace ExcelFileManager
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            openFileDialog1.Filter = "Excel(*.xlsx)|*.xlsx";
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                ExcelFileLoading(openFileDialog1.FileName);
            }
        }
 
        private void ExcelFileLoading(string fileName)
        {
            dataGridView1.Columns.Clear();
            dataGridView1.Rows.Clear();
            dataGridView1.Refresh();
 
            Microsoft.Office.Interop.Excel.Application application = new Microsoft.Office.Interop.Excel.Application();
            Workbook workbook = application.Workbooks.Open(Filename: @fileName);
            Worksheet worksheet1 = workbook.Sheets[1];  //workbook.Worksheets.get_Item("sheet1");
            application.Visible = false;
            try
            {
                Range range = worksheet1.UsedRange; //모든 구간을 읽자
                for (int i = 1; i <= range.Columns.Count; i++)
                {
                    if((range.Cells[1, i] as Range).Value2==null)
                    {
                        dataGridView1.Columns.Add(i.ToString(), i.ToString());
                    }
                    else
                    {
                        dataGridView1.Columns.Add(i.ToString(), (range.Cells[1, i] as Range).Value2.ToString()); // (range.Cells[1, i] as Range).Value2.ToString());
 
                    }
                }
                String[] rowdata = new string[range.Columns.Count];
                for (int i = 2; i <= range.Rows.Count; ++i)
                {
 
                    for (int j = 1; j <= range.Columns.Count; ++j)
                    {
                        if((range.Cells[i, j] as Range).Value2 != null)
                            rowdata[j - 1= ((range.Cells[i, j] as Range).Value2.ToString() + " ");
                    }
                    dataGridView1.Rows.Add(rowdata);
                }
 
                workbook.Close();
                application.Quit();
            }
            finally
            {
                ReleaseObject(worksheet1);
                ReleaseObject(workbook);
                ReleaseObject(application);
            }
 
            
        }
 
        private void button2_Click(object sender, EventArgs e)
        {
            saveFileDialog1.Filter = "Excel(*.xlsx)|*.xlsx";
            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                ExcelFileSave(saveFileDialog1.FileName);
            }
        }
 
        private void ExcelFileSave(string fileName)
        {
            Microsoft.Office.Interop.Excel.Application application = new Microsoft.Office.Interop.Excel.Application();
            Workbook workbook = application.Workbooks.Add(true);
            Worksheet worksheet1 = workbook.Sheets[1];
            application.Visible = false;
            try
            {
 
                int rowcnt = dataGridView1.RowCount;
                int colcnt = dataGridView1.ColumnCount;
 
                String[,] data = new string[rowcnt, colcnt];
 
                for (int i = 0; i < rowcnt; i++)
                {
                    for (int j = 0; j < colcnt; j++)
                    {
                        if (dataGridView1.Rows[i].Cells[j].Value != null)
                        {
                            worksheet1.Cells[i + 1, j + 1= dataGridView1.Rows[i].Cells[j].Value.ToString();
                        }
 
                    }
                }
                workbook.SaveAs(fileName);
                // Char Endchar = Convert.ToChar(Convert.ToInt32('A') + colcnt);
                // String EndStr = Endchar.ToString() + rowcnt.ToString(); //마지막 범위 위치 지정
                // worksheet1.get_Range()
 
                workbook.Close();
                application.Quit();
            }
            finally
            {
                ReleaseObject(worksheet1);
                ReleaseObject(workbook);
                ReleaseObject(application);
            }
            
        }
 
        private void ReleaseObject(Object obj)
        {
            try
            {
                if (obj != null)
                {
                    Marshal.ReleaseComObject(obj); // 액셀 객체 해제 
                    obj = null
                } 
            } catch(Exception ex) { 
                obj = null
                throw ex; 
            } finally { 
                GC.Collect(); // 가비지 수집 
            }
 
                
        }
    }
}
 
cs

 

ExcelFileManager.zip
0.26MB

 

동작

 

 

 

활용

- 엑셀파일을 제어하거나 보고서에서 엑셀파일로 내보내기 기능등에 활용

 

 

=====================================================

이 자료는 학생들과 특강시간에 만들어 보는 프로젝트입니다.

=====================================================

 

오늘도 최선을 다하는 우리 학생들을 응원합니다.

인천 서구 검단신도시 원당컴퓨터학원

 

사업자 정보 표시
원당컴퓨터학원 | 기희경 | 인천 서구 당하동 1028-2 장원프라자 502호 | 사업자 등록번호 : 301-96-83080 | TEL : 032-565-5497 | Mail : icon001@naver.com | 사이버몰의 이용약관 바로가기
  1. Favicon of https://xuronghao.tistory.com BlogIcon 空空(공공) 2021.02.17 06:25 신고

    엑셀 파일 다루는 방법이로군요
    바람불고 차가운 날씨입니다
    건강 유의 하시길..

  2. 핑구야날자 2021.02.17 06:47

    데이터를 엑셀로 전환하는 경우가 종종 필요한데 유용하겠어요

  3. Favicon of https://invitetour.tistory.com BlogIcon 휴식같은 친구 2021.02.17 11:24 신고

    시샾에서 엑셀파일 컨트롤도 가능하군요.

목표

- IKeyboardMouseEvents  를 활용하여 마우스,키보드,커서 등을 후킹하는 방법을 살펴 보자

 

 

준비

MouseEvent 를 후킹하기 위해서 Nuget관리자에서 MouseKeyHook 설치

 

 

 

 

폼구성

폼의 속성

FormBorderStyle: None 

WindowState : Maximized

 

Timer :StartTimer,LockTimer,timer1

PicturBox:pictureBox1

Resources 에 1.jpg,2.jpg 를 추가(화면보호기에서 두개의 이미지를 번갈아 화면에 뿌려줌)

 

Resources.zip
0.11MB

 

 

소스코드

 

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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
using Gma.System.MouseKeyHook;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
 
namespace ScreenSaver
{
    public partial class Form1 : Form
    {
        // 전역 이벤트 객체
        private IKeyboardMouseEvents globalHook;
        public static DateTime lastChangeTime; // Key 이벤트 혹은 마우스 이벤트의 마지막 시간
        public static int ImageIndex = 0;
        
        // 마우스나 키보드 입력시 화면보호기를 Stop
        private static void ScreenSaverStop()
        {
            FormHandler.Hide();
        }
 
        public Form1()
        {
            InitializeComponent();
            // 라이브러리로부터 이벤트를 가져온다.
            globalHook = Hook.GlobalEvents();
            // 키보드 이벤트
            // 키보드 키를 누르는 이벤트
            globalHook.KeyDown += GlobalHook_KeyDown;
            // 키보드 키를 떼는 이벤트
            globalHook.KeyUp += GlobalHook_KeyUp;
            // 키보드 키를 누르고 있는 이벤트
            globalHook.KeyPress += GlobalHook_KeyPress;
           
            // 마우스 이벤트
            // 마우스 이동 이벤트
            globalHook.MouseMove += GlobalHook_MouseMove;
            // 마우스 이동 이벤트 (확장형)
            globalHook.MouseMoveExt += GlobalHook_MouseMoveExt;
            // 마우스 클릭 이벤트
            globalHook.MouseClick += GlobalHook_MouseClick;
            // 마우스 더블 클릭 이벤트
            globalHook.MouseDoubleClick += GlobalHook_MouseDoubleClick;
            // 마우스 버튼 누름 이벤트
            globalHook.MouseDown += GlobalHook_MouseDown;
            // 마우스 버튼 누름 이벤트 (확장형)
            globalHook.MouseDownExt += GlobalHook_MouseDownExt;
            // 마우스 버튼을 떼는 이벤트
            globalHook.MouseUp += GlobalHook_MouseUp;
            // 마우스 버튼을 떼는 이벤트 (확장형)
            globalHook.MouseUpExt += GlobalHook_MouseUpExt;
            // 마우스 휠 이벤트
            globalHook.MouseWheel += GlobalHook_MouseWheel;
            // 마우스 휠 이벤트 (확장형)
            globalHook.MouseWheelExt += GlobalHook_MouseWheelExt;
            // 마우스 드래그 시작 이벤트
            globalHook.MouseDragStarted += GlobalHook_MouseDragStarted;
            // 마우스 드래그 시작 이벤트 (확장형)
            globalHook.MouseDragStartedExt += GlobalHook_MouseDragStartedExt;
            // 마우스 드래그 종료 이벤트
            globalHook.MouseDragFinished += GlobalHook_MouseDragFinished;
            // 마우스 드래그 종료 이벤트 (확장형)
            globalHook.MouseDragFinishedExt += GlobalHook_MouseDragFinishedExt;
 
            FormHandler.Form1Hide += FormHandler_Form1Hide;
            lastChangeTime = DateTime.Now;
        }
 
        private void GlobalHook_MouseDragFinishedExt(object sender, MouseEventExtArgs e)
        {
            // 콘솔 출력
            Console.WriteLine($"MouseDragFinishedExt");
        }
 
        private void GlobalHook_MouseDragFinished(object sender, MouseEventArgs e)
        {
            // 콘솔 출력
            Console.WriteLine($"MouseDragFinished");
        }
 
        private void GlobalHook_MouseDragStartedExt(object sender, MouseEventExtArgs e)
        {
            // 콘솔 출력
            Console.WriteLine($"MouseDragStartedExt");
        }
 
        private void GlobalHook_MouseDragStarted(object sender, MouseEventArgs e)
        {
            // 콘솔 출력
            Console.WriteLine($"MouseDragStarted");
        }
 
        private void GlobalHook_MouseWheelExt(object sender, MouseEventExtArgs e)
        {
            // 콘솔 출력
            Console.WriteLine($"MouseWheelExt");
        }
 
        private void GlobalHook_MouseWheel(object sender, MouseEventArgs e)
        {
            lastChangeTime = DateTime.Now;
            ScreenSaverStop();
            // 콘솔 출력
            Console.WriteLine($"MouseWheel");
        }
 
        private void GlobalHook_MouseUpExt(object sender, MouseEventExtArgs e)
        {
 
            // 콘솔 출력
            Console.WriteLine($"MouseUpExt");
        }
 
        private void GlobalHook_MouseUp(object sender, MouseEventArgs e)
        {
            // 콘솔 출력
            Console.WriteLine($"MouseUp");
        }
 
        private void GlobalHook_MouseDownExt(object sender, MouseEventExtArgs e)
        {
            // 콘솔 출력
            Console.WriteLine($"MouseDownExt");
        }
 
        private void GlobalHook_MouseDown(object sender, MouseEventArgs e)
        {
            lastChangeTime = DateTime.Now;
            ScreenSaverStop();// 콘솔 출력
            Console.WriteLine($"MouseDownX = {0}, Y = {1}",e.X.ToString(), e.Y.ToString());
        }
 
        private void GlobalHook_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            // 콘솔 출력
            Console.WriteLine($"MouseDoubleClick");
        }
 
        private void GlobalHook_MouseClick(object sender, MouseEventArgs e)
        {
            // 콘솔 출력
            Console.WriteLine($"MouseClick{e.Clicks}");
        }
 
        private void GlobalHook_MouseMoveExt(object sender, MouseEventExtArgs e)
        {
            // 콘솔 출력
            Console.WriteLine("MouseMoveExt X = {0}, Y = {1}", e.X.ToString(), e.Y.ToString());
 
        }
 
        private void GlobalHook_MouseMove(object sender, MouseEventArgs e)
        {
            lastChangeTime = DateTime.Now;
            ScreenSaverStop();
            // 콘솔 출력
            Console.WriteLine("MouseMove X = {0}, Y = {1}", e.X.ToString(), e.Y.ToString());
 
        }
 
        private void GlobalHook_KeyPress(object sender, KeyPressEventArgs e)
        {
            lastChangeTime = DateTime.Now;
            ScreenSaverStop();
            if (e.KeyChar == 0x1B)
            {
                Application.Exit(); // ESC이면 프로그램 종료하자.
            }
            // 콘솔 출력
            Console.WriteLine($"KeyPress " + e.KeyChar);
        }
 
        private void GlobalHook_KeyUp(object sender, KeyEventArgs e)
        {
            // 콘솔 출력
            Console.WriteLine($"KeyUp " + e.KeyData);
 
        }
 
        private void GlobalHook_KeyDown(object sender, KeyEventArgs e)
        {
            // 콘솔 출력
            Console.WriteLine($"KeyDown " + e.KeyData);
            lastChangeTime = DateTime.Now;
            ScreenSaverStop();
        }
 
        private void FormHandler_Form1Hide()
        {
            timer1.Enabled = true;
        }
 
        private void StartTimer_Tick(object sender, EventArgs e)
        {
            if (DateTime.Compare(lastChangeTime.AddSeconds(20), DateTime.Now) < 0)
            {
                StartTimer.Enabled = false;
                LockTimer.Enabled = true//화면이 잠기면 화면에 그림을 그리자.
                Visible = true;
            }
        }
 
        private void Form1_Load(object sender, EventArgs e)
        {
            timer1.Enabled = true;
        }
 
        private void timer1_Tick(object sender, EventArgs e)
        {
            Hide();
            timer1.Enabled = false;
 
            StartTimer.Enabled = true//키보드의 입력값이 일정시간 없는지 체크
            LockTimer.Enabled = false
            Cursor.Hide();
 
        }
        
        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
           
        }
 
        private void LockTimer_Tick(object sender, EventArgs e)
        {
            Console.WriteLine($"LockTimer_Tick" );
            if (ImageIndex == 0)
                pictureBox1.Image = Properties.Resources._2;
            else pictureBox1.Image = Properties.Resources._1;
            ImageIndex = 1 - ImageIndex;
 
        }
    }
 
    public static class FormHandler
    {
        private static Form1 frm1 = new Form1();
 
        public delegate void Form1HideEventHandler();
        public static event Form1HideEventHandler Form1Hide;
 
        public static void Hide()
        {
            if (Form1Hide != null)
            {
                Form1Hide();
            }
 
        }
    }
}
 
cs

 

이벤트 처리기에서 폼을 감추기 위해서 FormHandler 를 작성하여 연결해 주어야 한다.

 

ScreenSaver.zip
0.56MB

동작

일정시간 동안 키보드 혹은 마우스 입력이 없으면 폼을 띄우고 폼의 picturBox에 일정주기로 이미지를 바꿔준다.

ESC 키가 들어오면 프로그램을 종료하도록 처리함

 

 

활용

어플리케이션을 만든후 보안을 위해 일정시간 키 입력이 없을때 잠금 기능을 활성화 하여 비밀번호 입력 후 잠금을 풀어 주는 기능등으로 활용할 수 있다.

 

 

 

=====================================================

이 자료는 학생들과 특강시간에 만들어 보는 프로젝트입니다.

=====================================================

 

오늘도 최선을 다하는 우리 학생들을 응원합니다.

인천 서구 검단신도시 원당컴퓨터학원

 

 

사업자 정보 표시
원당컴퓨터학원 | 기희경 | 인천 서구 당하동 1028-2 장원프라자 502호 | 사업자 등록번호 : 301-96-83080 | TEL : 032-565-5497 | Mail : icon001@naver.com | 사이버몰의 이용약관 바로가기
  1. Favicon of https://xuronghao.tistory.com BlogIcon 空空(공공) 2021.02.03 05:00 신고

    학생들과 해 보면 좋을듯 합니다^^

  2. Favicon of https://heysukim114.tistory.com BlogIcon *저녁노을* 2021.02.03 06:30 신고

    오...잘 알고 갑니다.
    ㅎㅎ
    즐거운 하루 되세요

  3. 핑구야날자 2021.02.03 06:50

    화면 보호기를 만들 수 있다니 재미있는 코딩 이네요

  4. Favicon of http://pangyione.com/ BlogIcon 청결원 2021.02.03 06:51

    포스팅 잘 보고 갑니다
    오늘도 좋은 하루 보내세요~

  5. Favicon of https://invitetour.tistory.com BlogIcon 휴식같은 친구 2021.02.03 13:38 신고

    오, 전문적인 코딩이군요.
    따라하는 재미가 있겠어요.

  6. Favicon of http://deborah.tistory.com BlogIcon 데보라 2021.02.03 19:44

    와 정말 전문가만 알 수 있는 용어네요 ㅎㅎㅎㅎ

  7. Favicon of https://uhastory.tistory.com BlogIcon 유하v 2021.02.03 22:15 신고

    제눈에는 한글과 영어밖에 안 보이네요 ㅋㅋ;;;

  8. Favicon of https://lsmpkt.tistory.com BlogIcon 가족바라기 2021.02.03 23:48 신고

    요즘 it가 대세긴 하죠

  9. Favicon of http://pangyione.com/ BlogIcon 청결원 2021.02.05 12:58

    오늘도 포스팅 잘 보고 가네요
    좋은 하루 보내세요~

+ Recent posts