유돌이

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 31

Notice

2009. 1. 6. 08:44 유닉스*리눅스*SE

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

#!/bin/sh
echo -n "당신의 이름은? "
read name
echo -n "당신의 나이는? "
read age

echo 이름 : $name
echo 나이 : $age

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

예제2는 read 명령을 이용해서 키보드로부터 값을 읽어드린후
그 값을 변수에 저장하고 출력해보는 것이다.


'유닉스*리눅스*SE' 카테고리의 다른 글

[centos7] yum 명령어 안될시~  (0) 2019.09.12
[우분투 16.04] SSD 마운트 하기  (0) 2019.09.11
[안드로이드] 커널로그 보기  (0) 2019.09.11
cp시 omitting error 날때  (0) 2009.01.05
유닉스 명령어  (0) 2009.01.05
posted by 유돌이
2009. 1. 5. 22:31 C/C++/MFC

[숨기기]

GetDlgItem(숨길아아디)->ShowWindow(SW_HIDE);

 

 

[나타내기]

GetDlgItem(나타낼아이디)->ShowWindow(SW_SHOW);


'C/C++/MFC' 카테고리의 다른 글

API 종료 방법  (0) 2009.01.10
메뉴 항목 체크/ 해지 하기  (0) 2009.01.10
CWnd 클래스  (0) 2009.01.05
포인터 사용법  (0) 2009.01.05
MFC를 사용하여 웹 브라우저 만들기  (0) 2009.01.02
posted by 유돌이
2009. 1. 5. 22:29 C/C++/MFC

클래스

생성/소멸

l        CWnd

1.       설명 : CWnd 객체를 생성한다. Windows 윈도는 CreateEx나 Create 멤버 함수가 호출 될 때까지 생성되거나 부가되지 않는다.

l        DestroyWindow

1.       설명 : CWnd 객체에 부가되는 Windows 윈도를 파괴한다. DestroyWindow 멤버 함수는 그것의 활동을 제거하고 입력 초점을 제거하기 위해 윈도에 적절한 메시지를 전달한다. 또한 윈도의 메뉴를 파괴하고, 애플리케이션 큐를 지우며, 사용되는 타이머를 지우고, 클립보드 소유를 제거하며, 클립보드-뷰어의 체인이 CWnd의 뷰어 체인의 맨 위에 있다면 파괴한다. 그것은 CWnd 객체를 파괴하지 않는다. 

윈도가 어떠한 윈도의 부모이면, 이들의 자식 윈도들은 자동적으로 부모 윈도가 파괴될 때 파괴된다. DestroyWindow 멤버 함수는 또한 CDialog::Create 에 의해 생성된 모델이 없는 다이얼로그 박스를 파괴한다.

파괴된 CWnd가 자식 윈도이고 WS_EX_NOPARENTNOTIFY 스타일 세트를 갖지 않는다면,  WM_PARENTNOTIFY 메시지는 부모로 보내진다.

2.       구문 : virtual BOOL DestroyWindow();

3.       파라미터 : 없음.

4.       리턴값 : 윈도가 파괴되면 0 이외의 값이며, 그 외의 경우에는 0을 리턴한다.

초기화

l        Create

1.       설명 : Windows 자식 윈도를 생성하고 CWnd 객체에 그것을 부가한다. 두 단계로 자식 윈도를 생성할 수 있다. 우선 생성자를 호출한다. 그것은 CWnd 객체를 생성한다. 그리고 나서 Windows 자식 윈도를 생성하고 그것을 CWnd에 부가하는 Create를 호출한다. Create는 윈도의 클래스 이름과 윈도 이름을 초기화하며, 그것의 스타일, 부모, ID에 대한 값들을 등록한다.

2.       구문 : virtual BOOL Create( LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWND* pParentWnd, UINT nID, CcreateContext* pContext=NULL );

3.       파라미터

lpszClassName Window 클래스에 명명하는 널-종결된 문자 스트링을 가르킨다. ( WNDCLASS 구조체 )  이 클래스 이름은 전역 AfxRegisterWndClass 함수 또는 이미 정의 된 컨트롤 클래스 이름 중 어느 것으로 등록할 수 있다. 만일 NULL이면, 디폴트 CWnd 속성을 이용한다.

lpszWindowName 윈도 이름을 포함하고 있는 널 종결 문자 스트링을 가리킨다. 이 윈도 이름은 캡션으로 표시된다. 

dwStyle 윈도를 생성할 때 사용되는 윈도 스타일. WS_POPUP 스타일을 사용할 수 없다. 팝업 윈도우를 생성하기 위하여 CWnd::CreateEx 함수를 사용한다.

rect pParentWnd의 클라이언트 좌표에서 윈도의 크기와 위치를 나타낸다.

pParentWnd 윈도의 부모 윈도를 나타내는 CWnd에 대한 포인터. 부모가 테스크탑 윈도이면 NULL이다.

nID- 자식 윈도의 ID.

 pContext 생성되는 윈도우의 컨텍스트를 기술하는 데 사용되는 CCreateContext 구조체에 대한 포인터.       

4.       리턴값 : 윈도가 생성되면 비제로, 그렇지 않으면 0.

[ 윈도우 스타일 ]

WS_BORDER

가는 선 테두리로 된 윈도를 하나 만든다.

WS_CAPTION

타이틀 바가 있는 윈도를 하나 만든다. WS_BORDER스타일을 포함한다.

WS_CHILD

자식윈도나 컨트롤을 만든다. 이 스타일을 사용하면 WS_POPUP은 사용할 수 없다.

WS_CHILDWINDOW

WS_CHILD 스타일과 같다.

WS_CLIPCHILDREN

그리기 작업이 일어날 때 컨트롤의 자식 윈도를 클리핑한다. 이 스타일은 부모 윈도를 만들 때 사용된다.

WS_CLIPSIBLINGS

그리기 작업이 일어날 때 자식 윈도와 같은 레벨의 윈도들을 클리핑한다. 스타일이 정해져 있지 않고 자식 윈도가 WM_PAINT 메시지를 받으면 동기가 윈도로 윈도가 겹쳐져 있어도 윈도우의 전체 영역이 갱신 영역에 추가된다.

WS_DISABLED

만들어 질 때부터 사용자 입력이 불가능한 상태의 윈도가 만들어 진다.

WS_DLGFRAME

대화상자에 사용되는 스타일의 테두리가 있는 윈도를 하나 만든다. 이 스타일로 만들어진 윈도는 타이틀 바를 가질 수 없다.

WS_GROUP

한 그룹의 처음 컨트롤임을 표시한다. 다음 WS_GROUP 스타일을 가진 컨트롤을 만나면 현재 그룹은 끝나고 다음 그룹이 사작된다. 보통 라디오 버튼이 그룹화되어 존재하며 한 그룹 내의 개개 항목들간은 화살표 키로 이동할 수 있다.

WS_HSCROLL

수평 스크롤 바가 있는 윈도를 만든다.

WS_ICONIC

WS_MINIMIZE와 같다.

WS_MAXIMIZE

처음부터 전체 화면으로 표시되는 윈도를 하나 만든다.

WS_MAXIMIZEBOX

전체 화면 표시 버튼이 있는 윈도를 만든다.

WS_MINIMIZE

처음부터 아이콘 표시된 윈도를 만든다.

WS_MINIMIZEBOX

아이콘 표시 버튼이 있는 윈도를 만든다.

WS_OVERLAPPED

타이틀 바와 테두리가 있는 윈도를 만든다.

WS_OVERLAPPEDWINDOW

WS_BORDER, WS_POPUP, WS_SYSMENU, WS_THICKFRAME, WS_MAXIMIZEBOX, WS_MINIMIZEBOX의 조합

WS_POPUP

팝업 윈도를 만든다. WS_CHILD는 이 스타일과 함께 쓰일 수 없다.

WS_POPUPWINDOW

WS_BORDER, WS_POPUP, WS_SYSMENU의 조합. 시스템 메뉴가 보이도록 WS_CAPTION이 지정되어야 한다.

WS_SIZEBOX

WS_THICKFRAME과 같다.

WS_SYSMENU

타이틀 바에 시스템 메뉴가 있는 윈도를 만든다.

WS_TABSTOP

탭 키 멈춤 컨트롤을 지정한다.

WS_THICKFRAME

크기 조절 경계선이 있는 윈도를 만든다.

WS_TILED

WS_OVERLAPPED와 같다.

WS_TILED_WINDOW

WS_OVERLAPPEDWINDOW와 같다.

WS_VISIBLE

처음부터 눈에 보이는 윈도를 만든다.

WS_VSCROLL

수직 스크롤 바가 있는 윈도를 만든다.

 

l        CalcWindowRect

1.       설명 : 계획된 클라이언트 사각형 크기에 바탕을 둔 윈도 사각형의 요구된 크기를 계산하기 위해 이 멤버 함수를 호출한다. 결과로 생성되는 윈도 사각형(lpClientRect에 포함된)은 그때 클라이언트 영역이 원하는 크기를 지닌 윈도를 생성하기 위해 Create 멤버 함수를 지나칠 수 있다. 윈도를 생성하기 전에 윈도의 크기를 조절하기 위하여 프레임워크로 호출한다. 클라이언트 사각형은 클라이언트 영역을 완전히 봉하는 가장 작은 크기의 사각형이다. 윈도 사각형은 윈도를 완전히 봉하는 가장 작은 크기의 사각형이다.

2.       구문 : virtual void CalcWindowRect( LPRECT lpClientRect, UINT nAdjustType = adjustBorder );

3.       파라미터

lpClientRect 윈도 사각형의 결과 값을 포함하는 RECT 구조체나 Crect 객체에 대한 포인트들을 나타낸다. 함수의 처리가 완료되면, 이 사각형에는 그 결과 윈도 사각형의 좌표로 채워진다.

nAdjustType 사각형 좌표 계산에 스크롤바를 제외하려면 adjustBorder=0, adjustOutside=1은 사각형의 마지막 측정에 더해짐을 의미한다.

             4.  리턴값 : 아무 것도 리턴하지 않는다. 

l        GetStyle

1.       설명 : 윈도의 스타일 플래그를 리턴한다. GetStyle은 GWL_STYLE 플래그로 SDK함수 ::GetWindowLong를 호출한다.

2.       구문 : DWORD GetStyle() const;

3.       파라미터 : 없음.

l        GetExStyle

1.        설명 : 윈도의 확장 스타일 플래그를 얻는다. 이 함수는 단순히 GWL_EXSTYLE 플래그로 SDK함수 ::GetWindowLong를 호출한다.

2.        구문 : DWORD GetExStyle() const;

3.        파라미터 : 없음.

4.        리턴값 : 아무 것도 리턴하지 않는다.

l        Attach

1.       설명 : CWnd 오브젝트에 윈도(HWND)를 붙인다. 윈도가 CWnd 오브젝트에 붙어 있으면, CWnd 멤버 함수는 그 윈도를 조작하는데 사용된다. MFC 밖에서(CWnd::Create나 CWnd::CreateEx함수가 아닌) 생성된 윈도를 조작하려면 이 함수를 사용하라. 이것은 시스템 자체나 서드 파티 소프트웨어 라이브러리에서 생성된 윈도이다. CWnd 오브젝트에 윈도를 붙이는 것은 윈도에 전달된 메시지를 자동적으로 받을 수 없게 한다. 메시지를 받는 자세한 내용은 CWnd::SubclassWindow 함수를 참고하라.

2.       구문 : public BOOL Attach(HWND hWndNew);

3.       파라미터

hWndNew CWnd 오브젝트에 붙어 있게 될 윈도 핸들.

             4.  리턴값 : 아무 것도 리턴하지 않는다.

l        Detach

1.          설명 : 현재 붙어 있는 윈도우(HWND)에서 CWnd 오브젝트를 떼어낸다. CWnd 오브젝트가 HWND에 붙어 있으면 CWnd는 윈도를 조정하는 데 사용된다. 윈도에서 떨어지면 다시 붙을 때까지 CWnd 오브젝트를 사용할 수 없다.

2.          구문 : public HWND Detach();

3.          파라미터 : 없음.

4.          리턴값 : CWnd 오브젝트에 붙어 있는 HWND.

l        FromHandle

1.       설명 : 주어진 윈도 핸들을 CWnd에 대한 포인터로 리턴한다. MFC가 지정 핸들과 관련되는 영구 CWnd를 가지고 있지 않으면 임시 CWnd를 만들어 핸들에 연결한다. 임시 CWnd는 애플리케이션이 윈도에 제어를 리턴할 때 생기는 아이들 루프에 들어갈 때까지 FromHandle에 의해 리턴된 정당한 CWnd를 사용할 수 있도록 아이들 시간 처리 동안 자동적으로 파괴된다.  

2.       구문 : static CWnd* PASCAL FromHandle( HWND hWnd );

3.       파라미터

hWnd CWnd 오브젝트와 관련되는 윈도 핸들.

             4.  리턴값 : 임시적인 새로운 CWnd에 대한 포인터.

l        GetSafeHwnd

1.       설명 : CWnd 오브젝트와 현재 관련된 윈도 핸들을 리턴한다. NULL CWnd를 호출한다 해도 안전(safe)하기 때문에 GetSafeHwnd라 부른다.

2.       구문 : HWND GetSafeHwnd() const;

3.       파라미터 : 없음.

4.       리턴값 : CWnd 오브젝트와 현재 관련된 현재 관련된 윈도 핸들. CWnd가 NULL이거나 윈도에 관련된 핸들이 없으면 NULL.

l        CreateEx

1.        설명 : 주어진 특징과 스타일로 윈도를 생성하고 그 윈도를 CWnd 오브젝트와 관련시킨다. 확장된 스타일로 된 윈도, 예를 들어 투명 윈도를 생성하려면 CWnd::Create 함수 대신에 이 함수를 사용하라.

2.        구문 : public virtual BOOL CreateEx( DWORD dwExStyle, LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hwndParent, HMENU nID 또는 HMenu, LPVOID lpParam = NULL );

3.        파라미터

dwExStyle 확장된 윈도 스타일.

lpszClassName 윈도로 사용할 윈도 클래스의 이름을 갖는 널로 끝나는 문자열에 대한 포인터. NULL이면 MFC는 대부분의 경우에 충분히 만족할 수 있는 기본 윈도 클래스를 사용한다. 자기 자신의 윈도 클래스를 등록하기 위하여 AfxRegisterWndClass 함수를 사용할 수 있다.

LpszWindowName 윈도의 이름을 갖는 널로 끝나는 문자열에 대한 포인터. 이 윈도의 이름은 캡션으로 표시된다.

DwStyle 윈도를 생성할 때 사용되는 윈도 스타일. WS_POPUP 스타일이 사용될 수 없다는 것에 유의하라. 팝업 윈도를 생성하기 위하여 CWnd::CreateEx함수를 사용하라.

X 부모윈도의 사용자 좌표로 표시되는 윈도의 왼쪽 상단의 x좌표.

Y 부모윈도의 사용자 좌표로 표시되는 윈도의 왼쪽 상단의 y좌표.

NWidth 윈도의 폭.

NHeight 윈도의 높이.

hwndPrent 윈도의 부모 윈도의 핸들.

NIDorHMenu 윈도 스타일에 따라 할당되는 윈도나 메뉴 ID. 이 ID를 사용하여 부모윈도에 있는 자식 윈도를 참조한다. 예를 들어, CWnd::GetDlgItem 함수는 ID로 주어진 자식 윈도에 대한 포인터를 얻는다.

LpParam 사용자 데이터에 대한 포인터. 이 파라미터에 대해 어떤 포인터도 전달할 수 있다. 이 포인터는 CREATESTRUCT 구조체의 lpCreteParams로 CWnd::OnCreate 핸들러에 전달된다. 

             4.  리턴값 : 윈도가 생성되면 비제로, 그렇지 않으면 0.

WS_EX_ACCEPTFILES

드래그 앤 드롭 파일을 받아들이는 윈도를 생성한다.

WS_EX_APPWINDOW

최상위 레벨 윈도가 이이콘으로 표시되면 그 윈도를 작업표시줄에 넣는다.

WS_EX_CLIENTEDGE

윈도의 테두리에 움푹 들어간 가장자리가 있다.

WS_EX_CONTEXTHELP

윈도의 타이틀 바에 (?)표시를 둔다. 사용자가 이 표시를 클릭하면 커서가 물음표 표시가 있는 포인터로 바뀐다. 그 후 자식 윈도를 클릭하면 그 자식 윈도가 WM_HELP 메시지를 받는다. 

WS_EX_CONTROLPARENT

사용자가 TAB키를 눌러서 자식 윈도 사이를 왔다갔다 할 수 있게 한다.

WS_EX_DLGMODALFRAME

이중 테두리를 가진 윈도를 생성한다. 타이틀을 추가하려면 dwStyle값에 WS_CAPTION을 넣는다.

WS_EX_LEFT

좌측 정렬 속성을 가진 윈도우를 생성한다. 디폴트.

WS_EX_LEFTSCROLLBAR

수직 스크롤바를 만들 경우 클라이언트 영역의 왼쪽에 둔다.

WS_EX_LERREADING

왼쪽에서 오른쪽으로 읽는 텍스트를 가진 윈도를 생성한다. 디폴트.

WS_EX_MDICHILD

MDI 자식 윈도를 생성한다.

WS_EX_NOPARENTNOTIFY

WM_PARENTNOTIFY 메시지를 보내지 않는다.

WS_EX_OVERLAPPEDWINDOW

WS_EX_CLIENTEDGE와 WS_EX_WINDOEDGE 스타일의 조합이다.

WS_EX_PALETTEWINDOW

WS_EX_WINDOWEDGE, WS_EX_SMCAPTION, WS_EX_TOPMOST 스타일의 조합이다.

WS_EX_RIGHT

우측 정렬 속성을 가진 윈도를 생성한다.

WS_EX_RIGHTSCROOLBAR

수직 스크롤바를 만들 경우 클라이언트 영역으 오른쪽에 둔다. 디폴트.

WS_EX_RTLREADING

오른쪽에서 왼쪽으로 읽는 텍스트를 가진 윈도를 생성한다.

WS_EX_STATICEDGE

입체감 있는 테두리 스타일의 윈도를 생성한다. 사용자 입력을 받아들이지 않는 항목에 이 스타일을 사용한다.

WS_EX_TOOLWINDOW

도구(tool) 윈도를 생성한다. 도구 윈도는 위치 이동이 가능한 도구 상자에서 사용된다.

WS_EX_TOPMOST

최상위 레벨이 아닌 모든 윈도위에 두고자 하는 윈도를 생성한다.

WS_EX_TRANSPRENT

투명한 윈도를 생성한다. 이 윈도에 의해서 가려지는 동기간 윈도는 WM_PAINT 메시지를 먼저 받고 그 후 투명한 모양으로 윈도가 생성된다.

WS_EX_WINDOWEDGE

가장자리가 돌출된 테두리가 있는 윈도를 생성한다.

l        CreateControl

1.          설명 : CWnd 객체에 의해 MFC 프로그램에서 나타날 OLE 컨트롤을 생성하는데 사용한다. CreateControl은 CWnd::Create 함수의 직접적인 아날로그로서, CWnd를 위한 윈도를 생성 시킨다. CreateControl은 일상적인 윈도 대신 OLE 컨트롤을 생성시킨다. 단지 윈도 dwStyle 플래그의 서브 세트만이 CreateControl을 지원한다.( WS_VISIBLE, WS_DISABLED, WS_BORDER, WS_GROUP, WS_TABSTOP )

2.          구문 : BOOL CreateControl( LPCTSTR lpszClass{REFCLSID clsid}, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, Cfile* pPersist = NULL, BOOL bStorage = FALSE, BSTR  bstrLieKey = NULL );

3.          파라미터

lpszClass 생성될 컨트롤의 클래스를 대표하는 스트링에 대한 포인터이다.

lpszWindowName 컨트롤에 표시된 텍스트에 대한 포인터이다. 컨트롤의 Caption표시.

dwStyle Window 스타일.

rect 컨트롤의 크기나 위치를 지정한다.

pParentWnd 컨트롤의 부모 윈도를 지정한다. 이 값이 NULL이면 안된다.

nID 컨트롤 ID를 지정한다.

pPersist 컨트롤을 위한 지속적인 상태를 포함하는 Cfile에 대한 포인터이다. 디폴트 값은 NULL이며, 그것은 이 컨트롤을 위해 어느 지속적인 상태도 부하가 가해지지 않음을 가리킨다.

bStorage 데이터가 IStorage 데이터(TRUE) 또는 IStream 데이터(FALSE)로서 해석이 가능해야 한다. 디폴트 값은 FALSE이다.

bstrLicKey 선택적인 라이센스 키 데이터이다. 이 데이터는 단지 런타임 라이센스 키가 요구되는 생성 컨트롤에서만 필요하다. 디폴트 값은NULL이다.

clsid 컨트롤을 위한 유일한 클래스 ID이다.

             4.  리턴값 : 성공적으로 수행될 경우 0 이외의 값이며, 작동이 실패할 경우 0 이다.

 

윈도 상태 함수

l        IsWindowEnable

1.       설명 : CWnd이 마우스와 키보드 입력에 대해 실행 가능한지를 지정한다.

2.       구문 : BOOL IsWindowEnable() const;

3.       파라미터 : 없음.

4.       리턴값 : 윈도가 사용할 수 있으면 비제로, 그렇지 않으면 0.

l        EnableWindow

1.  설명 : 마우스의 입력과 키보드의 입력을 가능하거나 불가능하게 한다. 입력이 불가능하면, 마우스 클릭이나 키스느로크와 같은 입력은 무시된다. 입력이 가능하면, 윈도는 모든 입력을 처리한다. 마일 실행 가능 상태가 변한다면, WM_ENABLE 메시지가 이 함수가 리턴되기 전에 보내진다. 만일 불가능 상태이면, 비록 WM_ENABLE 메시지가 전달 되었어도 암시적으로 불가능하다. 윈도는 반드시 활동하기 전에 가능하게 되어야 한다. 디폴트로, 윈도는 그것이 생성될 때 사용 가능하다. 초기에 사용 불가능한 윈도를 생성하기 위해 Create 또는 CreateEx 멤버 함수에서 애플리케이션은 WS_DISABLED 스타일을 지정할 수 있다. 윈도가 생성된 후 애플리케이션은 또한 윈도를 사용가능하거나 불가능으로 만들기 위해 EnableWindow 멤버 함수를 이용한다.  

                    애플리케이션은 다이얼로그 박스에서 컨트롤을 사용 가능하거나 불가능하게 만들기 위해 이 함수를 이용할 수 있다. 불가능한 컨트롤은 입력 초점을 받지 못하거나, 액세스할 수도 없다.

2.       구문 : BOOL EnableWindow( BOOL bEnable = TRUE );

3.       파라미터

bEnable 윈도가 사용할 수 있게 하려면 TRUE, 사용할 수 없게 하려면 FALSE.

4.  리턴값 : 윈도가 이전에 사용할 수 없게 되어 있으면 TRUE, 사용할 수 있게 되어 있으면FALSE.

l        GetActiveWindow

1.         설명 : 현재 활성화된 윈도에 대한 포인터를 얻는다. 활성화 윈도는 입력 초점을 갖는 윈도나 CWnd::SetActiveWindow 함수에 대한 호출로 활성화 된 윈도이다.

2.         구문 : static CWnd* PASCAL GetActiveWindow();

3.         파라미터 : 없음.

