블로그 이미지
* Microsoft MVP - Windows Development 2014 ~ 2019 5ring * LINE : kaki104 * facebook : https://www.facebook.com/kaki104 https://www.facebook.com/groups/w10app/ kaki104

카테고리

List All (558)
Xamarin Forms (4)
Bot Framework (19)
Azure (9)
Windows 10 (39)
WPF (3)
Facebook News & Tips (158)
Windows App(Universa.. (84)
Windows 8&8.1 (113)
Windows Phone 8 (42)
Silverlight (37)
HTML5 & MVC4 (16)
Portable Class Library (2)
Uncategorised Tips a.. (3)
Kinect for Windows (2)
ETC (12)
kaki104 Scrap (4)
App News (11)
Total528,595
Today3
Yesterday23

실버라이트4.0 부터 기본적으로 웹켐과 오디오를 기본으로 사용할 수 있는 기능이 추가되어있다.
이 기능을 이용하는 방법을 알아보도록 하자..그런데, 왜 뜬금없이 웹켐에 대한 이야기를 하는 것일까? 다음 강좌에서 촬영한 사진을 WCF RIA Service로 서버로 전송하는 것을 올릴려고 하기 때문이다.


1. 화면보기

일단 기존 화면에 버튼을 하나 추가하고 버튼을 클릭하면 차일드 윈도우를 출력하고, 그 곳에서 웹켐 활성화를 시키고 사진 촬영을 하게 된다. 촬영시작을 누르면 위의 화면 처럼 실버라이트에서 카메라와 오디오에 엑세스를 허용할 것인지를 물어본다.(이렇게 나오도록 만든다고..몇시간 삽질을....나만 어렵게 적용했다는 생각이..쿨럭;;)


WebCam_Child.xaml

<controls:ChildWindow x:Class="SL4_RIA_Sample.WebCam_Child"
           xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
           xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
           xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
           Width="400" Height="300"
           Title="WebCam_Child" Loaded="ChildWindow_Loaded">
    <Grid x:Name="LayoutRoot" Margin="2">
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <!--이미지가 보이는 곳~-->
        <Rectangle Grid.Row="0" Name="rectVideo" Fill="Black" Margin="4" />

        <Button x:Name="CancelButton" Content="닫기" Click="CancelButton_Click" Width="75" Height="23" HorizontalAlignment="Right" Margin="0,12,0,0" Grid.Row="1" />
        <Button x:Name="OKButton" Content="촬영" Click="OKButton_Click" Width="75" Height="23" HorizontalAlignment="Right" Margin="0,12,79,0" Grid.Row="1" />
        <Button x:Name="StartButton" Content="촬영시작" Click="StartButton_Click" Width="75" Height="23" HorizontalAlignment="Right" Margin="0,12,158,0" Grid.Row="1" />
    </Grid>
</controls:ChildWindow>


WebCam_Child.xaml.cs

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace SL4_RIA_Sample
{
    public partial class WebCam_Child : ChildWindow
    {
        private CaptureSource _capture;

        public WebCam_Child()
        {
            InitializeComponent();
        }

        private void ChildWindow_Loaded(object sender, RoutedEventArgs e)
        {
            //캡춰소스 인스턴스
            _capture = new CaptureSource();
            _capture.CaptureImageCompleted += new EventHandler<CaptureImageCompletedEventArgs>(_capture_CaptureImageCompleted);
        }

        void _capture_CaptureImageCompleted(object sender, CaptureImageCompletedEventArgs e)
        {
            //이미지 캡춰가 완료되면 여기로
            WriteableBitmap wb = e.Result;
            //화면에 촬영된 이미지 보여주기
            if (_capture != null)
            {
                _capture.Stop();
                ImageBrush image = new ImageBrush();
                image.ImageSource = wb;
                rectVideo.Fill = image;
            }
        }

        private void OKButton_Click(object sender, RoutedEventArgs e)
        {
            //캡춰 시작
            _capture.CaptureImageAsync();
            //this.DialogResult = true;
        }

        private void CancelButton_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = false;
        }

        private void StartButton_Click(object sender, RoutedEventArgs e)
        {
            Button btn = ((Button)sender);

            if (_capture != null)
            {
                //일단 동작 정지
                _capture.Stop();

                if (btn.Content.ToString() == "촬영시작")
                {
                    //기본 비디오 디바이스를 가지고옴
                    _capture.VideoCaptureDevice = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();
                    //기본 오디오 디바이스를 가지고옴
                    _capture.AudioCaptureDevice = CaptureDeviceConfiguration.GetDefaultAudioCaptureDevice();

                    //비디오 브러쉬 만들고
                    VideoBrush videoBrush = new VideoBrush();
                    videoBrush.Stretch = Stretch.Uniform;
                    videoBrush.SetSource(_capture);

                    //xaml에 있는 사각형을 비디오브러쉬로 채운다
                    rectVideo.Fill = videoBrush;
                    // 사용자에게 인증을 받는 부분 - 이 부분은 폼로드 이벤트에 넣치 않는다. 별도의 이벤트 함수에서 처리하도록

                    // 해야 한다, 않그러면, 사용자에게 인증 받는 창이 뜨지를 안아서 한참을 헤메는 사태가 발생한다는..

                    if (CaptureDeviceConfiguration.AllowedDeviceAccess || CaptureDeviceConfiguration.RequestDeviceAccess())
                    {
                        _capture.Start();
                        btn.Content = "촬영종료";
                    }
                }
                else
                {
                    btn.Content = "촬영시작";
                }
            }
        }
    }
}

