유돌이

calendar

1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

Notice

2009. 5. 26. 20:26 C/C++/MFC
childNodes
  현재 노드의 자식 노드를 배열로 돌려준다.

firstChild
  현재 노드의 첫 번째 자식 노드를 참조한다.

lastChild
  현재 노드의 마지막 자식 노드를 참조한다.

nextSibling
  현재 노드의 바로 다음의 노드를 반환한다.

nodeName
  노드의 qualified name을 반환한다.

nodeType
  노드의 XML DOM 노드 형식을 지정한다.

nodeValue
  해당 노드의 값을 참조한다.

ownerDocument
  해당 노드를 포함하는 루트 엘레먼트를 반환한다.

parentNode
  해당 노드의 부모 노드를 반환한다.

previousSibling
  현재 노드 바로 앞에 오는 노드를 반환 한다.

xml
  현재 노드와 자식노드의 XML을 문자열로 반환한다.(IE 전용)

text
  현재 노드와 자식노드 들의 텍스트를 연결한 콘텐트를 반환 한다.(IE 전용)

2.DOM 메소드

getElementById(idName)
  도큐먼드에서 idName의 id로 정의된 요소를 찾아 반환한다.

getElementsByTagName(tagName)
  tagName을 가진 태그들의 노드 객체를 찾아 배열로 반환한다.
 
document.createElement(tagName)
  tagName 으로된 엘리먼트를 생성한다.

document.createTextNode(text)
  정적 텍스트를 담고 있는 노드를 생성한다.

<element>.appendChild(childNode)
  childNode를 에레먼트의 자식 노드로 추가 한다.

<element>.getAttribute(name)
  에레먼트에서 name에 해당하는 어트리뷰트 값을 반환한다.

<element>.setAttribute(name, value)
  엘레먼트에 name 속성에 value 값을 할당한다.

<element>.insertBefore(newNode, tartgetNode)
  엘레먼트의 자식노드 중 tartgetNode 전에 newNode를  삽입한다.

<element>.removeAttribute(name)
  엘리먼트에서 name 어트리뷰트을 제거한다.

<element>.removeChild(childNode)
  엘레먼트에서 자식 childNode 노드를 제거한다.

<element>.replaceChild(newNode, oldNode)
  엘레먼트에서 oldNode 를 newNode 로 치환한다.

<element>.hasChildNodes()
  엘레먼트가 자식 노드를 포함하는 경우 true, 자식요소가 없는 경우 false를 반환한다.

자세한 내용 : Traversing an HTML table with JavaScript and DOM Interfaces 
posted by 유돌이
2009. 5. 18. 13:17 C/C++/MFC
childNodes
  현재 노드의 자식 노드를 배열로 돌려준다.

firstChild
  현재 노드의 첫 번째 자식 노드를 참조한다.

lastChild
  현재 노드의 마지막 자식 노드를 참조한다.

nextSibling
  현재 노드의 바로 다음의 노드를 반환한다.

nodeName
  노드의 qualified name을 반환한다.

nodeType
  노드의 XML DOM 노드 형식을 지정한다.

nodeValue
  해당 노드의 값을 참조한다.

ownerDocument
  해당 노드를 포함하는 루트 엘레먼트를 반환한다.

parentNode
  해당 노드의 부모 노드를 반환한다.

previousSibling
  현재 노드 바로 앞에 오는 노드를 반환 한다.

xml
  현재 노드와 자식노드의 XML을 문자열로 반환한다.(IE 전용)

text
  현재 노드와 자식노드 들의 텍스트를 연결한 콘텐트를 반환 한다.(IE 전용)

2.DOM 메소드

getElementById(idName)
  도큐먼드에서 idName의 id로 정의된 요소를 찾아 반환한다.

getElementsByTagName(tagName)
  tagName을 가진 태그들의 노드 객체를 찾아 배열로 반환한다.
 
document.createElement(tagName)
  tagName 으로된 엘리먼트를 생성한다.

document.createTextNode(text)
  정적 텍스트를 담고 있는 노드를 생성한다.

<element>.appendChild(childNode)
  childNode를 에레먼트의 자식 노드로 추가 한다.

<element>.getAttribute(name)
  에레먼트에서 name에 해당하는 어트리뷰트 값을 반환한다.

<element>.setAttribute(name, value)
  엘레먼트에 name 속성에 value 값을 할당한다.

<element>.insertBefore(newNode, tartgetNode)
  엘레먼트의 자식노드 중 tartgetNode 전에 newNode를  삽입한다.

<element>.removeAttribute(name)
  엘리먼트에서 name 어트리뷰트을 제거한다.

<element>.removeChild(childNode)
  엘레먼트에서 자식 childNode 노드를 제거한다.

<element>.replaceChild(newNode, oldNode)
  엘레먼트에서 oldNode 를 newNode 로 치환한다.

<element>.hasChildNodes()
  엘레먼트가 자식 노드를 포함하는 경우 true, 자식요소가 없는 경우 false를 반환한다.

자세한 내용 : Traversing an HTML table with JavaScript and DOM Interfaces 
posted by 유돌이
2009. 3. 21. 11:34 C/C++/MFC

멤버변수를 추가 합니다.

CBitmapButton m_btnButton;

 

OnInitDialog() 함수에 아래와 같이 초기화 합니다.

 

m_btnButton.Create(NULL, WS_CHILD|WS_VISIBLE|BS_OWNERDRAW, CRect(230,50,0,0), this, 1000);

CRect(230,50,0,0) 는 위치와 크기

1000은 적용시킬 버튼의 리소스 아이디 입니다. 

만약 1로 하면 확인버튼의 기능을 동일하게 사용합니다.

 

 

m_btnButton.LoadBitmaps(IDB_BTNFRAME,IDB_BTNFRAME_FOC,IDB_BTNFRAME_SEL,IDB_BTNFRAME);

사용할 리로스 , 버튼이 선택되었을때의 리소스,

버튼이 포커스 돼었을때의 리소스, 해제되었을때의 리소스

 

 

m_btnButton.SizeToContent();

리소스의 크기에 맞게 버튼을 설정해주는 함수입니다.

 

---------------------------------------------------------------------------

 

* CBitmapButton 만드는 법_1

CBitmapButton으로 만든 버튼은 push button 형식이다.
1) 먼저 Form에 버튼을 만들고 Style에서 Owner Draw를 꼭 체크
2) 버튼의 캡션을 간단하게 지정(중요)

예를 들어 캡션이 "ONE"이라면..

3) 이제 리소스에 버튼 그림들을 추가합니다.

이때 추가 하는 리소스 이름은
2번에서 지정한 캡션의 이름뒤에 "D" "F" "U" "X" 를 붙입니다
이를테면 "ONED" "ONEF" "ONEU" "ONEX" 같은 식으로 말입니다.
"U"=UP/ "D"=Down/ "F"=포커스/ "X"=disable 의 뜻

4) CBitmapButton 객체를 멤버변수로 만듭니다.

CBitmapButton m_ButtonOne;

5) OnInitialUpdate() 에 다음과 같이 씁니다

m_ButtonOne.AutoLoad(IDC_BUTTON_ONE,this);


* CBitmapButton 만드는 법_2

방법 1과 크게 다르지 않고, 맵 연결 방법에서 차이가 있다.
1) 버튼의 속성중에 property -> style 에서 Owner draw 꼭 check !!
2) 비트맵으로 씌울 그림들을 프로젝트의 Bit 멥 부분에 Insert 시킴

(정적인 느낌을 피하기 위해 그림은 두개를 준비)

3) 해당 다이알로그 박스의 버튼에 해당하는 변수를 추가시켜 줌(물론 해드에 변수를 정의)
.h 파일 부분에서 public 부분에 만들어 주시고

CBitmapButton m_OK;
CBitmapButton m_Cancel;

.cpp 부분에

void CADD_AND_DEL_FRIEND::DoDataExchange(CDataExchange* pDX)
{

CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CADD_AND_DEL_FRIEND)
...
DDX_Control(pDX, IDOK, m_OK); // 변수를 해당 아이디와 연결 시켜준다.
DDX_Control(pDX, IDCANCEL, m_Cancel);
//}}AFX_DATA_MAP

}

4) 다이알로그가 생성되는 초기화 부분에서 버튼과 이미지를 연결시켜준다.

BOOL CADD_AND_DEL_FRIEND::OnInitDialog()
{

CDialog::OnInitDialog();
// 버튼이 눌러지기전 이미지와 눌렸을때 이미지를 설정해 준다.
m_OK.LoadBitmaps( IDB_OKU, IDB_OKD );
m_Cancel.LoadBitmaps( IDB_CancelU, IDB_CancelD );

// 버튼을 이미지 크기에 맞춰서 씌워준다.
m_OK.SizeToContent();
m_Cancel.SizeToContent();
return true;

}


posted by 유돌이
2009. 3. 21. 11:34 C/C++/MFC

다이얼로그 해더 부분에 추가

 

 CBitmap m_bmpMainBG; 

 int m_nMainWidth;
 int m_nMainHeight;

 

 

OnInitDialog() 부분에 추가

 

BITMAP bmpInfo; // 비트맵 정보

m_bmpMainBG.LoadBitmap(IDB_BKIMG2); // Main 배경 이미지 Load
m_bmpMainBG.GetBitmap(&bmpInfo); // Main 배경 비트맵 정보 읽기

m_nMainWidth = 280;//bmpInfo.bmWidth; // Main 윈도우 폭

m_nMainHeight = 140;//bmpInfo.bmHeight; // Main 윈도우 높이
SetWindowPos( NULL, 0, 0, m_nMainWidth, m_nMainHeight,SWP_NOZORDER | SWP_NOMOVE);

 

 

OnPaint() 부분에 추가

 

 CDC cdc;
 cdc.CreateCompatibleDC(&dc);
 cdc.SelectObject(m_bmpMainBG);
 dc.BitBlt(0, 0, m_nMainWidth, m_nMainHeight, &cdc, 0, 0, SRCCOPY);
 cdc.DeleteDC(); 


posted by 유돌이
2009. 3. 21. 11:33 C/C++/MFC
HBRUSH CXDialog::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

if (nCtlColor == CTLCOLOR_STATIC)
{
pDC->SetBkMode(TRANSPARENT);
return (HBRUSH)::GetStockObject(NULL_BRUSH);
}

return hbr;
}

posted by 유돌이
2009. 3. 21. 11:32 C/C++/MFC
출처 김규민의 침묵으로 쓰는 시(詩) | 정천사
원문 http://blog.naver.com/angelkkm80/20035746964

-마우스 클릭 메시지 (누름, 땜, 더블클릭 순서)
좌측 : WM_LBUTTONDOWN, WM_LBUTTONUP, WM_LBUTTONDBLCLK
우측 : WM_RBUTTONDOWN, WM_RBUTTONUP, WM_RBUTTONDBLCLK
중앙 : WM_MBUTTONDOWN, WM_MBUTTONUP, WM_MRBUTTONDBLCLK

wParam 값 : 마우스 버튼 상태와 키보드 조합키 상태가 전달
MK_CONTROL - CTRL 키가 눌려져 있다.
MK_LBUTTON - 마우스 왼쪽 버튼이 눌려져 있다.
MK_RBUTTON - 마우스 오른쪽 버튼이 눌려져 있다.
MK_MBUTTON - 마우스 가운데 버튼이 눌려져 있다.
MK_SHIFT - shift키가 눌려져 있다.
등등...
*자세한 내용은 인터넷검색이나 msdn, 혹은 .h파일을 참조


