블로그 이미지
Every unexpected event is a path to learning for you. blueasa

카테고리

분류 전체보기 (2794)
Unity3D (852)
Programming (478)
Server (33)
Unreal (4)
Gamebryo (56)
Tip & Tech (185)
협업 (11)
3DS Max (3)
Game (12)
Utility (68)
Etc (98)
Link (32)
Portfolio (19)
Subject (90)
iOS,OSX (55)
Android (14)
Linux (5)
잉여 프로젝트 (2)
게임이야기 (3)
Memories (20)
Interest (38)
Thinking (38)
한글 (30)
PaperCraft (5)
Animation (408)
Wallpaper (2)
재테크 (18)
Exercise (3)
나만의 맛집 (3)
냥이 (10)
육아 (16)
Total
Today
Yesterday

종료버튼 클릭시 최소화 시키기

 

1. 상태 Flag 변수 선언

2. Form_Closing Event에서 if(flag) else 문 처리

3. WndProc함수 재 정의

 

        private bool isExit = false; //선언

 

         private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            // 진짜 종료
            if (isExit == true)
            {

                 //...기타작업

                e.Cancel = false;
            }
            // 숨김
            else
            {

                this.hide();
                e.Cancel = true;
            }
        }

 

위처럼 이벤트 처리하면 우선 X버튼 클릭시 종료가 되지 않고 숨어버리게 되고

특정 버튼 클릭시 isExit 값을 변경해 주면 종료가 되게 된다.

 

하지만, 문제점!

윈도우 종료 시킬때 프로그램이 종료되지 않는다!ㅋㅋㅋ

 

그러면 아래처럼 정의해주면 끝~ㅋㅋㅋ

 

        protected override void WndProc(ref Message m)
        {
            UInt32 WM_QUERYENDSESSION = 0x11;   // Logoff or shutdown

            /*----------------------------------------------------*/
            /* 윈도우 종료시에 종료시켜 버린다.                   */
            /*----------------------------------------------------*/
            if (m.Msg == WM_QUERYENDSESSION)
            {
                isExit = true;
            }


            base.WndProc(ref m);
        }

반응형
Posted by blueasa
, |

@ 기호
@ 기호를 사용하면 문자열 생성자가 이스케이프 문자와 줄 바꿈을 무시하도록 할 수 있습니다.
@ 기호 뒤 문자열은 형태가 그대로 보존 된다고 보시면 됩니다. 이스케이프 문자를 무시하는 것이죠

아래 예제에서 p1 과 p2가 같은 결과를 보여 줍니다.
 
string p1 = "\\\\My Documents\\My Files\\";
string p2 = @"\\My Documents\My Files\";


출처 : http://www.hoons.kr/Board.aspx?Name=QACSHAP&Mode=2&BoardIdx=33871&Key=Title&Value=%40%22
반응형
Posted by blueasa
, |

           string strFullPathName;
            string strDirectoryName;
            string strFileName;

 

            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "실행화일(exe)|*.exe";

 

            if (DialogResult.OK == openFileDialog.ShowDialog())
            {
                strFullPathName = openFileDialog.FileName;

                strDirectoryName = System.IO.Path.GetDirectoryName(strFullPathName);
                strFileName = System.IO.Path.GetFileName(strFullPathName);

 

                MessageBox.Show(strFullPathName);
                MessageBox.Show(strDirectoryName);
                MessageBox.Show(strFileName);

             }

 

화일작업을 하다보면 화일명 또는 디렉토리명만 가져오고 싶은 경우가 있다..

 

이런경우 어떻게 하면될까..?

 

예를들어, C:\Windows\System32\aa.exe  가 있다고 하면

 

Full Path == "C:\Windows\System32\aa.exe"

Directory Name  == > "C:\Windows\System32"

File Name ==> "aa,exe"

 

이런식이다..

 

 

C++에서는 "\"문자찾아서 잘라내기 했던 기억이 있다.

 

하지만, C#에서는 이를 위한 클래스가 있다.

Path.GetDirectoryName()과 Path.GetFileName()이 그것이다..

 

필요할때 쓰면될것 같다. ^^

 

 

 

 

 

또하나.. 시스템 폴더명을 알아보자..

 

시스템폴더는 OS에 따라 Windows\System32가 될수도 있고, Winnt\System32가 될수있다.

 

            string strSysDir = Environment.SystemDirectory.ToString();
            MessageBox.Show(strSysDir);

 

