アニメーションするデスクトップアクセサリみたいなものを作ろうとしています。
しかし、SetWindowRgn()関数をうまく動作させる事が出来ないので質問させてください。
現在、
CRgn* _pRgns;
CBitmap* _pBitmap;
をメンバ変数として用意し、あらかじめビットマップの形をしたリージョンをフレーム枚数だけ_pRgnsに配列として作成しています。
onTimer() 関数内で、フレーム位置をインクリメントし、該当フレーム番号のビットマップとリージョンを適用後、描画させています。
この方法でアニメーションをさせた場合、ループ再生にしなければ問題なく動作するのですが、二回目のループになった時に、リージョンを再度SetWindowRgn()関数で設定すると失敗してしまいます。
(戻り値として0が帰ってきます。)
SetWindowRgn()関数の使い方がまずいのでしょうか。
ご存知の方おられましたら、教えていただけますでしょうか?
よろしくお願いします。
void TestAppDlg::OnTimer(UINT nIDEvent)
{
CString mes;
_frameNo++;
if ( _frameNo > 5 ) _frameNo = 0; // フレーム位置を先頭に戻す。
// ビットマップを選択
_pMemDC->SelectObject( _pBitmap + _frameNo );
// 非矩形ウィンドウの設定
int ret = SetWindowRgn( *(_pRgns + _frameNo), true );
if ( ret == 0 ){
// リージョンの設定に失敗
stopTimer();
}
// 描画
drawScene() ;
CDialog::OnTimer(nIDEvent);
}
開発環境:
Windows XP Professional SP1
Microsoft Visual C++ .NET
No.2ベストアンサー
- 回答日時:
重要なことを思い出しました。
おそらく、アニメーションの一巡目までは正常終了ということなので次の理由でしょう。
SetWindowRgn()は成功すると引数で指定されたリージョンは、Windowsによって管理が行われるようになります。
#これにより、ウィンドウに設定したリージョンは破棄が不要となります。
そのため、何度も同じリージョンを使いまわして設定しようとしても、2回目以降は失敗します。
これを避けるには、SetWindowRgn()を呼ぶ前に、リージョンをコピーし、配列に入っているリージョンではなく、コピーしたリージョンをパラメータに設定する必要があります。
No.1
- 回答日時:
第2引数はBOOL型なので、trueではなくTRUEを指定してください。
また、CWnd::SetWindowRgn()は内部でAPIを呼び出しているだけなので、NT系のOSならGetLastError()で詳細エラーを取得して調べてみてください。
あと怪しそうなのは、リージョンの作成方法ですかね。
コードがかかれていないのでわかりませんが。
この回答への補足
回答ありがとうございます。
早速、ご指摘いただいた箇所を改めました。
以下のコードを追加し、取得できたエラー文字列は、
『この操作を正しく終了しました。』でした。
ちなみに、エラーコード自身は0です。
// 非矩形ウィンドウの設定
int ret = SetWindowRgn( *(_pRgns + _frameNo), TRUE );
if ( ret == 0 ){
FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, GetLastError(), 0,
ErrorMes, 1024, NULL);
// リージョンの設定に失敗
stopTimer();
}
リージョンの作成部分ですが、以下のような処理を行っています。
bool TestAppDlg::createRgn()
{
unsigned char r, g, b;
unsigned char* buff;
COLORREF WHITE = RGB( 255, 255, 255 );
_pRgns = new CRgn[ BITMAP_NUM ];
if ( _pRgns == NULL ) return false;
int bitSize = IMAGE_WIDHT * IMAGE_HEIGHT * 4;
buff = new unsigned char[ bitSize ];
// フレーム数分、リージョンを作成する。
for ( int i=0; i<BITMAP_NUM; i++ ){
memset( buff, '\0', sizeof(buff) );
(_pBitmap + i)->GetBitmapBits( bitSize, buff );
(_pRgns + i)->CreateRectRgn( 0, 0, 0, 0 );
for( int y = 0; y < IMAGE_HEIGHT; y++ ){
for( int x = 0; x < IMAGE_WIDHT; x++ ){
int inx = (y * IMAGE_WIDHT) + x;
COLORREF color = RGB(buff[ 4*inx ], buff[ 4*inx+1 ], buff[ 4*inx+2 ] );
if ( color != WHITE ){
CRgn rgn;
rgn.CreateRectRgn( x, y, x + 1, y + 1 );
(_pRgns + i)->CombineRgn( (_pRgns + i), &rgn, RGN_OR );
}
}
}
}
delete[] buff ;
return true ;
}
以上、何かお気づきの点がございましたらご教示ください。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- 画像編集・動画編集・音楽編集 動画をディスク作成すると画像が乱れる。 4 2022/06/24 07:49
- 大学・短大 C言語線形リストの問題です 3 2022/12/22 00:45
- JavaScript カラーミーショップのsectionループ内で、[引数][戻り値]ありの関数的な処理を行いたいです。 1 2022/05/07 19:39
- Visual Basic(VBA) エクセルマクロでアニメを作る方法を教えてください。 1 2023/02/07 14:27
- その他(IT・Webサービス) ホームページにカウント数を表示する 2 2022/10/28 10:37
- C言語・C++・C# 【C++】IDirect3DSurfaceのディープコピーは可能ですか? 1 2022/07/06 02:47
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
- Visual Basic(VBA) 3つのプロシージャをまとめたら実行時エラー発生で対応不能 6 2022/05/17 01:47
- Java Java 南京錠 2 2023/02/04 11:46
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
コンテキスト依存とは?
-
[Active Basic]BitBltで画像を表示
-
SetWindowRgn()関数について。
-
メモリデバイスコンテキスト&...
-
GetPixelに使うHDCの作り方
-
Active Basic 再描写処理
-
些細な質問ですが、よろしくお...
-
PlgBltでの透過
-
エクセルで作った新しいウイン...
-
グラフの交点の求め方(Excel)
-
「アイテムは収集されました」...
-
フォントの大きさ
-
コンボボックス内の文字サイズ変更
-
検索の画面がでなくなってしま...
-
エクセルである点からの距離で...
-
作成したウインドウのサイズを...
-
エクセルのコントロールツール...
-
スピンボタンを右クリックして...
-
3次元空間上の2つの座標から...
-
VBAのフォント変更(エクセルか...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
コンテキスト依存とは?
-
画像処理 ビットマップ ダブ...
-
画面がチカチカする
-
BeginPaintの使い方
-
VC++のTextOutの再描画の仕方
-
BitBlt関数について教えてください
-
GetDC()とCreateCompatibleDC()
-
VBでFD、USBの有効・無効...
-
領域を塗りつぶしたい
-
ダブルバッファの作り方
-
ダイアログにビットマップを貼...
-
Rectangleで、リソースが解放さ...
-
GetPixelに使うHDCの作り方
-
デバイスコンテキストに関して2...
-
メモリデバイスコンテキストを...
-
画面のちらつきについて
-
WinAPIでスクリーン画像を映し...
-
VC++でBitmapとText文字を表示...
-
SetWindowRgn()関数について。
-
丸いボタンの表示でCPU100%
おすすめ情報