본문 바로가기

Library/.NET Framework with C#

Form에서 원하는 윈도우 스타일 지정 Win32 API인 CreateWindow() 계열의 함수를 사용하여 윈도우를 생성하던 사람은, WNDCLASS와 윈도우 스타일을 지정하여 원하는 윈도우를 생성했을 것이다. 그렇지만, Form 프로그래밍에서는 함수 몇개로 이러한 윈도우 모습을 지정하기보다는, 여러개의 확실히 구분된 프로퍼티를 통해서 윈도우 형태를 결정하게 된다. 따라서 처음 Form을 접하는 사람은 어떤 프로퍼티를 지정해야 원하는 효과를 낼 수 있는지 혼란스러울 것이다. * 캡션바의 최소화, 최대화, Close 아이콘에 대해서 설정하려면, Form의 MinimizeBox, MaximizeBox 프로퍼티를 설정한다. * 윈도우 스타일에서 WS_MAXIMIZE, WS_MAXIMIZE와 같은 효과를 내려면 Form의 WindowState 프로.. 더보기
MouseEnter, MouseLeave, MouseHover Form에서, MouseEventArgs를 인자로 가지는, 기본적인 마우스 관련 이벤트는 MouseDown, MouseUp, MouseMove, MouseWheel이다. MFC에서, 마우스 커서가 언제 윈도우 영역을 벗어나는지 확인하기 위해 WM_MOUSELEAVE 메세지를 처리해봤던 사람이라면, Form에서도 이것과 비슷하게 Enter, Leave 처리가 이루어진다는 것을 알 수 있을 것이다. 즉, MFC에서 WM_MOUSELEAVE 메세지를 잡기 위해서는 TrackMouseEvent라는 구조체를 정의하고 여기에 이벤트를 받도록 정의해야 하는데, 그래서 기본적으로 WM_MOUSELEAVE 메세지는 CWnd 클래스의 속성에 나타나지 않는다. 마찬가지로, MouseLeave 이벤트는 MouseEventAr.. 더보기
KeyDown, KeyUp, KeyPress KeyEvnetHandler의 인자인 KeyEventArgs와, 키가 눌려졌을 때 발생하는 이벤트인 KeyPressEventHandler의 인자인 KeyPressEventArgs는, 중복되는 것 같다. 하지만, 실제로는 그렇지 않다. 당장, 폼 하나를 생성하고 KeyDown, KeyPress 이벤트를 재정의해서 확인해보라. KeyDown, KeyUp 이벤트에서의 KeyEventArgs의 KeyCode, KeyData, KeyValue는 언뜻 생각하면 현재 눌려진 키의 키값을 생성한다고 생각되겠지만, 사실 그렇지 않다. 키보드에서 어떤 키가 눌려졌다면, 그 값의 Virtual Key 값을 의미하는 것이다. 즉, 키보드에서 Caps Lock이 켜져 있든 그렇지 않든, d를 눌렀다면 KeyCode, KeyDa.. 더보기
delegate / event System.Windows.Forms.Form의 Paint 핸들러는, public delegate void PaintEventHandler(object objSender, PaintEventArgs pea); 의 형식으로 정의되어 있는 delegate이다. 사실, Form을 상속받는 Form을 하나 생성했을 때, 여기에 어떠한 paintEventHandler를 설치하지 않아도 기본적으로 배경은 그려진다. 이것은, 이미 설치되어 있는 PaintEventHandler가 존재한다는 말인데, 그것은 어디에 있을까? 그것은 System.Windows.Forms.Control에 이미 설치되어 있다. 즉, 다음과 같은 빈 깡통 Form을 하나 생성해보자. 이 Form이 화면에 그려질 때, 어떤 일이 발생할까? cla.. 더보기
ref, out 키워드 C#에서는 모든 타입은 값 타입 아니면 참조 타입이다. 특히, 클래스는 언제나 참조 타입이다. 그런데, 이렇게 된다면 문제가 생기는데, 리턴값은 하나만 정의할 수 있기 때문에 여러개의 값을 돌려주고 싶을 경우에는 곤란한 상황이 발생한다. 이것을 해결하기 위해, 시그내처에 ref 키워드를 붙여주면, 해당 파라미터들은 값이 아니라 참조로서 메서드로 넘겨지게 된다. 그렇다면 out 인자는? out으로 선언된 파라미터들은, ref와 비슷하지만, 사용되기 전에 초기화된다는 점이 다르다. ref로 선언된 파라미터들은 실제로 어떤 값이 들어있는지 신경쓰지 않지만, out으로 선언된 파라미터들은, 오로지 값을 담아서 내보내는 것만이 목적일 때 유용하게 사용된다. 이런 목적의 파라미터들을 매서드 내부에서 초기화해주는 것.. 더보기
C#의 delegate C#에서의 delegate는 C/C++의 함수 포인터와 쓰임새와 비슷하지만, 구조적인 면에서는 STL의 Functor와 닮은 꼴이며, 패턴으로 설명하면 Observer 패턴과 유사하다고 할 수 있다. 그런데, 재미있는 것은 delegate를 사용하려면, 반드시 최소한 하나 이상의 delegate로 선언된 것과 같은 메서드를 등록해주어야 한다는 것이다. 다음과 같은 코드를 보자. class DelegateTest { public delegate void ShowMessageHandler(); public void GeneralMessage() { System.Console.WriteLine("General Message"); } public void LogMessage() { System.Console.W.. 더보기
C++에서 C#으로의 전환, MSDN http://www.microsoft.com/Korea/MSDN/MSDNMAG/ISSUES/2001/ctocsharp/default.aspx C++ 개발자들이 C#을 사용하고자 할 때 반드시 읽어봐야 할 주의 사항. C/C++ 달인이라고 하더라도, C#은 그렇게까지 쉬운 상대는 아니다. 특히, C#은 이름에서 보듯이 C/C++과 비슷한 것 같으면서도, .NET Framework에 맞춰져 있는 언어라 C/C++의 기본적인 개념이 틀린 경우가 많다. 이러한 부분을 주의하지 않으면 문제가 되는 코드들을 작성할 수 있다. 이 MSDN 문서를 반드시 읽어보도록. 시중의 어지간한 C# 입문서보다, C/C++ 개발자들에게 훨씬 유용한 문서다. 더보기
C#에서의 static 키워드 C#에서의 static 키워드가 의미하는 바는, C/C++과 중요한 차이점이 있다. static이란 키워드는, C#이나 C/C++이나 저장 형태를 의미하는 것은 동일하며, 프로그램이 생성될 때 단 한번만 생성된다는 점은 동일하다. C/C++의 클래스, 데이터멤버, 메서드 등에 static이 쓰였다면 이것은 클래스가 인스턴스화 되기 전이나, 되고 난 다음 언제라도 이 멤버들에 접근할 수 있지만, C#에서 static으로 선언된 메서드나 필드들은, 반드시 인스턴스가 아닌, 클래스 자체에 접근해서 호출해야 한다. C#에서 Dummy라는 클래스가 선언되었다고 하자. 그리고, Dummy 클래스에서 static으로 StaticMethod()라는 메서드가 선언되었다면, 다음과 같은 호출은 허용되지 않으며, 클래스 자.. 더보기
struct, class in C# C#에서 구조체와 클래스는 의미가 조금 다르다. C++에서 클래스와 구조체는 근본적으로 차이가 없다. 다만, C++에서는 관습적으로 구조체는 액세스 지정자가 public이며, 클래스는 private라는 점만이 다를 뿐, 두 데이터형은 동일하다. 하지만, C#에서는 이 둘은 차이가 있다. 즉, 근본적으로 어떤 타입의 데이터이냐의 문제인데, 스택과 힙 영역 어디에나 데이터를 생성할 수 있는 C/C++과 달리, C#에서 클래스는 항상 힙 영역에 생성된다. 하지만, 구조체는 항상 스택에만 생성되는 것은 아니다. 구조체 역시 힙에 생성할 수 있다. 예를 들어, 구조체 Dummy가 선언되었다고 했을 때 Dummy dummy = new Dummy();라는 문장은, 암묵적으로 디폴트 생성자를 사용하여 힙에 Dummy를.. 더보기
C#에서의 boxing과 unboxing C#에서 boxing과 unboxing은, 포인터라는 존재가 없는 C#에서 어떻게 값(value)과 참조(reference) 타입을 다루는지 보여주는 중요한 개념이다. 이미 알고 있겠지만, C#에서는 포인터라는 개념이 존재하지 않으며, 사용자가 할당한 힙은 가비지 컬렉터(Garbage Collector)에 의해서 자동적으로 수거된다. 일반적으로, C/C++ 프로그래머들은 변수들이 자동 변수(auto variable)들은 스택 영역과 힙에 생성될 수 있다고 알고 있을 것이다. 즉, 스택에 생성되는 변수들에 대해서는 메모리 해제에 신경 쓸 필요가 없다. 그렇다면 C#에서는 어떠한가? C#에서도 변수들이 생성되는 위치에 차이가 있는가? 간단히 설명하면, MSIL에서, value 타입으로 선언된 변수들은 스택에.. 더보기