<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>류종택의 프로그래밍 강의실</title>
    <link>https://ryulib.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Sat, 30 May 2026 09:29:16 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>ryujt</managingEditor>
    <image>
      <title>류종택의 프로그래밍 강의실</title>
      <url>https://tistory1.daumcdn.net/tistory/687298/attach/6803791549f94bfca5622dec70b84641</url>
      <link>https://ryulib.tistory.com</link>
    </image>
    <item>
      <title>http://10bun.tv/ 에서 다시 시작합니다.</title>
      <link>https://ryulib.tistory.com/notice/473</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;http://10bun.tv/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://10bun.tv/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로운 둥지에서 다시 시작합니다.&lt;/p&gt;
&lt;figure id=&quot;og_1636121541463&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;10분 TV&quot; data-og-description=&quot;&quot; data-og-host=&quot;10bun.tv&quot; data-og-source-url=&quot;http://10bun.tv/&quot; data-og-url=&quot;http://10bun.tv/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;http://10bun.tv/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;http://10bun.tv/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;10분 TV&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;10bun.tv&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <author>ryujt</author>
      <guid isPermaLink="true">https://ryulib.tistory.com/notice/473</guid>
      <pubDate>Fri, 5 Nov 2021 23:12:44 +0900</pubDate>
    </item>
    <item>
      <title>정수기를 쓰고 있다면 지금 당장 배수구를 확인하세요!</title>
      <link>https://ryulib.tistory.com/472</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;pic-1.jpg&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;270&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OUhML/btq1WK2KIAT/QfpXJATVvhNkcc1QxhbHJk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OUhML/btq1WK2KIAT/QfpXJATVvhNkcc1QxhbHJk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OUhML/btq1WK2KIAT/QfpXJATVvhNkcc1QxhbHJk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOUhML%2Fbtq1WK2KIAT%2FQfpXJATVvhNkcc1QxhbHJk%2Fimg.jpg&quot; data-filename=&quot;pic-1.jpg&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;270&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;저는 웅진코웨이를 사용하고 있고 정수기 배수관 문제로 물이 조금씩 새어나와 마루 바닥에 얼룩이 생긴 상황입니다. 웅진쪽에서는 이해가 안되는 이유로 보상 불가라고 하고요. 보상보다는 상황을 알리고난 다음에 그들의 태도 때문에 엄청 스트레스를 받았네요.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;여러분들은 저와 같은 경우를 겪지 않기를 바라면서 몇 가지 상황을 설명해 드립니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;before.gif&quot; data-origin-width=&quot;582&quot; data-origin-height=&quot;434&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bacgHn/btq1ONfPs9L/duBykmrun5kJbSSYxCqSUK/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bacgHn/btq1ONfPs9L/duBykmrun5kJbSSYxCqSUK/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bacgHn/btq1ONfPs9L/duBykmrun5kJbSSYxCqSUK/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/bacgHn/btq1ONfPs9L/duBykmrun5kJbSSYxCqSUK/img.gif&quot; data-filename=&quot;before.gif&quot; data-origin-width=&quot;582&quot; data-origin-height=&quot;434&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;위의 사진은 웅진에서 처음 정수기를 설치하고 배수관을 설치한 사진입니다. 화살표에 보이는 성의없는 본드가 떨어졌고 그 구멍으로 물이 조금씩 새어서 근처에 계속 고여 있었더군요. 이것을 너무 늦게 발견했고, 처음에는 결로나 보일러 문제라고 생각하여 날씨가 풀리면 보일러 수리를 하려던 참이었습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;IMG_0351.jpg&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bllZNN/btq1XhMLrk5/5dZH6Y23trjh2LqMYuWfM0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bllZNN/btq1XhMLrk5/5dZH6Y23trjh2LqMYuWfM0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bllZNN/btq1XhMLrk5/5dZH6Y23trjh2LqMYuWfM0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbllZNN%2Fbtq1XhMLrk5%2F5dZH6Y23trjh2LqMYuWfM0%2Fimg.jpg&quot; data-filename=&quot;IMG_0351.jpg&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;배수구는 위의 사진처럼 안쪽이라서 물이 새는 것을 바로 확인 못하였고, 곰팡이 냄새가 나서 혹시나하고 열어본 순간 정말 @.@&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;저의 첫 번 째 실수는 물이 새는 상황을 동영상으로 남기고 물이 고여있는 것을 사진찍어서 증거 사진으로 남겼어야 했습니다. 그런데 너무 당황스럽고 뜯어놓고 나니 냄새가 더 나서 바로 청소를 하고 직접 수리를 해버렸습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;IMG_0350.jpg&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9lrmy/btq1R8cJKqw/fwRvfIZUVXM9Ox3LTnlEo1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9lrmy/btq1R8cJKqw/fwRvfIZUVXM9Ox3LTnlEo1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9lrmy/btq1R8cJKqw/fwRvfIZUVXM9Ox3LTnlEo1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9lrmy%2Fbtq1R8cJKqw%2FfwRvfIZUVXM9Ox3LTnlEo1%2Fimg.jpg&quot; data-filename=&quot;IMG_0350.jpg&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;스스로 증거 인멸을 해버린 셈이죠 ㅎㅎ&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;자 그런데 이분들 현장에 와서 사진만 잔뜩 찍어가고 처리는 다른 곳에서 한다고 했는데, 아마도 외주 시공 업체인것으로 보입니다. 이분과 통화하다가 혈압으로 쓰러질 뻔했습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;다운로드.png&quot; data-origin-width=&quot;255&quot; data-origin-height=&quot;244&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lONjm/btq1Qn844mP/R8kxXARiPMTkgKZg7SZKw1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lONjm/btq1Qn844mP/R8kxXARiPMTkgKZg7SZKw1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lONjm/btq1Qn844mP/R8kxXARiPMTkgKZg7SZKw1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlONjm%2Fbtq1Qn844mP%2FR8kxXARiPMTkgKZg7SZKw1%2Fimg.png&quot; data-filename=&quot;다운로드.png&quot; data-origin-width=&quot;255&quot; data-origin-height=&quot;244&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;결론적으로 자신들이 뚫어 놓은 구멍을 제대로 막지 못해서 새어나오는 물이더라도, 정수기 물이 아니고 배수가 역류한 것이라면 보상되지 않는다는 것입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;검색해보니 정수기 배수 사고는 종종 있었던 것 같습니다. 여러분들도 저처럼 피해를 보지 않으시려면,&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;배수구 주변을 미리 보강해두세요.&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;물이 새어 나오고 있다면 동영상과 사진으로 증거를 확보하세요.&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;업체와는 신경전을 벌이실 필요 없습니다. 소보원 같은 곳에 신고하세요. (저는 이제 시작하려고 하는데 큰 기대가 되지는 않네요)&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;사실 보상은 기대하지도 않습니다. 다만, 자신들의 실수로 인하여 피해 입은 고객을 대하는 태도가 너무 괘씸해서 제가 할 수 있는 최대한으로 괴롭혀줄 방법을 찾아볼 생각입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;저와 같은 피해자가 발생하지 않도록 이 글을 읽는 분들께서는 널리 공유 부탁드립니다!&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;청소를 하고 수리를 할 때까지는 아주 심하지 않았는데, 그 동안 바닥 안에 물이 이미 새어 들었던 탓인지 웅진코웨이에 전화하고 난 뒤로 갑자기 더 심해지네요. 요즘은 마루 틈 사이로도 곰팡이가 생김 ㅠ.ㅠ&lt;/span&gt;&lt;/p&gt;</description>
      <category>etc</category>
      <author>ryujt</author>
      <guid isPermaLink="true">https://ryulib.tistory.com/472</guid>
      <comments>https://ryulib.tistory.com/472#entry472comment</comments>
      <pubDate>Mon, 5 Apr 2021 20:54:39 +0900</pubDate>
    </item>
    <item>
      <title>ecam - 쉬운 녹화 &amp;amp; 유튜브 방송 프로그램</title>
      <link>https://ryulib.tistory.com/471</link>
      <description>&lt;p&gt;&lt;a href=&quot;http://e-cam.s3-website.ap-northeast-2.amazonaws.com/&quot;&gt;http://e-cam.s3-website.ap-northeast-2.amazonaws.com/&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Release&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://e-cam.s3-website.ap-northeast-2.amazonaws.com/downloads/0.1-beta/ecam.zip&quot;&gt;ecam.zip - ecam 0.1 beta portable&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://e-cam.s3-website.ap-northeast-2.amazonaws.com/downloads/0.1-beta/ecam.exe&quot;&gt;ecam.exe - ecam 0.1 beta intaller&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;etc&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/how-to-use&quot;&gt;How to use&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/playlist?list=PL_K0yFEgjop-rZXCl0UG8aCilXanwM8zS&quot;&gt;프로토타입 개발 과정&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Known issues&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;PC 성능이 부족할 때 녹화가 메모리에 밀려서 한계에 도달하면 프로그램이 죽는 현상&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;초기화면&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bh5J62/btqFCo0ShuQ/rVBDk310Pgthz2mzmKzAK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bh5J62/btqFCo0ShuQ/rVBDk310Pgthz2mzmKzAK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bh5J62/btqFCo0ShuQ/rVBDk310Pgthz2mzmKzAK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbh5J62%2FbtqFCo0ShuQ%2FrVBDk310Pgthz2mzmKzAK0%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;녹화 시작 / 중지 버튼&lt;/li&gt;
