윈도우 32비트 프로그래밍 16 |
안녕하세요........돌팔이 황동준입니다..... 오늘은 메뉴 부분 마지막 강좌인 툴바와 툴팁 대해서 알아보도록 하겠습니다. 먼저 용어를 정의 툴바가 무엇인지 모르지는 않겠죠? 한글로 도구모음이라고 번역이 되는데 이것은 메뉴 아래에 MFC를 이용해서 프로그램을 만들면 이 툴바를 간단하게 구현할 수 있지만 API는 조금
자 그러면 툴바와 툴팁을 어떻게 구현하는지 알아 봅시다. 이 툴바와 툴팁을 구현하면 메뉴 툴바에 사용되는 그림은 윈도우즈에서 사용하는 비트맵 파일 포맷을 사용합니다. 비트맵 그림을 500 BITMAP "icon.bmp" 위와 같은 형태로 정의 해줍니다. 뭐가 다른지 알겠습니까? 우리가 예전에 비트맵 파일을 툴바를 만들어줄 함수를 사용하기 위해서는 아래의 헤더 파일을 포함시켜야 합니다. #include <commctrl.h> 이것은 우리가 CreateWindow() 함수와 같은 어떤 윈도우를 생성할 때 사용하는 void InitCommonControls(void); 위에서 선언한 헤더 파일에서 지원하는 컨트롤을 사용하기 위해서는 윈도우를 생성하는 툴바로 사용할 그림은 하나죠? 그러나 그 그림은 16크기로 구분되어져 있을 겁니다. 각 typedef struct _TBBUTTON { 구조체의 원형을 잘 보여주고 있군요. 각 구조체 멤버의 의미를 알아 봅시다. 우선 첫번째 TBSTATE_ENABLED 일반적인 버튼을 네번째 멤버인 fsStyle은 버튼의 스타일을 지정해 줄수 있는데 이때 지정될수 있는 TBSTYLE_BUTTON 일반적인 버튼을 나머지 멤버는 잘 쓰이지 않아 보통 0으로 지정해주면 됩니다. 자 그러면 정리해 봅시다. 비록 그림은 하나지만 그 그림속에 4개의 버튼이 있다면 위 WINCOMMCTRLAPI HWND WINAPI CreateToolbarEx(HWND 툴바를 만들기 위해서 위 CreateToolbarEx() 함수를 사용합니다. 우와~~~ hwnd 메인 윈도우의 핸들을 의미합니다. ws 윈도우의 스타일을 지정하면 됩니다. 보통 wID 전체 툴바에 대한 아이디를 지정하면 되는데 보통 -1을 nBitmaps 그림버튼의 개수를 지정하면 됩니다. 위에서 알아 본대로면 hBMInst 인스턴스 핸들을 지정하면 됩니다. wBMID 툴바로 사용할 그림의 아이디인데 이것은 리소스 파일에서 lpButtons 바로 위에서 배운 툴바 구조체의 주소를 지정해 주면 iNumButtons 역시 툴바 버튼의 개수를 지정하면 됩니다. 4라고 지정하면 dxButton 보통 0이라고 지정하면 됩니다. dyButton 보통 0이라고 지정하면 됩니다. dxBitmap 버튼 그림 하나의 가로 크기를 지정하면 됩니다. 16이라고 dyBitmap 버튼 그림 하나의 세로 크기를 지정하면 됩니다. 16이라고 uStructSize 툴바 구조체의 크기를 지정하면 됩니다. 툴바 구조체를 선언해서 값을 채워주고 위 함수를 이용하면 간단하게 툴바가 구현됩니다. 그렇게 커서가 툴바에 놓여진채 몇초가 지나면 WM_NOTIFY라는 메시지가 발생됩니다. 그런데 LPTOOLTIPTEXT ttText; case WM_NOTIFY : ttText = 자 여기까지입니다. 위의 것을 해석하려면 먼저 TOOLTIPTEXT라는 구조체의 typedef struct tagTOOLTIPTEXT { 멤버중 모르는 변수 타입이 있죠? 바로 NMHDR이라는 타입인데 이것도 구조체입니다. 다음은 typedef struct tagNMHDR 이젠 ttText->hdr.code 구문이 이해 가죠? 이 값이 switch(ttText->hdr.idFrom) ttText->lpszText = "Open"; } 100이라는 아이디를 가진 버튼에 커서가 놓여 있으면 Open이라는 풍선 도움말을 보내라는 먼저 리소스 파일의 소스입니다. #include <windows.h> 500 BITMAP "icon.bmp" MyMenu MENU 프로그램 메인 소스입니다. #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, HWND hToolbar; int WINAPI WinMain HWND hWnd; WndClass.style = hWnd = InitCommonControls(); while(GetMessage(&msg, NULL, 0, LRESULT CALLBACK WndProc(HWND hWnd, UINT mesg, switch(mesg) hDC = TextOut(hDC, 100, 100, "Open case 200 : TextOut(hDC, 100, 100, "Close case 300 : TextOut(hDC, 100, 100, "Save case 400 : TextOut(hDC, 100, 100, "Save As case 600 : ShowWindow(hToolbar, case 700 : ShowWindow(hToolbar, case WM_NOTIFY : ttText = ttText->lpszText = case 200 : ttText->lpszText = case 300 : ttText->lpszText = case 400 : ttText->lpszText = "Save case WM_DESTROY : PostQuitMessage(0); void CreateTOOLBAR(HWND hWnd, HINSTANCE tbToolbar[0].iBitmap = tbToolbar[1].iBitmap = tbToolbar[2].iBitmap = tbToolbar[3].iBitmap = tbToolbar[4].iBitmap = hToolbar = 1부 |
윈도우 32비트 프로그래밍 17 |
2부를 시작 하겠습니다. 먼저 툴바를 사용하기 위해 아래의 헤더 파일을 포함 시켰습니다. 이미 설명 드린 #include <commctrl.h> 윈도우 생성하는 CreateWindow() 함수 다음에 아래 함수도 사용해야 한다고 했을 InitCommonControls(); 못보던 함수가 하나 있죠? 바로 아래 함수인데 이것은 필자가 만든 함수입니다. 이 함수 CreateTOOLBAR(hWnd, hInstance); void CreateTOOLBAR(HWND hWnd, HINSTANCE 어허~~ 이렇게 이상한일이 발생할 수가????? 버튼이 4개로 구성되어 있다고 했는데 왜 tbToolbar[0].iBitmap = 리소스 파일에서 만든 메뉴 아이템중 100 값을 갖는게 있죠? 그것에 대한 버튼입니다. 보면 tbToolbar[1].iBitmap = 여기까지는 크게 어려운 부분이 없죠? 아래를 봅시다. tbToolbar[2].iBitmap = 버튼의 인덱스가 2가 되어야 하는데 0이 되고 아이디도 0이죠? 이 버튼은 버튼의 역할을 tbToolbar[3].iBitmap = tbToolbar[4].iBitmap = 나머지는 같군요. hToolbar = 실제로 등록한 값을 가지고 버튼을 생성하는 과정을 보여주고 있습니다. 버튼 개수를 지정하는 } 이 과정으로 인해서 툴바를 만드는 과정은 끝난 것입니다. 그러면 이번에는 툴팁처리 하는 case WM_NOTIFY : ttText = ttText->lpszText = case 200 : ttText->lpszText = case 300 : ttText->lpszText = case 400 : ttText->lpszText = "Save 아이고 쉬워라~~~~~~~~~~~~~ 이미 다 설명이 된 거군요. 그쵸? 할게 없네요. 바로 툴바를 보이게 하고 보이지 않게 하고 하는 부분인데 보통 윈도우즈용 프로그램을 보면 ShowWindow(hToolbar, SW_HIDE); 위 함수는 많이 본거죠? 첫번째 파라미터는 툴바의 핸들을 의미하고 두번째 파라미터는 툴바를 ShowWindow(hToolbar, SW_RESTORE); 반대 역할을 하는거군요. 다시 보이게 하는 역할을 합니다. 2부 끝~~~~~~~~~~~~~~~~~~~~ 오늘은 여기까지 |
윈도우 32비트 프로그래밍 18 |
안녕하세요...........돌팔이 황동준입니다................. 오늘 배울 것은 한가지입니다. 바로 상태바를 만드는 예제인데 툴바를 구현할 때와 크게 다른 #include 툴바를 구현할 때도 사용했죠? 현 작업영역의 크기를 알기 위해서 GetClientRect() 함수를 사용했던거 기억납니까? hStatebar = 위와 같은 형식으로 사용하면 되죠. 상태바를 생성하는 함수를 이용해서 생성했으니 이 상태바의 유저가 어떤 작업을 하게 되면 항상 메시지가 발생하게 됩니다. 그런데 우리는 이 메시지를 예를들어서 유저가 a라는 키를 누르게 되면 어떤 메시지가 보내집니까? 주 메시지인 mesg에 char cChar = 'a'; 위와 같은 구문으로 보낼 수 있습니다. 그런데 위 구문이 맞는지 모르겠네????? 하여간 SendMessage(hWnd, WM_DESTROY, (WPARAM)0, 메뉴 아이템이 선택되었을 때 위 구문을 사용하면 종료가 됩니다. 그렇겠죠? SendMessage() 함수의 쓰임을 알았으니 계속해서 상태바에 대한 부분을 얘기해 보도록 예를 하나 들어보죠. SendMessage(hStatebar, SB_SETPARTS, (WPARAM)3, 위의 구문은 상태바를 세 등분으로 나누고 있는 것을 보여 주고 있는 것입니다. 아마 SendMessage(hStatebar, SB_SETTEXT, (WPARAM)0, 위와 같이 역시 SendMessage() 함수를 이용해서 지정하면 되는데 세번째 파라미터에 char szBuff[100]; 첫벗째 파트에 현재 어떤 문자열이 지정되어 있는지 알 수 있게 해주는 구문입니다. 자 그러면 먼저 리소스 파일의 소스입니다. #include <windows.h> MyMenu MENU 프로그램 소스입니다. #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, HWND hStatebar; int WINAPI WinMain HWND hWnd; WndClass.style = hWnd = InitCommonControls(); while(GetMessage(&msg, NULL, 0, LRESULT CALLBACK WndProc(HWND hWnd, UINT mesg, switch(LOWORD(wParam)) ShowWindow(hStatebar, case 200 : ShowWindow(hStatebar, case WM_TIMER : if(LOWORD(wParam) == case WM_DESTROY : KillTimer(hWnd, char* TimeCal(void) void CreateSTATEBAR(HWND hWnd, HINSTANCE GetClientRect(hWnd, &rect); for(n=1; n<=3; hStatebar = SendMessage(hStatebar, SB_SETPARTS, (WPARAM)3, 자 그러면 구체적으로 분석해 봅시다. InitCommonControls(); 시간을 매초마다 갱신하기 위해서 타이머를 걸어 두었군요. 그리고 필자가 만든 함수가 void CreateSTATEBAR(HWND hWnd, HINSTANCE GetClientRect(hWnd, &rect); for(n=1; n<=3; 현재 작업영역의 크기를 이용해서 똑같이 세 부분으로 확인하는 과정입니다. hStatebar = 클래스 이름만 다르게 하고 상태바를 생성하는군요. 이미 앞에서 설명을 드린 SendMessage(hStatebar, SB_SETPARTS, (WPARAM)3, 지정해 준 좌표를 이용해서 세파트로 나누고 있는 부분입니다. SendMessage(hStatebar, SB_SETTEXT, 각 파트에 문자열을 지정하고 있습니다. TimeCal()이라는 함수는 이미 우리가 타이머를 case WM_TIMER : if(LOWORD(wParam) == 매 초가 되면 새로운 시간을 갱신해서 세번째 파트에 시간을 지정해 주고 있습니다. case WM_COMMAND : switch(LOWORD(wParam)) ShowWindow(hStatebar, case 200 : ShowWindow(hStatebar, 툴바를 보이고 하고 보이지 않게 했던 구문과 똑같죠? 역시 상태바를 보이게 하고 보이지 않게 그런데 중요한 설명을 빠뜨리고 설명을 드린 것 같군요. 툴바 때도 그렇고 상태바를 구현할 자 오늘은 여기까지 |
윈도우 32비트 프로그래밍 19 |
안녕하세요............돌팔이 황동준입니다...... 오늘부터는 그래픽 부분에 대한 강좌를 시작하겠습니다. 오늘은 점, 선, 박스를 윈도우의 먼저 점을 찍는 방법부터 알아 봅시다. 아주 간단합니다. 점 찍는 함수가 있거든요. 그 함수 COLORREF SetPixel(HDC hDC, int nX, int nY, COLORREF 디바이스 컨텍스트 핸들, 찍힐 좌표, 그리고 점의 색깔을 파라미터로 요구한다는 것을 쉽게 #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, int WINAPI WinMain WndClass.style = hWnd = ShowWindow(hWnd, while(GetMessage(&msg, NULL, 0, return msg.wParam; LRESULT CALLBACK switch(message) nX = case WM_DESTROY : PostQuitMessage(0); 마우스가 클릭되었을때 처리하는 부분을 보도록 합시다. case WM_LBUTTONDOWN : nX = LOWORD(lParam); 뭐 설명드릴 껀덕지가 없군요. 이번에는 선을 긋는 방법을 알아 봅시다. 여러분들이 어떤 HPEN CreatePen(int fnPenStyle, int nWidth, COLORREF 위 함수를 이용해서 펜을 생성할 수 있습니다. 리턴된 핸들을 SelectObject()라는 선택된 펜을 이용해서 작업을 다 했다면 펜 핸들을 반환해주어야 합니다. 디바이스 컨텍스트 BOOL DeleteObject(HGDIOBJ hgdiObj); 위 함수를 이용해서 반환해주면 됩니다. CreatePen() 함수의 파라미터에 대해 PS_DASH 점선을 의미합니다. 직접 위 예약어들을 지정하고 테스트 해보면 어떤 것을 의미하는지 알게 될 겁니다. 두번째 펜을 선택하는 방법을 알았으니 이제 그 다음에 어떤 작업이 필요한지 알아 봅시다. 그려질 선의 시작 좌표가 필요하겠네요. 시작 좌표는 현재 좌표를 이동하는 함수를 이용해서 BOOL MoveToEx(HDC hDC, int nX, int nY, LPPOINT 첫번째, 두번째, 세번째 파라미터가 어떤 역할을 하는지 짐작이 가죠? 좌표를 지정하는 자 그러면 실제로 선을 긋는 함수에 대해 알아 봅시다. BOOL LineTo(HDC hDC, int nX, int nY); 파라미터로 그려질 선의 목적 좌표를 지정해 주면 됩니다. 자 그러면 이 함수를 이용해서 만든 예제를 보도록 합시다. 아래 예제는 마우스로 클릭한 #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, int WINAPI WinMain WndClass.style = hWnd = ShowWindow(hWnd, while(GetMessage(&msg, NULL, 0, return msg.wParam; LRESULT CALLBACK switch(message) bMouse = case WM_LBUTTONUP : bMouse = case WM_MOUSEMOVE : if(bMouse) case WM_PAINT : if(bMouse) case WM_DESTROY : PostQuitMessage(0); 자 그러면 위 소스를 보도록 합시다. case WM_LBUTTONDOWN : bMouse = TRUE; 먼저 마우스의 왼쪽 버튼이 눌리면 버튼이 눌렸다는 신호를 TRUE로 세팅하고 그 case WM_LBUTTONUP : bMouse = FALSE; 마우스의 왼쪽 버튼이 놓여지면 왼쪽 버튼이 눌린 상태가 아니라는 것을 알리기 위해서 case WM_PAINT : if(bMouse) 자 WM_PAINT 메시지 처리 부분입니다. 한번 보세요. bMouse값에 따라 펜을 서로 case WM_MOUSEMOVE : if(bMouse) 위 메시지는 마우스가 움직일 때 발생되는 메시지라고 설명 드렸죠? 왼쪽 버튼이 눌린 상태에서 이번에는 박스를 어떻게 그리는지 알아 보겠습니다. 박스도 마찬가지입니다. 박스 그리는 함수 BOOL Rectangle(HDC hDC, int nLeftTop, int nTop, int 차례로 사각 모서리의 왼쪽 위 좌표, 오른쪽 아래 좌표를 의미하는 것입니다. 사각의 양 #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, int WINAPI WinMain WndClass.style = hWnd = ShowWindow(hWnd, while(GetMessage(&msg, NULL, 0, return msg.wParam; LRESULT CALLBACK switch(message) bMouse = case WM_LBUTTONUP : bMouse = case WM_MOUSEMOVE : if(bMouse) case WM_PAINT : if(bMouse) case WM_DESTROY : PostQuitMessage(0); 소스 코드가 똑같죠? 함수 하나만 다르군요. 오늘은 여기까지 |
윈도우 32비트 프로그래밍 20 |
안녕하세요..............돌팔이 황동준입니다............. 오늘도 역시 그래픽에 관련된 예제인데 크게 세가지를 알아 보겠습니다. 원, 다각형, 그리고 먼저 첫번째 프로그램으로 원을 그리는 예제를 보도록 하겠습니다. 이 원 그리는 예제도 BOOL Ellipse(HDC hDC, int nLeftTop, int nTop, int 파라미터는 앞에서 먼저 알아본 사각형을 그리는 함수와 같습니다. 즉 위 함수를 사용하면 사각 #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, int WINAPI WinMain WndClass.style = hWnd = ShowWindow(hWnd, while(GetMessage(&msg, NULL, 0, return msg.wParam; LRESULT CALLBACK switch(message) bMouse = case WM_LBUTTONUP : bMouse = case WM_MOUSEMOVE : if(bMouse) case WM_PAINT : if(bMouse) case WM_DESTROY : PostQuitMessage(0); 설명 드릴부분이 없군요. 그렇죠? 자 이번에는 어떤 특정한 모양의 그림을 그리는 것이 아니라 다각형은 꼭지점으로 이루어 졌죠? 이 꼭지점을 지정한 후에 이 꼭지점을 연결해 주는 함수를 BOOL Polygon(HDC hDC, CONST POINT *lpPoints, int 두번째 파라미터는 꼭지점 정보가 들어 있는 POINT 구조체의 주소입니다. 세번째 파라미터는 #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, int WINAPI WinMain WndClass.style = hWnd = ShowWindow(hWnd, while(GetMessage(&msg, NULL, 0, return msg.wParam; LRESULT CALLBACK switch(message) nX = case WM_DESTROY : PostQuitMessage(0); 위 예제가 어떤 역할을 하는 건지 짐작이 갑니까? 바로 윈도우의 작업영역에 마우스의 왼쪽 case WM_LBUTTONDOWN : nX = LOWORD(lParam); 마우스의 왼쪽 버튼을 누르면 그 좌표값을 저장하는 구문입니다. if(nCount == 5) 다섯번 클릭되었을 때 다각형을 그리는 구문이군요. 그렇게 어렵지는 않을 겁니다. 자 우리는 이제껏 다각형이나 선, 원, 사각형등을 그리는 에제만 보았습니다. 이제 마지막으로 HBRUSH CreateSolidBrush(COLORREF crColor); 위 함수를 이용해서 브러쉬 핸들을 얻으면 됩니다. 파라미터는 컬러입니다. 함수 이름에서 알 HBRUSH CreatHatchBrush(int fnStyle, COLORREF 첫번째 파라미터에 어떤 값을 넣는냐에 따라서 빗금치는 형식이 다른 브러쉬를 얻을 수 HS_HORIZONTAL 가로방향의 선을 의미합니다. 위에 보면 빗금이라고 되어 있는데 말로서 설명하지니 상당히 난감하군요.. 아래에 예제가 아래 예제는 바로 위에서 알아본 예제와 같습니다. 단지 다른 점은 그려진 다각형의 내부를 #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, int WINAPI WinMain WndClass.style = hWnd = ShowWindow(hWnd, while(GetMessage(&msg, NULL, 0, return msg.wParam; LRESULT CALLBACK switch(message) nX = f(nPattern == 4) return 0; case WM_DESTROY : PostQuitMessage(0); 우리가 알아본 내부를 칠하는 브러쉬를 어떻게 취하는지를 골고루 보여주고 있는 것입니다. 오늘은 여기까지 끝~~~~~~~~~~~~~~~~~~~~~ 추신 > 앞으로는 굉장히 어려워 집니다. 지금까지는 사실은 장난이죠..... 자! 진하게 준비하길 |