在这里为您提供一个最小的工作示例有点困难,但我将尝试解释我刚刚注意到的这个问题。
上下文
所以,我有一个常规CDialogEx
派生类,定义如下:
class CChristianLifeMinistryStudentsDlg : public CDialogEx
我已将其设置为边框不会调整大小:
主应用程序(也是CDialogEx
基于)有一个固定的窗口。那行为是正确的。
- 用户从菜单中显示一个可调整大小的对话框(编辑器)。
- 在这个对话框上是一个用户可以按下的按钮,它将依次显示我所指的弹出模式对话框。
发生什么了
当显示此对话框时,当您将鼠标悬停在对话框边框上时,我注意到了这一点:
我不明白为什么会这样。
光标管理
在产生这个弹出窗口的“编辑器”中,我确实有一些像这样的光标管理:
BOOL CChristianLifeMinistryEditorDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if (CPersistentWaitCursor::WaitCursorShown())
{
RestoreWaitCursor();
return TRUE;
}
return CDialogEx::OnSetCursor(pWnd, nHitTest, message);
}
但是,我暂时尝试从没有游标管理的主应用程序对话框中调用此弹出窗口,结果仍然相同。
间谍结果
根据要求,我刚刚使用 Spy 来检查窗口样式:
果然不出所料我们突然WS_THICKFRAME
设置了,当它不在资源编辑器中时!
所以
在我的 RC 文件中,对话框DS_MODALFRAME
设置了标志,但在运行时它最终WS_THICKFRAME
设置了。据我所知,我从未对这些受影响的对话框对象进行这些更改。
更新
我发现了以下内容:
BOOL CChristianLifeMinistryStudentsDlg::OnInitDialog()
{
LONG_PTR lStyle = GetWindowLongPtr(GetSafeHwnd(), GWL_STYLE);
if (lStyle & WS_THICKFRAME)
AfxMessageBox(_T("Thick"));
else if (lStyle & DS_MODALFRAME)
AfxMessageBox(_T("Modal"));
CDialogEx::OnInitDialog();
如果我在调用之前放置检查代码,CDialogEx::OnInitDialog();
则样式设置为DS_MODALFRAME
. 但是,如果我在调用后放置相同的检查代码,则CDialogEx::OnInitDialog();
它会更改为WS_THICKFRAME
. 为什么?
好的
因此,该CDialogEx::OnInitDialog
方法调用CWnd::LoadDynamicLayoutResource(LPCTSTR lpszResourceName)
. 这反过来调用CWnd::InitDynamicLayout()
. 在该方法中,它这样做:
if (!bIsChild && (pDialog != NULL || pPropSheet != NULL))
{
CRect rect;
GetClientRect(&rect);
ModifyStyle(DS_MODALFRAME, WS_POPUP | WS_THICKFRAME);
::AdjustWindowRectEx(&rect, GetStyle(), ::IsMenu(GetMenu()->GetSafeHmenu()), GetExStyle());
SetWindowPos(NULL, 0, 0, rect.Width(), rect.Height(), SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOOWNERZORDER);
}
我们去吧。所以这是因为我正在使用CDialogEx
我的基类。这是MFC中的错误吗?
澄清
“编辑器”(拥有按钮的弹出窗口的父窗口)确实使用动态布局功能:
但在这种情况下,弹出窗口不需要。但这是因为我的弹出窗口源于CDialogEx
这种情况。
情节变厚了
所以这是始终使用以下命令调用的 MFC 代码CDialog::OnInitDialog
:
BOOL CWnd::LoadDynamicLayoutResource(LPCTSTR lpszResourceName)
{
if (GetSafeHwnd() == NULL || !::IsWindow(GetSafeHwnd()) || lpszResourceName == NULL)
{
return FALSE;
}
// find resource handle
DWORD dwSize = 0;
LPVOID lpResource = NULL;
HGLOBAL hResource = NULL;
if (lpszResourceName != NULL)
{
HINSTANCE hInst = AfxFindResourceHandle(lpszResourceName, RT_DIALOG_LAYOUT);
HRSRC hDlgLayout = ::FindResource(hInst, lpszResourceName, RT_DIALOG_LAYOUT);
if (hDlgLayout != NULL)
{
// load it
dwSize = SizeofResource(hInst, hDlgLayout);
hResource = LoadResource(hInst, hDlgLayout);
if (hResource == NULL)
return FALSE;
// lock it
lpResource = LockResource(hResource);
ASSERT(lpResource != NULL);
}
}
// Use lpResource
BOOL bResult = CMFCDynamicLayout::LoadResource(this, lpResource, dwSize);
// cleanup
if (lpResource != NULL && hResource != NULL)
{
UnlockResource(hResource);
FreeResource(hResource);
}
if (bResult)
{
InitDynamicLayout();
}
return bResult;
}
由于某种原因,此调用BOOL bResult = CMFCDynamicLayout::LoadResource(this, lpResource, dwSize);
是 return TRUE
。结果,对话框最终调用InitDynamicLayout
. 在我的其他弹出对话框中,这不会发生。取而代之的是,bResult
最终FALSE
框架没有调整大小。
那么为什么它认为它有效呢?