[C#] 글자 간격 조정 C# 2012. 4. 4. 16:06

훈스에서 질문보다가 여기 저기 찾다보니 API에서 SetTextCharacterExtra 놈을 찾았다.

글자간의 간격을 조절해주는 것이라는데..

그래서 바로 한번 해 보았다.

[DllImport("gdi32.dll", CharSet=CharSet.Auto)] 
        public static extern int SetTextCharacterExtra(     
            IntPtr hdc,    // DC handle    
            int nCharExtra // extra-space value
        );

작업하기 전 저놈을 꼭!! 선언을 하고

private void Form1_Paint(object sender, PaintEventArgs e)
{
IntPtr hdc = e.Graphics.GetHdc();
SetTextCharacterExtra(hdc, 20);
e.Graphics.ReleaseHdc(hdc);

e.Graphics.DrawString("test", this.Font, Brushes.Black, 15, 5);
}

상에서 간격 조절(위에서 20) 해보니 해당하는 간격 만큼 글자 사이의 간격이 조절되어 나온다.

[C#] 한글 조합 C# 2012. 4. 4. 11:30

훈스 돌아다니다가 한글 조합하는 질의가 있어서 한번 해 봄..

계산식이 있었다 ㅎㅎ 네이버 형 찾아보다가 알았지만.. 뭐.. 그래도 일단 끄적..

알아두면 다 이득되니까..

string chosung = "ㄱㄲㄴㄷㄸㄹㅁㅂㅃㅅㅆㅇㅈㅉㅊㅋㅌㅍㅎ";
string jungsung = "ㅏㅐㅑㅒㅓㅔㅕㅖㅗㅘㅙㅚㅛㅜㅝㅞㅟㅠㅡㅢㅣ";
string jongsung = " ㄱㄲㄳㄴㄵㄶㄷㄹㄺㄻㄼㄽㄾㄿㅀㅁㅂㅄㅅㅆㅇㅈㅊㅋㅌㅍㅎ";
int cho_Index = chosung.IndexOf("ㄱ");
int jung_Index = jungsung.IndexOf("ㅏ");
int jong_Index = jongsung.IndexOf("");
int result = ((cho_Index * 588) + ((jung_Index * 28) + jong_Index)) + 44032;
char temp = Convert.ToChar(result);
MessageBox.Show(temp.ToString());

저짝에 계산하는 놈이 굉장이 중요한거 같다. 한글 유니코드 조합이라.. 흠..

[C#] InvokeRequired C# 2012. 2. 27. 15:13
InvokeRequired 이놈은 bool 형태로 그 상태를 확인 할 수 있다.

true의 경우에는 서로 다른 Thread 환경에서 나타나고 false 경우에는 같은 Thread 환경시 일어난다.

이는 보통 Thread 환경에서 다른 Control에 접근하여 쓰는 경우에 많이 있다.

대표적인 예로 Progress의 경우이다.

어떤 작업 비지니스 로직에서 이를 호출한 메인 Instance에서 그 내용을 변경 시 나타내는데 단순히 된다고 넘어 갈게 아니라

명심해 둬야 해서 이렇게 포스팅을 해 본다.
[C#] Socket C# 2012. 2. 23. 14:16

문득 생각나서 한번 작성해 본 코드이다.

.NET 에서 제공하는 리스너가 아닌 소켓만으로 작성한 예이다.

일반적으로 코드 내용은 같다.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;

namespace Server
{
    public partial class Form1 : Form
    {

        IPEndPoint _ip_end_point;
        Socket _server;

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                this._ip_end_point = new IPEndPoint(IPAddress.Any, 10000);
                this._server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);               
                this._server.Bind(this._ip_end_point);
                this._server.Listen(100);

                while (true)
                {
                    Application.DoEvents();
                    Socket client = this._server.Accept();

                    int recv_total = 0;
                    int recv_size = 0;
                    int left_data = 0;
                    int recv_data = 0;

                    byte[] size = new byte[4];
                    recv_data = client.Receive(size, 0, 4, SocketFlags.None);
                    recv_size = BitConverter.ToInt32(size, 0);
                    left_data = recv_size;

                    byte[] data = new byte[recv_size];

                    while (recv_total < recv_size)
                    {
                        Application.DoEvents();
                        recv_data = client.Receive(data, recv_total, left_data, 0);
                        if (recv_data == 0)
                        {
                            this.Text = "Zero Data";
                            break;
                        }
                        else
                        {
                            this.Text = "No Zero Data";
                            recv_total += recv_data;
                            left_data -= recv_data;
                        }
                    }
                    client.Close();
                    MessageBox.Show(Encoding.Default.GetString(data, 0, recv_size));
                }
            }
            catch
            {
            }
            finally
            {
                this._server.Close();
            }
        }
    }
}
코드에서 보면 알겠지만 엔드 포인트를 잡아주고 그것을 바인드 한 형태이다.

하나 의문인게 Listen 처리를 하지 않으면 안될까.. 고민 하다가 한번 빼 보고 했는데 바로 오류가 났다.

한 소켓에 접근하는 수를 제어하는 것인데 여러 수천, 수만명이 접근 할 때는 어떻게 되는 것인가 의문이 든다.

한번 연구 해 볼 만한 가치는 있는 듯 하다.(경력에 비해 해 본 것이 없는 것 같아 슬프다.)

나머지는 대략 접속한 소켓을 생성하고 그 내용을 바이트 처리 하여 하는 것이다. 여기까지가 서버 코드이다.

다음은 클라이언트 코드이다.

try
            {
                IPEndPoint ip_end_point = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 10000);
                Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                server.Connect(ip_end_point);

                int send_total = 0;
                int data_size = 0;
                int left_data = 0;
                int send_data = 0;

                EventHandler();

                byte[] data = new byte[data_size];
                data = Encoding.Default.GetBytes("TCP/IP Connect Test");
                data_size = data.Length;
                left_data = data_size;

                byte[] size = new byte[4];
                size = BitConverter.GetBytes(data_size);

                server.Send(size);

                while (send_total < data_size)
                {
                    send_data = server.Send(data, send_total, left_data, SocketFlags.None);
                    send_total += send_data;
                    left_data -= send_data;
                }
            }
            catch
            {
            }
            finally
            {
                server.Close();
            }
