C ++快速刷新桌面

时间:2012-10-30 12:26:51

标签: c++ windows animation desktop

我正在尝试制作一个程序,它将多边形输出到桌面以获得简单的动画。我目前遇到的问题是动画获得“洋葱”效果,因为桌面不刷新。我已经搜索了一种刷新桌面的方法,但因为它是一个动画,所以没有一个解决方案可以足够快地刷新它。以下是我的代码示例:

#include <iostream>
#include <Windows.h>
#include <math.h>
#include <Shlobj.h>


int main() {    
    //start ambrose
    POINT amby[5];
    POINT pos;
    /* hide console window */
    ShowWindow(FindWindowA("ConsoleWindowClass", NULL), false);
    /* Calling GetDC with argument 0 retrieves the desktop's DC */
    HDC hDC_Desktop = GetDC(0);

    //This is just an example of what I am doing

    for (int i = 0; i < 10000; i++) {

        pos.x = 600+sin(double(i)/50)*200;
        pos.y = 500+cos(double(i)/50)*200;
        amby[0].x = -10+pos.x;
        amby[0].y = -10+pos.y;
        amby[1].x = -50+pos.x;
        amby[1].y = -50+pos.y;
        amby[2].x = 50+pos.x;
        amby[2].y = -50+pos.y;

        Polygon(hDC_Desktop,amby, 3);
        Sleep(10);
    }
    //The method I was trying before that didn't work VVVVV
    //LPITEMIDLIST pidl;
    //SHGetSpecialFolderLocation(NULL,CSIDL_DESKTOP,&pidl);
    //SHChangeNotify(SHCNE_ASSOCCHANGED,SHCNF_IDLIST,pidl,0);
    return 0;
}

由于

修改

我尝试过使用invalidateRect:

...
for (int i = 0; i < 10000; i++) {

    pos.x = 600+sin(double(i)/50)*200;
    pos.y = 500+cos(double(i)/50)*200;
    amby[0].x = -10+pos.x;
    amby[0].y = -10+pos.y;
    amby[1].x = -50+pos.x;
    amby[1].y = -50+pos.y;
    amby[2].x = 50+pos.x;
    amby[2].y = -50+pos.y;

    Polygon(hDC_Desktop,amby, 3);
    InvalidateRect(GetDesktopWindow(),NULL, true);
    Sleep(10);
}
...

我想知道是否还有调用WM_ERASEBKGND或WM_DISPLAYCHANGE来强制进行更改。有谁知道是否有办法打电话给这些?

3 个答案:

答案 0 :(得分:2)

我不确定你想要实现的目标。让我回答洋葱效应的问题。擦除前一次迭代中绘制的内容的快速而肮脏的解决方案可能是使用XOR模式绘制,但解决方案有一些缺点,如闪烁和颜色可能是任意的。解决这两个缺点的适当解决方案是在内存DC和BitBlt中完成相同的绘图。

快速而肮脏的解决方案的代码是 -

SetROP2(hDC_Desktop,R2_XORPEN);
//This is just an example of what I am doing

for (int i = 0; i < 100; i++) 
{
    if(i!=0)
    {
        pos.x = 600+sin(double(i-1)/50)*200;
        pos.y = 500+cos(double(i-1)/50)*200;
        amby[0].x = -10+pos.x;
        amby[0].y = -10+pos.y;
        amby[1].x = -50+pos.x;
        amby[1].y = -50+pos.y;
        amby[2].x = 50+pos.x;
        amby[2].y = -50+pos.y;

                    Polygon(hDC_Desktop,amby, 3);
    }

    pos.x = 600+sin(double(i)/50)*200;
    pos.y = 500+cos(double(i)/50)*200;
    amby[0].x = -10+pos.x;
    amby[0].y = -10+pos.y;
    amby[1].x = -50+pos.x;
    amby[1].y = -50+pos.y;
    amby[2].x = 50+pos.x;
    amby[2].y = -50+pos.y;

    Polygon(hDC_Desktop,amby, 3);
    Sleep(10);
}

答案 1 :(得分:1)

有一个简单的解决方案,那就是不在桌面上实际绘制。而是创建一个透明全屏窗口。由于它是透明的,因此您未绘制的任何像素都将显示下方的桌面。因此,只有多边形像素才会隐藏底层桌面。

因此,桌面窗口永远不需要被无效或重新绘制等。

答案 2 :(得分:0)

为什么不使用透明的。

class COverlayWnd : public CWnd
{
    DECLARE_DYNAMIC(COverlayWnd)

public:
    COverlayWnd();
    virtual ~COverlayWnd();

protected:
    afx_msg void OnPaint();
    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
    DECLARE_MESSAGE_MAP()
};

// OverlayWnd.cpp : implementation file
//

实施。如果您希望动画在整个桌面上运行,只需移动窗口即可。

#include "stdafx.h"

// COverlayWnd

IMPLEMENT_DYNAMIC(COverlayWnd, CWnd)

COverlayWnd::COverlayWnd()
{
}

COverlayWnd::~COverlayWnd()
{
}

BEGIN_MESSAGE_MAP(COverlayWnd, CWnd)
    ON_WM_PAINT()
    ON_WM_CREATE()
END_MESSAGE_MAP()


void COverlayWnd::OnPaint()
{
    CPaintDC dc(this);
    CRect rect;
    GetClientRect( &rect );
    dc.FillSolidRect(&rect, RGB(1,1,1));
    //paint other stuff that don't have RGB(1,1,1)

}


int COverlayWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CWnd::OnCreate(lpCreateStruct) == -1)
        return -1;

    BOOL bRet = 0;

    bRet = ModifyStyleEx(0,WS_EX_LAYERED|WS_EX_TRANSPARENT);
    bRet = ModifyStyle(DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU,0);
    bRet = ModifyStyle(WS_POPUP,0);
    bRet = SetLayeredWindowAttributes(RGB(1,1,1),0,LWA_COLORKEY);
    //the RGB(1,1,1) is the transparent color 
    ASSERT(bRet);
    //this->EnableWindow(FALSE);

    return 0;
}