2. 다음에는
이 소스에 추가해서 촬영한 사진을 업로드 하는 것에 대해서 적어보도록 하겠다.

Posted by MVP kaki104

간단하게 한가지만 추가할려고 한다.

대량의 데이터를 한번에 불러오는 경우 불러오는데 시간이 오래 걸리고, 그 데이터가 불러오기 전까지는 화면에 출력되는 내용이 없다. 그래서, 주로 사용하는 방식이 페이징 방식인데.. 페이징 방식의 경우에는 모든 데이터를 한번에 볼 수 없기 때문에..울나라 사람들이 조아하는 엑셀로 한방에 출력하기시에 문제가 있다..

그런 문제의 해답으로 점진적 로드 방식이 있는데, 한번에 20-40개 정도의 로우만을 여러번 불러오는 것이다. 그럼 일단 화면에 데이터가 출력되어있기 때문에 프로그램이 느리다는 이야기는 듣지 않을 것이고, 좀 시간을 두고 기다리면 모든 데이터가 어느세 꽉~ 차고, 마음도 한결 가벼워 질 것이다.


1. DomainService1.cs 수정
일단 WCF RIA에 함수를 하나 추가한다. 조건을 인수로 받아서 해당대는 데이터를 ID 순으로 소트해서 반환하는 함수이다.
여기서 중요한 사항은 꼭 orderby문이 포함되어 있어야 한다는 것이다.

//날짜를 인수로 받아서 해당 조건에 만족하는 데이터만 반환한다.
public IQueryable<Order> GetOrders_By_Condition(DateTime FromDate, DateTime ToDate)
{
    var query = from order in this.ObjectContext.Orders
                where order.Order_Date >= FromDate && order.Order_Date <= ToDate
                orderby order.Order_ID
                select order;

    return query.AsQueryable();
}

작성이 완료되었으면 웹 프로젝트를 빌드한다. 빌드를 해줘야 추가된 함수를 실버라이트에서 사용 할 수 있다.


2. SL4_RIA_Sample 프로젝트에 Silverlight User Control을 하나 추가한다.
이름은 Orders.xaml로 한다.
Data Sources 메뉴를 클릭한다.

Order에 콤보박스 다운 버튼을 클릭하면 위와 같이 나온다.(한번에 앙나오면 다시 컴파일 하고 다시 열어본다) 여기서 GetOrders_By_ConditionQuery를 선택하고 드레그 드롭으로 Orders.xaml에 컨트롤을 만들고, 약간의 작업을 더해주어 아래와 같은 화면을 만든다.

일단 컨트롤을 만들어서 화면에 출력될 수 있는 기본은 만들었고, 실버라이트가 시작되었을 때 맨 처음으로 이 화면을 사용하도록 수정한다.

