노무현 전 대통령 서거 추모글 남기기

'전공'에 해당되는 글 64건

  1. 2008.05.07 C와 C++에서의 boolean 자료형 - BOOL vs. bool
  2. 2008.03.29 #pragma warning
  3. 2008.03.28 RegisterWindowMessage 1
  4. 2008.03.24 필수 윈도우관련 메시지 정리
  5. 2008.03.20 정의된 define들

퍼온 곳:  http://cafe.naver.com/applekoong/379


부울(G. Boole, 1815~1864)이라는 수학자가 있었답니다.

언제적 인물인지도 모르는 수학자가 만든 참과 거짓을 이용한 계산식을 부울 대수(Boolean Algebra)라고 부릅니다.

프로그래머에게는 부울 대수보다는 진리표(truth table)라는 이름이 친근합니다.

진리표가 어렵다면 논리 연산은 어떨까요?

한 가지 사물을 여러 가지 방법으로 부르는 것뿐입니다.

 

[참과 거짓에 대한 정의]

거짓, FALSE - 0

참, TRUE - 0이 아닌 모든 값

 

흔히 하는 실수로 참(TRUE)을 1로 생각하는 경우가 있습니다.

대부분 1이지만, 경우에 따라 1이 아닌 2가 될 수도 있고 -1이 될 수도 있습니다.

그러면 왜, 참을 이와 같이 복잡하게 정의한 것일까요?

실제로는 복잡하게 정의한 것이 아니라 안전하게 정의했다고 표현하는 것이 맞습니다.

 

일단 거짓(FALSE)은 "존재하지 않는다"라는 정도로 해석할 수 있기 때문에,

같은 의미를 갖는 숫자인 0을 사용합니다.

음수인 경우는 음수 크기만큼 갖는다고 얘기합니다.

0일 때 더함도 덜함도 없이 없는 것입니다.

 

만약 참을 1로 정의하면 어떤 일이 일어날까요?

참과 거짓을 알려주기로 약속을 해놓고,

상대방이 이도저도 아닌 -1을 주었습니다.

내 프로그램은 이때 어떻게 동작할까요?

현실에서 이와 같이 예상할 수 없는 일이 일어나면

여러분은 어떻게 행동합니까?

그렇습니다. 깜짝 놀라 당황합니다.

프로그램은?

마찬가지로 깜짝 놀라 당황하고, 비정상적으로 종료하게 될 것입니다.

 

비정상 종료가 발생하게 된 근본 원인은

참과 거짓에 대한 정의를 벗어날 수 있는 숫자가 있다는 것을 인정하지 않았다는 것입니다.

약속은 약속일 뿐이고, 언제든 약속을 어길 수가 있기 때문에 그에 대한 대비를 해야 합니다.

참과 거짓의 경우는 모든 숫자를 참과 거짓으로 나누어야

처리에 어떤 장애도 갖지 않을 수 있습니다.

 

모든 숫자에 대처하기 위해

거짓은 0이고, 참은 거짓이 아닌, 즉 0이 아닌 모든 숫자가 됐습니다.

이제 어떤 숫자가 와도 참과 거짓으로 판단할 수 있게 되었습니다.

 

[함수 반환값에서 주의할 점]

보통 참과 거짓을 함수에 대해 사용하는 경우에는

성공과 실패를 의미할 때가 많습니다.

참은 성공, 거짓은 실패를 의미합니다.

이와 같은 유형의 함수의 반환값은 두 가지가 있습니다.

 

    1. 진짜 참과 거짓을 반환하는 함수

    2. 0과 0이 아닌 정수를 반환하는 함수

 

두 가지 모두 실패는 0을 나타내고 상수로 표현하면 FALSE가 됩니다.

그러나, 참인 경우에는 서로 다릅니다.

1번은 진짜 참을 반환하기 때문에 1을 반환하지만,

2번은 0이 아닌 정수라고 표현했기 때문에 2나 3을 반환할 수도 있습니다.

이러한 함수에서 다음과 같은 코드는 재앙을 초래할 수 있습니다.

 

    if( ReturnValue == 1 )

        printf( "함수 성공" );

 

함수가 반환한 값이 1일 수도 있겠지만,

누차 얘기하듯이 2나 3일 수 있습니다.

그러면 2나 3은 성공이 아닙니까?

성공 맞습니다. 그러나, 성공에도 등급이 있을 수 있지 않습니까?

돈을 많이 버는데, 많이 버는 정도가 서로 다르다는 말입니다.

성공에 대해 0이 아닌 정수를 반환하는 경우는

성공을 여러 가지 형태로 나누길 바라기 때문입니다.

 

어떤 경우는 실패를 단순히 0이 아니라

여러 가지 경우로 나누어 처리하기도 합니다.

주로 음수를 사용해서 표현하는데,

-1은 이름을 잘못 사용했다던가

-2는 파일을 열 수 없었다던가 등등

실패의 종류를 구분하고 싶을 때가 있습니다.

 

    if( ReturnValue != 0 )

        printf( "함수 성공" );

 

제대로 표현하려면, 항상 거짓을 의미하는 0과 비교하는 습관을 들이는 것이 중요합니다.

거짓의 값은 0, 하나뿐이기 때문에 어떤 값을 반환하더라도 성공한 경우에 대처하게 됩니다.

 

[참/거짓과 조건]

