何度も何度もスクリーンセーバーについて質問させてもらっているスーです。
悲しいかな、今回も自分の力では解決できそうにないので皆さんの力を貸してください。
WindowsAPIを使ってスクリーンセーバーを作っています。
デスクトップ画面を表示しながら、複数のベジュ曲線を描写するというものです。
そのベジュ曲線は残像?を表示しながら画面内を跳ね返ります。
ここまではできたのですが、スクリーンセーバーを起動してから一定時間でベジュ曲線だけが消えてしまいます。
消える時間も表示するベジュ曲線の数によって変わります。
ベジュ曲線*3 残像は0本 線の合計は3本 はおよそ90秒後に
ベジュ曲線*3 残像は4本 線の合計は15本 はおよそ10秒後に
ベジュ曲線*3 残像は9本 線の合計は30本 はおよそ5秒後に消えてしまいます。
この現象の原因が分かる方がいましたら、是非教えてください。
よろしくお願いします。
環境
VC++2005
WindowsXP
添付ファイルにスクリーンセーバーを入れようと思ったら容量オーバーでした;;
http://www1.axfc.net/uploader/He/so/217943
こちらに本体をアップしました。パスワードは「suu」です。
以下ソースです。
//------------------------------------------- // main.cpp //------------------------------------------- #include <windows.h> #include <scrnsave.h> #include <time.h> //ベジュ曲線の数 #define LINE 3 //ペンの作成 LOGPEN RedPen; //ベジュ曲線のヘッダー #include "BezierCurve.h" //スクリーンセーバを作るためのライブラリ #pragma comment(lib,"ScrnSave.lib") #pragma comment(lib,"Comctl32.lib") //タイマーのID #define ID_TIMER 32767 //ウインドの縦、横幅 int wx,wy; /*ハンドルコンテキスト*/ //ダブルバッファ用 HDC backhdc; //デスクトップ画面用 HDC DeskBmphdc; //メインハンドル RECT rc; HDC hdc; //デスクトップ画面をDeskBmphdcに保存する void GetDeskTop(){ HDC Deskhdc; HBITMAP DeskBmp; // 画面のデバイスコンテキスト取得 Deskhdc = CreateDCA("DISPLAY",NULL,NULL,NULL); // /ビットマップ作成 DeskBmp = CreateCompatibleBitmap(Deskhdc,wx,wy); // ビットマップ描画用デバイスコンテキスト作成 DeskBmphdc = CreateCompatibleDC(Deskhdc); // デバイスコンテキストにビットマップを設定 SelectObject(DeskBmphdc, DeskBmp); // 画面上の領域をビットマップに描く BitBlt(DeskBmphdc, 0, 0, wx, wy, Deskhdc, 0, 0, SRCCOPY); //解放 ReleaseDC(NULL,Deskhdc); DeleteObject(DeskBmp); } //仮想的な裏画面を作る HDC Back_Init_Surface(HWND hwnd){ HDC hdc,BackDC; HBITMAP hBackBMP; //今の画面を取得 hdc = GetDC(hwnd); //仮想的なHDCの作成 BackDC = CreateCompatibleDC(hdc); //ビットマップ作成 hBackBMP = CreateCompatibleBitmap(hdc,wx,wy); //hBackBMPとBackDCの設定 SelectObject(BackDC,hBackBMP); //画面初期化 PatBlt(BackDC,0,0,wx,wy,BLACKNESS); //解放 DeleteObject(hBackBMP); ReleaseDC(hwnd,hdc); return BackDC; } LRESULT WINAPI ScreenSaverProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){ //乱数の初期化 srand((unsigned)time(NULL)); //ベジュ曲線を三つ作る static BezierCurve bez[LINE]; switch(msg){ //画面を消さない case WM_ERASEBKGND: return true; case WM_CREATE: //ウインドの縦、横幅所得 GetClientRect(hWnd,&rc); wx = rc.right-rc.left; wy = rc.bottom-rc.top; //デスクトップ画面所得 GetDeskTop(); //裏画面作成 backhdc = Back_Init_Surface(hWnd); //ペンの設定 RedPen.lopnStyle = PS_SOLID; RedPen.lopnWidth.x = 2; //ベジュ曲線初期設定の for(int i=0;i<LINE;i++) bez.Set(wx,wy); //タイマーのセット SetTimer(hWnd,ID_TIMER,8,NULL); break; case WM_TIMER: //画面初期化とデスクトップ画面描写 BitBlt(backhdc, 0, 0, wx, wy, DeskBmphdc, 0, 0, SRCCOPY); // 今の画面を取得 hdc = GetDC(hWnd); //ベジュ曲線の描写と移動等 for(int i=0;i<LINE;i++){ bez.Draw(backhdc); bez.Action(); } //もう描写しませんよ~ ReleaseDC(hWnd,hdc); //ダブルバッファ 裏画面にあるものを表画面に書く BitBlt(hdc,0,0,wx,wy,backhdc,0,0,SRCCOPY); break; case WM_DESTROY: //いろいろ解放 KillTimer(hWnd,ID_TIMER); ReleaseDC(hWnd,backhdc); ReleaseDC(hWnd,hdc); ReleaseDC(hWnd,DeskBmphdc); PostQuitMessage(0); return 0; default: break; } return DefScreenSaverProc(hWnd, msg, wParam, lParam); } //設定画面 まだ作れていない BOOL WINAPI ScreenSaverConfigureDialog(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam){ return TRUE; } BOOL WINAPI RegisterDialogClasses(HANDLE hInst){ return TRUE; }