2015.03.15 15:02


※ WM_SYSCOMMAND → WM_CLOSE → WM_DESTROY → WM_QUIT


1. WM_CLOSE
   - 윈도우가 닫히기 전에 메시지가 전달 된다.
   - 아직 윈도우가 파괴된 것은 아니므로 윈도우가 파괴되는 것을 중간에 제어 할 수 있다.
   - 윈도우의 “닫기” 를 누르거나, 키보드의 “Alt + F4”를 눌렀을 경우 발생




   - WM_CLOSE 의 핸들러(OnClose) 에서 추가적인 제어를 하지 않는다면 메시지는
      DefWindowsProc 로 보내진다.
   - CDialog::OnClose() 는 내부적으로 DestroyWindow() 함수를 호출 한다.
   - DestroyWindow() 함수는 내부적으로 WM_DESTROY 메시지를 발생 시킨다.


2. DestroyWindow()
   - CWnd내부에 있는 윈도우를 destroy 한다. 
   - 윈도우를 해제하고 입력 포커스를 제거하기 위한 적절한 message를 윈도에게 보낸다. 
   - 윈도우의 메뉴 제거  
   - application queue를 비운다.
   - timer를 제거 
   - Clipboard의 소유주 제거
   - Clipboard-viewer chain을 끊는다. ( CWnd가 viewer chain의 맨 위에 있을 경우 ) 
   - WM_DESTROY(OnDestroy)와 WM_NCDESTROY(OnNcDestroy) 메시지를 윈도우 에게 보낸다.
     하지만 아직 CWnd 객체는 destroy하지 않는다.


3. WM_DESTROY
   - Framework이 CWnd에게 현재 CWnd가 소멸되고 있는 중이라고 알려 주기 위하여 호출 
   - 화면에 윈도우를 숨긴 후 메시지 발생, 아직 윈도우 자체는 파괴되지 않았다
   - DestroyWindows() 함수에서 발생 시킨다.
   - WM_CREATE 에 반대되는 동작을 수행 한다.
   - 차일드 윈도우가 있다면 이 메시지를 차례대로 전달 한다.
   - 메인 윈도우에서 PostQuitMessage() 함수를 반드시 호출하여 프로세스의 메시지 루프
     를 종료시켜야 한다. 그렇지 않다면 윈도우만 파괴되고 메시지 루프는 계속 실행중인
     상태가 되므로 프로세스가 종료되지 않는다.


4. WM_NCDESTROY
   - Client 영역이 아닌 영역이 Destroy 될 때 Framework 에 의하여 불려짐.
   - 윈도우가 소멸될 때 마지막으로 호출되는 메시지
   - 핸들러를 재정의 한다면 기본 호출 함수를 가장 위에서 해주자.

   
5. PostNcDestroy()
   - 윈도우가 소멸된 후 OnNcDestroy() 함수에 의해 불려지는 함수
   - 사용자들이 상속받아 만든 클래스의 정리를 위한 코드를 넣음.


6. View가 닫혀질 때 호출되는 핸들러 순서
BOOL CAniView::DestroyWindow() 

  
// TODO: Add your specialized code here and/or call the base class 
// 윈도우가 안보여 지기전에 해야 할 작업 처리
  
 return CView::DestroyWindow(); 
  

  
void CAniView::OnDestroy() 

  
  CView::OnDestroy(); 
  
  // TODO: Add your message handler code here 
  

  
void CAniView::PostNcDestroy() 

  
  // TODO: Add your specialized code here and/or call the base class 
  
  CView::PostNcDestroy(); 
  
}


7. WM_QUIT
   - 응용프로그램을 종료 하라는 메시지
   - PostQuitMessage() 가 발생 시키는 메시지
   - GetMessage() 함수가 0 을 리턴하도록 함으로써 메시지 루프를 종료
   - PeekMessage() 함수는 따로 WM_QUIT 메시지를 점검해야 한다.





다음과 같이 종료 시킨다.


HWND hWndBuilder;

hWndBuilder = ::FindWindow( NULL, "NxBuilder" );

1번 : if(hWndBuilder!=NULL) ::PostMessage(hWnd,WM_CLOSE,0,0);  --> 정상종료시

2번 : if(hWndBuilder!=NULL) ::PostMessage(hWnd,WM_DESTROY,0,0);  --> 마찬가지

3번 : if(hWndBuilder!=NULL) ::PostMessage(hWnd,WM_QUIT,0,0); --> 강제종료





신고


Posted by injunech
2013.07.27 03:39





prjCapture.exe

#define WINVER 0x0500 
#include <windows.h> 

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM); 
HINSTANCE g_hInst; 
HWND hWndMain; 
LPCTSTR lpszClass=TEXT("Capture"); 

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance ,LPSTR lpszCmdParam,int nCmdShow) { 
    HWND hWnd; 
    MSG Message; 
    WNDCLASS WndClass; 
    g_hInst=hInstance; 

    WndClass.cbClsExtra=0; 
    WndClass.cbWndExtra=0; 
    WndClass.hbrBackground=(HBRUSH)(COLOR_WINDOW+1); 
    WndClass.hCursor=LoadCursor(NULL,IDC_ARROW); 
    WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION); 
    WndClass.hInstance=hInstance; 
    WndClass.lpfnWndProc=WndProc; 
    WndClass.lpszClassName=lpszClass; 
    WndClass.lpszMenuName=NULL; 
    WndClass.style=CS_HREDRAW | CS_VREDRAW; 
    RegisterClass(&WndClass); 

    hWnd=CreateWindow(lpszClass,lpszClass,WS_OVERLAPPEDWINDOW, 
        CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT, 
        NULL,(HMENU)NULL,hInstance,NULL); 
    ShowWindow(hWnd,nCmdShow); 

    while (GetMessage(&Message,NULL,0,0)) { 
        TranslateMessage(&Message); 
        DispatchMessage(&Message); 
    } 
    return (int)Message.wParam;
} 

int y; 
BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) {
    TCHAR sInfo[256]; 
    MONITORINFOEX mi; 

    mi.cbSize = sizeof(MONITORINFOEX); 
    GetMonitorInfo(hMonitor, &mi); 
    wsprintf(sInfo, TEXT("모니터 핸들 = %x, 좌표=(%d,%d)-(%d,%d) %s"), hMonitor, lprcMonitor->left, lprcMonitor->top, lprcMonitor->right, lprcMonitor->bottom, (mi.dwFlags & MONITORINFOF_PRIMARY)==0 ? TEXT(""):TEXT(":주 모니터")); 

TextOut((HDC) dwData, 10, y, sInfo, lstrlen(sInfo)); y+=20; return TRUE; } LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; TCHAR Mes[256]; int cMon; RECT rcVirt; switch (iMessage) { case WM_CREATE: hWndMain=hWnd; return 0; case WM_DISPLAYCHANGE: InvalidateRect(hWnd, NULL, TRUE); UpdateWindow(hWnd); return 0; case WM_PAINT: hdc=BeginPaint(hWnd, &ps); cMon = GetSystemMetrics(SM_CMONITORS); if (cMon == 0) { // Win 95/NT 에서는 다중 모니터를 지원하지 않아 0으로 Return한다. lstrcpy(Mes, TEXT("다중 모니터를 지원하지 않는 시스템입니다.")); TextOut(hdc, 10, 10, Mes, lstrlen(Mes)); } else { // 모니터 갯수와 색상 포멧이 모두 동일한지 출력한다. wsprintf(Mes, TEXT("모니터 개수 = %d, 색상 포멧=%s"), cMon, GetSystemMetrics(SM_SAMEDISPLAYFORMAT) ? TEXT("모두 동일"):TEXT("다름")); TextOut(hdc, 10, 10, Mes, lstrlen(Mes)); // 가상 모니터의 좌표를 출력한다. rcVirt.left = GetSystemMetrics(SM_XVIRTUALSCREEN); rcVirt.top = GetSystemMetrics(SM_YVIRTUALSCREEN); rcVirt.right = GetSystemMetrics(SM_CXVIRTUALSCREEN); rcVirt.bottom = GetSystemMetrics(SM_CYVIRTUALSCREEN); wsprintf(Mes, TEXT("가상 화면=(%d,%d)-(%d,%d)"), rcVirt.left, rcVirt.top, rcVirt.right, rcVirt.bottom); TextOut(hdc, 10, 30, Mes, lstrlen(Mes)); // 다중 모니터에 대한 정보를 출력한다. y = 50; EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, (LPARAM) hdc); } EndPaint(hWnd, &ps); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return(DefWindowProc(hWnd,iMessage,wParam,lParam)); }

신고


Posted by injunech
2013.07.22 17:00


StretchBlt 함수


이미지의 크기를 조절하여 화면에 출력해주는 함수입니다.


BitBlt 함수에서 불가능한 이미지 크기를 조절해서 출력할 수 있습니다.


이미지 크기를 조절할 때 생가는 색상의 손실을 SetStretchBltMode 함수를 사용하여 보정하는 것이 좋습니다.


이 함수를 쓰기 전에 먼저 비트맵 파일을 LoadImage 함수나 다른 방법을 이용하여 불러와야 합니다.




함수 원형


BOOL StretchBlt(

    HDC hdcDest,

    int nXOriginDest,

    int nYOriginDest,

    int nWidthDest,

    int nHeightDest,

    HDC hdcSrc,

    int nXOriginSrc,

    int nYOriginSrc,

    int nWidthSrc,

    int nHeightSrc,

    DWORD dwRop);




인수


hdcDest

이미지를 출력할 위치의 핸들입니다.


nXOriginDest, nYOriginDest

이미지를 출력할 위치인 x, y 좌표입니다.


nWidthDest, nHeightDest

출력할 이미지의 너비, 높이입니다.

이 크기만큼 hdcSrc로부터 받은 이미지를 이 너비와 높이에 맞게 이미지 크기를 변경합니다.


hdcSrc

이미지의 핸들입니다.


nXOriginSrc, nYOriginSrc

가져올 이미지의 시작지점인 x, y좌표입니다.

지정한 위치부터 nWidthSrcnHeightSrc만큼 이미지를 잘라옵니다.


nWidthSrc, nHeightSrc

원본 이미지로부터 해당 크기만큼 잘라낼 이미지의 너비, 높이입니다.

이 크기만큼 원본 이미지에서 잘라내어 nWidthDestnHeightDest의 크기에 맞게 이미지 크기를 변경합니다.


dwRop

이미지의 출력 방법입니다.


 값

 설명

 BLACKNESS

 이미지를 원본의 색이 아닌 검은색으로 채웁니다.

 DSTINVERT

 지정된 이미지와는 상관없이 화면의 색상을 반전시킵니다.

 MERGECOPY

 이미지의 색상과 현재 선택된 브러시를 AND 연산자를 사용하여 병합합니다.

 MERGEPAINT

 반전된 이미지와 화면의 색을 OR 연산자를 사용하여 병합합니다.

 NOMIRRORBITMAP

 Prevents the bitmap from being mirrored.

 NOTSRCCOPY

 이미지의 색상을 반전시킵니다.

 NOTSRCERASE

 화면과 이미지를 OR 연산자를 사용하여 합친 다음 색상을 반전시킵니다.

 PATCOPY

 현재 선택된 브러시를 출력합니다.

 PATINVERT

 현재 선택된 브러시 색과 화면을 XOR 연산자를 사용하여 결합합니다.

 PATPAINT

 현재 선택된 브러시 색과 반전된 원본 이미지를 OR 연산자를 사용하여 결합합니다.

 그다음 OR 연산자를 사용하여 화면과 결합합니다.

 SRCAND

 화면과 이미지를 AND 연산자를 사용하여 결합합니다.

 SRCCOPY

 원본 이미지를 출력합니다.

 SRCERASE

 반전된 화면과 이미지를 AND 연산자를 사용하여 결합합니다.

 SRCINVERT

 화면과 이미지를 XOR 연산자를 사용하여 결합합니다.

 SRCPAINT

 화면과 이미지를 OR 연산자를 사용하여 결합합니다.

 WHITENESS

 이미지를 원본의 색이 아닌 하얀색으로 채웁니다.




요구 사항


 운영체제

 Windows 2000 이상

 헤더

 Wingdi.h (include Windows.h)

 라이브러리

 Gdi32.lib

 DLL

 Gdi32.dll




예제


이 예제는 WinMain의 기본 구성에서 WndProc 부분에 그대로 복사하시면 됩니다.


난잡해서 이해가 잘 안가신다면 첨부파일을 참고해주세요.


//---------------------------------------------------------//

// 프로그램의 실질적이고 고유한 처리를 하는 곳

//---------------------------------------------------------//

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

{

    HDC hdc;

    PAINTSTRUCT ps;

    HDC hMemDC;

     HBITMAP hImage, hOldBitmap;

    int bx, by;

    BITMAP bit;

    LPCWSTR str;


    switch (iMessage)

    {

    case WM_PAINT:

        hdc = BeginPaint(hWnd, &ps);

        hMemDC = CreateCompatibleDC(hdc); // 메모리 DC를 만든다


        // 비트맵 속성으로 파일을 불러오고 HBITMAP으로 형변환해서 hImage에 저장한다

        // fuLoad 속성: 리소스 대신 파일명으로, 호환 비트맵이 아닌 DIB 섹션 비트맵으로 불러온다

        hImage = (HBITMAP) LoadImage(NULL, TEXT("image.bmp"),

             IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);


        // hImage가 선택되기 전의 핸들을 저장해 둔다

        hOldBitmap = (HBITMAP) SelectObject(hMemDC, hImage);


        // 비트맵 정보를 알아낸다

        GetObject(hImage, sizeof(BITMAP), &bit);

        bx = bit.bmWidth;

        by = bit.bmHeight;


        // 원본

        str = TEXT("원본");

        TextOut(hdc, 50, 30, str, lstrlen(str));


        BitBlt(hdc, 50, 50, bx, by, hMemDC, 0, 0, SRCCOPY);


        // 1.5

        str = TEXT("1.5");

        TextOut(hdc, 450, 30, str, lstrlen(str));


        StretchBlt(hdc, 450, 50, bx * 1.5, by * 1.5, hMemDC, 0, 0, bx, by, SRCCOPY);


        // 1.5배 / 0.5배 설명

        str = TEXT("1.5/ 0.5");

        TextOut(hdc, 50, 360, str, lstrlen(str));


        // BLACKONWHITE(기본 설정)

        str = TEXT("BLACKONWHITE(기본 설정)");

        TextOut(hdc, 50, 380, str, lstrlen(str));


        SetStretchBltMode(hdc, BLACKONWHITE);

        StretchBlt(hdc, 50, 400, 100, 100, hMemDC, 120, 70, 70, 70, SRCCOPY); // 부분 확대

        StretchBlt(hdc, 155, 400, bx * 0.5, by * 0.5, hMemDC, 0, 0, bx, by, SRCCOPY); // 축소


        // COLORONCOLOR

        str = TEXT("COLORONCOLOR");

        TextOut(hdc, 450, 380, str, lstrlen(str));


        SetStretchBltMode(hdc, COLORONCOLOR);

        StretchBlt(hdc, 450, 400, 100, 100, hMemDC, 120, 70, 70, 70, SRCCOPY);

        StretchBlt(hdc, 555, 400, bx * 0.5, by * 0.5, hMemDC, 0, 0, bx, by, SRCCOPY);


        // HALFTONE

        str = TEXT("HALFTONE");

        TextOut(hdc, 50, 530, str, lstrlen(str));


        SetStretchBltMode(hdc, HALFTONE);

        StretchBlt(hdc, 50, 550, 100, 100, hMemDC, 120, 70, 70, 70, SRCCOPY);

        StretchBlt(hdc, 155, 550, bx * 0.5, by * 0.5, hMemDC, 0, 0, bx, by, SRCCOPY);


        // WHITEONBLACK

        str = TEXT("WHITEONBLACK");

        TextOut(hdc, 450, 530, str, lstrlen(str));


        SetStretchBltMode(hdc, WHITEONBLACK);

        StretchBlt(hdc, 450, 550, 100, 100, hMemDC, 120, 70, 70, 70, SRCCOPY);

        StretchBlt(hdc, 555, 550, bx * 0.5, by * 0.5, hMemDC, 0, 0, bx, by, SRCCOPY);


        SelectObject(hMemDC, hOldBitmap); // hImage 선택을 해제하기 위해 hOldBitmap을 선택한다

        DeleteObject(hImage); // 선택 해제된 비트맵을 제거한다

        DeleteDC(hMemDC); // 메모리 DC를 제거한다

        EndPaint(hWnd, &ps);

        return 0;


    case WM_DESTROY:

        PostQuitMessage(0);

        return 0;

    }

    // WinProc에서 처리하지 않는 나머지 메시지를 윈도우 기본으로 처리하도록 전달

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

}




결과


* 이미지를 클릭해서 원본으로 보세요.





출처: http://msdn.microsoft.com/en-us/library/windows/desktop/dd145120(v=vs.85).aspx

신고


Posted by injunech