참과 거짓은 제어문과 반복문에 이는 조건문에서 주로 사용합니다.

성공과 실패를 판단해서 각각에 맞는 처리를 해야 하므로

조건문과 뗄레야 뗄 수 없는 관계를 맺게 됩니다.

 

그러면 조건문에서 거짓으로 판단하는 0의 값을 갖는 경우에는 어떤 것들이 있을까요?

 

1. 정수 - 0

2. 실수 - 0.0

3. 문자 - 0('\0')

4. 포인터 - 0(NULL 포인터)

 

메모리 관점에서 봤을 때,

비교하고자 하는 메모리의 모든 비트가 꺼져 있을 때를 0으로 간주하는데,

자료형에 따라 해석이 달라집니다.

정수는 0, 실수는 0.0이 되는 것처럼,

문자인 경우에는 null문자, 포인터라면 NULL 포인터가 됩니다

(0번지를 가리키는 주소가 아니라 가리키지 않는다는 뜻의 NULL 포인터입니다.).

이때 포인터의 종류는 상관없습니다.

int*, char*, 구조체 포인터 등등 모든 포인터가 가리키는 곳이 없으면 NULL 포인터가 됩니다.

 

[BOOL vs. bool]

참과 거짓을 나타내는 방법이 C와 C++에서 다릅니다.

C 언어는 대문자 BOOL 자료형을 사용하고

C++는 소문자 bool 자료형을 사용합니다.

둘 다 참과 거짓을 표현하기 위해 만들었지만, 내부는 완전히 다르고 호환되지 않습니다.

 

일단 BOOL 자료형이 C 언어에는 없습니다.

대문자 BOOL 자료형을 사용하려면 typedef를 통해 재정의해야 합니다.

 

    typedef  int  BOOL;

 

이제 int와 BOOL은 같은 자료형이 되었고, BOOL 자료형을 사용할 수 있습니다.

문제는 BOOL 자료형의 근본이 int 자료형이기 때문에

2나 3의 값도 잘 받아들인다는 것입니다.

앞서 말했듯이 항상 거짓인 0과 비교해야 하는 이유입니다.

여기에 대문자 TRUE와 FALSE를 사용하기 위해 enum이나 define으로 상수를 정의합니다.

 

    #define  FALSE  0

    #define  TRUE    1

 

아니면

 

    enum { FALSE, TRUE };

 

처럼 사용해도 됩니다.

다만 정수에 대해서만 정의했고, 둘 다 int 상수라는 점입니다.

자료형과 값을 따로따로 설정하는 것이 번거로워서

다음처럼 한번에 처리하기도 합니다.

 

    typedef enum { FALSE, TRUE } BOOL;

 

그러나, 여전히 BOOL 자료형의 근본이 int 자료형이라는 것에는 변함이 없습니다.

 

    BOOL sw = -1;

 

에러나지 않는 코드입니다.

-1을 의도적으로 넣는 분은 없겠지만,

실수했을 때 컴파일러가 잡아주지 않기 때문에

나중에 치명적인 버그로 나타납니다.

C++인 경우에는 이 코드에서 FALSE와 TRUE만 사용해야 에러가 나지 않습니다.

 

C++에서는 참과 거짓에 대한 단점을 보완하기 위해

C 언어에 없는 새로운 자료형은 제공했는데, 그게 소문자 bool 자료형입니다.

 

    bool sw = -1;

 

이제 이 코드는 에러입니다.

bool 자료형에는 소문자 true와 false만 넣을 수 있습니다.

그러나, VC++ 6.0에서는 에러가 발생하지 않고,

닷넷 컴파일러에서는 가벼운 에러를 뜻하는 경고(warning)가 뜹니다.

true와 false만 넣기 위해 만든 자료형에 -1을 넣는다는 것이

무슨 뜻인지 알 수 없기 때문에, 경고를 발생시키는 것이 맞습니다.

 

BOOL 자료형과 TRUE, FALSE 상수를 정의했다고 가정합니다.

 

    BOOL sw1 = TRUE;

    BOOL sw2 = true;            // VC++ 6.0에서 에러

    bool sw3 = TRUE;

    bool sw4 = true;

 

6.0에서는 에러가 발생하지 않아도 될 부분에서 에러가 발생합니다.

bool 자료형의 크기는 1바이트로,

정확하게 0과 1을 표현하기 때문에 1바이트 정수를 4바이트 정수에 넣는 코드에서 에러가 발생하고 있습니다.

닷넷 컴파일러에서는 전혀 에러가 발생하지 않습니다.

분명 BOOL과 bool 자료형은 다른 자료형임에도

컴파일러 내부적으로 0과 1의 값을 갖는지 판단하는 것 같습니다.

sw3과 sw4에 0과 1이 아닌 값을 넣으면 경고가 뜹니다.

상수로 정의하지 않더라도 0과 1을 넣으면 문제가 없습니다.

표준은 아니지만, 컴파일러 확장 옵션이라고 생각됩니다.

 

[boolean 자료형과 라이브러리]

리눅스와 윈도우 프로그래밍, 즉 C 언어를 벗어나서 운영체제에 특화된 코딩을

시스템 프로그래밍이라고 부릅니다.

윈도우에서는 Win32 API 프로그래밍이라고 부르고,

리눅스에서는 정직하게 시스템 프로그래밍이라고 부릅니다.

 

운영체제를 C 언어로 만들었다고 하는 것은