App.xaml.cs
private void Application_Startup(object sender, StartupEventArgs e)
{
     this.RootVisual = new Orders();
}

실행해보자

데이터가 1991년 부터 1995년까지 있기 때문에..1년간의 날짜를 입력한 후 Load버튼을 눌러서 조회를 해봤다.
모든 데이터가 한번에 쫘악 펼쳐지며 보인다. 아주 만은 데이터는 아니라서 빠르게 표시가 된다. 그러나 날자를 1995년까지로 변경하고 조회하면 처음에 화면 뜨는 속도가 무척 느리다는 것을 알 수 있다.


3. 점진적 로드 방식으로 변경

Orders.xaml

//WCF RIA Service 데이터 컬렉션을 로드, 필터링, 그룹화 및 정렬하기 위한 개체

//http://msdn.microsoft.com/ko-kr/library/system.windows.controls.domaindatasource_members(v=vs.91).aspx


<riaControls:DomainDataSource AutoLoad="False"
                              d:DesignData="{d:DesignInstance my:Order, CreateList=true}" Height="0"
                              LoadedData="orderDomainDataSource_LoadedData"
                              Name="orderDomainDataSource" LoadSize="40" LoadInterval="00:00:04"
                              QueryName="GetOrders_By_ConditionQuery"
                              Width="0" Margin="0,0,400,29">
    <riaControls:DomainDataSource.DomainContext>
        <my:DomainService1 />
    </riaControls:DomainDataSource.DomainContext>
    <riaControls:DomainDataSource.QueryParameters>
        <riaControls:Parameter ParameterName="FromDate" Value="{Binding ElementName=fromDateTextBox, Path=Text}" />
        <riaControls:Parameter ParameterName="ToDate" Value="{Binding ElementName=toDateTextBox, Path=Text}" />
    </riaControls:DomainDataSource.QueryParameters>
</riaControls:DomainDataSource>

위의 LoadSize와 LoadInterval을 이용하면 한번에 몇개씩 몇 초후에 가지고 오는 지를 지정해서 순서대로 데이터를 가지고 올 수 있다.

(시작 - 스크롤 바의 크기를 보면 된다.)

(로딩 중 - 스크롤 바의 크기가 줄어 들었다)



4. WCF로 전송되는 데이터량 늘리기
한번에 전송되는 양이 생각보다 적어서, 좀더 늘릴 필요가 있을 때 사용한다.

Web.config

  <system.serviceModel>
    <domainServices>
      <endpoints>
        <add name="OData" type="System.ServiceModel.DomainServices.Hosting.ODataEndpointFactory, System.ServiceModel.DomainServices.Hosting.OData, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
      </endpoints>
    </domainServices>
    <behaviors>
      <serviceBehaviors>
        <behavior name="">
          <serviceMetadata httpGetEnabled="True" />
          <serviceDebug includeExceptionDetailInFaults="True" />
          <dataContractSerializer maxItemsInObjectGraph="655360" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>


5. 실버라이트는
스트림라인드 오퍼레이션이 기본이기 때문에, 모든 데이터를 한번에 다 불러와야 보여지는 그런 화면은 좋은 화면이 아니다. 개발시에는 꼭 참고 하기 바란다. 그리고, 추가 강의 요청이 없어서..그냥 생각 날때 마다 하나씩 올려 놓을려고 한다.(요청은 환영)

Posted by MVP kaki104

지난번에 이어서 매우 간단한 CRUD 하는 방법을 설명하려고 한다. 최대한 간단하게 하기 위해서 타이틀리 커플드(tightly coupled)로 코딩을 하는 걸로 정했다. 나중에 문의가 들어온다면 MVVM을 적용한 루즐리 커플드(loosely coupled) 방식으로 변경하도록 하겠다.


1. 디자인 변경
화면의 상단에 공간을 좀 주고, 그 곳에 버튼을 3개 배치했다. 버튼의 이름은 Add, Update, Remove이다.


디자인을 변경하면 거의 50%는 한 셈이다. 이제 각 각의 버튼에 약간의 코딩을 하도록 하겠다.