&lt;li&gt;화면 영역 선택&lt;/li&gt;
&lt;li&gt;오디오 선택&lt;/li&gt;
&lt;li&gt;기타 설정&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;화면 영역 선택&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/W8mA9/btqFzGvNK2v/mMqjaN8fT7e11VtJfvrpa1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/W8mA9/btqFzGvNK2v/mMqjaN8fT7e11VtJfvrpa1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/W8mA9/btqFzGvNK2v/mMqjaN8fT7e11VtJfvrpa1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FW8mA9%2FbtqFzGvNK2v%2FmMqjaN8fT7e11VtJfvrpa1%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;영역을 지정하여 녹화&lt;/li&gt;
&lt;li&gt;전체 화면을 녹화&lt;/li&gt;
&lt;li&gt;선택한 윈도우 화면만 녹화&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;영역을 지정하여 녹화하는 장면&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Clyi5/btqFAPk1ben/G0vmM3M52uTF65rXlENABk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Clyi5/btqFAPk1ben/G0vmM3M52uTF65rXlENABk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Clyi5/btqFAPk1ben/G0vmM3M52uTF65rXlENABk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FClyi5%2FbtqFAPk1ben%2FG0vmM3M52uTF65rXlENABk%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;녹색의 테두리 안쪽이 녹화됩니다.&lt;/li&gt;
&lt;li&gt;테두리를 마우스로 드래그 하면 크기를 변경할 수 있습니다.&lt;/li&gt;
&lt;li&gt;가운데 화면 정보 판을 드래그하면 이동할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;선택한 윈도우만 녹화하는 장면&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dR7huM/btqFAeS8M28/nxJRMysWb8g8zezbUiKqtk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dR7huM/btqFAeS8M28/nxJRMysWb8g8zezbUiKqtk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dR7huM/btqFAeS8M28/nxJRMysWb8g8zezbUiKqtk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdR7huM%2FbtqFAeS8M28%2FnxJRMysWb8g8zezbUiKqtk%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;마우스를 녹화할 윈도우 컨트롤 위에 올려두면 빨간 테두리가 보입니다. 이때 윈도우를 클릭하면 선택이 됩니다.&lt;/li&gt;
&lt;li&gt;ESC키를 클릭하면 취소되고 전체 화면 녹화가 선택됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;오디오 선택&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cVhARu/btqFBY9bvym/M3uMsfSXss03jj811v4yQk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cVhARu/btqFBY9bvym/M3uMsfSXss03jj811v4yQk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cVhARu/btqFBY9bvym/M3uMsfSXss03jj811v4yQk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcVhARu%2FbtqFBY9bvym%2FM3uMsfSXss03jj811v4yQk%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;녹음할 오디오를 선택하는 화면입니다.&lt;/li&gt;
&lt;li&gt;시스템 오디오 캡쳐&lt;ul&gt;
&lt;li&gt;컴퓨터에서 재생되는 모든 소리를 녹음합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;마이크 선택&lt;ul&gt;
&lt;li&gt;녹을 할 마이크 장치를 선택합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;기타 설정&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dM8U5M/btqFBeEEF0N/e6cNXdwfFQkXsXX63AzOP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dM8U5M/btqFBeEEF0N/e6cNXdwfFQkXsXX63AzOP1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dM8U5M/btqFBeEEF0N/e6cNXdwfFQkXsXX63AzOP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdM8U5M%2FbtqFBeEEF0N%2Fe6cNXdwfFQkXsXX63AzOP1%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;현재 기타 설정에는 유튜브 방송에 관한 것만 제공합니다.&lt;/li&gt;
&lt;li&gt;유튜브 방송 중에는 녹화 파일이 생기지 않습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;녹화가 끝나면 녹화 파일을 저장할 곳을 물어봅니다.&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cBdF0D/btqFzF4KEym/bFWBKZRc2IwXIyJ7ide3ZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cBdF0D/btqFzF4KEym/bFWBKZRc2IwXIyJ7ide3ZK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cBdF0D/btqFzF4KEym/bFWBKZRc2IwXIyJ7ide3ZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcBdF0D%2FbtqFzF4KEym%2FbFWBKZRc2IwXIyJ7ide3ZK%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;취소를 하면 녹화 파일이 삭제됩니다. 주의하세요.&lt;/li&gt;
&lt;li&gt;임시 파일은 사용자의 임시 폴도에 저장됩니다. 보통은 C: 드라이브입니다. 다른 드라이브로 저장할 때에는 조금 시간이 걸릴 수도 있습니다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>프로젝트</category>
      <author>ryujt</author>
      <guid isPermaLink="true">https://ryulib.tistory.com/471</guid>
      <comments>https://ryulib.tistory.com/471#entry471comment</comments>
      <pubDate>Mon, 13 Jul 2020 04:32:01 +0900</pubDate>
    </item>
    <item>
      <title>vcpkg x2654 build error 대처 방법</title>
      <link>https://ryulib.tistory.com/470</link>
      <description>&lt;blockquote&gt;
