2

// 背景は飛ばして構いません

Windows デスクトップの背景用にアニメーション時計を作成しています。基本的に、事前に描画された画像(時計の数字)を使用してコードでbmp画像を作成し、bmp画像を保存してデスクトップの背景をその画像に設定します。c# と .Net を使用してみましたが、デスクトップの背景を設定するには、WinApi 関数 (SystemParametersInfo) を呼び出す必要があります。C# からこの関数を呼び出すには、ほぼ 1 秒かかります。アニメにしては長すぎる。

したがって、C++ を除いて同じことを行いたいと考えています。アンマネージ コードからの SystemParametersInfo の呼び出しが高速になることを願っています。編集:c# を使用して bmp を作成し、c++ を使用してデスクトップの背景を設定しましたが、高速です

//質問

Visual Studio 2012 を使用して Win32 コンソール プロジェクトを作成し、事前に描画された画像をリソースとして埋め込むことができました。次に、画像を 1 つのビットマップに結合し、hdd に保存する必要があります。最後に C++ でプログラミングしてから 4 年が経過しているため、画像を描画して保存する方法がわかりません。

グーグルで見つけたコードはすべて、画面にペイントする必要がありますが、これは明らかにやりたくないことです。

では、ビットマップを作成し、その上にリソース イメージ (ビットマップも) を描画し、すべて c++ で保存するにはどうすればよいでしょうか。

ご協力ありがとうございます。

4

2 に答える 2

0

この質問は、C++ よりも Windows API に関するものです。Windows API を使用する場合は、GDI+ を参照してください。

http://msdn.microsoft.com/en-us/library/windows/desktop/ms533798.aspx

.NET Framework は GDI+ をラップするため、手動のメモリ管理などを行う C# ではなく、C++ だけでクラスに慣れているかもしれません。

画像を操作できるライブラリは他にもいくつかあります。個人的には、多くの言語バインディングを備えた C スタイルの画像操作ライブラリである GD が好きです。

https://bitbucket.org/libgd/gd-libgd/downloads

ただし、オープンソースの場合はいつものように、依存関係と一緒に自分でビルドする必要があります。したがって、おそらく GDI+ が最適です。

于 2013-08-17T08:24:19.643 に答える
0

結局のところ、Win32 (c++) コードはデスクトップの背景をすばやく変更できます (i5 3.2 GHz では 20 ミリ秒未満)。マネージ C# コードは 500 から 3000 ミリ秒かかります。ただし、アンマネージ C++ コードでは、イメージの描画に時間がかかります (300 ~ 1500 ミリ秒)。そこで私がしたことは、連携して動作する 2 つのプログラムを作成することでした。マネージ C# プログラムは、イメージを作成し (20 ミリ秒未満)、保存します。アンマネージ C++ は、保存されたイメージをデスクトップの背景として設定します。

C# static void Main(string[] args) { //手動で計算されハード コードされた画像の位置 //最初の画像の位置 //X:532 //Y:335 Bitmap TheImage = new Bitmap(1366, 768);

        Graphics G = Graphics.FromImage(TheImage);

        DateTime DTNow = DateTime.Now;
        while (true)
        {
            //get the time 
            DTNow = DateTime.Now;
            //draw the canvas
            G.DrawImage(Resources.canvas, 0, 0,1366,768);

            //draw the first image of the hour
            G.DrawImage(GetImage(DTNow.Hour,0),532,330,174,217);
            //draw the second image of the hour
            G.DrawImage(GetImage(DTNow.Hour, 1), 711, 330, 174, 217);
            //draw the colon
            if (DTNow.Second % 2 == 0) G.DrawImage(Resources.aColon, 890, 365,57,147);
            //draw the first digit of the minute
            G.DrawImage(GetImage(DTNow.Minute, 0), 952, 330, 174, 217);
            //draw the second digit of the minute
            G.DrawImage(GetImage(DTNow.Minute, 1), 1131, 330, 174, 217);
            //save the file
            try
            {
                File.Delete("C:\\background.bmp");

                TheImage.Save("C:\\background.bmp", ImageFormat.Bmp);
            }
            catch
            {
            }
            //calculate sleep time and sleep until next second

            DTNow = DateTime.Now.AddSeconds(1);
            DateTime NextSecond = new DateTime(DTNow.Year,DTNow.Month,DTNow.Day, DTNow.Hour,DTNow.Minute, DTNow.Second,500);
            DTNow = DateTime.Now;
      System.Threading.Thread.Sleep((int)NextSecond.Subtract(DTNow).TotalMilliseconds);

        }

    }
    static Bitmap GetImage(int Number, int Index)
    {
        string NS = Number.ToString();
        if (NS.Length < 2) NS = "0" + NS;
        char[] digits = NS.ToCharArray();

        switch (digits[Index])
        {
            case '1': { return Resources.a1; } 
            case '2': { return Resources.a2; }
            case '3': { return Resources.a3; } 
            case '4': { return Resources.a4; } 
            case '5': { return Resources.a5; } 
            case '6': { return Resources.a6;} 
            case '7': { return Resources.a7;} 
            case '8': { return Resources.a8;} 
            case '9': { return Resources.a9; } 
            default: { return Resources.a0; } 
        }
    }
}

c++ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, char*, int nShowCmd) { while(true){ SystemParametersInfo(SPI_SETDESKWALLPAPER,0, L"C:\background.bmp", SPIF_UPDATEINIFILE); int MS = (int)(((long)floor((long)clock()/(long)CLOCKS_PER_SEC)*1000l+1000l)-((long)clock()));

if(MS<=1000 && MS>0){
std::this_thread::sleep_for(std::chrono::milliseconds(MS));
}
else
{

}

}
return 0;

}

于 2013-08-28T11:23:55.807 に答える