[API] 로딩 화면(팝업(popup)) 기획

simpled 2013.06.23 15:59 조회 수 : 6207

 1302111391158421779419712.jpg

04.exe


누구나 이해 할 수 있는 팝업의 전형적인 예이다.

원리는 쉬워보였는데, 만들기는 제법 힘들었다.

팝업은 만들었지만 여전히 남아있는 문제가 있는데, 팝업 윈도우가 종료 된 후에, 새로운 윈도우를 생성시켜야 하는 문제점이다.


소스코드는 의외로 간단히 설명 될 수 있다.

윈도우 초기 생성시 윈도우 스타일을 popup스타일로 정의하고  popup윈도우의 사이즈를 정한다.

그리고 바탕화면의 크기를 받아서 중간 지점을 찾고, popup윈도우를 중간에 위치시킨다.

마지막으로 타이머 함수를 사용하여 약 33밀리초 (1/30초)마다 그림을 화면에 정확한 사이즈로 뿌려준다.


이 소스코드는 나중에 키보드 메시지를 막음으로써, 화면 보호기를 만들 수 있을 것 같다.

또한 링크 따위를 걸어두면, PC방에서의 아이콘화 된 바탕화면을 만들 수 도 있을것 같다. (win 8이 나오면 필요 없겠지만...)


아무튼, WndProc 함수를 기술하겠다.



// 04.cpp : 응용프로그램에대한진입점을정의합니다.

//

 

#include "stdafx.h"

#include "04.h"

 

#define MAX_LOADSTRING 100

 

// 전역변수:

HINSTANCE hInst;                                                             // 현재인스턴스입니다.

TCHAR szTitle[MAX_LOADSTRING];                                // 제목표시줄텍스트입니다.

TCHAR szWindowClass[MAX_LOADSTRING];                  // 기본창클래스이름입니다.

 

// 이코드모듈에들어있는함수의정방향선언입니다.

ATOM                          MyRegisterClass(HINSTANCE hInstance);

BOOL                          InitInstance(HINSTANCE, int);

LRESULT CALLBACK       WndProc(HWND, UINT, WPARAM, LPARAM);

INT_PTR CALLBACK       About(HWND, UINT, WPARAM, LPARAM);

 

int APIENTRY _tWinMain(HINSTANCE hInstance,

                     HINSTANCE hPrevInstance,

                     LPTSTR    lpCmdLine,

                     int       nCmdShow)

{

        UNREFERENCED_PARAMETER(hPrevInstance);

        UNREFERENCED_PARAMETER(lpCmdLine);

 

        // TODO: 여기에코드를입력합니다.

        MSG msg;

        HACCEL hAccelTable;

 

        // 전역문자열을초기화합니다.

        LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);

        LoadString(hInstance, IDC_MY04, szWindowClass, MAX_LOADSTRING);

        MyRegisterClass(hInstance);

 

        // 응용프로그램초기화를수행합니다.

        if (!InitInstance (hInstance, nCmdShow))

        {

               return FALSE;

        }

 

        hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_MY04));

 

        // 기본메시지루프입니다.

        while (GetMessage(&msg, NULL, 0, 0))

        {

               if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))

               {

                       TranslateMessage(&msg);

                       DispatchMessage(&msg);

               }

        }

 

        return (int) msg.wParam;

}

 

 

 

//

//  함수: MyRegisterClass()

//

//  목적창클래스를등록합니다.

//

//  설명:

//

//    Windows 95에서추가된'RegisterClassEx' 함수보다먼저

//    해당코드가Win32 시스템과호환되도록

//    하려는경우에만이함수를사용합니다이함수를호출해야

//    해당응용프로그램에연결된

//    '올바른형식의작은아이콘을가져올수있습니다.

//

ATOM MyRegisterClass(HINSTANCE hInstance)

