#include <Windows.h>
#include "api0316.h"
//#define WINVER 0x0500
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
static TCHAR szAppName[] = TEXT("Main Window");
HWND hWnd;
MSG msg;
//윈도우 정보 등록
WNDCLASS wc; //WNDCLASS 구조체 변수 선언
wc.hInstance = hInstance; //현재 윈도우 인스턴스핸들값 대입
wc.style = CS_HREDRAW|CS_VREDRAW; //수평수직
wc.lpfnWndProc = WndProc; //프로시저 함수등록
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hIcon = LoadIcon(NULL,IDI_APPLICATION); //리소스정보<아이콘> 등록
wc.hCursor = LoadCursorW(NULL,IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszClassName = szAppName;
wc.lpszMenuName = NULL;
RegisterClass(&wc); //등록
/// 핸들 정수값 반환
hWnd = CreateWindow(szAppName, /* 핸들 없는 상태에서 윈도우 구별하기위한 문자열 */
TEXT("Hyojeong Window"), /* 제목 표시줄에 표시되는 프로그램 제목*/
WS_OVERLAPPEDWINDOW | WS_VSCROLL, /*출력되는 윈도우의 표준 사양 & 다른 윈도우와 겹치기 가능하도록 */
CW_USEDEFAULT, 0, CW_USEDEFAULT,0,
NULL, /* 상위, 부모 윈도우 핸들*/
NULL, /* 윈도우에 삽입 되는 메뉴표시줄 핸들*/
hInstance, /* 상위 인스턴스 핸들 */
NULL); /* 매개변수 갯수 */
ShowWindow(hWnd,nShowCmd);
UpdateWindow(hWnd);
/* 현재 출력된 위치와 크기의 윈도우에서 발생되는 윈도우 메세지를*/
/* 윈도우 메시지 처리함수로 잔달..*/
/* WM_QUIT 메세지들어 왔을때 루프나와서 WinMain 함수 리턴 - 종료 */
/* WM_QUIT 메세지가 들어와야 메모리에서 내려온다.*/
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg); /* 메시지 번역 */
DispatchMessage(&msg); /* OS로 메시지 큐에 저장된 구조체 번지값 전달 */
/* 메세지 정보는 큐 */
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static int cxChar, cyChar, cxCaps; //정적선언으로 ReleaseDC 때 값 사라짐 방지
HDC hDC; //화면 출력용 구조체[1]
PAINTSTRUCT ps; //화면 출력용 구조체[2]
TEXTMETRIC tm; //문자 가로 세로 사이즈 정보
TCHAR szBuffer[10]; // 문자열을 저장하는 변수는 관례적으로 다 sz를 붙임
// string terminated by zero character
// =WCHR = wchr_t 즉 문자 한 글자를 저장하기위해 2바이트(16bit)
static int cxClientWidth,cyClientHeight;
switch (message)
{
case WM_CREATE:
hDC = GetDC(hWnd);
GetTextMetrics(hDC,&tm);
cxChar = tm.tmAveCharWidth; //소문자 평균폭
cxCaps = (tm.tmPitchAndFamily & 1?3:2) * cxChar /2; //대문자 평균폭
cyChar = tm.tmHeight + tm.tmExternalLeading;
ReleaseDC(hWnd,hDC); //DC 해제
SetScrollRange(hWnd, SB_VERT, 0, NUMLINES-1, FALSE); // 수직 스크롤 범위 지정
//SetScrollRange(hWnd, SB_HORZ, 0, 75*cxChar, FALSE); // 수평 스크롤 범위 지정
SetScrollPos(hWnd, SB_VERT, 0, TRUE);
return 0;
case WM_PAINT: // View 영역이 출력될때
hDC = BeginPaint(hWnd,&ps);
for(int i=0;i<NUMLINES;i++)
{
TextOut(hDC,1,cyChar*i,sysmetrics[i].szLabel,lstrlen(sysmetrics[i].szLabel));
//(hDC, 10=x값(10픽셀),cyChar(=높이)*i, sysmetrics구조체의 0번째 문자열을 가져옴, lstrlen(문자열의 전체길이값을 정수형태로 리턴받아옴))
TextOut(hDC,20*cxChar,cyChar*i,sysmetrics[i].szDesc,lstrlen(sysmetrics[i].szLabel));
SetTextAlign(hDC,TA_RIGHT|TA_TOP);//TA_RIGHT:flag TA(Text Align) -> 오른쪽정렬하면서 위로 붙임
TextOut(
hDC,
70 * cxChar, // 폭
cyChar*i,
szBuffer, //
wsprintf(szBuffer,TEXT("%5d"),GetSystemMetrics(sysmetrics[i].iIndex)) //
);
SetTextAlign(hDC,TA_LEFT|TA_TOP); // 왼쪽정렬로 되돌려 줌
}
EndPaint(hWnd,&ps); // for문이 끝나면 Paint끝.
return 0;
case WM_SIZE:
//cxClientWidth = LOWORD(lParam); //WndProc의 4번째 변수 사용/수평스크롤 만들었을 때 사용
cyClientHeight = HIWORLD(lParam);
return 0;
case WM_VSCROLL:
switch(LOWORD(wParam))
{
case SB_LINEUP:
iVScrollPos -= 1;
break;
case SB_LINEDOWN:
iVScrollPos += 1;
break;
case SB_PAGEUP:
iVScrollPos -= cyClientHeight / cyChar;
break;
case SB_PAGEDOWN:
iVScrollPos += cyClientHeight /cyChar;
break;
case SB_THUMBPOSITION:
iVScrollPos = HIWORD(wParam);
default :
break;
}
iVScrollPos = max(0, min(iVScrollPos, NUMLINES -1));
if(iVScrollPos != GetScrollPos(hWnd, SB_VERT))
{
SetScrollPos(hWnd, SB_VERT, iVScrollPos, TRUE);
InvalidateRect(hWnd, NULL, TRUE);
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
/* 나머지 메시지 처리 */
return DefWindowProc(hWnd,message,wParam,lParam);
}