2
votes

I am currently working on finishing some code handed off to me. It was written in MFC in Visual Studio 2005 years ago, was put on hold, and now is brought to me.

While I know C++, I have spent the last ~2 months studying the code and learning MFC and it's starting to come together.

The GUI for the code is an SWF flash file embedded in an invisible dialog window. I do not have the source code for the SWF file so will probably, in the future, redo it in WPF or something. I have the WMMode set to "Window" because in Transparent/Opaque mode it doesn't display properly, where it flashes/blinks everytime a mouse event is captured.

Anyhow, in Win XP/Vista, clicking and dragging the flash control works. In windows 7/8.1, it won't move.

Happy to provide any and all info needed. I'm still a little overwhelmed by MFC dialogs so unsure what you'd all like to see.

I found this question: Moving window by click-drag on a control

Which looks like it solves a lot of the issue. However, I don't want the whole control to be clickable like this, only the top part. Unfortunately, in the MS Resource view, the ActiveX control is blank as the SWF is only loaded at runtime; I've tried to find resources for this kind of thing but it's very difficult as I am unsure of the technical terms to use.

EDIT

I have attempted this by creating a very simple MFC app that has a Static Text control and nothing else. I am trying to get it to work by clicking on the static text (though I may be painting myself into a corner as it does not have a built-in lButtonDown event).

Here is the relevant code:

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()

Overridden Method:

afx_msg void MyDialog::OnLButtonDown(UINT nFlags, CPoint point)
{
    CWnd::OnNcLButtonDown(HTCAPTION, point);

}

I have also tried setting nFlags to 0x2, calling OnLButtonDown (as opposed to onNcLButtonDown), various other things. The message fires but the window does not move (it does move from the title bar, as normal). What am I missing?

1
So it looks like you have solved the problem. You override OnLButtonDown and pass WM_NCLBUTTONDOWN. If you only want this on lets say the top part of the window then check mouse position and don't do anything if mouse is not in right place?Barmak Shemirani
Thanks for the response. I have edited my post above, can you provide any further insight?Moe45673

1 Answers

5
votes

Actually lets try this code instead with ON_WM_NCHITTEST(). This will drag the dialog if you click the mouse anywhere in client area (client area acts as caption). There is a line rc.bottom = rc.top + 100 if you uncomment it then it will only drag if you click the top section (I picked the number 100 at random).

//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);
}

Second option: If we want to move the dialog by clicking on a child control, and if that control captures the mouse, then try this method instead. ***Note, test to make sure the control works properly after it is moved.

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);
}