C++에서 제공하는 bool 자료형을 API에서 볼 수 없다는 것을 뜻합니다.

파일 확장자를 cpp로 주면,

여러분은 bool 변수를 만들어쓸 수는 있지만,

성공 여부를 반환하는 시스템 함수(API)는 대문자 BOOL을 반환할 거라는 뜻입니다.

컴파일러에 따라, 앞서 설명처럼 경고 또는 에러가 발생하겠지만

호환되지 않을 수 있다는 사실을 인지하고 있으면,

형변환이라도 해서 사용할 수 있겠습니다.

 

당연히 C++ 라이브러리에서는

성공 여부를 반환하는 함수는 bool 자료형을 반환합니다.

STL에 들어있는 컨테이너의 멤버 함수인 empty()는

비어있을 때 true, 비어있지 않을 때 false를 반환합니다.

C 언어는 아쉽게도 BOOL 자료형조차 정의하지 않고 있기 때문에

0과 1을 반환할 것입니다.

 

저는 가능하면 bool 자료형을 사용하려고 노력합니다.

잘못될 수 있는 여지를 막아주고 있는데,

사용하지 않는다면 그게 오히려 이상하다고 생각합니다.

라이브러리와 충돌이 나는 부분은 형변환을 통해서 처리합니다.

namespace, 참조 변수 등등 C 언어에 없는 많은 개념을 저는 사용하고 있습니다.

조건 비교에서 true와 비교할 수 있다는 것만으로도 가치가 있다고 생각합니다.

 

강요하는 것은 아니고

어떤 자료형을 쓸지는 여러분이 직접 결정해야 합니다.

저는 여러분이 선택할 수 있도록 정확한 정보를 제공할 뿐입니다.

Posted by Kelly Cook
,

#pragma warning

전공/c, c++, ce 2008. 3. 29. 11:45

pragma 디렉티브(지시자)는 컴파일러 제조회사에서 컴파일러의 기능을 확장시킬수 있도록 하는 지시자 입니다. 표준 컴파일러에 자신들의 컴파일러 제작 기술이 허락하는 대로 최대한의 기능을 제공할 수 있도록 여지를 남겨놓은 것인데, 만약 다른 컴파일러에서 해석할수 없는 pragma 디렉티브를 만나면 그냥 무시함으로서 소스간 호환성 문제도 해결하고 있습니다.


위의것은 Ms Visual C++에서 확장된 기능으로 보입니다.


#pragma warning 경고 메시지와 관련된 지시자로서

#pragma warning(disable : 4786)
#pragma warning(disable : 4100)


이렇게 소스 파일에 적어놓으면 이 지시자가 나타난 순간부터 각각 4786, 4100번의 경고 메시지를 출력하지 못하게 합니다. MS 컴파일러에서 각각의 경고 메시지는 자신의 고유번호를 갖고 있습니다. 예를 들어 다음 소스를 경고레벨 4에서 컴파일한다면,


void f(int a)
{
}

int main()
{
 return 0;
}


다음과 같은 메시지를 출력합니다.

e:\Temp Projects\Test2\Test2.cpp(6) : warning C4100: 'a' : 참조되지 않은 형식 매개 변수입니다.


이때 C4100이 바로 경고메시지의 고유번호입니다.

C는 컴파일러에서 발생했다는 뜻이며, 4100이 경고 메시지 번호입니다.


이런 경고 메시지가 많이 발생되는 경우, 컴파일 속도가 심각하게 느려질수 있습니다.

또, 깨끗한 프로그램을 위해 경고레벨4에서 경고메시지 없이 컴파일 되기를 원하는 개발사도 있습니다.  이럴때, 다음처럼 해당 경고를 삭제해 주는 것입니다.


#pragma warning(disable: 4100)


void f(int a)
{
}

int main()
{
 return 0;
}


위의 소스는 실제로는 경고메시지를 끄는 것 보다는 경고메시지의 근본적인 오류를 제거해야 할 것입니다. 무슨말이냐하면, 실제로 f라는 함수에서 a라는 매개변수를 사용하지 않기 때문에, 매개 변수를 없애던가, 함수내부에서 매개변수를 사용하게끔 하던가, 혹은 나중에 사용하기 위해 설계상 써놓은 것이라면, 다음처럼 소스를 수정합니다.


void f(int /* a 차후에 사용될 것임을 명시하는 주석문*/)
{
}


또는


void f(int a)
{

 a; // 차후에 사용될 것임을 명시하는 주석문.
}


하지만, 위 4786번 메시지의 경우 STL과 관련된 VC++6.0의 버그로서, 이 경우에는 어쩔수 없이 삭제해 주어야 합니다.

[출처] #pragma warning이란?|작성자 반딧불

#pragma warning


컴파일러 경고 레벨


#pragma warning( push, level )
#pragma warning( pop )

level은 1, 2, 3, 4값을 가질 수 있다. 레벨은 프로젝트 컴파일러 옵션에서 수정이 가능합니다.


default

#pragma warning( default, number )

해당 경고를 컴파일러 기본값으로 처리.


disable

#pragma warning( disable, number )

해당 경고를 비활성화 시킨다. 즉, 경고가 생겨도 화면에 출력하지 않는다.


error

#pragma warning( error, number )

해당 경고를 에러로 처리한다.


once

#pragma warning( once, number )

