본문 바로가기
코스웨어/15년 스마트컨트롤러

20151116_안향진_API_3

by 알 수 없는 사용자 2015. 11. 16.
728x90
반응형

=

4-1-라. TranslateMessage

  while (GetMessage(&Message, 000)) { // 윈도우가 보내는 메시지를 받는 함수 (메시지 큐에서 제일 오래된 것을 들고옴 - 원형 연결리스트 )
    // 창 닫으면 GetMessage는 0을 반환 => while문 종료 
    TranslateMessage(&Message); // 키보드
    DispatchMessage(&Message); // 위도우가 할 것은 끝났다 => 어플리케이션 WndProc를 불러다오  
  }


GetMessage는 메시지 큐에서 메시지를 꺼내온 후 이 메시지를 TranslateMessage 함수로 넘겨 준다. TranslateMessage 함수는 전달된 메시지가 WM_KEYDOWN인지와 눌려진 키가 문자키인지 검사해 보고 조건이 맞을 경우 WM_CHAR 메시지를 만들어 메시지 큐에 덧붙이는 역할을 한다. 물론 문자 입력이 아닐 경우는 아무 일도 하지 않으며 이 메시지는 DispatchMessage 함수에 의해 WndProc으로 보내진다. 만약 메시지 루프에서 TranslateMessage 함수를 빼 버리면 WM_CHAR 메시지는 절대로 WndProc으로 전달되지 않을 것이다. 


4-2-가. Mouse

LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam) // 어플리케이션 핵심 실제 메인 
{
  HDC hdc;
  PAINTSTRUCT ps;
  
static int x;
  
static int y;
  
static WCHAR wcBuffer[100];

  
switch (iMessage)
  {
    
case WM_PAINT:
      hdc 
= BeginPaint(hWnd, &ps);
      SetTextAlign(hdc, TA_CENTER);
      TextOut(hdc, 
100100, wcBuffer, lstrlen(wcBuffer));
      EndPaint(hWnd, 
&ps);
      
return 0;
    
case WM_MOUSEMOVE:
      x 
= LOWORD(lParam);
      y 
= HIWORD(lParam);
      wsprintf(wcBuffer, L"x는 %d, y는 %d이다.
", x, y); //s:메모리에 출력한다, ws:유니코드 지원함수이다.
      InvalidateRect(hWnd, NULL, TRUE);
      return 0;
    case WM_LBUTTONDBLCLK:
      wcBuffer[0] 
= 0; //wcBuffer을 비운다.
      InvalidateRect(hWnd, NULL, TRUE);
      return 0;
    case WM_DESTROY:
      PostQuitMessage(0);
      return 0;
  }

  return(DefWindowProc(hWnd, iMessage, wParam, lParam)); // DESTROY이외 처리는 윈도로 보냄 
}



4-2-나. 더블클릭


WndClass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; 

LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam) // 어플리케이션 핵심 실제 메인 
{
  HDC hdc;
  PAINTSTRUCT ps;
  
static int x = 100;
  
static int y = 100;
  
static WCHAR wcBuffer[100];
  
static BOOL bnowDraw = FALSE;

  
switch (iMessage)
  {
    
case WM_LBUTTONDOWN:
      x 
= LOWORD(lParam); //클릭했을 때의 x좌표
      y = HIWORD(lParam); //클릭했을 때의 y좌표
      bnowDraw = TRUE;
      
return 0;
    
case WM_MOUSEMOVE: //마우스가 움직이면 무조건 발생한다.
      if (bnowDraw == TRUE) //왼쪽 버튼이 눌러져 있으면~
      {
        hdc 
= GetDC(hWnd);
        MoveToEx(hdc, x, y, NULL);
        x 
= LOWORD(lParam);
        y 
= HIWORD(lParam);
        LineTo(hdc, x, y);
        ReleaseDC(hWnd, hdc);
      }
      
return 0;
    
case WM_LBUTTONUP:
      bnowDraw 
= FALSE; //if문을 사용하지 못하게 한다.
      return 0;

    
case WM_LBUTTONDBLCLK:
      InvalidateRect(hWnd, NULL, TRUE);
      
return 0;  
    case WM_DESTROY:
      PostQuitMessage(
0);
      
return 0;
  }

  
return(DefWindowProc(hWnd, iMessage, wParam, lParam)); // DESTROY이외 처리는 윈도로 보냄 
}



=>더블클릭




4-3-가.타이머

case WM_CREATE : //딱 한 번 호출

SetTimer(hWnd,1,1000,NULL)

1 : TIMER 번호

1000 :  간격

NULL : 1초마다 호출될 함수 주소 => 없으면 WM_TIMER 메시지만 발생


case WM_DESTROY

KillTimer(hWnd,1);

1: 타이머 번호와 일치해야 함

=>테트리스의 경우 블록 떨어지는 속도, 미사일 속도..



4-3-나. SendMessage

SendMessage(hWnd, WM_TIMER, 1, 0);

발생시킬 메시지

wparam

lparam


=>창 열리면 바로 타임표시됨


static RECT rt={100,100,400,120};

InvalidateRect(hWnd,&rt,TRUE);

=> 해당 영역만 다시그림






//4-3-가.타이머
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam) // 어플리케이션 핵심 실제 메인 
{
  HDC hdc;
  PAINTSTRUCT ps;
  time_t mytime;
  
static HANDLE hTimer;
  
static char *str;

  
switch (iMessage)
  {
    
case WM_CREATE:
      hTimer 
= (HANDLE)
        SetTimer(hWnd, 
21000, NULL);
      str 
= "";
    
case WM_TIMER:
      time(
&mytime);      
      str 
= ctime(&mytime);
      InvalidateRect(hWnd, NULL, TRUE);
    
case WM_PAINT:
      hdc 
= BeginPaint(hWnd, &ps);
      TextOut(hdc, 
100100, str, strlen(str)-1);
      EndPaint(hWnd, 
&ps);
      
return 0;
    
case WM_DESTROY:
      KillTimer(hWnd, 
2);
      PostQuitMessage(
0);
      
return 0;
  }

  
return(DefWindowProc(hWnd, iMessage, wParam, lParam)); // DESTROY이외 처리는 윈도로 보냄 
}


LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
  HDC hdc;
  PAINTSTRUCT ps;
  SYSTEMTIME st;
  
static TCHAR sTime[128];
  
static RECT rt = { 10100400300 };

  
switch (iMessage)
  {
  
case WM_CREATE:
    SetTimer(hWnd,
1,1000,NULL);
    SendMessage(hWnd, WM_TIMER, 
10);
    
return 0;
  
case WM_TIMER: // 타이머 구분시 wParam, lParam 에 인자 담아 SendMessage
    GetLocalTime(&st);
    wsprintf  (sTime
      ,TEXT(
"지금 시간은 %d:%d:%d입니다")
      ,st.wHour
      ,st.wMinute
      ,st.wSecond);
    
//InvalidateRect(hWnd,NULL,TRUE);
    InvalidateRect(hWnd, &rt, TRUE);
    
return 0;
  
case WM_PAINT:
    hdc
=BeginPaint(hWnd,&ps);
    TextOut(hdc,
10,100,sTime,lstrlen(sTime));
    EndPaint(hWnd,
&ps);
    
return 0;
  
case WM_DESTROY:
    KillTimer(hWnd,
1);
    PostQuitMessage(
0);
    
return 0;
  }
  
return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}







4-3-다. 두 개의 타이머


//4 - 3 - 다.두 개의 타이머
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
  HDC hdc;
  PAINTSTRUCT ps;
  SYSTEMTIME st;
  
static TCHAR sTime[128];
  
static TCHAR sTime2[128];
  
static RECT rt = { 10100400400 };

  
switch (iMessage)
  {
  
case WM_CREATE:
    SetTimer(hWnd,
1,1000,NULL);
    SetTimer(hWnd, 
25000, NULL);    
    SendMessage(hWnd, WM_TIMER, 
10);
    
return 0;
  
case WM_TIMER: // 타이머 구분시 wParam, lParam 에 인자 담아 SendMessage
    switch (wParam)
    {
      
case 1:        
        GetLocalTime(
&st);
        wsprintf(sTime
          , TEXT(
"지금 시간은 %d:%d:%d입니다")
          , st.wHour
          , st.wMinute
          , st.wSecond);
        InvalidateRect(hWnd, 
&rt, TRUE);
        
break;
      
case 2:
        wsprintf(sTime2
          , TEXT(
"타이머 2"));
        
break;
    }
  
    
return 0;
  
case WM_PAINT:
    hdc
=BeginPaint(hWnd,&ps);
    TextOut(hdc,
10,100,sTime,lstrlen(sTime));
    TextOut(hdc, 
10200, sTime2, lstrlen(sTime2));
    EndPaint(hWnd,
&ps);
    
return 0;
  
case WM_DESTROY:
    KillTimer(hWnd,
1);
    KillTimer(hWnd, 
2);
    PostQuitMessage(
0);
    
return 0;
  }
  
return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}









4-3-라. 콜백 함수


 WM_TIMER 메시지는 다른 메시지가 있을 경우 실행 순서에 밀려 늦게 호출되는 경우가 있지만 콜백 함수를 사용하면 정확한 시간에 호출된다는 점




