Windows CE 6.0에서는 따로 화면 캡쳐를 지원하지 않습니다. 프로그래밍 문서를 작성하거나, 사용설명서를 만들 때 캡쳐 화면이 필요하여, 다음과 같은 캡쳐 코드를 넣었습니다.

using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Imaging;

namespace NameSpace {
    public class Copy {

        enum RasterOperation : uint { SRC_COPY = 0x00CC0020 }

        [DllImport("coredll.dll")]
        static extern int BitBlt(IntPtr hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, RasterOperation rasterOperation);

        [DllImport("coredll.dll")]
        private static extern IntPtr GetDC(IntPtr hwnd);

        [DllImport("coredll.dll")]
        private static extern int ReleaseDC(IntPtr hwnd, IntPtr hdc);

        public static void CopyThere() {
            Rectangle bounds = Screen.PrimaryScreen.Bounds;
            IntPtr hdc = GetDC(IntPtr.Zero);
            Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height, PixelFormat.Format16bppRgb565);
            using (Graphics graphics = Graphics.FromImage(bitmap)) {
                IntPtr dstHdc = graphics.GetHdc();
                BitBlt(dstHdc, 0, 0, bounds.Width, bounds.Height, hdc, 0, 0,
                RasterOperation.SRC_COPY);
                graphics.ReleaseHdc(dstHdc);
            }
            string time = DateTime.Now.ToString("yyyyMMddHHmmss");
            bitmap.Save(time + "screenshot.jpg", ImageFormat.Jpeg);
            ReleaseDC(IntPtr.Zero, hdc);
        }

        internal static void SetCopy(Form form) {
            form.KeyPreview = true;
            form.KeyDown += new System.Windows.Forms.KeyEventHandler(Copy.Form_KeyDown);
        }

        internal static void Form_KeyDown(object sender, KeyEventArgs e) {
            if (e.KeyCode == Keys.F23) { //여기에 캡쳐를 하기 위한 물리 키 값를 넣으면 됩니다.
                Copy.CopyThere();
            }
        }
    }
}

위의 클래스를 구현한 후, 캡쳐 기능이 필요한 Windows Form에서 CopyThere(this) 메소드를 넣고, 실제 실행 중 지정한 키를 누르면 가장 상위 디렉토리에 스크린샷 사진이 저장됩니다.

.NCF에서는 DataGridView가 없고, DataGrid만이 있습니다.

이 DataGrid를 그릴 때 각각의 Cell 형태는 TextBox의 형태를 띄므로, 왼쪽 정렬이 기본 값입니다.

 

먼저, TextBox에서 오른쪽 정렬을 구현하려면.

- 희안하게도 TextBox 기본값에서는 Left 정렬 밖에 없습니다.

- 속성에서 Multiline을 true로 줘야지만 Center, Right 값을 선택할 수 있습니다.

- 그런고로 원하는 정렬을 설정 후, Enter 값을 먹지 않도록 하는 방식을 사용합니다.

- 이 Enter 입력을 FormPreView에서 KeyUp으로 막습니다.

참고 링크

 

이와 마찬가지로 DataGrid의 TextBox에서 Center, Right 정렬을 시키려면, Multiline을 true로 줘야 합니다. 

 

다음과 같은 메소드를 구성하여 DataTable의 내부 Column들을 조절하였습니다.