해당 경고 출력을 단 한번만 한다.



보통은 아래와 같이 사용한다.

#pragma warning( disable, 4700 ) // 경고 해제

.. 소스 코드 ...

#pragma warning( default, 4700 ) // 기본값으로 처리

Posted by Kelly Cook
,
다른 프로그램과 메세지를 주고 받는 방법으로는 간단하게 2가지
방법이 있습니다.
하나는 RegisterWindowMessage 함수를 사용하여 메세지를 등록하는
방법이고 또 하나는 공유 메모리를 사용하여 메모리를 공유하는
방법입니다.

위의 두가지 방법에 대해서 간단하게 설명드리면 다음과 같습니다.

먼저 RegisterWindowMessage 함수를 사용하는 경우는

아래와 같이 메세지를 등록합니다.

UINT nRegMsg = RegisterWindowMessage("My Message");
여기서 입력으로 들어가는 "My Message" 라는 문자열은 메세지를 서로 주고
받기로 한 프로그램간에 서로 약속한 문자열입니다.
이 함수는 메세지를 송신하는쪽이나, 메세지를 수신하는 쪽이나 모두
수행해야 합니다.

메세지가 등록되어 송수신 준비가 되면 SendMessage 또는 PostMessage 함수로
메세지를 전송하면 됩니다.
이때 메세지가 다른 프로그램으로 전달이 되게 하려면
SendMessage 또는 PostMessage함수의 첫번째 입력 인수로 반드시 HWND_BROADCAST를
지정해야 합니다. 그렇지 않으면 다른 프로그램으로 메세지가 전송되지 않습니다.
이때 wParam, lParam을 이용해서 각각 2Byte와 4Byte의 추가적인 정보를 전달
할 수 있습니다.

즉 ::PostMessage(HWND_BROADCAST, nRegMsg, (WPARAM)m_hWnd, (LPARAM)0);
이런식으로 사용하면 됩니다.

메세지를 수신하려는 쪽은 다음의 코드를 추가하면 됩니다.

즉 RegisterWindowMessage로 등록된 메시지를 받을때는
ON_REGISTERED_MESSAGE 매크로를 사용합니다.

즉 ON_REGISTERED_MESSAGE(nRegMsg, OnMessageFunc)
이런 식으로 메세지 수신을 처리하는 함수를 등록해 줍니다.
그리고 이 처리함수에서 메세지 수신을 처리하면 됩니다.

메세지 처리 함수는 다음과 같은 형식을 가집니다.

LRESULT MyClass::OnMessageFunc(WPARAM wParam, LPARAM lParam)
{
// 작업 코드
return 0;
}

그런데 만일 4Byte 이상의 데이터를 전송하려면 어떻게 해야 할까요??
구조체에 정보를 담거나, 메모리를 할당해서 여기에 데이터를 저장한 후
메포리 번지의 포인터를 전달하는 경우가 대부분일테지만, 이 방법은
단일 프로그램에서만 사용이 가능합니다.

즉 위의 방법으로는 문자열이나 기타 대량의 정보를 전송하는데는
문제가 있습니다.

대량의 정보를 서로 공유하려면 메모리 맵 파일을 이용합니다.
즉 공유 메모리를 이용하는 방법을 사용합니다.

메모리 맵 파일은 파일이 아닙니다. 파일처럼 취급되는 메모리의 일종이라고
보시면 됩니다.

기본적인 방법은 CreateFileMapping 함수를 사용하여 메모리 맵 파일을 생성하고
MapViewOfFile 함수를 호출하여 메모리 포인터를 얻어 이 포인터를 일반
포인터처럼 사용하시면 됩니다.

CreateFileMapping 에 대한 설명은 여기서는 모두 하기가 어렵고
Visual C++ 도움말이나 MSDN CD에서 도움말을 참조하시기 바랍니다.(죄송..)

그럼 간단하게 소스를 보면 다음과 같습니다.

LPVOID m_pViewOfFile = NULL;
HANDLE m_hFileMapping = 0;

m_hFileMapping = CreateFileMapping(
INVALID_HANDLE_VALUE, // system paging file
NULL, // security attributes
PAGE_READWRITE, // protection
0, // high-order DWORD of size
dwMemoryFileSize*sizeof(TCHAR), // low-order DWORD of size
sMemoryFileName); // name

if (!m_hFileMapping )
{
MessageBox(_T("Creating of file mapping failed"));
}
else
{
m_pViewOfFile = MapViewOfFile(
m_hFileMapping, // handle to file-mapping object
FILE_MAP_ALL_ACCESS, // desired access
0,
0,
0); // map all file

if (! m_pViewOfFile )
{
MessageBox(_T("MapViewOfFile failed"));
}

// Now we have m_pViewOfFile memory block which is common for
// all instances of this program
}
}

이제 m_pViewOfFile 변수를 자신이 원하는 형태로 캐스팅하여
사용할 수 있습니다.

메세지를 전송하는 프로그램은 이렇게 메모리를 ACCESS 한다음 여기에
데이터를 기록하면 됩니다.

메세지를 수신하는 프로그램에서는 OpenFileMapping함수를 사용하여
메모리 맵 파일을 오픈하고 MapViewOfFile 함수로 메모리 포인터를 얻어서
수신한 데이터를 사용할 수 있습니다.

이런식으로 서로 다른 프로그램이나 프로세스간에 메세지나 메모리를
공유할 수 있습니다.

