WIN32, C++: Is it possible to animate a window wit

2019-06-17 05:11发布

I Have an edit control (a text field) which I want to animate. The animation I want is that it slides out, creating an extra line for this text field. I am able to animate my text field and able to make it larger, however to show the sliding animation I first have to hide it. This means the entire text fields slides out as if being created for the first time from nothing, instead of just adding a new line.

This is the code I have now:

SetWindowPos(hwnd, HWND_TOP, x, y, newWidth, newHeight, SWP_DRAWFRAME);

ShowWindow(hwnd, SW_HIDE);

AnimateWindow(hwnd, 300, AW_SLIDE | AW_VER_NEGATIVE);

Is it possible to show this animation without hiding it?

3条回答
Melony?
2楼-- · 2019-06-17 05:24

I think it's not possible to do with the built-in AnimateWindow API. The MSDN entry to AnimateWindow http://msdn.microsoft.com/en-us/library/ms632669(VS.85).aspx says it is used to "produce special effects when showing or hiding windows", and the AW_HIDE flag determines that the function either shows or hides a window. And I can't see any alternative built-in function to do what you want.

Thus, Nick D. and Alan have the right approach of coding the resizing yourself. This is often the solution. (I had never heard of AnimateWindow before.) I assume AnimateWindow does something very similar internally, though I assume it's much more reliable.

You also obviously need to make sure the Timer does the right thing if another line is added or removed to the text box, or its otherwise resized, before it's finished animating.

And also give serious thought to making the animation low priority, if it's inconvenient to code.

查看更多
成全新的幸福
3楼-- · 2019-06-17 05:31

To expand on Nick D's answer, here's the code to achieve what you're looking for...

.h

#define ANIMATION_TIMER 1234
#define ANIMATION_LIMIT 8
#define ANIMATION_OFFSET 4

int m_nAnimationCount;

.cpp

void CExampleDlg::OnTimer(UINT_PTR nIDEvent)
{
    if (nIDEvent == ANIMATION_TIMER)
    {
        if (++m_nAnimationCount > ANIMATION_LIMIT)
            KillTimer(EXPAND_TIMER);
        else
        {
            CRect rcExpand;
            m_edtExpand.GetWindowRect(rcExpand);
            ScreenToClient(rcExpand);

            rcExpand.bottom += ANIMATION_OFFSET;

            m_edtExpand.MoveWindow(rcExpand);
        }   
    }

    CDialog::OnTimer(nIDEvent);
}

void CExampleDlg::OnStartAnimation()
{
    m_nAnimationCount = 0;
    SetTimer(ANIMATION_TIMER, 20, NULL);
}

Don't forget to set the Multiline property on the edit control (m_edtExpand)

查看更多
欢心
4楼-- · 2019-06-17 05:43

An alternative way is to simulate animation with SetTimer function which will call a routine to resize the window, incrementally.

查看更多
登录 后发表回答