사용자가 직접 만들어서 사용할 수 있는 구성요소 중에서 UserControl은 Component에 비해서 작성하기가 쉽다.


 개인적으로 UserControl은 여러 메뉴가 복합적으로 사용되어야 할 때에 사용하면 편하다. 가령 이미지 밑에 텍스트가 따로 출력되는 버튼 아이템은 기본으로 제공되지 않기 때문에 UserControl로 만들어 사용하면 간편하다.


[추가]

프로젝트 오른쪽 클릭 - 추가 - 사용자 정의 컨트롤

(다른 방법도 있다)


이름을 입력하고 확인을 누른다


[배치]

일반적인 디자인 편집화면의 배치와 동일하다. 원하는 아이템을 추가하고 적절하게 배치하도록 한다.


크기 설정에는 조금 신경을 써줘야 한다. 기본적인 크기는 고정 크기이기 때문에 아이템을 추가해서 크기를 늘려도 내부 아이템 크기는 변하지 않는다. Dock 옵션 혹은 코드상에서 크기 수정을 하거나 해서 크기가 변하도록 하는 것이 한 방법이다.


[속성값 설정]

내부의 아이템에 직접 접근할 수 있도록 해야 한다. 그렇지 않으면 계속 고정된 값만 사용해야 한다. 버튼을 만들어놓고 텍스트 수정을 할 수 있는 방법을 마련하지 않으면 같은 텍스트만 사용해야 한다.


코드 내부에 다음의 코드를 추가한다

[Description("설명"), Category("분류")]

        public string myText

        {

            get { return label1.Text; }

            set { label1.Text = value; }

        }


설명과 분류는 GUI 편집 화면에서 보조로 사용하기 위한 것이다.

설정하지 않은 경우에 기타 분류로 취급된다. 그러나 편의를 위해서 간략한 설명을 추가하도록 하자.


데이터 입출력 부분은 get/set을 사용하면 간편하다. 필요에 따라서 추가 기능을 넣어야 될 경우도 있으나 여기서는 생략한다.


[사용]

프로젝트 내부에서 직접 사용하는 방법에 대해서만 설명한다.

사용하기 위해서는 먼저 빌드를 할 필요가 있다.

빌드가 끝나면 GUI 편집창의 도구 상자 최상단에 방금 작성한 아이템이 추가된다.

이후 일반 Components 같이 끌어다 사용하면 된다.

Posted by Vermond
:

c#에서 인코딩을 바꿔서 넣어줘야 한다

전 글의 1번 예제 중에서 이 부분을 수정했다

private IntPtr Prepare(string query)

    {

      IntPtr stmHandle;


      byte[] str = System.Text.Encoding.GetEncoding("euc-kr").GetBytes(query);


      fixed (byte* p_str = str)

      {

          if (sqlite3_prepare_v2(_db, p_str, str.Length,

            out stmHandle, IntPtr.Zero) != SQLITE_OK)

              throw new SQLiteException(sqlite3_errmsg(_db));

      }

      return stmHandle;

    }


원 코드는 query를 그대로 입력했다. 영문의 경우에는 문제가 없으나 한글은 문제가 생긴다. 가장 큰 이유는 한글은 2바이트로 작성되어 길이가 맞지 않는다는 점


예를 들어

string query = "abcd가나다";

query.length 는 7로 나온다

그러나 C쪽으로 가면 얘는 10바이트가 된다

3바이트 차이가 난다 (한글 문자 개수)


고로 인코딩을 사용해 직접 char 혹은 byte 배열로 보내줘야 한다.

길이도 원문 길이가 아니라 인코딩을 변환한 byte 배열 크기로 보내주면 문제 없다.




에러 문제


좀 귀찮다. 방법은 의외로 어렵지는 않았다.

내가 현재 vs2010을 사용하는데 이 프로젝트는 08년도 제작되었다. 그걸 따져본다면 vs2008 이전 버전으로 제작되었다는 말이다. 그래서 차이가 생긴게 아닌가 싶다.


일단 디버깅 안 되는 문제 자체는 프로젝트 옵션의 디버그에서 비관리 코드 디버깅 사용을 체크하니까 해결되었다. 그러나 이게 실질적인 문제는 아니라고 본다. (아래 서술함)


이놈의 dll 연결 함수가 죄다 string으로 되어 있다. 그러나  실제 소스를 확인하면 (당연하겠지만) 포인터로 되어 있다. 이게 문제다. 이전 버전은 모르겠지만 2010은 이런데 엄격한가보다. 그래서 죄다 오류를 띄운다.


조금 번거롭지만 다음의 과정을 전부 행해야 한다

1. dll 함수 중에서 입력 변수 혹은 반환 타입이 string으로 되어 있는 함수를 모두 체크한다

2. 전부 다 포인터로 변경한다. (나는 byte*을 자주 쓴다)

3. 이에 맞도록 데이터를 수정한다.

string->byte->byte* (입력시)

byte*->byte->string (출력시)


ExecuteQuery 함수 내부에 이런 것이 있다.


dTable.Columns.Add(sqlite3_column_origin_name(stmHandle, i));