lParam 값 : 마우스 버튼이 눌러진 y,x 좌표 정보가 담겨있다.
왜 y,x 순서인가 하면 상위비트는y가, 하위비트에는 x이기 때문이다.
좌표검출(비트분해)을 위해 HIWORD(lParam), LOWORD(lParam)의 매크로 함수를 이용한다.
             ┌────┬────┐
lParam = │         Y │ X         │
             └────┴────┘

-WM_MOUSEMOVE : 마우스가 이동할때 마다 발생하는 메세지

wParam 값:조합키상태

lParam 값:마우스커셔의 위치

 

-WM_MOUSEWHEEL : 마우스 휠을 이용할때 발생하는 메세지
#include <zmouse.h>와 같이 이용(2000이하 사용자)

wParam 값:
HIWORD(wParam) : 휠을 굴렸을때 120, -120 값으로 위,아래를 결정한다.
LOWORD(wParam) : 휠과 같이 사용할 조합키를 나타낸다.(마우스클릭조합과 같음)

lParam 값:마우스커셔의 위치

이런방법도 있다.(메크로함수)
fwKeys = GET_KEYSTATE_WPARAM(wParam);
zDelta = GET_WHEEL_DELTA_WPARAM(wParam);
xPos = GET_X_LPARAM(lParam);
yPos = GET_Y_LPARAM(lParam);


-더블클릭
더블클릭 메세지를 사용하기위해서는 윈도우클래스 등록에서 style에 CS_DBLCLKS 을
추가 해야만 한다.
예)WndClass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;

이렇게 된 이유는 더블클릭이 생각보다 많은 딜레이를 발생하기 때문에 꼭 필요할
경우 계발자가 추가하도록 하기 위해서 이다.

 

-비 작업 영역에서의 마우스 메세지
-WM_NC******** 등으로 표현된다.(NC는 None Client 같다.)자세한 내용은 다음에..

 

 

주의 - wParam 과 lParam값은 메세지마다 틀리다.

 


posted by 유돌이
2009. 3. 21. 11:32 C/C++/MFC
include "stdafx.h"는 Visual C++에서 생성한 header file에서 쉽게 볼 수 있다.
여기서 발생하는 에러 2가지 정도에 대한 처리는 반드시 알고 있어야 한다.

1.fatal error C1010: unexpected end of file while looking for precompiled header directive
2.fatal error C1852: 'Debug/test.pch' is not a valid precompiled header file

이는 소스코드에 제일 상단에 #include "stdafx.h"을 주석처리하거나, 다른 파일을 먼저 #include 하거나 할 때 발생한다. 이는 Visual C++에서 컴파일 할 때 제일상단에 #include "stdafx.h"가 있는지를 확인하는데, 발견되지 않기 때문에 발생하는 에러이다. 해결방법은 모든 cpp파일의 제일상단에 #include "stdafx.h"를 해야 한다.

3.fatal error C1853: "Debug/test.pch" is not a precompiled header file created with this compiler
#include "stdafx.h"를 모든 cpp파일의 제일상단에 포함을 했는데에도 위 에러가 발생하는 경우가 종종 있다. 해결방법은 잠시 후에 하도록 하겠다.

그럼 #include "stdafx.h"이 뭔가?
사실은 #include "stdafx.h"이 중요한 것이 아니고, precompiled header가 무엇인지 아는 것이 중요하다. 물론 자세한 내용은 MSDN-Creating Precompiled Header Files을 참조하기를 바라고, 여기서는 간단하게만 설명을 하고 넘어가겠다.

windows programming에서 제공하는 다양한 resource(button, list, combo)를 사용하여 programming을 하게 되는데, 이들 resource를 포함하여 매번 컴파일을 하게 되면 컴파일 시간이 많이 걸린다. 이를 위해서 미리 이 부분에 대해서 컴파일을 해두고, 사용자가 컴파일 할 때 이러한 미리 컴파일 된 정보를 가져와서 빨리 컴파일을 하기 위한 용도로 precompiled header라는 것을 사용한다. Visual C++에서는 default로 precompiled header를 사용하도록 설정이 되어 있으며, 처음 프로젝트를 생성하여 컴파일 할 때에는 시간이 많이 걸리지만, 이후에 자신이 작성한 소스를 생성, 수정하여 컴파일 할 때에는 빠르게 처리되는 것을 한번쯤은 느껴보았을 것이다.

다시 말하면 precompiled header로 default로 설정이 되어 있는 것이 "stdafx.h"이고, 처음 컴파일을 하면 미리 컴파일 된 정보가 name.pch(파일 확장자 pch는 precompiled header의 약자)로 Debug 또는 Release 폴더에 생성되는 것을 볼 수 있다.

"stdafx.h"는 한번쯤 열어보면, windows program으로 project를 생성한 경우, window와 관련된 다양한 header file을 #include하고 있고, 본인은 여기에 모든 소스에 공통적으로 사용되기를 원하는 #define, #pragma(lib 처리를 위해 종종 사용, 자세한 것은 다음 시간에)등에 활용하기도 한다.

마지막으로 어떤 소스들은 #include "stdafx.h"를 제일상단에 포함을 하지 않았는데에도 아무런 에러가 발생하지 않는 경우가 있다. 이는 precompiled header를 사용하지 않겠다고 지정을 한 경우이다.

메뉴>Project/Settings

를 보면 /Yu"stdafx.h"를 볼 수 있는데, 이것이 이 프로젝트는 precompiled header로 "stdafx.h"를 설정, 이용하겠다는 의미이다. 그래서 만일 precompiled header를 이용하지 않으려면 /Yu"stdafx.h"를 지워버리고 OK버튼을 눌러주면 된다.

그 외 방법으로는 precompiled header 설정으로 가서



precompiled header를 이용하지 않거나, 다른 파일로 precompiled header를 설정할 수도 있다. 이를 이용하여 위의 3번 에러에 대한 수정도 할 수 있다.

#include "stdafx.h"와 precompiled header는 매우 자주 접하게 되는 에러와 연관이 있기 때문에 한번쯤 관심 있게 살펴보는 것이 매우 중요하다고 생각이 된다. 
posted by 유돌이
2009. 2. 9. 21:40 C/C++/MFC
미 아시겠지만, 세션에는 ASP.NET에는 3가지의 세션 모드를 지원하고 있습니다. 
 