private void TableStyleSetting(DataTable _DT) {
  Dictionary<string, int> set = new Dictionary<string, int> {
      {"컬럼 이름", 100} // 컬럼 길이 셋팅
  };

  dataGrid.TableStyles.Clear(); // 현 dataGrid의 스타일 제거

  DataGridTableStyle tableStyle = new DataGridTableStyle();
  tableStyle.MappingName = _DT.TableName;
  foreach (DataColumn item in _DT.Columns) {
    DataGridCustomTextBoxColumn Cell = new DataGridCustomTextBoxColumn();
    Cell.Owner = _DT;
    Cell.Width = set[item.ColumnName];
    Cell.MappingName = item.ColumnName;
    Cell.HeaderText = item.ColumnName;
    Cell.ReadOnly = true;

      string[] currency = new string[] { "수정할 컬럼 이름들" };
      foreach (string curr in currency) {
        if (curr.Equals(item.ColumnName)) {
          Cell.Format = "c"; // Text 포멧, 여기서는 화페 포멧을 예시로 하였다.
          Cell.Alignment = HorizontalAlignment.Right; // 오른쪽 정렬
        }
      }
      
    tableStyle.GridColumnStyles.Add(Cell);
 }
 dataGrid.TableStyles.Add(tableStyle); // 현 dataGrid에 설정한 스타일 추가
}

 

  여기서 DataGridCutomTextColumn을 구현하려면 몇몇 추가 클래스들이 있어야 합니다. 

  이 문제를 해결하는데 제가 참고하였던 이 페이지에서, 7718-DataGridCustomColumns.zip을 받아 DataGridCustomColumnBase와 DataGridCustomTextBoxcolumn을 구현하시면 됩니다.

 

  다만 구현 하실 때, 다음 부분도 수정해주셔야 합니다.

protected virtual void DrawBackground(Graphics g, Rectangle bounds, int rowNum, Brush backBrush) {
    Brush background = backBrush;

    //if ((null != background) && ((rowNum & 1) != 0) && !Owner.IsSelected(rowNum)) {
    //    background = _alternatingBrush; 
    //}

    g.FillRectangle(background, bounds);
}

  위의 코드는 DataGridCustomColumnBase에 있는 각각의 셀 배경을 그리는 DrawBackground 메소드인데, 위와 같이 주석처리를 해 주셔야 정상 작동합니다. if 문 안의 내용은 홀수 행마다 배경색을 변경하는 예를 넣어놓았는데, 그대로 작동할 경우 홀수 행이 정상적으로 나오지 않습니다.

.Net Compact Framework 에는 없는 것이 많습니다. ( 이하 .Net CF )

개중 컬럼 명을 클릭했을 때, ListViewItem 정렬도 구현되어 있지 않습니다.

 

검색결과 MS에서 직접 Sort 구현하는 법을 올려놓았더라구요.

그러나 VB code여서, C# 코드로 변환을 해봤습니다.

 

대략적인 흐름은 다음과 같습니다.

> 먼저 ColumnHeader를 상속받아 CostumHeader를 만들어 오름차순, 내림차순 변수를 추가한다.

> SortWrapper를 구현하여, ListViewItem을 감싸는 용도로 쓰고, 정렬이 가능하게 IComparer를 달아준다.

> 이벤트를 받아 컬럼이 선택되면, ArrayList에 담아 Sort를 시키고, 다시 꺼내어 ListView에 담는다.

 

첫 번째로 CostumHeader 입니다.

public class ColHeader : ColumnHeader { 
    public Boolean ascendig { get; set; } 

    public ColHeader(String text, int width, HorizontalAlignment align, Boolean asc) { 
        this.Text = text; 
        this.Width = Width; 
        this.TextAlign = align; 
        this.ascendig = asc; 
    } 
}

이를 ColumnHeader 대신에 대상 ListView에 넣어주시면 됩니다.

 

두 번째로 SortWrapper입니다. 클래스로 네임스페이스 안에 구현해주시면 됩니다.

( - 정렬을 위한 비교가 가능하게 IComparer가 삽입되어 있습니다. )

public class SortWrapper { 
    public ListViewItem sortItem { get; set; } 
    public int sortColumn { get; set; } 

    public SortWrapper(ListViewItem Item, int iColumn) { 
        sortItem = Item; 
        sortColumn = iColumn; 
    } 

    public class Sortcomparer : IComparer { 
        private Boolean ascending; 

        public Sortcomparer(Boolean asc){ 
            ascending = asc; 
        } 
         
