2011년 11월 28일 월요일

KeyEventArgs 의 Control 키와 Shift 키에 대하여.


WinForm의 키 이벤트 정보 인자로 KeyEventArgs가 있다.
이 이벤트 정보를 이용하는 이벤트는 다음 두 가지가 있다.
- KeyDown
- KeyUp

리스트뷰와 같은 컨트롤에서 여러개의 노드를 선택하기 위해서는 다음 방법을 사용한다.
1. Shift 키 + 방향 버튼
2. Control 키 + 방향 버튼

따라서 Shift 키 또는 Control 키가 눌려있는지 판별해야 할 필요가 있다.

해당 컨트롤의 KeyDown 이벤트 핸들러에서 키가 눌렀을 때 플래그값을 설정한다.


if (e.Control || e.Shift)

    key = true;




해당 컨트롤의 KeyUp 이벤트 핸들러에서 키가 눌렀다 띄었을 때 플래그값을 설정한다.


if ((e.KeyData == (Keys.LButton | Keys.ShiftKey)) || e.KeyData == Keys.ShiftKey)

     key = false;





의문스러운 것은 KeyUp 이벤트 핸들러에서 e.Control 과 e.Shift 값으로는 해당 이벤트 값을 잡을 수 없었다.
Control 키를 띄었을 때 e.KeyData == (Keys.LButton | Keys.ShiftKey) 

Shift 키를 띄었을 때e.KeyData == Keys.ShiftKey
아.. 왜 그런걸까??

우선 위와 같이 처리!


*) Conrol + a 키 처리
KeyDown 이벤트 핸들러에서


if (e.Control)

{
     if (e.KeyCode.ToString() == "A" || e.KeyCode.ToString() == "a")
     { ... }




*) Keboard Events - http://visualcsharptutorials.com

2011년 11월 24일 목요일

C# Conditional Methods


원문 : C# Conditional Methods - Black Wasp


C# 및 .NET Framework를 이용해 만들어진 어플리케이션은 conditional method (조건부 메소드) 를 포함할 수 있다. conditional method는 지정된 컴파일러 심벌이 정의되어 있을 경우만 호출되는 특별한 메소드 이다. 이 메소드를 사용하면 tracing 및 디버깅을 위한 코드를 더 이상적?!으로 만들 수 있다.


What are Conditinal Methods?

conditional method는 Conditional 어트리뷰터와 컴파일러 심벌 이름을 갖는 메소드이다. 지정한 컴파일러 심벌이 정의되었다면 코드 실행 시 conditional method가 실행된다. 지정한 컴파일러 심벌이 정의되어 있지 않다면 컴파일된 어셈블리에 포함되지 않는다.

목적?!
대부분의 경우 tracing 및 디버깅을 위한 용도로 사용한다.
이 경우 DEBUG 심벌을 사용한다. 디버깅 모드로 컴파일 시 컴파일 옵션에 자동으로 DEBUG 심벌이 추가되므로 디버깅시 어셈블리에 포함된다.
릴리즈 모드로 컴파일 시, DEBUG 심벌을 사용한 Conditional method는 빌드된 어셈블리에서 제외된다.

#if - #endif 와의 차이
#if - #endif 와 비슷하지만 중요한 차이점이 있다.
#if - #endif 에 둘러쌓인 부분은 지정된 심벌이 정의되지 않으면 빌드에서 제외된다.
conditional method 는 항상 빌드되어 최종 어셈블리에 포함된다. 지정한 컴파일 심벌이 존재하지 않으면 해당 메소드는 최종 어셈블리에 포함은 되지만 호출은 되지 않는다.

Conditional Method의 장점, 단점
단점으로 항상 conditional method가 어셈블리에 포함되기 때문에 어셈블리의 크기가 커진다.
장점으로는 하나의 어셈블리가 프로그램과 라이브러리에서 공유될 수 있다. 즉,  conditional method를 포함하는 하나의 어셈블리가 이 어셈블리를 호출하는 프로그램에 따라 다르게 사용될 수 있다. #if - #endif 를 사용하는 코드보다 깔끔하다?!는 장점도 있다.


