책정리/윈도우 API 정복2

34장 시스템 정보

GONII 2019. 3. 19. 23:11

01 시스템 정보

. 시스템 정보 조사

프로그램은 자신이 실행되는 환경을 조사한 환경에 맞게 실행되야 .

응용 프로그램이 제대로 실행되기 위해서, 그리고 다른 프로그램이나 운영체제와 매끄러운 조화를 이루기 위해서는 여러 가지 다양한 시스템 저보들이 필요하다. 장에서는 시스템 정보를 조사하여 정보에 따라 적절히 동작하는 호환성 높은 프로그램을 작성하는 방법에 대해 다룬다.

 

시스템의 정보를 조사하는 함수들 가장 기본이 되는 함수는 다음 함수이다.

VOID GetSystemInfo(LPSYSTEM_INFO lpSystemInfo);

함수는 시스템의 구성 정보를 조사하여 인수로 전달된 구조체에 채워 리턴함.

typedef struct _SYSTEM_INFO

{

union {

DWORD dwOemId;

struct {

WORD wProcessorArchitecture;

WORD wReserved;

}

};

DWORD dwPageSize;

LPVOID lpMinimumApplicationAddress;

LPVOID lpMaximumApplicationAddress;

DWORD_PTR dwActiveProcessorMask;

DWORD dwNumberOfProcessors;

DWORD dwNumberOfProcessors;

DWORD dwProcessorType;

DWORD dwAllocationGranularity;

WORD wProcessorLevel;

WORD wProcessorRevision;

} SYSTEM_INFO;

주로 CPU 메모리에 관련된 정보

구조체의 참조하면 CPU 개이고 어떤 종류의 CPU인지 알아낼 있다.

윈도우 NT 인텔 계열의 CPU뿐만 아니라 MIPS ALPHA같은 다른 종류의 CPU에서도 실행되는 버전이 따로 제공되고 있으며 복수 개의 CPU 지원한다.

 

다음 함수는 키보드의 종류와 펑션키 개수를 조사하는 함수이다.

int GetKeyboardType(int nTypeFlag);

nTypeFlag

리턴값의 의미

0

키보드 종류

1

키보드의 서브 타입

2

펑션키의 개수

 

최근 출시된 하이퍼 스레딩 지원 CPU 듀얼 코어 CPU 물리적인 CPU 하나지만 논리적인 CPU 두개 이상이므로 개수대로 조사된다.

. 컴퓨터 이름 조사

BOOL GetComputerName(LPTSTR lpBuffer, LPDWORD lpnSize);

BOOL GetUserName(LPTSTR lpBuffer, LPDWORD nSize);

이름을 리턴 받기 위한 버퍼의 주소를 번째 인수로, 버퍼의 길이를 담은 정수형 변수를 두번째 인자로 넘겨주면 된다.

번째 인수에 참조 호출을 사용하는 이유는 버퍼 길이가 부족할 경우 필요한 길이를 리턴하기 위해서인데 원칙상 인수로 NULL 전달하여 필요한 길이를 조사한 메모리를 할당하고 다시 호출하는 것이 옳다.

TCHAR szComName[255];

TCHAR szUserName[255];

DWORD dwLen;

 

dwLen = 255;

GetComputerName(szComName, &len);

dwLen = 255;

GetUserName(szUserName, &len);

wprintf(str, "ComName=%s, UserName=%s", szComName, szUserName);

 

BOOL SetComputerName(LPCTSTR lpComputerName);

변경된 컴퓨터의 이름은 레지스트리에 저장되며 변경은 컴퓨터를 다시 부팅할 때적용된다.

컴퓨터 일므을 함부로 바꾸게 되면 돌아가던 컴퓨터의 설정이 초기화되어 여기저기서 말썽이 생길 있음.

. 시스템 색상 조사

시스템 색상 조사 함수

DWORD GetSysColor(int nIndex);

nIndex 알고자 하는 색상 요소를 지정하면 해당 요소의 시스템 색상을 조사하여 리턴. COLOR_ 시작하는 매크로 상수가 정의되어 있다. COLOR_ACTIVECAPTION 활성 윈도우의 제목표시줄, COLOR_BTNTEXT 버튼의 텍스트 색상

 

BOOL WINAPI SetSysColors(int cElements, CONST INT *lpElements, CONST COLORREF* lpaRgbValues);

함수는 한꺼번에 여러 요소의 색상을 변경할 있다.

 

HBRUSH GetSysColorBrush(int nIndex);

 

// 패스~ 건너뜁니다.

. 운영체제의 버전 조사

BOOL GetVersionEx(LPOSVERSIONINFO lpVersionInfo);

 

typedef struct _OSVERSIONINFOEX

{

DWORD dwOSVersionInfoSize;

DWORD dwMajorVersion;

DWORD dwMinorVersion;

DWORD dwBuildNumber;

DWORD dwPlatformId;

TCHAR szCSDVersion[128];

WORD wServicePackMajor;

WORD wServicePackMinor;

WORD wSuiteMask;

BYTE wProductType;

BYTE wReserved;

}OSVERSIONINFOEX;

 