[출처] RegisterWindowMessage|작성자 형기

Posted by Kelly Cook
,

출처: http://cafe.naver.com/ryuts.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=19

필수 윈도우관련 메시지 정리

WM_CREATE

²        CreateWindow() 함수에 의해 메인 윈도우가 생성된 직후에 화면에 보여지기 전에 보내지는 메시지.

²        각종 초기화를 하기에 적합한 장소.

²        참고로, 대화상자는 이 메시지 대신 WM_INITDIALOG 메시지를 받는다.

²        wParam : 사용되지 않음.

²        lParam : 윈도우 생성정보인 CREATESTRUCT 구조체의 포인터.

WM_DESTROY

²        윈도우가 파괴될 때 보내지는 메시지.

²        각종 마무리 작업 하기에 적합한 장소.

²        사용자가 DestroyWindow 함수를 호출할 때, 윈도우가 파괴되는데, 이 함수 호출 결과로 WM_DESTROY 메시지가 전달된다.

²        사용자가 Alt+F4 혹은 닫기 버튼을 누를 경우, WM_CLOSE 메시지가 전달되며 이 메시지를 별도로 처리하지 않으면 DefWindowProc Destroywindow함수를 호출하여 윈도우를 파괴한다.

²        파괴되는 윈도우가 메인 윈도우의 경우, PostQuitMessage 함수를 반드시 호출하여 프로세스의 메시지 루프를 종료하도록 해야한다. 이 처리를 생략하면, 윈도우만 파괴되고, 메시지 루프는 계속 실행중인 상태가 되므로 프로세스가 종료되지 않는다.

WM_ACTIVATE

²        윈도우의 활성화 상태가 변경될 때 보내지는 메시지로써, 새로 활성화되는 윈도우와 비활성화 되는 윈도우에게 동시에 보내진다.

²        활성화 상태는 오직 하나만 존재할 수 있다.

²        LOWORD(wParam) : 윈도우가 활성화 되었는지 비활성화 되었는지의 정보.

n        WA_ACTIVE : 마우스 클릭 이외의 방법으로 활성화 됨. (SetActiveWindow() 함수를 호출했거나, Alt+Tab, Alt+Esc 등의 단축키로 활성화 되었을 경우)

n        WA_CLICKACTIVE : 마우스 클릭에 의해 활성화 됨.

n        WA_INACTIVE : 비 활성화 됨.

²        HIWORD(wParam) : 윈도우의 최소화 상태를 전달. 최소화 되어있으면 0 이외의 값을 가짐.

²        lParam : 활성화 상태가 변경된 다른 윈도우의 핸들이 전달. , 활성화 상태가 바뀐 상대편 윈도우의 핸들 값이다. 상대편 윈도우가 없을 경우는 NULL이 전달.

WM_CLOSE

²        윈도우가 닫히기 전에 전달되는 메시지이며, 메인윈도우인 경우는 프로그램이 종료된다는 신호임.

²        이 메시지를 처리하지 않고 DefWindowProc으로 보내면 DestroyWindow함수를 호출하여 윈도우를 파괴하도록 한다.

²        이 메시지가 전달되었을 때는 아직 윈도우가 파괴된 것이 아니므로, 메시지박스의 취소 등을 통해 윈도우가 파괴되는 것을 중간에 차단할 수 있다.

WM_SIZE

²        윈도우의 크기가 변경될 때 전달된다. (사용자가 윈도우 경계선을 드래그해서 직접 크기를 변경할 때 혹은 내부에서 MoveWindow, SetWindowPos 등의 함수로 윈도우의 크기를 변경할 때 등)

²        wParam : 윈도우의 크기가 변경된 이유와 유형 값을 가짐

n         SIZE_MAXHIDE : 다른 윈도우가 최대화되어 이 윈도우가 가려졌다.

n         SIZE_MAXIMIZED : 윈도우가 최대화되었다.

n         SIZE_MAXSHOW : 다른 윈도우가 원래 크기로 복구되어 이 윈도우가 드러났다.

n         SIZE_MINIMIZED : 윈도우가 최소화되었다.

n         SIZE_RESTORED : 윈도우의 크기가 변경되었다.(윈도우의 크기를 사용자가 드래그 등으로 직접 변경할 때)

²        lParam : 윈도우의 변경된 후의 크기. LOWORD(lParam)-> 윈도우의 폭, HIWORD(lParam)-> 윈도우의 높이.

²        사용예) 윈도우 가운데에 문자를 출력하는 프로그램이라면, 윈도우 크기가 변경될 때마다 다시 출력해줘야한다.

WM_MOVE

²        윈도우의 위치가 변경되면 이 메시지가 보내진다. (위치가 완전히 옮겨진 후에 보내짐)

²        LOWORD(lParam) : 새로 옮겨진 윈도우의 X좌표

²        HIWORD(wParam) : 새로 옮겨진 윈도우의 Y좌표. 차일드 윈도우는 부모 윈도우의 작업 영역을 기준으로 한 좌표임.

WM_SHOWWINDOW

²        윈도우의 보임 상태가 변경되기 직전에 보내지는 메시지.

²        사용예) 애니메이션이 돌고 있다가 윈도우가 가려지면 굳이 리소스 낭비하면서 돌릴 이유가 없다. 잠깐 멈췄다가 다시 보여지면 애니매이션을 이어서 돌린다는지의 작업.