1) InPro방식 , 2) StateServer방식, 3) SQLServer방식  
  1. 세션 저장방식 
    1) 웹서버의 메모리에 저장된다. 
     
    2) 분리된 프로세스(aspnet_state.exe)의 메모리에 serialize된 형태로 저장된다. 분리된 서버에 저장이 가능하다. 
     
    3) serialize된 형태로 SQL서버에 저장된다. 
     
  2. 성능 
    1) 속도가 가장 빠르다. 세션저장소가 웹서버의 메모리이므로 저장량이 많아질 경우 웹서버 처리속도에 영향을 미칠 수 있다. 
     
    2) 기본형식의 데이타(string, integer등)인 경우 기준으로 15%의 속도저하가 있다고 알려짐.  
    그렇지만, 일반 object를 저장할 경우, serialize/deserialize과정을 거쳐야 하므로 성능은 더욱 저하될 수 있다. 
     
    3) 기본형식의 데이타인 경우 기준으로 25%의 속도저하가 있다고 알려짐. 
    stateServer방식과 마찬가지로, 일반 object를 저장할 경우, serialize/deserialize과정을 거쳐야 하므로 성능은 더욱 저하됨. 
     
  3. 문제점 
    1) aspnet_wp 프로세스가 재기동(recycle)되면 세션상태가 사라짐(SP2: 비정상적 recycle을 해결함).  
    어플리케이션을 다시 시작해도 세션사라짐.  
    이유는 어플리케이션의 메모리영역에 세션을 저장하기 때문에, 어플리케이션이 재시작하면 메모리영역을 다시 할당받기 때문이다. 
     
    어플리케이션을 재시작되는 되는 사항 
     
           가) config파일의 수정(web.config, machine.config, global.asax등) 
           나) \bin 디렉토리 밑의 파일 수정(즉 컴파일을 새로 하게되면 세션 사라지는 큰 문제점이 있음) 
     
    2) Inproc방식의 세션사라지는 문제를 해결함. WebFarm환경에서 특정서버에 세션을 저장하게 하는 것을 가능하게 함. 
    그렇지만, 세션서버의 장애발생시 모든 웹서버의 세션이 작동안하는 문제점이 있음. 
     
    3) Inproc방식의 세션사라지는 문제를 해결함. SQL서버가 재기동되어도 세션 사라지지 않음. 
    또한 SQL서버의 클러스터링을 이용하면, 특정 SQL서버의 장애시에도 서비스 가능함. 
     
  4. 유의사항 
    1) Web Garden mode에선 제대로 동작안함.(주: Web Garden이란 프로세서(CPU) 독립적으로 aspnet_wp.exe가 실행됨) 
    WebGarden을 사용하려면, StateServer나 SQLSERVER로 바꾸어야 함. 
    Session_End 이벤트는 Inproc 모드에서만 동작한다. 
     
    2) Web Farm방식에서는 모든 웹서버들은 같은 machineKey를 가져야 한다. 
    또한 저장되는 객체가 serializable하는지 확인해야 한다. 
    Web Farm방식에서 다른 서버로 세션이 전달되기 위해서는 어플리케이션의 경로가 같아야 한다. 
     
    3) 저장되는 객체가 serializable하는지 확인해야 한다. 
    Web Farm방식에서 다른 서버로 세션이 전달되기 위해서는 어플리케이션의 경로가 같아야 한다. 
     
  5. 자주 묻는 질문 
    1) ASP와 ASP.NET의 세션을 공유할 수 있는지요..? 
    - 불가능합니다. 
     
    2) 서로 다른 웹어플리케이션 사이에 세션을 공유할 수 있는지요.. 
    - 불가능합니다. 
     
    3) Inproc방식에서 왜 가끔 세션값이 사라지나요? 
    - 어플리케이션의 recycle때문입니다. SP2에서 Fix 되었습니다. 
     
    4) 어떤 종류의 객체가 세션에 저장될 수 있나? 
    - 세션저장 방식에 따라 달라집니다. 
     
    Inproc방식에서는 어떤 객체라도 저장할 수 있으나,  
    StateServer와 SQLServer방식에서는 serializable한 객체만 저장될 수 있습니다. 
    사용자가 직접 만드는 클래스인 경우 serializable속성을 추가함으로써 저장이 가능하나,  
    제공되는 클래스인 경우 Object명.GetType.IsSerializable() 로써 알아볼 수는 있으나,  
    변경은 불가능한 것 같습니다. (확실하진 않습니다). 
     
    5) Serializable은 어떻게 지정하나? 
    - C# 
    [Serializable]  
    public class MyClass  
    {  
           //class code  
    }  
     
    - VB.NET 
    <Serializable()> _  
    Public Class MyClass  
           'Class code  
    End Class 
posted by 유돌이
2009. 2. 9. 21:39 C/C++/MFC
[인터페이스]

인터페이스란, 좁은 의의 인터페이스로

순수가상함수만을 갖는 클래스를 말합니다.

넓은 의미의 인터페이스란, 앞으로 프로그램을 어떻게 짤것인지,

클래스는 어떤 구조를 갖도록 설계할 것인지를 위한 약속이라고 보시면 됩니다.

 

[COM 이란?]

아래 보이는 그림이 바로 COM객체의 구조이다.

