MFC 单击和 move/drag 对话框 window
MFC click and move/drag dialog window
我目前正在完成一些交给我的代码。 2005年前Visual Studio用MFC写的,搁置了,现在拿来了。
虽然我了解 C++,但我在过去 ~2 个月的时间里研究了代码并学习了 MFC,并且它们开始融合在一起。
代码的 GUI 是嵌入在不可见对话框中的 SWF 闪存文件 window。我没有 SWF 文件的源代码,所以将来可能会在 WPF 或其他软件中重做。我将 WMMode 设置为 "Window",因为在 Transparent/Opaque 模式下它无法正确显示,每次捕获鼠标事件时它都会 flashes/blinks。
无论如何,在 Win XP/Vista 中,单击并拖动 flash 控件是有效的。在windows7/8.1中,它不会移动。
很乐意提供所需的所有信息。我仍然对 MFC 对话框有点不知所措,所以不确定你们都想看到什么。
我发现了这个问题:Moving window by click-drag on a control
看起来它解决了很多问题。但是,我不希望整个控件都像这样可点击,只有顶部。不幸的是,在 MS 资源视图中,ActiveX 控件是空白的,因为 SWF 仅在运行时加载;我曾尝试为这类事情寻找资源,但很难,因为我不确定要使用的技术术语。
编辑
我已经尝试通过创建一个非常简单的 MFC 应用程序来实现这一点,该应用程序只有一个静态文本控件,仅此而已。我试图通过单击静态文本使其工作(尽管我可能把自己画到角落里,因为它没有 built-in lButtonDown 事件)。
相关代码如下:
class MyDialog : public CDialog
{
public:
MyDialog(CWnd* pParent = NULL) : CDialog(MyDialog::IDD, pParent)
{ }
// Dialog Data, name of dialog form
enum{ IDD = INTERFACE1 };
protected:
virtual void DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); }
//Called right after constructor. Initialize things here.
virtual BOOL OnInitDialog()
{
CDialog::OnInitDialog();
pText = (CStatic *)GetDlgItem(ID_TEXT);
pText->SetWindowTextW(_T("Hello World!"));
return true;
}
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
private:
CStatic * pText;
public:
DECLARE_MESSAGE_MAP()
};
BEGIN_MESSAGE_MAP(MyDialog, CDialog)
ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()
覆盖的方法:
afx_msg void MyDialog::OnLButtonDown(UINT nFlags, CPoint point)
{
CWnd::OnNcLButtonDown(HTCAPTION, point);
}
我也试过将 nFlags 设置为 0x2,调用 OnLButtonDown(与 onNcLButtonDown 相反),以及各种其他操作。消息触发但 window 没有移动(它确实从标题栏移动,正常情况下)。我错过了什么?
实际上让我们用 ON_WM_NCHITTEST()
来试试这个代码。如果您在客户区的任意位置单击鼠标,这将拖动对话框(客户区充当标题)。有一行 rc.bottom = rc.top + 100
如果您取消注释它,那么它只会在您单击顶部部分时拖动(我随机选择了数字 100)。
//declare:
afx_msg LRESULT OnNcHitTest(CPoint point);
BEGIN_MESSAGE_MAP(MyDialog, CDialog)
ON_WM_NCHITTEST()
END_MESSAGE_MAP()
LRESULT MyDialog::OnNcHitTest(CPoint point)
{
ScreenToClient(&point);
CRect rc;
GetClientRect(&rc);
//rc.bottom = rc.top + 100;
if (rc.PtInRect(point))
return HTCAPTION;
return CDialog::OnNcHitTest(point);
}
第二个选项:
如果我们想通过单击 child 控件来移动对话框,并且如果该控件捕获鼠标,则尝试使用此方法。 ***注意,请测试控件移动后是否正常工作。
BOOL MyDialog::PreTranslateMessage(MSG *msg)
{
if (msg->message == WM_MOUSEMOVE && (msg->wParam & MK_LBUTTON))
{
CPoint p;
GetCursorPos(&p);
CRect r;
ActiveX->GetWindowRect(&r);
if (r.PtInRect(p))
{
ReleaseCapture();
SendMessage(WM_NCLBUTTONDOWN, HTCAPTION, 0);
SendMessage(WM_NCLBUTTONUP, HTCAPTION, 0);
return 1;
}
}
return CDialogEx::PreTranslateMessage(msg);
}
我目前正在完成一些交给我的代码。 2005年前Visual Studio用MFC写的,搁置了,现在拿来了。
虽然我了解 C++,但我在过去 ~2 个月的时间里研究了代码并学习了 MFC,并且它们开始融合在一起。
代码的 GUI 是嵌入在不可见对话框中的 SWF 闪存文件 window。我没有 SWF 文件的源代码,所以将来可能会在 WPF 或其他软件中重做。我将 WMMode 设置为 "Window",因为在 Transparent/Opaque 模式下它无法正确显示,每次捕获鼠标事件时它都会 flashes/blinks。
无论如何,在 Win XP/Vista 中,单击并拖动 flash 控件是有效的。在windows7/8.1中,它不会移动。
很乐意提供所需的所有信息。我仍然对 MFC 对话框有点不知所措,所以不确定你们都想看到什么。
我发现了这个问题:Moving window by click-drag on a control
看起来它解决了很多问题。但是,我不希望整个控件都像这样可点击,只有顶部。不幸的是,在 MS 资源视图中,ActiveX 控件是空白的,因为 SWF 仅在运行时加载;我曾尝试为这类事情寻找资源,但很难,因为我不确定要使用的技术术语。
编辑
我已经尝试通过创建一个非常简单的 MFC 应用程序来实现这一点,该应用程序只有一个静态文本控件,仅此而已。我试图通过单击静态文本使其工作(尽管我可能把自己画到角落里,因为它没有 built-in lButtonDown 事件)。
相关代码如下:
class MyDialog : public CDialog
{
public:
MyDialog(CWnd* pParent = NULL) : CDialog(MyDialog::IDD, pParent)
{ }
// Dialog Data, name of dialog form
enum{ IDD = INTERFACE1 };
protected:
virtual void DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); }
//Called right after constructor. Initialize things here.
virtual BOOL OnInitDialog()
{
CDialog::OnInitDialog();
pText = (CStatic *)GetDlgItem(ID_TEXT);
pText->SetWindowTextW(_T("Hello World!"));
return true;
}
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
private:
CStatic * pText;
public:
DECLARE_MESSAGE_MAP()
};
BEGIN_MESSAGE_MAP(MyDialog, CDialog)
ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()
覆盖的方法:
afx_msg void MyDialog::OnLButtonDown(UINT nFlags, CPoint point)
{
CWnd::OnNcLButtonDown(HTCAPTION, point);
}
我也试过将 nFlags 设置为 0x2,调用 OnLButtonDown(与 onNcLButtonDown 相反),以及各种其他操作。消息触发但 window 没有移动(它确实从标题栏移动,正常情况下)。我错过了什么?
实际上让我们用 ON_WM_NCHITTEST()
来试试这个代码。如果您在客户区的任意位置单击鼠标,这将拖动对话框(客户区充当标题)。有一行 rc.bottom = rc.top + 100
如果您取消注释它,那么它只会在您单击顶部部分时拖动(我随机选择了数字 100)。
//declare:
afx_msg LRESULT OnNcHitTest(CPoint point);
BEGIN_MESSAGE_MAP(MyDialog, CDialog)
ON_WM_NCHITTEST()
END_MESSAGE_MAP()
LRESULT MyDialog::OnNcHitTest(CPoint point)
{
ScreenToClient(&point);
CRect rc;
GetClientRect(&rc);
//rc.bottom = rc.top + 100;
if (rc.PtInRect(point))
return HTCAPTION;
return CDialog::OnNcHitTest(point);
}
第二个选项: 如果我们想通过单击 child 控件来移动对话框,并且如果该控件捕获鼠标,则尝试使用此方法。 ***注意,请测试控件移动后是否正常工作。
BOOL MyDialog::PreTranslateMessage(MSG *msg)
{
if (msg->message == WM_MOUSEMOVE && (msg->wParam & MK_LBUTTON))
{
CPoint p;
GetCursorPos(&p);
CRect r;
ActiveX->GetWindowRect(&r);
if (r.PtInRect(p))
{
ReleaseCapture();
SendMessage(WM_NCLBUTTONDOWN, HTCAPTION, 0);
SendMessage(WM_NCLBUTTONUP, HTCAPTION, 0);
return 1;
}
}
return CDialogEx::PreTranslateMessage(msg);
}