다음을 통해 공유


잉크 블로그 웹사이트 샘플

Ink Blog 샘플 애플리케이션은 잉크 입력 기능을 갖춘 관리형 UserControl 클래스를 생성하고, 그 컨트롤을 Microsoft Internet Explorer에 호스팅하는 방법을 보여 줍니다. 또한 이 샘플에서는 HTTP를 사용하고 서버에서 잉크를 유지하여 네트워크를 통해 잉크 데이터를 보내는 한 가지 기술을 보여 줍니다.

메모

이 샘플을 실행하려면 ASP.NET 설치된 Microsoft IIS(인터넷 정보 서비스)가 있어야 합니다. 컴퓨터에서 ASP.NET 애플리케이션을 실행하는 데 필요한 요구 사항을 컴퓨터에서 충족하는지 확인합니다.

 

메모

Microsoft Windows XP Tablet PC Edition Development Kit 1.7이 설치된 태블릿이 아닌 PC 컴퓨터에서 이 샘플을 실행하면 잉크 제목에 대한 텍스트 인식 기능이 작동하지 않습니다. 태블릿 PC SDK 1.7이 설치된 태블릿이 아닌 PC 컴퓨터에 인식기가 없기 때문에 이 문제가 발생합니다. 나머지 애플리케이션은 설명된 대로 수행됩니다.

 

개요

잉크 블로그 샘플은 잉크 활성화된 웹로그를 생성합니다. InkBlogWeb은 ASP.NET 애플리케이션입니다. 잉크 항목은 ASP.NET 페이지에서 참조되는 사용자 컨트롤을 통해 수행됩니다.

사용자 컨트롤은 태블릿 PC 플랫폼 구성 요소가 클라이언트 컴퓨터에 설치되어 있는지 여부를 검색합니다. 이 경우 사용자 컨트롤은 웹 페이지에 두 개의 잉크 사용 영역을 사용자에게 표시합니다. 하나는 블로그 항목의 제목을 잉크로 입력하고 다른 하나는 항목 본문에 대한 것입니다. 태블릿 PC 플랫폼 구성 요소가 설치되지 않은 경우 사용자에게 항목의 제목과 본문에 대한 표준 텍스트 상자 컨트롤이 제공됩니다.

사용자가 항목 만들기를 마치면 단추, 블로그 추가를 클릭하면 저장소를 위해 웹 서버로 게시물이 전송됩니다. 서버에서 애플리케이션은 타이틀 텍스트와 게시 날짜뿐만 아니라 GIF(그래픽 교환 형식) 파일에 대한 참조를 저장합니다. 서버에 저장된 GIF 파일은 본문의 잉크 데이터가 포함된 강화된 GIF 파일로 저장되어 있습니다. 강화된 GIF 형식에 대한 자세한 내용은 잉크를 HTML에 저장을 참조하세요.

InkBlog 솔루션에는 InkBlogControls 프로젝트와 InkBlogWeb 프로젝트라는 두 개의 프로젝트가 있습니다.

InkBlogControls 프로젝트

InkBlogControls 프로젝트는 웹 페이지에서 잉킹을 활성화하는 사용자 컨트롤에 대한 코드를 포함하는 UserControl 프로젝트입니다. 이 컨트롤의 코드인 InkArea 컨트롤은 InkArea.cs 파일에 있습니다.

InkArea 클래스는 UserControl 클래스에서 상속됩니다. InkArea 컨트롤의 생성자는 도우미 메서드 CreateInkCollectionSurface을 호출합니다.

public InkArea()
{
    // Standard template code

    try
    {
        inputArea = CreateInkCollectionSurface();
    }
    catch (FileNotFoundException)
    { 
        inputArea = new TextBox();
        ((TextBox)inputArea).Multiline = true;
    }

    inputArea.Size = this.Size;

    // Add the control used for collecting blog input
    this.Controls.Add(inputArea);
}

CreateInkCollectionSurface 메서드는 InkCollector 클래스의 인스턴스를 생성하려고 시도하여 클라이언트에서 태블릿 PC 잉킹 구성 요소를 사용할 수 있는지 여부를 결정합니다. CreateInkCollectionSurface 메서드 호출이 성공하면 메서드는 Panel 개체를 컨트롤로 반환합니다.

protected Control CreateInkCollectionSurface()
{
    try
    {
        Panel inkPanel = new Panel();
        inkPanel.BorderStyle = BorderStyle.Fixed3D;
        inkCollector = new InkCollector(inkPanel);
        ((InkCollector)inkCollector).Enabled = true;
        return inkPanel;
    }
    catch
    {
        throw;
    }
}

잉킹 플랫폼 파일을 찾을 수 없어 생성자가 실패하는 경우 InputArea 컨트롤은 TextBox 컨트롤로 인스턴스화되며, 이는 InkCollector 컨트롤가 아닙니다. 그런 다음 생성자는 컨트롤의 크기를 부모 사용자 컨트롤의 크기로 조정하고 부모의 Controls 컬렉션에 추가합니다.

InkArea 컨트롤 클래스는 InkData, TextData 및 WebEnabled의 세 가지 흥미로운 공용 속성을 구현합니다.

InkData 속성은 읽기 전용이며 클라이언트가 수동 입력을 지원하는 경우 직렬화된 잉크 데이터에 대한 액세스를 제공합니다. 클라이언트가 수동 입력을 지원하지 않는 경우 InkData 속성은 빈 문자열을 가져옵니다. InkData 속성은 도우미 메서드인 SerializeInkData를 호출하여 클라이언트가 수동 입력을 지원하는지 확인합니다.

protected String SerializeInkData()
{
    Debug.Assert(InkEnabled, null, "Client must be ink-enabled");

    // Obtain the ink associated with this control
    Ink ink = ((InkCollector)inkCollector).Ink;

    // Serialize the ink
    if (ink.Strokes.Count > 0) 
    {
        byte[] inkDataBytes = ink.Save(PersistenceFormat.Gif);
        return Convert.ToBase64String(inkDataBytes);
    }

    // Default to returning the empty string.
    return String.Empty;
}

SerializeInkData 메서드에서는 inputAreaControl로 선언되어 있기 때문에, Ink 객체를 가져올 때는 InkCollector로의 캐스트가 필요합니다. Ink 개체에 스트로크가 포함된 경우 잉크 데이터는 inkDataBytes 바이트 배열에 GIF로 저장됩니다(PersistenceFormat 열거형 값을 사용하여 지정됨). 그런 다음 바이트 배열을 Base64로 인코딩된 문자열로 변환하고 이 문자열을 반환합니다.

클라이언트가 인식을 수행할 수 있다고 가정하면 TextData 속성은 잉크 데이터를 필기 인식기로 전달하는 RecognitionResult 개체를 반환합니다. 클라이언트가 잉크를 인식하지 않는 경우 다음 코드와 같이 텍스트 상자 내용이 반환됩니다.

public string TextData
{
    get
    {
        if (this.WebEnabled) 
        {
            return RecognizeInkData();
        }
        else
        {
            return ((TextBox)inputArea).Text;
        }
    }
}

TextData 속성은 다음 코드에 표시된 RecognizeInkData도우미 메서드를 호출하여 인식을 수행합니다. 인식 엔진이 시스템에 있으면 RecognizeInkData 메서드는 RecognitionResult 개체의 TopString 속성이 포함된 문자열을 반환합니다. 그렇지 않으면 빈 문자열을 반환합니다.

protected String RecognizeInkData()
{
    // Obtain the ink associated with this control
    Ink ink = ((InkCollector)inkCollector).Ink;

    if (ink.Strokes.Count > 0) 
    {

        // Attempt to create a recognition context and use it to
        // retrieve the top alternate.
        try 
        {
            RecognizerContext recognizerContext = new RecognizerContext();
            RecognitionStatus recognitionStatus;
            recognizerContext.Strokes = ink.Strokes;
            RecognitionResult recognitionResult = recognizerContext.Recognize(out recognitionStatus);
            if (recognitionStatus == RecognitionStatus.NoError) && ( null != recognitionResult) )
            {
                return recognitionResult.TopString;
            }
        }
        catch (Exception)
        {
            // An exception will occur if the client does not have
            // any handwriting recognizers installed on their system.
            // In this case, we default to returning an empty string. 
        }
    }

    return String.Empty;
}

InkEnabled 속성은 클라이언트 컴퓨터에서 잉킹이 지원되는지 여부를 나타내는 읽기 전용 부울 값입니다.