4.         리턴값 : 활성화된 윈도에 대한 포인터나 어떤 윈도도 현재 활성화되지 않았다면 NULL. 리턴 포인터는 임시적이고 나중 사용을 위하여 보관하지 않아야 한다. 임시 CWnd는 애플리케이션이 윈도에 제어를 리턴할 때 일어나는 아이들 루프에 들어갈 때까지 GetActiveWindow에 의해 리턴되는 정당한 CWnd를 사용할 수 있도록 아이들 시간 처리 동안 자동적으로 파괴된다.

l        SetActiveWindow

1.       설명 : 윈도를 활성화 윈도로 만든다.

2.       구문 : CWnd* SetActiveWindow();

3.       파라미터 : 없음.

4.       리턴값 : 이전에 활성화된 윈도에 대한 포인터. 리턴 포인터는 임시적이고 나중 사용을 위하여 보관되지 않아야 한다. 임시 CWnd는 애플리케이션이 윈도에 제어를 리턴할 때 일어나는 아이들 루프에 들어갈 때까지 SetActiveWindow에 의해 리턴되는 정당한 CWnd를 사용할 수 있도록 아이들 시간 처리 동안 자동적으로 파괴된다.

l        GetCapture

1.       설명 : 마우스 캡처를 갖는 윈도에 대한 포인터를 얻는다. 한 번에 단 하나의 윈도만이 마우스 캡처를 가질 수 있다. 윈도는 CWnd::SetCapture 함수를 호출하여 마우스를 캡처한다. 윈도가 캡처된 마우스를 가질 때, 커서 위치가 윈도 내에 없더라도 마우스 메시지를 받는다.

2.       구문 : static CWnd* PASCAL GetCapture();

3.       파라미터 : 없음.

4.       리턴값 : 마우스 캡처를 갖는 윈도에 대한 포인터나 마우스 캡처를 갖지 않으면 NULL. 리턴 포인터는 임시적이고 나중 사용을 위하여 보관되지 않아야 한다. 임시 CWnd는 애플리케이션이 윈도에 제어를 리턴할 때 일어나는 아이들 루프에 들어갈 때 까지 GetActiveWindow에 의해 리턴되는 정당한 CWnd를 사용할 수 있도록 아이들 시간 처리 동안 자동적으로 파괴된다.

 

l        SetCapture

1.        설명 : 커서가 이 윈도우 위에 있는가에 관계없이 모든 마우스 메시지가 이 윈도에 보내지게 한다. 마우스 메시지는 CWnd::ReleaseCapture 함수가 호출될 때까지 잡힌다(Capture). 종종 사용자가 왼쪽 마우스 버튼을 누를 때 이 함수를 호출하고 버튼이 해제될 때 캡처를 해제한다.

2.        구문 : CWnd* SetCapture();

3.        파라미터 : 없음.

4.        리턴값 : 전에 캡처를 갖는 윈도에 대한 포인터. 아무 것도 없으면 NULL. 리턴 포인터는 임시 적이고 나중 사용을 위하여 보관되지 않아야 한다. 임시 CWnd는 애플리케이션이 윈도우에제어를 리턴할 때 일어나는 아이들 루프에 들어갈 때까지 SetCapture에 의해 리턴되는 정당한 CWnd를 사용할 수 있도록 아이들 시간 처리 동안 자동적으로 파괴된다.

l        GetFocus

1.       설명 : 현재 입력 초점을 갖는 윈도에 대한 포인터를 리턴한다.

2.       구문 : static CWnd* PASCAL GetFocus();

3.       파라미터 : 없음.

4.       리턴값 : 현재 입력 초점을 갖는 CWnd에 대한 포인터. 이 포인터는 임시적이고 나중 사용을 위하여 보관되지 않아야 한다. 임시 CWnd는 애플리케이션이 윈도에 제어를 리턴할 때 일어나는 아이들 루프에 들어갈 때까지 GetFocus에 의해 리턴되는 정당한 CWnd를 사용할 수 있도록 아이들 시간 처리 동안 자동적으로 파괴된다.

l        SetFocus

1.       설명 : 입력을 위해 선택된 것을 알린다. 입력 초점은 모든 키보드 입력을 윈도에 직접 전달한다. 이미 입력 초점을 가졌던 윈도는 입력 초점을 잃지 않는다. SetFocus함수는 WM_KILLFOCUS를 윈도에 보내 입력 초점을 잃게 하고 WM_SETFOCUS를 보내 입력 초점을 받아들이게 한다. 그 윈도나 부모 윈도를 활성화시킨다. 어떤 윈도도 초점을 가지고 있지 않았을 때 키가 눌러지면 WM_SYSCHAR, WM_SYSKEYDOWN, WM_SYSKEYUP 메시지를 발생한다.

2.       구문 : CWnd* SetFocus();

3.       파라미터 : 없음.

4.       리턴값 : 초점을 가진 윈도 객체에 대한 포인터. 이런 객체가 없으면 NULL을 리턴한다. 리턴된 포인터는 일시적이며 저장될 수 없다.

l        GetDesktopWindow

1.       설명 : 데스크탑 윈도에 대한 포인터를 얻는다. 데스크탑 윈도는 전체 윈도를 나타내는 바탕 화면이고, 그위에 모든 윈도가 그려진다. 이 포인터는 임시 적이고 나중 사용을 위하여 보관되지 않아야 한다.

2.       구문 : static CWnd* PASCAL GetDesktopWindow();

3.       파라미터 : 없음.

4.       리턴값 : 데스크탑 윈도에 대한 포인터.

l       ModifyStyle

1.  설명 : 특정 스타일 플래그를 추가하고 다른 특정 스타일 플래그를 제거하여 이 윈도와 관련된 윈도 스타일을 수정한다. 또한 nFlags가 0 이외의 값이면, ModifyStyle은 ::SetWindowPos 함수를 호출하여 다음의 네 가지, 미리 설정된 플래그와 조합하여 윈도를 다시 그린다.

SWP_NOSIZE 현재의 크기를 유지한다.

SWP_NOMOVE 현재의 위치를 유지한다.

SWP_NOZORDER 현재의 Z순서를 유지한다.

SWP_NOACTIVATE 윈도를 활성화 시키지 않게 한다.

2.       구문 : BOOL ModifyStyle( DWORD dwRemove, DWORD dwAdd, UINT nFlags = 0 );

3.       파라미터

dwRemove 윈도에서 제거되는 윈도 스타일 플래그의 조합.

dwAdd 윈도에서 추가되는 윈도 스타일 플래그의 조합.

NFlags SetWindowPos호출에 전달되는 SetWindowPos 플래그. 플래그 SWP_NOSIZE, SWP_NOMOVE, SWP_NOZORDER, SWP_NOACTIVATE는 ModifyStyle에 필요한 파라미터를 기술하는 어떤 방법도 없기 때문에 자동적으로 사용된다. 이 파라미터가 0이면 SetWindowPos는 호출되지 않는다.

             4.  리턴값 : 성공하면 비제로, 그렇지 않으면 0.

[ SetWindowPos의 nFlags 값 ]

SWP_DRAWFRAME

윈도우 주위에 윈도 클래스의 정의에 따라 프레임을 그린다.

SWP_FRAMECHANGED

윈도의 크기가 바뀌지 않더라도 윈도에 WM_NCCALCSIZE 메시지를 강제로 보내게 한다.

SWP_HIDEWINDOW

윈도를 숨긴다.

SWP_NOACTIVATE

윈도를 활성화 시키지 않는다.

SWP_NOCOPYBITS

클라이언트 영역의 내용을 복구 시키지 않는다.

SWP_NOMOVE

X와 Y값을 무시한다. 윈도의 크기는 변경만 가능하다.

SWP_NOOWNERZORDER

Z-order에서 소유자 윈도의 위치를 변경시키지 않는다.

SWP_NOREDRAW

윈도 이동이 있은 후에도 다시 그리는 일을 하지 않게 한다. 그릴 필요가 있는 부분은 응용프로그램이 분명히 무효화 시키고 다시 그려야 한다.

SWP_NOREPOSITION

SWP_NOOWNERZORDER 플래그와 같다.

SWP_NOSENDCHANGING

윈도가 WM_WINDOWPOSCHANGING 메시지를 받지 못하게 한다.

SWP_NOSIZE

cx와 cy 값을 무시한다. 윈도의 이동만 가능하다.

SWP_NOZORDER

hwndInsertAfter 값을 무시한다. 

SWP_SHOWWINDOW

윈도를 출력한다.

l       ModifyStyleEx

1.       설명 : 특정 스타일 플래그를 추가하고 다른 특정 스타일 플래그를 제거하여 이 윈도에 관련되는 윈도 스타일을 수정한다. 또한, ModifyStyleEx는 임으로 특정 플래그로 ::SetWindowPos 함수를 호출한다.

2.       구문 : BOOL ModifyStyleEx( DWORD dwRemove, DWORD dwAdd, UINT nFlags = 0 );

3.       파라미터

dwRemove 윈도에서 제거되는 윈도 확장 스타일 플래그의 조합.

dwAdd 윈도에 추가되는 윈도 확장 스타일 플래그의 조합.

nFlags SetWindowPos 호출에 전달되는 SetWindowPos 플래그. 플래그 SWP_NOSIZE, SWP_NOMOVE, SWP_NOZORDER, SWP_NOACTIVATE는 ModifyStyle에 필요한 파라미터를 기술하는 어떤 방법도 없기 때문에 자동적으로 사용된다. 이 파라미터가 0이면 SetWindowPos는 호출되지 않는다.

4.       리턴값 : 성공하면 비제로, 그렇지 않으면 0.

 

윈도의 크기와 위치

l       IsIconic

1.       설명 : CWnd가 최소화(아이콘화)되는지의 여부를 지정한다.

2.       구문 : BOOL IsIconic() const;

3.       파라미터 : 없음.

4.       리턴값 : CWnd가 최소화되었으면 비제로, 그 외의 경우에는 0이다.  

l       IsZoomed

1.       설명 : 윈도가 최대 화면인가 아닌가를 판단한다.

2.       구문 : BOOL IsZoomed() const;

3.       파라미터 : 없음.

4.       리턴값 : 윈도가 최대 화면이면 비제로, 그렇지 않으면 0.

l       MoveWindow

1.        설명 : 윈도가 특정 위치로 이동시키고 특정 크기로 조정한다. 이 함수로 윈도를 이동할 때 , 윈도는 윈도에 WM_GETMINMAXINFO 메시지를 보낸다. 이 메시지는 윈도의 크기와 위치를 제어할 기회를 윈도에 준다.

2.        구문 : void MoveWindow( int x, int y, int nWidth, int nHeight, BOOL bRepaint = TRUE );

  void MoveWindow( LPCRECT lpRect, BOOL bRepaint = TRUE );

             3.  파라미터

                    x 윈도의 왼쪽 상단의 새 x좌표. 이 윈도가 최상위 윈도이면, x는 스크린의 왼쪽 상단을 기준으로 한다. 이 윈도가 자식 윈도이면, x는 부모 윈도의 사용자 영역의 왼쪽 상단을 기준으로 한다.

y 윈도의 왼쪽 상단의 새 y좌표. 이 윈도가 최상위 윈도이면, y는 스크린의 왼쪽 상단을 기준으로 한다. 이 윈도가 자식 윈도이면, y는 부모 윈도의 사용자 영역의 왼쪽 상단을 기준으로 한다.  

nWidth 윈도의 새 폭.

nHeight- 윈도의 새 높이.

bRepaint 윈도가 다시 칠해져야 하면 TRUE, 그렇지 않으면 FALSE. 이 파라미터에 FALSE를 전달하면 어떤 다시 칠하는 것도 발생하지 않는다.

lpRect 윈도의 새 위치와 크기를 포함하는 RECT 구조체와 CRect 오브젝트에 대한 포인터. 

             4.  리턴값 : 아무 것도 리턴하지 않는다.

l       SetWindowPos

1.       설명 : 윈도의 크기, 위치, 자식 윈도의 Z 순서, 팝업, 상위 레벨을 변경하기 위해 함수를 호출한다. 윈도는 화면에 Z 순서에 따라 나열 되어 있다. 즉 Z 순서 맨 위에 있는 윈도는 화면 맨 위에 나타난다. 모든 자식 윈도의 좌표는 부모 윈도의 사용자 영역 좌측 상단과 연관 있는 사용자 좌표이다.

2.       구문 : BOOL SetWndowPos( const CWnd* pWndInsertAfter, int x, int y, int cx, int cy, UINT nFlags );

3.       파라미터

pWndInsertAfter 이 윈도가 Z 순서에 넣은 다음의 윈도. 또한, wndBottom, wndTop, wndTopMost, wndNoTopMost 상수중의 하나이다.

wndBottom

윈도를 Z 순서 끝에 놓는다. 이 CWnd가 맨 위 윈도이면 상위 상태 속성을 잃게 된다. 시스템이 다른 윈도 밑에 이 윈도를 놓기 때문이다.

wndTop

윈도를 Z 순서 맨 위에 놓는다.

wndTopMost

윈도를 맨 위에 놓는다. 비활성화되더라도 최상위 자리를 유지한다.

wndNoTopMost

윈도를 모든 맨 위 윈도가 아닌 윈도 최상 즉 모든 맨 위 윈도 아래 위치에 재 지정한다 이미 그 위치에 있으면 효과가 없다.

                 x 윈도의 왼쪽 상단의 새 x 좌표.

                 y 윈도의 왼쪽 상단의 새 y 좌표.

                 cx 윈도의 새로운 폭.

                 cy 윈도의 새로운 높이.

                 nFlags - [ SetWindowPos의 nFlags 값 ]의 조합.

             4.  리턴값 : 성공하면 비제로, 그렇지 않으면 0.

l       BringWindowToTop

1.       설명 : 윈도를 오버랩 윈도의 스택의 맨 위에 올려 놓는다. 윈도가 완전하게 보이게 하려면 이 함수를 사용하라. 이 함수는 윈도의 스타일을 항상 최상위로 만들지는 않는다. 윈도를 항상 최상위로 만들려면, CWnd::SetWindowPos 함수를 사용하라. 윈도가 팝업, 상위 수준이거나 MDI 자식 윈도이면 이 함수는 그 윈도를 활성화시킨다.

2.       구문 : public void BringWindowToTop();

3.       파라미터 : 없음.

4.       리턴값 : 아무 것도 리턴하지 않는다.

l       GetWindowRect

1.       설명 : 윈도의 사각형의 좌표를 얻는다. 좌표는 스크린 좌표이다.

2.       구문 : void GetWindowRect( LPRECT lpRect ) const;

3.       파라미터

lpRect 윈도 좌표로 채워지는 RECT 구조체나 CRect 오브젝트에 대한 포인터.

4.       리턴값 : 아무 것도 리턴하지 않는다.

l       GetClientRect

1.       설명 : 윈도의 사용자 영역을 정의하는 사각형을 얻는다. 사각형은 사용자 좌표로 표시되기 때문에 상대적이므로 외쪽 상단은 항상 (0, 0)이다.

2.       구문 : void GetClientRect( LPRECT lpRect ) const;

3.       파라미터

lpRect 윈도의 사용자 영역의 좌표로 채워지는 RECT 구조체나 CRect 오브젝트에 대한 포인터.

             4.  리턴값 : 아무 것도 리턴하지 않는다.

 

윈도 액세스 함수

l       ChildWindowFromPoint

1.         설명 : 주어진 위치를 갖는 자식 윈도를 알아낸다. 주어진 위치가 자식 윈도우 내에 있지않고, CWnd의 사용자 영역의 밖에 있으면, NULL이 리턴된다. 주어진 위치가 CWnd의 하나의 자식윈도 이상에 있을 경우는 발견한 첫번째 윈도가 리턴된다. 이 함수의 두번째 버전은 윈도 95에서 새롭게 제공되고 검색을 위하여 걸러내는 윈도의 타입을 기술할 수 있다. 보이지 않거나 사용할 수 없거나 투명한 윈도는 제거된다.

2.         구문 : public CWnd* ChildWindowFromPoint( POINT pt ) const;

public CWnd* ChildWindowFromPoint( POINT pt, UINT nFlags ) const;

             3.  파라미터

                 pt 판단할 자식 윈도에 대한 부모 윈도의 사용자 영역의 위치.

                 nFlags 건너뛸 자식 윈도를 지정한다. 다음의 값들의 조합으로 이루어질 수 있다.

CWP_ALL

어떠한 자식 윈도도 건너 뛰지 말라.

CWP_SKIPINVISIBLE

보이지 않는 자식 윈도를 건너 뛰어라.

CWP_SKIPDISABLED

기능이 억제된 자식 윈도를 건너 뛰어라.

CWP_SKIPTRANSPARENT

투명한 자식 윈도를 건너 뛰어라.

4.       리턴값 : 지정한 위치를 포함하는 자식 윈도를 나타내는 CWnd에 대한 포인터. 지정한 위치가CWnd의 사용자 영역 내에 있지 않으면, NULL이 리턴된다. 지정한 위치가 사용자 영역 내에 있지만 CWnd의 자식 윈도 내에 있지 않으면 CWnd 자체에 대한 포인터가 리턴된다.

l       FindWindow

1.        설명 : 지정한 클래스 이름과 윈도 이름을 갖는 톱 레벨 윈도를 찾는다. FindWindow는 자식 윈도를 찾지 못한다.

2.        구문 : static CWnd* PASCAL FindWindow( LPCTSTR lpszClassName, LPCTSTR lpszWindowName )

3.        파라미터

lpszClassName 원하는 윈도의 클래스 이름을 갖는 NULL로 끝나는 문자열 버퍼에 대한 포인터. 어느 클래스 이름이나 허용되면 NULL일 수 있다.

lpszWindowName 원하는 윈도의 윈도 이름을 갖는 NULL로 끝나는 문자열 버퍼에 대한 포인터. 어느 윈도우 이름이나 허용되면 NULL일 수 있다.

4.        리턴값 : 일치하는 CWnd 오브젝트에 대한 포인터, 또는 어느 것도 발견되지 않으면 NULL. 이 포인터는 나중에 사용하기 위하여 보관되지 않도록 임시적이어야 한다.

l       GetNextWindow

1.       설명 : 윈도 매니저 리스트에 있는 다음이나 이전 윈도에 대한 포인터를 얻는다. 윈도 메니저 리트스는 최상위 윈도들과 그들과 연관된 자식 윈도, 그리고 어떠한 자식 윈도의 자식윈도에 대한 앤트리들을 포함한다. 이 윈도가 최상위 윈도이면, 이 함수는 다음이나 이전 최상위 윈도를 찾는다. 이 윈도가 자식 윈도이면, 이 함수는 다음이나 이전 자식 윈도를 찾는다. 

2.       구문 : CWnd* GetNextWindow( UINT nFlag = GW_HWNDNEXT ) const;

3.       파라미터

nFlag 다음 윈도를 얻기 위해서는 GW_HWNDNEXT나 이전 윈도를 얻기 위해서는 GW_HWNDPREV.

4.       리턴값 : 멤버 함수가 동작에 성공하면 윈도 메니저의 리스트에 있는 다음의(또는 이전의) 윈도를

확인한다. 리턴된 포인터는 일시적일 수 있으며, 나중에 사용하려고 저장할 수 없다.

l       GetOwner

1.        설명 : 윈도의 소유자에 대한 포인터를 얻는다. 윈도가 소유자가 없다면, 부모 윈도 객체에 대한 포인터가 디폴트로 리턴된다. 소유자와 소유된 윈도 사이의 관계가 여러 가지 중요한 면에서 부모-자식 윈도의 관계와는 다르다는 것에 주의한다. 예를 들어, 부모를 지닌 윈도는 그것의 부모 윈도의 클라이언트 영역에 국한된다. 소유된 윈도는 데스크탑의 어떠한 위치에서도 이끌어 낼 수 있다.

2.        구문 : CWnd* GetOwner() const;

3.        파라미터 : 없음.

4.        리턴값 : 이 윈도의 오너 윈도에 대한 포인터. 이 포인터는 나중 사용을 위하여 보관되지 않아야 한다. 

l       SetOwner

1.       설명 : 이 윈도의 오너를 특정 윈도로 변경한다. 기본적으로, 윈도의 오너는 자신의 부모이다. 오너를 다른 윈도로 설정하는 것은 윈도에서 자신의 부모보다는 다른 윈도에 알림 코드가 전달되게 한다. 이 특징은 자식 윈도의 부모가 컨테이너 애플리케이션에 있지만 오너는 서브 애플리케이션에 뒤에 있는 MFC OLE 구현에서 많이 사용된다.

2.       구문 : void SetOnwer( CWnd* pOnwerWnd );

3.       파라미터

pOnwerWnd 윈도의 새로운 오너. 윈도가 어떤 오너도 갖지 않으면 NULL이다.

             4.  리턴값 : 아무 것도 리턴하지 않는다. 

l       GetParent

1.       설명 : 이 윈도의 부모 윈도를 얻는다.

2.       구문 : CWnd* GetParent() const;

3.       파라미터 : 없음.

4.       리턴값 : 이 윈도의 부모 윈도에 대한 포인터. 이 포인터는 나중 사용을 위하여 보관되지 않아야 한다. 이 함수는 CWnd 오브젝트가 윈도에 붙어 있지 않거나 윈도가 부모 윈도를 갖지 않으면 NULL를 리턴한다.

l       SetParent           

1.        설명 : 이 윈도의 부모를 특정 윈도로 변경한다. 이 자식 윈도가 보이면, 필요한 다시 그리기가 자동적으로 행해진다.

2.        구문 : CWnd* SetParent( CWnd* pWndNewParent );

3.        파라미터

pWndNewParent 새로운 부모 윈도에 대한 포인터.

4.        리턴값 : 이전 부모 윈도에 대한 포인터. 리턴 포인터는 임시적이고 나중 사용을 위하여 보관되지 않아야 한다.

l       GetTopWindow

1.       설명 : 이 윈도의 최상위 자식 윈도를 얻는다. 이 윈도가 어떤 자식 윈도도 갖지 않으면 NULL을 리턴한다.

2.       구문 : CWnd* GetTopWindow() const;

3.       파라미터 : 없음.

4.       리턴값 : 이 윈도의 최상위 자식 윈도에 대한 포인터. 이 포인터는 나중 사용을 위하여 보관되지 않도록 임시적이어야 한다.

 

l       GetWindow

1.       설명 : 이 윈도와 특정 관계를 갖는 윈도에 대한 포인터를 얻는다.

2.       구문 : CWnd* GetWindow( UINT nCmd ) const;

3.       파라미터

nCmd 이 윈도와 원하는 윈도 사이의 관계를 나타내는 상수. 다음 값 중의 하나이다.

GW_CHILD

윈도의 첫번째 자식 윈도를 얻는다.

GW_HWNDFIRST

이 윈도가 자식 윈도이면, 부모가 같은 첫번째 윈도를 얻고 그렇지 않으면 첫번째 최상위 윈도를 얻는다.

GW_HWNDLAST

이 윈도가 자식 윈도이면, 부모가 같은 마지막 윈도를 얻고 그렇지 않으면 마지막 최상위 윈도를 얻는다.

GW_HWNDNEXT

윈도 관리자 리스트에 있는 다음 윈도를 얻는다.

GW_HWNDPREV

윈도 관리자 리스트에 있는 이전 윈도를 얻는다.

GW_OWNER

윈도의 오너를 얻는다.

             4.  리턴값 : 요청한 윈도에 대한 포인터.

l       GetLastActivePopup

1.       설명 : CWnd에 의해 소유된 팝업 윈도 중 가장 최근 활성화된 팝업 윈도를 결정한다. 

2.       구문 : CWnd* GetLastActivePopup() const;

3.       파라미터 : 없음.