최초의 작업은 서버 측과 동일하다. 엔드 포인트를 잡아주고 소켓을 생성해서 서버와 접속을 한다.

물론 데이터 처리는 서버와 동일하게 하기 위해서 바이트 처리를 하게 해봤다.

이것 말고도 네트워크 스트림을 이용하여 스트림을 이용해서 문자열들을 보내는 통신 또한 가능하다.

각기 해당하는 스트림을 생성하여 Flash() 처리를 해 주면 된다.

그렇게 작업 할 경우 반드시 스트림 처리엔 Flash() 처리를 해 줘야한다. 아닐 경우 버퍼에 쌓인 데이터 문제도 있을 뿐더러

통신 결과가 원할하지 않거나 문제가 발생하는 것을 확인 할 수가 있을 것이다.

[C#] Delegate와 Event C# 2012. 2. 23. 10:35

대리자와 이벤트는 종종 많이 쓰인다.

보통 부모와 자식의 관계를 맺고 있거나, 쓰레드를 이용할 경우 필자는 종종 썼다.

예전에 좀 무식하게 부모창으로 넘길 때는 this 키워드를 이용해서 Invoke 하는 방식으로 했는데

혼자서 좀 생각을 해 보니 다음과 같이 해도 될 것 같아 해 보니 동작은 한다.

일단 자식 측에 아래와 같이 코드를 작성해 본다.

public delegate void m_delegate(string msg);
        public event m_delegate m_event;

        public Form2()
        {
            InitializeComponent();          
        }

        private void button1_Click(object sender, EventArgs e)
        {
            m_event("Test");
        }
그리고 부모 측의 코드는 다음과 같다.

private void button1_Click(object sender, EventArgs e)
        {
            Form2 form = new Form2();
            form.m_event += new Form2.m_delegate(event_test);
            form.ShowDialog();
        }

        private void event_test(string msg)
        {
            MessageBox.Show(msg);
        }

부모 측에 보면 자식에 접근하여 그곳의 이벤트를 생성한 것을 알 수가 있다.

그러나 테스트 코드를 짜다보니 결과가 원하는 대로 나오지 않았다.

왜냐.. 자식 측에 어떤 특정한 이벤트가 일어나지 않으면

m_event("Test"); 부분은 작성 할 수가 없었다.(아니면 누군가 보시다 지적 바랍니다.)

혹시나 싶어서 버튼 이벤트를 주고 해 보니 동작했다.

사용 방법마다 조금씩 다르겠지만.. 이 역시 숙지 해 둔다면 좋을 법 하다.

그리고 대리자와 이벤트의 관계를 잘 보면 이벤트는 대리자의 선언 명으로 형식을 지정하는데

이는 이벤트가 대리자를 캡슐화 한다고 생각해도 무방 할 듯 하다.

혼자서 이거 저거 만지다 보니 재밋는 현상을 봤다.

일단.. 폼에 패널을 딱!! 올려서 배경색을 지정한다.

그 다음 폼 속성의 TransparencyKey 값을 패널에 지정한 배경색과 같은 값을 넣어주면 다음과 같이 나온다.


마치 구멍을 뚫은 듯 뒷 부분이 보인다.

나름 재밋는 것인듯;;
[C#] Thread 동기화 C# 2012. 2. 3. 11:26
thread 에서 동기화가 중요하다는 것은 모두가 아는 사실이다.

하지만 방법상에 문제가 생길 수가 있다.

lock을 예로 들면

lock(this){동기화 코드} 형식으로 많이 쓰지만

그 작업 대상이 static으로 정적으로 되어 있을 경우에는

typeof(클래스명) 처리를 해서 해야한다.

그렇지 않을 경우 문제가 생김을 확인 할 수 있을 것이다.
[C#] 병렬처리 C# 2012. 1. 31. 15:32
http://msdn.microsoft.com/ko-kr/library/dd460688.aspx

MSDN에서 찾은 내용!! 틈틈히 공부를.. 근데 PLINQ라 해서 내용으로 되어 있는데..

4.0의 병렬관련 ForEach (?) 그런 내용은 어딧을꼬...
우리들은 오라클을 설치하고 CS 돌렸던 적이 있다.
(필자도 2009년에 그렇게 했다가 포스팅 하는 것을 깜박하고 이제서야 올린다.)

하지만 매번 그러하기엔.. 많은 시간과 귀차니즘을 발생시키는데..

그것을 해결하기 위해서는 다음과 같이 하면 된다.

먼저 ODP.NET 을 XCOPY 버전으로 다운 받아 그 안의 Oracle.DataAccess.dll, OraOps11w.dll 파일을

프로젝트에서 참조하고 오라클과 관련된 코드를 짠다.

그리고 커넥션 스트링을 넣어주는데 DataSource 부분에 TNS에서 쓰는 내용 그대로 가져다 주면 된다.

그리고 실행 되는 폴더 안에

mfc71.dll, oci.dll, ociw32.dll, orannzsbb11.dll, oraocci11.dll, oraociei11.dll

이 파일을 넣어주고 실행을 하면..

오라클 없이도 배포가 잘 됨을 확인 할 수 있다.

단!! 그 PC에 또 다른 오라클이 설치가 되어 있다면 경로 문제로 에러가 난다는 것을 명심하자.
[C#]레지스트 키 값 이용 C# 2011. 11. 22. 17:45
까먹기 전에 다시 깨작 깨작..

일단 레지스트 등록이다.

요 직전 포스팅의 내용인 권한과도 가끔 물려서 이용하면 좋다(?)

1.레지스트 등록

RegistryKey regKey = Registry.LocalMachine.CreateSubKey(@"SOFTWARE\IdPassKey", RegistryKeyPermissionCheck.ReadWriteSubTree);
regKey.SetValue("ID", "id", RegistryValueKind.String);
regKey.SetValue("PASS", "pw", RegistryValueKind.String);
regKey.SetValue("Check", "true", RegistryValueKind.String);

2.레지스트 조회
RegistryKey regKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\IdPassKey", RegistryKeyPermissionCheck.ReadWriteSubTree);

3.레지스트 삭제
Registry.LocalMachine.DeleteSubKey(@"SOFTWARE\IdPassKey");

이렇게 쓴다!!

아!! using Microsoft.Win32; 요놈은 항상 참조 해 주기!!

창고야 쌓여라~ -_-;; 내가 머리가 나쁘니 ㅠ_ㅠ