InkArea 컨트롤 클래스의 또 다른 중요한 공용 멤버는 DisposeResources 메서드입니다. 이 메서드는 내부적으로 Dispose 메서드를 호출하여 사용자 컨트롤에서 활용하는 모든 리소스가 정리되도록 합니다. InkArea 컨트롤을 사용하는 모든 애플리케이션은 컨트롤 사용이 완료되면 DisposeResources 메서드를 호출해야 합니다.

InkBlogWeb 프로젝트

InkBlogWeb 프로젝트는 InkArea 컨트롤을 참조하여 블로깅 기능을 제공하는 웹 설정 배포 프로젝트입니다. 웹 설치 배포 프로젝트에 대한 자세한 내용은 웹 설치 프로젝트 배포을 참조하세요.

블로깅 샘플을 구현하는 .aspx 파일은 Default.aspx 및 AddBlog.aspx. Default.aspx InkBlogWeb 애플리케이션의 기본 페이지입니다. 이 페이지의 코드 숨김 파일은 Default.aspx.cs입니다. 이 페이지는 새 블로그 항목 양식이 포함된 페이지에 대한 링크를 제공하고 기존 블로그 항목을 표시합니다. 이 프로세스는 새 블로그 항목 양식 페이지 AddBlog.aspx의 검토가 끝난 후에 설명됩니다.

AddBlog.aspx 및 코드 숨김 파일 AddBlog.aspx.cs 새 블로그 항목을 만들기 위한 논리 및 사용자 인터페이스 코드를 포함합니다. AddBlox.aspx 다음 예제와 같이 HTML OBJECT 요소를 사용하여 InkBlogControls 프로젝트에서 만든 InkArea 컨트롤 클래스의 두 인스턴스를 참조합니다. 한 인스턴스에는 inkBlogTitle의 id 특성이 있고 다른 인스턴스에는 inkBlogBody의 ID 특성이 있습니다.

<OBJECT id="inkBlogTitle" classid="InkBlogControls.dll#InkBlog.InkArea" width="400" height="48" VIEWASTEXT>``</OBJECT>``<br/>``<OBJECT id="inkBlogBody" classid="InkBlogControls.dll#InkBlog.InkArea" width="400" height="296" VIEWASTEXT>``</OBJECT>

InkBlogControls.dll 어셈블리는 참조하는 .aspx 페이지와 동일한 디렉터리에 있어야 합니다. 웹 설치 배포 프로젝트는 배포 프로젝트에 "InkBlogControls의 주요 출력" 항목이 존재함으로써 이를 보장합니다.

타이틀 컨트롤의 높이가 48픽셀에 불과하여 타이틀에 대한 잉크 한 줄의 진입을 용이하게 합니다. 본문 제어 요소는 여러 줄에 걸치거나 그림이 포함된 더 큰 블로그 항목을 수용할 수 있도록 296픽셀 높이로 설정됩니다.

InkArea 컨트롤은 표준 HTML BUTTON 요소의 onclick 이벤트 처리기를 통해 클라이언트 쪽 스크립트 함수인 AddBlog에 연결됩니다.

<button id="BUTTON1" type="button" onclick="AddBlog()">Add Blog</button>

페이지에는 BlogTitleText, BlogBodyText 및 BlogBodyInkData의 세 가지 숨겨진 INPUT 요소가 포함된 HTML 양식도 있습니다. 이 양식은 블로그 항목 데이터를 서버에 다시 게시하는 데 사용됩니다. AddBlog.aspx 양식에 대해 정의된 포스트백 처리기입니다.

Microsoft JScript<엔터티 type="reg"/>로 작성된 AddBlog 함수는 InkArea 컨트롤에서 블로그 데이터를 추출하고 결과를 서버에 게시합니다.

function AddBlog() 
{
    // Extract the blog's title data as ink and text
    form.BlogTitleText.value  = inkBlogTitle.TextData;
    
    // Extract the blog's body data as ink and text
    form.BlogBodyText.value = inkBlogBody.TextData;
    form.BlogBodyInkData.value = inkBlogBody.InkData;   

    form.submit();
}

