[MFC] Dialog 닫기 (OnOK/EndDialog)

Programming/MFC 2017. 2. 8. 16:54 Posted by TanSanC
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

[MFC] Dialog 닫기 (OnOK/EndDialog)


 
1. OnOK()
 
2. OnClose()
 
3. EndDialog()
 
4. DestoryWindow()


CDialog::OnOK

Override this method to perform actions when the OK button is activated. If the dialog box includes automatic data validation and exchange, the default implementation of this method validates the dialog box data and updates the appropriate variables in your application.

If you implement the OK button in a modeless dialog box, you must override the OnOK method and call DestroyWindow inside it. Do not call the base-class method, because it calls EndDialog which makes the dialog box invisible but does not destroy it.

CDialog::EndDialog

Call this member function to terminate a modal dialog box.



virtual void CDialog::OnOk();
호출 : 사용자가 OK버튼을 누르면 호출된다. (id값이 IDOK인 버튼)
        즉, OnOk()함수는 OK버튼클릭 메시지 핸들러라고 할 수 있다.
사용 : 컨트롤 값을 읽거나 값의 타당성을 검사한 후 Dialog 닫기





다이얼로그를 닫을때 OnOK 로 닫는것 [확인(OK)] 버튼을 눌러서 닫는 것



EndDialog 는 다이얼로그를 강제로 중지시킨다.








MFC Dialog Position Save & Load

Programming/MFC 2016. 11. 10. 11:45 Posted by TanSanC
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

MFC Dialog Position Save & Load


참조 : http://www.codeproject.com/Articles/1154/Saving-a-windows-size-position-and-state-in-MFC


Saving the window placement








BOOL CMainFrame::DestroyWindow() 
{
    WINDOWPLACEMENT wp;
    GetWindowPlacement(&wp);
    AfxGetApp()->WriteProfileBinary("MainFrame", "WP", (LPBYTE)&wp, sizeof(wp));

    return CMDIFrameWnd::DestroyWindow();
}






Restoring the window placement









void CMainFrame::OnShowWindow(BOOL bShow, UINT nStatus) 
{
    CMDIFrameWnd::OnShowWindow(bShow, nStatus);

    static bool bOnce = true;

    if(bShow && !IsWindowVisible()
        && bOnce)
    {
        bOnce = false;

        WINDOWPLACEMENT *lwp;
        UINT nl;

        if(AfxGetApp()->GetProfileBinary("MainFrame", "WP", (LPBYTE*)&lwp, &nl))
        {
            SetWindowPlacement(lwp);
            delete [] lwp;
        }
    }
}







'Programming > MFC' 카테고리의 다른 글

[MFC] Dialog 닫기 (OnOK/EndDialog)  (0) 2017.02.08
CWnd::Invalidate  (0) 2016.11.15
MFC - 다이얼로그 생성시 발생되는 메세지들...  (0) 2016.11.07
MFC x64 ADO msado15.dll  (0) 2016.10.28
x64 ADO import  (0) 2016.10.28
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

출처 : http://namacin.egloos.com/1368314



MFC - 다이얼로그 생성시 발생되는 메세지들...

다이얼로그가 생성될 때 발생되는 메세지의 순서로는

DoModal()
PreSubclassWindow()
OnNcCreate()
OnNcCalcSize()
OnCreate()
OnSize()
OnMove()
OnSetFont()
OnInitDialog()
OnWindowPosChanging()
OnMove()
OnWindowPosChanged()
OnWindowPosChanging()
OnNcActivate()
OnActivate()
OnShowWindow()
OnWindowPosChanging()
OnNcPaint()
OnEraseBkgnd()
OnChildNotify()
OnCtlColor()
OnWindowPosChanged()
OnPaint()
OnCtlColor()
OnCtlColor()
OnNcHitTest()
OnSetCursor()
PreTranslateMessage()
OnMouseMove()
OnNcHitTest()
OnSetCursor()
PreTranslateMessage()


클래스 위자드에서 메세지 필터를 Window로 주고 발생하는 모든 메세지에 대해서
간단한 문자 출력용 핸들러를 주었다.

이 상황에서 아무것도 없는 기본 다이얼로그 화면을 DoModal() 함수로 띄웠을 때 
발생하는 메세지들을 캡쳐한것이다.

어떠한 핸들러들은 afx_msg 함수로 메세지 맵에 등록되고 어떠한 함수들은
vitual로 선언되며 메세지 맵에 등록되지 않았다. 이렇게 구분되는 기준은 무얼까?


