커널 오브젝트 : Windows 운영체제에서 리소스(Resource : 프로세스, 쓰레드, 파일)들을
                      관리하기 위한 데이터를 저장하는 메모리 블록



Windows에서 관리하는 리소스 특성을 변경하기 위해서는 해당 리소스의 커널 오브젝트를 조작해야한다.

해당 리소스의 정보를 저장하고 있는 커널 오브젝트에 접근하기 위해서는

커널 오브젝트들을 구별하는 커널 오브젝트 핸들(Object Handle)을 얻어야 한다.



커널 오브젝트와 핸들 :

커널 오브젝트는 Windows 운영체제에 종속적이다.

사용자가 리소스 생성을 요청하면 운영체제에서 사용자가 요청한 대로 리소스를 생성하게 되고

이를 관리하기 위해 커널 오브젝트를 생성한다.

즉, 커널 오브젝트는 Windows 운영체제에 의해 생성 및 소멸이 결정된다.


리소스가 생성되어 커널 오브젝트가 생성되면 커널 오브젝트에 핸들이 부여되고

부모 리소스도 구조체 변수를 통해 자식의 커널 오브젝트 핸들을 획득할 수 있다.

즉, 부모와 자식이 자식의 커널 오브젝트를 공유한다.


예)

부모 프로세스가 자식 프로세스의 커널 오브젝트 핸들 획득.

typedef struct _PROCESS_INFORMATION
{
      HANDLE hProcess;            // 커널 오브젝트 구분 위한 핸들
      HANDLE hThread;
      DWORD dwProcessId;        // 프로세스 구분 위한 ID
      DWORD dwThreadId;         
} PROCESS_INFORMAION;

위 구조체는 CreateProcess 호출할때 인자로 전달되는 구조체이다.(&pi)
호출이 완료되면 이 구조체에 자식 프로세스의 커널 오브젝트 핸들값이 hProcess 에 저장된다.

자신의 커널 오브젝트 핸들 획득.

GetCurrentProcess()

위함수를 사용하면 자신의 커널 오브젝트 핸들값을 리턴한다.



커널 오브젝트와 Usage Count :

운영체제는 해당 커널 오브젝트를 참조하는 대상이 하나도 없을때 커널 오브젝트를 소멸시킨다.

참조하는 대상은 Usage Count(참조 횟수)로 관리한다.

즉, Usage Count = 0 일 때 커널 오브젝트를 소멸한다.

리소스의 생성과 동시에 해당 커널 오브젝트의 Usage Count = 1 이된다.
생성이 완료되면 부모가 자식 리소스 커널 오브젝트의 핸들을 획득하기에 Usage Count = 2 가 된다.

만약 자식 리소스를 소멸하면 Usage Count 가 하나 줄어든다.

여기서 문제가 발생한다. 리소스가 소멸됬음에도 그 리소스를 관리하는 커널 오브젝트는 소멸되지 않는다.
(Usage Count 가 1이므로)

Usage Count = 0 을 만들기 위해선

부모의 자식의 커널 오브젝트 참조를 해제해야 한다.

CloseHandle() 함수를 사용하면 자식의 커널 오브젝트 핸들을 반환하여 참조를 해제한다.

즉, Usage Count 가 하나 줄어든다.

따라서 커널 오브젝트를 소멸하기 위해서는

부모가 소유한 자식의 커널 오브젝트 핸들을 반환해야 한다.


예)

부모 프로세스가 자식의 커널 오브젝트 핸들을 반환하지 않아 커널 오브젝트가 소멸되지 않았다고 가정할때

계산기 프로세스를 생성하면 그에 따른 커널 오브젝트가 생성된다.

계산기 프로세스를 종료시켜도 커널 오브젝트는 소멸되지 않는다(Usage Count =  1이므로 )
 
실행-> 종료, 실행 -> 종료 를 반복한다고 할때

커널 오브젝트는 실행의 수만큼 존재한다.

따라서 이 문제를 해결하기 위해 CloseHandle 을 통해 부모의 자식의 커널 오브젝트 참조를 해제함으로써

자식 프로세스가 종료될때 Usage Count = 0 이 되어 커널 오브젝트가 소멸된다)


(참고 :

바탕화면에서 아이콘을 통해 프로세스를 생성할 경우에도 Usage Count = 2 다.

바탕화면 자체도 프로세스이기 때문이다. 이 때는 바탕화면이 부모 프로세스가 된다.
(Cmd 에서 실행하면 Cmd 가 부모 프로세스)

즉, 프로세스는 생성과 동시에 Usage Count = 2 가 된다)