&lt;p&gt;git clone &lt;a href=&quot;https://github.com/Microsoft/vcpkg.git&quot;&gt;https://github.com/Microsoft/vcpkg.git&lt;/a&gt;&lt;br&gt;cd vcpkg&lt;br&gt;git reset --hard 86f5397f76fa6b8141ea828640e94050b9c7b8e1&lt;br&gt;bootstrap-vcpkg.bat&lt;br&gt;vcpkg integrate install&lt;br&gt;vcpkg install x264&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;일단 5월 1일자로 되돌려서 빌드하는 것이고 이렇게 하면&lt;br&gt;Visual Studio 최신 버전에서 vcpkg 라이브러리가 자동으로 올라오지 않을 수 있습니다.&lt;br&gt;inlcude, lib 폴더 추가하시고 lib 파일들도 수동으로 포함시켜야 합니다.&lt;/p&gt;
&lt;p&gt;일단 x264 빌드 이후 다시 git pull 해서 최신으로 되돌리고  &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;bootstrap-vcpkg.bat&lt;br&gt;vcpkg integrate install&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;로 하면 될지도 ㅡ.ㅡ;&lt;/p&gt;</description>
      <category>오픈소스 연구</category>
      <author>ryujt</author>
      <guid isPermaLink="true">https://ryulib.tistory.com/470</guid>
      <comments>https://ryulib.tistory.com/470#entry470comment</comments>
      <pubDate>Tue, 30 Jun 2020 22:02:20 +0900</pubDate>
    </item>
    <item>
      <title>오픈소스 PC 원격제어</title>
      <link>https://ryulib.tistory.com/469</link>
      <description>&lt;blockquote&gt;
&lt;p&gt;DeskZip.dll은 개인적인 사용만 가능합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;Remote Control&lt;/h1&gt;
&lt;p&gt;소스코드는 &lt;a href=&quot;https://github.com/ryujt/remote-control&quot;&gt;https://github.com/ryujt/remote-control&lt;/a&gt;를 참고하세요.&lt;/p&gt;
&lt;h2&gt;Requirement&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/ryujt/ryulib-delphi&quot;&gt;https://github.com/ryujt/ryulib-delphi&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/ryujt/supersocket&quot;&gt;https://github.com/ryujt/supersocket&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;참고 사이트&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://10bun.tv/&quot;&gt;http://10bun.tv/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;사용방법&lt;/h2&gt;
&lt;h3&gt;Gateway 서버 실행&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;bin 폴더에 있는 remo_server.exe 파일을 아이피 공개된 외부에서 접속이 가능한 서버에서 실행합니다. &lt;/li&gt;
&lt;li&gt;Options.ini 파일을 같은 폴더에 저장해주세요.&lt;/li&gt;
&lt;li&gt;Gateway 서버는 기본적으로 8282번 포트를 사용합니다.&lt;/li&gt;
&lt;li&gt;Options.ini 파일의 내용을 변경하면 포트를 변경할 수 있습니다. 포트를 변경하시면 클라이언트와 서버 모두 같은 포트로 변경해서 사용해야 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;서버 실행&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yu0fx/btqB4ZFgagT/bgDESMGaKsRecd2cfvAH91/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yu0fx/btqB4ZFgagT/bgDESMGaKsRecd2cfvAH91/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yu0fx/btqB4ZFgagT/bgDESMGaKsRecd2cfvAH91/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fyu0fx%2FbtqB4ZFgagT%2FbgDESMGaKsRecd2cfvAH91%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;서버는 원격지원을 받을 PC에서 실행합니다.&lt;/li&gt;
&lt;li&gt;bin 폴더에 있는 remo_server.exe 파일을 실행하면 됩니다.&lt;/li&gt;
&lt;li&gt;DeskZip.dll 파일을 같은 폴더에 저장해주세요.&lt;/li&gt;
&lt;li&gt;Options.ini 파일을 같은 폴더에 저장해주세요.&lt;/li&gt;
&lt;li&gt;서버가 실행되면 화면에 접속코드가 표시됩니다. 이것을 원격으로 접속할 사용자에게 전달해주시면 됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;클라이언트 실행&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bK7ZYH/btqB5h6KeI9/VDkq3vy9hknct43tOCKWF0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bK7ZYH/btqB5h6KeI9/VDkq3vy9hknct43tOCKWF0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bK7ZYH/btqB5h6KeI9/VDkq3vy9hknct43tOCKWF0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbK7ZYH%2FbtqB5h6KeI9%2FVDkq3vy9hknct43tOCKWF0%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;클라이언트는 원격으로 접속할 PC에서 실행합니다.&lt;/li&gt;
&lt;li&gt;bin 폴더에 있는 remo_client.exe 파일을 실행하면 됩니다.&lt;/li&gt;
&lt;li&gt;DeskZip.dll 파일을 같은 폴더에 저장해주세요.&lt;/li&gt;
&lt;li&gt;Options.ini 파일을 같은 폴더에 저장해주세요.&lt;/li&gt;
&lt;li&gt;서버 쪽에서 받은 접속코드를 입력창에 넣고 화살표가 가리키는 연결 버튼을 클릭합니다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>프로젝트</category>
      <author>ryujt</author>
      <guid isPermaLink="true">https://ryulib.tistory.com/469</guid>
      <comments>https://ryulib.tistory.com/469#entry469comment</comments>
      <pubDate>Wed, 19 Feb 2020 13:13:18 +0900</pubDate>
    </item>
    <item>
      <title>초보 탈출 #2 - 멀티 스레드 프로그래밍의 1</title>
      <link>https://ryulib.tistory.com/468</link>
      <description>&lt;p&gt;&lt;a href=&quot;http://10bun.tv/beginner/episode-2/&quot;&gt;http://10bun.tv/beginner/episode-2/&lt;/a&gt; 링크 참고&lt;/p&gt;
&lt;h2&gt;핵심 강의&lt;/h2&gt;
&lt;iframe src=&quot;https://www.youtube.com/embed/guPB2hXtaQA&quot; width=&quot;800&quot; height=&quot;450&quot; allow=&quot;accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;

&lt;h2&gt;강의 개요&lt;/h2&gt;
&lt;p&gt;멀티 스레드가 필요한 가장 큰 이유는 프로그램의 실행 효율을 높이기 위해서입니다. 그러나, 스레드를 이용하면 코드가 복잡해지고 디버깅하기가 까다로워 집니다. 그리고 오히려 성능을 해치는 경우도 발생합니다. 이 강의에서는 기초적인 스레드 사용의 패턴을 통해서 효과적으로 스레드를 사용할 수 있는 방법들을 알아봅니다.&lt;/p&gt;
&lt;p&gt;::: tip 제가 생각하는 중급으로 넘어가기 위한 장벽들입니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;기초 알고리즘&lt;/li&gt;
&lt;li&gt;OOP&lt;/li&gt;
&lt;li&gt;멀티 스레드 (비동기 프로세스)&lt;/li&gt;
&lt;li&gt;포인터&lt;/li&gt;
&lt;li&gt;함수 호출의 구조 (재귀 프로세스 등)&lt;br&gt;:::&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;강의 전 준비 사항&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Visual Studio 2015 Update 3 또는 이후 버전&lt;/li&gt;
&lt;li&gt;git&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/ryujt/multi-thread-exapmle&quot;&gt;https://github.com/ryujt/multi-thread-exapmle&lt;/a&gt; 예제 다운로드&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;이 강의에서 다룰 내용&lt;/h2&gt;
&lt;p&gt;이 강의에서는 이미 만들어진 라이브러리를 활용하여 구체적인 구현보다는 논리적인 개념을 파악하는데 집중하겠습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;스레드 프로그래밍의 기초&lt;/li&gt;
&lt;li&gt;스레드를 사용하는 패턴들&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>소프트웨어 공학</category>
      <author>ryujt</author>
      <guid isPermaLink="true">https://ryulib.tistory.com/468</guid>
      <comments>https://ryulib.tistory.com/468#entry468comment</comments>
      <pubDate>Sun, 1 Dec 2019 02:39:57 +0900</pubDate>
    </item>
    <item>
      <title>아두이노 보드 개발 후기</title>
      <link>https://ryulib.tistory.com/467</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;KakaoTalk_20190110_142857260.jpg&quot; data-origin-width=&quot;744&quot; data-origin-height=&quot;683&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ps1kg/btqz3CcAdS2/n8d8TPOSPK6hWNJiE1aAS0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ps1kg/btqz3CcAdS2/n8d8TPOSPK6hWNJiE1aAS0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ps1kg/btqz3CcAdS2/n8d8TPOSPK6hWNJiE1aAS0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPs1kg%2Fbtqz3CcAdS2%2Fn8d8TPOSPK6hWNJiE1aAS0%2Fimg.jpg&quot; data-filename=&quot;KakaoTalk_20190110_142857260.jpg&quot; data-origin-width=&quot;744&quot; data-origin-height=&quot;683&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;KakaoTalk_20190321_155531279.jpg&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;718&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Hf6EN/btqz03prj5P/0PGww3rBcVd3WSyjnAvmP1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Hf6EN/btqz03prj5P/0PGww3rBcVd3WSyjnAvmP1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Hf6EN/btqz03prj5P/0PGww3rBcVd3WSyjnAvmP1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHf6EN%2Fbtqz03prj5P%2F0PGww3rBcVd3WSyjnAvmP1%2Fimg.jpg&quot; data-filename=&quot;KakaoTalk_20190321_155531279.jpg&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;718&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;schematic.png&quot; data-origin-width=&quot;1663&quot; data-origin-height=&quot;1095&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/duzhVo/btqz1BMXM7n/RstLmnlxOCe0cUyE8Z9KNk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/duzhVo/btqz1BMXM7n/RstLmnlxOCe0cUyE8Z9KNk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/duzhVo/btqz1BMXM7n/RstLmnlxOCe0cUyE8Z9KNk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FduzhVo%2Fbtqz1BMXM7n%2FRstLmnlxOCe0cUyE8Z9KNk%2Fimg.png&quot; data-filename=&quot;schematic.png&quot; data-origin-width=&quot;1663&quot; data-origin-height=&quot;1095&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;ESP8266과 ESP32를 이용하여 파이썬으로 구동되는 피지컬 컴퓨팅 교재를 개발하는 동안 다양한 모델의 ESP 보드들을 모두 구매하여 테스트해보았지만, 문제가 상당히 많았습니다.&lt;/p&gt;
&lt;p&gt;그 중에서도 &lt;a href=&quot;https://robotdyn.com/&quot;&gt;https://robotdyn.com/&lt;/a&gt; 제품들이 이쁘고 다양한 모델이 있어서 테스트해보았지만, 다른 제품들에 비해서 오류가 많아서 적용을 포기했습니다.&lt;/p&gt;
&lt;p&gt;아래 사진의 NodeMCU와 쉴드를 주로 사용했는데, 여기서도 문제가 발생합니다. 쉴드가 불량이 많고 심지어 배선이 반대로 되어 있어 부품이 타는 일도 발생하였습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;212929365948B35325.jpg&quot; data-origin-width=&quot;630&quot; data-origin-height=&quot;354&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bunKxS/btqz03bQTIu/XYdONnYKsFh6tRkVFKG1V1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bunKxS/btqz03bQTIu/XYdONnYKsFh6tRkVFKG1V1/img.jpg&quot; data-alt=&quot;NodeMCU와 실드&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bunKxS/btqz03bQTIu/XYdONnYKsFh6tRkVFKG1V1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbunKxS%2Fbtqz03bQTIu%2FXYdONnYKsFh6tRkVFKG1V1%2Fimg.jpg&quot; data-filename=&quot;212929365948B35325.jpg&quot; data-origin-width=&quot;630&quot; data-origin-height=&quot;354&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;NodeMCU와 실드&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;대부분의 제품의 가장 큰 문제는 서보모터 4개를 달면 전력 공급 부족으로 보드가 다운된다는 점입니다. 서보모터가 아니더라도 부품을 많이 사용하여 전력공급이 부족해지면 역시나 불안정해지는 문제가 발생합니다.&lt;/p&gt;
&lt;p&gt;이에 직접 보드를 만들고 생산하기로 하고 맨 위의 이미지들과 같이 ESP32 기반의 보드를 직접 만들어서 사용하고 있습니다. 사실 크게 바꾼 것은 없고 오히려 불필요한 부품을 삭제하고 레귤레이터와 전원공급을 이원화하여 부품이 전력을 많이 사용해도 보드로 가는 전력에 영향을 최소화한 것이 주요 설계사항입니다.&lt;/p&gt;
&lt;p&gt;보드를 이용한 교육 프로그램과 제품은 &lt;a href=&quot;http://asomeit.com/main&quot;&gt;http://www.asomeit.com/&lt;/a&gt; 사이트를 참고하시기 바랍니다.&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=Gt0CNcGQu-8&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/XlSmO/hyDSJLuxwM/06fgki130WWeajJoY8kAhK/img.jpg?width=480&amp;amp;height=360&amp;amp;face=0_0_480_360&quot; data-video-width=&quot;480&quot; data-video-height=&quot;360&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/Gt0CNcGQu-8&quot; width=&quot;480&quot; height=&quot;360&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍/Arduino &amp;amp; IoT</category>
      <category>pcb</category>
      <category>회로설계</category>
      <author>ryujt</author>
      <guid isPermaLink="true">https://ryulib.tistory.com/467</guid>
      <comments>https://ryulib.tistory.com/467#entry467comment</comments>
      <pubDate>Tue, 26 Nov 2019 22:09:32 +0900</pubDate>
    </item>
    <item>
      <title>엔트리 하드웨어 개발</title>
      <link>https://ryulib.tistory.com/466</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;Pic-5.png&quot; data-origin-width=&quot;736&quot; data-origin-height=&quot;982&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/daLTNM/btqz1AHdfyw/nZx0rT07YWVoYHWv38Y0oK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/daLTNM/btqz1AHdfyw/nZx0rT07YWVoYHWv38Y0oK/img.png&quot; data-alt=&quot;교재의 일부&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/daLTNM/btqz1AHdfyw/nZx0rT07YWVoYHWv38Y0oK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdaLTNM%2Fbtqz1AHdfyw%2FnZx0rT07YWVoYHWv38Y0oK%2Fimg.png&quot; data-filename=&quot;Pic-5.png&quot; data-origin-width=&quot;736&quot; data-origin-height=&quot;982&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;교재의 일부&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;2년에 걸쳐서 프로그래밍 교육용 하드웨어와 소프트웨어를 개발을 해왔습니다. 마지막에는 엔트리를 추가 개발해야 했는데, 약간 고생한 편이라서 생각날 때마다 팁을 정리해보려고 합니다.&lt;/p&gt;
&lt;h2&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2&gt;개발환경 설치&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://entrylabs.github.io/docs/guide/&quot;&gt;https://entrylabs.github.io/docs/guide/&lt;/a&gt; 문서를 따라서 진행하였습니다. 설치부터 조금 삐걱거리기 시작했는데요. 소스가 빌드되지 않아서 문서에 있는 Node.js와 npm의 버전을 문서와 같이 오래 전 것을 찾아서 설치해보아도 마찬가지였습니다. 문제의 이슈는 &quot;npm install --global --production windows-build-tools&quot;로 설치하는 C++ 툴이 제 PC에 설치되어 있는 Visual Studio와 충돌하는 것으로 보였습니다. 아무것도 설치되지 않은 클린 PC에서 개발환경을 설치하고 빌드하여 빌드된 소스 폴더를 통째로 다시 복사해와서 사용하였습니다. 한 번 빌드되면 엔트리 하드웨어에 추가되는 파일들은 변경사항이 바로 적용이되기 때문에 굳이 개발 PC에서 빌드하지 않고 저처럼 다른 PC에서 빌드하여 복사해와도 문제 없습니다.&lt;/p&gt;
&lt;h2&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2&gt;하드웨어 블록 만들기&lt;/h2&gt;
&lt;p&gt;문서에 있는 하드웨어 블록 작성이 방법이 오래 된 것인지 적용에 다소 어려움을 겪었습니다. 그래서 저는 아두이노 소스를 그대로 복사하여 원하는 기능을 변경하면서 코드의 전반적인 흐름과 구조를 이해하는것부터 시작하였습니다. 제가 만들어야 하는 하드웨어는 파이썬을 사용하고 있어서 방식이 전혀 달랐지만, 일단 구조를 파악하는데에 중점을 두고 원래 하드웨어 개발에서는 처음부터 다시 시작하는 방법을 선택했습니다. (이부분도 다른 회사의 제품 코드를 일부 활용하기도 했습니다)&lt;/p&gt;
&lt;h3&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3&gt;entry-hw 소스&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;requestInitialData(): 하드웨어 접속이 되면 최초에 한 번 실행됩니다.&lt;/li&gt;
&lt;li&gt;handleRemoteData(): 엔트리에서부터 들어오는 메시지를 처리하는 함수입니다. 저희 제품의 경우에는 블록마다 파이썬 코드를 하드웨어에 전송하면, 하드웨어의 인터프리터가 이를 해석하고 실행하는 방식을 선택하였습니다.&lt;/li&gt;
&lt;li&gt;requestLocalData(): 엔트리에서 들어온 메시지를 가공하여, 하드웨어에 시리얼 통신으로 전송하는 함수입니다. 버퍼(큐)에 있는 메시지들을 하나씩 읽어와서 처리하는 구조입니다.&lt;/li&gt;
&lt;li&gt;handleLocalData(): 하드웨어에서 시리얼 통신으로 입력받은 메시지를 처리하는 함수입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;아래는 전체 소스코드입니다.&lt;/p&gt;
&lt;pre class=&quot;kotlin&quot;&gt;&lt;code&gt;const _ = require('lodash');
const BaseModule = require('./baseModule');

class AsomeBot extends BaseModule {
    constructor() {
        super();

        this.isDraing = false;
        this.sendBuffer = [];

        this.receivedText = &quot;&quot;;

        this.msg_id = '';
        this.sendToEntry = {
            msg_id: &quot;&quot;,
            distance: 0,
            udp_msg: &quot;&quot;,
        };
    }

    connect() {
    }

    socketReconnection() {
        this.socket.send(this.handler.encode());
    }

    requestInitialData() {
        console.log(&quot;requestInitialData&quot;);

        var init_str = &quot;import asomebot; import hcsr04; asomebot.ready(5, 6, 7,8); hcsr04.open(3, 2)\r&quot;;
        return Buffer.from(init_str, &quot;ascii&quot;);
    }

    setSerialPort(sp) {
        this.sp = sp;
    }

    setSocket(socket) {
        this.socket = socket;
    }

    checkInitialData(data, config) {
        return true;
    }

    validateLocalData(data) {
        return true;
    }

    requestRemoteData(handler) {
        var sendToEntry = this.sendToEntry;
        // console.log(&quot;to Entry: &quot;, sendToEntry);

        for (var key in sendToEntry) {
            handler.write(key, sendToEntry[key]);
        }
        return;
    }

    handleRemoteData({ receiveHandler = {} }) {
        const { data: handlerData } = receiveHandler;
        if (_.isEmpty(handlerData)) {
            return;
        }

        if (handlerData.msg_id == undefined) {
            console.log(&quot;from handlerData.msg_id == undefined&quot;, handlerData);
            return;
        }

        if (handlerData.msg_id != this.msg_id) {
            console.log(&quot;from Entry: &quot;, handlerData);

            this.msg_id = handlerData.msg_id;
            this.sendBuffer.push(Buffer.from(handlerData.msg + &quot;\r&quot;, 'ascii'));
            this.sendBuffer.push(Buffer.from(&quot;'#I'&quot; + &quot;'D &quot; + handlerData.msg_id + &quot;'\r&quot;, 'ascii'));

            // 초음파 센서를 이동 블록등과 함께 사용할 때 신호가 처리 안되는 경우가 있다.
            // 반복 실행해도 상관없는 코드이기 때문에 모든 명령 수행시에 추가로 실행하여 최신 측정값을 갱신해 둔다.
            this.sendBuffer.push(Buffer.from(&quot;print('#D' + 'T ' + str(hcsr04.get_distance()) + '  ###')\r&quot;));
        }
    }

    requestLocalData() {
        var self = this;

        if (!this.isDraing &amp;amp;&amp;amp; this.sendBuffer.length &amp;gt; 0) {
            this.isDraing = true;
            var msg = this.sendBuffer.shift();
            console.log(&quot;to AsomeBot: &quot;, msg.toString(), this.sendBuffer.length);
            this.sp.write(msg, function() {
                if (self.sp) {
                    self.sp.drain(function() {
                        self.isDraing = false;
                    });
                }
            });
        }

        return null;
    }

    handleLocalData(data) {
        // console.log(&quot;handleLocalData: &quot;, this.receivedText);

        this.receivedText = this.receivedText + data.toString();

        var index = this.receivedText.indexOf('\r');
        while (index &amp;gt;= 0) {
            var line = this.receivedText.substring(0, index);
            this.receivedText = this.receivedText.substring(index + 1);

            console.log(&quot;from AsomeBot: &quot;, line);

            if (line.indexOf('#DT') &amp;gt;= 0) {
                var values = line.split(&quot; &quot;);
                if (values.length &amp;gt; 1) this.sendToEntry.distance = values[1];
            }
            if (line.indexOf('#UDP') &amp;gt;= 0) {
                var values = line.split(&quot; &quot;); 
                if (values.length &amp;gt; 1) {
                    this.sendToEntry.udp_id = this.msg_id;
                    this.sendToEntry.udp_msg = values[1];
                }
            }
            if (line.indexOf('#ID') &amp;gt;= 0) this.sendToEntry.msg_id = line;

            index = this.receivedText.indexOf('\r');
        }
    }

    setSocketData({ socketData, data }) {
    }

    lostController() { }

    disconnect(connect) {
        connect.close();
        this.sp = null;
    }

    reset() {
        this.sp = null;
        this.isPlaying.set(0);
        this.sendBuffer = [];
        this.receivedText = &quot;&quot;;
    }
}

module.exports = new AsomeBot();&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;entryjs 소스의 일부분과 설명&lt;/h3&gt;
&lt;pre class=&quot;scala&quot;&gt;&lt;code&gt;asomebot_toggle_led: {
    template: Lang.template.asomebot_toggle_led,
    color: EntryStatic.colorSet.block.default.HARDWARE,
    outerLine: EntryStatic.colorSet.block.darken.HARDWARE,
    skeleton: 'basic',
    statements: [],
    params: [
        // 블록 내에 입력창의 데이터 타입 (문자열)
        {
            type: 'Block',
            accept: 'string',
        },

        // 블록 맨 뒤에 아이콘이 달린 꼬리 표시
        {
            type: 'Indicator',
            img: 'block_icon/hardware_icon.svg',
            size: 12,
        },
    ],

    // 입력창에 입력된 데이터의 키값
    paramsKeyMap: {
        VALUE: 0,
    },
    events: {},
    def: {
        params: [
            // 콤보 박스 형태로 데이터를 직접 입력하지 않고 선택할 수 있는 방식
            // 디폴트는 'on'이며, &quot;on&quot;, &quot;off&quot; 중에 선택할 수 있는 형태
            {
                type: 'arduino_get_digital_toggle',
                params: ['on'],
            },
            null
        ],
        type: 'asomebot_toggle_led',
    },
    class: 'Basic',
    isNotFor: ['AsomeBot'],
    func: function(sprite, script) {
        var sq = Entry.hw.sendQueue;
        var pd = Entry.hw.portData;

        // 입력창에서 입력받은 값을 가져온다.
        var value = script.getValue('VALUE');

        if (!script.is_started) {
            script.is_started = true;

            // 하드웨어에서 명령을 처리할 동안 기다리기 위해서 고유 id 발급
            script.msg_id = random_str(16);
            sq.msg_id = script.msg_id;

            // 실행해야할 파이썬 코드
            sq.msg = format_str(&quot;OutputPin(4).{0}()&quot;, value);

            // script가 리턴되면 블록 실행이후 다음으로 넘어가지 않고 기다리게 된다.
            return script;
        } 

        // 만약 리턴받은 id가 발급했던 id와 같으면 이 블록 실행을 마치고 다음 실행으로 넘어가도록 한다.action-button
        if ((pd.msg_id) &amp;amp;&amp;amp; (pd.msg_id.indexOf(script.msg_id) &amp;gt;= 0)) {
            delete script.is_started;
            delete script.msg_id;
            return script.callReturn();
        }

        return script;
    },
    syntax: undefined,
},&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로젝트/엔트리</category>
      <category>entry</category>
      <category>엔트리</category>
      <author>ryujt</author>
      <guid isPermaLink="true">https://ryulib.tistory.com/466</guid>
      <comments>https://ryulib.tistory.com/466#entry466comment</comments>
      <pubDate>Tue, 26 Nov 2019 21:47:45 +0900</pubDate>
    </item>
    <item>
      <title>Episode #1 - 어려운 문제 조각내서 해결하기</title>
      <link>https://ryulib.tistory.com/465</link>
      <description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=bqvvmDGYOUk&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/GASn3/hyDORKRuyv/lPZi4LHVdICqDgKVg5fEh1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=1104_620_1158_680&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/bqvvmDGYOUk&quot; width=&quot;860&quot; height=&quot;484&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;설명 문서 자료: &lt;a href=&quot;http://10bun.tv/beginner/episode-1/&quot;&gt;http://10bun.tv/beginner/episode-1/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>소프트웨어 공학</category>
      <author>ryujt</author>
      <guid isPermaLink="true">https://ryulib.tistory.com/465</guid>
      <comments>https://ryulib.tistory.com/465#entry465comment</comments>
      <pubDate>Sun, 24 Nov 2019 11:42:43 +0900</pubDate>
    </item>
    <item>
      <title>클래스 핼퍼를 이용하여 디버깅하기</title>
      <link>https://ryulib.tistory.com/464</link>
      <description>&lt;p&gt;델마당에 올라온 질문에 답하기위해서 오랫만에 블로그에 글을 남겨 봅니다.&lt;/p&gt;
&lt;p&gt;질문 내용은 아래와 같습니다.&lt;br /&gt;&lt;a href=&quot;https://www.delmadang.com/community/bbs_view.asp?bbsNo=17&amp;amp;bbsCat=0&amp;amp;indx=457334&amp;amp;page=1&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.delmadang.com/community/bbs_view.asp?bbsNo=17&amp;amp;bbsCat=0&amp;amp;indx=457334&amp;amp;page=1&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;저의 제안은 클래스 핼퍼를 이용해서 SetFocus를 덮어 써서 자신의 이름을 화면에 표시하는 것입니다. 문제는 SetFocus가 덮어써져서 실제 포커스를 이동하는 기능이 정지되는 것인데요, 이렇게 되면 Invisible 상태에서도 에러가 발생하지 않습니다. 그래서 원래의 SetFocus 코드를 가져와서 그대로 실행해주는 것을 덧 붙였습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1574478336106&quot; class=&quot;go&quot; style=&quot;display: block; overflow: auto; padding: 15px; color: #383a42; background: #f6f7f8; font-size: 14px; border-radius: 3px; font-family: Menlo, Consolas, Monaco, monospace; border: 1px solid #dddddd; margin: 20px auto 0px; cursor: default; z-index: 1; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls;

type
  TGetFocusControl = class helper for TWinControl
  public
    procedure SetFocus;
    procedure NewSetFocus;
  end;

  TForm1 = class(TForm)
    Panel1: TPanel;
    Edit1: TEdit;
    Edit2: TEdit;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  Edit1.SetFocus;
  Edit2.SetFocus;
end;

{ TGetFocusControl }

[UIPermission(SecurityAction.InheritanceDemand, Window=UIPermissionWindow.AllWindows),
UIPermission(SecurityAction.LinkDemand, Window=UIPermissionWindow.AllWindows)]
procedure TGetFocusControl.NewSetFocus;
var
  Parent: TCustomForm;
begin
  Parent := GetParentForm(Self);
  if Parent &amp;lt;&amp;gt; nil then
    Parent.FocusControl(Self)
  else if ParentWindow &amp;lt;&amp;gt; 0 then
    Winapi.Windows.SetFocus(Handle)
  else
    ValidParentForm(Self);
end;

procedure TGetFocusControl.SetFocus;
begin
  ShowMessage(Name);
  NewSetFocus;
end;

end.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;만약 디버깅해야 할 유닛이 너무 많아서 일일히 핼퍼 코드를 복사하기가 싫다면, 별도의 유닛을 만들어서 포커스 때문에 문제가 되는 콤포넌트들을 모두 아래처럼 수정하시면 됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1574480672522&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;unit NewWinControl;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls;

type
  TEdit = class (Vcl.StdCtrls.TEdit)
  private
  public
    procedure SetFocus; override;
  end;

implementation

{ TNewWinControl }

procedure TEdit.SetFocus;
begin
  ShowMessage(Name);
  inherited;
end;

end.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이제 필요한 유닛마다 uses 맨 앞에 방금 만든 유닛을 추가해주시면 됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1574480708360&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls,
  NewWinControl;

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    Edit1: TEdit;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  Edit1.SetFocus;
end;

end.&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/Delphi</category>
      <author>ryujt</author>
      <guid isPermaLink="true">https://ryulib.tistory.com/464</guid>
      <comments>https://ryulib.tistory.com/464#entry464comment</comments>
      <pubDate>Sat, 23 Nov 2019 12:05:55 +0900</pubDate>
    </item>
  </channel>
</rss>