コードが適切に機能しない前に、同様の状況に遭遇したことがあります。問題を解決するために、それらの変更にコメントして問題を修正するよりもいくつかの変更を加えました。突然、どこかのファイルを「編集」するだけで問題は修正されましたが、コードに実際の変更はありませんでした。私は再び同様の問題に遭遇しましたが、これはどのように起こるのでしょうか?
void CDlgResizeHelper::Init(HWND hparent)
{
m_hParent = hparent;
m_CtrlsList.clear();
if (::IsWindow(m_hParent))
{
::GetWindowRect(m_hParent, m_OrigParentSize);
// get all child windows and store their original sizes and positions
HWND hCtrl = ::GetTopWindow(m_hParent);
while (hCtrl)
{
CtrlSize cs;
cs.hctrl = hCtrl;
::GetWindowRect(hCtrl, cs.orig_size);
::ScreenToClient(m_hParent, &cs.orig_size.TopLeft());
::ScreenToClient(m_hParent, &cs.orig_size.BottomRight());
// CString msg;
// msg.Format("Old Size: %d %d %d %d\r\n", cs.orig_size.left, cs.orig_size.top, cs.orig_size.right, cs.orig_size.bottom );
// TRACE( msg );
m_CtrlsList.push_back(cs);
hCtrl = ::GetNextWindow(hCtrl, GW_HWNDNEXT);
}
}
}
このクラス/関数は、ダイアログのサイズに基づいてコントロールのサイズを変更します。デバッグ版では動作していましたが、リリース版では同じコードが動作しません(=正しくリサイズされません)。上記の TRACE 関数のループに 3 行を変更して追加しました。リリース版でも正常に動作するようになりました。これらの行にコメントしたよりも、リリースビルドでも機能します。それらを削除したところ、リリース ビルドでは機能しなくなりました。リリースビルドが正しいことを行うために、これらの行にコメントを付けておく必要があります。これはどのように正当化できますか?このファイルの「編集」は、実際のコードでは実際には変更されず、問題を解決する可能性がありますか?
また、必ずしも問題を解決するとは限らないファイル内の他の場所で、「編集」を試みたか、新しいコードにコメントしたことを追加したいと思います。それを修正する上記の関数にコメント付きのコードが必要なだけです。
更新ここに完全なクラスがあります。このクラスは Web のどこかで無料で入手でき、私はオリジナルの作成者ではありません。
Init
OnInitDialog
サイズ変更が必要なダイアログのから呼び出されます。すべてのコントロールの座標を格納するだけです。OnSize() は実際にサイズ変更を行います。
CDlgResizeHelper::CDlgResizeHelper() { }
void CDlgResizeHelper::Init(HWND hparent) { m_hParent = hparent; m_CtrlsList.clear();
if (::IsWindow(m_hParent)) { ::GetWindowRect(m_hParent, m_OrigParentSize); // get all child windows and store their original sizes and positions HWND hCtrl = ::GetTopWindow(m_hParent); while (hCtrl) { CtrlSize cs; cs.hctrl = hCtrl; ::GetWindowRect(hCtrl, cs.orig_size); ::ScreenToClient(m_hParent, &cs.orig_size.TopLeft()); ::ScreenToClient(m_hParent, &cs.orig_size.BottomRight()); CString msg; msg.Format("Old Size: %d %d %d %d\r\n", cs.orig_size.left, cs.orig_size.top, cs.orig_size.right, cs.orig_size.bottom ); Sleep( 50 ); m_CtrlsList.push_back(cs); hCtrl = ::GetNextWindow(hCtrl, GW_HWNDNEXT); } }
}
void CDlgResizeHelper::Remove(HWND hwnd) { CtrlList::iterator it;
for (it = m_CtrlsList.begin(); it != m_CtrlsList.end(); ++it) { if (it->hctrl == hwnd) { m_CtrlsList.erase(it); return; } }
}
void CDlgResizeHelper::Update(HWND hwnd) { if (m_hParent && hwnd) { CtrlList::iterator it;
for (it = m_CtrlsList.begin(); it != m_CtrlsList.end(); ++it) { if (it->hctrl == hwnd) { ::GetWindowRect(hwnd, &(it->orig_size)); ::ScreenToClient(m_hParent, &(it->orig_size.TopLeft())); ::ScreenToClient(m_hParent, &(it->orig_size.BottomRight())); } } }
}
void CDlgResizeHelper::Add(HWND hwnd) { if (m_hParent && hwnd) { CtrlSize cs; cs.hctrl = hwnd;
::GetWindowRect(hwnd, cs.orig_size);
::ScreenToClient(m_hParent, &cs.orig_size.TopLeft());
::ScreenToClient(m_hParent, &cs.orig_size.BottomRight());
m_CtrlsList.push_back(cs);
}
}
void CDlgResizeHelper::OnSize() { if (::IsWindow(m_hParent)) { CRect currparentsize; ::GetWindowRect(m_hParent, currparentsize);
double xratio = ((double) currparentsize.Width()) / m_OrigParentSize.Width();
double yratio = ((double) currparentsize.Height()) / m_OrigParentSize.Height();
HDWP hdwp;
hdwp = BeginDeferWindowPos((int)m_CtrlsList.size());
// resize child windows according to their fix attributes
CtrlList::const_iterator it;
for (it = m_CtrlsList.begin(); it != m_CtrlsList.end(); ++it)
{
CRect currctrlsize;
HorizFix horiz_fix = it->horiz_fix;
VertFix vert_fix = it->vert_fix;
if (horiz_fix & LEFT)
currctrlsize.left = it->orig_size.left;
else
currctrlsize.left = (LONG)( ((horiz_fix & WIDTH) && (horiz_fix & RIGHT)) ? (it->orig_size.left + currparentsize.Width() - m_OrigParentSize.Width()) : (it->orig_size.left * xratio));
if (horiz_fix & RIGHT)
currctrlsize.right = it->orig_size.right + currparentsize.Width() - m_OrigParentSize.Width();
else
currctrlsize.right = (LONG)((horiz_fix & WIDTH) ? (currctrlsize.left + it->orig_size.Width()) : (it->orig_size.right * xratio));
if (vert_fix & TOP)
currctrlsize.top = it->orig_size.top;
else
currctrlsize.top = (LONG)(((vert_fix & HEIGHT) && (vert_fix & BOTTOM)) ? (it->orig_size.top + currparentsize.Height() - m_OrigParentSize.Height()) : (it->orig_size.top * yratio));
if (vert_fix & BOTTOM)
currctrlsize.bottom = it->orig_size.bottom + currparentsize.Height() - m_OrigParentSize.Height();
else
currctrlsize.bottom = (LONG)((vert_fix & HEIGHT) ? (currctrlsize.top + it->orig_size.Height()) : (it->orig_size.bottom * yratio));
UINT flags = SWP_NOZORDER;
if (! it->resize)
flags |= SWP_NOSIZE;
hdwp = ::DeferWindowPos(hdwp, it->hctrl, NULL, currctrlsize.left, currctrlsize.top, (it->resize)? currctrlsize.Width() : 0, (it->resize)? currctrlsize.Height() : 0, flags);
if (hdwp == NULL)
return;
} //end for (it = m_CtrlsList.begin(); it != m_CtrlsList.end(); ++it)
EndDeferWindowPos(hdwp);
} //end if (::IsWindow(m_hParent))
}
BOOL CDlgResizeHelper::Fix(HWND a_hCtrl, HorizFix a_hFix, VertFix a_vFix, bool resize / = true /) { CtrlList::iterator it;
for (it = m_CtrlsList.begin(); it != m_CtrlsList.end(); ++it)
{
if (it->hctrl == a_hCtrl)
{
it->horiz_fix = a_hFix;
it->vert_fix = a_vFix;
it->resize = resize;
return TRUE;
}
}
return FALSE;
}
BOOL CDlgResizeHelper::Fix(int a_itemId, HorizFix a_hFix, VertFix a_vFix, bool resize / = true /) { return Fix(::GetDlgItem(m_hParent, a_itemId), a_hFix, a_vFix, resize); }
BOOL CDlgResizeHelper::Fix(HorizFix a_hFix, VertFix a_vFix, bool resize / = true /) { CtrlList::iterator it;
for(it = m_CtrlsList.begin(); it!=m_CtrlsList.end(); ++it)
{
it->horiz_fix = a_hFix;
it->vert_fix = a_vFix;
it->resize = resize;
}
return TRUE;
}
UINT CDlgResizeHelper::Fix(LPCTSTR a_pszClassName, HorizFix a_hFix, VertFix a_vFix, bool resize / = true /) { char cn_buf[200];
memset(cn_buf, 0, 200);
UINT cnt = 0;
CtrlList::iterator it;
for (it = m_CtrlsList.begin(); it!= m_CtrlsList.end(); ++it)
{
::GetClassName(it->hctrl, cn_buf, sizeof(cn_buf));
if (strcmp(cn_buf, a_pszClassName) == 0)
{
cnt++;
it->horiz_fix = a_hFix;
it->vert_fix = a_vFix;
it->resize = resize;
}
}
return cnt;
}