Conditional Attribute

conditional 어트리뷰트를 적용할 수 있는 메소드는 void 리턴값을 갖어야 한다.
conditional 어트리뷰트는 하나의 string 매개 변수를 갖는다. 이 매개 변수에는 컴파일 심벌값이 들어가야한다.

ex)
[Conditional("DEBUG")]

public static void OutputTraceInformation()

{

    Console.WriteLine("Trace information");

}



2011년 11월 21일 월요일

Debugging Using Assertions


출처 : Debugging Using Assertions - BlackWasp


What is an Assertion?

Assertion은 유용한 디버깅 툴을 제공한다. 프로그램의 실행시간에 Assertion을 수행한다. 모든 Assertion은 필수 조건, Boolean 조건을 갖으며 항상 true가 됨을 예측한다. 만약 조건이 거짓이 된다는 것은 가정이 잘못됬다는 것이고 코드에 버그가 있다는 것이다. 이 때 프로그램을 계속 진행시키는것 보다는 코드를 중지시키고 문제를 해결하는게 정신건강에 좋다.

개발하는 동안 Assertion을 활성화 시키지만 프로그램이 개발 완료되어 사용자에게 전달할 때에는 Assertion을 비활성화 시킨다. .NET 프로그램은 Release모드로 컴파일된 어셈블리는 자동으로 Assertion이 제거되어진다.

Assertion은 private 메소드의 precondition 과 postcondition을 검증하는데 사용되기도 한다.

Assertion은 단지 디버깅의 목적만으로 사용될 수 도 있다. Assert 되는 것을 프로그램의 정상적이지 않은 처리로 여겨진다. 또는 예외 처리 메소드로 사용되어진다.


Debug.Assert Method
Debug 클래스의 Assert 정적 메소드를 이용하면 C# 코드에서 쉽게 Assertion을 생성할 수 있다. Debug 클래스는 System.Diagnostics 네임스페이스에 있다.

다음은 간단한 콘솔 데모 프로그램이다.

Debug 클래스를 사용하는 클래스 파일 최 상단에 네임스페이스를 선언한다.


        using System.Diagnostics;




        public static void Main(string[] args)
        {
            string inputString;
            int minutes;


            do
            {
                Console.WriteLine("Enter a number of minutes to add.");
                inputString = Console.ReadLine();
            } while (!int.TryParse(inputString, out minutes));


            ShowTimePlusMinutes(minutes);
            Console.ReadLine();
        }



        private static void ShowTimePlusMinutes(int minutes)
        {
            Debug.Assert(minutes >= 0);


            DateTime time = DateTime.Now.AddMinutes(minutes);
            Console.WriteLine("In {0} minutes it will be {1}", minutes, time);
        }



 간단히 Debug.Assert 메소드에 Boolean 조건식을 매개변수로 전달하여 사용할 수 있다. 이 조건식이 참이면 Assert를 통과하고 거짓이면 Assert 실패 대화상자가 출력된다.
 위 예제에서 ShowTimePlusMinutes 메소드에 Assert 메소드가 있다. minutes 값이 0보다 크거나 같으면 다음 코드로 이동하고, minutes 값이 0보다 작으면 Assertion Failed 대화상자가 출력된다. 대화상자에는 Assert 한 곳에서의 stack trace 가 출력된다.



Assertion Failed 대화상자는 3개의 옵션 버튼을 갖는다.

1. Abort (중단)
: 프로그램이 즉시 중단되고 종료된다.

2. Retry (다시 시도)
: Assert 한 곳에서 부터 Debug 모드로 들어간다.

3. Ignore
: Assertion을 무시하고 프로그램을 계속 동작시킨다.


