0

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

#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 来强制更改。有谁知道是否有办法调用这些?

4

3 回答 3

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);
}
于 2012-10-30T13:40:29.567 回答
1

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

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

于 2012-10-30T15:40:34.337 回答
0

你为什么不使用透明的wnd。

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;
}
于 2012-10-30T13:05:16.983 回答