2

私は本当に混乱しています。:(

以下は、新しいプロパティ シートです。

#include "stdafx.h"
#include "resource.h"
#include "VisitsRotaMFCPropertySheet.h"


CVisitsRotaMFCPropertySheet::CVisitsRotaMFCPropertySheet()
    :CResizingMFCPropertySheet(_T("VisitsRota"), AFX_IDS_APP_TITLE, nullptr, 0)
{
    ConstructSheet();
}

CVisitsRotaMFCPropertySheet::~CVisitsRotaMFCPropertySheet()
{
}


BOOL CVisitsRotaMFCPropertySheet::OnInitDialog()
{
    BOOL bResult = CResizingMFCPropertySheet::OnInitDialog();

    m_Menu.LoadMenu(IDR_MENU);
    SetMenu(&m_Menu);

    return bResult;
}


void CVisitsRotaMFCPropertySheet::ConstructSheet()
{
    m_psh.dwFlags |= PSH_NOAPPLYNOW;

    AddPage(&m_ElderlyInfirmPage);
    AddPage(&m_ShepherdingPage);
}

に由来しCResizingMFCPropertySheetます。これはそのクラスのソースです:

https://www.dropbox.com/s/fzpfo4c3dpt6l51/ResizingMFCPropertySheet.cpp?dl=0

現在、このウィンドウには 2 つのページがあります。定義の 1 つを次に示します。

IDD_PAGE_ELDERLY_INFIRM DIALOGEX 0, 0, 420, 202
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_CAPTION
CAPTION "Elderly && Infirm"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
    GROUPBOX        "Elders ...",IDC_STATIC,6,7,132,188
    LISTBOX         IDC_LIST_BOOKSTUDY,12,18,120,147,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
    PUSHBUTTON      "Add",IDC_BUTTON_ADD_GROUP,12,172,35,18
    PUSHBUTTON      "Edit",IDC_BUTTON_EDIT_ELDER,55,172,35,18
    PUSHBUTTON      "Delete",IDC_BUTTON_DELETE_GROUP,97,172,35,18
    GROUPBOX        "Publishers ...",IDC_STATIC,144,7,132,188
    LISTBOX         IDC_LIST_ELDERY_INFIRM,150,18,120,147,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
    PUSHBUTTON      "Add",IDC_BUTTON_ADD_ELDERLY,150,172,35,18
    PUSHBUTTON      "Edit",IDC_BUTTON_EDIT_ELDERLY,193,172,35,18
    PUSHBUTTON      "Delete",IDC_BUTTON_DELETE_ELDERLY,235,172,35,18
    GROUPBOX        "Report Settings ...",IDC_STATIC,281,7,132,188
    LTEXT           "Starting month:",IDC_STATIC,286,18,120,8
    COMBOBOX        IDC_COMBO_MONTH,286,31,120,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
    LTEXT           "Number of months:",IDC_STATIC,286,49,78,12
    COMBOBOX        IDC_COMBO_NUM_MONTHS,376,49,30,96,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
    LTEXT           "Number of publishers to visit each month:",IDC_STATIC_NUM_PUB,286,65,84,18
    COMBOBOX        IDC_COMBO_PUB_PER_MONTH,376,66,30,12,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
    LTEXT           "Starting publisher:",IDC_STATIC,286,90,120,8
    COMBOBOX        IDC_COMBO_PUBLISHER,286,103,120,12,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
END

ページとして正しく設定されており、最初に IDE を介して制御データを設定しました。

IDD_PAGE_ELDERLY_INFIRM AFX_DIALOG_LAYOUT
BEGIN
    0,
    0, 0, 0, 100,
    0, 0, 0, 100,
    0, 100, 0, 0,
    0, 100, 0, 0,
    0, 100, 0, 0,
    0, 0, 0, 100,
    0, 0, 0, 100,
    0, 100, 0, 0,
    0, 100, 0, 0,
    0, 100, 0, 0,
    100, 0, 0, 100,
    100, 0, 0, 0,
    100, 0, 0, 0,
    100, 0, 0, 0,
    100, 0, 0, 0,
    100, 0, 0, 0,
    100, 0, 0, 0,
    100, 0, 0, 0,
    100, 0, 0, 0
END

CDialog代わりにプロパティ シートを呼び出すようにアプリケーションを調整しました。シート自体のサイズ:

シート

シート コントロールのサイズが自動的に変更されないのはなぜですか? 私はそれを理解していません。私の他のアプリケーションは同じ基本クラスを使用していますが、これらすべてのプロパティ ページは動的レイアウト機能を使用してコントロールなどのサイズを正しく変更しています。

アップデート

これを私のページの1つに追加しました:

void CElderlyInfirmPage::OnSize(UINT nType, int cx, int cy)
{
    CMFCPropertyPage::OnSize(nType, cx, cy);

    AfxMessageBox(_T("Size"));

    // TODO: Add your message handler code here
    auto pManager = GetDynamicLayout();
    if (pManager != nullptr)
    {
        AfxMessageBox(_T("Valid"));
    }
}

「ページ」に実際に動的レイアウトマネージャーがないことを確認します。シートのみです。問題は、動的レイアウト メカニズムを使用できないことだと思います。

更新 2

私はいくつかの進歩を遂げました。例:

サイズ変更

プロパティ ページは、ダイアログの場合のように動的レイアウト リソースをロードしていないようです。手動で作成し始めました:

BOOL CElderlyInfirmPage::OnInitDialog()
{
    CMFCPropertyPage::OnInitDialog();

    // TODO:  Add extra initialization here
    ReadSettings();
    InitMonthCombo();

    // Init to THIS month
    COleDateTime    datNow = COleDateTime::GetCurrentTime();
    m_cbMonth.SetCurSel(datNow.GetMonth()-1);

    EnableDynamicLayout(TRUE);
    auto pManager = GetDynamicLayout();
    if (pManager != nullptr)
    {
        pManager->Create(this);
        pManager->AddItem(IDC_COMBO_MONTH, CMFCDynamicLayout::MoveHorizontal(100), CMFCDynamicLayout::SizeNone());
        pManager->AddItem(IDC_COMBO_NUM_MONTHS, CMFCDynamicLayout::MoveHorizontal(100), CMFCDynamicLayout::SizeNone());
        pManager->AddItem(IDC_COMBO_PUB_PER_MONTH, CMFCDynamicLayout::MoveHorizontal(100), CMFCDynamicLayout::SizeNone());
        pManager->AddItem(IDC_COMBO_PUBLISHER, CMFCDynamicLayout::MoveHorizontal(100), CMFCDynamicLayout::SizeNone());
    }

    return TRUE;  // return TRUE unless you set the focus to a control
    // EXCEPTION: OCX Property Pages should return FALSE
}

ご覧のとおり、コントロールが移動するので進行状況です。しかし、現在の問題は、これらのページに多くのIDC_STATICコントロールがあり、ID 番号を変更したくないということです。これは、アプリケーションがローカリゼーション用の翻訳を既に持っているためです。ID 値を変更すると、翻訳が壊れてしまいます。[CMFCDynamicLayout::LoadResource][3]そのため、この方法を使用してRCファイルから完全な設定をロードできるかどうか疑問に思っています. しかし、ここに電話する方法がわかりませんLoadResource。それがこの質問に対する答えになると確信しています。

アップデート 3

コードをたどったところです。ここを見ると:

LRESULT CPropertySheet::HandleInitDialog(WPARAM, LPARAM)
{
    LRESULT lResult = OnInitDialog();

    CMFCDynamicLayout* pDynamicLayout = GetDynamicLayout();
    if (pDynamicLayout != NULL)
    {
        CRect rectWindow;
        GetWindowRect(rectWindow);
        m_sizeMin = rectWindow.Size();

        for (CWnd *pChild = GetWindow(GW_CHILD); pChild->GetSafeHwnd() != NULL; pChild = pChild->GetWindow(GW_HWNDNEXT))
        {
            HWND hwndChild = pChild->GetSafeHwnd();
            if (!pDynamicLayout->HasItem(hwndChild))
            {
                if (pChild->SendMessage(WM_GETDLGCODE) & DLGC_BUTTON)
                {
                    pDynamicLayout->AddItem(hwndChild, CMFCDynamicLayout::MoveHorizontalAndVertical(100, 100), CMFCDynamicLayout::SizeNone());
                }
                else if (IsLeftNavigationPane(hwndChild))
                {
                    pDynamicLayout->AddItem(hwndChild, CMFCDynamicLayout::MoveNone(), CMFCDynamicLayout::SizeVertical(100));
                }
                else if (DYNAMIC_DOWNCAST(CPropertyPage, pChild) == NULL || CanAddPageToDynamicLayout())
                {
                    pDynamicLayout->AddItem(hwndChild, CMFCDynamicLayout::MoveNone(), CMFCDynamicLayout::SizeHorizontalAndVertical(100, 100));
                }
            }
        }
    }

    return lResult;
}

実際にはレイアウトが適切に機能していないようです。

私は使用しようとしました:

LoadDynamicLayoutResource(m_lpszTemplateName);

そして、私はそれを追跡しました。最終的にここにたどり着きました:

BOOL CMFCDynamicLayout::LoadResource(CWnd* pHostWnd, LPVOID lpResource, DWORD dwSize)
{
    if (pHostWnd->GetSafeHwnd() == NULL || !::IsWindow(pHostWnd->GetSafeHwnd()) || lpResource == NULL)
    {
        return FALSE;
    }

    CMFCDynamicLayoutData layoutData;
    BOOL bResult = layoutData.ReadResource(lpResource, (UINT)dwSize);
    layoutData.ApplyLayoutDataTo(pHostWnd, FALSE);

    return bResult;
}

最初のステートメントで、ApplyLayoutDataTo呼び出しに失敗しました:if

BOOL CMFCDynamicLayoutData::ApplyLayoutDataTo(CWnd* pHostWnd, BOOL bUpdate)
{
    if (pHostWnd->GetSafeHwnd() == NULL || m_listCtrls.IsEmpty())
    {
        return FALSE;
    }

    ASSERT_VALID(pHostWnd);

    pHostWnd->EnableDynamicLayout(FALSE);
    pHostWnd->EnableDynamicLayout();

m_listCtrls.IsEmpty()空でした。とにかく、それを適切に読み込んでいませんでした。

静的コントロールも含め、すべてのコントロールに ID を割り当て、動的レイアウトを手動で構築する以外に選択肢はないと思います。他のアイデアがない限り。

4

1 に答える 1