Adding Assertion Messages
위 Assertion Failed 대화상자를 보면 X 아이콘 옆이 비어있는것을 볼 수 있다. Assert 메소드의 두 번째 매개변수를 전달하면 X 아이콘 옆에 설정한 메시지가 출력된다.


Debug.Assert(minutes >= 0, "Minutes must be zero or more");





 

X 아이콘 옆에 자세한 메시지도 추가할 수 있다. Assert 메소드의 세 번째 매개변수를 이용한다.


Debug.Assert(minutes >= 0, "Minutes must be zero or more", "The number of minutes was " + minutes);






Demo Program


2011년 11월 17일 목요일

[VS-] Breakpoints and Tracepoints in Visual Studio


원문 : Breakpoints and Tracepoints in Visual Studio - BlackWasp


 프로그램 코드를 디버깅할 때 원하는 위치에서 코드를 멈추게 하는게 중요해요!!
Visual Studio 에서는 breakpoint 를 이용하여 코드를 특정 위치에 멈추게 하며 Trace 정보를 출력시킬 수 도 있다.


What are Breakpoints?

Release 모드로 컴파일된 프로그램이 실행되었을 경우와 디버거가 활성화 되지 않을 경우 breakpoint를 이용할 수 없다.


Settings and Clearing Breakpoints

breakpoint는 프로그램이 실행될 때 실행되는 코드 라인과 클래스 라이브러리에 추가할 수 있다.
주석이나 공백 라인, 클래스 선언부에는 breakpoint를 추가할 수 없다.

테스트할 코드이다. 새로운 콘솔 응용프로그램을 만들고 다음 코드를 메인 메소드에 추가 추가!


for (int i = 1; i <= 12; i++)

{

    Console.WriteLine("Multiplication table {0}.\n", i);

    for (int j = 1; j <= 12; j++)

    {

        Console.WriteLine("{0} x {1} = {2}", j, i, i * j);

    }

    Console.WriteLine("\n");

}




Setting a Breakpoint

breakpoint 추가하는 방법 몇가지가 있는데 우선 Visual Studio의 메뉴를 이용한다. 이 경우 커서가 위치한 곳에 breakpoint가 찍힌다. 단축키 F9를 이용해도 된다.




맨 좌측에 빨간색 동그라미를 "Breakpoint Glyph" 라고 부른다고 한다. (실제로는 한 번도 못들어봤음 ㅋ)


F5키를 눌러 디버깅 모드로 돌입! 프로그램 실행 중 코드의 breakpoint를 만나면 프로그램은 break 모드로 들어간다.
break 모드에서 디버깅 툴을 이용해 코드를 단계별로 디버깅 할 수 있다. 다시 F5를 누르면 break 모드를 빠져나온다.

breakpoint는 맨 좌측 부분을 마우스로 클릭해서도 추가 가능!


Removing a Breakpoint

breakpoint를 추가하는 방법으로 breakpoint를 제거할 수 있다.
규모가 큰 프로그램을 디버깅 할 때 많은 breakpoint를 설정한다. 디버깅이 끝났다면 디버그 메뉴의 "Delete All Breakpoints"를 선택하여 모든 breakpoint를 제거할 수 있다.


Disabling Breakpoints

지정한 breakpoint를 해제하지 않고 일시적으로 비활성화 시킬 수 있다. 지정한 breakpoint에서 마우스 오른쪽 버튼을 누른 후 "Disable Breakpoint"를 선택해 준다. (커맨드 메뉴의 디버그 메뉴 에서도 가능) 비활성화된 breakpoit는 가운데 색이 빠진 원 모양으로 표시된다.






File Breakpoint Dialog

위와 같은 간단한 breakpoint를 생성하는 것 외에 Visual Studio 에서 breakpoint의 추가 설정을 할 수 있다.






활성화된 breakpoint 에서 마우스 오른쪽 버튼을 눌러 "Location..."을 선택한다.
File Breakpoint dialog box 에서 3가지 설정을 이용하여 breakpoint의 위치 정보를 설정한다.
- File           : breakpoint가 위치될 코드 파일의 파일 이름
- Line          : breakpoint가 위치될 코드 라인(행) 번호
- Character  :  breakpoint가 위치될 코드의 열 번호

