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 に答える