데이터가 서버에 도착하면 AddBlog.aspx.cs 코드는 Page_Load 이벤트 처리기를 확인하여 HttpRequest 개체의 Form 속성에 데이터가 포함되어 있는지 확인합니다. 이 경우 다음 코드와 같이 현재 시스템 시간에 따라 파일 이름을 만들고, 양식 데이터를 세 개의 문자열 변수에 넣고, HTML 파일 및 잉크 데이터가 포함된 GIF 파일에 데이터를 씁니다(있는 경우).

if ( (String.Empty != inkBody) )
{           
    // Use helper method to create a GIF image file from ink data 
    CreateGif(imagePath, fileName, inkBody);
    
    // Create an HTML fragment to reference the image file
    content = "<img src=\"Blogs/Images/" + fileName + ".gif\"></img>";
}                
else 
{
    // If no ink data is available create an HTML fragment that contains
    // the blog's text directly.
    content = "<P>" + textBody + "</P>";
}

// Use helper method to create the blog web page on the server
CreateHtm(blogPath, fileName, blogTitle, content);

도우미 메서드에 대한 자세한 내용은 샘플 소스 코드를 참조하세요.

샘플 실행

태블릿 PC SDK 1.7은 기본적으로 잉크 블로그 웹 샘플을 설치합니다. 샘플을 실행하려면 Internet Explorer에서 https://localhost/TabletPCSDK_WebSamples/InkBlogWeb/Default.aspx.으로 이동하세요. Windows Server 2003을 실행하는 경우 컴퓨터 이름을 "localhost"로 대체합니다.

메모

컴파일된 웹 샘플은 SDK에 대한 기본 설치 옵션으로 설치되지 않습니다. 사용자 지정 설치를 완료하고 "미리 컴파일된 웹 샘플" 하위 옵션을 선택하여 설치해야 합니다.

 

또한 .NET을> Microsoft Visual Studio<엔터티 type="reg"/에서 프로젝트를 열고 빌드한 다음 IIS를 실행하는 별도의 컴퓨터에 배포하여 샘플을 실행할 수도 있습니다.

샘플 문제 해결

샘플을 실행하거나 호스팅할 때 어려움을 일으킬 수 있는 세 가지 영역은 사용 권한 및 인식입니다.

권한

샘플에는 새 블로그 항목을 만들려고 하는 계정에 대한 가상 루트 폴더 내의 쓰기 권한이 필요합니다. 기본적으로 태블릿 PC SDK 1.7에 제공된 샘플의 컴파일된 버전에는 이 요구 사항을 충족하도록 설정된 올바른 권한이 있습니다.

제공된 웹 설정 배포 프로젝트를 사용하여 샘플을 빌드하고 배포하는 경우 inkBlogWeb 가상 루트(예: C:\InetPub\WWWRoot\InkBlogWeb)가 가리키는 파일 시스템 폴더에 대한 %MACHINENAME%\Users 그룹 쓰기 액세스 권한을 제공해야 합니다. 사용자 그룹에는 IIS에서 사용하는 익명 계정이 포함되어 있으므로 ASP.NET 애플리케이션에서 파일 시스템에 새 블로그 항목을 쓸 수 있습니다. 대안은 가상 루트에 대한 익명 액세스를 제거하고 인증을 강제하는 것입니다.

인식

블로그 제목에서 잉크를 인식하려면 필기 인식기를 설치해야 합니다. Windows XP Tablet PC Edition 이외의 운영 체제가 있지만 태블릿 PC SDK 1.7이 설치된 컴퓨터에서 InkBlog 애플리케이션에 액세스하는 경우 InkArea 컨트롤에서 잉크로 쓸 수 있지만 인식 엔진은 존재하지 않으며 블로그 항목에 대한 제목은 표시되지 않습니다. 하지만 본문의 잉크 콘텐츠는 여전히 나타납니다.

컴퓨터 구성

컴퓨터에 ASP.NET 및 .NET Framework를 설치한 다음 IIS를 제거하고 다시 설치한 경우 스크립트 맵이 중단되고 ASP.NET 작동하지 않습니다. 이 경우 ASP.NET IIS 등록 도구(Aspnet_regiis.exe -i)를 사용하여 ASP.NET 스크립트 맵을 복구할 수 있습니다.

InkCollector

잉크

잉크 데이터 형식

System.Windows.Forms.UserControl 클래스