%%
메세지 맵에 등록되는 함수(핸들러) 들은 정말 윈도가 뿌려대는 메세지에 대한
핸들러이고 virtual로 선언되는 함수들은 메세지에 대한 핸들러가 아니라
프로세스가 진행되면서 당연히 호출되는 함수들이 아닐까 생각된다.

 

어떠한 핸들러들은 publc으로, 어떠한 핸들러들은 protected로 선언된다.
(메세지 맵에 등록된 핸들러들은 모두 protected이다.)

중요한지 아닌지는 모르겠지만 차근차근 알아봐야할 내용들..

 


[메세지에 대한 설명은 www.winapi.co.kr 에서 발췌]

DoModal - 
PreSubclassWindow -

WM_NCCREATE - 
WM_NCCALCSIZE - 
WM_CREATE - 
WM_SIZE - 
WM_MOVE - 
WM_SETFONT - 
WM_ONINITDIALOG - 
 다이얼로그가 메모리에 만들어지고 화면에 보이기 적전에 보내진다고 한다.
 오버랩드 윈도우의 WM_CREATE에 해당한다는데...
 
WM_WINDOWPOSCHANGING - 
WM_MOVE - 
WM_WINDOWPOSCHANGED - 
WM_WINDOWPOSCHANGING - 
WM_NCACTIVATE - 
 비 작업영역(client영역을 제외한 영역을 말하는것이 아닐까..)에 대한 활성 
 또는 비 활성화시 변경되는 내용이 있을 때 보내진다고 한다.
 
WM_ACTIVATE - 
 WM_NCACTIVATE가 비 작업 영역에 대한 메세지라면 이 메세지는 작업영역에 대한
 처리를 위한 메세지..

WM_SHOWWINDOW - 
 윈도우의 보임 상태가 변경되기 직전에 보내진다고 한다. WS_VISIBLE 스타일을 가진 윈도우가
 생성될 때도 보내진다고 한다.
 
WM_WINDOWPOSCHANGING - 
WM_NCPAINT - 
 비 작업 영역을 그려야 할 때 발생한다고 한다
 
WM_ERASEBKGND - 
 윈도우 크기가 변경 되었거나 다른 윈도우에 가려진 부분이 드러났다거나 할 때 배경을 지우기 위해
 이 메셎가 보내진다고 함. WM_PAINT에서 출력하기 전에 먼저 그려진 내용을 지워야 하는데 이 메세지에
 대해 처리를 하지 않으면 "윈도 클래스에 등록된!!" 디폴트 배경 브러시로 지운다고함.
  
 %% 윈도 클래스 배경 브러시가 NULL 일경우 아무것도 하지 않음.
 
WM_CHILDNOTIFY - 
WM_WINDOWPOSCHANGING - 
WM_PAINT - 
 1. 윈도우가 처음 생성되었을 때
 2. 윈도우의 위치가 이동되었을 때
 3. 윈도우의 크기가 변경, 최소, 최대화 되었을 때
 4. 다른 윈도우에 가려져 있다가 드러날 때
 5. 스크롤 될 때
 발생한다고 한다.
 
WM_CTLCOLOR - 
 윈도우가 그려질 필요가 있을 때 발생되어 브러시의 색상을 지정하게 된다.
 
WM_CTLCOLOR - 
WM_NCHITTEST - 
 마우스를 이동하거나 버튼을 누르거나 놓을 때마다 발생. 커서가 있는 위치가 윈도우의 어디쯤인지를
 윈도우에게 질문을 하며 운영체제닌 이 메세지의 리턴값에 따라 마우스를 처리한다고 한다
 
WM_SETCURSOR -

PreTranslateMessage -

뒤로

WM_MOUSEMOVE
WM_NCHITTEST
WM_SETCURSOR

의 메세지가 연속적으로 나오는데 이 메세지는 다이얼로그 생성과는 관계가 없는듯..
또, 각 메세지들의 중간중간에 WindowProc, DefWindowProc, WM_CTLCOLOR, PreTranslateMessage
메세지가 매우 자주 섞여 나왔다.


'Programming > MFC' 카테고리의 다른 글

CWnd::Invalidate  (0) 2016.11.15
MFC Dialog Position Save & Load  (0) 2016.11.10
MFC x64 ADO msado15.dll  (0) 2016.10.28
x64 ADO import  (0) 2016.10.28
MSSQL 테이블명, 컬럼명 검색  (0) 2016.10.27
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

MFCGridCtrl CGridCtrl ScrollBar Visible






If you change Dialog color used by OnEraseBkgnd();



you can't see CGridCtrl's ScrollBar











in that case, you should add m_Grid.SetRedraw(true, true); to OnEraseBkgnd();











BOOL CMyDialog::OnEraseBkgnd(CDC* pDC)
{
	// TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.

	CRect rect;

	GetClientRect(&rect);

	CBrush myBrush(RGB(255, 255, 255));    // dialog background color <- 요기 바꾸면 됨.
	
	CBrush *pOld = pDC->SelectObject(&myBrush);

	BOOL bRes = pDC->PatBlt(0, 0, rect.Width(), rect.Height(), PATCOPY);

	pDC->SelectObject(pOld);    // restore old brush

	m_Grid.SetRedraw(true, true);

	return bRes;                       // 	return CDialog::OnEraseBkgnd(pDC);
}


MFC Control Color Change

Programming/MFC 2016. 10. 19. 17:20 Posted by TanSanC
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

MFC Control Color Change






afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);


 

 

      CBrush m_combo_brush;

      m_combo_brush.CreateSolidBrush(RGB(0, 0, 255)); // Brush 속성을 생성한다.





HBRUSH MyDialog::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)

{

      HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);

 

      // TODO:  여기서 DC의 특성을 변경합니다.

 

      switch (nCtlColor) {

           

      case CTLCOLOR_STATIC:

            pDC->SetTextColor(RGB(255, 0, 0));

            pDC->SetBkColor(RGB(0, 0, 0));

            return (HBRUSH)(m_combo_brush);

      case CTLCOLOR_LISTBOX:

            pDC->SetTextColor(RGB(0, 255, 0));

            pDC->SetBkColor(RGB(0, 0, 0));

            return (HBRUSH)(m_combo_brush);

      default:

            break;

      }

      if (pWnd->m_hWnd == GetDlgItem(IDC_SERVERLIST_COMBO)->m_hWnd)

            hbr = HBRUSH(m_combo_brush);

 

      // TODO:  기본값이 적당하지 않으면 다른 브러시를 반환합니다.

      return hbr;

}

 




pDC

자식 창에 대 한 디스플레이 컨텍스트를 포인터를 포함합니다. 일시적일 수 있습니다.

pWnd

컨트롤의 색을 요청에 대 한 포인터를 포함 합니다. 일시적일 수 있습니다.

nCtlColor

컨트롤의 형식을 지정 하는 다음 값 중 하나가 포함 됩니다.

  • CTLCOLOR_BTN 단추 컨트롤

  • CTLCOLOR_DLG 대화 상자

  • CTLCOLOR_EDIT 편집 컨트롤

  • CTLCOLOR_LISTBOX 목록 상자 컨트롤

  • CTLCOLOR_MSGBOX 메시지 상자

  • CTLCOLOR_SCROLLBAR 스크롤 막대 컨트롤

  • CTLCOLOR_STATIC 정적 컨트롤



'Programming > MFC' 카테고리의 다른 글

MFC CWnd Control Border Color Change  (0) 2016.10.20
MFC CheckBox 컨트롤의 현재 상태  (0) 2016.10.19
MFC Bitmap Button  (0) 2016.10.18
MFC Tab Control Color Change #2  (0) 2016.10.18
MFC Tab Control Color Change #1  (1) 2016.10.18

MFC Dialog Modal

Programming/MFC 2016. 9. 22. 16:48 Posted by TanSanC
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

부모 Dialog 에서





자식 Dialog를 Domodal로 부른 뒤


  void CMyDialog::OnMenuShowSimpleModal()
{
   CSimpleDlg myDlg;
   INT_PTR nRet = myDlg.DoModal();

   if (nRet == IDOK || nRet == 5)
      AfxMessageBox(_T("Dialog closed successfully"));
}



자식 Dialog가 종료 될때




  void CSimpleDlg::OnRButtonUp(UINT nFlags, CPoint point)
{
   UNREFERENCED_PARAMETER(nFlags);
   // Do something

   int nRet = point.x; // Just any value would do!
   EndDialog(nRet); // This value is returned by DoModal!

   // Do something

   return; // Dialog closed and DoModal returns only here!
}


MFC Modal and Modeless Dialog Boxes

Programming/MFC 2016. 9. 6. 10:56 Posted by TanSanC
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

Modal and Modeless Dialog Boxes