4.       리턴값 : 가장 최근에 활성화된 팝업 윈도에 대한 포인터. 리턴값은 다음의 내용 중 일치하는 것이 있으면 윈도 그 자체가 된다.

¨ 윈도 자체가 가장 최근에 활성화 되었다. 

¨ 윈도는 어떠한 팝업 윈도들을 가지고 있지 않다.

¨ 윈도는 최상위 윈도가 아니거나 다른 윈도에 의해 소유된다.

                 이 포인터는 나중 사용을 위하여 보관되지 않아야 한다. 

l       IsChild

1.       설명 : 특정 윈도가 자식 윈도인지 이 윈도의 후손 윈도인가를 판단한다.

2.       구문 : BOOL IsChild( const CWnd* pWnd ) const;

3.       파라미터

pWnd 검사할 윈도에 대할 포인터.

             4.  리턴값 : 윈도가 이 윈도의 자식 윈도이거나 후손이면 비제로, 그렇지 않으면 0.

l       GetDlgItem

1.        설명 : 다이얼로그 박스 또는 다른 윈도에 있는 특정한 컨트롤이나 자식 윈도에 대한 포인터를 검색한다. 리턴된 포인터는 일상적으로 nID에 의해 식별된 컨트롤의 타입에 속하게 된다.

2.        구문 : CWnd* GetDlgItem( int nID ) const;

  void CWnd::GetDlgItem( int nID, HWND* phWnd ) const;

             3.  파라미터

                 nID 얻을 자식 윈도 ID.

                 phWnd 지정 자식 윈도 핸들로 채워지는 HWND에 대한 포인터.

4.        리턴값 : 첫번째 형식의 함수는 지정 자식 윈도에 대한 포인터를 리턴하거나  자식윈도가 존재하지 않으면 NULL.

l       GetDlgCtrlID

1.        설명 : 윈도나 어떠한 자식 윈도의 컨트롤 ID값 또는, 다이얼로그 박스에서 컨트롤의 ID 값들을 리턴한다. 최상위 윈도들이 ID 값을 갖지 않으므로, 이 함수의 리턴 값은 CWnd가 최상위 윈도라면 유효하지 않다.

2.        구문 : int GetDlgCtrlID() const;

3.        파라미터 : 없음.

4.        리턴값 : 자식 윈도 ID.

l       SetDlgCtrlID

1.       설명 : 윈도 ID나 컨트롤 ID에 새로운 값을 설정한다. 이 윈도는 다이얼로그 박스에 있는 컨트롤이나 자식 윈도는 가능하지만 상위 레벨 윈도는 가능하지 않다.

2.       구문 : int SetDlgCtrlID( int nID );

3.       파라미터

nID 컨트롤, 자식윈도 새로운 ID.

4.       리턴값 : 컨트롤, 자식윈도 이전 ID.

l       GetParentFrame

1.       설명 : 이 윈도의 부모 프레임에 대한 포인터를 얻는다. 이 윈도에 대한 어떤 부모 프레임 윈도가 아니면, GetParentFrame은 NULL을 리턴한다.

2.       구문 : CWnd* GetParentFrame() const;

3.       파라미터 : 없음.

4.       리턴값 : 부모 프레임 윈도에 대한 포인터. 이 포인터는 나중에 사용을 위하여 보관되지 않아야 한다.

l       UpdateData

1.       설명 : 다이얼로그 데이터 교환과 확인을 한다. 이 함수는 몇 가지 초기화 작업을 수행하고 실제 데이터 교환과 확인을 수행하기 위하여 CWnd의 CWnd::DoDataExchange 멤버를 호출한다. 보통 MFC는 CDialog::OnInitDialog함수에서 다이얼로그 컨트롤을 초기화하고 CDialog::OnOK의 기본 구현에서 다이얼로그로부터 데이터를 얻기 위하여 이 함수를 자동으로 호출한다.

2.       구문 : BOOL UpdateData( BOOL bSaveAndValidate = TRUE );

3.       파라미터

bSaveAndValidate TRUE는 데이터가 윈도에서 얻어지고 임의로 확인되어야 한다는 것을 나타내고, FALSE는 데이터가 윈도에 보내야 한다는 것을 나타낸다.

             4.  리턴값 : 성공하면 비제로, 그렇지 않으면 0.

l       BeginPaint

1.         설명 : 칠하기 위하여 윈도를 준비하고 칠하기 위한 디바이스 컨텍스트를 생성하고 리턴한다. PAINTSTRUCT 구조체에 칠하는 정보를 체운다. 전형적으로 WM_PAINT 메시지에 응답하기 위해서만 이 함수를 호출한다. 이 함수를 호출하면 칠하기를 끝냈을 때에 반드시 CWnd::EndPaint를 호출하여야 한다. 보통 MFC CPaintDC 클래스는 윈도 칠하기를 캡슐화했기 때문에 이 함수를 호출할 필요는 없다. 윈도 갱신 영역이 지워지기 위하여 마크되면 BeginPaint는 윈도에 WM_ERASEBKGND 메시지를 보낸다. 칠해지는 영역에 카렛을 포함하고 있으면 BeginPaint는 자동적으로 칠하여 카렛이 지위지지 않도록 숨긴다.

2.         구문 : public CDC* BeginPaint( LPPAINTSTRUCT lpPaint );

3.         파라미터

lpPaint PAINTSTRUCT에 대한 구조체.

             4.  리턴값 : 칠하는 데 사용되는 CDC 오브젝트에 대한 포인터.

l       EndPaint

1.        설명 : WM_PAINT 메시지에 응답하여( CWnd::OnPaint 메시지 핸들러 ) 칠하려고 하는 윈도를 칠하였을 때 이 함수를 호출한다. 이 함수는 CWnd::BeginPaint 함수의 호출로 할당된 디바이스 컨텍스트를 해제한다. 종종 자신의 생성자와 소멸자 내에서 BeginPaint와 EndPaint를 호출을 캡슐화하는 CPaintDC를 사용하는 것이 더 쉽다.

2.        구문 : void EndPaint( LPPAINTSTRUCT lpPaint );

3.        파라미터

lpPaint CWnd::BeginPaint 호출에 응답으로 제공되는 PAINTSTRUCT 구조체에 대한 포인터.

4.        리턴값 : 아무 것도 리터하지 않는다.

l       GetDC

1.       설명 : 윈도의 사용자 영역에 대한 디바이스 컨텍스트를 얻는다. 보통 리턴된 디바이스 컨텍스트는 일반 디바이스 컨텍스트이다. 그러나 윈도우 클래스에 사용되는 스타일 플래그에 따라 개인 또는 클래스 디바이스 컨텍스트가 리턴된다. CS_OWNDC, CS_PARENTDC와 CS_CLASSDC 플래그는 기능을 제어한다. 디바이스가 컨텍스트가 윈도 클래스에 속하지 않으면, ReleaseDC 멤버 함수는 반드시 색칠이 끝난 후에 상황을 풀기 위해 호출되어야 한다. 시스템은 전체 5개의 일반 디바이스 컨텍스트로 제한하기 때문에 16비트 윈도(그리고 Win32s)에서 ReleaseDC를 사용하는 것은 아주 중요하다.

2.       구문 : CDC* GetDC();

3.       파라미터 : 없음.

4.       리턴값 : 디바이스 컨텍스트에 대한 포인터. 이 포인터는 임시적이고 나중 사용을 위하여 보관 되지 않아야 한다. 

l       GetWindowDC

1.       설명 : 캡션 바, 메뉴들, 그리고 스크롤 바들을 포함하는 전체 윈도에 대한 디스플레이 내용을 얻는다. 클라이언트 영역을 대신하여 내용의 원점이 CWnd의 왼쪽상단 구석이므로, 윈도 디스플레이 내용은 CWnd의 어느 곳에서나 색칠하기를 허용한다. 디포트 속성은 그것이 내용을 얻을 때마다. 디스플레이 내용에 할당된다. 이전의 속성은 잃어버린다. GetWindowDC는 CWnd 비클라이언트 영역 안의 특별한 색칠 효과에 사용되는 의도가 있다. 어떤 윈도의 비클라이언트 영역의 색칠은 추천되지 않는다. GetSystemMetrics Windows 함수는 캡션 바나, 메뉴, 그리고 스크롤 바와 같은 비클라이언트 영역의 다양한 부분들의 치수들을 얻기 위해 사용될 수 있다. 색칠이 완료된 후, ReleaseDC 멤버 함수는 반드시 디스플레이 내용을 해제하기 위해 호출되어야 한다. 디스플레이 내용의 해제에 실패하면 동시에 오픈될 수 있는 디바이스 내용의 수에 제한이 있어서 애플리케이션에 의해 요청된 색칠에 심각한 영향을 미친다.

2.       구문 : CDC* GetWindowDC();

3.       파라미터 : 없음.

4.       리턴값 : 전체 윈도 영역에 대한 디바이스 컨텍스트에 대한 포인터. 이 포인터는 임시적이고 나중 사용을 위하여 보관 되지 않아야 한다. 

 

l       ReleaseDC

1.       설명 : CWnd::GetDC나 CWnd::GetDCEx 함수를 사용하여 얻어지는 디바이스 컨텍스트를 해제한다.

2.       구문 : int ReleaseDC( CDC* pDC );

3.       파라미터

pDC 해제되는 디바이스 컨텍스트에 대한 포인터.

             4.  리턴값 : 성공하면 비제로, 그렇지 않으면 0.

l       Invalidate

1.       설명 : 윈도의 전 클라이언트 영역을 무효화한다. 이 함수를 호출하는 것은 MULL 사각형 포인터로 CWnd::InvalidateRect를 호출하는 것과 동일하다. 윈도의 무효화 영역은 현재 갱신 영역에 모인다. 갱신 영역은 윈도가 WM_PAINT 메시지를 보내는 다음 번에 칠하는 윈도의 영역이다. 윈도는 갱신 영역이 비어있지 않고 애플리케이션에 대해 대기한 그 이상의 메시지가 없을 때에만 윈도에 칠하기 명령을 보낸다.

2.       구문 : void Invalidate( BOOL bErase = TRUE );

3.       파라미터

bErase 칠하기 전에 갱신 영역은 지워야 한다면 TRUE. 갱신 영역의 어떤 부분을 지우기 마크되면 전체 갱신 영역이 지워진다. 영역은 윈도에 WM_ERASEBKGND 메시지를 보내 지워진다.

4.       리턴값 : 아무 것도 리턴하지 않는다.

l       InvalidateRect

1.       설명 : 특정 사각형을 무효화로 만든다. 윈도의 무효화 영역은 현재 갱신 영역에 쌓인다. 갱신 영역은 윈도가 윈도에 WM_PAINT 메시지를 보내는 다음 번에 칠하는 윈도의 영역이다. 윈도는 갱신 영역이 비어 있지 않고, 애플리케이션에 대해 대기한 그 이상의 메시지가 없을 때에만 윈도에 칠하는 명령을 보낸다. CWnd::ValidateRgn이나 CWnd::ValidateRect 함수를 호출하여 갱신 영역의 일 부분을 제거할 수 있다.

2.       구문 : void InvalidateRect( LPCRECT lpRect, BOOL bErase = TRUE );

3.       파라미터

lpRect 사용자 좌표로 무효화되는 사각형을 갖는 RECT 구조체나 CRect 오브젝트에 대한 포인터. NULL이면, 윈도는 윈도의 전체 사용자 영역을 무효화한다.

BErase 칠하기 전에 갱신 영역을 지워야 한다면 TRUE. 갱신 영역의 어떤 부분을 지우기 위해 마크되면 전체 갱신 영역이 지워진다. 영역은 윈도에 WM_ERASEBKGND 메시지를 보내 지운다.

             4.  리턴값 : 아무 것도 리턴하지 않는다.

l       ShowWindow

1.       설명 : 윈도의 보이기,숨기와 상태를 제어한다.

2.       구문 : BOOL ShowWindow( int nCmdShow );

3.       파라미터

nCmdShow 다음 플래그의 하나이다.

SW_HIDE

이 윈도를 숨기도 다른 윈도로 활성화를 전달한다.

SW_MINMIZE

윈도를 최소화하고 관리자 리스트에 있는 최상위 윈도를 활성화한다.

SW_RESTORE

윈도를 활성화 하고 표시한다. 윈도가 최대,최소화되어 있으면 원래 크기와 위치로 복원한다.

SW_SHOW

윈도를 현재 크기, 위치로 활성화 하고 디스플레이한다.

SW_SHOWMAXIMIZED

윈도를 활성화하고 최대 크기로 디스플레이한다.

SW_SHOWMINIMIZED

윈도를 활성화하고 아이콘으로 디스플레이한다.

SW_SHOWMINNOACTIVE

윈도를 아이콘으로 디스플레이하고 현재 활성화된 윈도는 활성화 상태로 있다. 즉 다른 윈도를 활성화하지 않는다.

SW_SHOWNA

윈도를 현 상태로 디스플레이하고 현재 활성화된 윈도는 활성화 상태로 있다.

SW_SHOWNOACTIVATE

윈도를 가장 최근의 크기와 위치로 디스플레이한다. 현재 활성화된 윈도가 활성화 상태로 있다.

SW_SHOWNOMAL

윈도를 활성화하고 디스플레이한다. 윈도가 최대, 최소화된 상태이면 원래 크기, 위치로 복원된다.

             4.  리턴값 : 윈도가 이미 나타나 있으면 비제로, 그렇지 않으면 0.

l       IsWindowVisible

1.       설명 : 윈도가 보이는지 보이지 않는지를 판단한다. 이 함수는 WS_VISIBLE 스타일이 윈도에 설정되어 있고 부모 윈도도 보이면 TRUE. IsWindowVisible은 실제로 윈도가 표시 화면에 보이는지를 판단하지는 않는다. ( 다른 윈도에 의해 숨겨질 수도 있다. )

2.       구문 : BOOL IsWindowVisible() const;

3.       파라미터 : 없음.

4.       리턴값 : 윈도가 보이면 비제로, 그렇지 않으면 0.

 

좌표 맵핑 함수

l       ClientToScreen

1.        설명 : 주어진 포인트나 스크린 좌표에 표시되는 사각형의 클라이언트 좌표를 스크린 좌표로 전환한다. 클라이언트 좌표는 CWnd의 클라이언트 영역의 왼쪽 상단을 기준으로 한다. 스크린 좌표는 화면 스크린의 왼쪽 상단을 기준으로 한다.

2.        구문 : public void ClientToScreen( LPPOINT lpPoint ) const; 

public void ClientToScreen( LPRECT lpRect ) const;

             3.  파라미터

                    lpPoint 클라이언트 좌표로 된 위치를 갖는 POINT 구조체나 CPoint 오브젝트에 대한 포인터. 이 위치 좌표의 내용은 계산된 스크린 좌표로 교체된다.

lpRect 클라이언트 좌표로 된 위치를 갖는 RECT 구조체나 CRect 오브젝트에 대한 포인터. 이 사각 좌표의 내용은 계산된 스크린 좌표로 교체된다.

             4.  리턴값 : 아무 것도 리턴하지 않는다.

l       ScreenToClient

1.       설명 : 윈도에 대한 스크린 좌표를 클라이언트 자표로 변환한다. 스크린 좌표는 스크린의 왼쪽 상단을 기준으로 한다. 클라이언트 좌표는 클라이언트 영역의 왼쪽 상단을 기준으로 한다.

2.       구문 : void ScreenToClient( LPPOINT lpPoint ) const;

void ScreenToClient( LPRECT lpRect ) const;

            

3.  파라미터

                 lpPoint 변환할 위치를 포함하는 POINT 구조체나 CPoint 오브젝트에 대한 포인터.

                 lpRect 변환할 위치를 포함하는 RECT 구조체나 CRect 오브젝트에 대한 포인터.

             4.  리턴값 : 아무 것도 리턴하지 않는다.

 

윈도 텍스트 함수

l       SetWindowText

1.       설명 : 지정된 텍스트로 윈도 타이틀을 정한다. 윈도가 컨트롤이면 컨트롤 안의 텍스트가 설정된다. 이 함수는 WM_SETTEXT 메시지를 그 윈도에 전한다.

2.       구문 : void SetWindowText( LPCTSTR lpszString );

3.       파라미터

lpszString 새로운 윈도 텍스트로 사용되는 널로 끝나는 문자열에 대한 포인터.

             4.  리턴값 : 아무 것도 리턴하지 않는다.

l       GetWindowText

1.       설명 : 현재 윈도 캡션의 텍스트를 얻는다. 편집박스에서 캡션 텍스트는 편집 컨트롤 자체에 있는 텍스트이다.

2.       구문 : int GetWindowText( LPTSTR lpszStringBuf, int nMaxCount ) const;

void GetWindowText( CString& rString ) const;

             3.  파라미터

                 lpszStringBuf 널로 끝나는 윈도에 있는 문자 버퍼에 대한 포인터.

                 nMaxCount lpszStringBuf에 의해 가리키는 버퍼의 크기.

                 rString 윈도 텍스트로 체워지는 CString에 대한 참조.

4.  리턴값 : 첫번째 형식의 함수는 제공되는 버퍼에 실제 복사되는 문자들의 수이다. 두번째 형식의 함수는 아무 것도 리턴하지 않는다.  

l       GetWindowTextLength

1.       설명 : 현재 윈도 캡션의 길이를 얻는다. 윈도 캡션 텍스트를 담는 데 필요한 버퍼의 크기를 판단하기 위하여 문자 버퍼 포인터의 파라미터를 받는 GetWindowText 함수의 형식을 호출하기 전에 이 함수를 호출하라.

2.       구문 : int GetWindowTextLength() const;

3.       파라미터 : 없음.

4.       리턴값 : 현재 윈도 캡션에 있는 문자의 수.

l       SetFont

1.       설명 : 윈도의 현재 글꼴을 다른 글꼴로 변경한다.

2.       구문 : void SetFont( CFont* pFont, BOOL bRedraw = TRUE );

3.       파라미터

pFont 새로운 폰트를 지정한다.

bRedraw -  TRUE이면 윈도를 다시 그린다.

l       GetFont

1.       설명 : 윈도의 현재 글꼴에 대한 포인터를 리턴한다.

2.       구문 : CFont* GetFont() const;

3.       파라미터 : 없음.

4.       리턴값 : 윈도에 의해 사용되는 글꼴에 대한 포인터. 이것은 임시적이고 나중 사용을 위하여 보관되지 않아야 한다.

드래그-드롭 함수

l       DragAcceptFiles

1.       설명 : 윈도가 파일관리자에서 드래그되는 파일을 받는가를 나타내기 위하여 이 함수를 호출한다. 받는 것이 가능하면, 윈도는 WM_DROPFILE 메시지를 받는다. 보통 자신의 애플리케이션의 맨 처음 애플리케이션의 메인 윈도에서 이 함수를 호출한다.

2.       구문 : void DragAcceptFiles( BOOL bAccept = TRUE );

3.       파라미터

bAccept 윈도가 드래그 파일을 받으면 TRUE, 그렇지 않으면 FALSE.

4.       리턴값 : 아무 것도 리턴하지 않는다.

 

다이얼로그 박스 아이템 함수

l       DlgDirList

1.       설명 : 파일이나 디렉토리 리스팅을 지닌 리스트 박스를 채운다. DlgDirList는           LB_RESETCONTENT와 LB_DIR 메시지를 리스트 박스에 전한다. 주어진 경로와 일치하는 모든 파일들의 이름을 갖고 nIDListBox에 의해 지정된 리스트 박스를 채운다. 

2.       구문 : public int DlgDirList( LPTSTR lpPathSpec, int nIDListBox, int nIDStaticPath, UINT nFileType );

3.  파라미터

lpPathSpec 경로나 파일 이름을 함유하고 있는 널 종결 스트링을 가리킨다. DlgDirList는 수정을 충분히 함유할 정도로 긴 이 스트링을 수정한다. 더 많은 정보는 다음의 설명 부분을 참조한다.

nIDListBox 리스트 박스의 식별자를 지정한다. 만일 nIDListBox가 0이면, DlgDirList는 리스트 박스가 존재하지 않으며 하나의 박스도 채우려하지 않음을 나타낸다.

nIDStaticPath 현재의 드라이브와 디렉토리를 나타내는데에 사용되는 정적 텍스트 컨트롤의 식별자를 지정한다. 만일 nIDStaticPath가 0이면, DlgDirList는 그와 같은 텍스트 컨트롤이 존재하지 않음을 나타낸다.

nFileType 나타날 파일들의 속성들을 지정한다. 다음의 값들의 조합으로 나타날 수 있다.

DDL_READWRITE

부가적인 속성없이 데이터 파일을 읽고 쓴다.

DDL_READONLY

읽기 전용 파일들.

DDL_HIDDEN

히든 파일들.

DDL_SYSTEM

시스템 파일들.

DDL_DIRECTORY

디렉토리들.

DDL_ARCHIVE

아카이브

DDL_POSTMSGS

LB_DIR 플래그. 만일 LB_DIR 플래그가 설정되면, Windows는 애플리케이션 큐에 있는 DlgDirList에 발생된 메시지를 넣는다. 그렇지 않으면 다이얼로그박스 프로시저에 직접 전달한다.

DDL_DRIVES

드라이브. DDL_DRIVES 플래그가 설정되면 DDL_EXCLUSIVE 플래그가 자동으로 설정되기 때문에 드라이브와 파일을 갖는 디렉토리 리스트를 생성하기 위하여 DlgDirList를 두 번 호출해야 한다. 한 번은 DDL_DRIVES 플래그를 설정하여 호출한다.

DDL_EXCLUSIVE

Exclusive 비트. Exclusive 비트가 설정되면, 지정 타입의 파일만이 리스트되고, 그렇지 않으면 일반 파일과 지정 타입의 파일들만이 리스트된다.

             4.  리턴값 : 성공하면 비제로, 그렇지 않으면 0.

l       DlgDirListComboBox

1.       설명 : 주어진 경로와 파일 스펙과 주어진 위치와 주어진 타입과 일치하는 파일의 리스트를 지정 콤보박스에 채운다.

2.       구문 : public int DlgDirListComboBox( LPTSTR lpPathSpec, int nIDComboBox, int nIDStaticPath, UINT nFileType );

3.       파라미터

lpPathSpec 리스트되는 파일에 대한 디렉토리와 파일 스펙을 갖는 널로 끝나는 문자열 버퍼를 가리킨다. 이 파라미터가 가리키는 문자열이 파일 스펙을 갖지 않으면, *.*이 된다. 이 함수가 실행되면, 지정 문자열의 드라이브와 경로는 제거된다.

nIDComboBox 파일이 리스트되는 콤보박스의 리소스 ID. 이 파라미터가 0이면, DlgDirListComboBox는 어떤 콤보박스도 파일 문자열로 채워지지 않는다.

nIDStaticPath 현재 드라이브와 디렉토리로 설정되는 스태틱 컨트롤의 리소스 ID. 이 파라미터가 0이면, DlgDirListComboBox는 어떤 컨트롤도 이 정보를 갖지 않는다.

nFileType 리스트 되는 파일의 타입을 나타내는 플래그. DlgDirList와 동일.

4.       리턴값 : 성공하면 비제로, 그렇지 않으면 0.

l       GetDlgItemText

1.       설명 : 다이얼로그 박스에 있는 컨트롤에 연관된 타이틀이나 텍스트를 얻기 위해 이 멤버 함수를 호출한다. GetDlgItemText 멤버 함수는 lpStr에 의해 지정된 위치에 텍스트를 복사하며 복사한 텍스트의 바이트 수의 크기를 리턴한다.

2.       구문 : int GetDlgItemText( int nID, LPTSTR lpStr, int nMaxCount ) const;

int GetDlgItemText( int nID, CString& rString ) const;

3.       파라미터

nID 타이틀이 검색될 컨트롤에 대한 정수 식별자를 지정한다.

lpStr 컨트롤의 타이틀과 텍스트를 받는 버퍼를 가리킨다.

nMaxCount lpStr에 복사될 스트링의 최대 길이(바이트)를 지정한다. 스트링이 nMaxCount보다 길다면, 짤리게 된다.

rString CString에 대한 참조이다.

4.  리턴값 : 널 문자의 종결을 포함하지 않은채, 버퍼에 복사된 바이트의 실제 수를 확인한다. 텍스트가 복사되지 않는다면, 0이다.

l       SendDlgItemMessage

1.       설명 : 컨트롤에 메시지를 보낸다. SendDlgItemMessage는 멤버 함수는 메시지가 처리될 때까지 리턴되지 않는다. SendDlgItemMessage를 이용하는 것은 주어진 컨트롤에 대해 CWnd*를 얻고 SendMessage 멤버 함수를 호출하는 것과 동일하다.

2.       구문 : LRESULT SendDlgItemMessage( int nID, UINT message, WPARAM wParam=0, LPARAM lParam=0 );

3.       파라미터

nID 메시지를 받을 다이얼로그 박스 컨트롤의 식별자를 지정한다.

Message 보내진 메시지를 지정한다.

WParam 부가적인 메시지 종속 정보를 지정한다.

LParam 부가적인 메시지 종속 정보를 지정한다.

4.  리턴값 : 컨트롤의 윈도 프로시저에 의해 리턴된 값을 지정한다. 또는 만일 컨트롤이 찾지 못하면 0이다.

 

메뉴 함수

l       GetMenu

1.       설명 : 이 윈도와 관련된 메뉴에 대한 포인터를 얻는다. 자식 윈도는 메뉴를 갖고 있지 않기 때문에, 자식 윈도에 대해 이 함수를 호출하지 않아야 한다.

2.       구문 : CMenu* GetMenu() const;

3.       파라미터 : 없음.

4.       리턴값 : 메뉴를 확인한다. CWnd가 메뉴를 갖지 않는다면 NULL이다. CWnd가 자식 윈도이면 리턴 값은 정의되지 않는다.

l       SetMenu

1.        설명 : 현재 매뉴를 다른 매뉴로 변경한다. 변경된 메뉴를 반영하기 위해 윈도가 다시 그려져야 한다. SetMenu는 이전 메뉴를 없애지 않는다. CMenu::DestroyMenu 함수를 호출하여 이전 메뉴를 없애야 한다.

2.        구문 : BOOL SetMenu( CMenu* pMenu );

3.        파라미터

pMenu 새로운 메뉴를 나타낸다. NULL이면 현재 메뉴가 없어진다.

             4.  리턴값 : 성공하면 비제로, 그렇지 않으면 0.

 

타이머 함수

l       SetTimer

1.        설명 : 시스템 타이머를 설치한다. 설정된 시간 간격마다 시스템은 WM_TIMER를 애플리케이션 메시지 큐나 TimerProc 콜백 함수에 보낸다. 타이머는 한정된 전역 자윈이다. 그러므로 프로그램은 타이머가 실제로 사용할 수 있는 것인지 확인하기 위해 SetTimer의 리턴 값을 검사하는 것이 중요하다.

2.        구문 : UINT SetTimer( UINT nIDEvent, UINT nElapse, void (CALLBACK EXPORT* lpfnTimer)(HWND, UINT, UINT, DWORD );

 

3.  파라미터

                 nIDEvent 0이 아닌 타이머 ID를 지정한다.

                 nElapse 시간 간격(millisecond 단위)을 지정한다.

       lpfnTimer WM_TIMER를 처리하는 TimerProc 콜백(callback) 함수의 주소. NULL이면 WM_TIMER는 에플리케이션의 메시지 큐에 들어가도 CWnd에 의해 처리된다. lpfnTimer 콜백 함수는 TimerProc로 명명할 필요는 없으나 다음과 같이 정의되고 0을 리턴해야 한다.

       Void CALLBACK EXPORT TimerProc(

             HWND hWnd,                                 //handle of CWnd that called SetTimer

             UINT nMsg,                                   //WM_TIMER

             UINT nIDEvent,                              //timer identification

             DWORD dwTime               //system time

       );

4.  리턴값 : 새로운 타이머의 ID를 리턴한다. 타이머를 없애기 위해 KillTimer 함수에 이 값을 넘긴다. 성공이면 비제로, 그렇지 않으면 0.

 

경고 함수

l       FlashWindow

1.       설명 : 주어진 윈도를 한번 플래쉬하게 한다. 연속적인 플래쉬를 위해서는 시스템 타이머를 생성하고 반복적으로 FlashWindow를 호출한다. CWnd를 호출하는 것은 마치 CWnd가 비활성에서 활성으로의 변환을 의미하거나, 또는 그 역을 행하는 것처럼 윈도의 타이틀 바의 외형을 변화시키는 것을 의미한다.(비활성 타이틀 바는 활성화된 타이틀 바로 변화된다. 활성화된 타이틀 바는 비활성화된 바로 변환된다.) 전형적으로 윈도는 주의를 요구하거나 현재 입력 초점을 지니고 있지 않는 사용자에게 정보를 알려주기 위해 플래쉬하게 된다. 파라미터 bInvert는 윈도가 입력 초점을 취하거나 더 이상 플래쉬하지 않을 때에만 FALSE가 되어야 한다. 입력 초점을 취하기 위해 기다리는 동안 연속적인 호출하는 것에는 TRUE이어야 한다. 이 함수는 항상 최소화된 윈도들에 대해 0 이외의 값을 리턴한다. 윈도가 최소화되면, FlashWindow는 간단히 윈도의 아이콘을 플래쉬시킨다. bInvert는 최소화된 윈도들에 대해 무시한다.

2.       구문 : BOOL FlashWindow( BOOL bInvert );

3.       파라미터

bInvert CWnd가 플래쉬되었거나 윈래의 상태로 리턴했는지를 지정한다. CWnd는 bInvert가 TRUE이면 한 상태에서 다른 상태로 플래쉬한다. 만일 bInvert가 FALSE이면 윈도는 원래의 상태를(활성화에 관계없이) 리턴한다.

4.  리턴값 : FlashWindow 멤버 함수를 호출하기 전에 윈도가 활성화되었다면 비제로, 그 외의 경우에는 0이다.

l       MessageBox

1.       설명 : 애플리케이션 제공된 메시지와 캡션을 포함하는 윈도를 생성하고 디스플레이하며, 이미 정의된 아이콘들과 Message-Box Style 리스트에서 기술한 푸시 버튼의 조합을 추가할 수 있다. 메시지 박스 스타일의 리스트를 위해, Style 절에 있는 Message-Box Style을 참조한다. 애플리케이션에 메시지를 처리하기 위해 이 멤버 함수를 대신하여 전역 함수인 AfxMessageBox를 이용한다.

2.       구문 : int MessageBox( LPCTSTR lpszText, LPCTSTR lpszCaption = NULL, UINT nType = MB_OK );

3.       파라미터

lpszText 디스플레이될 메시지를 포함하는 CString 객체나 널 종결 스트링을 가리킨다.

lpszCaption 메시지 박스 캡션에 이용될 메시지를 포함하는 CString 객체나 널 종결 스트링을 가리킨다. 만일 lpszCaption이 NULL이면, 디폴트 캡션 Error가 이용된다.

nType 메시지 박스의 내용과 거동을 지정한다.

             4.  리턴값 : 함수의 결과를 지정한다. 메시지 박스를 생성할 만큼 충분한 메모리가 없다면 0이다.

 

윈도 메시지 함수

l       GetCurrentMessage

1.       설명 : 현재 처리되는 메시지에 대한 포인터를 얻는다. 보내는 정확한 메시지를 판단하기 위해서 메시지에 응답할 때 이 함수를 호출할 수 있다.

2.       구문 : static const MSG* PASCAL GetCurrentMessage();

3.       파라미터 : 없음.

4.       리턴값 : 현재 메지시를 정의하는 MSG 구조체에 대한 포인터. 

l       PreTranslateMessage

1.  설명 : TranslateMessage(virtual-key messages를 character messages로 변환하는 함수)와 DispatchMessage(The DispatchMessage function dispatches a message to a window procedure. It is typically used to dispatch a message retrieved by the GetMessage function.)

    Windows 함수로 그들이 디스패치하기 전에 윈도 메시지를 번역하기 위해 클래스 CWinApp에 의해 이용된다. 툴팁 메시지를 거르고 전달하기 위해 MFC에 의해 호출된다.

2.  구문 : virtual BOOL PreTranslateMessage( MSG* pMsg );

3.        파라미터

pMsg 처리할 메시지를 포함하는 MSG 구조체를 가리킨다.

             4.  리턴값 : 만일 메시지가 번역되고 디스패치가 안된다면 TRUE, 그렇지 않으면 FALSE.

l       SendMessage

1.       설명 : 윈도에 메시지를 보낸다. 보내지는 메시지는 즉시 전달되기 때문에 포스트되는 메시지와는 다르다. SendMessage는 그 메시지가 처리될 때까지 리턴하지 않는다. 메시지를 윈도의 메시지 큐에 보낸 후 이 값을 즉시 리턴한다.

2.       구문 : LRESULT SendMessage( UINT message, WPARAM wParam=0, LPARAM lParam=0 );

3.       파라미터

message 전송할 메시지를 나타낸다.

wParam 부가적인 메시지에 의존하는 정보를 나타낸다.

lParam 부가적인 메시지에 의존하는 정보를 나타낸다.

4.  리턴값 : 처리되는 메시지의 결과이다. 그것의 값은 보내진 메시지에 의존하므로 메시지에 따라 리턴값이 다르다.

l       PostMessage

1.       설명 : 애플리케이션의 메시지 큐에 메시지를 포스트한다. 메시지를 포스트하는 것은 메시지를 보내는 것과는 다르다. 메시지를 보내면 즉시 받게 된다. 메시지가 포스트될 때, 큐에 이미 있는 다른 메시지들의 뒤에 넣어지고 나중 어느 시점에서 애플리케이션에서 받게 된다. PostMessage는 메시지가 처리되는 것을 기다리지 않는다. 메시지 큐의 메시지는 GetMessage나 PeekMessage Windows 함수에 대해 호출함으로써 검색된다. Windows PostMessage 함수는 다른 애플리케이션에 액세스하는데 이용될 수 있다.

2.       구문 : BOOL PostMessage( UINT message, WPARAM wParam=0, LPARAM lParam=0 );

3.       파라미터

message 포스트되는 메시지.

wParam 부가적인 메시지 종속 정보를 지정한다. 이 파라미터의 내용은 전송된 메시지에 의존한다.

lParam 부가적인 메시지 종속 정보를 지정한다. 이 파라미터의 내용은 전송된 메시지에 의존한다.

             4.  리턴값 : 메시지가 전송되면 비제로, 그렇지 않으면 0.

 

오버라이드 가능한 함수

l       DefWindowProc

1.        설명 : 애플리케이션이 처리되지 않은 어떠한 윈도 메시지에 대한 디폴트 프로세싱을 제공하는 디폴트 윈도 프로시저를 호출한다. 이 멤버 함수는 모든 메시지가 처리됨을 확실히 한다. 윈도 프로시져에 의해 받은 것과 동일한 파리미터들을 지닌채 호출되어야 한다.

2.        구문 : virtual LRESULT DefWindowProc( UINT message, WPARAM wParam, LPARAM lParam );

3.        파라미터

message 처리될 윈도 메시지를 지정한다.

WParam 부가적인 메시지 의존 정보를 지정한다.

LParam 부가적인 메시지 의존 정보를 지정한다.

             4.  리턴값 : 보내진 메시지에 따라 다르다.

l       DoDataExchange                                                                                                                                                                                                                                                                                                                     

1.       설명 : 다이얼로그 데이터를 교환하고 유효화 하기 위해 프레임워크로 호출한다. 이 함수는 절대로 직접 호출하지 말아야 한다. 이 함수는 UpdateData 멤버 함수로 호출한다. 대화 박스의 컨트롤을 초기화하거나 다이얼로그 박스로부터의 데이터를 얻는데 UpdateData를 호출한다. Cdialog에서 애플리케이션 특정 다이얼로그 박스 클래스를 이끌어 내려면, 또는 프레임워크의 자동 데이터 교환과 유효화를 이용하기를 원한다면 이 멤버 함수를 오버라이드할 필요가 있다. ClassWizard는 다이얼로그 데이터교환(DDX)과 유효화(DDV) 전역 함수 호출의 의도된 데이터 맵을 포함하는 멤버 함수의 오버라이드 버전을 작성할 것이다. UpdateData(TRUE)가 호출되면 DoDataExchange 함수가 호출되면서 DDV_로 시작되는 함수들이 호출되고, 이 함수들은 컨트롤에 입력된 값이 이 컨트롤과 Value형 멤버 변수로 전송되기에 적합한 데이터 형으로 되어 있는지, 또 유효한 입력 범위 안에 있는지를 확인하는 일을 한다. 컨트롤에 입력된 값이 Value형 멤버 변수로 전송되기에 적합한 데이터 형이고 유효한 입력 범위 안에 있으면 DDX_로 시작하는 함수들이 호출되어 실제로 데이터가 전송되고, 그렇지 않으면 에러 메시지가 출력되고, 데이터 전송은 취소된다. 여기서 DDV와 DDX는 각각 Dialog Data Validation(다이얼로그 데이터 유효성 확인)과 Dialog Data exchange(다이얼로그 데이터 교환)의 약자이다. UpdateData(FALSE)가 호출되면 DoDataExchange함수가 호출되면서 DDX_로 시작하는 함수들이 호출되어 Value형 멤버 변수에 설정된 데이터가 컨트롤로 전송되어 화면에 출력된다. DoDataExchange 오버라이드 멤버 함수는 반드시 소스 파일에 있는 메크로 문장을 실행해야 한다.

2.       구문 : virtual void DoDataExchange( CDataExchange* pDX );

3.       파라미터

pDX CDataExchange 객체에 대한 포인터.

             4.  리턴값 : 아무 것도 리턴하지 않는다.

 

시스템 메시지 핸들러

l       OnSysCommand

1.        설명 : 사용자가 제어 메뉴에서 명령을 선택할 때나 또는 사용자가 최대화 또는 최소화 버튼을 선택할 때 이 함수가 호출된다. 기본적으로 설정된 값에 의해, OnSysCommand는 이전의 테이블에서 지정된 미리 정해진 동작에 대한 제어 메뉴의 요구를 수행한다. WM_SYSCOMMAND 메시지 내에서, 윈도는 내부적으로 nID의 네 개의 low-order 비트들을 사용한다. 애플리케이션이 nID의 값을 조사할 때, 애플리케이션은 올바른 결과를 얻기 위해 AND 연산자를 사용함으로써 0xFFF0 값과 nID값을 결합시켜야 한다. 제어 시스템 내의 메뉴 아이템은 GetSystmeMenu, AppendMenu, InsertMenu, 그리고 ModifyMenu 함수에 의해 변경될 수 있다. 제어 메뉴를 변경시키는 애플리케이션들은 WM_SYSCOMMAND 메시지와 OnSysCommand에 전달되어야 하는 애플리케이션이 다루지 않는 모든 WM_SYSCOMMAND 메시지를 처리해야만 한다. 애플리케이션이 추가하는 모든 명령어 값들은 애플리케이션이 처리해야만 하고, OnSysCommand에 전달될 수는 없다. 애플리케이션은 WM_SYSCOMMAND 메시지를 OnSysCommand에 전달함으로써 언제든지 모든 시스템 명령을 수행할 수 있다. 제어 메뉴에서 아이템을 선택하기 이해 정의된 단축키들을 눌렀는지를 해석하여 OnSysCommand를 호출하게 된다. 모든 단축키들이 WM_SYSCOMMAND 메시지로 해석된다.

2.        구문 : afx_msg void OnSysCommand( UINT nID, LPARAM lParam );

3.        파라미터

nID 요청되는 시스템 명령 타입을 지정한다. 이 파라미터는 다음 중 어느 값을 가질 수 있다.

SC_CLOSE

CWnd 객체를 종료한다.

SC_HOTKEY

애플리케이션에서 지정한 단축키와 관련된 CWnd 객체를 활성화한다. Lparam의 low-order 단어는 활성화되는 윈도의 HWND를 판별한다.

SC_HSCROLL

수평으로 스크롤한다.

SC_KEYMENU

키가 눌렸는지의 여부로 메뉴를 검색한다.

SC_MAXIMIZE

(or SC_ZOOMM)

CWnd를 최대화.

SC_MINIMIZE

(or SC_ICON)

CWnd를 최소화(아이콘화).

SC_MOUSEMENU

마우스 버튼이 눌렸는지의 여부로 메뉴를 검색한다.

SC_MOVE

CWnd 객체를 이동한다.

SC_NEXTWINDOW

다음 윈도로 이동한다.

SC_PREVWINDOW

이전의 윈도로 이동한다.

SC_RESTORE

정상적인 윈도의 크기와 위치로 윈도를 복원한다.

SC_SCREENSAVE

[부트] 섹션의 SYSTEM.INI 파일에서 지정한 화면 보호기를 실행한다.

SC_SIZE

CWnd 객체의 크기를 정한다.

SC_TASKLIST

윈도의 태스크 매니저 애플리케이션을 실행 또는 활성화한다.

SC_VSCROLL

수직으로 스크롤한다.

                    LParam 마우스로 제어 메뉴 명령을 선택하면 lParam은 커서의 좌표를 포함하게 된다. low-order 단어에는 x 좌표, 그리고 high-order 단어에는 y 좌표를 포함한다. 다른 경우에는 이 파라미터는 사용되지 않는다.

                    Low-order 단어에는 x 좌표, 그리고 high-order 단어에는 y 좌표를 포함한다. 다른 경우에는 이 파라미터는 사용되지 않는다. SC_HOTKEY, SC_SCREENSAVE.

             4.  리턴값 : 아무 것도 리턴하지 않는다.

 

일반 메시지 핸들러

l       OnCommand

1.        설명 : 프레임워크는 사용자가 메뉴의 아이템을 선택할 때나 자식 컨트롤이 주의 메시지를 전달할 때, 또는 accelerator 키스트로크가 전환될 때 이 멤버 함수를 호출한다. OnCommand는 컨트롤 주의와 ON_COMMAND 엔트리들에 대한 메시지 맵을 처리하며, 적절한 멤버 함수를 호출한다. WM_COMMAND 메시지를 다루기 위해 파생된 클래스에서 이 함수를 오버라이드 한다. 오버라이드는 베이스 클래스 OnCommand가 호출되지 않으면 메시지 맵을 처리하지 못한다. 프레임워크에서 이 함수를 호출함으로써 사용자의 애플리케이션이 윈도의 메시지를 다룰 수 있게 된다. 사용자의 함수에 전달된 파라미터들은 메시지가 수신되었을 때 프레임워크가 수신한 파라미터들을 반영하게 된다. 사용자가 이 함수의 기본 수행을 호출하면 이것은 사용자가 함수에 제공한 파라미터들을 사용하는 것이 아니라 메시지를 갖고 전달된 파라미터들을 원래대로 사용할 것이다.

2.        구문 : virtual BOOL OnCommand( WPARAM wParam, LPARAM lParam );

3.        파라미터

wParam wParam의 low-order 단어는 메뉴 아이템이나 컨트롤의 명령 ID를 확인한다. WParam이 high-order 단어는 만일 메시지가 컨트롤에서 나온 것이면 주의 메시지를 지정한다. 만일 메시지가 accelertor에서 나온 것이면 high-order 단어가 1이다. 만일 메시지가 메뉴에서 나온 것이면, high-order 단어가 0이다.

LParam 만일 메시지가 컨트롤에서 나온 것이면 메시지를 전송하는 컨트롤을 확인한다. 그 외

의 경우에는, lParam은 0이다.

4.        리턴값 : 만일 애플리케이션이 이 메시지를 처리한다면 0이외의 값, 그 외의 경우에는 0이다.

               // example for ON_COMMAND
               BEGIN_MESSAGE_MAP( CMyDoc, CDocument )
               //{{AFX_MSG_MAP( CMyDoc )
            ON_COMMAND( ID_MYCMD, OnMyCommand )
            // ... More entries to handle additional commands
            //}}AFX_MSG_MAP
               END_MESSAGE_MAP( )

l       OnActivate

1.       설명 : 프레임워크는 CWnd 객체가 활성화나 비활성화될 때에 이 멤버함수를 호출한다. 처음에는, 비활성화된 주 윈도는 OnActivate를 호출시키며, 그리고 나서 활성화된 주 윈도가 OnActivate를 호출한다. CWnd 객체가 마우스 클릭으로 활성화되면, OnMouseActivate 멤버 함수의 호출을 받는다.

2.       구문 : afx_msg void OnActivate( UINT nState, CWnd* pWndOther, BOOL bMinimized );

3.       파라미터

nState CWnd가 활성화되거나 비활성화되고 있는지의 여부를 지정한다. 다음 값들 중 하나일 수 있다.

WM_INACTIVE

윈도가 비활성화 된다.

WM_ACTIVE

윈도가 마우스 클릭외의 다른 방법들을 통하여 활성화된다. (예를 들어, 윈도를 선택하기 위한 키보드 인터페이스의 사용을 통한다.)

WM_CLICKACTIVE

윈도가 마우스 클릭으로 활성화된다.

PWndOther 활성화되거나 비활성화된 CWnd에 대한포인터이다. 그 포인터는 NULL이 될 수 있으며, 일시적이다.

BMinimized 활성화되거나 비활성화된 CWnd의 최소화된 상태를 지정한다. TRUE 값은 윈도가 최소화됨을 가리킨다.

l       OnClose

1.       설명 : 프레임워크는 CWnd 또는 애플리케이션이 종결하는 신호로서 이 멤버함수를 호출한다. 디폴트 수행은 DestroyWindow를 호출한다.

2.       구문 : afx_msg void OnClose();

3.       파라미터 : 없음.

l       OnCreate

1.        설명 : Create나 CreateEx 멤버 함수 호출에 의해 생성되는 Windows 윈도를 애플리케이션이 요청할 때에 이 멤버 함수를 호출한다. CWnd 객체는 윈도가 생성된 후 그러나 가시화되기 전에 이 호출을 받는다. OnCreate는 Create나 CreateEx 멤버 함수가 리턴하기 전에 호출된다. 파생된 필수의 초기화를 수행하기 위해 이 멤버 함수는 오버라이드된다.

2.        구문 : afx_msg int OnCreate( LPCREATESTRUCT lpCreateStruct);

3.        파라미터

lpCreateStruct 생성될 CWnd 객체에 대한 정보를 함유하고 있는 CREATESTRUCT 구조체를 가리킨다.

4.        리턴값 : OnCreate는 CWnd 객체의 생성을 계속하기 위해 0을 리턴해야한다. 만일 애플리케이션이 1을 리턴하면, 그 윈도는 파괴된다.

l       OnDestroy

1.           설명 : 프레임워크는 파괴될 CWnd 객체에 정보를 주기 위해 이 멤버 함수를 호출한다. OnDestroy는 CWnd 객체가 스크린에서 제거된 후에 호출된다. OnDestroy는 처음에 파괸된 CWnd를 위해 호출되며, 그리고 나서 파괴되었기 때문에 CWnd의 자식 윈도를 위해 호출된다. 모든 자식 윈도들은 여전히 OnDestroy가 가동 중인 동안에 존재한다고 가정할 수 있다.

2.           구문 : afx_msg void OnDestroy()

l       OnEraseBkgnd

1.        설명 : 프레임워크는 CWnd 객체 배경을 지우려고 할 때 이 멤버 함수를 호출한다. 색칠을 위한 무효화된 영역을 준비하기 위해 호출한다. 디폴트 수행은 윈도 클래스 구조체의 hbrBackground 멤버에 의해 지정된 윈도 클래스 배경을 이용하여 배경을 지운다. 만일 hbrBackground 멤버가 NULL이면, OnEraseBkgnd의 오버라이드 버전은 배경색을 지워야 한다. 또한 브러시를 위한 UnrealizeObject를 처음에 호출함으로써 CWnd 좌표들을 갖고 의도된 브러시의 원점을 정렬해야 한다. 만일 오버라이드된 OnEraseBkgnd가 메시지를 처리하고 배경을 지운다면 OnEraseBkgnd는 WM_ERASEBKGND에 대한 응답으로써 0 이외의 값을 리턴한다. 이것은 더 이상 지우기가 필요하지 않다는 것을 가리킨다. 만일 그것이 0을 리턴한다면, 윈도는 지워야할 필요의 의미로 표시된 채 남아 있다.

2.        구문 : afx_msg BOOL OnEraseBkgnd( CDC* pDC );

3.        파라미터

pDC 디바이스 칸텍스트 객체를 지정한다.

4.        리턴값 : 만일 배경이 지워진다면 0 이외의 값, 그 외의 경우에는 0이다.

l       OnMove

1.       설명 : CWnd의 위치가 변경된 후에 호출된다.

2.       구문 : afx_msg void OnMove( int x, int y );

3.       파라미터

x 클라이언트 영역의 좌측 상단의 새로운 x좌표를 지정한다. 이 새로운 위치는 윈도를 겹쳐지게 하거나 생성하기 위해, 그리고 자식 윈도에 대한 부모 클라이언트 좌표를 위해 스크린 좌표로 주어진다.

Y 클라이언트 영역의 좌측 상단의 새로운 y좌표를 지정한다. 이 새로운 위치는 윈도를 겹쳐지게 하거나 생성하기 위해, 그리고 자식 윈도에 대한 부모 클라이언트 좌표를 위해 스크린 좌표로 주어진다.

l       OnPaint

1.       설명 : 윈도 또는 애플리케이션이 한 애플리케이션 윈도의 일부분을 다시 칠하도록 요구할 때 호출된다. UpdateWindow 또는 RedrawWindow 함수가 호출되면 WM_PAINT 메시지가 보내진다. 윈도는 결과적으로 RDW_INTERNALPAINT 플래그 세트를 가진 RedrawWindow 함수를 호출 함으로써 내부적인 색칠 메시지를 받을 수 있다. 이 경우, 윈도는 새로 갱신된 영역을 갖지 않을 수 있다. 애플리케이션은 윈도가 새로 갱신된 영역을 갖고 있는지 결정하기 위해 GetUpdateRect 함수를 호출해야 한다. 만약 GetUpdateRect 함수가 0인 값을 리턴하면 애플리케이션은 BeginPaint와 EndPaint 함수를 호출해서는 안된다. WM_PAINT 메시지는 무효영역과 RDW_INTERNALPAINT 플래그 세트를 가진 RedrawWindow 함수에 대한 호출 모두에 대해 발생할 수 있으므로 애플리케이션은 내부적으로 다시 칠하는 것 또는 각각의 WM_PAINT 메시지에 대한 내부 데이터 구조체들을 살펴봄으로써 새로 갱신해야 하는 것들을 체크 할 책임이 있다. 내부의 WM_PAINT 메시지는 단지 한 번만 윈도로 전송된다. UpdateWindow 함수는 WM_PAINT 메시지를 윈도로 보낸 후에, 윈도가 무용 지물이 되거나 RDW_INTERNALPAINT 플래그 세트를 가진 RedrawWindow 함수가 다시 호출될 때까지 WM_PAINT 메시지는 전송되거나 배치되지 않는다. 뷰 애플리케이션 내에 이미지를 렌더링하는데에 대한 정보는 CView::OnDraw를 참조한다.

2.       구문 : afx_msg void OnPoint();

l       OnSetFocus

1.       설명 : 입력 포커스를 얻은 후에 이 함수가 호출된다. 삽입 기호를 디스플레이하기 위해 이 시점에서 CWnd는 적절한 삽입 기호 함수를 호출해야 한다.

2.       구문 : afx_msg void OnSetFocus( CWnd* pOldWnd );

3.       파라미터 

pOldWnd 입력 포커스를 유실하는 CWnd 객체를 포함한다. 이 포인터는 임시적일 수 있으며, 나중에 사용하기 위해 저장할 수 없다.

l       OnShowWindow

1.       설명 : CWnd 객체가 감춰지거나 표시될 때 이 함수가 호출된다. 윈도는 ShowWindow 함수가 호출될 때, 겹쳐진 윈도가 최대화 또는 저장될 때, 또는 겹쳐졌거나 생성되는 윈도가 닫히거나(아이콘화되거나) 열릴 때(화면 상에 디스플레이될 때) 감춰지거나 표시 된다. 겹쳐진 윈도가 닫힐 때, 모든 그 윈도와 연관된 모든 생성되는 윈도는 감춰지게 된다.

2.       구문 : afx_msg void OnShowWindow( BOOL bShow, UINT nStatus );

3.       파라미터

bShow 윈도가 표시되는지를 지정한다. 윈도가 표시된다면 TRUE, 윈도가 감춰지니다면 FALSE이다.

NStatus 표시되는 윈도의 상태를 지정한다. ShowWindow 함수의 호출 때문에 메시지가 보내진다면 0, 그렇지 않으면 다음 값들 중 하나가 된다.

SW_PATENCLOSING

부모 윈도가 닫히거나(아이콘화되거나) 생성되는 윈도가 숨겨진다.

SW_PARENTOPENING

부모 윈도가 열리거나(디스플레이되거나)생성되는 윈도가 표시된다.

l       OnSize

1.       설명 : 윈도의 크기가 변화된 후 이 함수가 호출된다. OnSize에서 자식 윈도에 대해 SetScrollPos 또는 MoveWindow 함수가 호출된다면 CWnd가 다시 칠해지도록 하기 위해 SetScrollPos 또는 MoveWindow 함수의 bRedraw 파라미터는 0이 아닌 값이 되어야 한다.

2.       구문 : afx_msg void OnSize( UINT nType, int cx, int cy );

3.       파라미터

nType 크기를 재조절하도록 요청하는 형태를 지정한다. 이 파라미터는 다음 값들 중 하나가 될 수 있다.

SIZE_MAXIMIZED

윈도가 최대화되었다.

SIZE_MINIMIZED

윈도가 최소화되었다.

SIZE_RESTORED

윈도의 크기가 재조절되었다. 그러나 SIZE_MINIMIZED 또는 SIZE_MAXIMIZED가 적용된 것은 아니다.

SIZE_MAXHIDE

다른 윈도가 최대화될 때 생성되는 모든 윈도에 메시지가 전달된다.

SIZE_MAXSHOW

다른 윈도가 이전의 크길 환원되었을 때 생성되는 모든 윈도에 메시지가 전달된다.

                  Cx 클라이언트 영역의 새로운 폭을 지정한다.

                  Cy 클라이언트 영역의 새로운 높이를 지정한다.

 

컨트롤 메시지 핸들러

l       OnWndMsg

1.       설명 : WindowProc로 호출하거나, 메시지를 반영하는 동안 호출된다.

2.       구문 : virtual BOOL OnWndMsg( UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult );

3.       파라미터

message 보내진 메시지를 지정한다.

wParam 부가적인 메시지 종속 정보를 지정한다.

LParam 부가적인 메시지 종속 정보를 지정한다.

PResult WindowProc의 리턴 값이다. 메시지에 종속된다. NULL이 될 수 있다.      

4.       리턴값 : 만일 메시지가 다루어졌다면 0 이외의 값, 그 외의 경우에는 0이다.

 

입력 메시지 핸들러

l       OnChar

1.       설명 : 프레임워크는 넌시스템 문자로 키스트로크가 전환할 때 이 멤버 함수를 호출한다. 이 함수는 OnKeyUp 멤버 함수가 호출되기 이전에 OnKeyDown 멤버 함수가 호출된 이후에 호출된다. OnChar는 누르거나 풀었을 때의 키보드 키의 값을 포함한다. 눌러진 키들 간의 1대1 대응이 필요없고 OnChar의 호출이 발생되기 때문에, nFlags 상의 정보는 일반적으로 애플리케이션에는 유용하지 못하다. NFlags 에 있는 정보는 단짖 최근의 OnKeyUp 멤버 함수나 또는 OnChar의 호출을 처리하는 OnKeyDown 멤버 함수에 적용된다. ALT 키와 CTRL 키, 숫자 키패드 왼쪽에 회색의 INS, DEL, HOME, END, PAGE UP, PAGE DOWN, 그리고 화살키들, 그리고 숫자 패드에 있는 슬래쉬(/)와 엔터키이다. 다른 키보드들도 nFlags에서 이러한 확장된 키 비트를 지원할 수 있어야 한다.

2.       구문 : afx_msg void OnChar( UINT nChar, UINT nRepCnt, UINT nFlags );

3.       파라미터

nChar 키의 문자 코드를 포함한다.

NRepCnt 반복되는 카운트, 사용자가 키를 아래로 고정할 때 반복되는 키스트로크의 횟수를 포함한다.

NFlags 다음의 표에 나오는 스캔 코드, 키-변환 코드, 이전의 키 상태, 그리고 칸텍스트 코드들을 포함한다.

플래그들의 설명

0-7

스캔 코드(OEM 의존 값)

8

확장키, 기능키 또는 숫자 패드 상의 키(확장키라면 1, 이외의 키라면 0)

9-10

사용되지 않음.

11-12

윈도가 내부적으로 사용.

13

칸텍스트 코드( ALT 키가 눌려 있는 동안 키를 눌렀을 때 1, 이외의 경우 0)

14

이전 키의 상태(메시지가 보내지기 전에 키를 누를 때 1, 키를 놓았을 때 0)

15

전환 상태(키를 놓았을 대 1, 키를 눌렀을 때 0)

l       OnKeyDown

1.       설명 : 프레임워크는 넌시스템 키가 눌러졌을 때 이 멤버 함수를 호출한다. 넌시스템 키는 ALT 키가 눌러지지 않은 키보드의 키이거나 CWnd가 입력 초점일 때 눌러진 키보드의 키이다. 자동 반복 때문에, 이 함수는 OnKeyUp 멤버 함수가 호출되기 이전에 OnKeyDown 멤버 함수가 호출된 호출된 이후에 호출된다. 이전 키의 상태가 OnKeyDown의 호출이 첫 번째 다운 전환이거나 만복된 다운 전환인지의 여부를 결정하는데에 이용될 수 있다. Enhanced 키들은 주요 부분들 상의 오른쪽 ALT 키와 오른쪽 CTRL 키이다. INS, DEL, HOME, END, PAGE UP, PAGE DOWN, 그리고 화살키들, 그리고 숫자 패드에 있는 슬래쉬(/)와 엔터키이다. 다른 키보드들도 nFlags에서 이러한 확장된 키 비트를 제공 한다.

2.       구문 : afx_msg void OnKeyDown( UINT nChar, UINT nRepCnt, UINT nFlags );

3.       파라미터 

nChar 주어진 키의 가상 키 코드를 지정한다.

NRepCnt 카운트를 반복한다. (키스트로크 횟수는 사용자가 키를 누르고 있는 결과이다.)

NFlags 다음 리스트에 나온것과 같은, 스캔 코드, 키 전환 코드, 이전 키의 상태, 그리고 칸텍스트 코드들이다. => OnChar 참조

l       OnKeyUp

1.       설명 : 프레임워크는 넌시스템 키가 눌러졌을 때 이 멤버 함수를 호출한다. . 넌시스템 키는 ALT 키가 눌러지지 않은 키보드의 키이거나 CWnd가 입력 초점일 때 눌러진 키보드의 키이다. 자동 반복 때문에, 이 함수는 OnKeyUp 멤버 함수가 호출되기 이전에 OnKeyDown 멤버 함수가 호출된 호출된 이후에 호출된다. 이전 키의 상태가 OnKeyDown의 호출이 첫 번째 다운 전환이거나 만복된 다운 전환인지의 여부를 결정하는데에 이용될 수 있다. Enhanced 키들은 주요 부분들 상의 오른쪽 ALT 키와 오른쪽 CTRL 키이다. INS, DEL, HOME, END, PAGE UP, PAGE DOWN, 그리고 화살키들, 그리고 숫자 패드에 있는 슬래쉬(/)와 엔터키이다. 다른 키보드들도 nFlags에서 이러한 확장된 키 비트를 제공 한다.

2.       구문 : afx_msg void OnKeyUp( UINT nChar, UINT nRepCnt, UINT nFlags );

3.       파라미터 : OnKeyDown과 동일.

l       OnTimer

1.       설명 : 타이머를 설치하는데 사용된 SetTimer 함수 내에 지정된 각각의 시간 간격 후에 이 함수가 호출된다. 애플리케이션의 메시지 큐 내에 다른 어떤 메시지도 없을 때 DispatchMessage 윈도 함수는 WM_TIMER 메시지를 보낸다.

2.       구문 : afx_msg void OnTimer( UINT nIDEvent );

3.       파라미터

nIDEvent 타이머의 식별자를 지정한다.

 

MDI 메시지 핸들러

l       OnMDIActivate

1.        설명 : 프레임워크는 자식 윈도를 활성화 또는 비활성화시키기 위해 이 멤버 함수를 호출한다. MDI 자식 윈도는 MDI 프레임 윈도에 따라 활성화된다. 프레임이 활성화되면 OnMDIActivate 호출을 받고 마지막으로 활성화된 자식 윈도는 WM_NCACTIVATE 메시지를 받아 활성화된 윈도 프레임과 캡션 바를 그리게 된다. 그러나 또다른 OnMDIActivate 호출을 받지 않는다.

2.        구문 : afx_msg void OnMDIActivate( BOOL bActivate, CWnd* pActivateWnd, CWnd* pDeactivateWnd );

3.        파라미터

bActivate 자식이 활성화되면 TRUE, 비활성화되면 FALSE이다.

PActivateWnd- MDI 자식 윈도가 활성화되도록 하는 포인터를 갖는다. MDI 자식 윈도가 전해주면 pActvateWnd는 활성화되는 자식 윈도에 대한 포인터를 갖는다. 이 포인터는 일시적인 것일 수 있으며, 이후에 사용하기 위해 저장해서는 안된다.

PDeactivateWnd MDI 자식 윈도가 비활성화되도록 하는 포인터를 갖는다. 이 포인터는 일시적인 것일 수 있으며 이후에 사용하기 위해 저장해서는 안된다. 

 


'C/C++/MFC' 카테고리의 다른 글

메뉴 항목 체크/ 해지 하기  (0) 2009.01.10
API 컨트롤 숨기기, 나타내기  (0) 2009.01.05
포인터 사용법  (0) 2009.01.05
MFC를 사용하여 웹 브라우저 만들기  (0) 2009.01.02
[API]버튼만들기  (0) 2009.01.02
posted by 유돌이
2009. 1. 5. 20:57 유닉스*리눅스*SE

cp 명령어로 카피를 하려는데 omitting error가 난다면,

해당 파일이나 디렉토리를 어떤 프로세서에서 사용하고 있는 것일수도 있다.

이럴땐

 

#cp -rvf /home/test.c /opt

 

이렇게 옵션을 주면 해결 할 수 있다.

 

또는 tar로 압축을 해서 다른곳으로 옮긴뒤 압축을 해제 할 수도 있다.

 

#tar -cxv /opt/test.tar /home/test.c

'유닉스*리눅스*SE' 카테고리의 다른 글

[centos7] yum 명령어 안될시~  (0) 2019.09.12
[우분투 16.04] SSD 마운트 하기  (0) 2019.09.11
[안드로이드] 커널로그 보기  (0) 2019.09.11
쉘 프로그래밍(read)  (0) 2009.01.06
유닉스 명령어  (0) 2009.01.05
posted by 유돌이
2009. 1. 5. 20:52 유닉스*리눅스*SE

1. ls  디렉토리의 파일 표시

2. cd  현재 작업하는 디렉토리를 변경 copy directory

3. mv  파일이름 및 위치 변경

4. cp    파일 및 디렉토리를 복사

5. rmdir      디렉토리를 삭제

6. mkdir     디렉토리를 생성

7. find      사용자가 지정한 특정 범위에 해당하는 모든 파일을 검색

8. rm        파일 이나 디렉토리 지우기

9. ll (ls-l)       전체폴더구조보기

10. cat      파일 내용을 한화면에 표준 출력

11. useradd     새로운 유저를 등록

12. userdel      계정을 삭제

13. usermod     사용자계정정보 수정

14. ps           현재 실행되고 있는 프로세스들의 상태를 볼 때 사용합니다.

15. pstree        프로세스 상관관계 보여줌

16. pkill          프로세스 한꺼번에 중단

17. kill           특정 프로세스를 중단

18. killall         파일명으로 프로세스 중단

19. modprobe     모든모듈 적재 및 삭제

20. insmod       로드 가능한 커널 모듈을 검사

21. rmmod        모듈삭제

22. lsmod       사용 중인 모듈 적재

23. more         파일 내용이나 입력을 표준 출력으로 한 페이지씩 출력합니다.

24. less        페이지단위로 출력, 앞뒤로 이동 가능

25. touch      내용이 없는 빈 파일을 생성, 이미 생성된 파일의 수정 시간 갱신

26. ifconfig     네트워크 구성설정, 표시

27. ifup         파일설정 유지한 채로 네트워크 디바이스 구동

28. ifdown       파일설정 유지한 채로 네트워크 디바이스 종료

29. dir           디렉토리 목록표시

30. sed          스트림 편집기

31. awk         program file에서 기술된 pattern들중 일치되는 line 을 찾기 위해 입력 화일을 검색하는 명령어

32. tar           파일을 묶음, 압축

33. gzip         gzip 압축 방식으로 압축하는 명령어

34. gunzip       .gz 파일을 푸는 명령어입니다

35. bzip2           블럭 정렬 파일 압축기

36. fdisk           디스크의 파티션을 변경한다

37. ldd             공유 라이브러리의 의존성을 출력한다.  

38. dd             한 파일을 복사하는 동한 변환한다. 

39. ldconfig        LD Path를 수정 적용해주는 명령어 (라이브러리 파일업데이트)

40. fireconfig      방화벽설정

41. netconfig      콘솔기반의 네트워크 설정

42. mail           사용자들간에 전자우편을 주고 받는 명령어

43. tail   파일의 카운트로 정한 숫자만큼의 끝 부분 줄 수를 보여주는 명령으로 카운트를 지정을 안하면 디폴트로 10이 된다.

44. iptables         리눅스커널 2.4버전에서 사용하는 방화벽이다 (패킷필터링 실행)

45. startx           그래픽모드실행

46. passwd         패스워드를 변경할 때 사용합니다. 이전 패스워드와 새로운 패스워드를 입력합니다.

47. vim           텍스트편집기

48. vi            파일편집기 (화면편집기)

49. date         시스템에 설정된 날짜와 시간을 출력합니다.

50. rdate         네트윅으로 시간설정하기

51. mknod       디렉토리 또는 특별한 또는 일반적인 파일을 생성한다

52. rmnod       디렉토리 및 파일 제거

53. service      서비스관리 (인터넷 네트워크 서비스 리스트)

54. rpm          패키지를 설치 및 업그레이드 (패키지관리자)

55. yum          자동으로 패키지를 업데이트, 설치, 삭제

56. alternate      오류발견시 항목삭제

57. sort      파일의 내용이나 다른 명령의 결과값을  줄단위로 정렬한다.

58. cut       파일이 각 line에서 선택된 필드를 절단하는 명령어

59. chgrp    파일의 그룹 소유권 변경

60. chown     파일과 연관된 소유자 또는 그룹을 변경합니다. (ex.  chown andy.andy andy/)

61. chmod     파일 소유자/그룹/다른사용자 의 권한을 변경합니다.

62. uniq       파일내 중복되는 행 제거

63. df     (disk free) - 디스크의 남은 용량보기

64. du      디스크의 사용공간 표시

65. diff      두개의 파일이 일치되도록 변경시키기 위한 정보를 제공해 줌. 두파일차이점비교

66. cpio         복사본 만들기

67. man         명령어 등의 메뉴얼 페이지(man page)를 보여 줍니다

68. rename      파일의 이름이나 위치를 변경

69. seq        주어진 범위내의 순차적인 번호를 출력한다.

70. route     IP routing table 보여줌

71. echo   인수지정된 문자열 화면에 출력  -> echo "천재완섭“

72. yes    반복하여 문자를 출력

73. fsck     파일시스템의 상태유지 및 수정

74. mount  특정 디렉토리에 자신이 원하는 파일 시스템을 연결하여 리눅스에서 볼 수 있는 명령이다.

75. umount  지정한 파일시스템의 연결을 제거한다

76. su         임시로 다른 사용자로 로그인해서 사용하고자 할 때 사용합니다.

77. sudo 관리자(root)가 특정 사용자(특정 그룹)에게 특정 명령(명령그룹)을 root계정으로 실행할 수 있는 권한부여

78. pwd      현재/작업 디렉토리명을 보기,출력한다

79. chkconfig   시작서비스 관리


 

'유닉스*리눅스*SE' 카테고리의 다른 글

[centos7] yum 명령어 안될시~  (0) 2019.09.12
[우분투 16.04] SSD 마운트 하기  (0) 2019.09.11
[안드로이드] 커널로그 보기  (0) 2019.09.11
쉘 프로그래밍(read)  (0) 2009.01.06
cp시 omitting error 날때  (0) 2009.01.05
posted by 유돌이
2009. 1. 5. 20:42 C/C++/MFC
1. 포인터(포인터 변수)의 개념

(1) 일반 변수와 포인터 변수의 차이점

   일반 변수는 정수/실수/문자 중 1개의 값을 저장한다.
   포인터 변수는 값이 아니라 "주소"(변수, 배열 등 저장공간이 할당된 것)를 저장한다.

	int i=100, data[100]={ 1, 3, 5, 7, 9 };
	int *p, *q;

	p = &i;		// 변수 i의 주소
	q = data;	// 배열 data의 주소

	*p = 200;	// i = 200; 과 동일
	*(q+1) = 30;	// data[1] = 30; 과 동일

(2) 포인터 변수를 이용하여 값을 사용/변경

    포인터를 이용하여 값을 사용하거나, 변경할 수 있는 범위는
    포인터가 가리키는 주소에 따라 결정된다.

    즉, 위 예에서 포인터 p는 i를 가리키므로 1개의 값만 사용/변경할 수 있다.
    그러나 q는 배열 data를 가리키므로 100개의 값을 사용/변경할 수 있다.

(3) 포인터 변수가 배열을 가리킬 때 --- 포인터 변수의 증감 연산

    - 포인터 연산자 '*' 대신에 배열의 인덱스 사용
	즉, *(q+3) 은 q[3] 과 동일하며, 배열과 동일한 형태로 사용할 수 있다.

    - 포인터 변수가 가리키는 배열의 위치 이동
	아래와 같이 포인터 변수가 가리키는 위치를 변경할 수 있다.
	단, 포인터가 가리키는 배열 data[100]의 인덱스 범위를 벗어날 수 없다.

		q = q + 2;
		q++;
		q--;


2. 포인터 배열

   여러 개의 변수(예: 100개의 변수)를 선언하는 대신에 배열을 선언하는 것과 같다.
   즉, 포인터 배열은 포인터 변수를 여러 개 선언하는 대신에 포인터 배열을 사용한다.

	int *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9, *p10;

   와 같이 10개의 포인터 변수를 선언하기 보다는

	int *p[10];

   로 선언하여 p1, p2, ..., p10 대신에 p[0], p[1], ..., p[9] 를 사용한다.


3. 다중 포인터

    1차원 포인터는 값(정수/실수/문자)이 저장된 변수(또는 배열)의 주소.
    2차원 포인터는 1차원 포인터 변수의 주소.
    3차원 포인터는 2차원 포인터 변수의 주소.
    n차원 포인터는 n-1차원 포인터 변수의 주소.

	int i=100, data[100]={ 1, 3, 5, 7, 9 };
	int *p, *q[10];		// 1차원 포인터
	int **dp1, **dp2;	// 2차원 포인터
	int ***tp1, ***tp2;	// 3차원 포인터

	p = &i;
	dp1 = &p;		// p는 포인터 변수
	tp1 = &dp1;

	q[2] = data;
	dp2 = q;		// q는 포인터 배열
	tp2 = &dp2;

   위 예에서

	i, *p, **dp1, ***tp1

   은 모두 동일하다. 마찬가지로 data[0], *q[2], **dp2, ***tp2 도 동일하다.


4. 포인터와 문자 배열, 스트링 상수의 관계

주의 1. 모든 배열의 이름은 배열에 할당된 공간의 첫번째 "주소"이다.

주의 2. 스트링 상수 "ABC"는 그 자체가 "주소"이며, 값을 변경할 수 없다.
	('A', 'B', 'C', '\0' 순서의 4문자가 저장된 "주소"를 지칭한다.
	 이 문자들은 static area에 자동으로 저장된다.)

	단, 문자배열의 초기화(예: char a[] = "ABC";)에 사용된 "ABC"는
	문자배열의 초기화를 편리하게 하기 위한 것일 뿐이며, 스트링 상수가 아니다.

<예1>
	char *p;
	char a[] = { 'A', 'B', 'C', '\0' };	// char a[] = "ABC"; 와 동일함!

	p = a;
	*p = 'X';
	*(p+1) = 'Y';
	*(p+2) = 'Z';

<예2>
	char *p = "ABC";	// p는 스트링 상수 "ABC"를 가리킴
	char b[100];

	strcpy(b, p);
	b[3] = *(p+1);
	b[4] = 'B';
	b[5] = '\0';

   포인터 p는 "스트링 상수"를 가리키고 있으므로 각 문자를 사용할 수 있으나,

	*p = 'X';
	strcpy(p, "XYZ");

   와 같이 값을 변경하는 것은 허용되지 않는다. 그러나 모든 포인터는 다른 주소를
   가리키게 할 수 있으므로

	p = "XYZ";
	p = b;

   와 같은 문장은 당연히 허용된다.(포인터의 정확한 이름은 "포인터 변수"이며,
   포인터 변수가 다른 주소를 가리키게 할 수 있다.)


<예3> char *p = "ABC"; 는

	char *p;
	p = "ABC"

   와 같다. 그러나 char a[] = "ABC"; 를

	char a[4];
	a = "ABC"

   와 같이 쓸 수는 없다.(배열이름은 고정된 주소값이며, 포인터 변수가 아니다.)


5. "구조체 변수"와 "구조체 포인터"에서 항목 선택 방법

(1) 연산자 '.' --- "구조체 변수"의 각 항목을 선택할 때(field selection)

	struct ABC {
	   int a;
	   int b;
	} x, *p;

    의 경우에 "구조체 변수" x의 항목 a 혹은 b를 선택할 때는

	x.a = 100;
	x.b = 200;

    과 같이 사용한다.

(2) 연산자 '->' --- "구조체 포인터"의 각 항목을 선택할 때(field selection)
   
    "구조체 포인터" p를 이용하여 a, b를 가리킬 때는 아래와 같이 사용한다.

	p = &x;		// 포인터 p는 변수 x를 가리키게 했음.
	p->a = 100;
	p->b = 200;

위 예에서 p는 포인터이므로 *p는 x와 동일하다. 따라서 일반적인 포인터 사용법에 따라
위 예는 아래와 같이 써도 무방하다.

	p = &x;
	(*p).a = 100;
	(*p).b = 200;

다만, p->a 가 (*p).a 보다 이해하기가 더 편하고 readability가 좋으므로
일반적으로 이렇게 쓰는 경우는 거의 없다.

<참고> (*p).a를 *p.a 라고 쓰면 안된다. 왜냐하면 '.'이 '*'보다 우선순위가 높아서
       *p.a 는 *(p.a) 와 같아지게 되기 때문이다.


6. 포인터 관련 선언문 예

	int *p;		--- 포인터 변수 p, 정수형 주소 저장
	char *p;	--- 포인터 변수 p, 문자형 주소 저장
	int *p[n];	--- 크기 n인 포인터 배열 p, (p[0], …, p[n-1]에 정수형 주소 저장)

	int *p();	--- 함수 p의 선언, "return값이 int pointer"인 함수 p
	int *p()[];	--- 함수 p의 선언, "return값이 int pointer 배열"인 함수 p

	int (*p)[n];	--- 포인터 변수 p, "크기 n인 정수형 배열 구조를 갖는 주소"를 저장
	int (*p)();	--- 포인터 변수 p, "return값이 int인 함수"의 주소 저장
	int (*p[])();	--- 포인터 배열 p, "return값이 int인 함수"의 주소 저장

'C/C++/MFC' 카테고리의 다른 글

API 컨트롤 숨기기, 나타내기  (0) 2009.01.05
CWnd 클래스  (0) 2009.01.05
MFC를 사용하여 웹 브라우저 만들기  (0) 2009.01.02
[API]버튼만들기  (0) 2009.01.02
Invalidate() , OnDraw(CDC* pDC)  (0) 2009.01.02
posted by 유돌이
2009. 1. 5. 18:13 델파이

지난회에서는 소스필터와 변환필터 각각의 종류에 대하여 설명하였습니다. 그렇다면 이제 DShow에서 제공하는 중요 기본 필터들을 살펴보고, 그 특성과 사용방법에 대하여 강의할 것입니다. 일단 여러분이 밥먹듯이 익히고 사용해야 할 주요 필터들의 항목은 다음과 같습니다. 다음의 필터는 GraphEdit의 '필터삽입윈도우'에서 DirectShow Filters 카테고리에 있는 것들입니다.  

 => Avi Mux, Avi Splitter, Color Space Converter, File Source(Async.), File Writer, Infinite Pin Tee Filter, Overlay Mixer, Sample Grabber, Smart Tee, Video Renderer

위에서 Overlay Mixer 나 Infinite Pin Tee Filte 를 제외하고는 DShow를 대변하는 주요 필터라고 할 수가 있겠습니다.
DShow용 어플을 개발하는데 있어서 거의 필수적이라고 생각하셔도 무방할 것입니다. 그럼 하나씩 알아보도록 하겠습니다. 

 (1) Avi Mux

통상 '먹스'라고 부릅니다. 여러분은 '믹싱'과 '먹싱'에 대하여 구분하셔야 합니다.
믹싱은 두개이상의 데이터를 하나에 완전히 혼합시키는 것을 의미합니다. 예를 들어서 강남콩이 반쯤 담겨있는 통에 좁쌀을 붓고서 마구 흔들어 섞어지는 형태를 의미한다고 할 수 있겠습니다. 강남콩과 좁쌀이 완전히 뒤섞여 다시 원래대로 분류하기가 힘들게 되어 버리는 것을 의미합니다. 몇달전에 비디오 스트림 안에 자막을 '믹싱'처리 해달라는 의뢰를 받은 적이 있었습니다. 이것은 즉 비디오 영상의 각 프레임마다 자막을 이미지 위에 그려넣어달라는 것을 의미합니다.

자, 그렇다면 '먹싱'이란 무엇을 의미하는 것일까요. 먹싱은 하나의 통에 강남콩과 좁쌀을 별도로 비닝봉지에 넣어 보관하는 상태를 의미합니다. '먹싱' 을 예로 들때에 대표적으로 영상과 음성의 스트림입니다. 영상과 음성은 서로 독립된 형태의 데이타로서 보존해야 하기때문에 대부분 '먹싱'처리를 합니다. 여러분의 하드디스크에 어떤 영화파일이 있다면 한번 울트라 에디트로 열어보시길 바랍니다. 영상과 음성의 데이터 사이에 일정한 간격을 두고 마치 공백처럼 느껴지는 FF값으로 가득차 있는 곳을 간혹 발견하실 수가 있을 것입니다. 이것이 바로 영상과 음성이 나뉘어지는 칸막이 비슷한 것이라고 생각하시면 되겠습니다.

우리가 동영상을 Avi로 저장하기 위해서는 이렇게 일단 '먹싱'를 해야 합니다.  위의 Avi Mux 필터를  GraphEidt 상에서 '필터삽입윈도우'를 사용하여 생성시키면 메인화면에는 Input핀 하나와 OutPut핀 하나가 있는 네모박스 형태의 비주얼한 필터가 보여질 것입니다. 자, 이상태에서 USB 카메라의 입력장치를 하나 필터로 생성시켜 봅니다. 이것은 제가 Video Capture Source 카테고리에 있다고 하였지요. 두개의 필터를 연결시켜 보시면 알겠지만, 연결하자 마자  Avi Mux 필터에는 또다른 하나의 입력핀이 생겨지는게 보이실 것입니다. 

-------------------------------------------------------------------------------------------------
참고 -> Avi Mux 필터의 입력핀은 이렇게 계속해서 생겨집니다. 현재 연결되어 있는 핀보다 항상 갯수가 하나더 만들어지게 되어 있는 것이죠. 만일 여러분이 필터개발자라면 이런식으로 동적 핀을 생성하게 만드는 것도 사실 간단한 일은 아닙니다. 동적핀을 만드는 것이 내부적으로 어려운 것은, 그 핀들을 단순히 생성시키는 것의 문제가 아니라 계속해서 또다른 입력이 들어올 수 있다는 가정하에 내부로직을 준비해야 하기 때문입니다. 
-------------------------------------------------------------------------------------------------

Avi Mux 필터의 입력핀에 비디오 스트림을 연결시키면 하나의 입력핀이 더 생겨집니다. 이때 두번째 입력핀에 오디오 스트림을 연결하고 보면 출력핀은 그대로 하나인 것을 보실 수가 있습니다. 이처럼 영상과 음성 두개의 입력 스트림이 Mux 되어 하나의 스트림으로 출력되는 것입니다. 
 
그럼 여기서 GraphEdit를 사용하여 간단하게 파일을 만드는 법을 설명하겠습니다.  


  Cam Filter ----> Avi Mux -> File Writer    
                            ▲  
  Audio Filter ------┘


위와같이 연결하시고 Play를 하시면 되겠습니다. 물론 Cam Filter는 제가 앞서말한 Video Capture Source 카테고리에 있는 USB 카메라 입력장치를 말합니다. 또한 AudioFilter는 Audio Capture Source 카테고리에 있습니다. 마지막으로 Filter Writer는 Avi Mux와 마찬가지로 DirectShow Filtes 카테고리에 있을 것입니다. Play를 하면 화면에는 어떠한 랜더링 창도 뜨질 않지만, 대신에 하드디스크에 여러분이 지정하신 파일 이름으로 영상과 음성이 먹싱되어 저장되는 중일 것입니다. 마이크가 있으시다면 목소리를 가다듬고 소리를 지르셔도 좋으실 것입니다.

자, 지금까지 '믹싱'과 '먹싱'의 차이에 대하여 알아보았으며 실제로 영상과 음성을 '먹싱'처리하여 저장하기까지 하였습니다. 

(2) Avi Splitter 

Avi Splitter는 '파서 필터'의 일종이라고 전회에 설명하였습니다. 따라서 추가 설명은 하지 않겠습니다. 

(3) Color Space Converter

이 Color Space Converter라는 필터가 아주 고마운 녀석입니다. 이 필터는 입력핀에 YUV형태의 미디어타입이 들어온것을 RGB형태로 변환합니다. 일반적으로 YUV를 RGB로 변환하는 로직을 MMX나 SSE로 최적화된 로직이 있습니다. 하지만 이런 로직을 DShow에서 사용하기 위해서는 별도의 변환필터를 만들거나 해야합니다. 그런데 DShow에서 아예 이런 필터를 준비해 뒀다는 것은 참으로 고마운 것입니다. 이것을 다른 시각에서 본다면 DShow를 사용하면 이런 형태의 서비스를 받을 수가 있다는 의미도 될 것입니다. 

사실 제가 DShow 초보시절에 바로 이 필터의 존재조차도 몰라서 직접 변환로직을 만들기위해 얼마간 끙끙거렸던 적이 있었습니다. 왜냐하면 연결하려는 앞의 필터에서 나오는 출력핀의 미디어 타입에 RGB형이 없고 죄다 YUV형 타입이었기 때문입니다. 머리가 나쁘면 손발이 고생한다고, 눈앞에 뻔히 있는 것을 별도로 만들기 위해 몇일간을 헤메었던 기억이 눈앞에 선합니다. 굳이 있는 것을 별도로 만들 필요는 없을 터이죠. 게다가 테스트한 결과 이 Color Space Converter 필터의 변환 성능은 상당히 최고급 수준입니다. 

(4) Overlay Mixer

이 Overlay Mixer 필터는 예전에 영상이나 자막을 합성할때 사용하던 필터입니다. 그래픽 카드의 오버레이 평면을 이용한 것인데요, 이것은 하나의 디스플레이 평면 위에 또다른 평면이 오버레이 되면서 합성되어지는 방식을 의미합니다. 하도 오래전에 사용해 보아서 기억이 가물가물합니다. 이 필터는 요즘 별로 사용하지 않을 거라는 생각이 듭니다.

자막을 아직도 이 필터를 사용해서 하는지 모르겠습니다. 예전에 지금의 곰플레이어가 아닌 아드레날린이라는 어플이 마악 태동할 초창기에는 자막 처리가 동영상 어플 개발자들의 관심사항 첫순위였습니다. 신화선님의 책에도 자막처리가 독립된 장으로 상당히 할당되어 나와있을 정도였으니까요.
아무튼 언듯 기억나는 것은 메인화면 위에 오버레이 평면이 겹쳐지게 되는데요, 이때 오버레이 평면에 특정한 색을 투명으로 지정을 하면 그 부분만 뻥 뚤려서 아래의 메인화면과 합성되어 보여지는 식입니다. 이것은 CPU에 전혀 부담이 없이 그래픽카드에서 처리해 주는 것입니다.
만일 자막 처리를 CPU에서 '믹싱'의 방식으로 버퍼링 처리를 하였다면 상당한 부담이 되었을 터입니다. 그당시 컴퓨터 성능이 상당히 낮았고, 웬만한 동영상 파일하나 재생 하는데에도 CPU 점유율이 20, 30%까지 치솟았던 점을 감안한다면 왜 그렇게 자막처리에 안달을 볶았는지 지금에서야 이해되는 측면도 있습니다.  아무튼 그냥 이정도만 알고 계셔도 무방하다고 생각합니다.
OverLay에 대해서 더 알고 싶으시다면 차라리 DirectX 게임관련 서적을 참고하시는 게 더 자세하다고 생각합니다. 왜냐하면 OverLay라는 것 자체가 그래픽카드에서 지원되는 자원중 하나이기 때문입니다. 

(5) Sample Grabber

이 Grabber를 사전에서 찾아보면 1. 부여잡는 사람, 강탈자, 욕심꾸러기, 2. 흥미진진한 것, 깜짝 놀라게 하는 것. 이라고 나와 있습니다. 하지만 프로그래밍에서 혹은 전산일반에서 Grabber(그래버)라고 한다면 이 말의 의미는 조금 독특한 성격의 어떤 기능을 대변하고 있습니다. 즉, 어떤 것들 중에서 하나를 추려내는 기능이라는 의미인 것입니다. 아마도 '부여잡는 사람'이라는 첫번째 의미와 비슷할 것입니다만, 그와는 또다른 차원의 전산적 의미를 내포하는 것이라 하겠습니다. 

FA라는 공장자동화 계열에는 비젼시스템이라고 있습니다. 이 시스템은 생산라인에서의 불량을 자동 체크하는 기능을 갖도록 이미지 판독을 위한 카메라와 보드등을 갖추고 있는데요, 여기서도 '그래버 기능'이라는 표현이 사용되어 집니다. 실제로 '그래버 기능'이라는 것은 연속된 스트림에서 어느 한 프레임을 '찰칵' 찍어내는 기능을 의미합니다.
아마도 이게 사실 어떤 것인지 이해하기 어려울 지도 모르겠습니다. 동영상이라는게 연속된 일련의 이미지들인데, 여기서 기껏 한장을 뽑아내는 기능을 별도로 '그래버 기능'이라고 말할 정도까지 까다로운 것인가 하고요...  결론적으로 말씀드린다면 까다롭고요, 까다로울 수 밖에 없는 이유는 각각의 R, G, B  채널과 주파수와의 상관 관계에 있습니다. 아무튼 중요한 것은 이렇듯 FA라는 산업분야의 비젼시스템에서도 '그래버'라는 용어를 사용하고 있다는 것입니다. 

그래버라는 것은 전산일반에서 사전적인 뜻 이외의 독특한 기능을 대변하고 있다는 것을 알고 계시면 좋을 것 같아서 이렇게 설명이 삼천포로 빠졌습니다. 나중에 FA의 비전시스템 SDK 프로그래밍을 하실때 이 '그래버'라는 의미를  지금 기회에 알아두시면 좋을 것 같아서 설명드린 것입니다. 

아마도 다음회부터 우리는 만들고자 하는 테스트 프로그램에서 바로 이 Grabber 필터를 사용할 것입니다. 이것을 사용하여 카메라로부터 들어온 영상 중에서 '착칵'하고 한 프레임의 사진을 뽑아내어 이미지로 저장해 보일 것입니다. 

(6) File Source(Async.)

이 필터는 글자 그대로 소스필터입니다. 보다 정확히 표현한다면 소스필터 중에서 풀모드 형식의 소스필터입니다. 우리는 전회에서 '소스필터'의 종류와 내부기능에 대하여 공부하였습니다. 이 필터 뒤에는 반드시 파서필터가 붙어야 하며, 일반적인 Avi 표준형식이라면 DShow에서 이미 제공하고 있는 위의  Avi Splitter 필터가 달라 붙게 될 것입니다. 

대부분의 풀모드 소스필터가 그러하듯이 이 필터가 하는 일이란 달랑 원하는 동영상 파일을 로딩하는 것입니다. 이런 서비스를 하기 위해서 IFileSourceFilter 라는 인터페이스를 내부적으로 가지고 있는데요, 우리는 이것을 사용하여 원하는 파일을 로딩하게끔 코딩상에 설정하실 수가 있습니다. 

만일 여러분이 GraphEdit에서 본 필터를 생성하였다면, 생성과 동시에 '파일선택 다이알로그 창'이 뜨게될 것입니다.
여기서 원하는 동영상 파일을 선택하면, GraphEdit의 메인화면에 네모난 박스형태의  File Source 필터안에 여러분이 선택한 파일이름이 표시되어 나타날 것입니다. 

DShow SDK를 설치하셨다면 여러분은 이 소스필터의 원형을 직접 살펴보실 수가 있습니다.  

  ===>  C:\DXSDK\Samples\C++\DirectShow\Filters\Async

위 디렉토리에 가시면 File Source 소스필터의 C++ 소스를 만나보실 수가 있습니다. 풀모드 소스필터임에도 불구하고 상당히 복잡하게 되어있습니다. 

-------------------------------------------------------------------------------------------------
참고 => DirectShow SDK에 있는 샘플 필터의 소스를 살펴보시면 우선 무엇인지도 모를 엄청난 양의 소스에 질겁을  하게 될 것입니다. 이것은 어쩌면 당연한 일입니다. 왜냐하면 이곳에 놓인 필터들의 성격은 굉장히 범용적인 사용을  위한 준비로서 다양한 로직을 갖춰놓고 있기 때문입니다. 따라서 여러분이 필터의 기본적인 구조에 대한 이해도 없이 마구잡이로 이곳에 있는 필터들의 소스를 분석하고자 한다면, 그것은 참으로 어리석은 일이 될 것입니다.
참고로 제가 예전에 그랬었습니다. 그냥 죽기 아니면 까무러치기로 파고 들어가면 어차피 클래스고 함수일터인데 해석하지 못할까 싶었기 때문입니다. 그러나 감히 말씀드리자면 이것은 지도없이 낯선 도시를 헤메는 것과 같은 어리석음입니다. 만일 누군가 DShow 필터개발자가 옆에 있어서, 막힐때마다 친절하게 가르침을 배울 수 있는 환경이라면 모를까, 무턱대고 필터의 소스부터 프린트해서 해독하기 위해 밤새고 그러는 것은 전혀 바람직하지 않습니다.
------------------------------------------------------------------------------------------------

(7) File Writer

이 필터의 기능은 글자 그대로 입력된 스트림을 파일로 기록하는 기능을 하고 있습니다. 여러분이 GraphEdit로 필터를 생성시키면 위의 File Source 필터와 비슷하게 '파일저장 다이알로그 창'이 뜨게 됩니다. 물론 이렇게 윈도우가 뜨는것은 얼마든지 DShow 어플의 코딩상에서 내부적으로 처리할 수가 있습니다. 

자, 그런데 이 필터를 설명드리면서 앞에서 한가지 부족했던 부분에 대하여 보충설명을 드려야 하겠습니다. 앞의 서두에서 저는 Avi Mux 필터에 대하여 단순히 영상과 음성의 스트림을 '먹싱'처리하여 하나의 스트림으로 내보내는 역활을 한다고 하였습니다. 그러나 이때 단순히 두개의 데이타를 하나로 합쳐지게 만드는 것이 아니라, Avi 표준구조에 맞게 합쳐지게 한다는 것입니다. 즉, 가장 첫머리에 Avi 헤더가 붙고, 각각의 영상 프레임이나 음성 데이터 마다 식별코드와 파일 사이즈등의 정보들이 붙어 있게 된다는 것입니다.

제가 위와같은 보충설명을 드린 것은 다음과 같은 원인을 설명하고자 하기 때문입니다. 여러분이 만일 GraphEdit상에서 카메라입력장치를 하나 생성시키고, 그 다음에 File Writer를 생성시키고서, 이 두개의 필터를 직접 연결시킨다면, 아마도 '연결을 가능하게 하는 중간 필터를 찾을 수가 없습니다'라는 메시지가 뜨는 것을 보시게 될 것입니다. 즉 카메라 입력장치든지(광의의 필터) 혹은 위에서 언급한 파일소스필터와 파서필터가 붙은 상태에서의 파서필터이든지, 곧바로 File Writer필터를 붙일 수가 없다는 것입니다. 왜냐하면 지금까지 계속해서 강조해 왔듯이 양쪽의 미디어 타입이 일치가 되지 않기 때문이며, File Writer 필터의 입력핀쪽 미디어타입에서 서브타입으로 Avi형식을 요구하고 있기 때문입니다. 즉, 연결하려는 앞쪽의 필터에서 Avi의 완성된 미디어형 타입이 있어야 한다는 것입니다.

위와같은 상황이 이해가 잘 안되신다면, 그냥 일반적으로 File Writer 필터는 앞에 꼭 Avi Mux 필터가 붙어야 한다라고 생각해주시면 되겠습니다. 이것은 마치 위의 File Source(Async.) 필터의 뒤에는 반드시 Avi Splitter필터가 붙어야 한다는 것과 함께 쌍으로 염두에 두시면 좋을 것입니다. 

(8) Smart Tee  

Smart Tee 필터(이하 스마트티 필터)는 Video Renderer 필터 다음으로 DShow에서는 밥먹듯이 사용해야하는 중요한 필터입니다. 이 필터가 필요한 이유를 들어 보겠습니다. 우리가 카메라로부터 들어온 영상을 저장과 동시에 랜더링하고자 한다고 생각해 보십시오. 그렇다면 하나의 입력 스트림을 두개로 쪼개어 흘려 보내야 합니다. 즉, 필터에는 한 개의 입력핀과 두개의 출력핀을 갖되, 출력핀에서 나오는 각각의 동영상은 모두 동일해야 한다는 것입니다. 이것을 다음과 같이 Smart Tee 필터로서 그려보겠습니다. 


            Cam Fitler -> Smart Tee  -->  Video Renderer 
                                            └---->  Avi Mux -> File Writer 


위와같은 연결이 만들어질 것입니다. 위에서 스마트 티 필터는 입력으로 들어오는 한개의 스트림을 가지고 두개로 쪼개어 아랫쪽으로 흘려보내는 역활을 하고 있습니다. 이런 역활을 하는 필터가 없다면 여러분은 직접 이런 역활의 필터를 개발해야 했을 것입니다. DShow에서 스마트 티라는 필터를 미리 마련해 두었으니 우리는 사용만 하는 되는 것이곘죠. 

(9)  Infinite Pin Tee Filter

이 Infinite Pin Tee 필터는 위에서 언급한 Smart Tee 필터와 비슷한 역활을 하는 것입니다. 즉 하나의 입력스트림을  여러개의 출력으로 분배하는 것이죠. 그러나 여러분이 일단 이 필터를 GraphEdit 상에서 생성시키면 달랑 입력과 출력이 각각 1개뿐인 필터로 보여지실 것입니다. 이때 당황하지 마시고 출력핀을 어딘가로 연결시켜 보시기 바랍니다.

그러면 연결되자마자 곧 새로운 출력핀이 한개가 더 만들어 지는게 보이실 것입니다. 그렇습니다. 이러한 방식은 Avi Mux에서 입력핀이 계속 증가하는 것과 동일한 형태인 것입니다. 다시말해서 출력핀은 언제나 연결된 핏의 갯수보다 하나가 많은 상태로 유지가 된다는 것이죠. 이렇듯 Infinite Pin Tee 필터는 Smart Tee 필터와는 다르게 입력스트림을 무한하게 여러개의 출력으로 나누어 보낼 수가 있는 것입니다.  

자, 여러분은 이제 이 Infinite Pin Tee 필터 (일명 무한필터)를 사용하여 Smart Tee 필터처럼 사용할 수도 있습니다. 
즉 아래와 같이 연결할 수 있다는 말이 되겠습니다. 


            Cam Fitler -> Infinite Pin Tee  -->  Video Renderer 
                                             └---->  Avi Mux -> File Writer 
                                             └---->   //항상 연결된 핀갯수보다 하나가 더 많게 된다. 

 

Smart Tee 필터와   Infinite Pin Tee 필터의 역활은 비슷합니다. 하지만 우리는 어떨때 Smart Tee 필터를 사용하고 어떨때 Infinite Pin Tee 필터를 사용해야 하는지에 대해서도 알아야 합니다. 그러기 위해는 필터의 내부 특성을 알아야 하는데요,  여기서는 Help에 나온 사항을 참고하겠습니다.

스마트티는 하나의 입력핀을 단지 두개의 출력핀으로 나눌 뿐입니다. 하지만 각각의 핀에는 독특한 이름이 부여되는데요, 바로 Capture 핀과  Preview 핀이라는 이름입니다. 이 각각의 이름은 중요한 차이를 가지고 있습니다. 물론 사용법도 다르게 되겠지요. 일반적으로 Captuer핀에서 흘러나오는 스트림은 Avi Mux로 연결되어서 동영상을 저장하기 위한 용도로 사용됩니다. 그리고 Preview 핀에서 흘러나오는 스트림은 Renderer 로 향해서 랜더링되어 집니다. 

그런데 만일 이 두가지를 반대로 사용한다면 어떻게 될까요. 만일 여러분이 Capture 핀으로 랜더링을 하고 Preview 핀으로 저장을 한다면 GraphEidt는 에러메시지를 보내게 될 것입니다. 그 메시지에는 '타팀스탬프가 없습니다'라는 문구가 될 것인데요, 이것이 중요한 차이입니다. 즉 에러메시지가 발생한 이유는 Preview 핀에서 스트림을 저장하기 위해 연결한 Avi Mux 필터에서는 반드시 '타임스탬프'가 존재해야 하는데요,  Preview 핀에서 흘러나오는 스트림은 '타임스탬프'가 제거된 상태이기 때문입니다. 이거 왜 이럴까요?

동영상을 랜더링 하면서 동시에 실시간 Write 한다면 필터그래프에는 지연시간이라는게 발생하게 됩니다. 따라서 만일 Preview핀에서 흘러나오는 스트림에 타임스탬프가 존재한다면 지정된 시간에 프레임이 랜더링되지 못하고 드롭되고 마는데요, 이것은 상당히 부자연스러운 차이를 만들게 됩니다. 이처럼 랜더링 되어야할 프레임이 드롭되는 것을 막고자 Preview 핀에서 강제로 타임스탬프를 제거하여 내보내는 것입니다.

일반적으로 동영상을 저장과 동시에 랜더링을 하고자 할 때에는 위와같은 이유로 무한필터보다는 스마트 티 필터를 이용하기를 권장합니다. 장난삼아 무한필터로도 테스트해 보곤 하는데요, 별차이는 없어 보였습니다. 하지만 헬프에 그렇게 나와 있으므로 굳이 무한필터를 사용하지는 마시기 바랍니다. 

++ 타임스탬프 ++
-------------------------------------------------------------------------------------------------

타임스탬프라는 것에 대해서 잠시 설명 드리겠습니다. 타임스탬프는 하나의 미디어물이 최종적으로 랜더링 되어야하는 StartTime과 EndTime을 의미합니다. 예를 들어 우리가 DShow 어플을 Play하면 그 순간부터 절대시간이 생성되어집니다. 0초, 1초, 2초, 3초... 이렇게 말이죠. 이런 상태에서 연속된 프레임에서 각각의 프레임마다 언제 랜더링되어져야 하는지를 가지고 있습니다. 만일 초당 30프레임이라면 가장 첫번째 프레임의 타임스탬프 시간은  StartTime 이 0 이 될 터이고, EndTime이 30/1000 초가 될 것입니다. 두번째 프레임은 어떻게 될까요.이것을 다음과 같이 나타내 보겠습니다.

                1번째 프레임    StartTime     0초             EndTime  0.03초
                2번째 프레임    StartTime     0.03초         EndTime  0.06초
                3번째 프레임    StartTime     0.06초         EndTime  0.09초
                4번째 프레임    StartTime     0.09초         EndTime  0.12초
                        .                    .                                     .
                        .                    .                                     .  

위와 같이 각 프레임마다 StartTime 과 EndTime을 가지고 있다는 것이죠. 그런데 간혹 이것들이 여러개의 필터들을  거치면서 제시간에 도착하지 못하는 경우가 발생될 때가 있습니다. Smart Tee 경우와 함께 일반적으로 네트워크 필터에서도 이런 경우가 발생하여, 저같은 경우도 마지막에는 결국 타임스탬프를 제거해야만 했습니다.

사실 네트워크 소스필터의 경우에는 Smart Tee와 같은 이유 때문에 타임스탬프를 제거한 것이 아니라, 전송지와 수신지와의 동시성을 위해서 어쩔 수없는 선택이었습니다. 예를 들어, 전송지에서 TCP/IP를 통해 서버로 하나의 프레임을 전송했다면 수신지에서는 다시 그 서버에서부터 하나의 프레임을 받아올 것입니다. 그런데 어떤 경우는 통신이 느려졌다가 갑자기 빨라질 경우가 생기는데, 이 경우 전송지의 소켓버퍼와 서버의 버퍼에 그동안 밀려서 쌓여있던 프레임이 한꺼번에 전달되기 때문에 문제가 발생 합니다. 만일 타임스탬프가 존재하고 순식간적으로 한꺼번에 밀려들어온 각각의 프레임에 일정시간을 동일하게 배분 한다면 전송지와 수신지와의 랜더링시간은 계속해서 차이가 벌어지게 될 것입니다. 저는 약 1시간 가까이 딜레이 되는 것을 지켜봐야 했습니다. 참으로 놀라운 딜레이 현상이었습니다.


출처 : 델마당  dong님의 글(dongsoft)

posted by 유돌이
2009. 1. 5. 18:11 델파이

지금까지 우리는 간단한 USB 카메라용 DShow 어플을 제작하였습니다. 너무도 간단한 것이었지만 이해하기가 쉽지는 않았을 터인데요, COM에 대해서는 좀더 체계적인 공부를 하라고 권해 드리고 싶습니다. 자, 이번장 부터는 DShow 의 필터에 대하여 공부해 보겠습니다. 우리는 필터들의 내부구조를 조금씩 들여다보고, 그 각각의 역할과 의미를 짚어본 다음에 DShow에서 제공하는 몇몇 기본 필터들에 대하여 공부할 것입니다. 이 지식들을 활용하여 전장에서 실습하였던 USB 카메라의 랜더링 프로그램을 수정하여 간단하게 AVI 파일로 저장하는 것과 중간의 프레임에서 원하는 이미지 사진을 뽑아내는 기능을 추가할 것입니다. 

[1] DShow 필터의 역할과 구조. -- (소스필터)   

우리는 지난회에서 DShow의 버퍼공유에 대하여 언급하였습니다. DShow에 있어서 버퍼공유가 얼마나 중요한 가에 대해서는 그당시 적절하게 설명을 하였다고 생각합니다. 그렇다면 이제 버퍼공유의 내부적인 원리를 약간 살펴보고  넘어가야 할듯 싶습니다. 이 원리는 중요성에 비하여 그리 거창하게 복잡한 것은 아닙니다. 아주 간단한 예를 들어 보겠습니다. 우리가 압축안된 AVI라는 파일을 TFileStream이라는 객체를 통하여 로딩하였다고 생각해 봅니다. 그리고 로딩한 파일에서 한 프레임에 해당하는 버퍼를 일정시간마다 읽어봅니다.
 
procedure TForm1.Run_ButtonClick(Sender: TObject);
var
  FileStm : TFileStream;
  Buff : PChar;
begin
  FileStm := TFileStream.Create('C:\무압축다이하드.avi', fmOpenRead );
  GetMem(Buff, 320*240*3);  //320 * 240의 크기에 RGB24라면...

  while FileStm.Position < FileStm.Size do
  begin
    FileStm.Read(Buff^,320*240*3);    //파일에서 하나의 프레임을 읽어낸다.
    Transfer(Buff);                             //Transfer 함수로 버퍼의 포인터만 보낸다. 
    Sleep(33);                                   // 1초당 30개의 프레임이라고 가정한다.
  end;

  FreeMem(Buff);
  FileStm.Free;
end;

 
procedure TForm1.Transfer(var Buff: PChar);
begin
  //비디오 프레임을 변환시킬 일이 있다면 변환시킨다.
  Renderer(Buff);
end;

 
procedure TForm1.Renderer(var Buff: Pchar);
begin
   //Buff로 랜더링을 한다.
end;

 

만일 DShow의 COM Object구조가 아닌, 일반 어플에서 시도를 했다면 위와 같은 구조를 생각해 볼수가 있을 것입니다. (실제로 적용한다면 AVI파일의 헤더를 읽는 부분과 위의 Renderer 함수에서 비디오 카드의 DirectDraw평면을 가져와서 그곳에 데이터를 옮기는 작업을 하게될 것입니다.) 자, 위의 프로그램은 아주 간단합니다. 압축안된 AVI 파일을 읽어서 그것을 일정시간 간격으로 계속해서 두개의 함수, Transfer과 Renderer 함수를 실행시킨다는 것입니다. 

상식적으로 위의 모든 과정은 하나의 함수안에 포함시킬 수가 있습니다. 필터도 마찬가지입니다. 우리가 소스필터나  변환필터나 랜더러필터도 각각 그 역할을 나눠놓는 것이 사용하기 편하기 때문에 한것이지, 굳이 구조적으로 반드시  그렇게 해야할 이유는 없다는 것입니다. 그렇다면 우리는 하나의 의문이 생깁니다. DShow는 버퍼공유가 중요하다고 했는데, 아니 하나의 필터에 몽땅 집어 넣을수가 있다면 굳이 버퍼공유라는 이유 때문에 복잡한 여러종류의 필터를 연결해서 사용해야만 하는 이유는 무엇인가.  

우리가 Visual C++을 한다는 것은  MFC를 사용한다는 것과 마찬가지이고, 델파이를 한다는 것은 VCL을 사용한다는 것과 마찬가지이듯이, DShow를 한다는 것은 결국 기본적으로 제공되는 수많은 DShow의 필터를 이용할 수 있다는 것과 동일한 의미일 것입니다. 즉, 'DShow는 버퍼공유를 위해서 필터형식으로 되어있다'는 것이 아니라, '동영상 어플 개발에 있어서 다양한 필터형식의 서비스를 제공함에도 불구하고 버퍼공유를 한다'는 의미로 받아들여야 할 것입니다. 

DShow에는 다양한 종류의 기본필터가 준비되어 있습니다. 이들 필터를 사용한다는 것은 어플개발을 손쉽게 할 수 있다는 의미 이외에도 윈도우즈라는 운영체제에 있어서 범용인 동영상 어플을 개발할 수 있다는 의미도 있을 것입니다.

다양한 필터형식의 범용적인 서비스를 제공하면서 동시에 하부구조 깊숙히 자리잡은 버퍼공유를 함으로서 동영상 개발을 획기적으로 진보시켰다고 볼수가 있을 것입니다. (그러나 배우기는 어렵다는 거... 쩝.)

Anyway... 이제 다시 본론으로 들어가겠습니다. 위의 예제샘플 프로그램에서 우리는 동영상 어플개발의 기본적인 구조를 살펴볼 수가 있습니다. 파일을 로딩하고, 그것을 루프를 돌려서 한 프레임씩 읽어내고, 읽어낸 것을 변형하고 랜더링한다는 것입니다. 눈치 채셨겠지만, 각각의 함수들은 모두 DShow에서 각각의 필터들의 역할을 대변하고 있습니다. 즉, 파일을 로딩하여 루프를 돌리는 첫 프로시저는 '소스필터'를 의미하고 두번째 Transfer는 말 그대로 변환필터를 의미하며 마지막으로 Renderer함수도 랜더러필터를 의미할 것입니다.  

자, 그런데 소스필터에 있어서는 약간 다르게 구조화되는 경우를 생각해 볼수가 있습니다. 즉, 로딩하는 부분과 루프를 돌려서 한 프레임씩 읽어내는 경우를 별도의 필터로 만드는 것인데요, 이렇게 별도의 필터로 나누어 만드는 방식을 풀모드라고 하고, 하나의 필터에 로딩과 루프를 모두 갖춘것을 푸쉬방식이라고 합니다.
여기서 루프는 사실 스레드를 의미한다고 생각하시면 될 것입니다. 또한 두개의 부분으로 나뉘었을때 앞의 필터를 풀모드의 소스필터라고 하며 뒤의  필터를 '파서 필터'라고 합니다. 푸쉬 소스필터 하나를 굳이 풀모드 소스필터와 파서필터로 나누어 놓는 것은 DShow 가 각부분의 필터 서비스를 좀더 세밀하게 제공하기 위함이라고 생각하시면 될 것입니다.  

소스필터를 너무 간단히 설명드렸지만, 사실 소스필터는 무지하게 복잡한 구조를 가지고 있습니다. 우선 이것은 수 없이 다양한 Avi파일의 표준구조를 읽어내야하고, 음성과 영상의 프레임을 각각 뽑아내어 동기화작업도 해야합니다. 또한 네트워크를 통해서 들어올 경우에는 소켓을 포함하여 그에 따른 로직이 준비되어 있어야 할 것입니다.
DShow 의 필터 개발자들이 우선 첫번째로 경험삼아 개발하는 것이 변환필터이고, 그 다음으로는 바로 이 네트워크 소스필터인데요 제가 처음에 말씀드렸던 신화선님의 사이트에 가시면 '네트워크 소스필터'로 인하여 울부짓는 질문들이 상당수 있을 것입니다. 네트워크 소스필터가 어려운것은 소켓 프로그래밍 때문이 아니라, 영상과 음성의 싱크문제, 각각의 스레드의 동기화 문제, 버퍼링 문제와 같은 것들입니다. 이들 모두가 소스필터에 해당한다고 보시면 될 것입니다.  


이번에는 파서필터를 직접 만나시겠습니다. 여러분이 만약 GraphEidt로 인터넷에서 다운받은 영화를 Render Media File...이라는 메뉴로 불러오셨다면 메인화면에는 수없이 많은 필터들이 연결되어 있는 것을 보실수가 있을 것입니다.
그 여러종류의 필터들 중에 유독 하나의 필터에서 두개의 Out핀이 나온것을 보실 수가 있는데요, 요놈이 바로 파서필터입니다. 이름은 아마도 'Avi Splitter'라고 적혀 있을 것입니다. 이 Avi Splitter이라는 놈은 결코 우수운 놈이 아닙니다.
 
위에서 설명드린 것처럼 수없이 다양한 Avi파일의 표준구조를 읽어내고 영상과 음성의 프레임을 각각 동기화시켜서 스레드로 푸쉬(다른 필터로 밀어내기)하고 있는  것입니다. 

지금까지 정리하자면 다음과 같습니다. 

  1) 소스필터는 두가지 종류가 있는데, 하나는 푸쉬모드 소스필터이고 다른 하나는 풀모드 소스필터이다. 
  2) 푸쉬모드 소스필터는 영상파일을 로딩하는 것과 스레드 안에서 각 프레임을 뽑어내는 기능 모두를 포함한다. 
  3) 풀모드 소스필터의 경우는 영상파일을 로딩하는 기능만을 가지고 있으며 뒤에는 스레드로 각 프레임을 뽑아내는 기능을 하는 '파서필터'가 별도로 붙는다.  

[2] DShow 필터의 역할과 구조. -- (변환필터)   

이제 변환필터에 대해서 말씀드리겠습니다. 아마도 여러분이 가장 원하시는 종목이 바로 변환필터 만들기 일 것입니다. 일단 이 변환필터를 만드는 데에는 크게 두가지의 경우가 있습니다. 첫째로, 소스필터에서 시작된 영상의 형식을 그대로 두고 버퍼의 내용만 바꾸는 것과, 둘째로 영상의 형식과 내용 모두를 바꿔치기하는 방식입니다. 전자의 것을 InPlace 변환필터라고 하고 후자의 것을 Copy 변환필터라고 합니다. 자, 이 두개가 무슨 의미가 있는지를 설명하겠습니다. 

우리가 앞의 필터에서 흘러나온 스트림을 변환시키기 위해서는 뒤로 흘려보낼 경우까지 모두 고려해야 할 것입니다.
만일 앞의 영상이 YUV의 형태였고, 뒤쪽으로 흘려보내야하는 영상이 RGB24라면 어떻게 될까요. 이경우 어쩔 수 없이 한번의 버퍼링을 반드시 해야할 것입니다. 왜냐하면 뒤쪽의 타입에 맞게 변경해줘야 하기 때문이지요. 그러나 앞과 뒤의 영상타입이 정확히 일치한다면 우리는 굳이 버퍼링을 할 필요가 없습니다. 이 경우 필터는 앞의 필터에서 사용되어진 버퍼의 포인터를 그대로 가져와 사용할 수가 있는 것입니다. 
 
