IT_Programming/MFC · API

[API] 윈도우 프로퍼티 (Window Property)

JJun ™ 2009. 7. 24. 10:28

==================================================================================================

 

윈도우 프로퍼티 : 여분의 메모리와 같은 용도 - 여분의 메모리보다 유연하고 편리한 방법

                           프로퍼티는 윈도우에 저장되는 고유 데이터이며, 각 프로퍼티에 이름을 줄 수 있기

                           때문에 오프셋으로 값을 엑세스하는 여분의 메모리보다 사용하기도 훨씬 편리하다.

                           프로퍼티에 기억되는 값은 32비트의 길이를 가지며 그러므로 포인터로 표현할 수 있는

                           모든 정보를 저장할 수 있다.

                          

 

사용 : BOOL SetProp(HWND hwnd, LPCSTR lpString, HANDLE hData)

          - hwnd 윈도우에 lpString이라는 이름으로 프로퍼티를 생성하고, 이 프로퍼티에 hData라는 값을

            기억시킨다. 이 때 lpString이 이미 존재한다면 값을 변경한다.

 

         HANDLE GetProp(HWND hwnd, LPCSTR lpString)

         - lpString이라는 이름의 프로퍼티에 기억되어 있는 값을 읽는다.

           프로퍼티에 기억되는 값은 HANDLE형의 어떤 데이터라도 상관없다.

           주로 메모리 핸들이나 파일 핸들 등의 핸들을 많이 기억해 놓으므로

           프로퍼티의 타입이 HANDLE로 되어 있지만, 캐스팅만 적절히 하면

           32비트의 어떤 값이라도 저장해 놓을 수 있다.

 

         HANDLE RemoveProp(HWND hwnd, LPCSTR lpString)

         - 생성한 프로퍼티 제거 용도. 프로퍼티에 기억된 값을 리턴.

         - 만약 프로퍼티에 기억된 값이 동적으로 할당된 메모리의 핸들이라면

            메모리도 같이 해제해주어야 한다.

         - WM_DESTROY 등의 메시지에서 필요한 해제 처리를 하면 가장 적합하다.

 

--------------------------------------------------------------------------------------------------

 

[ 예제 : 윈도우즈API정복 1권 ]

==================================================================================================

 

[실행화면]

 

 - 초기화면

 

 - 마우스 왼쪽 버튼 클릭시

 

 - 윈도우 창 크기를 줄였다가 다시 크게 할 경우 

 

 

==================================================================================================

 

[소스코드]

#include <windows.h>

 

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

 

HINSTANCE g_hInstance;

 

int APIENTRY WinMain( HINSTANCE hInstance,

                                   HINSTANCE hPrevInstance,

                                   LPSTR lpCmdLine,

                                   int nShowCmd)
{
      HWND  hwnd;
      MSG   message;
      WNDCLASS wndclass;
      static char lpszMainClass[] = TEXT("MainWindow");
 
      g_hInstance = hInstance;

 

      wndclass.cbClsExtra  = 0;
      wndclass.cbWndExtra  = 0;
      wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
      wndclass.hCursor  = LoadCursor(NULL, IDC_ARROW);
      wndclass.hIcon   = LoadIcon(NULL, IDI_APPLICATION);
      wndclass.hInstance  = hInstance;
      wndclass.lpfnWndProc = WndProc;
      wndclass.lpszClassName = lpszMainClass;
      wndclass.lpszMenuName = NULL;
      wndclass.style   = CS_HREDRAW | CS_HREDRAW;
      RegisterClass(&wndclass);

    

      // 이전 예제와 달리 여분의 메모리를 사용하겠다는 지정 부분이 없다!

      wndclass.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
      wndclass.hCursor = LoadCursor(NULL, IDC_CROSS);
      wndclass.lpfnWndProc = ChildProc;
      wndclass.lpszClassName = TEXT("ChildsCls");

      RegisterClass(&wndclass);

 

     hwnd = CreateWindow (
                                          lpszMainClass,
                                          lpszMainClass,
                                          WS_OVERLAPPEDWINDOW,
                                          CW_USEDEFAULT,
                                          CW_USEDEFAULT,
                                          CW_USEDEFAULT,
                                          CW_USEDEFAULT,
                                          NULL,
                                          (HMENU) 0,
                                          hInstance,
                                          NULL
                                    );

 

      ShowWindow(hwnd, nShowCmd);

 

      while(GetMessage(&message, NULL, 0, 0)) // 메시지 루프
      {
            TranslateMessage(&message);
            DispatchMessage(&message);
      }

 

      return (int)message.wParam;
}

 

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp)
{
      int x, y;
 
      switch(message)
      {
            case WM_CREATE : for(x=0; x<300; x+=100) // x 좌표
                                          {
                                                for(y=0; y<300; y+=100) // y 좌표
                                                {
                                                      CreateWindow (
                                                                               TEXT("ChildsCls"),
                                                                               NULL,
                                                                               WS_CHILD | WS_VISIBLE,
                                                                               x,
                                                                               y,
                                                                               100,
                                                                               100,
                                                                               hwnd, // 부모 윈도우 핸들 등록

                                                                               (HMENU) NULL,
                                                                               g_hInstance,
                                                                               NULL
                                                                         );
                                                }
                                          }

                                                      return 0;

 

           case WM_DESTROY : PostQuitMessage(0);
                                           return 0;
    }

 

    return DefWindowProc(hwnd, message, wp, lp);
}

 

LRESULT CALLBACK ChildProc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp)
{
     HDC   hdc;
     PAINTSTRUCT ps;
     BOOL  prop;
 
     switch(message)
     {
          case WM_CREATE :  SetProp(hwnd, TEXT("bEllipse"), (HANDLE)TRUE);
                                         return 0;

 

          case WM_LBUTTONDOWN : // (HANDLE)!prop : TRUE → FALSE , FALSE → TRUE
                                                    prop = (BOOL)GetProp(hwnd, TEXT("bEllipse"));
                                                    SetProp(hwnd, TEXT("bEllipse"), (HANDLE)!prop);

                                                    // 강제로 WM_PAINT 메시지를 발생시킴
                                                    InvalidateRect(hwnd, NULL, TRUE); 
                                                    return 0;

 

         case WM_PAINT :   hdc = BeginPaint(hwnd, &ps);
                                      prop = (BOOL)GetProp(hwnd, TEXT("bEllipse"));     

                                      if(prop) // TRUE
                                      {
                                            // ㅇ(동그라미) 그리기
                                            Ellipse(hdc, 10, 10, 90, 90);
                                      }
                                      else // FALSE
                                      {
                                           // X(엑스)자 그리기
                                           MoveToEx(hdc, 10, 10, NULL);
                                           LineTo(hdc, 90, 90);
         
                                           MoveToEx(hdc, 10, 90, NULL);
                                           LineTo(hdc, 90, 10);
                                      }

                                      EndPaint(hwnd, &ps);
                                      return 0;

 

        case WM_DESTROY :  RemoveProp(hwnd, TEXT("bEllipse"));
                                         return 0;
    }

    return DefWindowProc(hwnd, message, wp, lp);

}

 

==================================================================================================