You can use class CDialog to manage two kinds of dialog boxes:

  • Modal dialog boxes, which require the user to respond before continuing the program

  • Modeless dialog boxes, which stay on the screen and are available for use at any time but permit other user activities

The resource editing and procedures for creating a dialog template are the same for modal and modeless dialog boxes.

Creating a dialog box for your program requires the following steps:

  1. Use the dialog editor to design the dialog box and create its dialog-template resource.

  2. Create a dialog class.

  3. Connect the dialog resource's controls to message handlers in the dialog class.

  4. Add data members associated with the dialog box's controls and to specify dialog data exchange and dialog data validations for the controls.




생성되는 윈도우는 두가지 형태가 있다.
대화가 필요한 모달형과, 대화가 필요없는 모달리스

대화가 필요한 모달형은 대화를 마치지 않으면 다음으로 넘어갈 수 없는 윈도우다.
즉, 파일열기를 해서 파일목록이 나오고 파일을 선택하는 윈도우가 팝업되었을 때, 
그 윈도우창을 무시하고 그 전의 윈도우를 컨트롤 할 수 없도록 되어있다. (취소를 하시든가)
무조건 적으로 대화가 필요한 모달형에 비해,
대화가 필요없는 모달리스형이 있다.
모달리스형은 익스플로러를 하면서 Ctrl F키를 눌러서 찾기 기능을 사용할 때, 개념을 찾을 수 있는데, 
찾기 윈도우가 팝업되었지만, 기존의 익스플로러 윈도우에도 편하게 접근이 가능하다.
대화따위... 존재하지 않은지가 오랜지...


Modal Dialog

써먹을려면 CDialog 클래스의 일부함수를 재정의 해야 하는데, 
이렇게 가상함수들을 재정의할 때, 함수의 호출 시점을 꿰고있는게 좋을 것이다.

대화상자 객체를 주로 스택에 생성한다.

virtual BOOL CDialog::OnInitDialog();
호출 : CDialog::DoModal() 함수에 의해서 대화상자가 생성되고 WM_CREATE메시지가 발생하게 된다.
        OS는 이 메시지를 받고, Dialog 템플릿에 선언된 컨트롤을 모두 생성한 후 대화상자가 화면에 보이기전에
        WM_INITDIALOG 메시지를 발생시키는데, 이 때 OnInitDialog()함수가 호출된다.
        즉, OnInitDialog()함수는 WM_INITDIALOG메시지 핸들러라고 할 수 있다.
사용 : 컨트롤 초기화 및, 키보드 포커스 변경시 사용

virtual void CDialog::OnOk();
호출 : 사용자가 OK버튼을 누르면 호출된다. (id값이 IDOK인 버튼)
        즉, OnOk()함수는 OK버튼클릭 메시지 핸들러라고 할 수 있다.
사용 : 컨트롤 값을 읽거나 값의 타당성을 검사한 후 Dialog 닫기

virtual void CDialog::OnCancel();
호출 : 사용자가 Cancel버튼을 누르면 호출된다. (id값이 IDCANCEL인 버튼)
        즉, OnCancel()함수는 Cancel버튼클릭 메시지 핸들러라고 할 수 있다.
사용 : 대화상자 닫기.

위의 3가지 함수는 메시지핸들러의 기능을 하지만, 가상함수로 정의되어 있으므로 
굳이 메시지 맵이 필요없이 자동 호출된다.

생성은 CDialog::DoModal(), 닫을때는 CDialog::EndDialog()
OnOk()나 OnCancel()함수는 자동으로 EndDialog() 호출하므로,
만약 다른 방법으로 대화상자를 닫기 원할 때, CDialog::EndDialog() 호출하면 된다.



Modeless Dialog

주의사항. 모달형과 생성 및 닫는 함수가 다르다.
DoModal()대신 CDialog::Create()
EndDialog()대신 CWnd::DestroyWindow() 함수를 사용한다.
대화상자 객체를 힙에 생성한다.
(스택에 객체를 생성해버리면 변수선언영역을 벗어났을때 소멸자가 호출되어 대화상자가 소멸되므로
대화상자를 계속 유지할 수 없기 때문이다.)





'Programming > MFC' 카테고리의 다른 글

공유 DLL에서 MFC 사용 VS 정적 라이브러리에서 MFC 사용  (0) 2016.10.06
MFC Dialog Modal  (0) 2016.09.22
MFC Alert MessageBox2  (0) 2016.09.06
MFC Alert MessageBox  (0) 2016.09.06
MFC Drag And Drop FileName 만 추출  (0) 2016.08.30
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