²        wParam : TRUE 이면 윈도우가 보여지는 것이고, FASLE이면 윈도우가 숨겨지는 것이다.

²        lParam : 이 메시지가 전달된 이유이다. 0이면 ShowWindow()함수에 의해 이 메시지가 전달된 것이며, 0이 아니면 다음 값 중 하나가 된다. (많이 사용되지는 않음)

SW_OTHERRUNZOOM : 다른 윈도우가 최대화되었다가 복구 또는 최소화됨으로써 이 윈도우가 보여지게 되었다.

SW_OTHERZOOM : 다른 윈도우가 최대화되면서 이 윈도우가 가려지게 되었다.

SW_PARENTCLOSING : 부모 윈도우가 최소화되었다.

SW_PARENTOPENING : 부모 윈도우가 복구되었다.

● 그 밖에 메시지들..

²        WM_ERASEBKGND : 윈도우의 크기가 변경되었거나 다른 윈도우에 가려진 부분이 드러났다거나 할 때 배경을 지우기 위해 이 메시지가 보내진다. WM_PAINT에서 작업 영역에 출력을 하기 전에 먼저 전에 그려져있던 내용을 지워야한다. 이 메시지를 처리하지 않을 경우 DefWindowProc은 배경 브러시로 작업 영역을 지운 후 WM_PAINT에서 출력을 내보내게 된다.

²        WM_HSCROLL : 수평 스크롤바를 클릭 할 때 발생

²        WM_VSCROLL : 수직 스크롤바를 클릭 할 때 발생

²        WM_COMMAND : 메뉴 항목을 선택 했을 때 발생

²        WM_CONTEXTMENU : 팝업 메뉴 전용 메시지

 

필수 윈도우관련 함수 정리

GetWindowRect() 함수

BOOL GetWindowRect(HWND hWnd, LPRECT lpRect);

 

²        윈도우의 현재 위치를 lpRect를 통해 좌표값으로 알려준다. (전체화면을 기준으로 한 좌표임)

²        윈도우의 크기를 구하고 싶으면, right-left, bottom-top을 계산하면 된다.

GetClientRect() 함수

BOOL GetClientRect(HWND hWnd, LPRECT lpRect);

 

²        윈도우의 작업영역(ClientArea) 크기를 계산해준다.

²        작업영역이란, 윈도우의 타이틀바, 스크롤바, 경계선, 메뉴 등을 제외한 영역이다.

²        lpRect left, top은 항상 0이며, right, bottom이 곧 윈도우의 크기를 나타낸다.

ShowWindow() 함수

BOOL ShowWindow(HWND hWnd, int nCmdShow);

 

²        윈도우의 보이기/숨기기/최대화/최소화/복구상태 등 현재 상태를 지정한다.

²        nCmdShow : 지정하고자 하는 보이기 상태이며, 다음 값 중 하나를 지정한다.

u       SW_SHOW, SW_HIDE, SW_MAXMIZE, SW_MINIMIZE, SW_RESTORE ..

²        리턴값 : 윈도우가 이전에 보이던 상태였다면 0이 아닌값을 리턴, 보이지 않던 상태였다면 0을 리턴.


 ※ SW_SHOW, SW_HIDE 를 받는 쪽 처리
case WM_ACTIVATE:
  if(LOWORD(wParam) == WA_INACTIVE)//SW_SHOW
   strcpy(Mes, "비활성화 상태");
  else                                                 //SW_HIED
   strcpy(Mes, "활성화 상태");
  InvalidateRect(hWnd, NULL, TRUE);
  return 0;

 // wParam ; TRUE-활성화 , FALSE-비활성화
 // lParam ; 활성화 상태가 변경될 때 상대편 윈도우를 소유한 스레드
 //   ID 가 전달된다.
 // WM_ACTIVATE 메시지
 // LOWORD(wParam) -
 //  WA_INACTIVE ; 비활성화
 //  WA_CLICKATIVE ; 마우스 클릭에 의해 윈도우 활성화
 //  WA_ACTIVE ; 마우스 클릭 이외의 방법에 의해 윈도우 활성화  
 // HIWORD(wParam) - 윈도우가 최소화 상태인가 아닌가를 전달해
 //     주는데 상위 워드가 0이외의 값을 가지면
 //     윈도우가 최소화 되어 있는것이다.
 // lParam - 윈도우의 활성화/비활성화에 따라 활성화가 변경된
 //   상대편 윈도우의 핸들이 전달된다.



MoveWindow() 함수

BOOL MoveWindow(HWND hWnd, int X, int Y, int nWidth, int nHeight, BOOL bRepaint);

 

²        윈도우의 위치와 크기를 변경하는 가장 일반적인 함수.

²        X, Y : 윈도우의 위치를 지정.

²        nWidth, nHeight : 윈도우의 폭과 높이를 지정.

²        bRepaint : 이동 후에 윈도우를 다시 그릴 것인가 여부. TRUE면 이동 후 WM_PAINT 메시지를 보내 윈도우를 다시 그리도록 한다. 이때 작업영역, 비작업영역 다 그려지게 된다.

²        인자를 통해 위치는 물론 크기까지 한꺼번에 변경할 수 있다. 만약 위치만 변경하고 싶다면, GetWindowRect를 통해 영역을 구한 다음 원하는 값만 변경하는 식으로 처리한다. 만약 크기만 변경하고 싶다면, SetWindowPos함수를 사용한다.

