windows — C ++ быстро обновляет рабочий стол

Я пытаюсь сделать программу, которая выводит многоугольник на рабочий стол для простой анимации. Проблема, с которой я сейчас сталкиваюсь, заключается в том, что анимация получает «луковый» эффект, потому что рабочий стол не обновляется. Я искал способ обновления рабочего стола, однако, поскольку это анимация, ни одно из решений не может обновить его достаточно быстро. Ниже приведен пример моего кода:

#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 для принудительного изменения. Кто-нибудь знает, есть ли способ назвать это?

0

Решение

Я не уверен, что вы пытаетесь достичь. Позвольте мне просто ответить на проблему с эффектом лука. Быстрое и грязное решение для удаления того, что было нарисовано в предыдущей итерации, могло бы состоять в рисовании с использованием режима 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);
}
2

Другие решения

Есть простое решение, и оно не на самом деле рисовать на рабочем столе. Вместо этого создайте прозрачный полноэкранное окно. Поскольку он прозрачный, любой пиксель, который вы не рисуете, будет показывать рабочий стол внизу. Следовательно, только ваши пиксели многоугольника будут скрывать основной рабочий стол.

В результате окно рабочего стола никогда не должно быть аннулировано или перекрашено и т. Д.

1

Почему бы тебе не использовать прозрачный 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;
}
0