Windows XP 平板电脑版Visual C++ 7.1Visual C++ 8.0Windows VistaVisual C++ 7.0.NET 1.0Visual Studio .NET 2003Windows 2003.NET 1.1.NET 3.0Visual Studio 2005Windows 2000Visual C++ 6.0Windows XP.NET 2.0MFC中级开发Visual StudioWindowsC++.NET
创建可移动的子窗口控件
一个关于构建可在运行时由用户移动的 Windows 控件的教程。
引言
我遇到了很多关于“如何在对话框上制作可移动控件”和“如何在运行时制作一组可移动控件”的疑问。 这里尝试以最简单的形式实现相同的功能; 但是,可以根据需要进行修改。
背景
按照 Windows 预定义的行为,我们可以使用对话框/框架窗口的标题栏在运行时移动它们。 有时您可能想要移动没有标题栏的控件/一组控件。 这里的示例代码解决了这个问题。
使用代码
该代码是使用 Microsoft Visual Studio 6.0 编写和编译的。
使用 Windows 的对话框布局编辑器将控件放置在对话框上。
您可以根据您的要求将成员变量与这些控件关联起来
// MovableTrialDlg.h
CStatic m_staticMovable;
CEdit m_editMovable;
在类 CMovableTrialDlg
中定义额外的成员变量。
// MovableTrialDlg.h
bool m_bMoving;
请在您的代码中包含 PreTranslateMessage()
。
// MovableTrialDlg.h
virtual BOOL PreTranslateMessage(MSG* pMsg);
PreTranslateMessage()
对需要移动的控件执行所需的操作。
BOOL CMovableTrialDlg::PreTranslateMessage(MSG* pMsg)
{
// TODO: Add your specialized code here and/or call the base class
if(pMsg->hwnd == m_editMovable.m_hWnd)
{
if(pMsg->message == WM_LBUTTONUP)
{
OnMovableStaticLButtonUp(pMsg);
}
if(pMsg->message == WM_LBUTTONDOWN)
{
OnMovableStaticLButtonDown(pMsg);
}
if(pMsg->message == WM_MOUSEMOVE)
{
OnMovableStaticMouseMove(pMsg);
}
}
return CDialog::PreTranslateMessage(pMsg);
}
当鼠标移动且移动窗口的状态 m_bMoving
为 true
时,通过更改控件的窗口位置来执行移动。
void CMovableTrialDlg::OnMovableStaticMouseMove(MSG* pMsg)
{
if(m_bMoving == false)
return;
WINDOWPLACEMENT wp;
::GetWindowPlacement(m_editMovable.m_hWnd, &wp);
int nXDiff = wp.rcNormalPosition.right - wp.rcNormalPosition.left;
int nYDiff = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;
POINT pt = pMsg->pt;
ScreenToClient(&pt);
wp.rcNormalPosition.left = pt.x - 5;
wp.rcNormalPosition.top = pt.y - 5;
wp.rcNormalPosition.right = wp.rcNormalPosition.left + nXDiff;
wp.rcNormalPosition.bottom= wp.rcNormalPosition.top + nYDiff;
::SetWindowPlacement(m_editMovable.m_hWnd, &wp);
::GetWindowPlacement(m_staticMovable.m_hWnd, &wp);
nXDiff = wp.rcNormalPosition.right - wp.rcNormalPosition.left;
nYDiff = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;
pt = pMsg->pt;
ScreenToClient(&pt);
wp.rcNormalPosition.left = pt.x - 5;
wp.rcNormalPosition.top = pt.y - nYDiff - 5;
wp.rcNormalPosition.right = wp.rcNormalPosition.left + nXDiff;
wp.rcNormalPosition.bottom= wp.rcNormalPosition.top + nYDiff;
::SetWindowPlacement(m_staticMovable.m_hWnd, &wp);
m_editMovable.Invalidate();
m_staticMovable.Invalidate();
}
一旦鼠标左键按下事件发生在编辑控件上,将移动状态 m_bMoving
设置为 true
。
void CMovableTrialDlg::OnMovableStaticLButtonDown(MSG* pMsg)
{
m_bMoving = true;
}
类似地,当鼠标左键抬起时,将移动状态 m_bMoving
更改为 false
。
void CMovableTrialDlg::OnMovableStaticLButtonUp(MSG* pMsg)
{
m_bMoving = false;
}
历史
我将提供代码,以便控件组看起来像一个带有非 MDI 框架/对话框的子容器,并且可以使用标题栏进行移动。 标题栏将被模拟。