Posted by Kelly Cook
,

// 변수들

UINT : unsigned int
WORD : unsigned short


// 함수에서 쓰는 것들

SetMapMode

 _ MM_TEXT : X축은 왼쪽에서 오른쪽으로 커지고, Y축은 아래로 내려갈 때 커집니다


DrawText : 문자를 출력할 때 어느 영역을 정하고 이영역에 출력하는 함수

 값

  내용

DT_TOP

DT_BOTTOM

DT_LEFT

DT_RIGHT

 설정된 lpRect영역에 상단으로(DT_TOP) 하단으로(DT_BOTTOM) 좌측으로(DT_LEFt)우측으로(DT_RIGHT) 문자를 출력 한다. DT_SINGLELINE가 함께 지정되어 있어야 한다.

DT_CENTER

 설정된 영역의 가로중앙에 정렬시킨다

DT_VCENTER

 설정된 영역의 세로 중앙에 정렬 시킨다.



DT_EXPANDTABS

 문자열에 탭이 포함되어 있을 때 공백으로 띄어 준다.

 기본폭은 8이다.

DT_CALCRECT

 텍스트가 출력할 사각형의 영역을 계산한다. 이때 문자는 출력되지 않는다.

DT_EXTERNALLEADING

 문자의 높이를 계산할 때 extenal leading sapce를 호함시킨다.

DT_SINGLELINE

행바꿈과 라인 피드를 무지하고 한줄로 출력한다.

DT_NOCLIP

클리핑 없이 문자를 출력한다.

DT_NOPREFIX

&문자를 표식어로 상용하지 않는다. 일반적으로& 코드는 출력하지 않고 다음 문자에 밑줄을 그린다.

DT_TABSTOP

Flat 상위 8비트에 값을 넣어서 탭간격을 변화시킨다.

DT_WORDBREAK

문자열이 영역밖으로 출력되면 개행하여 출력한다.


SetBkMode

 - TRANSPARENT : 투명하게 하는 것으로 글자 뒤로 배경이 보이게 한다

 - OPAQUE : 불투명한 배경을사용 뒷배경이 지워진다


CreateFont

▶fnWeight : 폰트의 무게를 0~1000까지의 값으로 설정한다. 쉽게 말해서 폰트의 두께를 설정한다. 0~1000까지의 값을 지정할 수 있으며 보통 굵기인 FW_NORMAL과 굵은 문자인 FW_BOLD만 사용된다.

두께
FW_DONTCARE 0
FW_THIN 100
FW_EXTRALIGHT 200
FW_ULTRALIGHT 200
FW_LIGHT 300
FW_NORMAL 400
FW_REGULAR 400
FW_MEDIUM 500
FW_SEMIBOLD 600
FW_DEMIBOLD 600
FW_BOLD 700
FW_EXTRABOLD 800
FW_ULTRABOLD 800
FW_HEAVY 900
FW_BLACK 900

▶fdwCharSet : 문자 셋을 설정한다. 폰트 매퍼가 논리 폰트를 생성할 때 참조하는 중요한 값이므로 폰트의 타입 페이스를 지정할 경우 반드시 해당 폰트의 문자셋과 일치하도록 써 주어야 한다.

문자셋 실제값 설명
ANSI_CHARSET 0 윈도우즈에서 사용하는 문자셋
DEFAULT_CHARSET 1 이름과 크기만으로 폰트를 선택하도록 한다. 만약 이 문자셋으로 폰트를 생성할 때 지정한 폰트가 없으면 임의의 문자셋으로 대체될 수도 있기 때문에 원하지 않는 폰트가 생성될 수도 있다.
SYMBOL_CHARSET 2  
OEM_CHARSET 255 운영체제에 종속적인 문자셋
HANGUL_CHARSET 129 HANGUEL_CHARSET으로 중복 정의되어 있다.
BALTIC_CHARSET 186  
CHINESEBIG5_CHARSET 136  
EASTEUROPE_CHARSET 238  
GB2312_CHARSET 134  
GREEK_CHARSET 161  
MAC_CHARSET 77  
RUSSIAN_CHARSET 204  
SHIFTJIS_CHARSET 128  
TURKISH_CHARSET 162  
JOHAB_CHARSET 130 한글 윈도우즈에서만 사용 가능
HEBREW_CHARSET 177 중앙 아시아 윈도우즈에서만 사용 가능
ARABIC_CHARSET 178 중앙 아시아 윈도우즈에서만 사용 가능
THAI_CHARSET 222 타이 윈도우즈에서만 사용 가능

▶fdwOutputPrecision : 출력 정확도를 설정한다. 같은 이름의 폰트가 여러 벌 있을 경우 폰트 매퍼가 어떤 폰트를 선택할 것인가를 지정한다.

