WinAPI QueryPerformanceCounter 함수와 Stopwatch 클래스를 이용해 두가지 버젼으로 구현하였다.

 

 

 

 

usSleep.zip

 

 

 

 

QueryPerformanceCounter를 이용한 us Sleep

 

 

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Threading;
 
namespace Some
{
    public class Sleep
    {
        [DllImport("Kernel32.dll")]
        private static extern bool QueryPerformanceCounter(out long lpPerformanceCount);
 
        [DllImport("Kernel32.dll")]
        private static extern bool QueryPerformanceFrequency(out long lpFrequency);
 
        private static long freq;
        private static double ufreq;
        private static double mfreq;
 
        static Sleep()
        {
            if (QueryPerformanceFrequency(out freq) == false)
            {
                throw new Win32Exception();
            }
            ufreq = freq / 1000000;
            mfreq = freq / 1000;
        }
 
        public Sleep()
        {
            USleep(0);
        }
 
        public void USleep(double us)
        {
            long startTime = 0;
            long nowTime = 0;
 
            QueryPerformanceCounter(out startTime);
 
            while (((nowTime - startTime) / ufreq) < us)
            {
                QueryPerformanceCounter(out nowTime);
            }
        }
 
        public void MSleep(double ms)
        {
            long startTime = 0;
            long nowTime = 0;
 
            QueryPerformanceCounter(out startTime);
 
            while (((nowTime - startTime) / mfreq) < ms)
            {
                QueryPerformanceCounter(out nowTime);
            }
        }
    }
}

 

 

 

 

 

Stopwatch Class를 이용한 us Sleep

 

 

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
 
namespace Some
{
    class SWSleep
    {
        long freq = 0;
        public SWSleep()
        {
            this.freq = Stopwatch.Frequency;
            USleep(0);
        }
 
        internal void USleep(int us)
        {
            double sec = (double)us / 1000000;
            Stopwatch sw = Stopwatch.StartNew();
            while (sw.ElapsedTicks / (double)freq < sec)
            {
            }
        }
 
        internal void MSleep(int ms)
        {
            double sec = (double)ms / 1000;
            Stopwatch sw = Stopwatch.StartNew();
            while (sw.ElapsedTicks / (double)freq < sec)
            {
            }
        }
    }
}

 

DataGridView의 특정 Column에 자동완성 기능을 추가할 때는 아래와 같이 진행하시면 됩니다.

 

특정 Column이 셀 편집을 시작한다면, 내부의 TextBox Control의 AutoCompleteMode를 지정하면 됩니다.

 

 

 

 

 

AutoCompleteStringCollection auto = new AutoCompleteStringCollection();

 
string[] hints = new string[] { "Hint0""Hint1""Hint2""Hint3" };
auto.AddRange(hints);
 
this.dgvView.EditingControlShowing += 
       new DataGridViewEditingControlShowingEventHandler(dgvView_EditingControlShowing);

 

 

 

 

void dgvView_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)

{
    int column = this.dgvView.CurrentCell.ColumnIndex;
    string headerText = this.dgvView.Columns[column].Name;
 
    if (headerText.Equals("chName"))
    {
        TextBox tb = e.Control as TextBox;
 
        if (tb != null)
        {
            tb.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
            tb.AutoCompleteCustomSource = auto;
            tb.AutoCompleteSource = AutoCompleteSource.CustomSource;
        }
 
    } 
}

 

 

C#으로 개발을 하다보면 Win32API나 Unmanaged 코드를 작성 해야 할 때가 있습니다.

 

마샬링 작업을 일일이 하기엔 너무 시간이 오래걸려서, 구글링 해보니 좋은 툴이 있었습니다.

 

http://clrinterop.codeplex.com/releases/view/14120

 

위의 링크로 이동하셔서  PInvoke Interop Assistant Installation 을 클릭해 설치하시면

 

디폴트로 진행시 C:\Program Files (x86)\InteropSignatureToolkit 의 경로에 설치가 완료됩니다.

 

SigImp Search는 Win32API에 관련 함수 및 구조체를 검색합니다.

 

 

 

 

SigImp Translate Snippet는 Native Code Snippet에 Unmannaged 코드에서 노출해주는 구조체 및 함수 등등을 작성 한 후  

 

Generate 버튼을 클릭하면 C# 또는 VisualBasic의 PInvoke 형식으로 변경해줍니다.

 

 

회사에서 MSDN 구독을 해서 Visual Studio 2013 Professional 로 갈아탔습니다.

 

그런데.............ㅠㅠ VS2010 Professional에 있던 MS 자동테스트 만들기 기능이 없었습니다.....ㅠㅠ

(제가 못찾은거일수도.......혹시 아시는분 알려주세요..ㅠㅠ)

 

구글링 끝에 Unit Test Generator 라는 Visual Studio 확장을 찾았습니다.

 

Visual Studio 2013 Professional 에서 테스트 결과 잘 만들어 지는 것을 확인했습니다.

 

http://visualstudiogallery.msdn.microsoft.com/45208924-e7b0-45df-8cff-165b505a38d7

 

위의 링크로 들어가셔서 다운로드 받고 간단히 설치하시면 됩니다.

 

주의 하실 점은 Class 및 메서드의 접근자가 public 이여야만 자동 생성됩니다.

 

'.Net > Unit Test' 카테고리의 다른 글

Rhino.Mocks 목,스텁 개체 생성시 internal 관련 오류  (2) 2013.09.27

많은 양의 데이터를 보여줄때 깜빡임이 있을 때에는 더블버퍼링을 이용합니다.

 

Contorl 클래스의 DoubleBuffered 속성을 true로 주면 됩니다.

 

    public class ExtendGridView : DataGridView     {         public ExtendGridView()         {             base.DoubleBuffered = true;         }     }

 

 

 

 

DoubleBuffred 속성이 protected 인지라 상속을 받아야 하는데 리플렉션을 이용해서 간단히 속성을 변경 할 수 있습니다.

 

    using System.Reflection;     using System.Windows.Forms;     public static class ControlHelper     {         /// <summary>         /// 컨트롤의 DoubleBuffered 속성을 변경합니다.         /// </summary>         /// <param name="contorl"></param>         /// <param name="setting"></param>         public static void SetDoubleBuffered(this Control contorl, bool setting)         {             Type dgvType = contorl.GetType();             PropertyInfo pi = dgvType.GetProperty("DoubleBuffered"BindingFlags.Instance | BindingFlags.NonPublic);             pi.SetValue(contorl, setting, null);         }     } 

 

 

//업데이트 시작
this.gridView1.BeginDataUpdate();
                    
//바인딩 전의 왼쪽 좌표
int leftCoord = this.gridView1.LeftCoord;
 
//바인딩 전의 보여지는 Row Index
int viewRowIndex = this.gridView1.TopRowIndex;
 
//바인딩
this.gridView1.Columns.Clear();
this.gridControl1.DataSource = value;
 
//바인딩 전의 보여지는 영역 재설정
this.gridView1.LeftCoord = leftCoord;
this.gridView1.TopRowIndex = viewRowIndex;
 
//업데이트 종료
this.gridView1.EndDataUpdate();

 

 

 

private void flowLayoutPanel1_Layout(object sender, LayoutEventArgs e)
{
    flowLayoutPanel1.Controls[0].Dock = DockStyle.None;
    for (int i = 1; i < flowLayoutPanel1.Controls.Count; i++)
    {
        flowLayoutPanel1.Controls[i].Dock = DockStyle.Top;
    }
    flowLayoutPanel1.Controls[0].Width = flowLayoutPanel1.DisplayRectangle.Width - 
           flowLayoutPanel1.Controls[0].Margin.Horizontal;
    flowLayoutPanel1.Controls[0].Height = flowLayoutPanel1.DisplayRectangle.Height/5; 
}

 

 

 

- 스크롤 없이 Dock

for (int i = 0; i < flowLayoutPanel1.Controls.Count; i++)

{

    flowLayoutPanel1.Controls[i].Width = flowLayoutPanel1.DisplayRectangle.Width - flowLayoutPanel1.Controls[0].Margin.Horizontal;

    flowLayoutPanel1.Controls[i].Height = ((flowLayoutPanel1.DisplayRectangle.Height) / this.flowLayoutPanel1.Controls.Count) 

        - (flowLayoutPanel1.Controls[0].Margin.Vertical);

}

 

1.  XmlDocument 클래스를 이용해 XML 작성하기

 

아래와 같은 XML 파일을 작성하는 예제를 진행하겠습니다.

 

<?xml version="1.0" encoding="utf-8"?>

<Students>

  <Student Number="1" Name="김동영">

    <Score>

      <Korean>10</Korean>

      <English>20</English>

      <Math>30</Math>

      <Science>40</Science>

      <Music>50</Music>

      <Art>60</Art>

    </Score>

  </Student>

</Students>

2 작성할 XML 내용

 

XmlDocument doc = new XmlDocument();
 
//"<?xml version='1.0' ?>" 생략 가능
doc.LoadXml("<Students></Students>");
 
//XmlElement rootElem = doc.CreateElement("Students");
//doc.AppendChild(rootElem);

3 루트 생성

먼저 XmlDocument 개체를 생성합니다. LoadXml 메서드를 호출하게 되면 XML 형식의 문자열을Load 할 수 있습니다. 혹은 Students Element를 직접 생성해서 자식 Element로 설정 할 수 있습니다.

 

 

 

 
XmlElement newElem = doc.CreateElement("Student");
           
XmlAttribute newAttr = doc.CreateAttribute("Number");
newAttr.Value = "1";
newElem.Attributes.Append(newAttr);
 
newAttr = doc.CreateAttribute("Name");
newAttr.Value = "김동영";
newElem.Attributes.Append(newAttr);
 
…
 
doc.DocumentElement.AppendChild(newElem);

4 Student 노드 생성 및 Attribute 정의

먼저 XmlDocument 클래스의 CreateElement 메서드를 호출하여 Student Element를 생성합니다. Student Attribute“Number”“Name”을 가지고 있기 때문에, XmlDocument 클래스의 CreateAttribute 메서드를 통해 Attribute 개체를 생성합니다. “Number” Attribute에는 “1”, “Name” Attribute에는 김동영이라는 값으로 설정하였습니다. 생성한 Attribute는 해당 Element Attributes 속성에 있는 Append 메서드를 이용해 붙이게 됩니다. 생성한 Student Element는 루트 개체인 DocumentElement 속성의 자식으로 설정합니다. DocumentElement는 첫번째 Element를 가리킵니다.

 

 

 

XmlElement subNode = doc.CreateElement("Score"); XmlElement score = doc.CreateElement("Korean"); score.InnerXml = "10"; subNode.AppendChild(score); score = doc.CreateElement("English"); score.InnerText = "20"; subNode.AppendChild(score); score = doc.CreateElement("Math"); score.InnerText = "30"; subNode.AppendChild(score); score = doc.CreateElement("Science"); score.InnerText = "40"; subNode.AppendChild(score); score = doc.CreateElement("Music"); score.InnerText = "50"; subNode.AppendChild(score); score = doc.CreateElement("Art"); score.InnerText = "60"; subNode.AppendChild(score); newElem.AppendChild(subNode);

5 Score 노드 생성 및 과목별 점수 노드 생성

Student Element를 생성하는 것과 동일하게 XmlDocument 클래스의 CreateElement 메서드를 호출하여 Score Element를 생성합니다. <Node> </Node> Node 안에 값을 작성하기 위해서는 XmlElement 개체의 InnerText 속성을 정의하면 됩니다. 생성한 Element Score Element의 자식 Element 이기 때문에 AppendChild 메서드를 이용해 뒤쪽에 붙여줍니다.

 

InnerXml 속성을 이용해 <XML></XML>” 값을 설정하면 아래와 같습니다. Node1 Element InnerXml, Node2 Element InnerText에 값을 설정 하였습니다. InnerText를 실제로 보면 “<XML></XML>” 이라는 문자열이 값으로 설정됩니다.

<Node1>

        <XML>

        </XML>

</Node1>

<Node2>&lt;XML&gt;&lt;/XML&gt;</Node2>

6 InnerText InnerXml의 차이

 

 

 

XmlDocument 클래스의 InnerXml 속성에 접근하여 작성한 XML을 확인 할 수 있습니다. 파일로 내보내기 위해서는 XmlTextWriter 클래스를 이용합니다. XmlTextWriter 개체의 Formatting 속성을 Formatting.Indented로 설정하면 XmlTextWriter 개체의 속성 Indentation IndentChar 값으로 자식 요소가 들여쓰기가 되어 저장됩니다.

 
using (XmlTextWriter writer = new XmlTextWriter(xmlFilePath, Encoding.UTF8))
{
    writer.Formatting = Formatting.Indented;
    doc.Save(writer);
}

7 XML 파일로 작성

 

 

 

2.  XmlDocument 클래스를 이용해 XML 읽기 및 수정

XmlDocument 개체를 이용해 위에서 작성한 XML 파일의 데이터를 읽기 및 수정하는 방법입니다. 예제에서는 XML 파일에 접근 하므로 XmlDocument Load 메서드를 이용하였습니다.

 

 
XmlDocument doc = new XmlDocument();
doc.Load(xmlFilePAth);

8 XmlDocument 개체 생성 및 Load 메서드 호출

Load 메서드를 호출한 후 InnerXml 속성을 확인하여 XML 내용이 제대로 메모리에 로드가 되었나 확인 할 수 있습니다.

 

 

 

XmlNodeList stuNodes = doc.SelectNodes("Students/Student");
 
foreach (XmlElement stuNode in stuNodes)
{
    Console.WriteLine("학생의 이름 : {0}", stuNode.Attributes["Name"].Value);
    Console.WriteLine("학생의 번호 : {0}", stuNode.Attributes["Number"].Value);
 
    foreach (XmlElement scoreNodes in stuNode.ChildNodes)
    {
        Console.WriteLine("영어 점수 : {0}", scoreNodes["English"].InnerText);
        scoreNodes["English"].InnerText = "-100";
        Console.WriteLine("영어 점수 -100으로 변경");
    }
}

9 Student 노드의 Attribute Child Node에 접근

XmlDocument 클래스의 SelectNodes 메서드를 이용해 Node들을 검색합니다. SelectNodes 메서드는 Xpath 식과 일치하는 노드의 목록을 검색합니다. Students의 노드에서 하위인 Student 를 검색하고 싶다면

"Students/Student" XPath를 인자로 넘깁니다. 

맨 처음에 검색될 노드만 찾고자하면 SelectSingleNode 메서드를 이용하면 됩니다. ※더 자세하게 “Xpath 탐색을 사용하여 노드를 검색하고자 한다면 를 클릭해서 MSDN에서 확인하십시오

 

 Attribute는 노드의 Attributes 개체에서 인덱싱을 통해 접근 할 수 있습니다.

 

Attribute는 노드의 Attributes 개체에서 인덱싱을 통해 접근 할 수 있습니다.

 

Student 노드의 하위 노드는 ChildNodes 속성에 인덱싱을 통해 접근 할 수 있습니다.

 

 

 

doc.Save(xmlFilePAth);

10 XML 파일 수정

Load XML파일 경로를 이용해 Save 메서드를 호출하면 변경된 내용이 저장되는 것을 확인 할 수 있습니다.

 

 

 

 

 

/// <summary>
/// Student XML 파일의 내용을 하나씩 접근하여 출력합니다.
/// </summary>
/// <param name="xmlFilePAth"></param>
private static void PrintStudentXml(string xmlFilePAth)
{
    XmlDocument doc = new XmlDocument();
    doc.Load(xmlFilePAth);
 
    XmlNodeList nodes = doc.SelectNodes("Students/Student");
    Console.WriteLine(TabInsertToHead("<Students>", 0));
 
    foreach (XmlElement node in nodes)
    {
        Console.Write(TabInsertToHead("<Student", 1));
 
        //Student Attribute
        foreach (XmlAttribute attr in node.Attributes)
        {
            Console.Write(" {0}={1}", attr.Name, attr.Value);
        }
        Console.WriteLine(">");
 
        //Student Score Element
        foreach (XmlElement stuScore in node)
        {
            //Student Score Child Element
            foreach (XmlElement score in stuScore)
            {
                Console.Write(TabInsertToHead("<", 2));
                Console.Write(score.Name);
                Console.Write(">");
 
                Console.Write(score.InnerText);
 
                Console.Write("</");
                Console.Write(score.Name);
                Console.WriteLine(">");
            }
        }
 
        Console.WriteLine(TabInsertToHead("</Student>", 1));
    }
 
    Console.WriteLine(TabInsertToHead("</Students>", 0));
}
 
/// <summary>
/// 문자열 앞 부분에 Tab을 tabCount 만큼 삽입합니다.
/// </summary>
/// <param name="str"></param>
/// <param name="tabCount"></param>
/// <returns></returns>
private static string TabInsertToHead(string str, int tabCount)
{
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < tabCount; i++)
    {
        sb.Append("\t");
    }
    sb.Append(str);
 
    return sb.ToString();
}

11 Attribute Element에 접근

XmlDocument 개체의 InnerXml 속성에 접근하면 쉽게 출력 할 수 있지만, XML 노드 및 속성에 각각 접근할 수 있음을 나타내기 위해 작성하였습니다.

 

 

 

.NET 개발 표준 가이드는 Microsoft 고객들을 위해 배포되었습니다. 본 문서는 상업적 목적으로 재 활용될 수 없으며, 기업 내부에서 사용할 목적으로는 자유롭게 수정, 보완하실 수 있습니다. .NET 개발 표준 가이드 문서에 대한 모든 권리는 마이크로소프트()에 있으며, 이 개발 표준 가이드에 대한 기술지원은 제공되지 않습니다.

 

 

NET 표준개발가이드.doc

 

알고리즘군을 정의하고 각각을 캡슐화하여 교환해서 사용할 수 있도록 만든다.
스트래티지를 활용하면 알고리즘을 사용하는 클라이언트와는 독립적으로 알고리즘을 변경 할 수 있다.

 

 

 

 

 

 

 

 

 

static void Main(string[] args)

        {

            Man badGuy = CreateBadGuy();

 

            Man superMan = CreateSuperMan();

 

            badGuy.Attack();

            superMan.Attack();

 

            Console.ReadKey();

        }

 

        private static Man CreateSuperMan()

        {

            SuperMan superMan = new SuperMan();

            superMan.AttackBehavior = new SuperManAttackBehavior();

            return superMan;

        }

 

        private static Man CreateBadGuy()

        {

            BadGuy badGuy = new BadGuy();

            badGuy.AttackBehavior = new BadGuyBehavior();

            return badGuy;

        }

  

 

 

 

 

AboutStrategyPattern.zip

 

+ Recent posts