子ウィンドウダイアログにビットマップボタンを貼り付け方法

[戻る]
万年係長 2004/09/28(火) 15:46:47
VC++ 6.0 MFC Windows2000 

子ウィンドウダイアログにビットマップボタンを貼り付けようと試みています。
親ウィンドウにはビットマップボタンが貼りつくのですが、
子ウィンドウに貼り付けると本来bmpを貼り付けようとする位置からずれてしまいます。
親ダイアログの位置をずらすと子ウィンドウのbmpボタン位置がずれてしまうようです。
pWndを変更してみたのですが、うまくいきませんでした。(下)
    CWnd *pWnd;    //
    pWnd=GetTopWindow();    //CWndに属している最初の子ウィンドウを返す

どなたかご教授おねがいします。

ソースは以下のとおりです
定義
#define Bmp_Width 298
#define Bmp_Height 310

#define posisionX 10
#define posisionY 270

初期化です。
BOOL CDllDialog_1::OnInitDialog() 
{
    CDialog::OnInitDialog();
    // TODO: この位置に初期化の補足処理を追加してください
//親ウィンドウダイアログは以下3行を書かずに正常にbmp貼り付け完了
    CWnd *pWnd;    //
    pWnd=GetTopWindow();    //CWndに属している最初の子ウィンドウを返す
//    pWnd=AfxGetMainWnd();    //親ウィンドウのハンドルを取得する
//AZ,ZAボタンにBMPを貼り付ける-----------------------------------------------
    // 元ボタンの位置、サイズを取得
    CButton *AZ,*ZA;
    AZ=(CButton *)pWnd->GetDlgItem(IDC_AZ);
    ZA=(CButton *)pWnd->GetDlgItem(IDC_ZA);
    RECT binfo1,binfo1_1;
    

    AZ->GetClientRect( &binfo1 );
    ZA->GetClientRect( &binfo1_1 );
    int AZWidth = binfo1.right;
    int AZHeight = binfo1.bottom;

    int ZAWidth = binfo1_1.right;
    int ZAHeight = binfo1_1.bottom;


    CRect binfo2,binfo2_2;

    pWnd->GetDlgItem(IDC_AZ)->GetWindowRect(&binfo2);
    pWnd->GetDlgItem(IDC_ZA)->GetWindowRect(&binfo2_2);

    int iX = binfo2.left;
    int iY = binfo2.top - AZHeight;
    int ZAX = binfo2_2.left;
    int ZAY = binfo2_2.top - ZAHeight;

    // 元ボタン上にビットマップを貼り付けて、
    m_IMAGE_AZBUTTON.Create
("IDC_AZ",BS_OWNERDRAW|WS_VISIBLE|WS_CHILD,CRect
(iX,iY,iX+AZWidth,iY+AZHeight),this,IDC_AZ);
    m_IMAGE_AZBUTTON.LoadBitmaps(IDB_SORT_AZ_UP,IDB_SORT_AZ_DW);

    m_IMAGE_ZABUTTON.Create
("IDC_ZA",BS_OWNERDRAW|WS_VISIBLE|WS_CHILD,CRect
(ZAX,ZAY,ZAX+ZAWidth,ZAY+ZAHeight),this,IDC_ZA);
    m_IMAGE_ZABUTTON.LoadBitmaps(IDB_SORT_ZA_UP,IDB_SORT_ZA_DW);

    // 元ボタンは見えなくする。
    AZ->ShowWindow( SW_HIDE );
    ZA->ShowWindow( SW_HIDE );

//AZ,ZAボタンにBMPを貼り付ける終了-----------------------------------------------
------省略
}

monkey 2004/09/28(火) 16:34:08
・GetWindowRectで取得できる矩形領域は,当該ウィンドウのスクリーン座標系(画面左
上を(0,0)とする)
・GetClientRectで取得できる矩形領域は,当該ウィンドウのクライアント座標系(ウィ
ンドウのクライアントエリアの左上を(0,0)とする)
・Create関数の第4引数に指定する矩形領域は,第5引数に指定する親ウィンドウのク
ライアント座標系

これらの整合がとれていないためと思われます。

monkey 2004/09/28(火) 16:47:21
ちょっと分かりにくいので、書き直します。

・GetWindowRectで取得できる矩形領域は,スクリーン座標系(画面左上を(0,0)とす
る)による当該ウィンドウの位置とサイズ

・GetClientRectで取得できる矩形領域は,当該ウィンドウのクライアント座標系(クラ
イアントエリアの左上を(0,0)とする)による当該ウィンドウのクライアントエリアの位
置とサイズ(top, leftは0になる)

・Create関数の第4引数に指定する矩形領域は,第5引数に指定する親ウィンドウのク
ライアント座標系

これらの整合がとれていないためと思われます。
ScreenToClient,ClientToScreen関数も調べて下さい。

万年係長 2004/09/28(火) 16:56:39
monkeyお返事ありがとうございます。

つまり、create関数の第4引数と第5引数が
誤っているということですか?

monkey 2004/09/28(火) 17:13:06
"m_IMAGE_AZBUTTON"、"m_IMAGE_ZABUTTON"で表されるコントロールは、どのウィンドウ
を親として、どの位置・サイズで作成したいのでしょうか。

万年係長 2004/09/28(火) 17:24:25
説明不足でした。
bmp貼り付けボタンのダイアログはDLLで作成しています。
EXEダイアログ(親ウィンドウダイアログ)からボタンを押して、
DLLを呼び出し子ウィンドウダイアログにbmpを貼り付けるという仕様です。

"m_IMAGE_AZBUTTON"、"m_IMAGE_ZABUTTON"はDLL側に記述しています。

class AFX_EXT_CLASS CDllDialog_1 : public CDialog
{
public:
    CBitmapButton m_IMAGE_AZBUTTON;        // AZ用ビットマップボタン
    CBitmapButton m_IMAGE_ZABUTTON;        // ZA用ビットマップボタン
-----
}

monkey 2004/09/28(火) 17:38:43
IDC_AZ,IDC_ZAで識別されるコントロールは、CDllDialog_1の子でしょうか?
であれば、↓で良いと思います。

BOOL CDllDialog_1::OnInitDialog() 
{
    ...

    CWnd* pAZ = GetDlgItem( IDC_AZ );
    CRect rect;
    pAZ->GetWindowRect( &rect );

    ScreenToClient( &rect );

    m_IMAGE_AZBUTTON.Create( 略, 略, rect, this, 略 );
    m_IMAGE_AZBUTTON.LoadBitmap( 略 );

    ...
}

万年係長 2004/09/28(火) 18:19:28
IDC_AZ,IDC_ZAで識別されるコントロールは、CDllDialog_1の子です。
上の方法でやってみましたが、
親ダイアログの位置をずらすと子ウィンドウのbmpボタン位置がずれてしまうようです。

他の個所に問題がないかチェックしてみます。

万年係長 2004/09/28(火) 18:24:57
[[解決]]
上の方法で無事解決しました。
作成したdllファイルをexeダイアログのdebugに挿入するの忘れてました。
monkeyさんありがとうございました。

BOOL CDllDialog_1::OnInitDialog() 
{
    CDialog::OnInitDialog();

    // TODO: この位置に初期化の補足処理を追加してください

    CWnd* pAZ = GetDlgItem(IDC_AZ);
    CWnd* pZA = GetDlgItem(IDC_ZA);
    CRect rect,rect1;

    pAZ->GetWindowRect(&rect);
    pZA->GetWindowRect(&rect1);

    ScreenToClient(&rect);
    ScreenToClient(&rect1);

    // 元ボタン上にビットマップを貼り付けて、
    m_IMAGE_AZBUTTON.Create
("IDC_AZ",BS_OWNERDRAW|WS_VISIBLE|WS_CHILD,rect,this,IDC_AZ);
    m_IMAGE_AZBUTTON.LoadBitmaps(IDB_SORT_AZ_UP,IDB_SORT_AZ_DW);

    m_IMAGE_ZABUTTON.Create
("IDC_ZA",BS_OWNERDRAW|WS_VISIBLE|WS_CHILD,rect1,this,IDC_ZA);
    m_IMAGE_ZABUTTON.LoadBitmaps(IDB_SORT_ZA_UP,IDB_SORT_ZA_DW);

------省略-------
}

古いスレッドには追加発言できません。