동영상 스트림의 형태는 상당히 까다롭습니다. 이 형태를 '미디어형'이라고 하는데요, DShow를 하기 위해서는 반드시 이 '미디어형'의 전체 구조가 머릿속에 들어가 있어야 합니다. 이것에 대한 의미를 정확히 안다면 필터개발에 있어서 반이상을 정복하셨다고 해도 과언이 아닐 것입니다. 그런데 이 미디어형을 알기 위해서는 각각의 미디어타입의 의미를 또한 알고 있어야 합니다. 예를 들어 대체 YUV는 무엇인가에 대한 해답을 가지고 있어야 한다는 것입니다. 

간단하게 YUV에 대해서 설명해보겠습니다. 우리가 일반적으로 색을 표현할 때에는 Red, Green, Blue 이렇게 세가지의 색을 조합해서 표현하는 RGB 방식을 흔히 사용합니다. 그런데 이 방식은 Image로 표현하는데 있어서는 상당히 정확한 방식이지만, 반면에 인간이 느끼지 못하는 부분까지 구분하고 있기 때문에 정보의 취급 효율면에서는 떨어집니다. 그 효율이 아주 작은 차이라고 하더라도 동영상에서는 무시하지 못할 엄청난 차이가 됩니다. 따라서 동영상에서는 주로 이 RGB 계열의 형식을 사용하지 않습니다. 대신 색의 밝기인 Y성분과 색상인 U와 V성분으로 조절되어지는 YUV 형태를 주로 사용합니다. 이 방식을 사용하는 이유는 효율이 상당히 크기 때문입니다.
일반적으로 인간의 시각은 명도에 민감하고 색상에는 별로 민감하지 않습니다. 예를 들어 320*240 크기의 프레임 이미지라면 명도에 해당하는 Y부분을 320*240 크기로 1바이트씩 배정해 놓고 나머지 색상에 해당하는 U와 V는 각각 네 개마다 하나씩 공유 하게 되어도 큰 문제가 없다는 것이죠.    


      y           y             y            .             .              .

           uv          uv

      y           y             y

 
 
      .

 

자, 위와 같은 경우 이미지의 크기는 반으로 줄어들게 됩니다. RGB의 경우, 픽셀당 각각 1바이트 씩을 차지하므로 모두 3바이트였다면, 위와같은 형식의 YUV인 경우에는 각 픽셀당 Y가 1바이트, UV가 0.5바이트를 차지하게 되므로 전체 메모리는 반으로 줄어들게 되는 것입니다. 그런데 아이러니한 것은, 이렇게 정보의 크기가 반으로 줄어들었음에도 불구하고 RGB의 경우보다 오히려 더 선명하게 느껴진다는 것입니다. 이것은 일종의 착시현상으로 픽셀과 픽셀간의 색차 정보가 흐려지는 결과로 빚어지는 것입니다. 

위의 YUV의 형태를 인식하는 것은 중요한 첫 걸음입니다. YUV의 형태는 실제 다양한데요, 24비트로 된 것도 있고, 16 비트나 12비트, 심지어 8비트로 된 것도 있습니다. 그러나 가장 중요한 것은 이것을 사용했을때의 효능입니다. RGB에 비하여 엄청난 결과를 가져옵니다. 즉, 영상의 화질은 더 부드럽고(비록 착시현상이지만...)  CPU의 점유율은 거의 절반으로 떨어지기 때문입니다. 모든 영화 파일의 기본압축 미디어형이 바로 이 YUV형식 인것도 바로 이 때문인 것입니다. ( 일부를 제외하고 거의 모든 Mpeg의 압축을 위해서 들어가는 기본 형태는 RGB가 아닌 YUV형식이다. 반대로 그 압축된 데이터가 DeCoder 필터를 통해 압축 해제되어 나오는 미디어의 기본 형태도 바로 YUV형식중 하나이다.)