Posted by Dakuo

#include <windows.h>

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_hInst;
LPCTSTR lpszClass=TEXT("Sample");

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance
    ,LPSTR lpszCmdParam,int nCmdShow)
{
        HWND hWnd;
        MSG Message;
        WNDCLASS WndClass;
        g_hInst=hInstance;
 
        WndClass.cbClsExtra=0;
        WndClass.cbWndExtra=0;
        WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
        WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
        WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
        WndClass.hInstance=hInstance;
        WndClass.lpfnWndProc=WndProc;
        WndClass.lpszClassName=lpszClass;
        WndClass.lpszMenuName=NULL;
        WndClass.style=CS_HREDRAW | CS_VREDRAW;
        RegisterClass(&WndClass);

        hWnd=CreateWindow(lpszClass,lpszClass,WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
        NULL,(HMENU)NULL,hInstance,NULL);
        ShowWindow(hWnd,nCmdShow);
 
        while (GetMessage(&Message,NULL,0,0))
        {
               TranslateMessage(&Message);
               DispatchMessage(&Message);
        }
        return (int)Message.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
       switch (iMessage)
       {
              case WM_DESTROY:
              PostQuitMessage(0);
              return 0;
       }
       return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}




#include <windows.h> :

윈도우즈에서는 하나의 헤더 파일에 모든 API 함수들의 원형과 사용하는 상수들(매크로), 기본적인 데이터 타입, 그 외 윈도우즈 프로그래밍에 필요한 헤더 파일을 거의 포함하고 있기 때문에 이 헤더 하나만 포함하면 된다.(특별한 경우에는 해당 헤더 파일을 포함해야 한다)


LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_hInst;
LPCTSTR lpszClass=TEXT("Sample");

: 함수의 원형과 전역 변수를 선언한다



int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance
    ,LPSTR lpszCmdParam, int nCmdShow)

: 윈도우즈 프로그램의 엔트리 포인트(Entry Point : 프로그램의 시작점)이다.
APIENTRY 지정자는 __stdcall 형 호출 규약을 사용한다.

 파라미터  의미
 hInstance  프로그램의 인스턴스 핸들
 hPrevInstance  바로 앞에 실행된 현재 프로그램의 인스턴스
 핸들. 없을 경우 NULL이며 Win32에서는 항
 상 NULL이다. 호환성을 위해서 존재하는
 파라미터다.
 IpszCmdParam  명령행으로 입력된 프로그램 파리미터다.
 도스의 argv인수에 해당한다.
 nCmdShow  프로그램이 실행될 형태이며 최소화, 보통
 모양 등이 전달된다. 

(참고 : 인스턴스(Instance) : 클래스가 메모리에 실제로 구현된 실체를 의미. 윈도우즈 프로그램은 하나의 프로그램이 여러 번 실행될 수도 있다. 이때 실행되고 있는 각각의 프로그램을 인스턴스라고 한다.
예를 들어 그림판을 두 번 실행했다고 하면 각각의 프로그램은 모두 그림판이지만 운영체제는 각각 다른 메모리를 사용하는 다른 프로그램으로 인식한다. 이때 각 그림판은 서로 다른 인스턴스 핸들을 가지며 운영체제는 이 인스턴스 핸들값으로 두 개의 그림판을 구별한다)

hInstance : 프로그램 자체를 일컫는 정수값이며 프로그램 내부에서 자기 자신을 가리키는
1인칭 대명사다. WinMain의 파라미터로 전달된 hInstace 값은 지역변수이기 때문에 WinMain 안에서만 쓸 수 있다 때문에 다른 곳에서 쓰기 위해 전역변수에 대입해놓는다.


윈도우 클래스 :

윈도우가 있어야 사용자로부터 입력을 받을 수 있고 출력을 보여 줄수도 있다. 윈도우를 만들려면 윈도우 클래스를 먼저 등록한 후 CreateWinodw 함수를 호출한다. 윈도우 클래스는 만들어질 윈도우에 여러가지 특성을 정의하는 구조체이며 모든 윈도우는 윈도우 클래스의 정보를 기반으로 만든다.

typedef struct tagWNDCLASS
{
         UINT style;
         WNDPROC lpfnWndProc;
         int cbClsExtra;
         int cbWndExtra;
         HINSTANCE hInstance;
         HICON hIcon;
         HCURSOR hCursor;
         HBRUSH hbrBackground;
         LPCSTR lpszMenuName;
         LPCSTR lpszClassName;
} WNDCLASS;

1. style : 윈도우가 어떤 형태를 가질 것인가를 지정한다. 가장 많이 사용하는 값은CS_HREDRAW 와 CS_VREDRAW 이다. 이 두 값을 OR 연산자(|)로 연결하여 사용한다. 이 값은 윈도우의 수직(or 수평) 크기가 변할 경우 윈도우를 다시 그린다.

2. lpfnWndProc : 메시지 처리 함수를 지정한다. 메시지가 발생할 때마다 이 멤버가 지정하는 함수가 호출되며 이 함수가 모든 메시지를 처리한다.

3. cbClsExtra, cbWndExtra : 에약 영역이다. 특수한 목적에 사용되는 여분의 공간이다.
사용하지 않을 경우 0으로 지정한다.

4. hInstance : 윈도우 클래스를 등록하는 프로그램의 번호이며 이 값은 WinMain의 파라미터로 전달된 hInstance 값을 그대로 대입한다.

5. hIcon, hCursor : 사용할 마우스 커서와 아이콘을 지정한다. LoadCursor 함수와 LoadIcon 함수를 사용하여 커서, 아이콘을 읽어와 이 멤버에 대입한다. 사용자가 직접 아이콘과 커서를 만들어 사용할 수도 있다.

6. hbrBackground : 윈도우의 배경 색상을 채색할 브러시를 지정한다.GetStockObject 함수를 사용하여 기본적으로 제공하는 브러시를 지정하거나 시스템 색상을 지정할 수도 있다.

7. lpszMenuName : 사용할 메뉴를 지정한다. 메뉴는 프로그램 코드에서 실행중에 만드는 것이 아니라 리소스 에디터에 의해 별도로 만들어진 후 링크시에 합쳐진다. 메뉴를 사용하지 않을 경우 NULL(0)을 대입한다.

8. lpszClassName : 윈도우 클래스의 이름을 문자열로 정의한다. 지정한 이름은 CreateWinodw 함수에 전달된다. 클래스의 이름은 마음대로 정할수 있으나 관습상 실행 파일의 이름과 일치시켜 전역변수 lpszClass에 정의하며 이 전역변수를 대입시켜준다.

이 중 가장 중요한 멤버는 윈도우 클래스의 이름을 정의하는 lpszClassName과 메시지 처리함수를 지정하는 lpfnWndProc이다. 나머지 멤버는 디폴트나 0, NULL 같은 값을 주면 무난하다.


ATOM RegisterClass(CONST WNDCLASS *lpWndClass);

: 파라미터로  정의한 WNDCLASS 구조체의 번지를 넘겨준다.
정의한 윈도우 클래스 구조체를 운영체제에 등록한다.


HWND CreateWindow(lpszClassName, lpszWindowName, dwStyle, x, y,
                               nWidth, nHeight, hwndParent, hmenu, hinst, lpvParam);

: 윈도우 클래스를 기본으로 실제 윈도우를 생성하는 함수이다.
윈도우에 관한 모든 정보를 메모리에 만든 후 윈도우 핸들을 리턴값으로 넘겨준다.

1. lpszClassName : 생성하고자 하는 윈도우의 클래스를 지정하는 문자열이다. 윈도우 클래스의 lpszClassName에 대입했던 전역변수를 이 값에 넣어주면 된다.

2. lpszWinodowName : 윈도우 타이틀 바에 나타날 문자열을 지정한다.

3. dwStyle : 만들고자 하는 윈도우의 형태를 지정하는 값이다. 비트 필드값이며 매크로 상수들이 정의되어 있고 필요한 매크로 상수를 OR 연산자로 연결하여 다양한 형태를 지정한다.
WS_OVERLAPPEDWINDOW 스타일을 사용하면 가장 무난한 윈도우 설정 상태가 된다.

4. x, y, nWidth, nHeight : 윈도우의 크기와 위치를 픽셀 단위로 지정한다. 정수값을 바로 지정해도 되며 CW_USEDEFAULT를 사용하면 화면 크기에 맞게 적당한 크기와 위치를 설정한다

5. hWndParent : 부모 윈도우가 있을 경우 부모 윈도우의 핸들을 지정한다. 윈도우끼리 수직적인 상하관계를 가져 부자 관계(parent-child)가 성립되는데 이 관계를 지정해 주는 파라미터다. 없을 경우 NULL(0)로 지정한다.

6. hmenu : 사용할 메뉴의 핸들을 지정한다. 윈도우 클래스에서 지정한 메뉴를 그대로 사용하려면 이 값을 NULL로 다른 메뉴를 사용하려면 원하는 메뉴 핸들을 넣는다.

7. lpvParam : CREATESTRUCT 라는 구조체의 번지이며 특수한 목적에 사용된다. 보통은 NULL값을 대입한다.


BOOL ShowWindow(hWnd,nCmdShow);

: hWnd 파라미터는 화면으로 출력하고자 하는 윈도우의 핸들이며 CreateWindow 함수가 리턴한 핸들을 그대로 넘겨준다. nCmdShow는 화면에 출력하는 방법을 지정하며 다음의 매크로 상수들이 정의되있다.

 매크로 상수  의미 
 SW_HIDE  윈도우를 숨긴다
 SW_MINIMIZE  윈도우를 최소화하고 활성화하지 않는다
 SW_RESTORE  윈도우를 활성화한다,
 SW_SHOW  윈도우를 활성화시켜 보여준다
 SW_SHOWNORMAL  윈도우를 활성화시켜 보여준다

nCmdShow 파라미터에는 WinMain 함수의 파라미터로 전달한 nCmdShow를 그대로 넣어주면 된다. 따라서 거의 호출 형식이 정해져있다.


메시지 루프 : 윈도우즈를 메시지 구동 시스템(Message Driven System)이라고도 하며
순서를 따르지 않고 주어진 메시지에 대한 반응을 정의하는 방식으로 프로그램이 실행된다.
윈도우즈 프로그램에서는 메시지 처리 부분을 while문으로 묶어서 무한히 반복시킨다.

메시지 : 사용자나 시스템의 내부적인 동작에 의해 발생된 일체의 변화에 대한 정보

while (GetMessage(&Message, 0, 0, 0)){
               TranslateMessage(&Message);
               DispatchMessage(&Message);}

BOOL GetMessage( LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin,
                             UINT wMsgFilterMax);

: 메시지 큐에서 메시지를 읽어들인다. 메시지 큐(Message Queue)는 시스템이나 사용자로부터 발생된 메시지가 잠시 대기하는 메시지 임시 저장 영역이다. 읽어들인 메시지는 첫 번째 파라미터가 지정하는 MSG 구조체에 저장된다. 읽어들인 메시지가 WM_QUIT일 경우 FALSE를 리턴하여 루프가 종료되며, 그 외 메시지에는 TURE를 리턴하여 루프가 계속된다.
나머지 세 개의 파라미터는 읽어들일 메시지의 범위를 지정하는데 잘 사용되지 않는다.

BOOL TranslateMessage( CONST MSG *lpMsg);

: 키보드 입력 메시지를 가공하여 프로그램에서 쉽게 쓸 수 있도록 해준다. 키보드를 눌러서 키보드 메시지를 발생시키면 문자가 입력되었다는 메시지로 바꿔준다.
(WM_KEYDOWN -> WM_CHAR)

LONG DispatchMessage( CONST MSG *lpmsg);

: 메시지 큐에서 꺼낸 메시지를 윈도우의 메시지 처리 함수(WndProc)로 전달한다. WndProc는 메시지를 윈도우로 전달하고 윈도우에서 전달된 메시지를 점검하여 다음 동작을 결정한다.

메시지 루프의 세 함수는 공통적으로 MSG 라는 메시지에 대한 정보를 정의하는 구조체를 사용한다.

typedef struct tagMSG
{
      HWND       hwnd;
      UINT         message;
      WPARAM   wParam;
      LPARAM   lParam;
      DWORD     time;
      POINT       pt;
} MSG;

 멤버  의미
 hwnd  메시지를 받을 윈도우 핸들
 message  메시지 종류를 나타낸다. 가장 중요하다
 wParam  전달된 메시지에 대한 부가적인 정보 32비트
 lParam  전달된 메시지에 대한 부가적인 정보 32비트
 time  메시지가 발생한 시간
 pt  메시지가 발생했을 때의 마우스 위치

message 멤버를 읽어서 메시지의 종류를 파악하며 message 값에 따라 프로그램의 반응이 달라진다. wParam, lParam은 메시지의 부가적인 정보를 가지되 메시지별로 의미가 다르다. GetMessage 는 읽은 메시지를 MSG 형의 구조체에 대입해 주며 DispatchMessage 에 의해 WndProc 로 전달된다.(WM_QUIT 메시지가 올때까지)

메시지는 실제로 하나의 정수값으로 표현되는데 종류가 무척많아 windows.h 에 메시지 별
매크로 상수를 정의해 두었다.(접두어 WM_)

 메시지  의미 
 WM_QUIT  프로그램을 끝낼 때 발생하는 메시지
 WM_LBUTTONDOWN  마우스의 좌측 버튼을 누를 경우 발생
 WM_CHAR  키보드로부터 문자가 입력될 때 발생
 WM_PAINT  화면을 다시 그려야 할 필요가 있을때 발생
 WM_DESTORY  윈도우가 메모리에서 파괴될 때 발생
 WM_CREATE  윈도우가 처음 만들어질 때 발생

메시지 루프가 종료되면 프로그램은 마지막으로 Message.wParam 을 리턴하고 종료한다.
이 값은 WM_QUIT 메시지로부터 전달된 탈출 코드(exit code)이다.


WinMain에서 한일을 정리해보면

WndClass 정의  ->   CreateWindow               ->   ShowWindow                
윈도우 클래스 정의    메모리상에 윈도우를 만든다   윈도우를 화면에 표시한다.

-> 메시지 루프
사용자로부터 메시지를 처리한다.



윈도우 프로시저 :

메시지가 발생할 때 프로그램의 반응을 처리하는 일을 한다. WndProc 은 WinMain 에서 호출하는 것이 아니라 메시지가 입력되면 운영체제에 의해 호출되어 메시지를 처리한다.
(참고 : 운영체제에 의해 호출되는 응용 프로그램 내의 함수를 콜백(CallBack)함수라 한다)

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)

WndProc의 파라미터는 4개이며 MSG 구조체의 멤버 4개와 동일하다(iMessage = message)

WndProc의 구조는 다음과 같으며 메시지의 종류에 따라 다중 분기하여 메시지별로 처리한다.

switch (iMessage)
{
       case Msg1 :
               처리 1;
               return 0;
       case Msg2 :
               처리 2;
               return 0;
}
return(DefWindowProc(hWnd,iMessage,wParam,lParam));

Msg1 메시지가 전달 되면 처리 1을 한 후 리턴하고 Msg2 메시지가 전달되면 처리 2를 한 후 리턴하는 식이다. 이 외에 메시지가 전달되면 DefWindowProc 함수에서 디폴트 처리한다.
(주의 : 메시지 처리 후 반드시 0을 리턴해야한다. 또한 DefWindowProc에서 메시지를 처리한 경우에 DefWindowProc에서 리턴한 값을 WndProc가 다시 리턴해야한다)



메시지 처리 순서도 :

'Windows > _Windows Programming' 카테고리의 다른 글

타이머(Timer)  (0) 2009.12.23
입력하기  (0) 2009.12.01
출력하기  (2) 2009.11.28
윈도우 기초 프로그래밍  (0) 2009.11.27
윈도우즈(Windows) 프로그래밍의 기초  (0) 2009.11.27
.xxx 파일 만들기  (2) 2009.11.24
Posted by Dakuo
윈도우즈(Windows)의 장점 :

1. 그래픽 기반의 운영체제이다.

2. 멀티 태스킹이 가능하다.

3. 장치에 영향을 받지 않는다.

4. 일관성



개발툴의 선택 :

1. API :

API(Application Programming Interface) : 운영체제가 응용 프로그램을 위해 제공하는 함수의 집합

2. SDK :

SDK(Software Development Kit) : 윈도우즈를 만든 Microsoft에서 제공하는 윈도우즈용 프로그램 개발 킷이다. API 함수들을 사용하여 프로그램을 작성하며 가장 원론적이고 먼저 발표된 개발방법이다. 섬세하고 막강하며 속도가 빠르고 크기에 유리하나 방대한 API 함수를 알아야 하며 코드가 길어지고 생산성도 낮다.

3. 클래스 라이브러리

API 함수들을 좀 더 쉽고 빠르게 사용하기위해 클래스로 잘 포장하여 클래스 위주로 프로그램을 작성하는 방법이다. 클래스가 잘 설계되어 있어 사용하기도 쉬우며 기능 또한 막강하다.
MFC(Microsoft사)가 대표적이다. 다만 클래스 라이브러리의 문법적 기반인 OOP에 대해 상세히 알아야 하며 API 함수를 기반으로 하기 때문에 API 함수에 대한 기본 개념이 있어야 한다.

4. 비주얼 툴

API는 어렵고 생산성이 너무 떨어지고 클래스 라이브러리도 배우기가 쉽지 않다.
API나 OOP를 몰라도 프로그램을 작성할 수 있는 비주얼 툴이 있다.
그림을 그리듯 화면을 디자인 하며 필요한 곳에만 간단한 코드를 작성하는 개발툴이다.



API 를 알아야 하는 이유 :

1. 운영체제를 이해하기 위해

2. 어차피 알아야 하므로

3. 개발툴이 제공하지 않는 것을 구현하기 위해



API 공부하기 전에 :

1. API 를 사용하기 위해서는 윈도우즈의 표준 언어인 C를 컴파일 하는 컴파일러가 있어야 한다.
또한 API는 C언어로 형식으로 되어 있기에 C 프로그래밍에 대해 어느정도 알고 있어야 한다.



2. 사전 지식 :

2-1. 변수 명명법 :

 접두어  원래말   의미
 cb  Count of Bytes  바이트 수
 dw  double word  부호없는 long형 정수
 h  handle  윈도우, 파일 등의 핸들
 sz  Null Terminated   NULL 종료 문자열
 ch  Character  문자형
 a  Array  배열
 w  Word  부호없는 정수형
 i  Integer  정수형
 b  Bool  논리형

변수명을 나타내는 이런 약속 외에도 윈도우즈는 새로운 데이터형을 만들어서 사용한다.
이 데이터 형은 windows.h 라는 헤더파일에 typedef 로 선언되어 있으며 모든 프로그램에서 표준 데이터형처럼 사용한다.

 데이터형  의미 
 BYTE  unsigned char 형
 WORD  unsigned short 형
 DWORD  unsigned long 형
 LONG  long형과 동일
 LPSTR  char* 와 동일
 BOOL  정수형이며 TRUE, FALSE 중 한값을 가진다


2-2. 핸들에 대한 이해 :

핸들(Handle) : 어떤 대상에 붙여진 번호이며 문법적으로는 32비트 정수값이다.
만들어진 윈도우에는 윈도우 핸들(hWnd)를 붙여 윈도우를 번호로 관리하며 거의 모든 것에 다 핸들을 붙여 구분하는데 그 이유는 문자열 보다 정수를 사용하는 것이 훨씬 더 속도가 빠르고 간편하기 때문이다.

핸들의 특징 :

1. 32비트 정수값이다.

2. 운영체제가 발급해 주며 사용자는 쓰기만 하면 된다. 사용자가 직접 핸들을 만들 경우는 없다.

3. 같은 종류의 핸들끼리는 중복될 수 없다.(단 다른 종류의 핸들은 중복된 값을 가질수도 있다)

4. 핸들의 실제 값을 몰라도 상관없다. 구분을 위한 표식일 뿐이므로 값에 의미를 부여하지 않는다.

핸들은 접두어 h로 시작되며 핸들을 저장하기 위한 별도의 데이터형이 정의되있다.
(HWND, HPEN, HBRUSH, HDC 등이 있다 - 부호없는 정수형)


2-3. 비트 OR 연산자 :

API 함수들은 작업에 대한 세부 정보(옵션)를 파리미터로 전달받는다. 전달 가능한 옵션이 여러 개가 있을 경우 하나의 파라미터에 복수 개의 옵션을 묶어 전달하는데 이때 비트 OR 연산자(|)를 사용한다.


비트 OR 연산자를 사용하면 여러개의 옵션을 묶어서 하나의 정수값만 전달하더라도 함수는 개별 비트를 테스트한 후 어떤 옵션이 선택되었는지 알 수 있다. 각 옵션의 실제값이 어떻게 정의되어 있는가는 알 필요가 없으며 매크로 상수만 알면 된다.
API 함수는 이런식의 파라미터 전달법을 흔히 사용하며 상관없는 옵션들이 하나의 파라미터에 전달되는 경우도 있고 옵션끼리 배타적인 경우도 있다.

'Windows > _Windows Programming' 카테고리의 다른 글

타이머(Timer)  (0) 2009.12.23
입력하기  (0) 2009.12.01
출력하기  (2) 2009.11.28
윈도우 기초 프로그래밍  (0) 2009.11.27
윈도우즈(Windows) 프로그래밍의 기초  (0) 2009.11.27
.xxx 파일 만들기  (2) 2009.11.24
Posted by Dakuo