{

        WNDCLASSEX wcex;

 

        wcex.cbSize = sizeof(WNDCLASSEX);

 

        wcex.style                    = CS_HREDRAW | CS_VREDRAW;

        wcex.lpfnWndProc       = WndProc;

        wcex.cbClsExtra               = 0;

        wcex.cbWndExtra               = 0;

        wcex.hInstance         = hInstance;

        wcex.hIcon                    = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MY04));

        wcex.hCursor           = LoadCursor(NULL, IDC_ARROW);

        wcex.hbrBackground     = (HBRUSH)(COLOR_WINDOW+1);

        // wcex.lpszMenuName   = MAKEINTRESOURCE(IDC_MY04);

        wcex.lpszMenuName      = NULL;

        wcex.lpszClassName     = szWindowClass;

        wcex.hIconSm           = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

 

        return RegisterClassEx(&wcex);

}

 

//

//   함수: InitInstance(HINSTANCE, int)

//

//   목적인스턴스핸들을저장하고주창을만듭니다.

//

//   설명:

//

//        이함수를통해인스턴스핸들을전역변수에저장하고

//        주프로그램창을만든다음표시합니다.

//

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)

{

   HWND hWnd;

 

   hInst = hInstance; // 인스턴스핸들을전역변수에저장합니다.

 

   hWnd = CreateWindow(szWindowClass, szTitle, WS_POPUP,

      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

 

   if (!hWnd)

   {

      return FALSE;

   }

 

   ShowWindow(hWnd, nCmdShow);

   UpdateWindow(hWnd);

 

   return TRUE;

}

 

class clValue_popup

{

public:

        // popup 화면을중앙에띄우는역할을합니다.

        HWND hWnds;

        RECT reBase, rePopup;

 

public:

        // popup 화면의크기를결정합니다.

        int iPopup_Vertical;

        int iPopup_Horizontal;

       

public:

        // popup 화면에비트맵을띄우는역할을합니다.

        HDC MemDC;

        HBITMAP MyBitmap, OldBitmap;

        BITMAP bit;

        HFONT hFont, OldFont;

 

public:

        // popup 화면의비트맵개수와카운터를저장합니다.

        int iTimer_Count;

        int iBitmap_Count;

        int iBitmapOfNumber;

 

public:

        TCHAR tcMessage[128];

        TCHAR tcCounter[128];

 

public:

        clValue_popup();

        clValue_popup(int _iBitmapOfNumber);

};

clValue_popup::clValue_popup()

{

        iTimer_Count=0;

        iBitmap_Count=0;

        iBitmapOfNumber=0;

}

 

clValue_popup::clValue_popup(int _iBitmapOfNumber)

{

        iTimer_Count=0;

        iBitmap_Count=0;

        iBitmapOfNumber=_iBitmapOfNumber;

}

 

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

{

        int wmId, wmEvent;

        PAINTSTRUCT ps;

        HDC hdc;

 

        static clValue_popup val(3); // 비트맵의개수를입력해줘야한다.

 

        switch (message)

        {

               case WM_CREATE:

                       val.hWnds = GetDesktopWindow();

                       GetClientRect(val.hWnds, &val.reBase);

                       val.iPopup_Vertical=350;

                       val.iPopup_Horizontal=500;

                       SetRect(&val.rePopup,

                              -(val.iPopup_Horizontal),

                              -(val.iPopup_Vertical) ,

                              val.iPopup_Horizontal,

                              val.iPopup_Vertical);

                       SetWindowPos(hWnd, HWND_TOPMOST,

                              int((val.reBase.right/2.0)-(val.iPopup_Horizontal/2)),

                              int((val.reBase.bottom/2.0)-(val.iPopup_Vertical/2)),

                              int(val.rePopup.right),

                              int(val.rePopup.bottom), NULL);

                       SetTimer(hWnd, 1, 1, NULL);                  // 비트맵과텍스트를출력한다.

                       SetTimer(hWnd, 2, 1000, NULL);        // 1초단위를체크한다.

                       SendMessage(hWnd, WM_TIMER, 1, 1);

                       SendMessage(hWnd, WM_TIMER, 2, 2);

                       break;

               case WM_SYSKEYDOWN:

                       break;

               case WM_KEYDOWN:

                       switch(wParam)

                       {

                              case VK_ESCAPE:

                                      PostQuitMessage(0);

                                      break;

                       }

                       break;

               case WM_TIMER:

                       switch(wParam)

                       {

                              case 1:

                                      hdc=GetDC(hWnd);

                                      val.MemDC=CreateCompatibleDC(hdc);

                                      val.MyBitmap=LoadBitmap(hInst,

                                             MAKEINTRESOURCE(IDB_BITMAP1+2));

                                      val.OldBitmap=(HBITMAP)SelectObject(val.MemDC, val.MyBitmap);

                                      GetObject(val.MyBitmap, sizeof(BITMAP), &val.bit);

                                      StretchBlt(hdc, 0, 0,val.rePopup.right, val.rePopup.bottom,

                                                             val.MemDC, 0, 0, val.bit.bmWidth, val.bit.bmHeight, SRCCOPY);

 

                                      val.hFont=CreateFont(15, 0,0,0, 0,0,0,0, HANGEUL_CHARSET, 0,0,0,

                                             VARIABLE_PITCH | FF_ROMAN, TEXT("돋움"));

                                      val.OldFont=(HFONT)SelectObject(hdc, val.hFont);

                                      SetBkMode(hdc, TRANSPARENT);

                                     

                                      wsprintf(val.tcCounter, TEXT("KNU :: Lab. for Manufacturing system"), val.iTimer_Count);

                                      TextOut(hdc, 10, 10, val.tcCounter, lstrlen(val.tcCounter));

                                     

                                      if(0<=val.iBitmap_Count && val.iBitmap_Count<1)

                                             wsprintf(val.tcCounter, TEXT("[%d][%d] Now Loading."), val.iBitmap_Count, val.iTimer_Count);

                                      if(1<=val.iBitmap_Count && val.iBitmap_Count<2)

                                             wsprintf(val.tcCounter, TEXT("[%d][%d] Now Loading.."), val.iBitmap_Count, val.iTimer_Count);

                                      if(2<=val.iBitmap_Count && val.iBitmap_Count<3)

                                             wsprintf(val.tcCounter, TEXT("[%d][%d] Now Loading..."), val.iBitmap_Count, val.iTimer_Count);

                                     

                                      TextOut(hdc, 10, 30, val.tcCounter, lstrlen(val.tcCounter));

                                     

                                      SelectObject(hdc, val.OldFont);

                                      SelectObject(val.MemDC, val.OldBitmap);

                                      DeleteObject(val.hFont);

                                      DeleteObject(val.MyBitmap);

                                      DeleteDC(val.MemDC);

                                      ReleaseDC(hWnd, hdc);

                                      val.iBitmap_Count++;

                                     

                                      if(val.iBitmap_Count > val.iBitmapOfNumber-1)

                                             val.iBitmap_Count=0;  

                                      break;

                             

                              case 2:

                                      val.iTimer_Count++;

                                      break;

                       }

                       break;

              

               case WM_COMMAND:

                       wmId    = LOWORD(wParam);

                       wmEvent = HIWORD(wParam);

                       // 메뉴의선택영역을구문분석합니다.

                       switch (wmId)

                       {

                              case IDM_ABOUT:

                                      DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);

                                      break;

                              case IDM_EXIT:

                                      DestroyWindow(hWnd);

                                      break;

                              default:

                                      return DefWindowProc(hWnd, message, wParam, lParam);

                       }

                       break;

               case WM_PAINT:

                       hdc = BeginPaint(hWnd, &ps);

                       EndPaint(hWnd, &ps);

                       break;

               case WM_DESTROY:

                      

                       KillTimer(hWnd, 2);

              

                       KillTimer(hWnd, 1);

                      

                       PostQuitMessage(0);

                       break;

               default:

                       return DefWindowProc(hWnd, message, wParam, lParam);

        }

        return 0;

}

 

// 정보대화상자의메시지처리기입니다.

INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)

{

        UNREFERENCED_PARAMETER(lParam);

        switch (message)

        {

               case WM_INITDIALOG:

                       return (INT_PTR)TRUE;

 

               case WM_COMMAND:

                       if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)

                       {

                              EndDialog(hDlg, LOWORD(wParam));

                              return (INT_PTR)TRUE;

                       }

                       break;

        }

        return (INT_PTR)FALSE;

}