위와같이 Environment.systemDirectory()를 이용하면 된다. ^^


출처 : http://club.paran.com/club/home.do?clubid=eypgworld-bbsView.do?menuno=2509143-clubno=1078741-bbs_no=0PIGp

반응형

'Programming > C#' 카테고리의 다른 글

C# 종료버튼 클릭시 최소화 시키기  (0) 2010.07.20
@" 는 무슨 의미인가요?  (0) 2010.07.20
은양의 프로그래밍 세상  (0) 2010.07.19
이펙티브 C# - 요점 정리  (0) 2010.07.19
Form Show()/Hide()  (0) 2010.07.19
Posted by blueasa
, |
반응형
Posted by blueasa
, |
반응형
Posted by blueasa
, |

Form Show()/Hide()

Programming/C# / 2010. 7. 19. 18:26

우선 생성될  Form3의 OnClose를 약간 수정합니다.

class Form3
{
    // 창 우상단의 닫기 버튼을 누르면 발생하는 이벤트 헨들러
    // 기본 동작은 창을 죽이므로 죽이지 말고 그냥 Hide 시킴
    // OnFormClosed를 오버라이드 하세요.
    protected override void OnFormClosed(FormClosedEventArgs e)
    {
        // 창을 숨기기만 함
        this.Hide();

        // 기본 동작을 취하지 않음
        // base.OnFormClose(e);
    }
}

다음 폼을 생성시킬 부모 폼의 생성자 내에서 미리 하나 만들어 놓으시고,

Form3 frm = null;
Form1()
{
    frm = new Form3();
}

...

private void OnClickedBtn(object sender, EventArgs e)
{
   // 창이 보이지 않는 경우에만 Show 시킴
   if(frm.Visible == false)
        frm.Show();
}

반응형

'Programming > C#' 카테고리의 다른 글

은양의 프로그래밍 세상  (0) 2010.07.19
이펙티브 C# - 요점 정리  (0) 2010.07.19
Random Class를 파해쳐 보자!  (0) 2010.07.16
화살표 그리기(.NET Pen Class)  (0) 2010.07.16
.NET 중복 실행 방지  (0) 2010.07.16
Posted by blueasa
, |

어제 프로젝트 관련된 코딩을 하다가 난수를 써야 할 일이 있어서
C#의 Random Class에 관해 알아 보았다!

사실 Random Class의 사용방법은 그리 복잡하지도 어렵지도 않지만;
내가 만들고 싶은 난수가 적절히 만들어 지지 않아 몇시간을 테스트한김에
이와 관련된 포스팅을 하게 되었다;

예전 C언어나 C++의 rand() 함수를 사용할때는

int random = rand()%50;
위의 코드를 수행하게 되면 random 변수에는 에는 0부터 49까지 난수가 들어가게 된다;
rand()에sms seed 값이 있어 저렇게만 수행할 경우
만약 랜덤한 수가 1 3 6 2 6 순으로 나왔다면; 프로그램을 껏다 켜도 똑같은 패턴으로 나오게 된다;
그래서 아래의 항목을 추가하게 되면 그것을 막을 수 있었다;

srand(time(NULL)); // 시간에 따른 난수 발생, 없을경우 실행때마다 같은 난수가 발생한다.


이제 C# 의 Random Class를 보자;

사용법 정말 간단하다;

Random r  = new Random();

생성자는 오버로딩 되어있어 생성시 시드값을 정할수 있고! 정하지 않을수 있다;

정할경우 위에 말한대로 계속 똑같은 패턴의 난수가 발생하며 디폴트일 경우에는 시스템의 시간을 이용하여 
시드값을 정하기 때문에 매번 다른 패턴의 난수
가 발생한다;

제공하는 매소드를 알아보자;

r.Next() : 범위가 없는 랜덤한 값을 리턴한다
r.Next(int maxValue) : 난수의 범위의 상한을 지정
r.Next(int minValue, int maxValue) : 난수의 범위의 하한과 상한을 지정!


여기서 중요한것은 난수의 하한은 난수에 포함 되지만 상한은 포함 되지 않는다는것이다;
즉 1부터 10의 값을 난수로 얻고 싶을때 Next(1,10); 을 호출하면 10은 죽어도 안나온다는 말인다;;
10을 난수로 얻고 싶다면 Next(1,11)을 호출 해야한다;