        int IComparer.Compare(object x, object y) { 
            SortWrapper xItem = (SortWrapper) x; 
            SortWrapper yItem = (SortWrapper) y; 

            String xText = xItem.sortItem.SubItems[xItem.sortColumn].Text; 
            String yText = yItem.sortItem.SubItems[yItem.sortColumn].Text; 

            int direction = ascending ? 1 : -1; 
            return xText.CompareTo(yText) * direction; 
        } 
    } 
}

 

마지막으로, ColumClick Event 내부입니다.

저는 Sort라는 함수로 구현하였는데요.

Event 메소드 안에 "Sort(e.Column, lv_Target);" 이런 방식으로 넣어주시면 됩니다.

private void Sort(int SelectColumn, ListView lv_) { 
     
    ColHeader clickCol = (ColHeader)lv_.Columns[SelectColumn]; 
    clickCol.ascendig = !clickCol.ascendig; 

    lv_.BeginUpdate(); 

    ArrayList SortArray = new ArrayList(); 
    foreach (ListViewItem item in lv_.Items) { 
        SortArray.Add(new SortWrapper(item, SelectColumn)); 
    } 

    SortArray.Sort(new SortWrapper.Sortcomparer(clickCol.ascendig)); 
    lv_.Items.Clear(); 

    foreach (SortWrapper Sort in SortArray) { 
        lv_.Items.Add(Sort.sortItem); 
    } 

    lv_.EndUpdate(); 
}

인터페이스를 적용시키는데 애먹었는데, 다들 잘 사용하셨으면 좋겠습니다.

2019년 이후에 Window CE 6.0으로 개발하게 되신 여러분 환영합니다.

 

제 개발환경은 다음과 같습니다.

- Windows 8.1 K

- Visual Studio 2008

 

Windows CE 6.0의 가상 시뮬레이터는 따로 존재하지 않습니다.

Windows Moblie 6의 가상장치를 이용하여 불완전하게 실행 테스트를 하거나,

Windows CE 6.0으로 구동되는 기기에 연결하여 직접 테스트를 해보아야 합니다.

 

가상 기기를 최대한 이용하고 싶은 경우 다음과 같이 설치하는 것이 좋습니다.

 

Windows Mobile 6 Professional SDK Refresh     -- 윈도우 모바일 SDK

Windows Mobile 6 Professional Images (KOR)   -- 윈도우 모바일 가상 에뮬레이터 (한국어)

 

가상 에뮬레이터를 한국어 버젼으로 설치하지 않을 경우 한글이 깨져 나오며, 그를 수정하는 것은 매우 어렵습니다.

또한 가상 기기 내에서 네트워크 연결을 위해서는 다음 프로그램이 필수입니다.

 

Virtual PC 2007 setup

 

미리 설치하여 인터넷 혹은 네트워크 연결에 차질이 생기지 않도록 준비합시다.

 

이와 같이 준비하였다면, (Visual Studio 2008의 경우)

파일 -> 새 프로젝트 -> 프로젝트 형식 (Visual C#, 스마트 장치) - 스마트 장치 프로젝트
탬플릿 - .NET Framework 2.0 선택

로 프로젝트를 만들고 새 스마트 장치 추가에서

대상 플랫홈 - Windows CE 선택
.NET Compact Framework - Version 2.0 선택
탬플릿 - 장치 응용 프로그램 선택 (상황에 따라 선택)

프로젝트를 추가한 후 진행하시면 되겠습니다.

 

* 프로젝트 작성 시 기기에서 지원하는 .NET Framework 버젼을 확인 한 후 탬플릿을 조정하십시오.

* 기본적으로 Windows CE 6.0에서는 .NET Framework 2.0를 지원하며 그 이상은 에러를 일으킬 수 있습니다.

 

기본적으로 사용 기기의 스팩을 알아야 하지만, 320 * 240 해상도를 지원할 경우,

KOR Windows MObile 6 Professional Emulater로 틀을 잡아놓는 것이 좋습니다.

 

* 결국 실제 기기에서 Windws CE 6.0 위에 구현되는 것과 가상기기에 구현되는 것은 다르기에 빠르게 기기를 구하는게 좋습니다.

 

 

 

 

+ Recent posts