Below is a quick tutorial on how to nest a child dialog inside another using MFC (useful when, say, implementing your own tab-strip-like control). Disclaimer: caveat emptor — this method may be flawed, but it works for me.

  1. Using the resource editor, create the parent dialog. As the child dialog will be a child window, be sure to set Control Parent to True.

  2. Optional: Create and insert a placeholder control of the desired dimensions for your nested child dialog. I typically use a CStatic with a border and caption for reference. Assign it a resource id that isn’t IDC_STATIC and generate a control member variable because you will need it later.

    Here is a picture of a sample parent dialog with a placeholder control:

    Nested dialogs parent dialog

    If you do not use a placeholder control, you will have to set the child window position manually.

  3. Using the resource editor, create a dialog to act as the child. Make sure that it is no larger than your placeholder control or it will be truncated (unless you handle resizing). Set Style to Child, Control to True, and Border to None. TheControl setting is particularly important for a smooth user experience —Raymond Chen describes what it does in What is the DS_CONTROL style for?

    Here is a picture of a sample child dialog:

    Nested dialogs child dialog
  4. Assuming that you named the placeholder control member variablem_staticPlaceholder, insert the following code snippet into the parent dialog’sOnInitDialog() function:

    // Get the static placeholder client rectangle, which we will use
    // to size the child dialog.
    CRect rct;
    m_staticPlaceholder.GetWindowRect(&rct); // In screen coordinates
    ScreenToClient(&rct);
    m_staticPlaceholder.ShowWindow(SW_HIDE);
    
    CDialog* pchild = new CChildDialog;
    // Call Create() explicitly to ensure the HWND is created.
    pchild->Create(CChildDialog::IDD, this);
    
    // Set the window position to be where the placeholder was.
    pchild->SetWindowPos
        (
        NULL,
        rct.left,
        rct.top,
        rct.Width(),
        rct.Height(),
        SWP_SHOWWINDOW
        );
    

    You may want to examine SetWindowPos()’s flags to see if there is a more appropriate combination of flags for your usage scenario.

Here is a picture of the result where the child dialog is properly nested inside the parent:

Nested dialogs combined dialog

Using this method, even keyboard navigation works correctly!


Posted by 두장
에디트박스와 리스트 컨트롤의 내용이 꽉 찰경우에 자동으로 스크롤을 내려줄 때
다음과 같이 구현합니다.

1. EditBox Control
CEdit m_edit;
m_edit.LineScroll(m_edit.GetLineCount());
2. List Control
CListCtrl m_list;
m_list.EnsureVisible(m_list.GetItemCount()-1, FALSE);

Posted by 두장

Thread 사용시 UpdateData(false); 는 실행 중에 Debug Assertion Failed라는

에러는 발생시킨다.

예를 들면,

MyThread( CMyDlg *p )
{
p->UpdateData(BOOL);
}
위와 같은 방법은 않된다.

 

가능한 방법1.

GetDlgItem()->SetWindowText(CString); 방법을 사용해서 특정 아이템만

업데이트를 하는 것이다. 이때, SetWindowText()의 인자 값으로는 CString만 온다는 것에 주의.

예제.

  int cnt = 100;

  CString num;
  num.Format("%d",cnt);

  Pointers->GetDlgItem(IDC_STATIC_RESULT)->SetWindowText(num);

 


그러나 콘트롤 하나 하나 직접 처리하는게 번거로워
UpdateData()로 일괄처리하고 싶으시다면..

유저메시지를 하나 만들어서 윈도로 쏘세요.. PostMessage( UM_UPDATE) 따위로
..
그래서 그 윈도가 스스로 UpdateData를 실행하도록 하셔야 합니다
.

예를 들면
..
#define UM_UPDATE WM_USER

BEGIN_MESSAGE_MAP(CMyDlg, CDialog)
    ON_MESSAGE( UM_UPDATE, OnUpdateData)
END_MESSAGE_MAP()

LRESULT CMyDlg::OnUpdateData( WPARAM wParam, LPARAM lParam)
{
    UpdateData( FALSE);

    return 0;
}

위와 같이 해 놓고.. 필요할때..스레드 상에서 다음과 같이 호출하면 되겠지요
.

pDlg->PostMessage( UM_UPDATE);

pDlg
CMyDlg의 포인터입니다. CMyDlg가 매인 윈도우라면

AfxGetApp()->m_pMainWnd
으로 얻을 수 있으며,
아니라면 스레드의 파라메터로 넘겨받아 쓰면 되죠
.

참고로 MFC가 모든 스레드 환경에서 완전하게 작동하진 않습니다
.
스레드로 뭔가를 할 때는 꼭 염두에 두셔야 해요.. -_-;

 

Posted by 두장
이전버튼 1 이전버튼