요거 오류나는 부분 중의 하나다. 근데 실행 되긴 된다. sqlite3_column_origin_name의 반환 형식이 string이라서 실행은 된다. 다만 기본 상태에서는 디버깅이 되지 않고, 비관리 코드 디버깅 체크해도 이 부분에서 에러 뜨면서 걸린다. (디버깅 안하고 하면 실행되긴 된다)


이 부분을 다음과 같이 수정하니 일단 에러는 안 걸린다

byte* b_ori = sqlite3_column_origin_name(stmHandle, i);

          List<byte> b_array = new List<byte>();


          for (int j = 0; b_ori[j] != 0; j++)

          {

              b_array.Add(b_ori[j]);

          }


          string str = System.Text.Encoding.GetEncoding

("euc-kr").GetString(b_array.ToArray());


          dTable.Columns.Add(str);


더 좋은 방법이 있을 수도 있겠지만 일단 이런 식으로 해놨다. 반복 사용을 염두에 둔다면 이 부분만 빼서 함수로 만들어도 되니까.


여튼 string이 직접 dll과 연결되지 않도록 죄다 수정해야 한다. 입력은 맨 위의 예제같이, 출력은 바로 위 예제같이 다 수정해 준다.


수정이 전부 끝났는지 확인해보는 방법

프로젝트 옵션의 디버그에서 비관리 코드 디버깅 사용 해제해도 제대로 디버깅이 되면 수정이 제대로 끝난 것이다



여담 

- 사실 방법만 아니까 그리 어렵진 않다. 예제 코드도 생각보단 짧고 간단하다. 어차피 래핑 밖에 안되서 그럴지도 모르지만

- 웹이라서 그런건지는 모르겠는데 작성자 코드 스타일이 좀 내 맘에는 안 든다. 엔터가 많고, 한줄짜리 if문 뒤의 명령문은 중괄호 안친다. 그래서 좀 헷갈렸다

- 수정한거는 일단 첨부함

SQLite.cs

참고로 위 파일은 예제 파일에서 그냥 테스트해보고 올린거라 몇가지 사소한 문제가 있을 수 있다. 닷넷 버전때문에 dll 호출 구문을 다음과 같이 수정해야 할 수도 있다. (위 파일에는 적용되어 있지 않음)


[DllImport("sqlite3.dll", EntryPoint = "sqlite3_column_double")]

를 아래와 같이 수정한다

[DllImport("sqlite3.dll", CallingConvention = CallingConvention.Cdecl)]


'Programming > C#' 카테고리의 다른 글

c# - c dll 디버깅시 주의할 점  (0) 2013.12.20
c# 문자열에서 문자 개수 알아내기  (0) 2013.12.19
C# 타이머 사용 예제  (0) 2013.12.10
C#에서 User Control 만들기  (0) 2013.11.12
c#에서 SQLite 한글 사용하기 -1-  (0) 2013.11.05
Posted by Vermond
:

단순하게 쓸거면 다음의 사이트도 괜찮다

http://system.data.sqlite.org/index.html/doc/trunk/www/index.wiki


c#에서만 입출력하게 만들거면 위의거 써도 상관없다


문제는 지금 c와 c#에서 동시에 접근해야 하는데 이 경우 어느 한쪽이 깨져서 나온다는 점이다. c에서 넣은건 c#에서 깨지고 c#에서 넣은건 c에서 깨진다. 기본 제공되는 커맨드라인 툴을 사용해서 확인하면 c#이 깨진 걸로 나온다.


인코딩 변환 문제라고 의심해서 직접 c에서 단문을 한글로 쳐서 바이트 확인한 다음에 직접 바이트 배열 만들어서 변환한 다음에 넣어주었다. 그래도 여전히 문제가 생긴다.


http://www.hoons.net/Board/QACSHAP/Content/41967

자답은 좋은데 해결방식을 안써놨다 -_-;

그래도 방법이 이 수밖에 없을 듯 해서 검색해봤다.

다음의 사이트를 발견했다.

http://tech.pro/tutorial/852/csharp-tutorial-writing-a-dotnet-wrapper-for-sqlite

http://pkario.blogspot.com/2010/11/sqlite-c-wrapper.html


래핑에 대해서 샘플 코드를 기술해놓은 곳이다. 일단 첫번째 링크로 테스트 중이다. 

첫번째 링크의 문제

1. 디버그로 실행시 원인불명의 오류 발생 -_-;

일단 노디버그로 실행하면 되긴 된다

2. 한글 입력 처리 안됨

읽기는 된다


제대로 동작이 된다면 그에 대한 내용을 빨리 정리해두겠음

'Programming > C#' 카테고리의 다른 글

c# - c dll 디버깅시 주의할 점  (0) 2013.12.20
c# 문자열에서 문자 개수 알아내기  (0) 2013.12.19
C# 타이머 사용 예제  (0) 2013.12.10
C#에서 User Control 만들기  (0) 2013.11.12
c#에서 SQLite 한글 사용하기 -2-  (0) 2013.11.05
Posted by Vermond
: