Win32 API 주요 함수
AdjustWindowRect : BOOL AdjustWindowRect(LPRECT lpRect, DWORD dwStyle, BOOL bMenu);
작업 영역의 크기는 윈도우 크기에서 타이틀 바와 경계선, 메뉴, 스크롤 바 등의 영역을 제외한 영역이다. 일반적으로 MoveWindow, SetWindorPos 등의 함수로 윈도우 크기는 원하는대로 바꿀 수 있지만 작업 영역의 크기를 원하는대로 설정하는 방법은 없다. 작업 영역을 특정한 크기대로 설정하려면 이 함수로 원하는 윈도우 크기를 먼저 계산하고 MoveWindow 등의 함수로 윈도우 크기를 변경해야 한다.
이 함수는 윈도우의 스타일(타이틀 바의 유무, 타이틀 바의 높이, 경계선의 두께)와 메뉴의 존재 여부 등을 고려하여 작업 영역의 크기가 lpRect가 될 수 있는 윈도우 크기를 구해 lpRect로 리턴해 준다. 단 이 함수는 메뉴 바가 두 줄로 출력되어 있는 경우와 스크롤 바의 존재에 대해서는 정확한 계산을 해 주지 않는다. 만약 스크롤 바를 가지고 있다면 구해진 영역 크기에 스크롤바의 높이와 폭을 더해 주어야 한다
////////////////////////////////////////////////////////////////////////////////////////////////////
BeginPaint : HDC BeginPaint(HWND hwnd, LPPAINTSTRUCT lpPaint);
윈도우즈 환경에서 화면이나 프린터로 출력을 하려면 DC를 먼저 구해야 한다. DC를 구하는 일반적인 방법은 두 가지가 있는데 GetDC와 ReleaseDC를 사용하는 방법이 있고 BeginPaint와 EndPaint를 사용하는 방법이 있다. BeginPaint와 EndPaint는 짝을 이루어 사용되며 반드시 WM_PAINT 메시지 내부에서만 사용해야 한다.
////////////////////////////////////////////////////////////////////////////////////////////////////
BitBlt :
BOOL BitBlt(HDC hDC,int X,int Y,int nWidth,int nHeignt, HDC hSrcDC,int XSrc,int ySrc,DWORD dwROP);
하나의 DC에 있는 비트맵을 다른 DC로 복사하는 비트맵 전송함수이다. 이때 두 DC는 호환되어야 하나 만약 색상 포맷이 호환되지 않을 경우 BitBlt는 복사원의 색상 포맷을 복사처의 포멧에 맞게 변경한다. 비트맵을 화면에 출력하기 위해서는 우선 CreateCompatibleDC함수를 사용하여 메모리 DC를 만들어야 하며 SelectObject 함수를 사용하여 메모리 DC에 출력하고자 하는 비트맵을 선택한 후 BitBlt로 실제 화면 DC에 전송한다. 이때 비트맵은 원본 그대로 복사가 되지만 ROP코드에 따라 배경과 함께 논리 연산되어 변형될 수는 있다. 복사원의 비트맵은 복사처의 맴핑모드에 따라 크기가 커지거나 작아지기도 한다. 모든 장치가 BitBlt를 지원하는 것은 아니므로 GetDeviceCaps를 사용하여 BitBlt를 쓸 수 있는 장치인가를 확인해 보아야 한다
////////////////////////////////////////////////////////////////////////////////////////////////////
CheckDlgButton : BOOL CheckDlgButton(HWND hDlg, int nIDButton, UINT uCheck);
체크 버튼이나 라디오 버튼 등 체크 상태를 가지는 버튼의 체크 상태를 변경한다. 이때 해당 컨트롤로 BM_SETCHECK 메시지를 보낸다.
////////////////////////////////////////////////////////////////////////////////////////////////////
CheckRadioButton :
BOOL CheckRadioButton( HWND hDlg, int nIDFirstButton, int nIDLastButton, int nIDCheckButton );
대화상자에 배치된 라디오 버튼 그룹 중 하나의 라디오 버튼을 체크한다. 두번째 인수와 세번째 인수는 라디오 버튼의 그룹의 지정하되 이 두 ID 사이에 속한 라디오 버튼들을 같은 그룹으로 인식한다. 이 함수는 네번째 라디오 버튼을 체크하되 그룹에 속한 다른 모든 버튼의 체크는 해제한다. 라디오 버튼의 체크 상태를 변경하기 위해 각 라디오 버튼으로 BM_SETCHECK 메시지를 보낸다.
////////////////////////////////////////////////////////////////////////////////////////////////////
ClientToScreen : BOOL ClientToScreen(HWND hWnd, LPPOINT lpPoint);
hWnd의 작업 영역 원점을 기준으로 하는 좌표 lpPoint를 전체 화면을 기준으로 하는 좌표로 변환한다. hWnd윈도우의 작업 영역 원점의 화면 좌표가 cx, cy일 때 lpPoint는 lpPoint.x + cx, lpPoint + cy로 변환된다. 작업 영역의 좌표를 받아 GetCurosrPos, MoveWindow 등과 같이 화면 좌표를 요구하는 함수로 좌표를 전달하기 위해 이 함수를 사용한다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
CloseHandle : BOOL CloseHandle(HANDLE hObject);
열려진 핸들을 닫는다. 대상이 되는 핸들은 파일, 파일 맵핑, 콘솔 입력, 콘솔 버퍼, 소켓, 프로세스, 스레드, 뮤텍스, 이벤트, 세마포어 등이다. Win32 환경에서 핸들로 표현되는 대부분의 커널 오브젝트를 닫는다. 그러나 아이콘, 윈도우, 펜, 브러시 등의 유저 오브젝트, GDI 오브젝트는 이 함수로 닫을 수 없다.
이 함수는 핸들의 사용 카운트를 1 감소시키고 오브젝트를 계속 유지할 것인가를 결정한다. 오브젝트를 가리키는 마지막 핸들이 닫히면 오브젝트를 제거한다. 단, 스레드는 이 함수로 핸들을 닫는다고 해서 스레드가 파괴되는 것은 아니다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
CloseWindow : BOOL CloseWindow( HWND hWnd );
hWnd윈도우를 최소화하여 아이콘 상태로 만든다. 단순히 최소화시킬 뿐이며 윈도우를 파괴하는 것은 아니다. 윈도우는 아이콘 영역으로 이동하며 아이콘 아래에 윈도우의 타이틀이 출력된다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
CopyFile : BOOL CopyFile(LPCTSTR lpExistingFileName, LPCTSTR lpNewFileName, BOOL bFailIfExists);
파일을 복사하여 새로운 파일을 만든다. DOS의 copy 명령과 사용하는 방법이 동일하다. CopFile("a","b", FALSE);는 a파일을 복사하여 b 파일을 만들되 이미 b 파일이 있으면 덮어쓴다. 파일의 속성은 복사되나, 보안 속성은 복사되지 않는다.
이 함수는 원본 파일을 읽어 새 파일을 완전히 작성한 후에 리턴한다. 만약 파일 복사중에 경과를 보여주고 싶다면 CopyFileEx 함수를 사용해야 한다. 복사중에 데이터를 변경하거나 검사하고 싶다면 이 함수를 사용할 수 없으며 ReadFile, WriteFile 함수로 직접 파일의 데이터를 일정량만큼 복사해 주어야 한다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
CreateCompatibleDC : HDC CreateCompatibleDC(HDC hdc);
인수로 주어진 hdc와 호환되는 메모리 DC를 생성한다. 여기서 호환된다는 뜻은 색상 포맷이 같다는 뜻이며 색상 포맷이 같은 DC끼리는 비트맵을 전송할 수 있다.
화면 DC는 메모리 상에 존재하는 그리기 표면이다. 실제 화면 DC와 마찬가지로 모든 GDI 출력 함수를 사용할 수 있으므로 프로그램 내부에서 미리 그리기를 할 때 메모리 DC를 사용한다. 메모리 DC로 보내지는 출력은 메모리 DC에 선택되어 있는 비트맵의 표면으로 출력된다.
최초 메모리 DC가 생성되면 그리기 표면은 1픽셀짜리 흑백 비트맵을 가지며 비트맵을 선택해 주면 이 비트맵의 높이와 폭, 색상 포맷을 가지는 그리기 표면이 만들어진다. 따라서 메모리 DC에 미리 그리기를 하고자할 때는 먼저 CreateCompatibleBitmap 함수로 생성한 원하는 크기의 비트맵을 먼저 선택해 주어야 한다. 또는 미리 읽어놓은 그림을 출력할고자 할 때는 LoadBitmap으로 읽은 비트맵을 메모리 DC에 선택해 준 후 BitBlt 등의 함수로 화면 DC로 전송한다.
다음 코드는 비트맵을 화면으로 출력하는 가장 일반적인 코드이다. 화면 DC와 호환되는 메모리 DC를 생성한 후 비트맵을 메모리 DC에 선택하고 BitBlt로 화면 DC로 전송한다. 화면 DC는 비트맵을 선택할 수 없기 때문에 반드시 메모리 DC에 비트맵을 선택한 후 원하는 부분을 화면 DC로 전송해야 한다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
CreateDialog :
HWND CreateDialog(HINSTANCE hInstance, LPCTSTR lpTemplate, HWND hWndParent, DLGPROC lpDialogFunc);
lpTemplate 인수가 지정하는 템플리트로 대화상자를 생성하며 대화상자 프로시저로 WM_INITDIALOG메시지를 보내 초기화를 하도록 한다. 대화상자 템플리트가 WS_VISIBLE 스타일을 가지고 있으면 대화상자를 화면으로 출력하나 이 스타일이 없으면 ShowWindow 함수를 호출하기 전에는 대화상자가 보이지 않는다. 이 함수는 대화상자 생성 후 곧바로 대화상자 핸들을 리턴한다.
주로 모델리스 대화상자를 생성할 때 이 함수를 사용한다. 이 함수를 호출하기 전에 반드시 이 대화상자가 이미 생성되어 있는지를 점검해 보아야 한다. 메인 윈도우는 이 함수로 모델리스 대화상자를 생성한 후 메시지로 상호 작용을 하며 대화상자가 필요없을 때 DestroyWindow 함수로 대화상자를 파괴힌다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
CreateFile : HANDLE CreateFile(LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES pSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);
이 함수는 파일을 생성하는 가장 기본적인 함수이다. 그러나 이름과는 달리 파일을 생성하는 것뿐만 아니라 기존의 파일을 열 수도 있으며 파일 외에 다음과 같은 오브젝트를 생성하거나 열 수도 있다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
CreateFont : HFONT CreateFont( int nHeight, int nWidth, int nEscapement, int nOrientation, int fnWeight, DWORD fdwItalic, DWORD fdwUnderline, DWORD fdwStrikeOut, DWORD fdwCharSet, DWORD fdwOutputPrecision, DWORD fdwClipPrecision, DWORD fdwQuality, DWORD fdwPitchAndFamily, LPCTSTR lpszFace );
CreateFont는 인수가 지정하는 특성에 가장 일치하는 논리 폰트를 생성하며 이 함수로 생성한 논리 폰트는 SelectObject 함수에 의해 DC에 선택된다. 논리 폰트는 응용 프로그램이 사용하고자 하는 폰트에 대한 정의일 뿐이며 실제로 시스템에 존재하는 물리 폰트와는 다르다. GDI는 논리 폰트의 정보를 참조하여 시스템에 존재하는 물리 폰트 중 논리 폰트의 특성에 가장 근접 폰트를 선택해 준다. 논리 폰트에 가장 근접하는 물리 폰트를 찾는 과정을 폰트 맵핑이라고 하며 그 알고리즘을 폰트 매퍼라고 한다. CreateFont 함수는 인수가 지정하는 특성대로 논리 폰트를 만들 뿐이며 폰트 매퍼에 의해 물리 폰트를 선택하는 것은 SelectObject 함수가 한다.
폰트 매퍼가 폰트를 선택할 때 가장 우선적으로 고려하는 요소는 문자셋, 패치와 패밀리 그리고 타입 페이스이다. 따라서 정확한 결과를 얻기 위해서는 최소한 이 세값을 정확하게 요구해야 한다. 만약 "BaboFont"라는 이름을 가지는 폰트를 선택하고 싶다고 해서 타입 페이스만 "BaboFont"라고 요구하고 나머지 정보를 아무렇게나 요구할 경우 이 폰트가 설치되지 않은 시스템에서는 엉뚱한 폰트가 선택될 수도 있다. 문자셋, 피치, 패밀리 정보를 정확하게 요구했으면 설사 이 폰트가 없어도 최대한 비슷한 폰트를 찾아 선택할 수 있다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
CreateFontIndirect : HFONT CreateFontIndirect(CONST LOGFONT *lplf);
LOGFONT 구조체가 지정하는 특성의 논리 폰트를 생성한다. 이 구조체의 멤버는 CreateFont 함수의 인수와 정확하게 일치하므로 자세한 사항은 CreateFont 함수의 인수 설명을 참조하기 바란다. 단 이 함수는 폰트의 특성 지정에 구조체를 사용하므로 구조체 배열을 미리 만들어 놓거나 저장할 수 있다는 장점이 있으며 비슷한 특성을 가지는 일련의 폰트를 반복적으로 만들 수 있다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
CreateHatchBrush : HBRUSH CreateHatchBrush( int fnStyle, COLORREF clrref);
브러시는 GDI가 도형의 안쪽을 채우기 위해 사용하는 오브젝트이다. 이 함수는 무늬와 색상이 있는 브러시를 생성한다.사용하고 난 후에는 반드시 DeleteObject 함수로 브러시를 삭제해 주어야 한다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
CreatePen : HPEN CreatePen(int fnPenStyle, int nWidth, COLORREF crColor);
펜은 GDI가 선을 그릴 때 사용하는 오브젝트이며 DC에 선택된 펜의 속성대로 선이 그어진다. 디폴트 펜은 굵기 1의 검정색 실선이나 펜을 만들어 DC로 전송하면 만들어진 펜대로 선이 그어진다. 다 사용하고 난 후에는 DeleteObject 함수로 펜을 삭제해야 한다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
CreateSolidBrush : HBRUSH CreateSolidBrush( COLORREF crColor);
브러시는 GDI가 도형의 안쪽을 채우기 위해 사용하는 오브젝트이다. DC가 처음 만들어지면 디폴트로 흰색의 브러시가 선택되어 있으나 브러시를 만들어 선택해 주면 원하는 색상으로 도형의 내부를 채색할 수 있다. 사용하고 난 후에는 반드시 DeleteObject 함수로 브러시를 삭제해 주어야 한다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
CreateWindow : HWND CreateWindow(LPCTSTR lpClassName, LPCTSTR lpWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HANDLE hInstance, LPVOID lpParam);
윈도우 클래스와 이 함수의 인수 정보를 바탕으로 하여 윈도우를 생성한다. RegisterClass 함수로 직접 윈도우 클래스를 등록하여 메인 윈도우를 만들 수도 있으며 또는 이미 등록된 컨트롤을 생성할 수도 있다.
이 함수는 윈도우 생성 후 WM_CRETATE. WM_GETMINMAXINFO, WM_NCCREATE 메시지를 해당 윈도우로 차례대로 보내주며 WS_VISIBLE 스타일이 지정되어 있을 경우 윈도우를 보여주고 활성화시키기 위한 모든 동작을 하며 관련 메시지를 보내준다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
CreateWindowEx : HWND CreateWindowEx(DWORD dwExStyle, LPCTSTR lpClassName, LPCTSTR lpWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HANDLE hInstance, LPVOID lpParam);
윈도우를 생성하는 기능은 CreateWindow 함수와 동일하되 확장 스타일을 지정하는 dwExStyle 멤버가 있다는 점만 다르다. CreateWindow 함수는 dwExStyle이 0인 매크로 함수로 정의되어 있다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
DefWindowProc : LRESULT DefWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
이 함수는 윈도우 프로시저가 처리하지 않은 메시지의 디폴트 처리를 한다. WndProc은 원하는 메시지를 처리하고 자신이 처리하지 않은 메시지는 이 함수에게 전달하여 디폴트 처리를 하도록 해 주어야 한다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
DeleteObject : BOOL DeleteObject( HGDIOBJ hObject);
GDI오브젝트를 삭제하고 오브젝트가 사용하던 시스템 리소스를 해제한다. CreatePen, CreateSolidBrush 등의 함수로 만들어진 GDI 오브젝트는 반드시 삭제해 주어야 한다. DC에 선택되어 있는 오브젝트는 삭제할 수 없으므로 삭제하기 전에 반드시 같은 타입의 다른 오브젝트를 선택해 주어야 한다. 패턴 브러시가 삭제될 때 비트맵은 삭제되지 않으므로 직접 삭제해 주어야 한다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
DestroyWindow : BOOL DestroyWindow( HWND hWnd );
hWnd 윈도우를 파괴한다. 단, 이 함수로 다른 스레드에서 생성한 윈도우를 파괴할 수는 없다. 이때 이 함수는 다음과 같은 일련의 동작을 수행한다.
1.파괴되는 윈도우에게 WM_DESTROY, WM_NCDESTROY 메시지를 보내준다. 윈도우 프로시저는 이 메시지를 받았을 때 윈도우에서 할당한 자원을 해제하는 등의 종료 처리를 한다. hWnd가 메인 윈도우이면 PostQuitMessage 함수를 호출하여 프로세스를 종료하도록 해야 한다.
2.키보드 포커스를 제거한다.
3.윈도우의 메뉴를 파괴한다.
4.스레드의 메시지 큐를 비운다.
5.타이머를 파괴한다.
6.클립보드의 소유권을 해제한다.
7.파괴되는 윈도우의 차일드와 소유된 윈도우들을 차례대로 파괴한 후 hWnd 윈도우를 파괴한다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
DialogBox : int DialogBox( HINSTANCE hInstance, LPCTSTR lpTemplate, HWND hWndParent, DLGPROC lpDialogFunc );
이 함수는 모달 대화상자를 실행한다. lpTemplate가 지정하는 대화상자를 생성하여 화면으로 출력하며(WS_VISIBLE 스타일이 없어도 화면에 보인다) 소유자 윈도우를 사용 금지시키고 lpDialogFunc 인수가 지정하는 메시지 처리 함수로 메시지를 보내주어 대화상자를 실행한다. 모달 대화상자는 EndDialog가 호출될 때까지 실행을 계속하며 이 함수는 대화상자가 완전히 종료되어야 리턴한다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
DispatchMessage : LONG DispatchMessage(CONST MSG *lpmsg);
이 함수는 GetMessage가 읽은 메시지를 이 메시지를 처리할 윈도우로 보낸다. 단, WM_TIMER 메시지의 lParam이 NULL이 아닐 경우, 즉 콜백 함수가 지정되어 있을 경우는 윈도우 프로시저로 메시지를 보내는 대신 lParam이 저장하는 콜백 함수를 곧바로 호출한다. 이 함수는 윈도우 프로시저가 메시지를 완전히 처리하기 전에는 리턴하지 않는다. 다음은 일반적인 메시지 루프이다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
DrawText : int DrawText(HDC hDC, LPCTSTR lpString, int nCount, LPRECT lpRect, UINT uFormat);
문자열을 사각 영역 내부에 출력하며 사각 영역 외부로는 출력을 하지 않는다. 단, DT_NOCLIP 플레그가 설정된 경우는 예외적으로 사각 영역 바깥으로도 출력을 할 수 있다. DT_SINGLELINE 플레그가 설정된 경우를 제외하고 문자열이 여러줄로 구성된 것으로 간주한다. TextOut 함수에 비해 여러 줄을 한꺼번에 출력할 수 있다.
출력에 사용할 폰트와 문자열의 색상, 배경 색상은 TextOut 함수와 마찬가지로 DC에 선택된 글꼴과 색상 설정을 따른다. 그러나 SetTextAlign으로 정렬 상태를 변경할 수는 없으며 Escapement, Orientation이 0이 아닌 글꼴, 즉 기울어진 글꼴은 출력할 수 없다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
Ellipse : BOOL Ellipse(HDC hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);
주어진 사각형에 내접하는 타원을 그린다. 타원의 원주는 현재 DC에 선택된 펜으로 그려지며 타원의 내부는 현재 DC에 선택된 브러시로 채워진다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
EndDialog : BOOL EndDialog(HWND hDlg,int nResult);
DialogBox등의 함수로 생성한 대화상자를 종료한다. 모달 대화상자는 반드시 이 함수로 종료해야 하며 또한 이 함수는 대화상자 종료 이외의 목적으로 사용해서는 안된다. 이 함수는 대화상자 프로시저에서 언제든지 호출할 수 있으며 심지어 대화상자 초기화 중인 WM_INITDIALOG에서도 호출할 수 있다. 만약 초기화중에 일정한 조건에 의해 대화상자를 종료하기 위해 이 함수를 호출할 경우 대화상자는 화면에 보이기 전에 파괴된다.
이 함수는 호출 즉시 대화상자를 파괴하지 않고 대화 상자 파괴를 지시하는 플레그만 설정한다. 시스템은 다음 메시지를 읽을 때 이 플레그의 설정상태를 보고 대화상자를 종료한다. 따라서 이 함수 호출 다음에 있는 명령문은 모두 제대로 실행된다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
EndPaint : BOOL EndPaint(HWND hWnd, CONST PAINTSTRUCT *lpPaint);
WM_PAINT 함수 내에서 그리기를 종료하기 위해 사용된다. BeginPaint와 항상 짝을 이루어 사용되며 BeginPaint가 캐럿을 숨겼을 경우 캐럿을 다시 화면으로 출력해 주는 역할을 한다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
FillRect : int FillRect(HDC hDC, CONST RECT *lprc, HBRUSH hbr);
lprc 사각 영역을 hbr 브러시로 칠한다. 경계선은 그리지 않으며 내부만 칠하기 때문에 특정 영역을 단색으로 칠할 때 편리하다. 사각 영역의 왼쪽과 위쪽은 채색 영역에 포함되지만 오른쪽과 아래쪽은 맵핑모드에 상관없이 포함되지 않는다. 예를 들어 (10,10)-(100,100) 영역을 칠하면 실제로 칠해지는 영역을 (10,10)-(99,99)까지이다.
브러시는 CreateSolidBrush, CreateHatchBrush 등으로 만든 커스텀 브러시를 쓸 수도 있고 GetStockObject 함수로 구한 스톡 브러시를 쓸 수도 있다. 또는 시스템 색상에 1을 더하여 사용하는 것도 가능하다. 브러시의 핸들을 인수로 전달하며 DC에 먼저 브러시를 선택해 놓을 필요가 없기 때문에 다른 GDI 함수에 비해 필요한 코드가 훨씬 더 짧다는 것이 특징이다. 경계선을 그리지 않으므로 주로 특정 영역을 완전히 채울 때 많이 사용하며 특히 배경색과 동일한 브러시를 사용하면 이미 출력된 내용을 지울 수 있다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
FindWindow : HWND FindWindow(LPCTSTR lpClassName, LPCTSTR lpWindowName);
윈도우 클래스와 캡션으로 윈도우를 검색하여 핸들을 얻는다. 윈도우간의 상호작용을 하기 위해서는 윈도우의 핸들이 필요한데 이 함수로 원하는 윈도우의 핸들을 조사할 수 있다. 윈도우 클래스 또는 윈도우 캡션 둘 중 하나의 조건으로 검색할 수 있다. 차일드 윈도우는 검색할 수 없으며 탑 레벨 윈도우만 검색 대상이 된다. 윈도우 클래스와 캡션 문자열은 대소문자를 가리지는 않지만 부분 문자열을 검색할 수는 없다. 따라서 캡션이 가변적으로 변하는 윈도우를 검색하는 목적으로는 이 함수를 사용할 수 없으며 우연히 같은 캡션을 가지는 윈도우가 있을 경우 잘못된 검색을 할 위험도 있다.
두 프로그램이 상호 작용을 하고자 할 때 미리 캡션을 정해 놓고 정해진 캡션으로 상대방을 찾는 용도로 주로 많이 사용된다. 이 경우 윈도우의 캡션은 항상 고정되어 있어야 한다는 제약이 있다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
GetBkColor : COLORREF GetBkColor(HDC hdc);
현재 DC에 설정되어 있는 배경 색상을 조사한다. 배경 색상은 문자열 출력시 문자의 획 뒤쪽에 출력되는 색상이다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
GetBkMode : int GetBkMode(HDC hdc);
DC에 설정되어 있는 혼합 모드를 조사한다. 혼합 모드란 출력되는 문자열의 배경을 어떻게 처리할 것인가를 지정하는 값이며 불투명 모드, 투명 모드 두 가지가 있다. 혼합 모드에 대한 자세한 사항과 예제는 SetBkMode 함수를 참조하기 바란다. 디폴트 혼합 모드는 OPAQUE이다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
GetClassLong : DWORD GetClassLong( HWND hWnd, int nIndex);
윈도우 클래스는 WNDCLASS(EX) 구조체에 의해 속성들이 지정되며 RegisterClass(Ex) 함수에 의해 이 속성들이 등록된다. 일단 등록된 클래스의 속성을 조사하고자 할 때 이 함수를 사용하며 SetClassLong 함수로 속성값을 변경할 수도 있다. 속성값을 대입할 때는 SetClassLong 함수를 사용할 수 있지만 기존에 설정되어 있는 값을 편집하고자 할 경우는 GetClassLong 함수로 값을 조사하여 변경한 후 SetClassLong 함수로 다시 지정하면 된다. 예를 들어 윈도우 클래스의 스타일에 다른 스타일을 추가로 지정하고자 할 때는 먼저 값을 조사한 후 스타일에 원하는 추가 스타일을 OR 연산자로 지정해야 한다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
GetClientRect : BOOL GetClientRect(HWND hWnd, LPRECT lpRect);
윈도우의 작업영역 크기를 계산해 준다. 크기만 계산해 주기 때문에 좌상단(left, top)값은 항상 0,0이며 우하단 좌표(right, bottom)가 곧 윈도우의 크기를 나타낸다. 작업영역이란 윈도우의 타이틀바, 스크롤 바, 경계선, 메뉴 등을 제외한 영역이며 윈도우가 그리기를 하는 대상 영역이다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
GetDC : HDC GetDC( HWND hWnd);
윈도우즈 환경에서 화면이나 프린터로 출력을 하려면 DC를 먼저 구해야 한다. DC를 구하는 일반적인 방법은 두 가지가 있는데 WM_PAINT 메시지내에서 DC를 얻을 때는 BeginPaint, EndPaint 함수쌍을 사용하며 이 메시지 이외의 코드에서 DC를 얻을 때는 GetDC, ReleaseDC 함수쌍을 사용한다. GetDC의 인수로 DC를 구하고자 하는 핸들을 주면 이 윈도우의 DC를 구해준다. 윈도우의 클래스 스타일에 따라 윈도우 DC와 클래스 DC가 구해지는 경우도 있으나 대부분의 경우 작업 영역에 그리기를 할 수 있는 커먼 DC가 리턴된다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
GetDeviceCaps : int GetDeviceCaps(HDC hdc, int nIndex);
DC가 참조하는 장치의 여러 가지 속성이나 능력을 조사한다. 이 값들은 장치에 대해 그리기나 기타 각종 설정 변경 등에 참고 정보로 사용된다. 예를 들어 플로터는 벡터의 직선이나 곡선을 그릴 수는 있지만 비트맵은 출력할 수 없으며 흑백 프린터는 색상을 표현하지 못한다. 이런 장치의 특성이나 능력을 이 함수로 반드시 먼저 조사한 후 가능한 기능일 때만 사용해야 한다.
이 함수로 조사할 수 있는 값의 종류가 많고 의미가 어려운 것도 있으므로 정확하게 의미를 파악한 후 사용해야 한다. 이 함수로 조사한 값을 부적절하게 사용할 경우 엉뚱한 동작을 할 수도 있다. 다른 방식으로는 조사하기 힘든 정보를 의외로 쉽게 구할 수도 있으므로 이 함수의 인덱스들은 한번씩 눈여겨 봐두는 것이 좋다
/////////////////////////////////////////////////////////////////////////////////////////////////////
GetDlgItem : HWND GetDlgItem(HWND hDlg,int nIDDlgItem);
대화상자내에서의 컨트롤은 ID로 구분된다. 컨트롤의 ID는 CreateWindow 함수의 hMenu인수로 지정하거나 리소스 편집기의 ID란에 정수로 지정한다.
같은 대화상자에 속한 컨트롤들은 중복된 ID를 가지지 않으며 ID는 컨트롤의 유일한 식별자 역할을 한다. 컨트롤의 ID를 알고 있으면 GetDlgItemInt(Text) 등의 함수로 컨트롤의 값을 읽거나 쓸 수 있으며 통지 메시지에서 어떤 컨트롤로부터 통지 메시지가 전달되었는지를 알 수 있다.
또한 대화상자내의 컨트롤들은 각각이 독립된 차일드 윈도우이므로 고유의 윈도우 핸들을 가진다. 컨트롤의 ID로부터 윈도우 핸들을 구하고자 할 때 이 함수를 사용한다. 일단 윈도우 핸들을 구하면 SetWindowText, ShowWindow, MoveWindow 등 윈도우를 대상으로 하는 모든 함수를 사용할 수 있다.
이 함수는 주로 대화상자에 속한 차일드의 윈도우 핸들을 구할 때 사용하지만 일반 윈도우에도 적용할 수 있다. 일반 윈도우에서도 차일드 컨트롤이 있고 이 컨트롤이 ID를 가지고 있으면 GetDlgItem 함수로 차일드 컨트롤의 ID를 구할 수 있다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
GetDlgItemInt : UINT GetDlgItemInt( HWND hDlg, int nIDDlgItem, BOOL *lpTranslated, BOOL bSigned );
이 함수는 WM_GETTEXT 메시지로 대화상자 컨트롤의 텍스트를 읽어 정수형으로 변환해 리턴해 준다. 만약 읽는 텍스트가 INT_MAX 또는 UINT_MAX 범위보다 더 클 경우 이 함수는 0을 리턴한다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
GetDlgItemText : UINT GetDlgItemText( HWND hDlg, int nIDDlgItem, LPTSTR lpString, int nMaxCount );
WM_GETTEXT 메시지를 컨트롤로 보내 컨트롤의 텍스트를 읽어 lpString 버퍼에 채워준다. 이때 컨트롤은 버튼, 에디트, 스태틱 등의 텍스트 표현이 가능한 컨트롤이어야 한다. 만약 버퍼 길이(nMaxCount)보다 문자열이 더 길면 문자열은 잘려진다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
GetFocus : HWND GetFocus(VOID);
현재 스레드의 윈도우중 포커스를 가진 윈도우, 즉 키보드 관련 메시지를 받을 윈도우의 핸들을 조사한다. 다른 스레드의 윈도우가 포커스를 가지고 있으면 NULL이 리턴된다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
GetLocalTime : VOID GetLocalTime(LPSYSTEMTIME lpSystemTime);
로컬 시간을 조사해 준다. 로컬 시간이란 시스템이 유지하는 시스템 시간(UTC)에서 현재 컴퓨터가 실행되고 있는 시간대와 일광절약 설정을 계산하여 변환한 시간이다. 대한민국의 로컬 시간은 UTC 시간보다 9시간 더 빠르므로 시스템 시간에서 9시간만큼 더해주어야 로컬 시간이 구해진다. 일반적으로 현지 시간이라고 하면 이 함수로 구해지는 로컬 시간을 의미한다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
GetMapMode : int GetMapMode(HDC hdc);
SetMapMode로 설정한 DC의 맵핑 모드를 조사해 준다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
GetMessage : BOOL GetMessage(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax);
호출한 스레드에서 메시지를 꺼내 첫번째 인수로 전달된 lpMsg구조체에 채워준다. 특정 윈도우(그 차일드도 포함된다)로 보내지는 메시지나 PostThreadMessage 함수에 의해 스레드로 보내진 메시지를 조사할 수 있으며 특정한 범위에 있는 메시지만 조사할 수도 있다. 이 함수는 다른 스레드나 다른 프로세스의 메시지는 조사하지 못하며 오직 호출 스레드의 메시지만 조사할 수 있다. 다음은 전형적인 메시지 루프의 예이다.
while(GetMessage(&Message,0,0,0)) {
TranslateMessage(&Message);
DispatchMessage(&Message);
}
return Message.wParam;
전체 루프는 while문으로 싸여져 있어 GetMessage가 WM_QUIT를 조사할 때까지 반복된다. GetMessage는 이 스레드에 속한 모든 윈도우에 대해 모든 메시지를 조사하여 Message구조체에 채워준다. 이 메시지는 DispatchMessage 함수에 의해 해당 윈도우의 윈도우 프로시저로 보내진다.
GetMessage 함수는 스레드 메시지 큐에서 메시지를 읽은 후 이 메시지를 큐에서 제거한다. 단 예외적으로 WM_PAINT 메시지는 이 메시지가 처리된 후에 메시지 큐에서 제거된다.
GetMessage 함수는 메시지 큐에 대기중인 메시지가 없을 경우 메시지가 전달될 때까지 무한히 대기한다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
GetObject : int GetObject(HGDIOBJ hgdiobj, int cbBuffer, LPVOID lpvObject);
GDI 오브젝트에 대한 정보를 구한다. 오브젝트 타입에 따라 적절한 구조체를 선언하고 그 구조체의 포인터를 lpvObject 인수로 전달해 주면 구조체에 조사된 정보를 채워 준다. 이 정보들은 일반적으로 오브젝트를 생성할 때 지정한 정보와 동일하다. 생성 정보를 가지고 있지 않거나 임의의 오브젝트에 대해 동작하는 범용적인 함수를 작성할 때는 이 함수로 오브젝트의 정보를 실행중에 조사해야 한다.
인수로 전달되는 임의의 비트맵에 대해 동작해야 하므로 GetObject 함수로 이 비트맵 오브젝트의 크기를 실행중에 조사하도록 하였다. BITMAP 구조체를 선언하고 GetObject로 정보를 조사한 후 bmWidth, bmHeight 멤버를 읽어 비트맵 크기를 구하였다. 따라서 이 함수는 어떤 크기의 비트맵이라도 임의의 위치에 출력할 수 있다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
GetOpenFileName : BOOL GetOpenFileName(LPOPENFILENAME lpofn);
파일 입출력을 하기 전에 대상 파일을 입력받기 위해 이 함수를 호출한다. 이 함수는 lpofn 구조체의 설정대로 파일 열기 공통 대화상자를 열어 주며 사용자가 선택한 파일의 완전 경로를 구조체로 다시 리턴해 준다. 함수를 호출하기 전에 먼저 구조체에 초기값을 적절하게 설정해 주어야 하며 리턴값과 구조체의 결과값으로 사용자가 선택한 파일명을 구할 수 있다. 이렇게 입력받은 파일명은 이후 CreateFile 등의 함수로 열어서 입출력에 사용한다.
OPENFILENAME 구조체를 선언하고 이 구조체의 모든 멤버를 0으로 초기화해 준 후 필수적으로 필요한 멤버에만 값을 대입해 주었다. lpstrFile 멤버에는 사용자가 선택한 파일명을 리턴받기 위한 충분한 길이의 버퍼 포인터를 반드시 대입해 주어야 함을 유의하도록 하자. 사용자가 파일을 선택했으면 lpstrFile 멤버를 읽어 어떤 파일을 선택했는지 메시지 박스로 보여준다. 이 멤버로 리턴되는 경로는 CreateFile 함수에 곧바로 사용할 수 있다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
GetPixel : COLORREF GetPixel(HDC hdc, int nXPos, int nYPos);
hdc의 한 점에 출력되어 있는 색상을 조사한다. 이 함수는 자주 사용되지는 않지만 복잡한 영역에 대한 좌표 점검을 할 때 색상으로 특정 좌표의 영역을 조사하는 용도로 종종 사용된다. 화면이나 메모리 DC등은 이 함수를 지원하지만 프린터나 플로터 등은 이 함수를 지원하지 못한다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
GetROP2 : int GetROP2(HDC hdc);
DC에 설정되어 있는 ROP값을 조사한다. ROP값은 이미 그려져 있는 값과 그려지는 값과의 관계를 정의하는 값이며 SetROP2 함수에 의해 설정한다. 디폴트 ROP값은 R2_COPYPEN이다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
GetScrollInfo : BOOL GetScrollInfo(HWND hwnd, int fnBar, LPSCROLLINFO lpsi);
스크롤 바위 위치, 범위, 페이지 크기, 트래킹중의 위치 등을 조사한다. 이 함수를 사용하면 WM_THUMBTRACK 메시지 등에서 스크롤 바의 32비트 범위값을 조사할 수 있다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
GetStockObject : HGDIOBJ GetStockObject( int fnObject);
스톡 오브젝트(Stock Object)는 운영체제가 기본적으로 제공해주는 GDI 오브젝트이다. 생성할 필요가 없으며 이 함수로 핸들을 구해 언제든지 사용할 수 있고 파괴시켜 주지 않아도 된다. 다음 코드는 흰색 스톡 브러시를 구해 윈도우 클래스의 배경 브러시로 지정한다.
WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
이 윈도우는 배경을 지울 필요가 있을 때 희색 브러시를 사용하므로 배경은 항상 흰색으로 채색된다
/////////////////////////////////////////////////////////////////////////////////////////////////////
GetSubMenu : HMENU GetSubMenu(HMENU hMenu, int nPos);
메뉴 바에서 하위 메뉴를 구한다. 이 함수로 메뉴 바에 있는 하위 메뉴 하나에 대한 핸들을 구한 후 팝업 메뉴로 출력할 수 있다. 이 함수에 대한 사용예는 TrackPopupMenu 함수를 참조하기 바란다
/////////////////////////////////////////////////////////////////////////////////////////////////////
GetSystemDirectory : UINT GetSystemDirectory(LPTSTR lpBuffer, UINT uSize);
윈도우즈 시스템 디렉토리의 경로를 구한다. lpBuffer는 경로를 대입받을 수 있는 충분한 길이를 제공해야 하는데 일반적으로 MAX_PATH길이면 충분하다. 조사된 경로는 백슬레쉬 문자를 포함하지 않는다. 시스템 디렉토리는 운영체제 동작에 필수적으로 필요한 DLL, OCX, DRV 등의 중요한 파일을 가진다.
시스템 폴더는 윈도우즈 디렉토리 아래에 있으며 일반적으로 95/98계열은 System이라는 이름을 가지며 NT/2000계열은 System32라는 이름을 가진다. 그러나 다음 버전의 운영체제에서는 이 디렉토리의 이름이 바뀔 수도 있으므로 시스템 디렉토리의 경로가 필요한 경우는 반드시 이 함수로 그 경로를 조사하여 사용해야 한다. 예를 들어 시스템 폴더에 DLL을 복사하는 설치 프로그램의 경우 이 폴더의 경로를 정확하게 구해 복사해야 모든 프로그램이 DLL을 제대로 공유할 수 있다. 다음 코드는 Src 경로에 있는 MyProgram.dll을 윈도우즈 시스템 폴더로 복사한다.
GetSystemDirectory(Dest,MAX_PATH);
strcat(Dest,"\\MyProgram.dll");
CopyFile(Src,Dest,FALSE);
일반적으로 설치 프로그램이 이 함수를 많이 사용하는데 마찬가지 이유로 설치 해제 프로그램도 삭제할 프로그램의 정확한 경로를 조사하기 위해 이 함수를 사용해야 한다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
GetSystemMetrics : int GetSystemMetrics( int nIndex );
시스템 설정 정보를 조사한다. nIndex가 지정하는 정보를 조사해 주며 각 값을 해석하는 방법은 nIndex에 따라 다르다. 시스템의 설정값은 실행중에도 항상 변경될 수 있으므로 이 함수로 필요한 설정 정보를 그때 그때 조사해서 사용해야 한다. 예를 들어 마우스가 설치되어 있지 않은 시스템에서 실행을 거부한다거나 할 때 이 함수로 마우스 설치 여부를 조사할 수 있다. 이 함수는 값을 조사할 수만 있으며 변경할 수는 없다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
GetTextAlign : UINT GetTextAlign(HDC hdc);
텍스트 정렬 방식을 조사한다. 정렬 방식에 대해서는 SetTextAlign 함수의 예제를 참고하기 바란다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
GetTextColor : COLORREF GetTextColor(HDC hdc);
DC에 설정되어 있는 텍스트의 전경색을 조사한다. 전경색은 출력되는 문자의 색상을 지정하며 디폴트 전경색은 검정색이다. 전경색은 SetTextColor 함수로 변경할 수 있으며 이 함수는 현재 설정된 전경색을 조사한다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
GetTextMetrics : BOOL GetTextMetrics(HDC hdc, LPTEXTMETRIC lptm);
DC에 현재 선택되어 있는 폰트의 여러 가지 정보를 조사한다. 주로 폰트의 크기에 대한 정보를 얻을 수 있다리턴되는 정보는 다음과 같이 선언되어 있는 구조체이다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
GetWindowLong : LONG GetWindowLong( HWND hWnd, int nIndex);
CreateWindow(Ex) 함수로 윈도우를 생성할 때 지정한 윈도우의 속성을 조사한다. 일단 생성된 윈도우의 속성을 조사하고자 할 때 이 함수를 사용하며 SetWindowLong 함수를 사용하면 속성을 변경할 수도 있다. 단순히 속성을 변경할 때는 SetWindowLong 함수를 사용하지만 기존의 속성값을 편집하고자 할 경우는 이 함수로 먼저 속성값을 읽어야 한다. 예를 들어 윈도우의 스타일에 다른 스타일을 추가로 지정하고자 할 때는 먼저 값을 조사한 후 스타일에 원하는 추가 스타일을 OR 연산자로 지정해야 한다.윈도우의 속성을 변경하는 예제는 SetWindowLong 함수를 참조하기 바란다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
GetWindowRect : BOOL GetWindowRect(HWND hWnd, LPRECT lpRect);
윈도우의 현재 위치와 크기를 구해준다. (left, top)은 윈도우의 현재 좌상단 위치를 나타내는데 이 좌표는 전체 화면을 기준으로 한 좌표이다. (right, bottom)은 윈도우의 우하단 위치를 나타내며 역시 전체 화면을 기준으로 한 좌표이다. 윈도우의 현재 크기(폭과 높이)를 구하고 싶으면 right-left, bottom-top을 계산하면 된다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
GetWindowsDirectory : UINT GetWindowsDirectory(LPTSTR lpBuffer, UINT uSize);
운영체제가 설치되어 있는 경로를 구한다. lpBuffer는 경로를 대입받을 수 있는 충분한 길이를 제공해야 하는데 일반적으로 MAX_PATH길이면 충분하다. 조사된 경로는 백슬레쉬 문자를 포함하지 않으나 단, 윈도우즈가 루트 디렉토리에 설치된 겨우는 백슬레쉬 문자를 가질 수도 있다.
운영체제가 설치되는 폴더는 일반적으로 95/98 계열은 C:\Windows이며 NT/2000 계열은 C:\Winnt이나 설치시의 상황에 따라 또는 사용자의 특별한 지정이 있을 경우는 다른 폴더가 될 수도 있다. 따라서 반드시 이 함수로 설치된 경로를 조사한 후 사용해야 한다. 이 폴더에는 초기화 파일(INI)과 도움말 파일, 스크린 세이버 등의 주요 파일이 복사되어 있다. 윈도우즈 디렉토리에 설치되어 있는 Some.scr 이라는 스크린 세이버의 완전 경로를 조사하고 싶다면 다음 코드를 작성한다.
TCHAR ScrPath[MAX_PATH];
GetWindowsDirectory(ScrPath,MAX_PATH);
lstrcat(ScrPath,"\\Some.scr");
윈도우즈 디렉토리에 있는 파일이라고 해서 c:\Windows\Some.scr이라고 함부로 가정해서는 안된다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
GetWindowText : int GetWindowText( HWND hWnd, LPTSTR lpString, int nMaxCount);
윈도우의 캡션을 조사한다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
InvalidateRect : BOOL InvalidateRect(HWND hWnd, CONST RECT *lpRect, BOOL bErase);
운영체제는 윈도우의 작업 영역중 일부에 무효 영역이 있으면 WM_PAINT 메시지를 보내 다시 그리도록 한다. 프로그램 내부에서 작업 영역을 변경한 경우 이 함수로 변경된 부분을 무효화해 주어야 WM_PAINT 메시지가 발생하며 화면이 다시 그려진다. 배경을 지우고 그려야 할 때는 bErase를 TRUE로 설정해 주어야 이전에 출력되어 있던 내용이 삭제되고 다시 그려진다. 그리기 속도를 최대한 빠르게 하려면 lpRect에 무효화할 최소한의 영역을 지정하여 꼭 필요한 부분만 다시 그리도록 해 주어야 한다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
IsDlgButtonChecked : BOOL IsDialogMessage(HWND hDlg, LPMSG lpMsg);
lpMsg의 메시지가 hDlg 대화상자를 위한 메시지인지를 검사하고 만약 그렇다면 이 메시지를 대화상자 프로시저로 보내 처리하도록 한다. 예를 들어 Tab키나 커서 이동키를 누를 경우 컨트롤간의 포커스 이동이나 라디오 그룹내에서의 포커스 이동을 처리한다. 이 함수 내부에서 메시지의 변환 전송을 모두 처리하므로 이 메시지가 TRUE를 리턴하면, 즉 이 함수에 의해 메시지가 처리되었으면 이 메시지는 더 이상 DispatchMessage 함수로 전달되지 않아도 상관없다.
주로 모델리스 대화상자를 위해 이 함수를 사용하지만 컨트롤을 가지고 있는 모든 윈도우에 이 함수를 사용할 수 있다. 이 함수에 대한 예제 코드는 CreateDialog 함수를 참조한다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
IsIconic : BOOL IsIconic( HWND hWnd );
hWnd 윈도우가 최소화 상태, 즉 아이콘 상태인지를 조사한다. 최소화된 상태에서는 특별한 다른 처리를 하고자 할 때 이 함수로 윈도우의 현재 상태를 조사할 수 있다. 예를 들어 최소화 상태일 때 아이콘을 직접 그리고 싶으면 WM_PAINT에서 이 함수를 호출하여 현재 상태를 조사하고 작업 영역 대신 아이콘으로 출력을 내보낸다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
IsWindow : BOOL IsWindow(HWND hWnd);
인수로 주어진 hWnd가 유효한 윈도우 핸들인지 조사한다. 이 윈도우가 존재하는지, 생성되어 있는지 검사하고자 할 때 이 함수를 사용한다. CreateDialog의 예제를 보면 모델리스 대화상자의 존재 여부를 조사할 때 이 함수를 사용하는 코드를 볼 수 있다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
IsWindowEnabled : BOOL IsWindowEnabled( HWND hWnd );
hWnd 윈도우가 사용 가능한 상태인지 조사한다. 사용 가능한 윈도우만 사용자로부터 입력을 받아들일 수 있다. 그러나 사용 금지된 윈도우도 내부적인 메시지는 처리한다. 버튼, 에디트 등의 컨트롤이 입력을 받을 수 있는 상태인지를 조사할 때 이 함수가 사용된다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
IsWindowVisible : BOOL IsWindowVisible( HWND hWnd );
윈도우가 보이는 상태인지 숨겨진 상태인지를 조사한다. 윈도우가 화면에 보이려면 WS_VISIBLE 스타일을 가지고 있어야 하며 또한 부모 윈도우가 WS_VISIBLE 스타일을 가지고 있어야 한다. 보인다는 뜻은 이 스타일이 설정되어 있다는 뜻일 뿐 실제로 화면에 나타나 있다는 뜻은 아니다. 이 함수가 TRUE를 리턴하더라도 다른 윈도우에 완전히 가려져 있을 경우 화면에 보이지 않을 수도 있으며 폭이나 높이가 0일 경우도 이 함수는 TRUE를 리턴하지만 화면에서는 숨겨져 있을 수 있다. 이 함수는 다만 윈도우의 WS_VISIBLE 스타일이 설정되어 있는지만을 검사할 뿐이다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
IsZoomed : BOOL IsZoomed( HWND hWnd );
hWnd 윈도우가 최대화되어 있는 상태인지를 조사한다. 최대화된 상태에서는 특별한 다른 처리를 하고자 할 때 이 함수로 윈도우의 현재 상태를 조사할 수 있다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
KillTimer : BOOL KillTimer(HWND hWnd, UINT_PTR uIDEvent);
SetTimer에 의해 설치된 타이머를 해제한다. 메시지 큐에 이미 포스팅된 WM_TIMER 메시지가 있을 경우 이 함수는 메시지를 제거하지 않는다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
LineTo : BOOL LineTo(HDC hdc, int nXEnd, int nYEnd);
현재 위치에서 (nXEnd, nYEnd) 끝점까지 선을 긋는다. 이때 끝점은 선에서 제외된다. 선을 긋고 난 후 현재 위치를 끝점으로 옮겨주므로 LineTo 함수를 계속 호출하면 선을 이어서 그릴 수 있다. 현재 위치는 DC에 보관되어 있으며 MoveToEx 함수로 변경할 수 있다.
그려지는 선은 DC에 선택되어 있는 펜으로 그려지므로 선의 모양을 변경하려면 펜을 생성한 DC에 선택해 주어야 한다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
LoadAccelerator : HACCEL LoadAccelerators(HINSTANCE hInstance, LPCTSTR lpTableName);
응용 프로그램의 리소스에 정의된 액셀러레이터 테이블을 읽어온다. 액셀러레이터 테이블은 응용 프로그램이 사용하는 단축키의 목록을 가지는 리소스이다. 이 함수로 읽어온 액셀러레이터 테이블은 메시지 루프에서 TranslateAccelerator 함수에 의해 해석되어 WM_COMMAND 메시지로 변환된다. 이 함수로 읽어온 액셀러레이터 테이블은 응용 프로그램이 종료될 때 자동으로 파괴되므로 직접 파괴해주지 않아도 된다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
LoadBitmap : HBITMAP LoadBitmap(HINSTANCE hInstance, LPCTSTR lpBitmapName);
비트맵 리소스를 읽어온다. 리소스에 정의된 비트맵은 장치에 독립적인 DIB 포맷으로 저장되어 있으나 이 함수로 읽혀질 때 현재 화면 모드와 호환되는 DDB로 변환된다. 따라서 이 함수로 읽은 비트맵은 호환 DC에 곧바로 선택할 수 있으며 BitBlt 함수로 출력할 수 있다. 비트맵 출력 예제는 BitBlt 함수를 참조한다. 비트맵을 다 사용하고 난 후에는 반드시 DeleteObject 함수로 삭제해 주어야 한다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
LoadCursor : HCURSOR LoadCursor(HINSTANCE hInstance, LPCTSTR lpCursorName);
표준 커서 또는 응용 프로그램의 리소스에 정의되어 있는 커서를 읽어온다. 단, 이미 커서가 로드되어 있을 때는 다시 읽지 않고 읽어 놓은 커서의 핸들을 구해 준다. 만약 lpCursorName 인수가 가리키는 리소스가 커서가 아닌 다른 리소스이더라도 이 함수는 NULL을 리턴하지 않으므로 반드시 커서 리소스만 지정하도록 주의해야 한다. 하나의 커서 리소스에 여러 가지 색상의 커서가 있을 경우 현재 화면 설정에 가장 적합한 커서를 읽어준다
/////////////////////////////////////////////////////////////////////////////////////////////////////
LoadIcon : HICON LoadIcon(HINSTANCE hInstance, LPCTSTR lpIconName);
표준 아이콘 또는 응용 프로그램의 리소스에 정의되어 있는 아이콘을 읽어온다. 단, 이미 아이콘이 로드되어 있을 때는 다시 읽지 않고 읽어 놓은 아이콘 핸들을 구해 준다. 아이콘 리소스 하나에 여러 포맷의 아이콘이 존재할 수 있는데 이 함수는 현재 화면 설정에 가장 적합한 아이콘을 읽어온다. 아이콘 리소스는 흑백일 수도 있고 색상을 가지고 있을 수도 있다.
이 함수는 현재 시스템 메트릭스가 정의하는 SM_CXICON, SM_CYICON 크기의 아이콘만 읽을 수 있는데 이 크기는 통상 32*32이다. 16*16크기의 작은 아이콘이나 기타 표준 아이콘 크기와 다른 크기의 아이콘을 읽을 때는 LoadImage 함수를 사용해야 한다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
LoadMenu : HMENU LoadMenu(HINSTANCE hInstance, LPCTSTR lpMenuName);
메뉴 리소스를 읽어온다. 메뉴는 통상 리소스로 작성되며 링크시 실행 파일에 합쳐진다. 윈도우에 메뉴를 붙이는 방법은 여러 가지가 있는데 가장 흔하게 사용되는 방법은 윈도우 클래스의 lpszMenuName 멤버에 사용할 메뉴 리소스를 지정해 주는 것이다.
WndClass.lpszMenuName=MAKEINTRESOURCE(IDR_MENU1);
lpszMenuName 멤버에 메뉴 리소스를 대입해 주면 이후부터 이 윈도우 클래스로부터 생성되는 모든 윈도우는 이 메뉴 리소스를 사용한다. 두번째 방법은 CreateWindow의 hMenu 멤버에 사용할 메뉴 핸들을 대입해 주는 것이다. 만약 윈도우 클래스에도 메뉴가 지정되어 있고 CreateWindow에도 메뉴 핸들이 지정되어 있으면 CreateWindow의 메뉴 지정이 우선이므로 윈도우 클래스에 있는 메뉴 대신 다른 메뉴를 사용하려면 CreateWindow에 메뉴 핸들을 지정하면 된다. 하지만 통상적으로 한 윈도우 클래스로부터 하나의 메인 윈도우를 만드므로 첫번째 방법이 훨씬 더 많이 사용된다.
메뉴를 사용하는 세번째 방법은 실행중에 메뉴를 읽어와 윈도우에 붙이는 것이며 이때 LoadMenu 함수가 사용된다. LoadMenu로 읽어온 메뉴 핸들을 SetMenu 함수로 윈도우에 붙여주면 된다. 단, 이때 LoadMenu로 읽은 메뉴 핸들은 반드시 DestroyMenu 함수로 해제해 주어야 한다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
LoadString : int LoadString(HINSTANCE hInstance, UINT uID, LPTSTR lpBuffer, int nBufferMax);
리소스에서 문자열을 읽어 지정한 버퍼에 채워준다. 문자열의 끝에 널 종료 문자를 덧붙여 주므로 이 함수로 읽은 문자열은 곧바로 사용할 수 있다. 프로그램 사용법이나 안내문, 에러 메시지 등의 문자열은 코드에서 바로 정의해서 쓰지 말고 가급적이면 문자열 리소스로 정의해서 사용하는 것이 일괄적으로 수정하기에 편리하다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
MessageBeep : BOOL MessageBeep(UINT uType);
지정한 사운드를 연주한다. 이 함수는 사운드를 큐에 넣은 후 즉각 리턴하며 사운드는 비동기적으로 연주되므로 곧바로 다른 작업을 할 수 있다. 만약 지정한 사운드를 연주할 수 없으면 시스템 디폴트 비프음을 내며 시스템 디폴트 음도 낼 수 없으면 스피커로 표준 비프음을 낸다. 사용자에게 사운드로 주의를 주고자 할 때 이 함수를 사용하며 또한 디버깅용으로도 자주 사용된다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
MessageBox : int MessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType);
메시지 박스는 응용 프로그램이 사용자와 대화할 수 있는 가장 간단한 방법이다. 짧은 메시지와 함께 MB_OK 플래그로 간단하게 전달 사항만 전달하는 것이 보편적이다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
MoveFile : BOOL MoveFile(LPCTSTR lpExistingFileName, LPCTSTR lpNewFileName);
파일이나 디렉토리를 다른 위치로 옮긴다. 파일의 경우 같은 디렉토리의 다른 이름으로 변경할 수도 있으며 디렉토리는 포함된 모든 파일과 서브 디렉토리를 같이 이동시킨다. 위치를 옮기는 것은 원래 파일을 지우고 새 위치에 파일을 생성하는 것과 동일하지만 같은 드라이브내에서는 디스크 할당 표만 수정하고 실제 데이터는 이동하지 않아도 되므로 CopyFile 함수를 사용하는 것보다 이 함수를 사용하는 것이 훨씬 더 빠르다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
MoveFileEx : BOOL MoveFileEx(LPCTSTR lpExistingFileName, LPCTSTR lpNewFileName, DWORD dwFlags);
MoveFile과 마찬가지로 파일이나 디렉토리를 다른 위치로 옮기되 세부적인 동작에 대해 몇가지 플래그를 지정할 수 있다는 점이 다르다. 특히 재부팅할 때 실제로 파일을 옮겨 주는 기능은 설치 프로그램이 이미 사용중인 DLL을 교체하는 용도로 자주 사용된다. 이 함수는 다음 부팅시 이동할 파일을 레지스트리의 다음 위치에 기록해 놓는다.
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations
이 값은 복수개의 널 종료 문자열로 구성되는 REG_MULTI_SZ 타입으로 되어 있으며 이동 대상이 되는 파일 목록을 가진다. 재부팅할 때 AUTOCHK 후 이 레지스트리에 기록된 대로 파일을 이동시키는데 이 때는 페이징 파일도 생성되기 전이므로 페이징 파일까지도 삭제할 수 있다.
단 재부팅 시 파일 이동은 NT/2000 이상에서만 지원되며 95/98에서는 이 기능을 사용할 수 없다. 대신 WinInit.ini 파일에 이동할 파일이나 디렉토리를 적어주면 되다. 이 파일의 [rename]섹션에 "대상=원본" 형식으로 엔트리를 작성해 놓으면 파일명이 변경된다. 단, 이 동작은 운영체제가 보호 모드로 들어가기 전에 이루어지므로 파일명은 반드시 짧은 이름으로 작성해야 한다. 파일명을 변경한 후 시스템은 WinInit.ini를 WinInit.bak로 변경하여 이 파일을 무효화시킨다.
재부팅시 파일을 교체하는 방법이 운영체제 버전에 따라 상이하므로 GetVersionEx 함수로 운영체제의 버전을 판변한 후 적절한 방법을 사용해야 한다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
MoveToEx : BOOL MoveToEx(HDC hdc, int X, int Y, LPPOINT lpPoint);
DC에는 현재 좌표가 보관되어 있으며 현재 좌표는 LineTo, PolyLineTo 등의 함수가 선의 시작점으로 사용한다. MoveToEx 함수는 현재 좌표를 (X,Y)좌표로 이동시켜 준다. 현재 위치는 LineTo, PolyLine등의 함수에 의해서도 변경된다.
이 함수의 16비트 버전은 MoveTo였으나 이 함수는 Win32에서 제거되었다. Win32에서 좌표값이 32비트로 확장됨으로써 리턴값 하나로 이전 좌표를 리턴할 수가 없게 됨에 따라 lpPoint로 이전 좌표를 조사하도록 변경되었다. 이 함수에 대한 예제는 LineTo 함수의 예제를 참고하기 바란다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
MoveWindow : BOOL MoveWindow(HWND hWnd, int X, int Y, int nWidth, int nHeight, BOOL bRepaint);
윈도우의 위치와 크기를 변경하는 가장 일반적인 함수이다. X,Y 인수로 윈도우의 위치를 지정하며 nWidth, nHeight 인수로 윈도우의 폭과 높이를 지정하므로 이 함수로 위치와 크기를 한꺼번에 변경할 수 있다. 단 위치만 변경하거나 크기만 변경하고자 할 경우는 GetWindowRect 등의 함수로 영역을 먼저 구한 후 원하는 값만 변경하거나 아니면 SetWindowPos 함수를 사용해야 한다.
이 함수는 일반적으로 부모 윈도우내에서 차일드 컨트롤을 정렬하기 위한 용도로 많이 사용하며 최상위 윈도우의 크기나 위치를 변경할 때는 이 함수 대신 SetWindowPos 함수를 사용하는 것이 바람직하다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
OutputDebugString : VOID OutputDebugString(LPCTSTR lpOutputString);
문자열을 디버거로 출력한다. 이 함수는 순수한 디버깅용의 함수이며 디버깅중에 프로그램의 실행 흐름과 상태를 쉽게 확인하기 위해 사용한다. 디버거(보통 비주얼 C++)가 없을 경우 시스템 디버거로 문자열을 보내며 시스템 디버거도 없을 경우 이 함수는 아무 일도 하지 않는다. 프로그램 실행중에 변수값이나 제어의 흐름을 확인하고자 할 때 메시지 박스 대신 이 함수를 사용한다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
PatBlt : BOOL PatBlt(HDC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, DWORD dwRop);
지정한 사각 영역을 채색하되 현재 DC에 선택되어 있는 브러시와 화면의 색상을 논리 연산한다. 논리 연산의 종류에 따라 두 색상을 다양하게 혼합할 수 있다. 비트맵 브러시가 선택되어 있다면 이 함수로 비트맵을 출력할 수도 있다. 모든 장치가 이 함수를 다 지원하는 것은 아니므로 GetDeviceCaps 함수의 RC_BITBLT 인덱스로 이 함수가 지원되는지를 먼저 조사한 후 사용해야 한다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
PeekMessage : BOOL PeekMessage(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg);
GetMessage 함수와 마찬가지로 메시지 큐에서 메시지를 읽는다. 메시지의 범위를 줄 수 있는 기능도 GetMessage와 동일하다. 그러나 이 함수는 GetMessage와는 달리 읽은 메시지를 무조건 제거하지 않으며 큐가 비어 있을 경우 대기하지 않고 곧바로 리턴한다는 점이 다르다. 따라서 이 함수는 메시지를 읽지 않고 단순히 메시지가 있는지 확인만 할 수 있으며 이런 특성은 백그라운드 작업에 적절하다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
PostMessage : LRESULT PostMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
메시지를 해당 윈도우의 메시지 큐에 붙이며 즉시 리턴한다. 이렇게 붙여진 메시지는 메시지 루프의 GetMessage 함수에 의해 꺼내져서 DiepatchMessage 함수에 의해 윈도우 프로시저로 보내지며 최종적으로 윈도우 프로시저에 의해 처리된다.
SendMessage와는 달리 메시지를 큐에 붙인 후 곧바로 리턴하므로 이 메시지는 곧바로 처리되지 않으며 메시지를 붙인 스레드는 곧바로 다른 작업을 할 수 있다.
메시지를 붙이는 시점과 메시지를 처리하는 시점이 비동기적이기 때문에 PostMessage의 wParam, lParam으로 포인터를 전달하는 것은 의미가 없다. 메시지를 붙일 때 존재하던 값이 메시지를 처리하는 시점에서는 사라질 수 있기 때문이다. 특히 WM_COPYDATA 메시지는 임시적인 데이터를 전역 공유 메모리에 생성한 후 전달하는데 이 메시지는 절대로 PostMessage로 붙일 수 없으며 SendMessage로만 보내야 한다.
PostMessage 호출의 아주 특수한 경우로 첫번째 인수가 NULL일 수도 있는데 이 경우는 특정 윈도우에게 메시지를 붙이는 것이 아니라 응용 프로그램 전반에 걸친 작업 지시를 보내는 경우이다. 대상 윈도우가 없기 때문에 이렇게 붙여진 메시지는 윈도우 프로시저까지 전달되지 않으며 메시지 루프에서 직접 처리해야 한다. 이때의 메시지 루프는 다음과 같이 작성한다.
while(GetMessage(&Message,0,0,0)) {
if (Message.message==WM_SOME) {
// 직접 처리
} else {
TranslateMessage(&Message);
DispatchMessage(&Message);
}
}
GetMessage로 읽은 메시지가 대상 윈도우가 없는 스레드 전반에 걸친 메시지이므로 DispatchMessage를 호출하기 전에 while루프 내부에서 직접 처리해 주어야 한다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
PostQuitMessage : VOID PostQuitMessage(int nExitCode);
스레드 메시지 큐에 WM_QUIT 메시지를 붙이고 즉시 리턴한다. WM_QUIT 메시지를 큐에 붙임으로써 시스템에게 이 스레드가 종료될 것이라는 것을 미리 알려준다. 메시지 루프는 보통 WM_QUIT 메시지를 받으면 종료하도록 되어 있으므로 이 함수를 호출하면 메시지 루프가 종료된다. 특히 이 함수를 호출하는 스레드가 주 스레드일 경우는 주 스레드의 메시지 루프가 종료됨으로써 프로세스가 종료된다.
단, 이 함수는 메시지를 큐에 붙인 후 즉시 리턴하므로 호출 즉시 프로세스가 종료되는 것은 아니다. 즉 PostQuitMessage 호출 후 다른 처리를 계속할 수 있으며 이미 메시지 큐에 들어와 있는 모든 메시지가 처리된 후에 WM_QUIT 메시지가 읽혀져야 종료된다. 반면 ExitProcess 함수는 즉시 프로세스를 종료하기 때문에 이 함수 아래에 작성된 코드는 실행되지 않는다.
통상 이 함수는 메인 윈도우의 WM_DESTROY 메시지 처리 코드에 작성되어 메인 윈도우가 파괴되면 응용 프로그램을 종료하는 역할을 한다. 차일드 윈도우가 WM_DESTROY에서 이 메시지를 호출해서는 안된다. 그래서 DefWindowProc은 WM_DESTROY 메시지를 디폴트 처리할 때 PostQuitMessage를 호출하지 않도록 되어 있다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
ReadFile : BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped);
파일로부터 데이터를 읽는다. 주로 동기적인 입력에 사용하므로 데이터를 완전히 읽기 전에는 리턴하지 않는다. 비동기 입력에 사용할 경우는 즉시 리턴한다. 파일 포인터 위치에서부터 데이터를 읽으며 다 읽은 후 실제 읽은 바이트 수만큼 파일 포인터를 이동시켜 준다. 단, 비동기 입출력중일 때는 응용 프로그램이 파일 포인터를 직접 이동시켜 주어야 한다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
Rectangle : BOOL Rectangle(HDC hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);
지정한 사각형을 그린다. 사각형의 변은는 현재 DC에 선택된 펜으로 그려지며 내부는 현재 DC에 선택된 브러시로 채워진다. 터보C의 Rectangle 함수와는 달리 내부를 채우므로 도스 프로그래밍을 해 본 사람은 주의해야 한다. 내부를 채우지 않으려면 NULL_BRUSH 스톡 오브젝트를 선택한 후 사각형을 그려야 한다. Ellipse의 예제를 참고하기 바란다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
RegisterClass : ATOM RegisterClass(CONST WNDCLASS *lpWndClass);
윈도우 클래스를 등록한다. 윈도우 클래스는 생성될 윈도우의 여러 가지 특성을 가지는 구조체이며 CreateWindow 함수로 윈도우를 생성하기 전에 윈도우 클래스가 반드시 등록되어 있어야 한다. WNDCLASS 구조체를 선언한 후 이 구조체에 원하는 속성을 설정하고 RegisterClass 함수로 윈도우 클래스를 등록한다. 다음 코드는 가장 일반적인 윈도우 클래스 등록 코드이다.
WNDCLASS WndClass;
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)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);
이 함수로 등록한 윈도우 클래스는 별도의 작은 아이콘을 지정할 수 없으며 hIcon 멤버가 지정하는 아이콘을 축소하여 작은 아이콘으로 대신 사용한다. 작은 아이콘을 따로 지정하려면 RegisterClassEx 함수를 사용해야 한다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
RegisterClassEx : ATOM RegisterClassEx(CONST WNDCLASSEX *lpwcx);
윈도우 클래스를 등록한다. RegisterClass 함수와 유사하되 이 함수가 사용하는 WNDCLASSEX 구조체는 작은 아이콘을 따로 등록할 수 있다는 점만 다르다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
ReleaseCapture : BOOL ReleaseCapture(VOID);
마우스 캡처를 푼다. 마우스를 캡처한 윈도우는 커서의 위치에 상관없이 모든 마우스 메시지를 받는데 이 함수로 캡처를 풀면 이 상태가 종료되며 마우스 메시지는 커서 아래쪽에 있는 윈도우로 전달된다. SetCapture로 마우스를 캡처한 윈도우는 필요한 동작을 완료한 후 반드시 이 함수를 호출하여 캡처를 풀어 주어야 한다예제는 SetCapture 함수를 참조하기 바란다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
ReleaseDC : int ReleaseDC(HWND hWnd, HDC hDC);
GetDC함수로 구한 커먼 DC의 핸들은 반드시 이 함수로 해제해 주어야 한다. 그러나 클래스 DC나 프라이비트 DC는 해제해 주지 않았도 된다. GetWindowDC로 구한 DC는 반드시 이 함수로 해제해 주어야 한다. 이 함수는 GetDC를 호출한 스레드 내에서 호출되어야 하며 다른 스레드에서 호출할 수 없다. GetDC 함수의 예제를 참고하기 바란다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
ScreenToClient : BOOL ScreenToClient(HWND hWnd, LPPOINT lpPoint);
화면의 원점을 기준으로 하는 좌표 lpPoint를 hWnd의 작업 영역을 기준으로 하는 좌표로 변환한다. hWnd윈도우의 작업 영역 원점의 화면 좌표가 cx, cy일 때 lpPoint는 lpPoint.x - cx, lpPoint - cy로 변환된다. GetCursorPos, MoveWindow, GetWindowRect 등과 같이 화면 좌표를 리턴하는 함수로부터 작업 영역의 좌표로 변환하고자 할 때 이 함수를 사용한다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
ScrollWindow : BOOL ScrollWindow(HWND hWnd, int XAmount, int YAmount, CONST RECT *lpRect, CONST RECT *lpClipRect);
윈도우를 스크롤시킨다. 일반적으로 이 함수는 WM_HSCROLL, WM_SCROLL 등의 스크롤 관련 메시지를 받았을 때 호출되며 스크롤 바로 스크롤 된 양만큼 작업 영역을 이동시키는 역할을 한다. 스크롤된 양만큼 작업 영역을 BitBlt 함수로 고속 복사하며 새로 드러나는 부분은 무효화시켜 WM_PAINT에서 다시 그리도록 해 준다.
만약 스크롤 영역에 캐럿이 있다면 스크롤하기 전에 캐럿을 숨기며 스크롤이 끝난 후 캐럿을 복구시켜준다. 캐럿의 위치는 자동으로 조정된다. 작업 영역의 일부부만을 스크롤시키고자 할 때는 lpRect에 스크롤 영역을 지정할 수 있으며 이때 화면의 깨짐을 방지하기 위해 클리핑 영역을 지정해 주는 것이 좋다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
SelectObject : HGDIOBJ SelectObject( HDC hdc,HGDIOBJ hgdiobj);
GDI는 그래픽 출력에 사용되는 도구이며 펜, 브러시, 비트맵, 리전, 패스, 팔레트, 폰트 등등이 있다. 그리기에 사용할 GDI 오브젝트를 변경하고자 할 때 이 오브젝트를 만든 후 이 함수로 DC에 선택해 주어야 한다. 다음은 브러시를 생성하여 DC에 선택하는 예이다.
HBRUSH MyBrush,OldBrush;
MyBrush=CreateSolidBrush(RGB(255,255,0));
OldBrush=(HBRUSH)SelectObject(hdc,MyBrush);
// 브러시를 사용한다.
SelectObject(hdc,OldBrush);
DeleteObject(MyBrush);
CreateSolidBrush로 MyBrush 브러시를 만든 후 SelectObject 함수로 이 브러시를 DC에 선택해 준다. 이 때 SelectObject가 리턴하는 이전 브러시의 핸들은 복구를 위해 OldBrush 등의 변수에 저장해 두어야 한다. 브러시를 선택한 후 모든 그리기 함수는 MyBrush로 면을 채색한다. 브러시를 사용한 후에는 반드시 DeleteObject 함수로 삭제해 주어야 하되 그전에 DC에 선택되어 있는 브러시를 선택해제해 주어야 한다. DC에 선택된 브러시는 삭제할 수 없기 때문이다. 그래서 OldBrush를 다시 선택해 주어 MyBrush를 해제하도록 하였다. 이 코드는 다음과 같이 한줄로 작성할 수도 있다.
DeleteObject(SelectObject(hdc,OldBrush));
SelectObject 함수가 이전에 선택되어 있던 같은 타입의 GDI 오브젝트를 리턴해 주기 때문에 리턴되는 브러시를 DeleteObject 함수로 삭제하였다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
SendMessage : LRESULT SendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
메시지를 윈도우에게 보낸다. 해당 윈도우의 윈도우 프로시저를 호출하여 이 메시지가 완전히 처리되기 전에는 리턴하지 않는다. 같은 스레드에 속한 윈도우에게 메시지를 보낼 때는 마치 서브루틴을 호출하는 것과 동일하다. 예를 들어 메인 윈도우가 차일드 윈도우인 리스트 박스에게 LB_ADDSTRING이나 LB_GETCOUNT 등의 메시지를 보내면 리스트 박스는 해당 동작을 수행하는 서브루틴을 호출하고 이 동작이 완료될 때까지 SendMessage는 리턴하지 않는다.
다른 스레드에 속한 윈도우에게 메시지를 보낼 때는 스레드 스위칭이 발생하며 메시지를 받는 스레드가 메시지를 읽는 코드를 실행중이어야 한다. 만약 메시지를 받는 스레드가 메시지 처리에 오랜 시간을 소모한다면 SendMessage를 호출한 스레드는 이 함수가 리턴할 때까지 블록 상태로 남아있게 된다.리스트 박스로 문자열을 추가할 때는 LB_ADDSTRING 메시지를 보내주면 된다. 이와 같이 부모 윈도우가 차일드에게 명령을 내리거나 상태를 조사하는 가장 기본적인 방법은 SendMessage로 메시지를 보내는 것이다. 각 차일드별로 보낼 수 있는 메시지의 종류가 다양하다.
SendMessage 함수는 보낸 메시지가 완전히 처리되기 전에는 리턴하지 않는 블록 특성을 가지고 있다. 특히 이런 특성은 다른 스레드간에 메시지를 주고 받을 때 자주 목격되는데 이 문제를 해결하는 방법에 대해서는 InSendMessage 함수를 참고하기 바란다.
WM_COPYDATA 등의 특정 메시지는 반드시 SendMessage 함수로만 보내야 하며 PostMessage를 쓸 수 없는 것도 있다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
SetBkColor : COLORREF SetBkColor(HDC hdc, COLORREF crColor);
TextOut나 ExtTextOut 함수로 출력되는 문자열은 DC에 설정되어 있는 배경색에 출력된다. 디폴트 DC의 배경색은 흰색이므로 아무 지정없이 문자열을 출력하면 흰 바탕에 문자열이 출력되나 이 함수로 배경색을 변경하면 출력되는 문자열의 배경색을 변경할 수 있다. SetTextColor 함수의 예제를 참고하기 바란다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
SetBkMode : int SetBkMode( HDC hdc, int iBkMode );
DC의 배경 혼합 모드(Mix Mode)를 설정한다. 혼합 모드란 새로 출력되는 문자열의 배경을 어떻게 처리할 것인가를 지정하는데 SetBkColor에 의해 설정된 배경색 또는 디폴트 배경색인 흰색으로 배경을 출력하는 OPAQUE와 문자열의 획 사이를 투명하게 처리하는 TRANSPARENT 두가지 방법이 있다. 디폴트 혼합 모드는 불투명 모드인 OPAQUE이므로 문자열의 배경 색상이 출력되나 이 모드를 변경하면 투명한 문자열을 출력할 수 있다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
SetCapture : HWND SetCapture(HWND hWnd);
마우스 버튼의 누름, 이동, 뗌 등의 마우스 메시지는 보통 커서 바로 아래쪽에 있는 윈도우로 전달된다. 이는 지극히 정상적이며 상식적이나 가끔 커서가 영역밖을 벗어나도 계속적으로 마우스 메시지를 받아야 하는 경우도 있다. 이런 경우는 마우스 커서를 캡처해야 한다. SetCapture 함수는 hWnd 윈도우가 마우스 커서를 캡처하도록 하며 이렇게 되면 커서가 윈도우의 영역밖을 벗어나더라도 계속해서 마우스 메시지를 보내준다. 이 상태는 ReleaseCapture 함수로 캡처를 풀기 전까지 계속된다. 주로 드래그 동작을 할 때 캡처가 필요하다현재 스레드에 속한 윈도우만 캡처를 할 수 있으며 한번에 하나의 윈도우만 마우스를 캡처할 수 있다. 마우스를 캡처한 윈도우는 모든 마우스 메시지를 전달받는데 단 예외적으로 다른 스레드에 속한 윈도우를 누를 경우는 캡처 여부에 상관없이 커서 아래쪽의 윈도우로 메시지가 전달되며 이 경우 해당 윈도우는 포그라운드 상태가 된다. 마우스 버튼 누름은 작업의 전환을 의미하므로 캡처 여부에 상관없이 해당 윈도우로 전달된다. 그러나 보통 마우스 버튼을 누른 상태에서 커서를 캡처하기 때문에 이런 경우는 극히 드물다.
포그라운드 윈도우가 마우스를 캡처하는 것이 보통이지만 백그라운드 윈도우도 마우스를 캡처할 수 있다. 이 경우 커서가 백그라운드 윈도우의 보이는 부분에 있을 때만 마우스 메시지가 전달된다. 캡처 상태에서는 메뉴의 핫키, 액셀러레이터 등은 동작하지 않는다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
SetClassLong : DWORD SetClassLong( HWND hWnd, int nIndex, LONG dwNewLong);
윈도우 클래스는 WNDCLASS(EX) 구조체에 의해 속성들이 지정되며 RegisterClass(Ex) 함수에 의해 이 속성들이 등록된다. 일단 등록된 클래스의 속성을 변경하고자 할 때 SetClassLong 함수가 사용되는데 WNDCLASS 구조체의 멤버 중 어떤 값을 변경할 것인가를 nIndex 인수로 지정해 주고 dwNewLong 인수로 새로운 속성값을 지정해 주면 된다. 단 윈도우 클래스의 정보 중 이름은 변경할 수 없다.
윈도우 클래스의 속성 중 어떤 것을 변경하는가에 따라 효과는 다양하게 나타난다. 배경 브러시를 변경할 수도 있고 커서 모양을 바꿀 수도 있고 윈도우 프로시저를 변경할 수도 있다. 이어지는 예제로 이 함수의 사용예를 살펴보도록 하자.
/////////////////////////////////////////////////////////////////////////////////////////////////////
SetCursor : HCURSOR SetCursor(HCURSOR hCursor);
마우스의 현재 위치를 알려주는 커서를 hCursor로 변경하되 만약 이미 hCursor가 설정되어 있다면 아무 일도 하지 않는다. 즉, 같은 커서를 두번 설정할 때는 불필요한 커서 변경을 하지 않는다. 여러벌의 커서를 준비해 두고 현재 상태에 따라 다른 모양의 커서를 사용하고자 할 경우 이 함수로 커서를 변경하면 된다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
SetDlgItemInt : BOOL SetDlgItemInt( HWND hDlg, int nIDDlgItem, UINT uValue, BOOL bSigned );
대화상자의 컨트롤에 정수값을 대입한다. 이때 컨트롤은 버튼, 에디트, 스태틱 등의 텍스트 표현이 가능한 컨트롤이어야 한다. 이 함수는 정수를 문자열로 변환한 후 WM_SETTEXT 메시지를 컨트롤로 보내 텍스트를 설정한다. 대입한 텍스트는 컨트롤의 적당한 위치에 나타난다. 다음 코드는 hDlg 대화상자의 IDC_EDIT1 컨트롤에 1234라는 정수를 대입한다.
SetDlgItemInt(hDlg,IDC_EDIT1,1234,FALSE);
이 함수는 내부적으로 정수를 문자열로 바꾼 후 문자열을 컨트롤에 대입하므로 다음 호출문과 동일하다.
itoa(1234,buf,10);
SetDlgItemText(hDlg,IDC_EDIT1,buf);
그러나 이렇게 직접 정수값을 문자열로 바꾼 후 대입할 경우 정수값을 16진수로 대입하거나 천단위로 콤마를 삽입하는 등의 추가 작업을 할 수 있다는 이점이 있다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
SetDlgItemText : BOOL SetDlgItemText( HWND hDlg, int nIDDlgItem, LPCTSTR lpString );
대화상자의 컨트롤에 텍스트를 대입한다. 이때 컨트롤은 버튼, 에디트, 스태틱 등의 텍스트 표현이 가능한 컨트롤이어야 한다. 이 함수는 WM_SETTEXT 메시지를 컨트롤로 보내 텍스트를 설정한다. 대입한 텍스트는 컨트롤의 적당한 위치에 나타난다. 다음 코드는 hDlg 대화상자의 IDC_EDIT1 에디트 컨트롤에 "테스트"라는 문자열을 대입한다.
SetDlgItemText(hDlg, IDC_EDIT1, "테스트");
이 함수 호출문은 다음 함수 호출문과 동일하다. 컨트롤의 윈도우 핸들을 구한 후 SetWindowText 함수로 텍스트를 대입할 수도 있고 WM_SETTEXT 메시지를 사용할 수도 있다.
SetWindowText(GetDlgItem(hDlg,IDC_EDIT1),"테스트");
SendMessage(GetDlgItem(hDlg,IDC_EDIT1),WM_SETTEXT,0,(LPARAM)"테스트");
이 두 함수는 GetDlgItem 함수로 윈도우 핸들을 먼저 구한 후 텍스트를 대입하지만 SetDlgItemText 함수는 컨트롤의 ID로 텍스트를 대입할 수 있기 때문에 훨씬 더 편리하다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
SetFocus : HWND SetFocus(HWND hWnd);
포커스란 입력 촛점이며 포커스를 가진 윈도우에게 키보드 메시지가 전달된다. 한번에 하나의 윈도우만 포커스를 가질 수 있으며 보통 사용자가 컨트롤을 선택함으로써 포커스를 이동시키지만 프로그램이 이 함수로 포커스를 강제로 이동시킬 수도 있다.
이 함수는 hWnd 윈도우로 포커스를 강제로 이동시키는데 이 윈도우는 반드시 같은 스레드에 속해 있어야 한다. 포커스를 변경하기 전에 이전에 포커스를 가지고 있던 윈도우로 WM_KILLFOCUS 메시지를 보내주며 새로 퐄서를 받는 윈도우로 WM_SETFOCUS 메시지를 보내준다. 새로 포커스를 받는 윈도우와 그 부모 윈도우는 활성화된다. 보통 WM_CREATE에서 원하는 컨트롤에 포커스를 설정하기 위해 이 함수를 사용한다. 대화상자의 경우 WM_INITDIALOG 메시지를 받았을 때 이 함수를 호출하여 포커스를 이동시키는데 이 경우 반드시 FALSE를 리턴해 주어야 한다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
SetMapMode : int SetMapMode(HDC hdc, int fnMapMode);
윈도우즈에서 사용되는 좌표는 논리 좌표와 물리 좌표 두가지가 있다.
■ 논리 좌표 : 윈도우즈 내부에서 사용되는 좌표를 말한다. TextOut (100,100,...)에서 지정한 (100,100)이 곧 논리 좌표이며 논리 좌표의 실제 위치는 경우에 따라 달라진다. 그래픽 함수들이 사용하는 모든 좌표는 논리 좌표이며 좀 더 현실적으로 얘기한다면 DC핸들을 인수로 받아들이는 모든 함수는 논리 좌표를 사용한다■ 물리 좌표 : 실제 화면에 출력되는 좌표이며 픽셀 단위를 사용한다. 모니터의 물리적인 픽셀 단위를 사용하므로 물리 좌표 (100,100)은 그 위치가 정해져 있다. 윈도우를 관리하는 함수(또는 메시지) 에서 사용하는 좌표는 물리 좌표이다.
맵핑 모드란 주어진 논리 좌표가 화면상의 어디에 해당하는지를 결정하는 변환 방법을 의미한다. 즉 논리 좌표와 물리 좌표의 관계를 정의한다. 디폴트 맵핑 모드는 논리 좌표와 물리 좌표가 일치되어 있는 MM_TEXT이므로 어떠한 좌표 변환도 일어나지 않지만 맵핑 모드를 변경하면 논리 좌표의 실제 화면 위치에 변화를 줄 수 있다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
SetMenu : BOOL SetMenu(HWND hWnd, HMENU hMenu);
윈도우의 메뉴를 설정 또는 변경한다. 윈도우에 메뉴가 붙어 있지 않으면 hMenu를 새로 붙이고 이미 메뉴가 붙어 있으면 새로운 메뉴로 대체된다. 이때 이전 메뉴는 자동으로 파괴되지 않으므로 DestroyMenu 함수로 파괴해 주어야 한다. 메뉴가 변경되면 윈도우는 다시 그려진다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
SetPixel : COLORREF SetPixel(HDC hdc, int X, int Y, COLORREF crColor);
점을 찍는다. 모든 장치가 이 함수를 지원하 않으므로 GetDeviceCaps 함수로 지원 여부를 조사해 본 후 이 함수를 호출해야 한다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
SetROP2 : int SetROP2(HDC hdc, int fnDrawMode);
그리기 모드란 GDI 함수가 화면에 출력을 내보낼 때 화면에 이미 출력되어 있는 그림과 새로 그려지는 그림과의 관계를 정의하는 것이다. AND, OR, XOR 등 비트간의 이진 연상 방법과 NOT 연산의 조합으로 지정된다.그리기 연산은 래스터 디바이스에만 적용되며 벡터 디바이스에는 적용되지 않는다.
이 함수명의 ROP는 Rater OPeration의 약자이며 2는 화면색상과 펜의 색상 2개를 피연산자로 취한다는 뜻이다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
SetScrollInfo : int SetScrollInfo(HWND hwnd, int fnBar, LPCSCROLLINFO lpsi, BOOL fRedraw);
스크롤 바의 범위와 위치를 설정한다. 이 함수로 범위를 지정하면 페이지 크기를 전달할 수 있으므로 비례 스크롤 바를 만들 수 있다. nPage, nPos 값에 대해 유효한 값인지를 점검하므로 엉뚱한 값이 들어가지 않도록 해 준다. 다음 코드는 ScrollWindow 함수의 예제에서 사용한 코드이다.
case WM_SIZE:
si.cbSize=sizeof(SCROLLINFO);
si.fMask=SIF_ALL | SIF_DISABLENOSCROLL;
si.nMin=0;
si.nMax=1000;
si.nPage=HIWORD(lParam);
si.nPos=yPos;
SetScrollInfo(hWnd, SB_VERT, &si, TRUE);
si.nPage=LOWORD(lParam);
si.nPos=xPos;
SetScrollInfo(hWnd, SB_HORZ, &si, TRUE);
return 0;
이 윈도우는 1000*1000의 크기를 가지므로 스크롤 범위도 0~1000으로 설정하였으며 페이지 크기는 윈도우의 폭과 높이로 설정하였다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
SetScrollPos : int SetScrollPos( HWND hWnd, int nBar, int nPos, BOOL bRedraw );
스크롤 바위 현재 위치, 즉 스크롤 바의 값을 설정한다. 통상 이 함수는 WM_HSCROLL, WM_VSCROLL 등의 스크롤 바 메시지 처리 루틴에서 스크롤 바의 위치값을 변경하기 위해 호출한다. 범위를 지정하는 nPos는 32비트의 정수이나 메시지로 전달되는 스크롤 바 위치는 16비트값이기 때문에 위치값은 16비트로 제한된다. 그러나 메시지의 인수를 참조하지 않고 GetScrollInfo 등의 함수로 스크롤 바의 위치를 직접 조사하면 32비트의 스크롤 위치값을 지정할 수도 있다.
이 함수에 대한 예제는 SetScrollRange 함수의 예제를 참조하기 바란다. 다음 코드는 스크롤 바위 범위를 0~255로 설정하고 초기 위치를 192로 설정한 것이다.
SetScrollRange(hScroll,SB_CTL,0,255,FALSE);
SetScrollPos(hScroll,SB_CTL,192,FALSE);
/////////////////////////////////////////////////////////////////////////////////////////////////////
SetScrollRange : BOOL SetScrollRange(HWND hWnd, int nBar, int nMinPos, int nMaxPos, BOOL bRedraw);
표준 스크롤 바 또는 스크롤 바 컨트롤의 범위를 설정한다. 표준 스크롤 바의 디폴트 범위는 0~100까지이며 스크롤 바 컨트롤의 디폴트 범위는 둘 다 0으로 비어 있다. 일반적으로 스크롤 바 생성 직후에 이 함수로 적절한 스크롤 범위를 설정해 주어야 한다. nMaxPos와 nMinPos의 차인 범위는 MAXLONG보다 커서는 안된다.
최소, 최대값이 같을 경우는 스크롤 바가 숨겨지는 효과가 있는데 이런 목적으로 이 함수를 호출하는 것은 바람직하지 않으며 ShowScrollBar 함수를 사용하는 것이 좋다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
SetTextAlign : UINT SetTextAlign(HDC hdc, UINT fMode);
TextOut 함수가 지정하는 좌표는 디폴트로 문자열 출력 영역의 좌상단 좌표이다. 이 함수는 문자열의 출력 영역과 출력 좌표와의 관계를 변경함으로써 문자열의 출력 위치에 영향을 준다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
SetTextColor : COLORREF SetTextColor(HDC hdc, COLORREF crColor);
TextOut나 ExtTextOut 함수로 출력되는 문자열은 DC에 설정되어 있는 전경색으로 출력된다. 디폴트 DC의 전경색은 검정색이므로 아무 지정없이 문자열을 출력하면 검정색으로 출력되나 이 함수로 전경색을 변경하면 출력되는 문자열의 색상을 변경할 수 있다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
SetTimer : WORD SetTimer(HWND hWnd, int nIDEvent,WORD wElapse,FARPROC lpTimerFunc);
타이머를 생성하고 wElapse가 지정하는 간격으로 WM_TIMER메시지를 보낸다. WM_TIMER 메시지를 받는 곳은 lpTimerFunc의 설정에 따라 달라진다. lpTimerFunc가 NULL일 경우는 타이머를 설치한 윈도우의 WndProc으로 보내지며 그렇지 않을 경우는 lpTimerFunc가 지정하는 콜백함수로 보내진다. 타이머 메시지는 응용 프로그램의 메시지 큐에 저장되며 윈도우즈의 다른 프로그램에 의해 시간이 지연될 수도 있으므로 반드시 정확한 간격으로 전달된다는 보장은 없다. 시계, 간단한 에니메이션 등 일정한 주기로 호출되어져야 할 함수가 있을 때 보통 타이머 메시지를 사용한다. 또는 시스템의 속도와는 무관하게 일정한 속도를 유지해야하는 게임등에도 타이머 메시지가 사용된다.
만약 hWnd의 nIDEvent 타이머가 이미 설치되어 있다면 이 함수는 새로운 주기로 타이머를 다시 설치하며 이 경우 타이머는 리셋된다. 타이머의 주기를 바꾸고자 할 경우 같은 ID로 이 함수를 호출해 준다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
SetWindowLong : LONG SetWindowLong( HWND hWnd, int nIndex, LONG dwNewLong);
윈도우의 속성은 CreateWindow(Ex) 함수로 윈도우를 생성할 때 지정한다. 일단 윈도우가 만들어진 후에는 이 함수로 윈도우의 속성을 변경할 수 있다. 이때 주로 변경의 대상이 되는 것은 GWL_STYLE 즉 윈도우의 스타일이며 여분 메모리 조작을 위해서도 이 함수가 사용된다. 또한 윈도우 프로시저의 번지를 새로운 함수로 바꿈으로써 윈도우를 서브 클래싱할 수도 있다.
단 이 함수는 같은 스레드에 속한 윈도우의 속성만을 변경할 수 있다. 다른 스레드에서 생성한 윈도우의 속성은 변경할 수 없다. 또한 이 함수로 변경할 수 있는 값들 중 특정 스타일은 시스템에 의해 캐시되므로 변경 즉시 효과가 나타나지 않을 수도 있으며 SetWindowPos 함수로 캐시를 비워주어야 하는 것도 있다. 다음 예제를 통해 이 함수의 사용예를 보도록 하자.
/////////////////////////////////////////////////////////////////////////////////////////////////////
SetWindowPos : BOOL SetWindowPos(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags);
이 함수는 윈도우의 위치, 크기, Z순서를 동시에 또는 일부만 변경할 때 사용된다. 예를 들어 크기는 그대로 두고 위치만 변경하고자 한다거나 위치와 크기는 그대로 두고 Z순서만 변경하고자 할 때 사용한다. MoveWindow 함수는 크기와 위치를 항상 같이 변경하지만 이 함수는 SWP_NOSIZE, SWP_NOMOVE 플래그로 위치와 크기를 개별적으로 변경할 수 있다.
또한 이 함수는 Z순서를 변경하기 위한 목적으로, 특히 항상 위(Top Most) 속성을 토글하기 위한 용도로도 많이 사용되는데 두번째 인수에 HWND_(NO)TOPMOST를 줌으로써 이 속성을 토글할 수 있다. 이 함수로 항상 위 속성을 설정하면 이 윈도우에 소유된 윈도우도 항상 위 속성을 같이 가지게 된다. 그러나 이 윈도우를 소유한 윈도우는 영향을 받지 않는다. 반대로 이 함수로 항상 위 속성을 해제하면 이 윈도우에 소유된 윈도우와 이 윈도우를 소유한 윈도우의 항상 위 속성이 모두 해제된다.
일반적으로 항상 위 속성을 가지지 않은 윈도우가 항상 위 속성을 가진 윈도우를 소유할 수는 있지만 반대는 불가능하다. 왜냐하면 소유된 윈도우는 소유한 윈도우보다 Z순서의 위쪽에 있어야 하므로 소유한 윈도우만 항상 위 옵션을 가질 수는 없기 때문이다. 이렇게 되면 항상 위 옵션을 가지는 윈도우의 차일드로 열려 있는 대화상자가 밑으로 숨어 버리는 현상이 발생할 수 있다. SetWindowPos 함수는 이 모든 처리를 다 해 주므로 항상 위 스타일을 토글 할 때는 SetWindowLong으로 SWL_EXSTYLE을 조작하지 말고 반드시 이 함수를 사용해야 한다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
SetWindowText : BOOL SetWindowText( HWND hWnd,l LPCTSTR lpString
윈도우나 컨트롤의 캡션을 설정한다. 윈도우의 캡션은 타이틀 바에 나타나며 컨트롤의 캡션은 작업 영역에 나타난다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
ShowWindow : BOOL ShowWindow(HWND hWnd, int nCmdShow);
윈도우의 보이기 상태를 지정한다. 보이기 상태(show state)란 보이기/숨기기는 물론이고 최대화/최소화/복구 상태 등 윈도우의 현재 상태를 통칭하는 용어이며 nCmdShow 인수가 지정하는 여러 가지 보이기 상태 중 하나를 선택할 수 있다.
단, 이 함수가 처음 호출될 때는 반드시 WinMain의 인수로 전달된 nCmdShow를 그대로 넘겨 주는 것이 좋다. 쉘은 프로그램을 실행할 때 사용자가 지정해 놓은 등록 정보를 WinMain으로 전달해 주는데 이 설정 상태대로 보여야 하기 때문이다. 만약 이 프로그램이 STARTUPINFO 구조체의 정보대로 생성되었다면 첫번째 ShowWindow 호출에서 nCmdShow 인수 지정은 무시되며 이 구조체가 지정하는 보이기 상태가 적용된다. 두번째 호출부터는 원하는 보이기 상태로 변경할 수 있다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
Sleep : VOID Sleep(DWORD dwMilliseconds);
스레드의 실행을 지정한 시간동안 잠시 정지시킨다. 지연 시간이 0일 경우 같은 우선 순위를 가진 다른 스레드에게 실행 시간을 양보하되 그런 스레드가 없으면 즉시 리턴하여 계속 실행한다. INFINITE는 무한 대기하도록 한다. 이 함수는 주로 스레드의 실행 시간을 천천히 수행하도록 함으로써 결과를 분명히 확인하고자 할 때 테스트용으로 종종 사용하며 스레드간의 동기화에도 사용된다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
StretchBlt : BOOL StretchBlt(HDC hdcDest, int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest, HDC hdcSrc, int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc, DWORD dwRop);
DC간에 비트맵을 전송하여 복사한다. BitBlt와 동작하는 방식이 유사하나 단 복사원의 크기와 높이를 따로 지정할 수 있기 때문에 확대및 축소 복사할 수 있다. 20*40의 크기를 가지는 비트맵을 40*80영역에 복사하면 이 비트맵은 2배로 확대되며 10*20영역에 복사하면 절반으로 축소된다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
TextOut : BOOL TextOut(HDC hdc, int nXStart, int nYStart, LPCTSTR lpString, int cbString);
hdc에 문자열을 출력한다. 이때 출력 좌표는 (nXStart, nYStart)이되 이 좌표는 SetTextAlign이 설정한 정렬 상태에 영향을 받는다. 출력할 문자열의 색상은 SetTextColor, SetBkColor, SetBkMode 함수의 영향을 받는다
/////////////////////////////////////////////////////////////////////////////////////////////////////
TrackPopupMenu : BOOL TrackPopupMenu(HMENU hMenu, UINT uFlags, int x, int y, int nReserved, HWND hWnd, CONST RECT *prcRect);
화면의 임의 위치에 팝업 메뉴를 출력한다. 팝업 메뉴는 주로 마우스 버튼을 누른 위치에 곧바로 열리므로 선택하기 편리하며 꼭 필요한 항목만을 포함하므로 메인 메뉴에 비해서는 사용하기 쉽다는 장점이 있다. 또한 마우스를 누른 위치나 상황에 따라 다른 메뉴를 보여줄 수도 있으므로 훨신 더 직관적이다.
팝업 메뉴를 만드려면 리소스에 메뉴를 만들고 LoadMenu, GetSubMenu 함수로 메뉴의 핸들을 구한 후 이 함수를 호출하면 된다. (x,y)는 팝업 메뉴가 출력될 좌표이되 팝업 메뉴는 화면상의 어디서나 열릴 수 있으므로 이 좌표는 작업 영역 좌표가 아닌 화면 좌표가 된다. 일반적으로 팝업 메뉴는 WM_CONTEXTMENU 메시지에서 여는데 이 메시지는 lParam으로 화면 좌표를 전달해 주므로 이 좌표에 팝업 메뉴를 열면 무난하다.
uFlags에는 여러가지 옵션의 조합을 줄 수 있는데 플래그는 성격에 따라 몇가지 그룹으로 분류할 수 있다. 다음 플래그들은 팝업 메뉴가 출력될 좌표를 해석하는 방법을 지정한다. 이 플래그들의 조합에 따라 (x,y)좌표를 팝업 메뉴의 어디로 해석할 것인가가 결정된다.
디폴트는 수평으로 좌측, 수직으로 위쪽에 정렬(TPM_LEFTALIGN | TPM_TOPALIGN)되며 이 위치가 가장 이상적이다. 수평으로 왼쪽 정렬된다는 것은 x좌표가 팝업 메뉴의 왼쪽 좌표라는 뜻이며 따라서 마우스 커서의 오른쪽에 팝업 메뉴가 열린다. 다음은 몇가지 플레그의 조합으로 팝업 메뉴의 출력 위치를 변경해 본 것이다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
TranslateAccelerator : int TranslateAccelerator(HWND hWnd, HACCEL hAccTable, LPMSG lpMsg);
액셀러레이터 명령을 만든다. 이 함수는 hAccTable을 참조하여 WM_KEYDOWN, WM_SYSKEYDOWN으로부터 WM_COMMAND, WM_SYSCOMMAND 메시지를 만들어 낸다. 눌러진 키가 액셀러레이터 테이블에 정의된 명령일 경우 명령 메시지로 변환하여 메시지 큐에 붙여주며 이 메시지는 다음번 GetMessage나 PeekMessage에 의해 읽혀져 처리되며 이 메시지가 완전히 처리되기 전에는 리턴하지 않는다.
일반적으로 액셀러레이터는 메뉴 항목에 대한 단축키를 제공하기 위해 작성한다. 이 경우 액셀러레이터키가 눌러지면 마치 메뉴가 선택된 것처럼 WM_INITMENU, WM_INITPOPUPMENU 메시지가 전달된다. 단 윈도우가 사용금지되어 있거나 메뉴 항목이 사용금지된 경우, 마우스가 캡처된 경우는 제외된다. WM_COMMAND 메시지는 명령이 액셀러레이터로부터 온 경우 wParam의 상위 워드로 1이 전달되며 메뉴로부터 온 경우 0이 전달되는데 보통 이 구분은 무시하지만 메뉴로부터의 명령과 액셀러레이터로부터의 명령을 구분하려면 HIWORD(wParam)을 참고하도록 한다. 다음은 액셀러레이터가 정의되어 있을 경우의 메시지 루프이다.
while(GetMessage(&Message,0,0,0)) {
if (!TranslateAccelerator(hWnd,hAccel,&Message)) {
TranslateMessage(&Message);
DispatchMessage(&Message);
}
}
GetMessage로 메시지를 조사한 후 먼저 TranslateAccelerator 함수가 이 메시지를 검사하여 액셀러레이터표에 있는 키보드 입력인지 조사한다. 만약 그렇다면 이 메시지는 WM_COMMAND로 변환되어 메시지 처리 함수로 보내지며 이 경우 TranslateMessage, DispatchMessage 함수는 호출되지 말아야 한다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
TranslateMessage : BOOL TranslateMessage(CONST MSG *lpMsg);
조사한 메시지를 문자 메시지로 변환한다. WM_KEYDOWN, WM_KEYUP 조합에 의해 WM_CHAR 메시지를 만들어 내며 WM_SYSKEYDOWN, WM_SYSKEYUP 조합에 의해 WM_SYSCHAR, WM_SYSDEADCHAR 메시지를 만들어낸다. 이때 TranslateMessage 함수는 키보드 드라이버가 제공하는 문자 구성에 따라 문자로 변환되는 키에 대해서만 변환을 하며 나머지 키 입력은 변환하지 않는다. 만들어진 문자 메시지는 메시지 스레드 큐에 붙여지며 다음번 GetMessage나 PeekMessage 함수에서 읽혀진다.
이 함수는 메시지 루프내에서 키보드 메시지를 문자 메시지로 변환하기 위한 목적으로만 사용되며 다른 목적으로 사용해서는 안된다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
UpdateWindow : BOOL UpdateWindow(HWND hWnd);
이 함수는 윈도우 프로시저로 WM_PAINT 메시지를 보내 작업영역을 강제로 그리도록 한다. WM_PAINT 메시지는 우선 순위가 늦기 때문에 무효 영역이 있더라도 먼저 처리해야할 다른 메시지가 있으면 즉시 처리되지 않는다. 만약 다른 어떤 메시지보다도 WM_PAINT를 먼저 처리해야 할 필요가 있다면 이 함수를 호출하여 즉시 작업영역을 다시 그리도록 할 수 있다.
이 함수는 메시지 큐를 통하지 않고 윈도우 프로시저로 곧바로 WM_PAINT 메시지를 전달하므로 메시지 대기 순서에 상관없이 즉시 작업영역을 다시 그리도록 한다. 그러나 작업영역에 무효영역이 없으면 이 함수를 호출한다하더라도 WM_PAINT 메시지는 보내지지 않는다. 작업영역을 완전히 다시 즉시 그리려면 InvalidateRect 함수로 작업영역을 무효화한 후 이 함수를 호출하면 된다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
WindowProc : LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
윈도우로 전달되는 메시지를 처리하는 메시지 처리 함수이며 보통 윈도우 프로시저(Window Procedure)라고 부른다. 사용자 정의 함수이므로 이름은 정해져 있지 않으나 보통 WndProc 또는 WindowProc이라는 이름을 많이 사용한다. 운영체제는 사용자의 조작과 시스템 내부의 변화가 있을 때 메시지 큐에 메시지를 넣으며 WinMain의 메시지 루프는 메시지 큐에서 메시지를 꺼내 윈도우 프로시저로 전달해 준다.
윈도우 프로시저는 자신에게 전달된 메시지의 의미를 분석하여 응용 프로그램 고유의 처리를 한다. 보통 하나의 프로그램이 복수개의 메시지를 처리하므로 윈도우 프로시저는 일반적으로 메시지별로 고유한 처리를 할 수 있는 switch문으로 구성된다.
/////////////////////////////////////////////////////////////////////////////////////////////////////
WriteFile : BOOL WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped);
파일에 데이터를 기록한다. 주로 동기적인 출력에 사용하지만 OVERLAPPED 구조체를 제공하면 비동기 입출력을 할 수도 있다. 파일 포인터가 가리키고 있는 지점에 데이터를 기록하며 기록을 완료한 후 실제 기록한 바이트수만큼 파일 포인터를 이동시켜 준다. 단, 비동기 입출력 중일 때는 응용 프로그램이 파일 포인터를 직접 이동시켜 주어야 한다.
파일뿐만 아니라 파이프, 소켓, 통신 포트, 콘솔 등의 장치로도 데이터를 출력할 수 있다.
'WindowsAPI' 카테고리의 다른 글
ComboBox 메세지 몇개 (0) | 2010.06.09 |
---|---|
static window 생성하고 따로 CALLBACK WNDPROC 돌리기 (0) | 2009.04.12 |
Windows Message List (0) | 2009.04.12 |
Win32 Error Codes (0) | 2009.04.12 |
Windows 의 Handle 값의 의미란 무엇인가. (4) | 2009.04.12 |