ピクチャーコントロール(CStatic)のフレームの色を変えたい – プログラミング – Home

ピクチャーコントロール(CStatic...
 
通知
すべてクリア

ピクチャーコントロール(CStatic)のフレームの色を変えたい


AIBO
 AIBO
(@AIBO)
ゲスト
結合: 18年前
投稿: 6
Topic starter  

環境はWinXP SP2、VC++6 SP6です。
ダイアログベースでピクチャーコントロールを貼り付けて、ピクチャープロパティのタイ
プ「フレーム」、色「黒」としています。フレームの色を赤へ変更したいのですが、やり
方がわかりません。

スタティックテキストの色変更を参考にして、OnCtlColorのなかで
if (pWnd->m_hWnd == m_CStaticFrame.m_hWnd) {
 return ::CreateSolidBrush(RGB(255,0,0));
}
としましたがダメでした。

よろしくお願いします。


引用解決済
トピックタグ
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

 僕もいろいろやってみましたが、だめでした。

 1. サイズを正確に設定する。
 2. タイプをビットマップに変更する。
 3. 自分で赤いフレームを描く。

 が一番手っ取り早い方法だと思います。
 
 すんなりいく方法があればどなたかお願いします。


返信引用
AIBO
 AIBO
(@AIBO)
ゲスト
結合: 18年前
投稿: 6
Topic starter  

ITO さま
赤いフレームを描いたビットマップをSetBitmapするということでしょうか。。。

HBITMAP hBitmap;
CString strFileName(赤い枠のBMP.bmp);
hBitmap = (HBITMAP)LoadImage(NULL, (LPCTSTR)strFileName, IMAGE_BITMAP, 0, 0,
LR_LOADFROMFILE);
m_CStatic1.SetBitmap(hBitmap);


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

CWnd* myWnd = GetDlgItem(ピクチャーコントロールのID);
とすれば、CWndが得られます。
CWndが得られればGetDC でCDCを得て、MoveTo,LineTo等で枠を描けば
いいと思いますが...
あと、ReleaseDCでCDCを解放するのを忘れずに。


返信引用
AIBO
 AIBO
(@AIBO)
ゲスト
結合: 18年前
投稿: 6
Topic starter  

ITO さま

ビットマップを貼るのではなかったですね。←いくらなんでも。

ご教授いただいた方法で、思いどおりのフレームが描けました。
ありがとうございます。

複数のフレームがほしいので、
CStaticの派生クラスCStaticExを作ってOnpaintの中に次のように書きました。

-----------------------------------------------------------
RECT rStatic1;
GetWindowRect(&rStatic1);
ScreenToClient(&rStatic1);

HDC hDC = ::GetDC( m_hWnd );

HPEN hPen, hPrevPen;
hPen = CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
hPrevPen = (HPEN)SelectObject(hDC, hPen);

MoveToEx(hDC, rStatic1.left, rStatic1.top, NULL);
LineTo(hDC, rStatic1.right, rStatic1.top);
MoveToEx(hDC, rStatic1.right, rStatic1.top, NULL);
LineTo(hDC, rStatic1.right, rStatic1.bottom);
MoveToEx(hDC, rStatic1.right, rStatic1.bottom, NULL);
LineTo(hDC, rStatic1.left, rStatic1.bottom);
MoveToEx(hDC, rStatic1.left, rStatic1.bottom, NULL);
LineTo(hDC, rStatic1.left, rStatic1.top);

SelectObject(hDC, hPrevPen);
DeleteObject(hPen );
::ReleaseDC(m_hWnd, hDC);
-----------------------------------------------------------

これで解決しました。


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

OnPaintならCPaintDCを使うべきなんじゃないかな。
(BeginPaint~EndPaintが自動的に呼ばれるし)

ただ、派生クラスのOnPaintをオーバーライドしちゃうと、不便かも。
(Bitmapを設定しても表示されないとか。)
親クラスのOnPantで十分な気もする。

else
{
CPaintDC dc(this);
CPen pen( PS_SOLID, 1, RGB( 255, 0, 0 ) ), *oldPen;

CRect rc;
CWnd* pWnd = this->GetDlgItem( IDC_STATIC1 );

pWnd->GetWindowRect( &rc );
this->ScreenToClient( &rc );
// 調整
rc.left--; rc.top--;

oldPen = dc.SelectObject( &pen );

dc.MoveTo( rc.left, rc.top );
dc.LineTo( rc.right, rc.top );
dc.LineTo( rc.right, rc.bottom );
dc.LineTo( rc.left, rc.bottom );
dc.LineTo( rc.left, rc.top );

dc.SelectObject( oldPen );

CDialog::OnPaint();
}


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

> dc.MoveTo( rc.left, rc.top );
> dc.LineTo( rc.right, rc.top );
> dc.LineTo( rc.right, rc.bottom );
> dc.LineTo( rc.left, rc.bottom );
> dc.LineTo( rc.left, rc.top );
透明ブラシを使って、Rectangleメソッドを使うほうが普通かも。

CBrush brush, *oldBrush;
brush.CreateStockObject( NULL_BRUSH );

//

dc.Rectangle( &rc );

//

dc.SelectObject( oldBrush );

CPen,CBrushはメンバ変数にしたほうがベターですかね。


返信引用
AIBO
 AIBO
(@AIBO)
ゲスト
結合: 18年前
投稿: 6
Topic starter  

Blue さま

ありがとうございます。
今手元に開発環境がないので月曜に確認させていただきます。

後出しで申し訳ありませんが、やりたいことは、
ビットマップ画像(大きさがいろいろで大きい場合は縦100*横100に収まるよう
に縦横比を保ったまま調整)を表示して、その周囲に赤い枠(縦100*横100の画
像に枠が隠れないよう大きく調整して)を描く。
画像が複数あるので、子画面に画像を表示し、子画面は親でスクロールさせる。
スクロールで中途半端に隠れるときにもうまく枠が描けるから(ダイアログに直接描く
とスクロールで隠れた部分を描画しないようにするのが面倒)、ピクチャーコントロー
ルのフレームを使いました。

私の「2006/11/17(金) 18:17:42」では、
ピクチャーコントロールのタイプをフレームにしてMoveToEx、LineToで線を描きまし
た。ビットマップはSetBitmapではなく親のOnPaintで描画させました。
これで思い通りのことができたので「解決」にしたのですが、CPaintDCやRectangleを使
うべきという、よりよい方法をご提示いただきありがとうございます。

毎回Moveto、LineToしなくてもよかったことも初めて知りました。
> dc.MoveTo( rc.left, rc.top );
> dc.LineTo( rc.right, rc.top );
> dc.LineTo( rc.right, rc.bottom );
> dc.LineTo( rc.left, rc.bottom );
> dc.LineTo( rc.left, rc.top );


返信引用
AIBO
 AIBO
(@AIBO)
ゲスト
結合: 18年前
投稿: 6
Topic starter  

親クラスのOnPantで試してみました。

else
{
CPaintDC dc(this); // 描画用のデバイス コンテキスト

CPen pen( PS_SOLID, 1, RGB( 255, 0, 0 ) ), *oldPen;
oldPen = dc.SelectObject( &pen );

CBrush brush, *oldBrush;
brush.CreateStockObject( NULL_BRUSH );
oldBrush = (CBrush*)dc.SelectObject(brush);

CRect rc;
pWnd->GetWindowRect( &rc );
this->ScreenToClient( &rc );
// 調整
// rc.left--; rc.top--;

dc.Rectangle( &rc );

dc.SelectObject( oldPen );
dc.SelectObject( oldBrush );

ReleaseDC(&dc);

CDialog::OnPaint();
}

これで赤い枠が描けるのですが、「調整」しないと基の位置からずれたのと、その上に元
の黒い枠が上書きされます(ブレークポイントを入れて見ました)。解決方法がわからず
ヤモヤが晴れません。。。
派生クラスのOnPaintの方では、「調整」しなくてもピタリと基の位置に枠が描け、黒い
枠で上書きされることもありませんでしたので、いまはこちらを使っています。

> CPen,CBrushはメンバ変数にしたほうがベターですかね。
はい、メンバ変数で書くように変更します。


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

> これで赤い枠が描けるのですが、「調整」しないと基の位置からずれたのと、その上
>に元の黒い枠が上書きされます(ブレークポイントを入れて見ました)。解決方法がわ
>からずヤモヤが晴れません。。。
一応、その方法は、
> 2. タイプをビットマップに変更する。
という大前提ですので、「フレーム」のままだと
>元の黒い枠が上書きされます
という動きになるのでしょう。


返信引用
AIBO
 AIBO
(@AIBO)
ゲスト
結合: 18年前
投稿: 6
Topic starter  

Blue さま

> 2. タイプをビットマップに変更する。
でしたね。ありがとうございます。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました