WPFImagePrintTest.zip



회사에서 일을 하던중에 이미지 파일의 인쇄가 프로그램을 만들게 되었습니다.


웹을 뒤져보니까 윈폼용을 있지만 WPF용으로는 없는 것 같아서 이렇게 블로깅을 하게 되었네요!


매우 간추리자면 PridDialog를 사용하면 됩니다! 아시는 문들은 MSDN에 가서 보시면 되시겠구요. 저는 버튼을 누르면 이미지 출력!


인쇄를 누르면 인쇄 하는 것 까지 만들어 보겠습니다.


파일 -> 새로 만들기 -> 프로젝트


먼저 Xaml은


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<Window x:Class="WPFImagePrintTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WPFImagePrintTest"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Image Name="image" Height="250" Width="425" Margin="82,10,10,59"></Image>
 
        <Button x:Name="button1" Content="이미지!" HorizontalAlignment="Left" Margin="10,279,0,10" Width="75" Click="button1_Click"/>
        <Button x:Name="button" Content="인쇄" HorizontalAlignment="Left" Margin="110,279,0,10"  Width="75" Click="button_Click"/>
    </Grid>
</Window>
 
cs

버튼 2개 이미지뷰 한개를 만들어서 올려줍니다. 어차피 간단한 테스트 프로그램이니 대충~ 원하는 대로!


먼저 이미지를 불러오는 함수를 만들어 줍시다.


1
2
3
4
5
6
7
8
9
private ImageSource imageLoad() // 이미지를 불러오는 부분
{
    var bi = new BitmapImage();
    bi.BeginInit();
    bi.CacheOption = BitmapCacheOption.OnLoad;
    bi.UriSource = new Uri(@"..\Assets\images.png", UriKind.Relative);
    bi.EndInit();
    return bi;
}
cs

비트뱁 이미지를 생성후에 Uri를 통해서 이미지를 가져옵니다.

먼저 이미지 소스에 이미지를 넣는 버튼 이벤트를 해보겠습니다.

1
2
3
4
private void button1_Click(object sender, RoutedEventArgs e)   // 이미지 보여주는 함수
{
    image.Source = imageLoad();
}
cs

네 참 쉽죠? 그냥 이미지의 속성중에 소스라는 곳에 비트맵을 넣어주면 됩니다.


실행해보면?



네 잘 나옵니다!


자 이제 정말 중요한 인쇄 부분을 보겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private void button_Click(object sender, RoutedEventArgs e) // 이미지를 인쇄하는 부분
{
    var bi = imageLoad();
 
    var vis = new DrawingVisual();
    var dc = vis.RenderOpen();
    dc.DrawImage(bi, new Rect { Width = bi.Width, Height = bi.Height });// 이것을 움직이면 크기를 바꿀 수 있습니다.
    dc.Close();
 
    var pdialog = new PrintDialog();
    if (pdialog.ShowDialog() == true)
    {   
        pdialog.PrintVisual(vis, "Smile Image");
    }
}
cs

비트맥에 이미지 로딩하는 부분을 넣은후

그 비트맵을 Visual이라는 형식으로 바꾸는 작업이 필요합니다. 그렇게 바뀌어진 Visual을 PrintDialog.PrintVisual에 넣으면 완성!


짠~ 전 pdf와 저의 인쇄기로 테스트해봤는데 잘 됩니다!


풀 소스와 프로젝트파일 까지 올려 놓을테니 많이 많이 도움이 되시길 바랍니다!


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
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        
    }
    private void button_Click(object sender, RoutedEventArgs e) // 이미지를 인쇄하는 부분
    {
        var bi = imageLoad();
 
        var vis = new DrawingVisual();
        var dc = vis.RenderOpen();
        dc.DrawImage(bi, new Rect { Width = bi.Width, Height = bi.Height });// 이것을 움직이면 크기를 바꿀 수 있습니다.
        dc.Close();
 
        var pdialog = new PrintDialog();
        if (pdialog.ShowDialog() == true)
        {   
            pdialog.PrintVisual(vis, "Smile Image");
        }
    }
    private void button1_Click(object sender, RoutedEventArgs e)   // 이미지 보여주는 함수
    {
        image.Source = imageLoad();
    }
    private ImageSource imageLoad() // 이미지를 불러오는 부분
    {
        var bi = new BitmapImage();
        bi.BeginInit();
        bi.CacheOption = BitmapCacheOption.OnLoad;
        bi.UriSource = new Uri(@"..\Assets\images.png", UriKind.Relative);
        bi.EndInit();
        return bi;
    }
}



cs



참고: http://stackoverflow.com/questions/265062/load-image-from-file-and-print-it-using-wpf-how


1. Windows Hello


이것이 무엇인가? 바로 생체 인증을 통해 컴퓨터에 로그인을 하는것!


특히 서피스 프로 4 에 탑재되어서 카메라를 바라보기만 해도 나를 인식하고 로그인을 해주는 것 입니다.


인텔 리얼 센스 기술을 이용해서 적외선으로 사람의 굴곡을 계산해서 로그인을 하는 것이라고 합니다.


제가 여기서 주목한 것은 적외선!! 왜냐하면 키넥트도 적외선이 되거든요!!! 그럼 이것으로 데스크탑에서 할수 있지 않을까?


라는 생각을 해보았는데요 네 됩니다 ㅎㅎㅎ


2. 하는 방법


2-1 메모장을 하나 연다


2-2


Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\DriverFlighting\Partner]

"TargetRing"="Drivers"


이렇게 적는다 귀찮으면 제가 첨부해놓은 파일을 받으세요


2-3 확장자를 reg로 마음에 드는 이름으로 저장한다.


저장된 파일! 이파일을 실행하면?

확인 확인 을 눌러줍니다.



키넥트 드라이브는 자동으로 깔리겠지만 레지스트리 추가로 인해 업데이트 됩니다.


온라인으로 소프트웨어 업데이트!



이렇게 한 후 컴퓨터를 재시작을 합니다



로그인 옵션으로 가보면 Windows Hello 가 사용 가능하다고 나옵니다!


윈도우즈 헬로우를 시작!


자기 얼굴을 등록해 줍니다!



완성!


그래서 저같은경우는 컴퓨터를 실행하면 키넥트가 빨갛게 되면서 윈도우즈 헬로우가 작동되네요!


이상으로 Kinect v2 로 윈도우즈 헬로우 하기 완성 입니다!


'Kinect' 카테고리의 다른 글

1. Kinect v2 개발과 환경 구축하기!  (0) 2016.11.07

게임기 보조 장치? 로 만들었지만 정작 게임기 보다는 산업 현장에서 더 많이 쓰인다는 키넥트!


처음 키넥트 360으로 나왔을때는 개발 서적도 좀 보이고 개발하는 분들도 좀 보이더만


엑스박스 원의 정책의 실패로 인해서 관련 도서도 없고 하시는 분들도 많이 보이지 않습니다.


그래서 제가 한 번 해 보겠습니다.


1. 키넥트 v2 구입


저같은 경우는 중고로 구입했습니다 중고는 10만원 정도이고 새거는 20만원 정도 하더군요 + 댄스 센트럴 해서요!


2. 커넥터 구입!


이렇게 생긴것을 구매하시면 됩니다. 7만원대 네요 원래 윈도우용으로도 나왔으나 이내 단종이 되고 모든 키넥트는 저 어댑터를 통해서 윈도우 10과 연결 할 수 있고 개발 할 수 있습니다.


이제 키넥트와 어댑터를 윈10 디바이스에 연결을 합니다


이제 개발을 위한 SDK를 설치해 보겠습니다.


먼저 마이크로소프트 사이트에가서 Kinect for WIndows SDK 2.0 을 받습니다

https://www.microsoft.com/en-us/download/details.aspx?id=44561


반드시 2.0 을 받읍시다 1.8도 있지만 키넥트360 용 SDK입니다. v2는 2.0 이기에 꼭 2.0을 받읍시다!





실행후 다음다음 다음만 눌러주면 설치 완료!



SDK Browser 을 실행해본 모습  샘플로 C# C++ 로 실행도 가능하고 설치도 가능합니다.

또한 자신의 컴퓨터가 잘 맞는지 보려면



저의 경우 USB가조금 위험하지만 작동에는 이상이 없습니다!


SDK와 함께 추가된 앱들 입니다 이렇게 되면 개발환경이 구축 된 것 입니다.! 참 쉽죠?


Color Basics-D2d를 실행시켜 보면 제방이 잘 나옵니다Private 하기때문에 좀 가렸습니다 하하핳하하




주의!!!!!!!!!!!


최소 사양입니다... 특히 USB 3.0에 대해서는 메인보드 별 성능 이슈가 있다고 합니다. 특히


https://social.msdn.microsoft.com/Forums/en-US/bb379e8b-4258-40d6-92e4-56dd95d7b0bb/confirmed-list-of-usb-30-pcie-cardslaptopsconfigurations-which-work-for-kinect-v2-during?forum=kinectv2sdk 에 보시면 몇멸 USB에 대해서는 안될수도 있다고 하니 자신의 컴퓨터 사양을 잘 보세요!



'Kinect' 카테고리의 다른 글

2. Kinect로 Windows Hello 작동 하기  (0) 2016.11.07

회사에서 코어로 되어있는 C++엔진을 C#으로 올리는 작업을 하게 되었습니다.

속도와 최적화를 위해 C++로 만든 라이브러리 같을 것을 생산성을 높이기 위해 C#에서 사용할 수 있습니다 

그 방법은 크게 두가지가 있는데 

첫번쨰는 C++/CLI를 이용해서 넘겨주는 것이고

두 번쨰는 DLLImport 해주는 방법입니다 저희 회사는 모종?의 이유로 첫번째를 사용합니다 

저도 처음 해보는 것 이기에 해보다 오늘 성공! 하고 잊지 않기 위해 포스팅! 첫번째 방법도 라이브러리가 정적,동적 두개가 있기때문에 크게 두가지로 나눌수 있는데

1.C++로만든 Lib ->C++/CLI -> C#

2.C++로만든 Dll -> C++/CLI -> C# 

회사 엔진은 Dll로 배포하기에 일단 2.으로 포스팅을 먼저 하겠습니다.

1.먼저 Dll이 필요합니다. 만약 없다면 하나 만들어봅시다 https://msdn.microsoft.com/ko-kr/library/ms235636.aspx

2.저 예제를 그대로 빌드하고 컴파일 하면

MathFuncsDll.dll

MathFuncsDll.lib

라고 나오는데 이름은 사실 상관없습니다. dll과 Lib 파일만 있으면 됩니다. 아 header 파일도 필요합니다.

3.자 이제 정말 만들어봅시다! 비주얼 스튜디오를 시작하고 파일->새로만들기->프로젝트를 누르고

Visual C++ -> CLR -> 클래스라이브러리를 선택합시다 솔루션 이름과 프로젝트 네임은 전 스샷처럼 했지만 자유롭게 정해봅시다

그러고 확인을 누르면 이렇게 되고 ref class가 자동으로 생성됩니다. 아마 Class1 이라고 나올것 입니다 

저는 파일이름과 맞추어주기위해 이름을 dllClr로 바꾸어 생성했습니다. 

이제 프로젝트의 솔루션이 있는 경로로 가서 dll,lib,h 파일을 '일단' 이 프로젝트 폴더에 넣어줍니다

사실...설정이 더 빡세고 짜증난다 ㅠㅠ 이제 설정을 해봅시다.

먼저 어떤 함수가 무엇을 하는지 알아야 합니다 그걸 알기위해서 헤더파일도 같이 있습니다.

그래서 프로젝트에 헤더파일란에 저 헤더파일을 추가해줍시다. 방금 일단 저 폴더에 넣자고 했는데 지금이야 작은 Dll이지만 나중에 커지면 관리하기 힘드니 지금 폴더를 나누어 줍시다 그래서 저는 include 폴더를 만들어서 헤더파일을 넣어주고 lib 폴더를 만들어서 dll과 lib 파일을 넣어주었습니다

자 아까 나누어주었던 라이브러리를 프로젝트에 추가해 줍시다.

하게 되면 왼쪽 소스 처럼 #include 에서 경로를 입력해주지 않아도 됩니다 

이제 아까 추가해준 헤더파일을 보면서 어떤 함수가 있는지 보면서 C++/CLR로 적어줍니다

소스파일 입니다 dll에 있는 함수를 가져옵니다

라이브러리도 추가해 주어야 하는데요 링커->입력 추가 종속성에서 라이브러리를 등록해줍니다! 주의 하실것은 라이브러리가 있는 폴더가 아니라

xxxx.lib를 직접 등록해 주어야 합니다.

한번 빌드! 네 잘 됩니다!

자 이제 C# 프로젝트를 만들어서  dll에 있는 것들을 가져와서 사용해 봅시다!

 

CLR 도 추가해줍니다. 이렇게 dll을 한번 감싼 것을 C# 프로젝트에서 사용할수 있게 합니다.

프로젝트 오른쪽 클릭 추가 참조를 눌러줍니다

참조관리자에서 솔루션에서 CLR프로젝트를 추가해서 넣어줍니다

CLR은 빌드 만 해주기때문에 그 라이브러리를 사용해서 직접 보여주는 것은 C# 프로젝트가 합니다

때문에 C# 프로젝트를 시작 프로그램으로 설정해 줍니다

여기서 가장 중요한것! 그 맨처음의 dll을 실행 파일이 있는 곳에 넣어주어야 합니다.

CLR이 참조하는 것들을 가져와야 하기떄문에 실행시점에 dll 파일이 있어야 합니다.(이것때문에 2시간 삽질 ㅠㅠ)

obj으로 가져온 dll속에 있는 함수들! 사용해 보면 잘 나옵니다!


ps.혹 실행이 안되신다면 64비트 32비트 맞추기 위해 빌드 에서 32비트 기본 사용을 체크 해제해 주세요

 

 

 

먼저 제가 첨부해 놓은 파일을 받아봅시다!

파일 이름에서 유추할수 있듯이 가위 바위 보 입니다.

윈도우즈 10 앱으로 제가 만들 가위 바위 보는 제가 그림을 클릭 하면 가위 바위 보를 내게 되고 컴퓨터도 그렇게 내어서 이겼는지 졌는지를 알수 있는 앱입니다.

저번에 그냥 텍스트 블록과 버튼만 필요했던 것과는 달리 이번에는 알아야 할것이 몇가지 있습니다. 짚어보겠습니다.

1. 버튼에 이미지 넣기!

Xaml에서 마이크로소프트가 제공하는 버튼을 넣으면

이렇게 나옵니다. 깔끔하긴한데 그렇게 이쁘? 지는 않는것 같습니다.

그리고 요즘 UI나 UX를 중요시 하는 시대라서 그런지 아마 저것을 그냥 쓰는 회사도 많이 없을거 같네요

그럼 어떻게 해야 할까요?

자 먼저 위의 버튼을 xaml 파일로 본다면

1
 <Button x:Name="button" Content="Button" HorizontalAlignment="Left" Margin="176,198,0,0" VerticalAlignment="Top" Width="182" Height="102"/>
cs

이렇게 나옵니다. 이름도 버튼 써있는 것도 버튼 그럼 우리 첨부파일중에 가위를 버튼이미지로 해보겠습니다.

1
2
3
4
5
6
7
<Button x:Name="button" Content="Button" HorizontalAlignment="Left" Margin="176,198,0,0" VerticalAlignment="Top" Width="182" Height="102">
            <Button.Template>
                <ControlTemplate>
                    <Image Source="Assets/Scissor.png"/>
                </ControlTemplate>
            </Button.Template>
        </Button>
cs

버튼 사이에 버튼 템플릿이라는 것을 넣고 더해서 컨트롤 템플릿을 넣으면 이미지소스를 통해서 이미지모양 버튼을 만들 수 있게 됩니다.

그럼 버튼이 어떻게 나오나 볼까요?


이렇게 칙칙한 회색 버튼이 가위로 바뀌었습니다! 버튼 사이에 템플릿 넣기! 기억해 둡시다

2. 이벤트시 그림 나오게 하기

우리 버튼 이벤트( 버튼을 클릭했을 때) 어떻게 했는지 기억 나시나요?

저버튼을 두번 클릭하기!

1
2
3
4
private void button_Click(object sender, RoutedEventArgs e)
        {
 
        }
cs

그럼 이렇게 메서드가 생기죠? 자 여기서 생각을 해봅시다. 우리가 버튼을 템플릿으로 만들었을때 이미지소스 즉 위치를 컴퓨터가 찾을수 있도록 해주었죠?

그럼 저 메서드 안에서 이미지 소스를 알려주어야 하지 않을까요? 즉 이미지를 보여주는 곳에 이미지 소스를 알려주면 되지 않을까요?

네 가능합니다.! 먼저 저 앱에서 ToolBox에서 이미지를 원하는 곳에 위치 시켜봅시다.

이미지를 보여주는것에 사용할 레고 세트를 사야합니다

using Windows.UI.Xaml.Media.Imaging;

를 추가 시켜 줍시다 그래야 Bitmap이라는 클래스를 이용해서 이미지를 보여줄수 있어요!

자 그럼 소스를 적어봅시다.

1
 image.Source = new BitmapImage(new Uri("ms-appx:///Assets/Scissor.png", UriKind.Absolute));
cs

이 한줄이면 버튼을 누르면 그것이 바로 Image가 위치한 화면에 뙇! 하고 나옵니다.

소스를 뜯어보면 image의 Source를 정해줄게요! 라는 것을 시작으로 비트맵 클래스의 uri를 정해주는 겁니다.

ms-appx는 Microsoft의 앱 데이터들을 말해주는 것이고요 urikind.absolute 보니까 감이 오지 않나요?

uri경로를 절대경로로 하겠다는 뜻입니다!


자 이렇게 그림 가위바위 보를 만들기 위한 그림과 요소들을 알아보았구요! 혼자 가위바위보를 만들어 봅시다!


우리 로또 번호을 universal app으로 만들어 봅시다

먼저 로또번호가 나와야할 Textblock이 하나 필요하겠네요

두번째 로는 버튼이 필요할 것 같네요 버튼을 누를때 마다 새로운 로또 번호를 생성하도록 만들어 보겠습니다

첫번째로는 xaml 파일로 버튼과 텍스트 블록을 만들어 줍니다. 위치나 크기 등등은 마음대로 해보세요

이렇게 위치도 바꾸어 보고 만져보면서 xaml에 더 나아가 윈도우앱에 익숙해집니다!



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<Page
    x:Class="uniappTest.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:uniappTest"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
 
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Margin="0,0,-647,0">
        <Button x:Name="button" Content="로또 번호 생성하기" HorizontalAlignment="Left" Margin="675,188,0,0" VerticalAlignment="Top" Click="button_Click"/>
        <TextBlock x:Name="textBlock" HorizontalAlignment="Left" Margin="148,188,0,0" TextWrapping="Wrap" Text="로또 번호 생성기" VerticalAlignment="Top" Width="522" Height="32"/>
 
 
    </Grid>
</Page>
 
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
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
 
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
 
namespace uniappTest
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        int[] number;
        Random my_rand;
        public MainPage()
        {
            number = new int[7];
            my_rand = new Random();
            this.InitializeComponent();
        }
 
        private void button_Click(object sender, RoutedEventArgs e)
        {
            MakeNumber();
            textBlock.Text = " "// 초기화 전에 있던 거 지우기
            
           
            for (int i = 0; i < number.Length;i++)
            {
                
                if (number.Length-1==i)
                {
                    textBlock.Text += " 보너스 번호는 " + number[number.Length - 1];
                }
                else
                {
                    textBlock.Text += " " + number[i];
                }
            }
        }
        void MakeNumber()
        {
            int a;
            for (int i = 0; i < number.Length; i++)
            {
                a = my_rand.Next(145);
                if (true == CheckSame(i, a))
                {
                    number[i] = a;
                }
                else
                {
                    i--;
                }
            }
 
        }
        bool CheckSame(int index,int value)
        {
            for (int i = 0; i < index; i++)
            {
                if (value == number[i])
                {
                    return false;
                }
            }
            return true;
        }
       
    }
}
 
cs


나머지는 앞에서 콘솔로 만들었던 것과 같습니다! 조금 달랐던점은 제가 주석으로 표시를 해두었으니 참고하시면서

꼭 자기손으로 만들어 보시길 바랍니다!


실행화면










올해 발표하고 많은 사람들이 업데이트한 Windows 10!

마이크로소프트의 차기 운영체제로 마이크로소프트에서도 밀고 있는 운영체제인데요 지금까지 배운 C#으로

GUI 프로그래밍을 해보겠습니다.

첫 번째로 프로젝트를 만들어 봅시다!

1. File -> New  -> Project 를 누릅니다.



2.Visual C# -> Universal -> Blank App(Universal Windows) 를 누르고 이름을 HelloWindows10 을 하고 OK를 눌러줍니다.

짠 하고 생성되었습니다 다른것들은 차차 알아갈테니 우리가 가장 중요하게 봐야 하는것!

MainPage.xaml을 클릭해줍니다


그럼 이렇게 Xaml과 Degin이 생깁니다.

우리가 중점을 두어야 할 것은 바로 이 Xaml입니다. 마이크로소프트는 처음에 C언어와 C++언어를 이용해서 윈도우즈 프로그래밍 언어를 만들게끔 도구들을 제공했습니다. 바로 Win32 API와 MFC 인데요 하지만 너무 어려웠고 비주얼 스튜디오때문에 쓴다는 말이 있을 정도로 그렇게 까지 좋지 않았습니다.

그렇게 발전하고 발전하다가 나온게 xaml이라는 마크업 언어로 디자인을 하고 C#/C++/VB로 코딩을 하는 방법을 나오게 되었고 지금 wpf->windows 8->windows 10이런식으로 발전하면서 윈도우즈 프로그래밍은 이렇게 만드는 것으로 고착화?가 된듯 합니다. 이런 배경이 궁금하신분들은 찾아보시고! 우리 Hello Windows 10을 만들어 봅시다

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<Page
    x:Class="HelloWindows10.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:HelloWindows10"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
 
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
 
    </Grid>
</Page>
 
cs

바로 생성된 xaml 파일! 하나하나 볼까요?

      x:Class="HelloWindows10.MainPage"

이것은 xaml 파일의 가장 중요한 루트(뿌리)에서만 나타나며 C#에 의하면 class 와 같은 의미를 가지는 것입니다 즉 HelloWindows10이라는 네임스페이스 하위의 Mainpage 클래스는 Page로부터 나타난 것이다 라고 생각하시면 됩니다.

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

2006년이 마이크로소프트가 이런 방식과 xaml을 처음으로 선보인 해 입니다. winfx라는것은 이런 방식이 wpf라고도 하는데 이렇게 발표되기 전에는 Winfx라고도 불렸다네요 그래서 winfx가 삽입되어 있습니다. xaml은 WPF,실버라이트,윈도우폰,윈도우즈 사이에서 어느정도 호환은 되지만 공통되는 것은 클래스와 속성과 기능뿐입니다.

나머지 세줄은 마이크로소프트에서 디자인과 기획툴로 사용되는 블랜드라는 툴을 위한 코드이므로 무시하셔도 됩니다!

자그럼 우리 Hello Windows 10을 만들어 볼까요?

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    </Grid>

사이에 코드를 적어 봅시다

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<Page
    x:Class="HelloWindows10.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:HelloWindows10"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
 
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <TextBlock Text="Hello, Windows 10"
                   FontFamily="segoe UI"
                   FontSize="96"
                   Foreground="SkyBlue"
                   HorizontalAlignment="Center"
                   VerticalAlignment="Center" />
    </Grid>
</Page>
 
cs

1. TextBlock 글자를 보여주는 도구 입니다 그안에 여러가지 속성이 있습니다.

Text=Text="Hello, Windows 10"""  ""안에 우리가 쓰고 싶은 글자를 써주시면 됩니다

FontFamily="segoe UI"               ""안에 원하는 폰트 이름을 넣어주시면 됩니다. 저는 윈도우 공식폰트인 segoe UI

FontSize="100"                         폰트 사이즈! 저는 단순하게 100 넣어볼게요!

Foreground="SkyBlue"              색생! 저는 시원하게 Skyblue를 넣어 보겠습니다!

 HorizontalAlignment="Center"   수평으로 가운데! 라는 뜻인데요 어느 플랫폼이든 가운데에 넣을 수 있게 됩니다!

 VerticalAlignment="Center"      수직으로 가운데! 이또한 어느 플랫폼이나 기기든 가운데에 넣을수 있게 됩니다.


이렇게 나오면 잘 됮거에요!

그럼 실행해 봅시다!


우아 먼가 멋있죠? 아 뭔가 예뻐... 우리의 첫 GUI 프로그램 Hello World가 완성되었습니다.

Xaml 생각보다 어렵지 않고 신기하죠? 다음은 로또번호 생성기를 만들면서 버튼도 만들어 보겠습니다!


드디어! 까만화면에 커서만 번뜩번뜩 하던것을 떠나서

우리가 정말 쓰는 프로그램 같은 네모에 이것저것 나오는 GUI 프로그래밍을 해볼 것 입니다.

C#에서 GUI를 만들때 쓰는 방법은 WindowsForm,WPF,Universal App 이정도로 있습니다(WIndows 8 은점유율이 낮으니 제외하도록 하겠습니다)

하지만 WindowsForm은 점점 쓰지 않는 기술이고 다른 두개와 방식이 많이 다릅니다. 그래서 저는 WindowsForm은 하지 않겠습니다.

제가 주로 할 것은 Uiversal App(Windows 10) 인데요 이 방식은 Xaml 이라는 Markup 언어를 사용하고 그 방식이 비슷합니다.

최근 Microsoft에서도 밀고 있는 언어이기도 하고 Universal App을 하게 되면 WPF나 Windows 8 사용하는데 큰 지장이 없습니다.

또한 이것을 통해서 익혀 두면 Web에서 사용하는 ASP .NET을 쉽게 익히실수 있을 것 입니다.(사실 이거 두개만해도 Windows 8 app도 가능합니다)

그래서 프로젝트를 WIndows 10 Universal App을  한번 만들어 보겠습니다.

우리가 콘솔환경에서 했던것을 GUI로 한번 복습한후 다음 진도로 넘어갈게요!

그럼 다음 포스팅때 봐요~~!

자 우리 까만화면 시리즈의 마지막 행맨을 해봅시다!

제가 생각한 방법은 

1. 클래스를 하나 더 만들겠습니다! 컴퓨터 클래스를 만들어서 문제들을 몇개 넣을거에요! 배열로요!

2. 이겼습니다 졌습니다 나오는 메서드와 행맨의 상태를 보여주는 메서드를 만들겠습니다.

3. 레벨이 5이상일때 끝내는 매서드를 만들겠습니다.

4. 레벨이 5면 끝내고 아니라면 입력한 문자를 바꾸어주는 메서드를 만들겠습니다.

5. 주 클래스로 와서 String을 입력받고 그 값이 에러가 아니라면 리턴해주는 메서드를 만들겠습니다.

6. 마지막으로 While문으로 이기거나 지기까지 계속 하게 만드는 메서드를 만들겠습니다.

Computer.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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace Hangman  // 크게 입력 문제인지, 비교문제인지, 알아 보아야 함
{
    class Computer
    {
        private String[] m_key =
        {
            "Boolean",
            "Integer",
            "String",
            "System",
            "Thread",
            "StringBuffer",
            "Package",
            "Class",
            "Object",
            "Void"
        };
        public StringBuilder m_user;  //유저가 넣은 글자
        public String m_word;        // 컴퓨터가 랜덤으로 넣은 글자
        private int m_level;          // 맞거나 틀리거나 한 레벨
        private int m_index;          // 크기를 알아야 그 크기 만큼 -로 채울수 있다
        public Computer()            //생성자를 통해서 변수 초기화
        {
            Random myrand = new Random();
            m_index = myrand.Next(m_key.Length-1); //랜덤으로 값을 인덱스에 넣고 번째 찾음
            m_word = m_key[m_index];               //나의 키 중에 나의 인덱스를 가진값을 word에 넣음 예 0은 boolean
            m_level = 0;                           //레벨은 9부터 시작
 
            m_user = new StringBuilder();         //유저가 넣은 값을 stringbuilder 에 넣음
           
            
            for(int i=0;i<m_word.Length;i++)       //word에 길이 만큼 -생성
            {
                m_user.Append('_');
            }
 
        }
        public void showEndMsg(Boolean isWin) // true false값을 통해서 메세지 생성 함수
        {
            String msg;
 
            if(true == isWin)
            {
                msg = "사형수를 구하셨습니다";
            }
            else 
            {
                msg = "사형이 집행 되었습니다.";
            }
            Console.WriteLine(msg);
        }
        public void showHangMan()           //레벨을 가지고 행맨을 보여주는 함수
        {
            Console.WriteLine("★ 집행 단계 ★");
            switch (m_level)
            {
                case 0:
                    Console.WriteLine("    ┌──┐");
                    Console.WriteLine("    ▲    ┃");
                    Console.WriteLine("          ┃");
                    Console.WriteLine("          ┃");
                    Console.WriteLine("          ┃");
                    Console.WriteLine("          ┃"); ;
                    break;
                case 1:
                    Console.WriteLine("    ┌──┐");
                    Console.WriteLine("    ▲    ┃");
                    Console.WriteLine("┌─┼─  ┃");
                    Console.WriteLine("          ┃");
                    Console.WriteLine("          ┃");
                    Console.WriteLine("          ┃");
                    break;
                case 2:
                    Console.WriteLine("    ┌──┐");
                    Console.WriteLine("    ▲    ┃");
                    Console.WriteLine("┌─┼─┐┃");
                    Console.WriteLine("          ┃");
                    Console.WriteLine("          ┃");
                    Console.WriteLine("          ┃");
                    break;
                case 3:
                    Console.WriteLine("    ┌──┐");
                    Console.WriteLine("    ▲    ┃");
                    Console.WriteLine("┌─┼─┐┃");
                    Console.WriteLine("    ┃    ┃");
                    Console.WriteLine("          ┃");
                    Console.WriteLine("          ┃");
                    break;
                case 4:
                    Console.WriteLine("    ┌──┐");
                    Console.WriteLine("    ▲    ┃");
                    Console.WriteLine("┌─┼─┐┃");
                    Console.WriteLine("    ┃    ┃");
                    Console.WriteLine("┌─┼─  ┃");
                    Console.WriteLine("          ┃");
                    break;
                case 5:
                    Console.WriteLine("    ┌──┐");
                    Console.WriteLine("    ▲    ┃");
                    Console.WriteLine("┌─┼─┐┃");
                    Console.WriteLine("    ┃    ┃");
                    Console.WriteLine("┌─┼─┐┃");
                    Console.WriteLine("          ┃");
                    break;
                default:
                    Console.WriteLine("  ┌───┐");
                    Console.WriteLine("      ┃");
                    Console.WriteLine("      ┃");
                    Console.WriteLine("      ┃");
                    Console.WriteLine("      ┃");
                    Console.WriteLine("      ┃");
                    break;
 
            }
        }
        private int checkEnd()              
        {
            String t_msg;
 
            t_msg = m_user.ToString();
            
            if(t_msg.Equals(m_key[m_index]))
            {
                return 1;
            }
 
            if(5<=m_level)
            {
                return 2;
            }
            return 0;
        }
        public int checkLevel(char msg)
        {
            Boolean find = false;
 
            for(int i =0;i<m_key[m_index].Length;i++)
            {
                if(m_key[m_index][i]==msg)
                {
                    if('_' == m_user[i]) //중복을 막아준다
                    {
                        m_user[i]=msg;
                        find = true;
                        break;
                    }
                }
            }
            if(false == find)
            {
                m_level++;
            }
            return checkEnd();
        }
    }
}
 
cs

Program.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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace Hangman
{
    class Program
    {
        Computer m_com;
        public void Hangman()
        {
            m_com = new Computer();
        }
        public char getKey()
        {
            String msg;
 
            char a;
            msg = "error";
         
            Console.WriteLine("알파벳을 입력하세요:");
            msg = Console.ReadLine();
         
            a = msg[0];
            return a;
        }
        public void run()
        {
            int result;
            char msg;
 
            while (true)
            {
                Console.WriteLine(" "+m_com.m_user);
                msg = getKey();
                result = m_com.checkLevel(msg);
 
                m_com.showHangMan();
                if(1==result)
                {
                    m_com.showEndMsg(true);
                    break;
                }
                else if(2==result)
                {
                    m_com.showEndMsg(false);
                    break;
                }
            }
           
 
        }
        static void Main(string[] args)
        {
            Program m = new Program();
            m.Hangman();
            m.run(); 
        }
    }
}
 
cs
프로그램 모습




음.. 제가 아마 처음 영어공부를 할때 였던거 같아요

아버님 회사 직원중 한분이 영어를 너무 잘하셔서 저희에게 영어를 가르쳐 주셨는데 전 그때 행맨을 알았어요

전 단순히 글자 맞추는 건줄 알았는데 왠걸? 나중에 알아보니 못 마출 경우 뭔가는 매다는? 무시무시한 게임이었어요

네 글자맞추기! 하지만 맞추지 못하면? 무엇인가를 매다는? 게임 행맨 을 해볼게요!






그전에 알아야 할 것들 첫번째는?


1. String 변수의 할당과 초기화


먼저 String을 해보면 string과 String 두개가 있습니다다 무슨차이일까요? 결론은 똑같습니다다.

System.String allias를 쓴다고 하는데 이런거 몰라도 되고 그냥 마음에 드는 것을 쓰자구요!

초기화는

String a;           //초기화 하지않기

String a = null    //null로 초기화

String a = "haha" //haha로 초기화 등

이렇게 쓸수 있습니다. 지금까지는 항상int로 바꾸었는데 String은 그냥 변수선언하고 따옴표안에 써 넣으면 됩니다.!


2. 두 String 비교하기


행맨을 하기 위해서는 두개의 String 변수를 비교해야 합니다. 그래서 저희는 .Equal 메서드를 사용할 것입니다.

이 문자열이 같은지 안같은지 알려주는 메서드이구요 같으면 true를 다르면 false를 돌려주면서 값이 같은지 안같은지 가르쳐 줍니다.

사용방법은

String a1 = "haha"

String a2 = "haha"

if(a1.Equals(a2))  //Ture로 반환 합니다.

{

정답

}

이렇게 사용하시면 됩니다.!

여기서 볼 것은 Haha와 haha는 다른데요 C#은 대문자 소문자 구별을 하기 때문입니다. 만약 아 그런거 필요없다! 하시는 분은

a.Equals(b, StringComparison.OrdinalIgnoreCase); 이런식으로 해주시면 됩니다.!


3. String 과 StringBuilder


이미 만들어진 문자열에 문자를 추가하거나 중간에 문자를 삽입하는 이렇게 조물딱 조물딱 하려면 String 객체로는 하기 어렵습니다.

그래서 나온것이 바로 StringBuilder 입니다.간단한 것은 String을 사용하고 복잡한 것은 StringBuilder를 사용하면 됩니다!

선언은

StringBuilder str = new StringBuilder();

문자열의 길이는?

str.length;

3번째 문자는?

str.Chars(2);

3번째 문자를 k로 변경하려면?

str[3] = k;

끝에 ab를 추가하면?

str.append("ab");

2번째에 '@'를 첨가하면?

str.insert(1,'@');

등등 정도 알아두면 된다.


4. 클래스의 변수와 메서드의 접근제어


처음 클래스를 배울때 Public Private,protected 에 대해서 배웠는데 public만 하고 나머지는 다음에 한다고 했었죠?

일단 protected는 다음에 알도록 하고 오늘은 private만 해보도록 합시다. public은 앞에서 말했다 시피 어디에서나 접근가능합니다.

public 공공의 라는 단어와 같이 그런 뜻을 지닙니다 그럼 private는? 네 그 메서드를 선언한 클래스 내에서만 사용가능한 메서드 입니다.

C#은 앞에 아무것도 붙이지 않으면 자동으로 private가 되므로 공공연하게 필요할때는 public을 선언해 봅시다. 예를 들어 볼까요? 주석을 봅시다!


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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace CallTest
{
    class Program
    {
        public Program()
        {
 
        }
        private void getValue()
        {
 
        }
        static void Main(string[] args)
        {
            
            t1 t = new t1();
            t.ptest();       //사용 가능
            t.priTest();     //사용 불가
 
        }
    }
    class t1
    {
        public t1()
        {
 
        }
        public int ptest()
        {
            int a=0;
            a++;
            
            return a;
        }
        private int priTest()
        {
            int b = 0;
            b++;
            return b;
        }
    }
}
 
cs

자 이정도면 행맨을 만들기에 충분히 안것 같습니다! 이 게임을 만든후 드디어!GUI를 하도록 하니 마지막 까지 힘냅시다!



+ Recent posts