void CALLBACK TimerProc(HWND hWnd, UINT uMsg, UINT idEvent, DWORD dwTime)
{
  HDC hdc;
  
int i;
  hdc 
= GetDC(hWnd);
  
for (i = 0; i<100; i++)
    SetPixel(hdc, rand() % 
500, rand() % 400,
    RGB(rand() % 
256, rand() % 256, rand() % 256, ));
  ReleaseDC(hWnd, hdc);
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
  
switch (iMessage) {
  
case WM_CREATE:
    SetTimer(hWnd, 
1100, (TIMERPROC)TimerProc);
    
return 0;
  
case WM_DESTROY:
    KillTimer(hWnd, 
1);
    PostQuitMessage(
0);
    
return 0;
  }
  
return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}

=>WM_PAINT 메시지 없으므로 다시 그려지지 않음



4-4-가. 생성및 파괴

 WM_CREATE와 WM_DESTROY에 있던 코드를 그대로 WinMain으로 옮겼는데 실행시켜 보면 완전히 동일하게 동작할 것이다.

그런데 어쨋든 결과가 같기는 하지만 WinMain에서 하는 초기화와 종료 처리는 WM_CREATE, WM_DESTROY 메시지가 발생했을 때 하는 것과는 엄밀하게 따지면 다르다. 두 메시지는 특정한 윈도우에 관련된 초기/종료 처리를 하는데 사용하는 것이 좋고 WinMain에서는 프로그램 전역적인 초기/종료 처리를 하는 것이 좋다.




=4-4-나. 작업 영역

LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
  HDC hdc;
  PAINTSTRUCT ps;
  
static RECT rt;

  
switch (iMessage) {
  
case WM_CREATE:
    GetClientRect(hWnd, 
&rt);
    
return 0;
  
case WM_PAINT:
    hdc 
= BeginPaint(hWnd, &ps);
    
GetClientRect(hWnd, &rt);
    SetTextAlign(hdc, TA_CENTER);
    TextOut(hdc, rt.right / 
2, rt.bottom / 2"Center String"13);
    EndPaint(hWnd, 
&ps);
    
return 0;
  
case WM_DESTROY:
    PostQuitMessage(
0);
    
return 0;
  }
  
return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}


=4-4-다. WM_SIZE


플레그

SIZE_MAXHIDE

다른 윈도우가  최대화되어 이 윈도우가 가려졌다.

SIZE_MAXIMIZED

최대화되었다.

SIZE_MAXSHOW

다른 윈도우가 원래  크기로 복구되어 이 윈도우가 드러났다.

SIZE_MINIMIZED

최소화되었다.

SIZE_RESTORED

크기가 변경되었다.




LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
  HDC hdc;
  PAINTSTRUCT ps;
  
static RECT rt;

  
switch (iMessage) {
    
case WM_PAINT:
      hdc 
= BeginPaint(hWnd, &ps);
      
      SetTextAlign(hdc, TA_CENTER);
      TextOut(hdc, rt.right / 
2, rt.bottom / 2"Center String"13);
      EndPaint(hWnd, 
&ps);
      
return 0;
    
case WM_SIZE:
      
//GetClientRect(hWnd, &rt);    
      rt.right = LOWORD(lParam);
      rt.bottom 
= HIWORD(lParam);
      InvalidateRect(hWnd, NULL, TRUE);
      
return 0;
    
case WM_DESTROY:
      PostQuitMessage(
0);
      
return 0;
  }
  
return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}



=>창 크기 변화 시에도 화면 중앙에 글자 표시





5-1-가. 리소스의 분리

5-2-가. 리소스 작성






=&File => File





=세부사상은 Properties에서 수정








=헤더파일 수정 가능해야 함


=

#include "resource.h"

WndClass.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);

LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
  HDC hdc;
  PAINTSTRUCT ps;
  
static RECT rt;

  
switch (iMessage) 
  {
    
case WM_COMMAND:
      
switch (LOWORD(wParam))
      {
        
case ID_FILE_MENU1:
          MessageBox(hWnd, L"첫번째 메뉴를 선택했습니다.
", L"Menu Demo", MB_OK);
          
break;
        
case ID_FILE_MENU2:
          MessageBox(hWnd, L"두번째 메뉴를 선택했습니다.
", L"Menu Demo", MB_OK);
          
break;
        
case ID_FILE_EXIT:
          PostQuitMessage(
0);
          
break;
      }
      
return 0;
    
case WM_DESTROY:
      PostQuitMessage(
0);
      
return 0;
    
default:
      
return(DefWindowProc(hWnd, iMessage, wParam, lParam));
  }  
}







=5-3 아이콘, 커서




728x90