안녕하세요. 이번에는 우리가 코드엔진에서 풀어본 문제 중 하나인 bagic의 03문제인 프로그램을 만들어보겠습니다. 일단 동작을 봅시다.

실행시 메세지박스가 하나 띄워집니다. 확인과 취소 버튼이 있는데 확인 버튼을 누른시 아래와 같은 창이 뜹니다. 반대로 취소 버튼을 누르면 그냥 종료가 되버립니다.

동작을 확인했으니 일단 겉만 만들어봅시다. 제가 작성한 소스를 보여드리겠습니다.

저번 포스팅에서 왠만한 api함수들은 전부 설명드렸으니 새로 나온 함수 혹은 코드만 설명하겠습니다.

- #include "resource.h"

리소스가 선언되어 있는 헤더파일을 불러옵니다. 이것은 나중에 설명드리겠습니다.

- #define REGCODE 0

  #define REGISTRIEREN 1

  #define Exit 2

edit컨트롤과 버튼컨트롤을 제어하기 위해 정의된 상수입니다.

- HWND regcode;

edit컨트롤의 핸들을 저장시킬 변수를 전역변수로 선언하였습니다.

WinMain을 살펴봅시다.

- int Message_result;

MessageBox함수의 결과값을 저장시킬 변수입니다.

- HBRUSH bgBrush;

윈도우의 배경색을 저장할 용도로 HBRUSH 형의 변수를 선언하였습니다.

- bgBrush = CreateSolidBrush(RGB(238,238,238));

HBRUSH형의 변수에 CreateSolidBrush의 결과값을 집어넣습니다. CreateSolidBrush의 정의를 봅시다. MSDN을 참고합시다.

컬러를 인자로 받아 HBRUSH 형태로 반환합니다. 즉 이 함수는 단색 브러쉬를 만드는 함수입니다. 윈도우의 배경색을 주기 위해 사용하였습니다.

- wndclass.hbrBackground = bgBrush;

윈도우의 배경색을 아까 만든 bgBrush로 지정합니다. 여기서는 RGB(238,238,238)로 만들었으므로 회색 비슷한 색깔로 지정됩니다.

- wndclass.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);

윈도우의 메뉴를 IDR_MENU1로 지정합니다. 이 IDR_MENU1는 리소스를 의미합니다. 이 리소스 작성법은 나중에 설명드리겠습니다.

그리고 MAKEINTRESOURCE함수가 사용되었습니다. MSDN을 참고합시다.

정수형을 받아서 문자열로 반환합니다. 즉 이 함수는 리소스번호를 받아 리소스 문자열로 반환시킵니다. 우리가 만든 메뉴 리소스인 IDR_MENU1이 헤더파일에 상수로 정의되어 있으므로 이 IDR_MENU1 번호를 문자열로 변환시켜 lpszMenuName에 넣어주었습니다.

 - wndclass.lpszClassName = L"a";

클래스 이름을 지정합니다. 여기서는 그냥 a로 주었습니다.

- Message_result = MessageBox(NULL,L"Entferne diesen Nag, oder bekomme das richtige Passwort heraus !",L"Nag Meldung",MB_ICONQUESTION | MB_OKCANCEL);

MessageBox함수를 사용하여 메세지박스를 띄웁니다. 이 메세지박스는 프로그램을 실행할 때 제일 먼저 나오는 메세지박스입니다.

여기서 눈여겨보실 부분은 마지막 인자부분인데 ,MB_ICONQUESTION | MB_OKCANCEL입니다. MB_ICONQUESTION은 질문 아이콘을 메세지박스에 띄우는 인자입니다. 즉

빨간박스의 저 물음표 아이콘을 띄운다는 뜻입니다. 

MB_OKCANCEL은 OK버튼과 CANCEL버튼을 만든다는 뜻입니다. MessageBox함수는 각각의 버튼을 눌렀을 때 반환되는 결과값이 다릅니다.

- if(Message_result == 1)

Message_result는 MessageBox함수의 결과값이죠. 즉 어떤 버튼을 눌렀느냐에 따라 if문을 실행하냐 안하냐를 결정합니다. 결과값이 1이면 확인버튼을 눌렀다는 뜻이므로 조건문이 참이 되어 if문 안의 코드를 실행합니다. 만약 취소를 눌렀다면 if문을 실행하지 않고 else문을 실행합니다.

- hwnd = CreateWindow(L"a",L"DCD VB5-CrackMe 1.0",WS_SYSMENU | WS_VISIBLE,73,73,253,181,NULL,NULL,hInstance,NULL);

윈도우를 생성합니다. 여기서는 윈도우 스타일에 WS_SYSMENU 인자를 주었습니다. 이 인자는 닫기 창만 존재하는 윈도우를 의미합니다. 덧붙여서 이 스타일이 적용된 윈도우는 크기를 바꿀 수 없습니다.

- else

return 0

메세지박스의 결과값이 1이 아닐 경우 프로그램을 종료합니다.

나머지 소스코드는 앞시간에 전부 설명드렸으니 따로 설명드리진 않겠습니다.

자 이제는 리소스를 만들어봅시다. 리소스 파일부분에서 rc파일을 만듭니다.

이제 만들었으니 편집을 할 차례입니다. 저는 resedit를 사용하겠습니다.

아 그리고 앞 포스팅에서 깜박하고 빼먹은 부분이 있는데 resedit를 사용하시는 분들은 resedit의 경로를 따로 지정해주어야 합니다.

Options의 Preferences...를 누릅시다.

General의 경로를 추가해주는데 어떤 경로로 설정하냐면 Windows.h 파일이 들어있는 경로로 설정해주면 됩니다.

경로를 지정해주었으면 아까 만든 리소스 파일을 열어봅시다. 보통 리소스파일은 생성시 소스파일과 동일한 위치에 생성됩니다.

해당 rc파일을 성공적으로 여셨다면 메뉴 리소스를 추가합시다.

IDR_MENU1이라는 리소스가 생성되었습니다. 우측에 보시면 Type here이 보이시죠? 이 부분이 바로 윈도우의 메뉴부분입니다. 03.exe에 맞게 직접 메뉴를 지정해줍시다.

지정을 다하시고 나서 해당 메뉴를 누르면 밑에 하위항목이 보입니다. 03.exe에는 하위항목이 Exit밖에 없으므로 Exit를 적어줍시다.

메뉴가 다 작성되었습니다. 이제 메뉴의 설정을 변경해봅시다.

메뉴 ?er을 누르고 속성부분에서 Popup부분을 False로 설정해줍니다. 이 Popup 부분은 이 메뉴가 하위항목이 있냐 없냐를 설정해주는 부분입니다. Programm 메뉴는 하위항목 Exit가 있기 때문에 이 부분을 True로 설정해주어야 하지만 ?er은 하위항목을 표시하지 않기 때문에 이 Popup부분을 False로 고쳐주어야 합니다.

여기까지가 메뉴였습니다. 이번에는 아이콘을 추가합시다. 아이콘 추출법과 추가하는 방법은 앞시간에 올렸으므로 따로 설명드리지 않겠습니다.

다 만들었으면 저장해줍시다. 그리고 비주얼 스투디오로 돌아와 리소스의 헤더파일을 추가합시다.

resource.h 파일을 찾아 추가해주시면 됩니다. 이 헤더파일 안에는 우리가 만든 리소스들이 상수로 정의되어있습니다. 이렇게 추가된 resource.h 파일을 사용하기 위해서는 소스코드이 위에 include "resource.h" 를 추가해주어야 합니다. 

여기까지 다되셨으면 우리가 만든 리소스를 사용하기 위해 소스코드를 약간 수정해줍시다. 소스코드에서는 메뉴가 추가되어있지만 아이콘을 따로 추가가 되어있지 않습니다. 그러므로 아이콘을 새로 추가해 줍시다. 다음과 같이 수정합시다.

 - wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION); -> 기존코드

 - wndclass.hIcon = LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1));

-> 수정코드

LoadIcon의 인자를 변경해줍니다. 기존에 정의되어 있는 아이콘을 사용할 경우에는 첫 인자 값을 NULL로 주지만 그 외의 아이콘을 사용할 경우에는 첫 인자에 hInstance를 줍니다. 두번째 인자는 우리가 만든 아이콘을 문자열 형태로 넣어주시면 됩니다.

자 이제 코드 설명이 전부 끝났습니다. 한번 실행을 시켜 봅시다.

그럴듯하게 만들어졌습니다. 다음포스팅에서는 동작을 구현해봅시다.

이것으로 포스팅을 마치겠습니다.

Posted by englishmath
,