MFC Dialog 가 이상한 위치에 배치, (0,0)에 배치



MFC TabCtrl 기반의 Dialog 를 Child로 배치 하였을때






Tab 별 Child Dialog 가 (0,0) 위치에 배치되어


TabCtrl 이 보이지 않는 경우가 발생하는 경우,













Child Dialog 가 OnInitDialog 실행 중 예외처리나 비정상 처리로 인해


제대로 된 값을 반환하지 못하는 경우


그런 상태가 발생 할 수 있다.





예외처리 시 return 으로


OnInitDialog 를 정상적으로 종료시킨 후 


동작시켜야 한다.










336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

MFC Dialog 에 OnInitDialog 추가하기





CDialog::OnInitDialog

이 메서드를 호출 하에서 여 WM_INITDIALOG 메시지.

virtual BOOL OnInitDialog( );

Windows를 보냅니다는 WM_INITDIALOG 중 대화 상자에 메시지를 만들기CreateIndirect, 또는 DoModal 대화 상자를 바로 표시 되기 전에 발생 하는 호출을.

대화 상자 초기화 될 때 특수 처리를 수행 하려는 경우이 메서드를 재정의 합니다. 재정의 된 버전에서 먼저 기본 클래스를 호출OnInitDialog 하지만 반환 값을 무시 합니다. 일반적으로 반환 합니다 TRUE 에서 메서드를 재정의 합니다.

Windows 호출을 OnInitDialog 일반 표준 글로벌 대화 상자 프로시저 모든 Mfc 라이브러리 대화 상자를 사용 하 여 함수. 사용자 메시지 맵을 통해이 함수를 호출 하 고이 메서드에 대 한 메시지 맵 엔트리는 필요 하지 않습니다 따라서.



Dialog 의 리소스뷰에서 OnInitDialog 를 추가 하려고 하면


메시지와 컨트롤 이벤트에서는 보이지 않는다.



불가능 한것이 아니고 다른 위치에서 하여야한다.




클래스 뷰에서


해당 다이얼로그의 클래스 함수를 선택 후


속성창을 보면


[재정의] 버튼이 있다.




재정의 화면 안에


OnInitDialog 가 존재한다.





MFC 4대 Class간 참조

Programming/MFC 2016. 7. 25. 08:55 Posted by TanSanC
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

 

4 Class간 참조

//각각 헤더파일 include

 









#include "MainFrm.h" //메인프레임 헤더파일

 

#include "ClassDoc.h"   //Doc클래스 헤더파일

 

#include "ClassView.h" //View include 할때는 반드시 Doc 헤더파일이 위에있어야한다

 

#include "Class.h" //APP Class 의 헤더파일

 

 









void CClassView::OnMenuView() //뷰클래스

 

CClassApp *pApp = (CClassApp *)AfxGetApp();   //View -> App

CMainFrame *pMain = (CMainFrame *)AfxGetMainWnd();  //View -> MainFrm

 

//View -> MainFrm -> Doc

 

CClassDoc *pDoc = (CClassDoc *)pMain->GetActiveDocument();

 

CClassDoc *pDoc = (CClassDoc *)GetDocument();         //View -> Doc

 

 









//MainFrame 클래스

 

CClassView *pView = (CClassView *)GetActiveView();  //MainFrm -> View

 

CClassDoc *pDoc = (CClassDoc *)GetActiveDocument();  //MainFrm -> Doc

 

CClassApp *pApp = (CClassApp *)AfxGetApp(); //MainFrm -> App

 

 









//Doc 클래스

 

CClassApp *pApp = (CClassApp *)AfxGetApp(); //Doc -> App

 

CMainFrame *pMain = (CMainFrame *)AfxGetMainWnd(); //Doc -> MainFrm

 

// Doc -> MainFrm -> View

 

CClassView *pView = (CClassView *)pMain->GetActiveView();

 

CClassView *pView = (CClassView *)m_viewList.GetHead();      // Doc -> View

 

 











//App 클래스

 

CMainFrame *pMain = (CMainFrame *)AfxGetMainWnd(); //App -> MainFrm

 

//App -> MainFrm -> View

 

CClassView *pView = (CClassView *)pMain->GetActiveView();

 

//App -> MainFrm -> Doc

 

CClassDoc *pDoc = (CClassDoc *)pMain->GetActiveDocument();