-WGPD에도 이와 동일한 그림이 첨부되있다.

사실 여러가지 설명이 있지만 개인적으로 보기엔 이 그림만으로 충분하다고 보기에

이것만 넣었고 다른 설명의 그림도 COM을 이해하는데 도움이 되지만 귀찮다 솔직히 ㅡㅡ;

 

 

 

 

흠...단순히 위의 그림을 설명하자면 'COM 객체'라는 커다란 사각형이 있고

작은 사각형 2개가 이 안에 포함돼 있다.이 사각형은 Interface A와 Interface B이고

각각 사각형은 입력과 출력이 존재한다.

즉 정리하자면 COM객체 안은 Interface들이 있고 각 Interface안에는 입력과 출력이 있으면

함수들(method)이 존재한다. 이게 COM이란다. 

참고로 인터페이스는 그냥 일련의 함수가 집합된C++에서의 Class라고 보면 된다.

이처럼 보통 COM객체는 하나 이상의 Interface를 포함한다.

-내 생각으론 입문자 입장에서 저 그림이상의 것은 아직까진 필요없다고 본다.

 

 

그러면 DirectX 또한 COM객체이므로 이런 구조를 갖는 것은 자명하다. 

또 같은 그림을 그리기 귀찮으니

Interface A는 DirectDraw를, Interface B는 DirectSound를 대입.뭐 이런식으로 보면 된다.

염두 해야 될점은 Interface는 내부의 또 다른 Interface를 갖을 수 있다는 점인데

이는 DirectDraw에 관한 chapter에서 언급하기로 한다.


posted by 유돌이
2009. 2. 9. 21:38 C/C++/MFC

PostQuitMessage

원형 VOID PostQuitMessage(int nExitCode);
인수

▶nExitCode : 종료 코드. 이 값은 WM_QUIT의 wParam으로 전달되며 잘 사용되지 않으므로 보통 0으로 전달한다. 이 값은 메시지 루프 종료 후에 다시 WinMain의 리턴값으로 재사용되며 결국 프로세스의 종료 코드가 되는데 프로세스의 종료 코드도 사용되는 경우가 드물다.

리턴 리턴값이 없다.
설명

스레드 메시지 큐에 WM_QUIT 메시지를 붙이고 즉시 리턴한다. WM_QUIT 메시지를 큐에 붙임으로써 시스템에게 이 스레드가 종료될 것이라는 것을 미리 알려준다. 메시지 루프는 보통 WM_QUIT 메시지를 받으면 종료하도록 되어 있으므로 이 함수를 호출하면 메시지 루프가 종료된다. 특히 이 함수를 호출하는 스레드가 주 스레드일 경우는 주 스레드의 메시지 루프가 종료됨으로써 프로세스가 종료된다.

단, 이 함수는 메시지를 큐에 붙인 후 즉시 리턴하므로 호출 즉시 프로세스가 종료되는 것은 아니다. 즉 PostQuitMessage 호출 후 다른 처리를 계속할 수 있으며 이미 메시지 큐에 들어와 있는 모든 메시지가 처리된 후에 WM_QUIT 메시지가 읽혀져야 종료된다. 반면 ExitProcess 함수는 즉시 프로세스를 종료하기 때문에 이 함수 아래에 작성된 코드는 실행되지 않는다.

통상 이 함수는 메인 윈도우의 WM_DESTROY 메시지 처리 코드에 작성되어 메인 윈도우가 파괴되면 응용 프로그램을 종료하는 역할을 한다. 차일드 윈도우가 WM_DESTROY에서 이 메시지를 호출해서는 안된다. 그래서 DefWindowProc은 WM_DESTROY 메시지를 디폴트 처리할 때 PostQuitMessage를 호출하지 않도록 되어 있다.

참고함수 PostMessage, SendMessage
플렛폼 95이상
본문참조  

posted by 유돌이
prev 1 2 3 4 next