dwPlatformId 운영체제의 계열을 나타내는

설명

VER_PLATFORM_WIN32S

윈도우즈 3.1에서 실행되는 Win32s

VER_PLATFORM_WIN32_WINDOWS

윈도우즈 95/98

VER_PLATFORM_WIN32_NT

윈도우즈 NT/2000

. DLL 버전 조사

운영체제의 버전 정보만으로 모든 기능의 유무를 파악하는 것은 부족하다. 마이크로소프트는 운영체제 자체의 기능과는 별도로 공통 컨트롤과 쉘을 꾸준히 업데이트해 왔는데 주로 인터넷 익스플로러와 함께 컨트롤들을 배포해왔다.

배포대상 DLL Comclt32.dll, Shell32.dll, Shlwapi.dll 가지이며 어떤 DLL 설치되어있는가에 따라 공통 컨트롤과 쉘의 기능에 많은 차이가 발생한다.

 

DLL 버전 정보 조사 함수

HRESULT CALLBACK DllGetVersion(DLLVERSIONINFO* pdvi);

 

typedef struct _DllVersionInfo

{

DOWRD cbSize;

DWORD dwMajorVersion;

DWORD dwMinorVersion;

DWORD dwBuildNumber;

DWORD dwPlatformID;

}DLLVERSIONINFO;

02 설정 정보

. 메트릭스

윈도우즈의 화면 구성을 보면 모든 윈도우가 거의 동일한 모양을 가지고 있다. 타이틀 바의 높이, 경계선의 두께, 타이틀 바의 버튼 크기 등등이 모두 균일하다.

윈도우즈의 화면 구성이나 설정 상태에 대한 수치들을 메트릭스라고 .

int GetSystemMertics(int nIndex);

nIndex

설명

SM_CMOUSEBUTTONS

마우스 버튼의 개수

SM_CX(Y)CURSOR

마우스 커서의 크기

SM_CS(Y)FRAME

크기 조정이 가능한 경계선의 높이와

SM_CX(Y)BORDER

3차원 효과 윈도우의 경계선 높이와

SM_CX(Y)SCREEN

화면의 수평, 수직 해상도

SM_CYCAPTION

타이틀바의 높이

SM_CYMENU

메뉴 바의 높이

SM_SWAPBUTTON

마우스의 좌우 버튼이 교체 상태이면 TRUE

. 파라미터

GetSystemMetrics함수는 16비트 윈도우즈부터 지원됐는데, 32비트 윈도우즈에서는 설정 사항들이 많아져서 함수만으로 모든 설정 사항을 조사하지 못함.

그래서 95부터 밑에 함수를 제공, 많은 설정 정보를 다룰 있도록함.

BOOL SystemParametersInfo(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni);

uiAction 140여개나 되는데 그만큼 함수가 있는 일의 종류가 많다.

번째 세번째 인수를 uiAction 따라 달라짐

마지막 인수 fWinIni 함수가 설정을 변경했을 WM_SETTINGCHANGE 메시지를 모든 레벨 윈도우에게 보낼 것인가 아닌가를 지정

메시지를 보내면 다른 윈도우들이 즉시 변화를 감지할 있으며 변경된 설정이 레지스트리에도 저장된다.

플래그

설명

SPIF_UPDATEINFILE

사용자 프로필에 변경 사항을 기록

SPIF_SENDCHANGE=

모든 레벨 우니도우에게 WM_SETTINGCHANGE

SPIF_SENDWININICHANGE

메시지를 보낸다.

. 배경 벽지 바꾸기

03 시간

. SYSTEMTIME

윈도우즈는 다섯가지나 되는 시간 포맷을 지원하며 포맷간의 변환이 가능함.

운영체제 차원에서 기본이 되는 시간 포맷은 다음 구조체로 표현되는 시스템 타임이다.

typedef struct _SYSTEMTIME

{

WORD wYear;

WORD wMonth;

WORD wDayOfWeek;

WORD wDay;

WORD wHour;

WORD wMinute;

WORD wSecond;

WORD wMilliseconds;

} SYSTEMTIME, *PSYSTEMTIME;

운영체제 내부적으로 유지하는 시간을 시스템 시간이라고 하는데 다음 함수로 조사한다.

VOID GetSystemTime(LPSYSTEMTIME lpSystemTIme);

함수가 조사하는 시스템 시간은 UTC 시간이다.(영국의 그리니치 천문대의 시간을 기준으로 하며 우리나라의 시간보다 9시간 느리다.)

 

현재 시스템에 설정된 시간대 조사 함수

VOID GetLocalTime(LPSYSTEMTIME lpSystemTime);

 

시간 설정 함수

BOOL SetSystemTime(CONST SYSTEMTIME* lpSystemTime);

BOOL SetLocalTime(CONST SYSTEMTIME* lpSystemTime);

시간 변경 WM_TIMECHANGE메시지를 모든 레벨 윈도우에게 방송해야 한다. 컴퓨터의 시간은 여러 프로그램이 참조하는 아주 중요한 정보이므로 일반 응용 프로그램이 함수로 수정해서는 안된다.

. FILETIME

typedef struct _FILETIME

{

DWORD dwLowDateTime;

DWORD dwHighDateTime;

}FILETIME, *PFILETIME;

,하위 32비트 값으로 구성되어 있는데 결국 64비트의 정수 하나로 표현될 있는 값이다.

 

윈도우즈는 디스크상의 파일에 대해 생성 시간, 최후 액세스한 시간, 최후 수정된 시간을 FILETIME 포맷으로 기록하는데 기록하는 방식은 파일 시스템에 따라 약간씩 다르다. FAT32 디스크에서는 로컬 시간으로 기록되는 반면 NTFS 디스크에서는 UTC 시간으로 기록되며 시간의 해상도도 서로 다르다. FAT32에서는 액세스 시간을 하루 단위로 기록하고 NTFS에서는 한시간 단위로 기록한다.

특정 파일의 파일 시간을 조사하거나 설정하는 함수는 다음과 같다.

BOOL GetFileTime(HANDLE hFile, LPFILETIME lpCreateTime, LPFILETIME lpLastAccessTime, LPFILETIME lpLastWriteTime);

BOOL SetFileTime(HANDLE hFile, CONST FILETIME* lpCreateTime, CONST FILETIME* lpLastAccessTime, CONST FILETIME* lpLastWriteTime);

 

GetFileTime함수로 조사한 시간은 일정 시점을 기준으로 경과 시간이기 때문에 곧바로 문자열로 출력하는 것은 불가능하다.

FILETIME SYSTEMTIME 포맷을 상호 변환할 때는 다음 함수를 사용한다.

BOOL FileTimeToSystemTime(CONST FILETIME* lpFileTime, LPSYSTEMTIME lpSystemTime);

BOOL SystemTimeToFileTime(CONST SYSTEMTIME* lpSystemTime, LPFILETIME lpFileTime);

 

NTFS 경우 GetFileTime 함수에 의해 조사된 시간은 UTC 시간이기 때문에 먼저 로컬 시간으로 바꾸어야 한다. FILETIME UTC시간과 로컬 시간으로 상화 변환하는 함수는 다음 함수이다.

BOOL FileTimeToLocalFileTime(CONST FILETIME* lpFileTime, LPFILETIME lpLOcalFileTime);

BOOL LocalFileTimeToFileTime(CONST FILETIME* lpLocalFileTime, LPFILETIME lpFileTime);

 

시간의 대소 비교 함수

LONG CompareFileTime(CONST FILETIME* lpFileTime1, CONST FILETIME* lpFileTIme2);

리턴값

설명

1

첫번째 시간이 크면

-1

번째 시간이 크면

0

시간이 같으면

. DiffDay

만들어 써야함.

. 카운트

카운트 : 운영체제가 부팅한 이후의 경과한 시간 (1000분의 1 단위로 기록됨)

32비트 정수로 표현되어 49.7 밖에 표현할 없다. 49.7일이 되면 다시 0 된다.

DWORD GetTickCount(VOID);

. 고해상도 타이머

1/1000 단위는 정밀한 계산에 쓰기에는 부족하며 32비트 정수로는 고작 49 밖에 카운팅할 없어, 높은 고해상도를 요구할 경우 고해상도 타이머(High Resolution Timer) 사용한다.

 

모든 시스템이 고해상도 타이머를 지원하는 것은 아니므로 먼저 지원 여부를 조사해야 한다. 고해상도 타이머는 카운트와 마찬가지로 부팅 카운팅을 시작해서 일정 주기로 계속 증가한다. 이때 1초에 증가하는 값을 주파수라고 하며 다음 함수로 조사할 있다.

BOOL QueryPerformanceFrequency(LARGE_INTEGER* lpFrequency);

1초에 함수가 리턴하는 주파수만큼 카운트가 증가하는데 시스템 속도에 따라 다르며 어떤 시스템에서는 CPU 클럭수가 주파수로 사용되기도 한다. 대략 백만 ~ 수백만 정도 되므로 해상도가 아주 정밀하다.

고해상도 타이머를 지원하지 않을 경우 주파수는 0으로 조사된다.

주파수는 부팅 후에는 절대 변하지 않으므로 카운트는 단위 시간당 일정한 양만큼만 증가한다. 특정 시간의 카운트를 조사할 때는 다음 함수가 사용된다.

BOOL QueryPerformanceCounter(LARGE_INTEGER* lpPerformanceCount);

 

(작업 끝난 카운트 - 작업 시작 카운트) / 주파수 = 진행된 시간()

04 다중 모니터

. 다중 모니터

. 시스템의 지원

. 모니터 정보 조사

. 다중 모니터 출력

. 모니터 위치 조사


반응형

'책정리 > 윈도우 API 정복2' 카테고리의 다른 글

41장 멀티 스레드  (0) 2019.04.16
39장 메모리  (0) 2019.04.04
40장 프로세스  (0) 2019.04.04
39장 메모리  (0) 2019.04.03
목차  (0) 2019.03.03