혹 어느 책에서는 YUV가 일종의 압축형태라고 표현하는 곳도 있는데요, 이것은 엄밀히 말하자면 틀린 말입니다. 하지만 그럼에도 불구하고 'YUV로 압축된 형태로 들어옵니다.'라고 표현하는 것은 절반의 데이타 양으로 거의 동일하게 표현하는 효율적인 측명을 지나치게 강조한 것이라고 할 수 있을 것입니다. 아무튼 YUV 이것을 아는게 중요합니다. 나중에 여러분이 필터를 만들게 되면 이 YUV를 직접 눈으로 보실수가 있게 됩니다. 저도 한번 샘플로 YUV를 RGB인 척 하고 랜더링한 적이 있는데요. 다음과 같은 모양이 나왔습니다. 


                  ************************************************
                  ************************************************
                  ************************************************
                  ***********************■************************
                  ***********************■************************
                  ***********************■************************
                  *********************■***■*********************
                  ********************■*****■********************
                  *******************■*******■*******************
                  ******************■*********■******************
                  ************************************************
                  ************************************************
                  ************************************************
                  ************************************************
                  ************************************************


                  ************************  ***********************
                  ***********■***********  **********■************
                  ***********■***********  **********■************
                  **********■*■**********  ********■**■**********
                  *********■***■*********  *******■****■*********
                  ************************  ***********************
                  ************************  ***********************


위에서 보시면 알겠지만, 가장 첫번째 큰 이미지가 Y값을 가진 전체 화면이 되겠고요, 나머지 두개의 작은 이미지가  각각 4개의 Y값에 대응하는 U와 V의 값들이 모여있는 화면입니다. 실제로 버퍼에 이런 식으로 저장이 되어 있는 것을 보고 정말 재미있어 했습니다.  

이야기하다보니 또 샛길로 빠졌습니다. 강의의 깊이를 조절하기가 정말 힘이 드네요. 이번 장에는 무려 5번의 새로쓰기를 하였습니다. 제 나름대로 전체적인 구조를 잡은 상태에서 진행하고 싶었는데요, 지나친 욕심이었나 봅니다. 아무튼 이번장이 중요한 것은, COM 다음으로 DShow의 배경지식이 되기 때문입니다.

변환필터에 대해서 이야기하였는데요, 두가지 형식이 있다고 하였습니다. 하나는 InPlace 변환필터, 일명 제자리 변환 필터라고 불리기도 하고요,  Copy 변환필터, 일명 복사 변환필터라고 합니다. 이 두개의 형식의 가장큰 차이는 전자의 것은 버퍼링이 없다는 것이고요, 후자의 것은 반드시 한번 이상의 버퍼링이 존재한다는 것입니다. 사실 Copy 변환필터가 내부적으로 버퍼링을 해야한다는 것은 당연한 일입니다. 앞에서 들어온 스트림의 미디어형이 뒤쪽으로 나가는 미디어형과 일치하지 않기 때문에, 그 형변환을 위해서는 버퍼링이 필요하고, 버퍼링을 하기 위해서 Copy 변환필터라는 구조가(COM Class가) 만들어진 것이기 때문이지요. 

지금까지의 설명을 종합하겠습니다. 

   1) 변환필터에는 InPlace 형과 Copy 형 두가지가 있다.
   2) InPlace형은 내부 버퍼링이 필요없고, 앞의 필터의 버퍼 포인터를 그대로 사용한다.
   3) Copy 형은 반드시 버퍼링이 필요하고, 앞의 InPut 미디어형과 뒤쪽의 OutPut 미디어형이 일치하지 않을때 사용한다. 
   4) DeCoder 압축해제필터는 일종의  Copy형 변환필터이다.
------------------------------------------------------------------------------------------------
추가해설 --> 엄밀히 이야기하자면 InPlace형 변환필터도 내부 버퍼링을 합니다. 그러나 위에서 내부 버퍼링이 필요없다고 한것은 이해의 편리를 위한 것이라고 생각하시면 될 것입니다. 좀더 정확히 표현하자면 'InPlace필터는 버퍼링을 최대한 하지 않아도 되게끔 지원한다.'는 표현이 맞을 것입니다. 자, 이것에 대해서는 후에 '할당자'를 설명하면서 논하게 될지도 모르겠습니다. 하지만 워낙 Inplace 필터의 구조가 복잡해서, 충분히 설명할 수 있을지 모르겠습니다. 

시간이 있으면 나중에 필터제작하는 시간에 '할당자'에 대한 부연설명을 하면서 보충할 수도 있을 것이지만, 아무튼 현재로는 'InPlace 필터는 내부 버퍼링을 가능한한 줄여주기 위해 지원한다' 는 정도로 이해하시면 좋을 것입니다.


출처 : 델마당  dong님의 글(dongsoft)

posted by 유돌이
2009. 1. 5. 18:09 델파이
지난 8부에서 우리는 비로소 TBaseDShow 클래스를 완성하였습니다. 이제 우리는 DShow용 어플의 기본적인 것을 모두 소화해 낸 것입니다. 이제부터는 노가닥성 코딩이라고 보아도 되겠습니다. TBaseDShow 를 이용하여 필터를 만들고 연결하고 실행하면 되는 것입니다. 이제 TBaseDShow에서 상속받아서 이 나머지 구체화 부분에 해당하는 클래스를 만들겠습니다. 현재 우리는 USB용 카메라를 동작시키기 위한 DShow용 어플을 제작하고 있으므로 이 클래스의 이름을 TCamDShow라고 하겠습니다.

우선 아래와 같은 클래스의 원형을 보시겠습니다. 

type
  TCamDShow = class(TBaseDShow)
  private
    Cam:               IBaseFilter;
    VideoRender:  IBaseFilter;
  protected
  public
    constructor Create(Screen:TPanel);
    destructor Destroy;override;
    function MakeBaseFilter:HRESULT;
    function ReleaseBaseFilter:HRESULT;
    function ConnectBaseFilter:HRESULT;
    procedure Run;
    procedure Stop;
  end;


자, 위의 클래스 원형에서 필터가(IBaseFilter형 타입의 변수) 달랑 두개 뿐이 없는 것을 보실수가 있습니다. 바로 Cam 과 VideoRender 입니다. 이 두개의 필터를 생성하고 연결해 주어야 합니다. (DShow 용 어플 제작에 있어서 필터라는 것은 IBaseFilter 형 타입의 변수를 의미 한다고 보시면 되겠습니다. 그러나 일반적으로 필터라 함은 COM Obejct  객체 자체를 말하는 것이라 생각해야 할 것입니다.). 위에서는 단지 두개뿐이지만 좀 복잡한 어플에서는 훨씬 많은 수의 필터들이 존재하고 있을 것입니다. 지금은 간단한 실습용이기 때문이라고 생각해 주세요.

위에서 두개의 필터와 함께 세개의 함수가 보이실 것입니다. 세개의 함수중 두개는 이름만으로도 이해하기가 쉬우실 것입니다. 즉, MakeBaseFilter는 각각의 필터를 만드는 곳이고,  ConnectBaseFilter는 각각의 필터를 연결하는 장소입니다. 그런데 ReleaseBaseFilter라는 함수는 무엇일까요. 이 함수는 필터들을 해제하기 위한 것입니다.  이것은 그냥 TCamDShow 객체의 소멸자에 해당 로직을 몽땅 몰아 넣어도 상관은 없습니다만, 사용의 편리성을 위해 별도로 준비한 것입니다.

마지막으로 한가지 더 눈여겨 보셔야 할 부분이 있습니다. 그것은 함수의 리턴타입입니다. HResult 라고 되어 있는데요, 이것은  DShow에서 밥먹듯이 사용해야 할 리턴타입니다. 현재 위에서 세개의 함수들이 굳이 HResult 형의 리턴 타입을 사용하지 않아도 상관은 없습니다만, 일부러 이렇게까지 한것은 이러한 관습에 익숙해지면 편리하기 때문입니다.
DShow를 넘어서 COM의 모든 인터페이스의 리턴타입이 바로 HResult입니다. 그렇기 때문에 HResult에 조금이라도 일관성을 유지하면서 익숙해진다면 좋기 때문입니다.  S_OK, S_False 이런 결과 값들을 기본으로 생각하고 있어야 할 것입니다.

자, 이제 생성자와 소멸자를 살펴보겠습니다.

constructor TCamDShow.Create(Screen: TPanel);
begin
  inherited Create;
  MakeBaseFilter;
  ConnectBaseFilter;
  VideoWindow.put_Owner(OAHWND(Screen.Handle));
  VideoWindow.put_WindowStyle(WS_CHILD or WS_CLIPSIBLINGS);
  VideoWindow.put_Width(320);
  VideoWIndow.put_Height(240);
  VideoWindow.put_Top(0);
  VideoWindow.put_Left(0);
end;

 
destructor TCamDShow.Destroy;
begin
  ReleaseBaseFilter;
  inherited Destroy;
end;


소멸자는 간단합니다. 위에서 말씀드린 것처럼 사용된 필터들을 해제하는 로직을 포함해야 하는데요, 이것을 별도의 ReleaseBaseFilter라는 함수에 넣어둔 것일 뿐입니다. 이제 생성자를 한번 보겠습니다. Inherited 아래의 문구에서 처음으로 필터를 생성하고(MakeBaseFilter함수) 그 다음으로 필터를 연결하고(ConnectBaseFilter 함수) 있습니다.

그런데 그 아래에 약간 특이한 코드가 보이는데요. 이것은 전에 말씀드렸듯이 TBaseDShow에 있는 필터그래프의
IVideoWindow 인터페이스를 사용한 것입니다. 이 인터페이스를 사용하여 비디오가 랜더링되는 창을 폼위의 어느곳 이든지 지정할 수가 있다고 설명을 드린적이 있는데요, 바로 이 코드가 그것입니다. TCamDShow 클래스의 생성자 매개변수를 TPanel형 타입으로 받아서 이것을 일종의 랜더링 스크린으로 사용하고 있습니다.

자, 이제 필터를 생성하는 함수를 보겠습니다. 함수는 아래와 같습니다.

function TCamDShow.MakeBaseFilter: HRESULT;
begin
  Result := S_OK; 

  Cam := GetCamFilter;
  FilterGraph.AddFilter(Cam,'Cam Filter'); 
  if Cam = nil then Result := S_FALSE;

 
  CreateFilter(CLSID_VideoRenderer,VideoRender);
  FilterGraph.AddFilter(VideoRender,'VdRenderFilter');
  if VideoRender = nil then Result := S_FALSE;

 
  if Result = S_FALSE then ShowMessage('MakeBaseFilter is Failed');
end;


위에서 보시면 아시겠지만 필터를 생성하자마자 필터그래프에 등록하고(혹은 Add하고) 있습니다. 단지 두개의 필터만이 사용되었기 때문에 현재는 상당히 간단해 보이지만, 사실 이 함수에는 나중에 각각의 필터들 고유의 또다른 인터페이스를 얻어내는 장소가 되기도 할 것입니다. 아무튼 중요한 것은 필터를 생성하고 필터그래프에 등록하였다는 사실입니다.  

위의 함수에서 조금 더 부언 설명을 드려야 하겠습니다. 카메라를 생성시킬때 사용한 GetCamFilter 라는 함수는 전장에서 TBaseDShow 클래스에서 소개한 적이 있었습니다. 그런데 사실 일반적으로 이렇게 Fixed하게 만들어 놓지는  않습니다. 보통 카테고리에서 특정한 장치(혹은 광의의 필터)를 얻어오기 위함 범용 함수를 만들어 놓고 사용하는데요
여기서는 이해의 편리를 위해 직설적으로 GetCamFilter라는 이름으로 간단하게 구성하게 된 것입니다. 

CreateFilter라는 함수는 기억하실 것입니다. 이것은 필터그래프를 생성하는 함수와 거의 동일하기 때문에 COM Object를 생성하는 범용함수를 만들어 놓고 사용해도 된다는 식의 설명을 드린적이 있을 것입니다. 자... 여기까지 이해가 어느정도 되셨을 것이라고 생각하겠습니다. 이제 두개의 필터를 연결하는 함수를 보시겠습니다.

function TCamDShow.ConnectBaseFilter: HRESULT;
var
  InPin : IPin;
  OutPin : IPin;
  hr : HRESULT;
begin
  Result := S_OK;
 
  FindPinOnFilter(Cam,PINDIR_OUTPUT,OutPin);
  FindPinOnFilter(VideoRender,PINDIR_InPUT,InPin);
  hr := FilterGraph.Connect(OutPin,InPin);
  if hr <> S_OK then Result := S_FALSE;
 
  OutPin := NIL;
  InPin := NIL;
 
  if Result = S_FALSE then ShowMessage('ConnectBaseFilter is Failed');
end;

위의 함수도 내용은 간단합니다. 두개의 필터 각각의 InPin과  OutPin 인터페이스를 얻어서 필터그래프로 하여금 두개의 핀을 연결시키게 하고 있습니다. 이때 FindPinOnFilter 함수는 여러분이 전장에서 TBaseDShow에 기술한 바로 그 함수입니다. FindPinOnFilter 매개변수로는 필터의 IBaseFilter 인터페이스형 변수와 핀의 방향, 그리고 마지막으로 받아낼 핀의 인터페이스형 변수가 되겠습니다. 

한가지 의문이 들수도 있을 것입니다. 위에서는 단지 두개의 필터를 연결시켰지만, 수많은 필터들을 연결시킬때에는 어떻게 할까하는 점입니다. 위의 코딩을 계속 반복해 나가면 얼마든지 필터를 연결시킬 수가 있습니다. 즉 순서대로  출력에서부터 최종 랜더링까지,  앞 필터의 출력핀을 얻고 뒷필터의 입력핀을 얻어서 연결하고, 다시 뒷필터의 출력핀을 얻고, 그 뒤뒤필터의 입력핀을 얻어서 연결하고... 이렇게 반복될 것입니다. 이 부분에 대해서는 뒤에서 동영상 파일의 랜더링 부분에 가서 구경하실 수가 있으실 것입니다.

이제 마지막으로 필터들을 소멸시키는 함수를 보시겠습니다.


function TCamDShow.ReleaseBaseFilter: HRESULT;
begin
  if Assigned(MediaControl) then MediaControl.Stop;
 
  FilterGraph.RemoveFilter(Cam);
  FilterGraph.RemoveFilter(VideoRender);
 
  While Assigned(Cam)             do Cam := nil;
  While Assigned(VideoRender)     do VideoRender := nil;
 
  Result := S_OK;
end;


위에서 필터들을 해제하기 바로 전에 필터그래프가 자신에게 등록되었던 필터들을 ReMove시키고 있는 것을 보실 수가 있습니다. 이것을 반드시 해두시라고 말씀은 못드리겠지만 해두시는 게 좋습니다.
자, 필터를 해제하는데 While문을 사용한 이유에 대해서는 전장에서 설명을 드렸으니, 여기서 다시 설명하지는 않겠습니다. 

마지막으로 우리는 두개의 함수, 즉 Run 과 Stop 함수를 보셔야 겠는데요, 이것은 아주 간단한 것입니다. 아래를 보시겠습니다. 
procedure TCamDShow.Run;
begin
  if Assigned(MediaControl) then MediaControl.Run;
end;
 
procedure TCamDShow.Stop;
begin
  if Assigned(MediaControl) then MediaControl.Stop;
end;

위에서 보시면 아시겠지만 MediaControl 인터페이스의 Run과 Stop 메소드를 사용하고 있습니다. MediaControl 는 필터그래프에서 얻은 인터페이스라고 설명을 드렸을 것입니다. 이제 모든것이 정리되었습니다. 완전한 풀 소스를 아래와 같이 보시겠습니다. 

unit cCamDShow;
interface
uses
  Windows, Dialogs, SysUtils, Classes, Registry, DirectShow9, ActiveX, ExtCtrls, DsUtil, cBaseDShow;

 
type
  TCamDShow = class(TBaseDShow)
  private
    Cam:          IBaseFilter;
    VideoRender:  IBaseFilter;
  protected
  public
    constructor Create(Screen:TPanel);
    destructor Destroy;override;
    function MakeBaseFilter:HRESULT;
    function ReleaseBaseFilter:HRESULT;
    function ConnectBaseFilter:HRESULT;
    procedure Run;
    procedure Stop;
  end;

 
implementation
 
 
{ TCamDShow }

 
constructor TCamDShow.Create(Screen: TPanel);
begin
  inherited Create;
  MakeBaseFilter;
  ConnectBaseFilter;
  VideoWindow.put_Owner(OAHWND(Screen.Handle));
  VideoWindow.put_WindowStyle(WS_CHILD or WS_CLIPSIBLINGS);
  VideoWindow.put_Width(320);
  VideoWIndow.put_Height(240);
  VideoWindow.put_Top(0);
  VideoWindow.put_Left(0);
end;

 
destructor TCamDShow.Destroy;
begin
  ReleaseBaseFilter;
  inherited Destroy;
end;

 
function TCamDShow.MakeBaseFilter: HRESULT;
begin
  Result := S_OK;
  Cam := GetCamFilter;   //카메라를 얻고...
  FilterGraph.AddFilter(Cam,'Cam Filter');  //카메라를 등록한다.
  if Cam = nil then Result := S_FALSE;
  CreateFilter(CLSID_VideoRenderer,VideoRender);  //비디오 랜더러를 얻고...
  FilterGraph.AddFilter(VideoRender,'VdRenderFilter'); //비디오 랜더러를 등록한다.
  if VideoRender = nil then Result := S_FALSE;
  if Result = S_FALSE then ShowMessage('MakeBaseFilter is Failed');
end;

 
function TCamDShow.ConnectBaseFilter: HRESULT;
var
  InPin : IPin;
  OutPin : IPin;
  hr : HRESULT;
begin
  Result := S_OK;
  FindPinOnFilter(Cam,PINDIR_OUTPUT,OutPin);     //Cam에서 첫번째 출력핀을 얻어낸다.
  FindPinOnFilter(VideoRender,PINDIR_InPUT,InPin); //랜더러에서 첫번째 입력핀을 얻어낸다.
  hr := FilterGraph.Connect(OutPin,InPin);       //필터그래프가 두개의 핀을 연결한다.
  if hr <> S_OK then Result := S_FALSE;
  hr := S_OK;
  OutPin := NIL;
  InPin := NIL;
  if Result = S_FALSE then ShowMessage('ConnectBaseFilter is Failed');
end;

 
function TCamDShow.ReleaseBaseFilter: HRESULT;
begin
  if Assigned(MediaControl) then MediaControl.Stop;
  FilterGraph.RemoveFilter(Cam);
  FilterGraph.RemoveFilter(VideoRender);
  While Assigned(Cam)             do Cam := nil;
  While Assigned(VideoRender)     do VideoRender := nil;
  Result := S_OK;
end;

 
procedure TCamDShow.Run;
begin
  if Assigned(MediaControl) then MediaControl.Run;
end;

 
procedure TCamDShow.Stop;
begin
  if Assigned(MediaControl) then MediaControl.Stop;
end;
end.  

자, TCamDShow 클래스를 사용하는 방법은 너무도 간단합니다. 델파이에서 빈프로젝트를 하나 시작합니다.
메인폼위에 Panel 하나와 버튼 두개를 올려놓습니다. 그리고 버튼의 클릭 이벤트에서 각각 다음과 같이 코딩해 놓습니다.

unit uMain;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, cCamDShow, StdCtrls, ExtCtrls;
 
type
  TfrmMain = class(TForm)
    Panel1: TPanel;
    Run_Button: TButton;
    Stop_Button: TButton;
    procedure Run_ButtonClick(Sender: TObject);
    procedure Stop_ButtonClick(Sender: TObject);
  private
  public
    CamDShow :TCamDShow;
  end;
 
var
  frmMain: TfrmMain;
implementation
                           
{$R *.dfm}

//Run 버튼을 클릭하였을 때...
procedure TfrmMain.Run_ButtonClick(Sender: TObject);
begin
  if not Assigned(CamDShow) then
  begin
    CamDShow := TCamDShow.Create(Panel1);
  end;
  CamDShow.Run;
end;


//Stop 버튼을 클릭하였을 때...
procedure TfrmMain.Stop_ButtonClick(Sender: TObject);
begin
  CamDShow.Stop;
end;
end.


지금까지의 프로젝트를 첨부파일로 올려놓았습니다. (델파이7) 
 
출처 : 델마당  dong님의 글(dongsoft) 

posted by 유돌이
2009. 1. 5. 18:05 비법전수

1. 장형석님의 PHP 형태소 분석기 0.52


  • Public Domain
  • PHP로 만들어졌다.
  • EUC-KR 문자셋
  • 상당히 간단하다.

2. KTS

확률을 기반으로 하고있는 이상호님의 KTS
  • GPL
  • 사전, 조사,어미, 등등
  • 이성진코드 기반.
  • EUC-KR 지원
  • 문서가 비교적 잘 만들어져있다.

3. S C Lee 님의 sma4

  • GPL
  • C언어
  • 사전, 조사, 어미, 관형사사전
  • EUC-KR 문자셋
  • 송재경님의 조합 한글 소스 바탕.
 
4. 초고속 한국어 형태소 분석기 MACH 1.0

Shim, Kwangseob
School of Computer Science and Engineering
Sungshin Women's University
Seoul 151-742, KOREA
shim at sungshin.ac.kr
 
5. KLT: Korean Language Technology -- (구)HAM: Hangul Analysis Module

  • [Down 가능] 윈도95/98/NT/2000용
  • [Down 가능] 32비트 리눅스용
  • 압축파일에 포함되어 있는 README.TXT를 꼭 읽으세요.(구버전 라이브러리를 교체할 경우에, 반드시 header/runmode.h를 교체하고 실행파일을 다시 만들어야 함)

  • 연구용 형태소 분석기는 윈도와 리눅스용만 제공합니다.
  • Sun Solaris, HP Unix, IBM AIX, Free BSD, Digital Unix 등 기타 플랫폼에 대한 연구용 버전은 제공하지 않으며, 정식 사용권을 얻어야 합니다.

  • 특징 1. 분석 정확도가 매우 높아졌음 -- 특히, 미등록어, 고유명사 등
  • 특징 2. 추출되는 용어의 개수가 줄었음 -- 불필요한 용어 추출 방지

  • 실행방법(리눅스, 유닉스 계열) -- "$ index -2 inputfile.txt", "$ indexT -2 inputfile.txt", OR "$ index -2"(표준 입출력)
  • 실행방법(윈도용) -- 1) indexWin.exe(윈도창) 2) DOS창에서 "C> index -2 inputfile.txt"(linux/unix용과 동일)
  • linux에서는 압축파일의 API라는 디렉토리에서 make하면 EXE 디렉토리에 실행파일이 생성됩니다.
  • KLT version 2.1.0f는 연구 및 실험용으로 2009년 12월까지만 사용할 수 있으며, 분석결과에 대한 기능상의 제약이 있을 수 있습니다.(어떤 경우에도 저작권자의 허락없이는 직접 혹은 간접적으로 상업적인 목적으로 활용할 수 없습니다) 

  • '비법전수' 카테고리의 다른 글

    컴퓨터 성능 확인.  (0) 2009.05.26
    컴퓨터 성능 확인  (0) 2009.05.19
    MS툴 무료 제공 및 설치  (0) 2008.12.20
    sticky tag를 제거 방법.  (0) 2008.12.20
    우분투 동영상 관련 설정  (0) 2008.12.20
    posted by 유돌이