GSI

C#의 Winfor에서 DataSet을 사용할때 BindingSource를 적용할 수 있습니다.
솔직히 아직까지 많은 부분 제대로 파악되지 않은듯 하지만.
참 편한듯 하지만 아직까지 사용하기 힘드네요.

우선 아래의 이미지 처름 MS Access의 파일을 사용해서
member, detail의 테이블을 제작했습니다.

사용자 삽입 이미지
사용자 삽입 이미지

member의 "_name"와 detail의 "_name"의 연결이 되어 있습니다.
잘 몰라서 "관계" 대화창에서 "관계만" 이걸로만 연결했습니다.
사용자 삽입 이미지

문제는 여기서 member의 _name의 정보를 사용해서 삭제 할때
detail의 _name가 같은 경우 모두 삭제를 해야 하는데요.

같은 이름의 내용을 모두 삭제 해야 하는데 자동으로 되는건지 모르겠네요.



그래서 우선 아래와 같이 해결했습니다.
1. member의 항목을 선택한다.
2. member의 memberBindingSource.Current의 값을 얻어 와서 해당 "_name"를 구합니다.
3. detail의 "_name"의 같은 이름을 구해옵니다.(쿼리함수 생성)
4. 구해온 detailDataTable의 정보를 사용해서 detailTableAdapter.Delete() 에서 삭제합니다.
5. memberBindingSource.RemoveCurrent()를 사용해서 member의 데이터를 삭제합니다.
6. .EndEdit()를 통해서 편집을 마칩니다.
7. tableAdapterManager.UpdateAll()를 통해서 값을 업데이트 합니다.