2. CRUD 코딩하기
버튼을 더블클릭해서 이벤트를 만들어보자. Button_Click이란 이름의 이벤트가 하나 만들어지면 그걸 나머지 2개의 버튼에도 같이 붙여버린다. 그리고 코딩을 살짝한다.

using SL4_RIA_Sample.Web;


private void Button_Click(object sender, RoutedEventArgs e)
{
    Button btn = (Button)sender;
    //Order는 DTO(Data Transfer Object)로 WCF RIA에서 자동으로 만들어준 것이다. 이걸 사용하려면

    //SL4_RIA_Sample.Web를 써주기만 하면 된다.           

    Order order;

    switch (btn.Content.ToString())
    {
        case "Add":

            //새로운 레코드를 추가하기 위해서는 그냥 새로운 order를 생성해서 추가한 후에 SubmitChanges()만 호출하면 된다.
            order = new Order();
            orderDomainDataSource.DataView.Add(order);
            break;
        case "Update":

            //SubmitChanges()가 실행되면 Insert, Update, Delete가 모두 적용된다.

            //RejectChanges()는 지금까지 수정된 사항을 모두 취소한다.
            orderDomainDataSource.DomainContext.SubmitChanges();
            break;
        case "Remove":

            //삭제는 단지 DataView에서 삭제하려는 Order를 지우기만 하면 된다.
            if (orderDomainDataSource.DataView.CurrentItem != null)
            {
                order = orderDomainDataSource.DataView.CurrentItem as Order;
                orderDomainDataSource.DataView.Remove(order);
            }
            break;
    }
}

3. 변경된 내용 조회
리플로 문의 주신 내용인데.. 데이터베이스가 내가 변경하지 않고 다른 사람이나 프로시저에서 변경된 경우에 새로 조회를 해도 변경된 내용이 바로 반영이 앙된다는 것인데.. 이것은 LoadBehavior에 대한 처리를 해주면 쉽게 해결 할 수 있다.

WCF RIA Control은 LoadBehavior를 기본적으로 KeepCurrent로 지정되어있다.

LoadBehavior는 데이터를 로드했을때 현재 내가 가지고 있는 데이터와 새로 불러온 데이터를 어떻게 처리 할지를 지정하는 것으로 KeepCurrent(현재 가지고 있는 데이터 유지), MergeIntoCurrent(현재 가지고 있는 데이터를 새로 가지고 온 데이터와 머지), RefreshCurrent(현재 데이터를 새로운 데이터로 몽땅 교체)의 3가지 방법을 제공한다.

이 LoadBehavior를 지정하기 위해서는 몇가지 방법이 있는데, 현재 소스에는 DomainDataSource라는 컨트롤을 사용하고 있고 그 컨트롤에서 지정 방법은 LoadingData 이벤트를 추가하고,

private void orderDomainDataSource_LoadingData(object sender, LoadingDataEventArgs e)
{
    e.LoadBehavior = System.ServiceModel.DomainServices.Client.LoadBehavior.RefreshCurrent;
}

위와 같이 코딩을 해주면 된다.

4. 이번에는 여기 까지만 올리겠다.
추가로 요청이 올라오면 더 자세한 강좌를 올리도록 하겠다.


Posted by MVP kaki104

실버라이트 4에 대한 기본적인 사항을 먼저 한번 쭈욱 정리를 하고 실버라이트 5로 넘어가야 할 것 같아서, 일단 초 간단 예제를 만들었다. 이 예제에 사용된 기술은 딱 2가지이다. 실버라이트4와 WCF RIA Service,

WCF RIA Service 설치는 http://www.silverlight.net/getstarted/riaservices/
이 페이지에 가면 3개의 링크가 있고, 3개를 모두 다운로드 받은 후 설치하면 된다.
WCF RIA가 올해 초까지만 해도 참 좋았는데..으흠..머 아직도 좋다..하하;;


1. 전체 레이아웃
1-1. 실버라이트 프로젝을 만든다.
1-2. 서버에 엔티티 프레임웍을 붙인다.
1-3. 데이터베이스를 연결한다.
1-4. 테이블에 기초한 엔티티를 만든다.
1-5. 컴파일 한다
1-6. WCF RIA(Domain Service)를 추가한다.
1-7. 컴파일 한다.
1-8. MainPage.xaml을 열어서 만들어진 컨텍스트를 드래그 드롭한다.
1-9. 실행한다.

무지 간단하다. 아마 한 10분이면 똑같이 만들 수 있을 것이다. 하지만 기능은 막강하다
물론 진짜 프로젝트에서 사용할려면 여러가지 추가적인 작업들이 들어가지만 그래도 좋다.
일단 만들어보고 더 필요한 부분이 있으면 요청이 있는 부분에 대해서만 추가 작업을 해서 올리겠다.


2. 실버라이트 프로젝을 만든다.
만드는 부분은 생략한다.

이름은 간단하게 정했다. 중요한 부분은 아래에 있는 Enable WCF RIA Services를 꼭 체크 해야한다는 것이다.


3. 서버에 엔티티 프레임웍을 붙인다.
서버 프로젝에서 Add -> New Item을 선택해서 Entity Data Model을 추가한다.

이름은 간단하게 기본 이름을 사용했다.


4. 데이터베이스를 연결한다.
기존 데이터베이스에 연결을 해서 모델을 만들 수 있는 기능을 선택한다.

여기서는 Compact 데이터베이스 파일을 사용한다. Compact 4.0을 설치하면 셈플DB인 Northwid.sdf 파일이 존재한다.
꼭 이 파일이 아니더라도 기존에 가지고 있던 데이터베이스 파일도 사용 가능하다.

여기서 Northwid.sdf파일을 선택하고 Next~

선택한 데이터베이스에서 테이블, 뷰, 프로시저 목록을 보여주고 자동으로 모델을 만들 수 있다. 여기서는 공짜니까 모든 테이블을 선택한다.
추가적으로 Pluralize or sigularize generated object names라는 것도 체크해준다. 그리고 finish

위의 그림이 자동으로 모델을 만들어 준 그림이다. 일단 여기까지 되었으면 꼭 F6키를 눌러서 컴파일을 해준다.


5. WCF RIA Service(Domain Service)를 추가한다

웹 프로젝트에서 Add -> New Item -> domain이란 이름으로 검색하면 Domain Service라는 것이 나온다. 이것이 바로 WCF RIA Service이다.

Add버튼을 누르면

위와 같은 화면이 나온다. 역시 공짜니까 다 선택한다. 오른쪽 체크 박스는 CRUD를 하겠냐는 것이다. 나중에 예제를 위해서라도 그냥 체크 하자 중요한 부분은 Generate associated classes for metadata에 체크를 해준다는 것이다.


여기까지 했을 때 완성된 솔루션 익스플로러의 모습이다.

또 다시 F6키를 눌러서 빌드를 하자


6. MainPage.xaml을 열어보자.
그리고 왼쪽으로 보면 Data Sources라는 것이 보이게 된다. (뜨는데 시간이 좀 걸린다)
이것이 WCF RIA Service를 사용 했을 때만 나오는 것으로 서버에서 만들어진 Context를 그냥 바로 드래그 드롭으로 사용 할 수 있도록 만들어 주는 것이다.

위의 내용 중에서 Order라는 것을 드래그 드롭으로 MainPage.xaml 위에 올려 놓고 위치를 조정해서 이쁘게 만든다.

그냥 올려다 놓기만해두 모든 필드의 내용들이 자동으로 데이터 그리드로 만들어진다. 얼마나 멋진 모습인지 흐흐

이제 마지막으로 실행 해보자 F5키를 눌러서 내용이 뜨는지를 보자

맨 처음에는 데이터가 뜨는데 시간이 약간 걸린다. 생각보다 Order테이블에 데이터가 좀 있다. 어차피 비동기 방식으로 가지고 오는 것이기 때문에 약간 기다리면 다 가지고 온다.


7. 초간단 프로젝트를 하나 만들었다.
하지만 여기서 조금만 더 손보면 바로 멋진 프로그램이 된다.
추가적으로 궁금한 사항, 추가 기능 등등을 많이 적어 주면 하나씩 기능을 보강해 보도록 하겠다.

Posted by MVP kaki104

실버라이트로 프로그램을 만들 때 가끔 나오는 오류인데..구글에서 찾아 봤을 때 거의 해결 방법을 찾을 수 없다.

[Arg_COMException]
Arguments:
Debugging resource strings are unavailable. Often the key and arguments provide sufficient information to diagnose the problem. See http://go.microsoft.com/fwlink/?linkid=106663&Version=5.0.60401.00&File=mscorlib.dll&Key=Arg_COMException

   at MS.Internal.XcpImports.CheckHResult(UInt32 hr)
   at MS.Internal.XcpImports.SetValue(IManagedPeerBase obj, DependencyProperty property, DependencyObject doh)
   at MS.Internal.XcpImports.SetValue(IManagedPeerBase doh, DependencyProperty property, Object obj)
   at System.Windows.DependencyObject.SetObjectValueToCore(DependencyProperty dp, Object value)
   at System.Windows.DependencyObject.SetEffectiveValue(DependencyProperty property, EffectiveValueEntry& newEntry, Object newValue)
   at System.Windows.DependencyObject.UpdateEffectiveValue(DependencyProperty property, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, ValueOperation operation)
   at System.Windows.DependencyObject.SetValueInternal(DependencyProperty dp, Object value, Boolean allowReadOnlySet, Boolean isBindingInStyleSetter)
   at System.Windows.Controls.Control.set_DefaultStyleKey(Object value)
   at System.Windows.Controls.TextBox..ctor()
   at MS.Internal.CoreTypes.GetCoreWrapper(UInt32 typeId)
   at MS.Internal.ManagedPeerTable.EnsureManagedPeer(IntPtr unmanagedPointer, Int32 typeIndex, Type type, Boolean preserveManagedObjectReference)
   at MS.Internal.XcpImports.ConvertDO(IntPtr doPointer, Int32 typeIndex, Boolean releaseObjectReference)
   at MS.Internal.XcpImports.ConvertType(CValue outVal, Int32 typeIndex, Boolean releaseObjectReference, Boolean deleteBuffer, IManagedPeerBase fromObject)
   at MS.Internal.XcpImports.ConvertCValueForManagedWithType(Type propertyType, CValue& outVal, Int32 outDOType, Boolean releaseObjectReference, Boolean deleteBuffer, IManagedPeerBase fromObject)
   at MS.Internal.XcpImports.GetValue(IManagedPeerBase managedPeer, DependencyProperty property)
   at System.Windows.RoutedEventArgs.get_OriginalSource()
   at Telerik.Windows.Controls.RadWindow.OnLostFocus(RoutedEventArgs e)
   at System.Windows.Controls.Control.OnLostFocus(Control ctrl, EventArgs e)
   at MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, Int32 actualArgsTypeIndex, String eventName, UInt32 flags)

문제점(the point at issue)
바인딩 데이터를 자동으로 처리하면서 이상한(?) 데이터를 넣을려고 하는 경우 발생할 확율 높음

해결책(a solution: perhaps)
바인딩 되는 데이터를 object형으로 Type을 바꾸어 주고 테스트를 해본다.
binding property change to object type.

내 경우에는 int? type 데이터를 20개 정도 바인딩으로 사용하고 있었는데, 지속적으로 위의 에러가 발생해서..엄청난 괴로움을 당하고 있었는데..object로 변형을 한 후에는 오류를 발생 시킬려고 일부러 이것 저것 눌러도 잘 발생을 하지 않는다.(그래도 100% 발생하지 않는 것은 아님)

'Silverlight > ETC' 카테고리의 다른 글

Prism 4.0 Tips  (0) 2012.06.13
Telerik Report Tips  (2) 2012.06.08
Rx, Linq Tips  (0) 2012.05.04
Silverlight Standard Tips  (0) 2012.04.27
Twitter Client Lecture(강좌 목록) by Silverlight 5  (0) 2012.01.05
[Arg_COMException] error solution: perhaps  (4) 2012.01.04
Posted by MVP kaki104

티스토리 툴바