그외에
r.NextBytes()
r.NextDouble() 
메소드가 있는데 int값만 필요해서 사용하지는 않았지만 메소드 명으로 쉽게 짐작 할수 있다;

이제 본론으로 들어가서 이렇게 간단한 Random Class의 사용방법을  포스팅을 하게 된 이유는
내가 발생하고 싶은 난수가 특정시간에 여러개의 객체를 생성할때 각각의 객체마다 다른 
난수를 가지고 있게 하고 싶었지만 Seed값을 기본적으로 시간을 사용하기 때문에 
할수가 없어서이다;

다음의 예제를 보면;
class Program
{
        static void Main(string[] args)
        {
            for (int i = 0; i < 10; i++)
            {
                Item item = new Item();
            }
        }
}

class Item
{
        int num1;
        int num2;
        public Item()
        {
            Random r = new Random();
            num1 = r.Next(1, 100);
            num2 = r.Next(100, 200);
            Console.WriteLine("{0} , {1}", num1, num2);
        }
}



매우 간단한 구조이다 Main()에서는 Item 객체를 10개 만들고 
Item 객체의 생성자에서는 난수를 2개 (각각 1~99, 100~199 범위의 값) 발생시켜
출력한다;

어떤 결과가 나올까? 10개의 객체는 각각 다른 난수를 가지고 있을까?

-- 실행 결과 --

결과처럼 '아니오' 이다; 

이와 같은 발생의 이유는 기본적으로 난수발생의 시드가 시간이기 떄문이다;
위에 예제처럼 빠르게 10개의 객체를 생성할 경우 시드가 같아져 같은 결과가 나오는것이다;

어떻게 해결할까?

밑의 두가지 예제의 차이를 알게되면 쉽게 해결 가능하다;
예제1)
Random
r = new Random();
for (int i = 0; i < 10; i++)
{
     Console.WriteLine("{0}", r.Next());               
}

예제2)
for (int i = 0; i < 10; i++)
{
     Random r = new Random();
     Console.WriteLine("{0}", r.Next());
}

--결과 화면--


화면에서 보다싶이 Random 객체를 빠르게 10번 생성한 예제 2에서는  같은 번호가 나왔고
객체를 재사용한 예제1에서는 다른 결과가 나왔다;


이 차이를 이용해 위에서 실패한 Item class에 랜덤한값을 배치 할수 있는것이다;

Random 객체를 static으로 두고 하나만 계속 사용한다면 위의 예제도 우리가 원하는 난수를 갖게 될것이다;


출처 : http://crynut84.tistory.com/15

반응형

'Programming > C#' 카테고리의 다른 글

이펙티브 C# - 요점 정리  (0) 2010.07.19
Form Show()/Hide()  (0) 2010.07.19
화살표 그리기(.NET Pen Class)  (0) 2010.07.16
.NET 중복 실행 방지  (0) 2010.07.16
App.Config XML읽고 쓰기..  (0) 2010.07.15
Posted by blueasa
, |

안녕하세요? 맨날맑음입니다.

화살표를 그려야 할 일이 생겨서 어떻게 그릴까 생각하다가, Line을 여러개 그려서 화살표를 만들려고 했습니다.
선의 각도에 따라 화살표 머리 부분의 각도가 변하기 때문에 수학을 못하는 저로써는 화살표 그리는 것 조차도 힘든일이 었습니다.

하지만! .NET의 Pen 클래스는 Line의 끝점들의 모양을 변경시켜 주는 기능을 제공합니다.
Pen 클래스의 좀더 자세한 설명은 아래의 MSDN 도움말을 참조 하시면 됩니다.
http://msdn.microsoft.com/ko-kr/library/system.drawing.pen(en-us,VS.85).aspx

MSDN에서 Pen 클래스의 속성을 보면 StartCap 과 EndCap이 있습니다. 이것이 선의 끝모양을 지정하는 속성입니다. 그럼 선의 시작과 끝 모양을 화살표로 바꾸어 보겠습니다.

Pen pen = new Pen(Color.Blue, 6);
pen.StartCap = LineCap.ArrowAnchor;
pen.EndCap = LineCap.ArrowAnchor;
위의 소스에서 처럼 Pen 객체를 생성하고, 해당하는Cap 속성을 바꿔주는 아주 간단한 방법으로 끝모양을 바꿔줄 수 있습니다.  LineCap 사용을 위해서는 using System.Drawing.Drawing2D;을 해주셔야 합니다.
화살표 모양 이외에도 여러 모양을 지정 할 수 있습니다. LineCap 을 살펴 보면 열거형으로 되어 있습니다. 각각의 멤버의 의미를 보면 다음과 같습니다.
Flat : 일직선 형태의 끝 모양을 지정합니다.
Square : 정사각형 형태의 선 끝 모양을 지정합니다.
Round : 둥근 선 끝 모양을 지정합니다.
Triangle : 삼각형 선 끝 모양을 지정합니다.
NoAnchor : 앵커를 지정하지 않습니다.
SquareAnchor : 정사각형 앵커 선 끝 모양을 지정합니다.
RoundAnchor : 둥근 앵커 끝 모양을 지정합니다.
DiamondAnchor : 다이아몬드 앵커 끝 모양을 지정합니다.

ArrowAnchor : 화살표 모양의 앵커를 지정합니다.
Custom : 사용자 지정 선 끝 모양을 지정합니다.

AnchorMask : 선 끝 모양이 앵커 모양인지 여부를 검사하는 데 사용되는 마스크를 지정합니다.
아래와 같이 간단하게 Windows Form 프로젝트를 생성해서 Paint 이벤트 핸들러에서 화살표를 그려 보겠습니다.

using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            this.Paint += new PaintEventHandler(Form1_Paint);
        }

        void Form1_Paint(object sender, PaintEventArgs e)
        {
            Pen pen = new Pen(Color.Blue, 6); //Pen 객체 생성
            pen.StartCap = LineCap.ArrowAnchor; //Line의 시작점 모양 변경
            pen.EndCap = LineCap.ArrowAnchor; //Line의 끝점 모양 변경
            e.Graphics.DrawLine(pen, 20, 50, 300,50); //Line 그리기
        }
    }
}
 
이와같이 복잡한 화살표 알고리즘 없이 Pen 클래스의 속성 변경 만으로도 간단하게 화살표를 그릴 수 있습니다.
참 쉽죠잉~


출처 : http://crynut84.tistory.com/48
반응형

'Programming > C#' 카테고리의 다른 글

Form Show()/Hide()  (0) 2010.07.19
Random Class를 파해쳐 보자!  (0) 2010.07.16
.NET 중복 실행 방지  (0) 2010.07.16
App.Config XML읽고 쓰기..  (0) 2010.07.15
ini파일을 간단히...사용하자.  (0) 2010.07.15
Posted by blueasa
, |
안녕하세요? 맨날맑음 입니다.

어플리케이션을 개발 하다 보면 같은 프로그램이 두번 실행 되지 않아야 하는 경우가 종종 생깁니다.
이를 해결 하기 위해 여러 방법이 있지만.. 이번 포스팅에 소개 할 내용은 커널 동기화 객체 중 하나인 뮤텍스(Mutex)를 이용하여 해결하는 방법을 소개하려 합니다.

Mutex는 .NET의 System.Threding 네이스페이스에 포함된 클래스 입니다. 사실 둘이상의 스레드가 동시에 공유될 수 있는 리소스에 접근 할때 데드락의 위험이 있으므로 동기화 매커니즘이 필요하게 되는데요. Mutex는 리소스에 대한 단독 엑세스 권한을 하나의 스레드에만 부여하여 동기화하는 기본형식 입니다.
같은 리소스에 접근 할때 하나의 스레드가 Mutex를 걸고 어떠한 일을 수행 할 경우 다른 스레드는 먼저 수행하고 있는 스레드가 Mutex를 해제 할때까지 기다리게(일시중지) 되게 됩니다.
Mutex에 관한 자세한 설명은 아래의 링크에서 MSDN 도움말을 확인 할 수 있습니다.
http://msdn.microsoft.com/ko-kr/library/system.threading.mutex.mutex.aspx

테스트 하는 어플리케이션으로는 Windows Form 프로젝트를 예로 들겠습니다.
WinForm 프로젝트를 생성하면 Program.cs 가 생성 됩니다.
Main 함수에 다음과 같은 코드를 추가 시켜 주면 메세지 막스가 뜨면서 해당하는 프로그램이 중복 실행 되었다는걸 알릴 수 있습니다. 매우 간단하죠?
static class Program
    {
        /// 
        /// 해당 응용 프로그램의 주 진입점입니다.
        /// 
        [STAThread]
        static void Main()
        {
            bool createdNew;
            Mutex dup = new Mutex(true, "Focus Explorer Mutex", out createdNew); //Mutex생성
            if (createdNew)
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new MainForm());
                dup.ReleaseMutex(); //Mutex 해제
            }
            else // 프로그램이 중복 실행된 경우
            {
                MessageBox.Show("이미 프로그램이 실행중입니다.","Focus Explorer");
            }
        }
    }
 
우선 Mutex를 생성하고, 생성자에 두번째 인자에 뮤텍스 이름을 지정합니다.
세번째 인자로준 bool 값이 false일 경우 이미 뮤텍스가 걸리있는 상태이기 때문에.. 해당 프로젝트가 이미 생성되었다고 생각하고 프로그램이 실행중이라는 메세지 박스를 띄우고, 프로그램을 종료합니다.

이상 간단한 Mutex를 사용한 프로그램 중복 방지 방법이었습니다.


출처 : http://crynut84.tistory.com/46
반응형

'Programming > C#' 카테고리의 다른 글

Random Class를 파해쳐 보자!  (0) 2010.07.16
화살표 그리기(.NET Pen Class)  (0) 2010.07.16
App.Config XML읽고 쓰기..  (0) 2010.07.15
ini파일을 간단히...사용하자.  (0) 2010.07.15
C# (윈폼/콘솔) 관련 사이트  (0) 2010.07.15
Posted by blueasa
, |

App.Config XML파일을 읽고 쓰는 간단한 함수를 하나 만들어 봤습니다..

더 좋은 정보 있으면 리플 달아 주세요

 

 

private string AppConfigRead(string keyName)

        {

            string strReturn;

            Configuration currentConfig =

                ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

 

            if (currentConfig.AppSettings.Settings.AllKeys.Contains(keyName))

                strReturn = currentConfig.AppSettings.Settings[keyName].Value;

            else

                strReturn = ""; //키가없으면.

 

            return strReturn;

        }

 

        private bool AppConfigWrite(string keyName, string value)

        {

            Configuration currentConfig =

                ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

 

            if (currentConfig.AppSettings.Settings.AllKeys.Contains(keyName)) //키가 있으면

                currentConfig.AppSettings.Settings[keyName].Value = value;

            else       //키가 없으면

                currentConfig.AppSettings.Settings.Add(keyName, value);

           

            currentConfig.Save();

            ConfigurationManager.RefreshSection("appSettings");   // 내용 갱신             

            return true;

        }


출처 : http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=18&MAEULNo=8&no=1699&ref=1699



우선 위 함수를 사용하려면 참조 추가와 namespace 추가가 필요합니다.
1) System.configuration <- 참조 추가
2) using System.Configuration; <- 추가

그렇게 하고도.. 위의 소스에서 Contains 라는걸 찾을 수 없어서 제맘대로 수정했습니다.
정석인진 모르겠지만..돌아가니 참고하실분은 하세요.


        public static string AppConfigRead(string keyName)
        {
            string strReturn = "";
            Configuration currentConfig =
                ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

            bool bIsKey = false;

            foreach (string key in currentConfig.AppSettings.Settings.AllKeys)
            {
                if (key.StartsWith(keyName))
                {
                    strReturn = currentConfig.AppSettings.Settings[keyName].Value;
                    bIsKey = true;
                    break;
                }
            }

            if(bIsKey == false)
                return string.Empty;
           
            return strReturn;
        }


        public static bool AppConfigWrite(string keyName, string value)
        {
            Configuration currentConfig =
                ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

            if (currentConfig.AppSettings.Settings.Count != 0)
            {
                bool bIsKey = false;
                foreach (string key in currentConfig.AppSettings.Settings.AllKeys)
                {
                    if (key.StartsWith(keyName))
                    {
                        currentConfig.AppSettings.Settings[keyName].Value = value;
                        bIsKey = true;
                        break;
                    }
                }

                if ( bIsKey == false )       //키가 없으면
                {
                    currentConfig.AppSettings.Settings.Add(keyName, value);
                }
            }
            else
            {
                currentConfig.AppSettings.Settings.Add(keyName, value);
            }

            currentConfig.Save();
            ConfigurationManager.RefreshSection("appSettings");   // 내용 갱신             

            return true;
        }

반응형
Posted by blueasa
, |