Character 설정을 이용하면 한 라인에 여러개의 커맨드가 있을 때 break할 커맨드를 설정할 수 있다.


일반적으로 break 모드로 디버깅할때 소스 코드 파일은 반드시 컴파일된 파일과 일치해야 한다. 때때로 사소한 수정을 코드에 했지만 기존 breakpoint를 그대로 사용하고 싶은 경우가 있다. 이 때 "Allow the source code to be different from the original version"(소스 코드가 원래 버전과 일치하지 않아도 됨) 옵션을 선택해 준다.


Conditional Breakpoints

conditional breakpoints는 조건에 맞을때만 break모드로 들어간다. 조건은 Breakpoint Condition dialog box를 이용하여 지정한다.


Condition 체크박스를 체크해야 조건을 판별한다. 조건식을 텍스트박스에 입력한다.
조건은 두가지가 있다.
- Is true           : 텍스트박스의 조건이 참일때만 break 모드로 들어간다.
- Has changed : 조건의 값이 변경되었을 경우 break 모드로 들어간다.

테스트를 위해 조건식에 "i == 10"을 입력한다. 옵션은 "Is true" 옵션 선택.

프로그램을 디버그 모드로 실행시키면 i 가 10일 경우에만 break 모드로 들어간다.
*) 이 경우 File breakpoint 옵션에서 character값을 수정하여 "i<=12"에 breakpoint가 지정되어 있어야 한다.


Setting a Hit Count

모든 breakpoints 는 디버그 모드로 실행중일 동안 hit count를 유지한다. hit count는 0부터 시작하며 breakpoint로 break모드로 들어갈 경우 그 수가 증가한다. Breakpoint Hit Count dialog box를 통해 현재 hit count에 해당하는 행동을 설정할 수 있다.
breakpoint에 마우스 오른쪽 버튼을 클릭하여 컨텍스트메뉴에서 Breakpoint Hit Count dialog box를 불러온다.

옵션
- break always.
: 기본 설정으로 breakpoint로 매번 hit될 때마다 break 모드로 들어간다.

- break when the hit count is equal to.
: 이 설정으로 breakpoint가 단 한번만 활성화 된다. hit count가 텍스트박스에 입력한 값과 같을때만 활성화됨.

- break when the hit count is a multiple of.
: hit count 가 지정한 수의 배수일 경우만 break 모드로 들어간다.

- break when the hit count is greater than or equal to.
: hit count 가 지정한 수보다 크거나 같을 경우만 break 모드로 들어간다.




Breakpoint Filters

한글 Visual Studio 의 Breakpoint Filter dialog box의 설명을 보자!
(자주 사용하는 기능이 아니라 읽어만 봐서는...)


다른 추가 설정과 마찬가지로 breakpont의 마우스 오른쪽 버튼을 눌러 컨텍스트 메뉴에서 "Filter..."를 선택해서 호출한다.


Creating Tracepoints

breakpoint를 tracepoint로 변환하는 방법을 알아보자. tracepoint는 메시지를 출력하거나 매크로를 실행시킨다는 점을 제외하고선 breakpoint와 비슷한다. 게다가 tracepoint를 사용할 경우 프로그램의 실행 중단은 선택적이다.

breakpoint를 tracepoint로 변경하기 위한 dialog box를 실행시킨다. breakpoint 에서 마우스 오른쪽 버튼을 누른 후 컨텍스트 메뉴에서 "When Hit..." (적중될 때)를 선택하면 된다.



breakpoint를 tracepoint로 변경하기 위해 tracepoint가 실행될 경우 출력될 메시지 또는 실행될 매크로 또는 이 두 옵션 모두를 설정한다. 메시지를 출력하기 위해 "Print a message" (메시지 표시) 옵션을 체크한다. 메시지는 breakpoint 주변의 변수이름을 이용하여 변수값을 출력할 수 있다. ("{변수}" 형식 이용). 또한 현재 함수, 프로세스, 스레드 정보를 출력하는 키워드를 사용할 수 있다.

테스트를 위해 메시지 표시 텍스트박스에 다음과 같이 입력한다.
New multiplication table {i}

tracepoint를 만날때 마다 출력 메시지로 설정한 메시지는 Visual Studio의 출력 윈도우에 출력된다.





두 번째 옵션인 "Run a macro" 를 선택하여 tracepoint가 hit되었을 경우 실행할 매크로를 지정할 수 있다. 매크로는 Visual Studio가 미리 정의한 매크로를 사용할 수 있으며 또한 사용자가 작성한 매크로도  사용할 수 있다.

마지막 옵션인 "Continue execution" (계속 실행) 는 tracepont가 breakpoint 처럼 동작할 것인지를 설정한다. 만약 이 옵션이 선택되었을 경우 tracepoint는 출력 및 매크로 실행 후 계속 프로그램을 진행시킨다. 옵션이 체크 해제되었을 경우 breapoint 처럼 hit되었을 경우 프로그램을 break 모드로 들어가게 한다.


The Breakpoint Window

Visual Studio는 Breakpoint 윈도우를 통해 현재 프로젝트의 breakpoint 와 tracepoint를 관리할 수 있게 도와준다.
메뉴의 Debug -> Windows -> Breakpoints 선택






Demo program


 

2011년 11월 16일 수요일

[VS-] Visual Studio Debug and Release Modes


원문 : Visual Studio Debug and Release Modes - BlackWasp
*) 개인적인 학습(?!)을 위해 작성하였으므로 정확하지 않을 수 있습니다.


Native Code 와 마찬가지로 .NET Framework 로 개발된 소프트웨어는 Debug 모드와 Release 모드로 컴파일될 수 있다. 두가지 모드로 컴파일된 모듈은 큰 차이가 있다.


Release Mode

Release 모드로 컴파일 할 때 컴파일러는 결과 모듈이 효율적으로 실행될 수 있도록 이용 가능한 모든 최적화 작업을 수행한다.
일반적으로 결과 모듈은 빠르고 경량이지만 디버깅툴로 접근할 수 없다.


Debug Mode

개발중인 모듈을 컴파일 할 때 사용하는 모드로 추가적인 정보가 모듈에 포함된다. 모듈의 최적화 과정은 수행되지 않는다.
결과 모듈은 사이즈가 크고, 수행 속도가 느리며 효율적이지 않다. 하지만 디버깅 툴로 모듈에 접근할 수 있다.


Setting the Build Mode

빌드 모드를 변경하는 가장 간단한 방법은 Visual Studio 툴바에서 변경하는 것으로, 기본적으로 Debug, Release, Configuration Manager 가 있다. 툴바로 변경하게 되면 솔루션에 포함된 모든 프로젝트에 영향을 주게 된다.


Using the Configuration Manager


<이미지 출처 : http://www.blackwasp.co.uk/images/ConfigurationManager.png>

Configuration Manager 로 솔루션의 빌드 모드를 선택할 수 있다. Debug 및 Release 모드 외에 사용자의 솔루션에 새로운 설정을 생성할 수도 있다. (<New...>를 이용해서) 새로 설정한 빌드 모드를 솔루션의 각각의 프로젝트에 적용할 수 있다.
각각의 프로젝트의 플랫폼을 설정할 수 있으며, 솔루션 빌드 시 각각의 프로젝트의 빌드 여부도 결정할 수 있다.



2011년 11월 13일 일요일

Detecting File Changes with FileSystemWatcher


FileSystemWatcher 클래스에 대해 잘 설명해 놓았다.
Detecting File Changes with FileSystemWatcher

지정한 폴더의 Changed 이벤트에 대한 활용이 어렵지만 참고할 만 하다.