설명
OUT_CHARACTER_PRECIS 사용되지 않는 값이다.
OUT_DEFAULT_PRECIS 폰트 매퍼의 디폴트 동작을 정의한다.
OUT_DEVICE_PRECIS 디바이스 폰트를 선택하도록 한다.
OUT_OUTLINE_PRECIS 트루 타입 또는 외곽선 폰트를 선택하도록 한다.
OUT_RASTER_PRECIS 래스트 폰트를 선택하도록 한다.
OUT_STRING_PRECIS 폰트 매퍼가 사용하지 않는 값이되 래스트 폰트 열거시 리턴된다.
OUT_STROKE_PRECIS 폰트 매퍼가 사용하지 않는 값이되 래스트 폰트 열거시 리턴된다.
OUT_TT_ONLY_PRECIS 트루 타입 폰트를 선택하도록 한다. 트루 타입 폰트가 없으면 디폴트 동작대로 한다.
OUT_TT_PRECIS 트루 타입 폰트를 선택하도록 한다.

▶fdwClipPrecision : 클리핑 정확도를 설정한다. 클리핑 영역을 벗어난 문자의 일부를 어떻게 클립할 것인가를 지정하면 다음과 같은 값들이 있다.

설명
CLIP_DEFAULT_PRECIS 디폴트 클리핑 동작
CLIP_CHARACTER_PRECIS 사용되지 않음
CLIP_STROKE_PRECIS  
CLIP_MASK 사용되지 않음
CLIP_EMBEDDED  
CLIP_LH_ANGLES  
CLIP_TT_ALWAYS 사용되지 않음

▶fdwQuality : 논리적 폰트를 물리적 폰트에 얼마나 근접시킬 것인가를 지정한다.

설명
DEFAULT_QUALITY 폰트의 모양을 문제삼지 않는다.
DRAFT_QUALITY PROOF_QUALITY보다 한단계 낮은 품질 등급이다.
PROOF_QUALITY 논리 폰트의 속성보다 글자의 품질을 더 중요시한다. 래스터 폰트의 경우 크기가 가장 근접한 폰트가 선택된다.

▶fdwPitchAndFamily : 폰트의 피치와 그룹을 설정한다.하위 2비트는 폰트의 피치를 나타내며 상위 4비트는 폰트의 패밀리를 지정한다. 피치는 폰트의 폭이 글자마다 다른가 일정한가를 지정하며 DEFAULT_PITCH, FIXED_PITCH(고정폭), VARIABLE_PITCH(가변폭) 세가지가 있다. 패밀리는 획의 굵기와 세리프 특성이 같은 폰트의 모임이며 다음 다섯 가지 종류가 있다.

패밀리 설명
FF_DECORATIVE 장식체
FF_DONTCARE 패밀리를 상관하지 않는다. 또는 패밀리를 알 수 없다. 이 값은 실제로 존재하는 패밀리가 아니라 임의의 패밀리를 지칭한다.
FF_MODERN 고정폭이며 세리프는 있을 수도 있고 없을 수도 있따.
FF_ROMAN 세리프가 있고 가변폭이다.
FF_SCRIPT 손을 쓴 듯한 필기체 형식의 폰트
FF_SWISS 세리프가 없고 고정폭이다.

이 인수에 피치와 패밀리 값을 OR 연산자로 같이 지정한다. 예를 들어 고정폭의 Roman 패밀리 폰트를 원할 경우 FIXED_PITCH | FF_ROMAN값을 지정하면 된다.


SetTextAlign

▶fMode:정렬 방식과 CP사용 여부 등의 플래그를 지정한다. 정렬 방식은 수평, 수직에 대해 각각 한 종류만 선택할 수 있다.

플래그 설명
TA_BLASELINE 텍스트의 기준선에 정렬
TA_BOTTOM 수직 하단 정렬
TA_TOP 수직 상단 정렬
TA_CENTER 수평 중앙 정렬
TA_LEFT 수평 왼쪽 정렬
TA_RIGHT 수평 오른쪽 정렬
TA_NOUPATECP 문자열이 출력된 후 CP는 변경되지 않는다.
TA_RTLREADING 문자열을 오른쪽에서 왼쪽으로 출력한다. 한글 윈도우즈에서는 의미가 없다.
TA_UPDATECP 문자열 출력 좌표 CP를 사용하며 문자열 출력 후 CP를 갱신한다.


CreateWindowEx

 - WS_THICKFRAME : 크기 조정이 가능한 두꺼운 경계선을 가진다

 - WS_CAPTION : 타이틀 바를 가진 윈도우를 만들며 WS_BORDER 스타일을 포함한다


// 펜 스타일 종류

- PS_SOLID : 실선을 그린다

- PS_DASH : 파선을 그린다

- PS_DOT : 점선을 그린다

- PS_DASHDOT : 점선과 파선으로 번갈아 구성된 선을 그린다.

- PS_NULL : 아무것도 그리지 않는다. (자리를 찾이하나?)

- PS_INSIDEFRAME : 이상한 펜 모양, 기본적으로 PS_SOLID와 같지만 도형 드로잉 함수에 건내주는 좌표의 의미가 변한다. 실선 이되 사각형 안쪽으로만 그려진다.(아직 이해가 잘 안됨)

// 빗금 패턴의 종류
- HS_BDIAGONAL : 우상에서 좌하로의 빗금
- HS_CROSS : 십자가 형태
- HS_DIAGCROSS : 사선십자가 형태
- HS_FDIAGONAL : 좌상에서 우하로의 빗금
- HS_HORIZONTAL : 수평 빗금
- HS_VERTICAL : 수직 빗금


//
- BS_SOLID : 단일색
- BS_PATTERN : 비트맵 패턴
- BS_HATCHED : 빗금 패턴

[출처] 정의된 define들|작성자 갓엘

Posted by Kelly Cook
,