코드는 아래와 같습니다.
private void btnDelete_Click(object sender, EventArgs e)
        {
            try
            {
                DataRowView drv = (DataRowView)this.memberBindingSource.Current;
                TestJoinDataSet.memberRow memberRow = (TestJoinDataSet.memberRow)drv.Row;

                TestJoinDataSet.detailDataTable ddt =
                    this.detailTableAdapter.GetDataBy(memberRow._name);

                foreach (TestJoinDataSet.detailRow row in ddt.Rows)
                {
                    this.detailTableAdapter.Delete(row.ID, row._name, row._info);
                }

                this.memberBindingSource.RemoveCurrent();
                this.memberBindingSource.EndEdit();
                this.detailBindingSource.EndEdit();
                this.tableAdapterManager.UpdateAll(this.testJoinDataSet);
            }
            catch (InvalidOperationException oex)
            {
                MessageBox.Show(oex.Message);
            }
            catch (NotSupportedException nex)
            {
                MessageBox.Show(nex.Message);
            }
            catch (DataException ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

이렇게 하는게 맞는지 조언 부탁해요 ^^

Posted by gsi
:

[C#] OpenGL 코드 연동하기

C# 2008. 8. 8. 12:50 |

사용자 삽입 이미지


관련코드 :


.
Posted by gsi
:

C#을 이용한 FTP로 파일 업로드 하는 코드 입니다.
MSDN에 있는
              ...........
            StreamReader sourceStream = new StreamReader("testfile.txt");
            byte [] fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
             .............
이런 코드를 사용하니까. 인코딩에서 데이터가 제대로 전달되지 못하는 문제가 발생합니다.
그래서 아래와같이 처리 했습니다.

        private void btnFileUploadTest_Click(object sender, EventArgs e)
        {
            Upload("blue.jpg");
            Upload("크기변환_dddd.png");
            Upload("zskin.txt");

            MessageBox.Show("Upload 가 완료되었습니다.");
        }

        private void Upload(string filename)
        {
            FileInfo fileInf = new FileInfo(filename);
            string uri = "ftp://192.168.0.3:8451/" + fileInf;
            FtpWebRequest reqFTP;

            UriBuilder URI = new UriBuilder(uri);
            URI.Scheme = "ftp";

            reqFTP = (FtpWebRequest)FtpWebRequest.Create(URI.Uri);
            reqFTP.Credentials = new NetworkCredential("administrator", "0000");
            reqFTP.KeepAlive = false;
            reqFTP.Method = WebRequestMethods.Ftp.UploadFile;
            reqFTP.UseBinary = true;
            reqFTP.ContentLength = fileInf.Length;
            reqFTP.UsePassive = true;

            int buffLength = 2048;
            byte[] buff = new byte[buffLength];
            int contentLen;

            FileStream fs = fileInf.OpenRead();

            try
            {
                Stream strm = reqFTP.GetRequestStream();
                contentLen = fs.Read(buff, 0, buffLength);

                while (contentLen != 0)
                {
                    strm.Write(buff, 0, contentLen);
                    contentLen = fs.Read(buff, 0, buffLength);
                }

                strm.Close();
                fs.Close();
            }
            catch (Exception ex)
            {
                throw;
            }
        }

Posted by gsi
:

C# 레지스트리 정보 읽기

private void ChkClientVersion() { RegistryKey reg = Registry.LocalMachine; reg = reg.CreateSubKey(@"Software\HI-NG\Azitro\AzitroAppLauncher", RegistryKeyPermissionCheck.ReadSubTree); FinalClientVersion[(int)CATEGORY_MODE.CAT_WORLD] = Convert.ToDouble((string)reg.GetValue("WorldVersion")); FinalClientVersion[(int)CATEGORY_MODE.CAT_ROOM] = Convert.ToDouble((string)reg.GetValue("RoomVersion")); FinalClientVersion[(int)CATEGORY_MODE.CAT_CON] = Convert.ToDouble((string)reg.GetValue("ConVersion")); reg.Close(); Console.WriteLine("<<클라이언트 레지스트리 버젼>>"); Console.WriteLine(" WorldVersion={0}", FinalClientVersion[(int)CATEGORY_MODE.CAT_WORLD]); Console.WriteLine(" RoomVersion={0}", FinalClientVersion[(int)CATEGORY_MODE.CAT_ROOM]); Console.WriteLine(" ConVersion={0}", FinalClientVersion[(int)CATEGORY_MODE.CAT_CON]); }

C# 레지스트리 정보 쓰기

private void UpdateVersionRegister() { RegistryKey reg = Registry.LocalMachine; reg = reg.CreateSubKey(@"Software\HI-NG\Azitro\AzitroAppLauncher", RegistryKeyPermissionCheck.ReadWriteSubTree); reg.SetValue("WorldVersion", upaser.FinalSvrVersion[(int)CATEGORY_MODE.CAT_WORLD]); reg.SetValue("RoomVersion", upaser.FinalSvrVersion[(int)CATEGORY_MODE.CAT_ROOM]); reg.SetValue("ConVersion", upaser.FinalSvrVersion[(int)CATEGORY_MODE.CAT_CON]); reg.Close(); }
Posted by gsi
:

[C#] 디자이너 페이지 오류

C# 2008. 3. 20. 11:30 |

form.cs[디자인] 페이지가 아래와 같은 내용으로 표시 되면서 로드 되지 않는 오류가 가끔 있다.
사용자 삽입 이미지
이 내용은 결국 프로그램의 규칙을 알지 못하고 막 짜다 보니 생기게 된 에러입니다. -.-;
하지만 지금도 확실한 에러 내용은 모르겠고, 저 같은 경우는 다음과 같이 해결했습니다.

문제가 생긴 부분은 아래의 코드 부분입니다.
namespace AzitroUpdater
{
    public class UpdateInfo   <--- 여기 클래스가 위치 하면서 오류가 남
    {
        public string UrlHttpPath { get; set; }
        public string UrlDownloadFolder { get; set; }
        public string UrlDownloadFile { get; set; }
    }
    public partial class Form1 : Form
    {
        int curIndex = 0;
        ...................

위의 코드에서 알 수 있듯이 시작하는 클래스가 Form1 인데
그 위에 다른 클래스가 존재 해서 문제가 생기는 거였다.
이 코드를 다른 파일이나 다른 위치로 옮기니 되었다.
Posted by gsi
:

[C#] - string.Split 사용법

C# 2008. 3. 13. 17:46 |

C++ 에서 C# 으로 읽어 들일때
char buf[128] 의 데이터를 아래와 같이 읽어 들일때.
buf1 = new string(br.ReadChars(128));
string [] split = buf1.Split(new Char [] {'\0'});
buf1 = split[0];

buf1 이 128로 읽어 들이면, 뒤에 \0 의 값이 쭉 저장되게 된다.
그렇게 하면  buf1 의 길이는 128이 된다. 즉, 필요 없는 공간이 생기게 마련이다.
(혹.. 이거 말고 다른 방법으로 읽을수 있다면 꼭 연락좀.. -.- )
그래서 \0 을 Split을 사용해서 나눈 다음에 필요한 정보만 가져 오도록 한다.

string [] split = buf1.Split(new Char [] {'\0'});
를 하고 나면 split 에 \0 으로 나누어진 데이터가 배열로 저장 된다.
이렇게 하고 나면 제일 앞쪽에 필요한 데이터만 모이게 된다.

buf1 = split[0] 을 해서 buf1 에 필요한 데이터만 담을 수 있다.
Posted by gsi
:

사용자 삽입 이미지

HTTP 프로토콜을 사용해서 원격파일 다운로드 프로그램 만들고 있습니다.

HTTP 를 통해서 파일을 받을때는 WebClient 를 사용하고 있다.
단순하게 다운로드 받기 위해서는 아래와 같이 DownloadFile()를 사용한다.

WebClient webclient = new WebClient();
webclient.DownloadFile(updatelistUrl, updatelistTxt);


그리고 다운로드 받는 상태를 알기 위해서는 DownloadFile 가 아닌 DownloadFileAsync 를 사용해야 한다.
그리고 받는 동안 호출되는 이벤트 함수와 다 받은후 처리 하는 함수를 등록해야 한다.

// 객체 생성
WebClient client = new WebClient();

// 이벤트 함수 등록
client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted);
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);

// 받는 동안 프로그래스바의 Value에 추가한다. (퍼센트 값이 바로 제공된다.)
void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
    progressfile.Value = e.ProgressPercentage;
}
//
void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{

}


파일을 실제로 다운로드 받을때는 아래와 같이 처리 합니다.
(DownloadFileAsync 이것을 사용해야 이벤트 함수가 호출 됩니다.)

client.DownloadFileAsync(new Uri(curFile.Url), curFile.Path);


스레드로 해도 될 듯 한데 우선 작업 하기 편하게 타이머를 사용해서 제작 하였습니다.
Test 버튼을 누르면 해당 동작이 시작 됩니다.


[동작 순서]

  1. Updatelist.txt 파일을 다운로드 한다.
  2. Updatelist.txt 파일의 정보를 분석해서 다운로드할 파일을 구성한다.
  3. 해당 파일을 타이머를 통해서 다 받을 때 까지 반복한다.
  4. 다 받으면 자동 종료 또는 특정 실행 파일을 실행한다.
Posted by gsi
:

디렉토리를 생성할때 디렉토리가 생성되어 있는지 검사도 해야 한다.

Directory 나 DirectoryInfo 를 사용하면 디렉토리 생성 및 검사도 가능하다.

방법#1

if (Directory.Exists(rootPath) == false)

    Directory.CreateDirectory(rootPath);

방법#2

DirectoryInfo di = new DirectoryInfo(rootPath);

if (di.Exists == false)

{

    di.Create();

}

Posted by gsi
:

Text File를 한줄 한줄 읽을때, 해당 문자를 기준으로 파서 할때 아래와 같이 하면 된다.
Regex는 다른 정규식도 표현할 수 있다고 하지만, @.@ 왠지 복잡하네요..

우선 단순하게 ";"를 기준으로 파서를 하는게 있어서 그 코드를 올려 봅니다.

static void ReadFromFile(string filename)
{
    StreamReader SR;
    string S;
    SR = File.OpenText(filename);
    S = SR.ReadLine();
    while (S != null)
    {
        Regex rx = new Regex(";");

        foreach (string ss in rx.Split(S))
        {
            Console.WriteLine(ss);
        }

        //Console.WriteLine(S);
        S = SR.ReadLine();
    }
    SR.Close();
}
Posted by gsi
:

C++ 에서 FILE 를 사용해서 데이터를 바이너리로 저장 했다면 C#에서 어떻게 읽어야 할까?.

C#을 배우는 상태에서 C++ 과의 파일 연동 문제가 고민이 되었다.
사실 모르니 궁금증이 생긴 거지만 몇가지 테스트를 하다 보니 바이너리 데이터는 BinaryReader 로 읽을수 있었다.

해당 파일을 읽을때 FileInfo를 사용해서 오픈 한 다음에 BinaryReader로 읽을 수 있다.
FileInfo fi = new FileInfo(@"D:\Testbinary.dat");
BinaryReader br = new BinaryReader(fi.OpenRead());

C++ 에서 아래 데이터를 저장했습니다.
FILE* fp = fopen(path, "wb");
int data0 = 100;
float data1 = 100.123f;
char buf0[128] = "son byoung uk";
fwrite(&data0, sizeof(int), 1, fp);
fwrite(buf0, 128, 1, fp);
fwrite(&data1, sizeof(float), 1, fp);
fclose(fp);

C# 에서 아래와 같이 데이터를 읽었습니다.
int data0;
float data1;
char[] buf0;
string buf1; data0 = br.ReadInt32();
buf0 = br.ReadChars(128);
buf1 = new string(buf0);
data1 = br.ReadSingle();

위의 내용을 아래와 같이 정리해봤습니다.

C++

C#

int

br.ReadInt32()

float

br.ReadSingle()

double

br.ReadDouble()

char[]

string a = new string(br.ReadChars(128))

Posted by gsi
:

사용자 삽입 이미지

Carousel 의 기본 구동 알로리즘을 사용해서 구현해본 예제 입니다.
버튼 컨트롤로 사용한 거지만, GDI+ 또는 Panel 등을 이용해서
처리 하면 깔끔하게 처리가 가능할 거 같습니다.

Posted by gsi
:

[C#] - GDImage - 좋은 데모

C# 2008. 3. 3. 16:34 |


C# .Net 의 GDI를 사용한 다양한 이미지 효과 데모를 제공하는 홈페이지

사용자 삽입 이미지

관련 홈페이지 주소 : http://www.zapsolution.com/winlift/ccorner.htm

Posted by gsi
:

사용자 삽입 이미지

Win32 대화 상자와 Windows 폼이 다른 점은 폼이 자동으로 사용자가 Enter, Esc 키가 눌렀을때 키보드 입력을 라우팅 하지 않는 다는데 있다. MFC와 같은 Win32 작업을 할때는 폼을 하나 생성하게 되면 Ok, Cancel 버튼이 생성되게 된다.
하지만 Windows 폼의 경우는 아무것도 생성되지 않는 윈도우만 생성된다.
이때 폼에 OK, Cancel 버튼을 넣어 주고 싶다면, 어떻게 해야 하는가?
이때 위의 이미지에 나오듯이 해당 버튼을 만들고 DialogResult의 속성을 정의해 주면 된다. 더 펀한듯 보인다.
Posted by gsi
:

C#, .NET 의 미리 정의된 타입 비교

C# 프로그램을 하다 보면 int 또는 Int32 라는걸 사용해서 타입을 정해줄 때가 있다.
처음에는 int 형이 있는데 Int32, Int64, int16 과 같은 걸 볼 수 있다.
지금 생각 해보면 int 는 C# 의 미리 정의된 타입이고, Int32 와 같이 int가 대문자 Int로
되는 것은 System을 네임스페이스로 가지는 .Net 의 미리 정의된 타입인거 같다.

몇가지 예)

bool

System.Boolean

True 인지 false 인지 나타내는 논리 값

기본값은 false 이다.

byte

System.Byte

0 부터 255 까지의 값을 저장하는 부호 없는 바이트, 기본값은 0 이다.

sbyte

System.SByte

-128 ~ 127 까지 저장하는 바이트, 기본값은 0이다.

char

System.Char

부호없는 16비트 유니코드 문자, 기본값은 ‘\0’ 이다.

decimal

System.Decimal

128 비트 데이터 형식, 재무 및 통화 계산에 적합하다. 기본값은 0.0m 이다.

double

System.Double

64비트 부동 소수점, 기본값은 0.0d 이다.

float

System.Single

32비트 부동 소수점, 기본값은 0.0f 이다.

int

System.Int32

부호 있는 32비트 정수 타입, 기본값은 0 이다.

uint

System.UInt32

부로 없는 32비트 정수 타입, 기본값은 0이다.

나머지는.. -.- 귀찮네욤. ^^

여기서 중요한건 C#으로 개발하는 사람은 C#의 타입을 사용해서 프로그램을 작성하는게
보다 명확하며, 다른 언어를 사용하는 컴포넌트 개발자와 함께 작업하는 경우에는
언어 사이의 타입을 일치시키기 위해서 반드시 위의 표와 같은 타입을 알고 있어야 한다.
Posted by gsi
:

Win Form Flicker Free

더블 버퍼링 옵션이 따로 있기는 하지만 윈폼도 MFC와 마찬가지로 마우스로 오브젝트 처리시
Flicker 현상은 발생하기 마련이다.

여러가지 자료를 찾다가 VS2008에서 테스트해본 결과 잘 되는거 같다.
이 자료의 출처는 아래와 같다.
http://www.codeproject.com/KB/GDI-plus/flickerFreeDrawing.aspx

이 자료가 2003 버젼인지 지금 테스트 하고 있는 2008에 맞지 않아서 그냥 카피 복사^^
해서 이식 했다.

잘되는듯 하다.
우선 더 해봐야 할 것이 타이머를 통한 많은 객체의 이동 처리 및 다양한
효과들을 구현해 봐야 할거 같다.

관련코드 :
Posted by gsi
: