윈도우 32비트 프로그래밍 01 |
안녕하세요...돌팔이 황동준입니다. 그냥 제가 알고 있는 윈도우즈 프로그램에 대해서 앞으로 자유롭게 강좌할 생각입니다. 최대한 저도 잘 모르는 부분이 있기 때문에 설명이 틀릴 수도 있으니 이런 부분 과감히 지적해 컴파일러는 비주얼씨 4.1을 기준으로 하고 방식은 API입니다. MFC를 익히려는 분들이 1. 윈도우즈 프로그램의 개요 윈도우즈 프로그래밍을 배울려고 하는 여러분들은 적어도 한가지 책은 가지고 있을 겁니다. 물론 윈도우즈는 도스와는 달리 특수한 방법으로 모든게 처리가 됩니다. 왜 도스와는 다른 방법으로 1.1 첫번째 알아야 할 사실 프로그램을 예를 들어 봅시다. 이 프로그램은 작업영역에 마우스가 클릭되면 마우스가 간단합니다. 마우스가 클릭되면 윈도우즈는 마우스가 클릭되었다는 메시지를 메시지 큐라는 곳에 한가지 배웠습니다. 바로 프로그램에는 항상 메시지 큐에서 메시지를 가져오는 루틴이 있어야 1.2 두번째 알아야 할 사실 자 그러면 두번째를 배워봅시다. 이런 경우는 어떻겠습니까? 위와 같은 프로그램 이 데스크탑 1.3 윈도우즈 프로그램의 구조 도스에서 프로그램을 짜면 항상 메인함수가 있어야 합니다. void main(void) 위와 같은 형태로 프로그램을 작성했을 겁니다. 그런데 윈도우즈에서는 위 메인 함수를 사용하지 그러면 어떤식으로 되는지 전체적으로 흐름을 알아봅시다. 먼저 윈 메인 함수에서는 윈도우를 생성하고 메시지 큐에서 메시지를 가져오는 역할을 합니다. 또 윈 메인함수도 내부적으로 크게 세 부분으로 나눌 수 있습니다. WinMain() 첫번째 파트에서 프로그래머가 해주어야 할 일은 생성할 윈도우의 속성을 지정해주는 것입니다. 두번째 파트에서는 실제로 윈도우를 생성해서 화면에 보이게하는 작업이고 마지막 세번째 자 이제 이해가 갑니까? 이해가 가면 벌써 절반은 끝난거나 다름없습니다. 쉽죠. 다음 시간에는 실제로 윈도우를 생성하는 프로그램을 만들어 보겠습니다. 그럼 안뇽...~~~~~~~~~~ |
윈도우 32비트 프로그래밍 02 |
안녕하세요... 돌팔이 황동준입니다. 이번에는 실제적으로 윈도우를 생성하는 예제에 대해서 알아 보도록하겠습니다. 2. 윈도우의 생성과 다루기 2.1 데스크탑위에 윈도우 생성하기 윈도우즈 프로그래밍을 작성하기 위해서는 항상 windows.h라는 헤더 파일을 포함시켜 저번시간에 배운 윈도우즈 프로그래밍 형태를 잘 생각해 봅시다. 먼저 윈 메인함수가 있어야 int WINAPI WinMain 윈 메인 함수는 위와 같은 형태를 취하는데 잘 보세요. 상당히 복잡하죠. 파라미터가 상당히 맨 앞에 있는 int는 여러분들도 알다시피 함수의 리턴값을 의미하는 것입니다. 그러면 그러면 이번에는 파라미터에 대해 알아봅시다. 첫번째로 인스턴스라는 것에 대해 알아봅시다. 앞에서 프로그램마다 고유의 번호인 핸들을 첫번째 파라미터는 바로 이 프로그램 번호를 의미하는 것입니다. 그러면 두번째 파라미터는 뭘 자 여기까지 메인 함수원형에 대해 알아보았습니다. 그러면 이번에는 윈 메인 함수를 구분짓는 우선 첫번째 파트에서 뭘 한다고 했습니까? 윈도우의 속성을 지정해 준다고 했을 겁니다. 여기서 사용하는 구조체는 WNDCLASS라는 그 구조체인데 아래는 그 구조체의 원형과 설명 typedef struct tagWNDCLASS 위 구조체의 각 멤버에 값을 대입하여 함수를 이용해서 등록하면 됩니다. 이때 등록하는 함수로 ATOM RegisterClass(const WNDCLASS *lpwc); 자 여기까지 하면 속성을 지정하는 파트1 부분이 이해가죠? 그러면 윈도우를 생성해서 보여주는 이제는 윈도우를 생성해야 하는데 생성할 때 사용하는 함수가 물론 있습니다. 한번 이 함수에 HWND CreateWindow( 자 위에보면 함수 원형이 하나 있죠? 바로 이 함수를 이용해서 윈도우를 생성하는 것 lpszClassName 우리는 이 함수를 사용하기 전에 생성할 윈도우의 속성을 RegisterClass()함수를 lpszWindowName 윈도우를 생성하였을때 타이틀바에 제목을 지정할수 있는데 그 제목이 이곳에 등록된 문자열이 dwStyle 생성될 윈도우의 모양을 정의해 주는 곳입니다. 최소화버튼, 최대화버튼등을 생성하도록 하고 x 생성될 윈도우의 X 좌표를 지정하면 됩니다. y 생성될 윈도우의 Y 자표를 지정하면 됩니다. nWidth 생성될 윈도우의 넓이를 지정하면 됩니다. nHeight 생성될 윈도우의 높이를 지정하면 됩니다. hwndParent 윈도우를 포함하고 있는 부모 윈도우의 핸들을 지정해 주면 됩니다. 핸들이 뭔지는 대략 hmenu 생성되어지는 윈도우가 메뉴를 가지고 있으면 그 메뉴 핸들을 hinst 현재 프로그램의 인스턴스 핸들을 지정하면 됩니다. 윈 lpvParam 보통 잘 쓰이지 않기 때문에 NULL로 많이 지정합니다. 자 이제는 윈도우를 생성했습니다. 그러면 뭘 해야 할까요? 바로 메시지 큐에서 메시지를 위에서 배운 CreateWindow() 함수를 이용해서 윈도우를 생성했다고 해서 화면에 BOOL ShowWindow( 먼저 첫번째 함수로 위 함수를 사용하는데 첫번째 파라미터를 보기 바랍니다. HWND라는 BOOL UpdateWindow( 이 함수를 설명 하려면 메시지중 WM_PAINT를 설명 드려야 하는데 일단은 위에서 배운 이제는 윈도우가 보이겠군요. 그럼 메시지 큐에서 메시지를 가져 오는 부분을 보도록 합시다. BOOL GetMessage( 무한 루프문의 조건을 위 함수의 리턴값으로 하는 형식을 많이 취합니다. 만약에 프로그램을 BOOL TranslateMessage( LONG DispatchMessage( 메시지를 가지고 왔으면 가져온 메시지를 처리해야 겠죠. 첫벗째 함수인 두번째 함수인 DispatchMessage() 함수는 가져온 메시지를 WNDCLASS에서 앞에서 이미 알아보았죠. 실제로 메시지를 가지고 처리하는 부분이 윈도우 함수부분이라는 자 여기까지 윈 메인 함수에 대해 알아보았습니다. 그러면 윈도우 함수 부분을 볼까요. LRESULT CALLBACK 위와 같은 형태로 윈도우 함수를 사용하는데 함수 이름이 WndProc으로 되어 있는 것은 두번째 파라미터가 바로 메시지 큐에서 가져온 메시지가 들어오는 곳입니다. 결국 이 메시지를 흠.. 이제 대충 다 알아본거 같군요. 그럼 실제로 윈도우를 띄우는 예제의 소스를 보도록 #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, int WINAPI WinMain HWND hWnd; WndClass.style = hWnd = ShowWindow(hWnd, while(GetMessage(&msg, NULL, 0, LRESULT CALLBACK WndProc(HWND hWnd, UINT mesg, PostQuitMessage(0); 다음 시간에는 이 프로그램을 비주얼C 4.1로 컴파일하는 방법과 프로그램 분석을 해 그럼 이만.... |
윈도우 32비트 프로그래밍 03 |
안녕하세요... 돌팔이 황동준입니다. 저번 시간에 이어서 계속 강좌를 하겠습니다. 먼저 저번시간에 코딩한 소스를 컴파일 해보도록 비주얼C 4.1의 통합환경은 Microsoft Developer Studio라고 써있는 자 구동이 됐습니까? 그러면 먼저 File 메뉴의 New를 선택하시기 바랍니다. 그러면 어떤 우리는 API함수를 이용해서 프로그램을 만들기 때문에 왼쪽의 타입을 Application에 자 여기까지 됐으면 다 된거나 다름없습니다. 여기까지 작업이 프로젝트 파일 구성 준비 당연히 컴파일할 파일을 이 프로젝트에 포함시켜 주어야겠죠. 우리가 만든 프로그램 소스는 다 됐으면 이제 Build메뉴의 Build를 선택해서 컴파일하면 됩니다. 만약에 에러가 에러가 없으면 Build 메뉴의 Excute를 선택하면 그 프로그램이 실행됩니다. 여기까지 자 그러면 구체적으로 그 소스를 분석해 볼까요? #include <windows.h> 먼저 항상 windows.h라는 헤더파일을 포함시켜 주어야 한다고 위에서 언급했을 겁니다. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, 윈도우 함수가 메인 함수의 뒤에 위치하기 때문에 함수원형을 선언 해준겁니다. int WINAPI WinMain HWND hWnd; 윈도우의 핸들 자료형이 HWND입니다. 이것은 CreateWindow() 함수를 사용할때 MSG msg; MSG는 메시지 자료형입니다. WNDCLASS WndClass; 윈도우 클래스 자료형입니다. char szAppName[] = "This program is to 생성할 윈도우의 타이틀바 제목과 클래스 이름을 이 변수로 할겁니다. 위에서 직접 컴파일
윈도우 속성을 지정하는 과정이군요. 위에서 제가 말씀드린 것을 이해한 분이라면 그렇게 어려운 WndClass.style = NULL; 스타일은 기본값으로 합니다. WndClass.lpfnWndProc = WndProc; 윈도우 함수를 지정하는 부분이죠. WndClass.cbClsExtra = 잘 쓰이지 않는다고 했죠. WndClass.hInstance = hInstance; 프로그램 인스턴스 핸들을 지정하는 부분인데 이 부분은 파라미터로 넘겨온 값을 지정하면 된다고 WndClass.hIcon = LoadIcon(NULL, 아이콘은 기본적으로 시스템에서 제공하는 것을 사용하겠다는 뜻입니다. 생소한 함수가 하나 HICON LoadIcon( IDI_APPLICATION 기본적인 프로그램 아이콘 만약에 유저가 그린 그림을 가지고 아이콘으로 사용하려면 첫번째 파라미터에는 프로그램의 WndClass.hCursor = LoadCursor(NULL, 역시 커서 모양을 정의하는 부분인데 윈도우즈에 말하는 커서는 도스에서 말하는 커서와는 의미가 HCURSOR LoadCursor( IDC_ARROW 화살표 모양의 커서 WndClass.hbrBackground = 윈도우의 백경색을 흰색으로 한다는 의미입니다. HGDIOBJ GetStockObject( 위에 GetStockObject()함수의 원형이 나와 있는데 이 함수는 앞으로도 많이 BLACK_BRUSH 검정색 브러쉬 WndClass.lpszMenuName = NULL; 생성될 윈도우에 메뉴가 없기때문에 NULL로 지정하였습니다. WndClass.lpszClassName = szAppName; 클래스 이름은 타이틀바 제목과 같이 했죠. 다르게 하기 귀찮아서요. if(!RegisterClass(&WndClass)) return 이렇게 등록한 WNDCLASS구조체를 실제로 등록하는 과정입니다. 위에서 이미 다 설명드렸을 hWnd = 각 파라미터의 의미는 이미 알고 있을 겁니다. 여기서 세번째 파라미터에 보면 윈도우 생성 WS_BORDER 윈도우의 테두리를 그려 줍니다. 네번째에서 일곱번째 파라미터를 보면 CW_USEDEFAULT라고 되어 있는데 이것은 ShowWindow(hWnd, 실제로 윈도우를 보여주는 과정이죠. 보여지는 형식은 기본적으로 윈도우즈에서 제공하는 형태를 while(GetMessage(&msg, NULL, 0, 메시지 처리하는 부분이군요. 뭐 특별히 설명드릴 필요는 없는것 같군요. return msg.wParam; 자 이번에는 실제적으로 메시지를 처리하기 위한 윈도우 함수부분입니다. LRESULT CALLBACK WndProc(HWND hWnd, UINT mesg, 윈도우즈 프로그램은 메시지 프로그램이라고 해도 과언이 아닙니다. 윈도우 함수 코딩한 것을 switch(mesg) PostQuitMessage(0); 유저가 프로그램을 종료하려고 하면 WM_DESTROY 메시지가 발생되므로 이때 종료시켜야 VOID PostQuitMessage( 파라미터로 0을 지정하면 프로그램이 종료됩니다. } 그 외의 메시지는 디폴트로 처리하기 때문에 위 DefWindowProc() 함수를 LRESULT DefWindowProc( 오늘은 여기까지입니다. 쉽죠... 그럼 안녕히.... |
윈도우 32비트 프로그래밍 04 |
안녕하세요........돌팔이 황동준입니다.... 저번시간에 간단하게 윈도우를 생성하는 예제를 해 보았는데 어때요? 기능에 비해서 너무 소스가 그렇지 않습니다. 도스에서 그 정도의 기능을 가진 윈도우를 만들려면 소스양이 더 길어집니다. 자 이번에는 다른 예제를 보도록 하죠. 이번 예제도 저번 예제와 크게 다른 점은 없습니다. 이번 예제는 생성되는 윈도우의 모양이 타이틀바만 가지고 있는 예제입니다. hWnd = 생성되는 윈도우가 타이틀바만 가지려면 우리가 처음에 알아본 간단하네요. 아래는 전체 소스입니다. 한번 컴파일해서 실행시켜 보십시요. #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, int WINAPI WinMain HWND hWnd; WndClass.style = hWnd = ShowWindow(hWnd, while(GetMessage(&msg, NULL, 0, LRESULT CALLBACK WndProc(HWND hWnd, UINT mesg, SendMessage(hWnd, WM_DESTROY, case WM_DESTROY : PostQuitMessage(0); 자 이번에는 타이틀바를 다뤄보도록 하겠습니다. 타이틀바가 뭔지는 알죠? CreateWindow()라는 함수를 이용해서 윈도우를 생성할때 파라미터중 타이틀바 제목을 int GetWindowText( 위 함수를 이용해서 현재 타이틀바의 제목을 알아낼 수 있습니다. 첫번째 파라미터는 타이틀바를 타이틀바의 제목을 알아내는 함수가 있으니 지정하는 함수도 당연히 있겠죠? BOOL SetWindowText( 위 함수를 이용해서 타이틀바의 제목을 새로 지정할 수 있습니다. 두번째 파라미터에 새로 #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, int WINAPI WinMain HWND hWnd; WndClass.style = hWnd = ShowWindow(hWnd, while(GetMessage(&msg, NULL, 0, LRESULT CALLBACK WndProc(HWND hWnd, UINT mesg, switch(mesg) SetWindowText(hWnd, case WM_KEYDOWN : if(LOWORD(wParam) == case WM_DESTROY : PostQuitMessage(0); 자 그러면 구체적으로 알아볼까요? 못보던 것들도 보이는군요. 그런데 잘 보면 알겠지만 윈 LRESULT CALLBACK WndProc(HWND hWnd, UINT mesg, 새 타이틀바 제목을 위 문자열로하기 위해서 정의해 준겁니다. char szGetTitle[80]; 현재 타이틀바 제목을 읽어와서 저장하기 위해서 위 변수를 선언했습니다. switch(mesg) SetWindowText(hWnd, 못보던 메시지가 있네요. WM_CREATE라는 메시지는 윈도우가 처음 생성될 때 발생하는 case WM_KEYDOWN : if(LOWORD(wParam) == 역시 못보던 메시지로 WM_KEYDOWN 이라는 메시지가 나왔습니다. 이 메시지는 특수키가 F1-F12, Shift, Ctrl, Alt, Delete키등과 같은 키를 의미합니다. 어떤 바로 부수적인 메시지가 들어간다는 wParam에 그 구체적인 값이 들어가는 것입니다. int MessageBox( MessageBox() 함수는 유저에게 어떤 정보를 보여주기 위한 간단한 대화 상자입니다. case WM_DESTROY : PostQuitMessage(0); 윈도우를 종료하는 메시지가 오면 종료되겠죠. } 자 오늘 강좌는 |
윈도우 32비트 프로그래밍 05 |
안녕하세요.......돌팔이 황동준입니다. 저번시간에 이어서 계속 강좌를 해 보겠습니다. 이번에도 역시 윈도우를 다루는 예제인데 예제는 그럼 시작해 보죠. 우리는 윈 메인 함수의 제일 앞 부분에서 어떤 작업을 하는지에 대해 이미 알고 있습니다. DWORD SetClassLong( 위 함수를 이용해서 윈도우의 배경색을 바꿀 수 있는데 사실 위 함수로 배경색 뿐만 아니라 첫번째 파라미터는 바꿀 윈도우의 핸들을 의미하고 두번째 파라미터는 예약어로서 이 예약어로 세번째 파라미터는 바꿀 새로운 값을 의미합니다. 다음은 두번째 파라미터에 들어갈 예약어와 그 GCL_HBRBACKGROUND 배경생을 바꿀때 사용합니다. 자 그러면 실제 예제를 보도록 합시다. 아래 예제는 유저가 Enter키를 쳤을 때 배경색을 #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, int WINAPI WinMain HWND hWnd; WndClass.style = hWnd = ShowWindow(hWnd, while(GetMessage(&msg, NULL, 0, LRESULT CALLBACK WndProc(HWND hWnd, UINT mesg, if(LOWORD(wParam) == case WM_DESTROY : PostQuitMessage(0); Enter키를 치면 하얀색이던 배경색이 검정색으로 바뀜을 확인할 수 있을 겁니다. 한번 직접 LRESULT CALLBACK WndProc(HWND hWnd, UINT mesg, if(LOWORD(wParam) == Enter키가 눌리면 수행이 되도록 위 구문을 사용한 것입니다. 앞 예제와 다른 점이 SetClassLong(hWnd, 배경색을 바꾸기 때문에 두번째 파라미터에 GCL_HBRBACKGROUND를 사용하였고 세번째 InvalidateRect(hWnd, NULL, 흠 .. 못보던 함수가 하나 있네요. 이 함수는 어떤 역할을 할까요? 이 함수는 윈도우를 전체적으로 해석해 볼까요? 배경색을 바꾸고 다시 그린다. 뭐 그런 의미가 되겠네요. BOOL InvalidateRect( 첫번째 파라미터는 이미 다 아실테고 두번째 파라미터는 다시 그릴 윈도우의 사각 영역의 좌표를 typedef struct _RECT { RECT 구조체의 구성이 위에 잘 나와있네요. 각 사각 좌표를 의미하는 것입니다. 특별한 함수의 마지막 파라미터는 지정된 부분을 복구할 때 배경을 지워진 상태로 하겠느냐 아니면 } case WM_DESTROY : PostQuitMessage(0); 이상으로 첫번째 예제 설명 끝~~~~~~~~ 그러면 두번째 예제를 보도록 합시다. 두번째 예제는 전체 윈도우의 크기와 작업영역(클라이언트 BOOL GetClientRect( 위 함수로 윈도우의 작업영역의 크기를 알수 있습니다. 두번째 파라미터는 바로 위에서 알아 int GetSystemMetrics( 현재 화면의 크기를 알려면 위 함수를 이용해서 할수 있는데 위 함수로 꼭 현재 화면의 SM_CXCURSOR 커서의 넓이를 알수 있게 해줍니다. 자 그러면 실제적인 전체 소스를 보도록 합시다. 아래 예제는 윈도우가 생성될 때 작업영역과 #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, int WINAPI WinMain HWND hWnd; WndClass.style = hWnd = ShowWindow(hWnd, while(GetMessage(&msg, NULL, 0, LRESULT CALLBACK WndProc(HWND hWnd, UINT mesg, switch(mesg) GetClientRect(hWnd, case WM_KEYDOWN : if(LOWORD(wParam) == case WM_DESTROY : PostQuitMessage(0); 별로 이해하기 어려운 부분은 없는것 같네요. 그렇죠? case WM_CREATE : GetClientRect(hWnd, 이미 함수는 다 설명 드렸고 혹시 sprintf()라는 함수를 사용해 본적이 있습니까? 아마 case WM_KEYDOWN : if(LOWORD(wParam) == Enter키가 눌리면 그 값을 출력해 주는 것입니다. 오늘은 여기까지 강좌 |