• 締切済み

チャイルドダイアログの最前面表示

現在、MDIフレーム上に、複数のチャイルドスタイルのダイアログが存在するプログラムを改造中です。 その中にMapDKIVの地図を描画しているダイアログがあり、その地図上に縮尺スケールのビットマップを描画しようとしています。(MapDKIVには、その機能がまだ無い為) 縮尺スケールのビットマップを描画する為のダイアログを同様にチャイルドスタイルにし、SetWindowPos()を使って最前面に表示しようとしましたが、地図を描画しているダイアログをクリックすると、後ろへ行ってしまいます。 MSDNのSetWindowPos()の説明には、 「子ウィンドウ、ポップアップウィンドウ、またはトップレベルウィンドウのサイズ、位置、および Z オーダーを変更します。」 と記述されています。 が、あるサイトでは、 「MDI子Formは、子Windowであって、TopLevelWindowではないのですから、SetWindowPosは最前面や最背面設定を受け入れません。」 と記述されています。 縮尺スケールのビットマップを描画する為のダイアログを通常のスタイルにし、「フォアグランド表示する」とすると、メインフレームのサイズを小さくしたり、移動した時に、その場所へ取り残されてしまいます。 何か、方法はないものでしょうか? 開発環境 VisualC++ 6.0 SP6 どなたかお助け下さい!よろしくお願いします。

みんなの回答

  • phoenix343
  • ベストアンサー率15% (296/1946)
回答No.1

> 縮尺スケールのビットマップを描画する為のダイアログを通常のスタイルにし、「フォアグランド表示する」とすると、メインフレームのサイズを小さくしたり、移動した時に、その場所へ取り残されてしまいます。 ここにヒントがある ハンドラを使え。 サイズ変更および移動のメッセージが飛んできたところで、そのダイアログを取り残されないようにするんだ。

関連するQ&A

  • 地図の上にL字スケールを描画

    MDIフレーム上に、複数のチャイルドスタイルのダイアログが存在するプログラムを改造しました。(元は別の人間が作成) その中にMapDKIVの地図を描画しているダイアログがあり、その地図上に別のダイアログをおき、そこに縮尺L字スケールのビットマップを描画しました。(MapDKIVには、その機能がまだ無い為) 色々と試行錯誤した結果、この方法を取ったのですが、納品した矢先、お客様から、地図をマウスでドラッグして動かそうとすると、スムーズに動いたり、カクカクとしか動かなかったり、時には全く動かない事があるとのクレームがありました。(その操作以外は正常に動作している模様) 以前はこの症状はなかったとの事から、今回のL字スケール描画に原因があるのではと調べていますが、原因が見付かりません。 以下に、ソースの一部分を記載しますので、どなたか助言をお願いします。 ******** ビットマップデータ管理クラス ******** ビットマップは、スケール毎に準備 <BitmapData.h> private: CBitmap m_bmpLScale0; CBitmap m_bmpLScale2; <BitmapData.cpp> //-------- 機能 ビットマップ情報の読込 -------- void CBitmapData::Load(void) { m_bmpLScale0.LoadBitmap(IDB_BITMAP_SCALE0); // 全国図 m_bmpLScale2.LoadBitmap(IDB_BITMAP_SCALE2); // 1/160万 //-------- 機能 ビットマップ情報の取得 -------- CBitmap& CBitmapData::GetScaleBitmap(void) { UINT unIndex = GetScaleNumber();// 現在選択されているスケールレベル switch(unIndex) { case 0:  return m_bmpLScale0; break; // 全国図 case 2:  return m_bmpLScale2; break; // 1/160万 ******** 地図描画ダイアログ ******** L字スケール描画用ダイアログの生成 <MainMap.cpp> // 地図描画フレームサイズを取得 m_ctrlMapFrame.GetWindowRect(LPRECT(rect)); // スケールレベルをセット g_BitmapData.SetScaleNumber(m_ctrlMapZoom.GetPos()); // スケール描画用ダイアログの生成(地図フレームの左下位置を渡す) m_pMapScaleDlg = new CMapScaleDlg(); m_pMapScaleDlg->Create(m_hWnd, IDD_MAP_SCALE_DIALOG, ・・・ ******** L字スケール描画ダイアログ ******** //-------- 機能 OnInitDialog() -------- // ウインドウ拡張スタイルをレイヤード設定 lStyle = GetWindowLong( this->m_hWnd, GWL_EXSTYLE ); lStyle |= 0x00080000; SetWindowLong( this->m_hWnd, GWL_EXSTYLE, lStyle ); // レイヤードウィンドウの不透明度と透明のカラーキーを設定(青色部分を透明化する) SetLayeredWindowAttributes( this->m_hWnd, RGB(0,0,255), 100, 0x00001/*LWA_COLORKEY*/ ); //-------- 機能 OnPaint() -------- BITMAP bitmap; CBitmap& mBitmap = g_BitmapData.GetScaleBitmap(); mBitmap.GetBitmap(&bitmap); CSize sz(bitmap.bmWidth, bitmap.bmHeight); CDC dc; dc.CreateCompatibleDC(&PaintDC); CBitmap *pOld = dc.SelectObject(&mBitmap); // もともとのディバイスコンテキストにビットマップを透過で転送(青色部分を透明化する) if( ::TransparentBlt(PaintDC, 0, 0, sz.cx, sz.cy, dc, 0, 0, sz.cx, sz.cy, (UINT)RGB(0,0,255)) == FALSE ){ } // ビットマップ選択解除 dc.SelectObject( pOld); } //-------- 機能 スケール(ビットマップ)変更メッセージを受信 -------- // 現在選択されているスケール用のビットマップを取得(ポインタ) CBitmap& mBitmap = g_BitmapData.GetScaleBitmap(); mBitmap.GetBitmap(&bitmap); CSize sz(bitmap.bmWidth, bitmap.bmHeight); // メインマップダイアログの地図フレームの左下になるよう変更 this->MoveWindow(m_nMapFrameLeft, (m_nMapFrameBottom - sz.cy), sz.cx, sz.cy); // ウインドウの再描画 this->Invalidate(); 1.L字スケール描画用のダイアログを、背景青色で準備 2.L字スケール描画用のダイアログの青色部分を透明化に設定 3.L字スケール描画用のダイアログのウインドウサイズを、選択されているスケール用のビットマップと同じサイズに、且つ、地図フレームの左下に位置を設定 4.地図ダイアログからスケール変更メッセージを受信  (1) その時に選択されているスケール用のビットマップと同じサイズに、且つ、地図フレームの左下に位置を設定  (2) ウインドウの再描画 this->Invalidate() 5.OnPaint()  (1) 現在選択されているスケールのビットマップ情報を取得  (2) ビットマップを透過で転送(青色部分を透明化)    ビットマップのL字以外の部分は青色 以上、文字数制限の為、かなり省略していますが、大変困っています。 とにかく助言を頂きたく、よろしくお願いします。

  • ダイアログ最前面表示時の後ろの画面操作について

    はじめまして。 お世話になります。 開発環境:WindowsXP VC++6.0 MFC使用 ダイアログベースで画面を作成(A.exe CDialogベース)し、その画面でボタンを押下し 子画面(A_Child)を表示させます。表示方法はDoModal()で。 そのA_ChildはCDialogベースです。 A_Childダイアログが表示されている間(最前面)は、デスクトップ上の操作を 何も出来ない様にしたいのですが、方法はありますでしょうか? (例:スタート→ログオフでダイアログが表示しますよね。 その時ってそのダイアログ以外は触れないですよね。) せめて、自分たちが作成したアプリだけでも操作不可能にしたいのです。 SetWindowPos()、ModifyStyle()、色々試しましたが上手くいきません。 DoModalで表示させるのがそもそもまちがいののでしょうか? 何か方法が有りましたらよろしくお願いします。 説明が下手ですみません。

  • MDIでのダイアログ生成

    VC++2005でMDIアプリケーションを作成しています。 ダイアログベースでは、DoModal()にてダイアログを生成していましたが、 MDIでのダイアログ生成の方法が分かりません。。 調べた結果、 (1)CreateWindow()にてクライアントウィンドウを作成 (2)CreateMDIWindow()にて子ウィンドウを作成 の順序で処理を行うことは分かりましたが、 関数の一部の引数に何を設定してやれば良いのかが不明です。。 ※下記はネット上にあったサンプルソースです。  「???」の箇所が不明な引数です。 (1) CreateWindow(   TEXT("MDICLIENT"), //MDICLIENT は固定です   NULL,   WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN,   0, 0, 0, 0,   hWnd,       //メインウィンドウのハンドル←???   (HMENU)1,    //←???   hInst,       //インスタンスハンドル←???   (LPSTR)&ccs    //CLIENTCREATESTRUCT構造体のポインタ←???  ); (2) HWND CreateMDIWindow(  MDI_CHILD ,   //ウィンドウクラス名  TITLE ,     //ウィンドウのタイトルバーテキスト  0 ,       //ウィンドウスタイル。WS_MAXIMIZE(最大化表示)など  CW_USEDEFAULT , //X座標  CW_USEDEFAULT , //Y座標  CW_USEDEFAULT , //幅  CW_USEDEFAULT , //高さ  hClientWindow , //クライアントウィンドウのハンドル ←???  hIns ,      //インスタンスハンドル       ←???  0        //アプリケーション定義の値 ); なお、行いたい処理の流れとしては、 CTestDialogクラスより、CTest2Dialogクラスのダイアログを、 呼び出したいのです。 うまく説明できず申し訳ありませんが、 お詳しい方おられましたら、具体例など交えてご説明頂けると幸いです。 お手数ですが、どうか宜しくお願い致します。

  • EXCELの最前面設定解除について

    こんにちは。 VBでFindWindow関数を使用してEXCELのハンドルを取得し、SetWindowPos関数で 最前面に設定しているのですがEXCEL標準のダイアログボックスを開いたり (オプション設定や列幅設定等)、タイトルバーをダブルクリックしたり最大化 ボタンを押下して画面最大にしその後画面を元に戻した後、他のウィンドウが 上位に来たりして最前面設定が消えていました。 これはなぜでしょうか?この現象が起こらない(何をしても常に最前面)ように するにはどうすればよいでしょうか? 長くなりましたがどうか宜しくお願いします。

  • チャイルドダイアログボックスでマウスクリックが効かない

    チャイルドウィンドウタイプのモードレスダイアログを表示すると  マウスでエディットボックス(など)をクリックしてもフォーカスが移動しない という現象がおきています。(tabキーではOK) 数年前に一度作ったときの記憶を頼りに作っているのですが、下記以外に設定などが必要になるのでしょうか? …というか、このやり方で問題ないのでしょうか?… ◎環境 WindowsXP Visual C++ 6.0 & MFC アプリケーションの種類…SDI ◎やったこと 1.ダイアログリソースを追加 リソースのプロパティ  「一般」タブ   ID…「IDD_DIALOGA」  「スタイル」タブ   スタイル…チャイルド   境界線…ダイアログ枠   その他…すべてoff  「その他のスタイル」タブ   可視のみon  「拡張スタイル」、「その他の拡張スタイル」タブ   すべてoff  このダイアログにいくつかのボタンやエディットボックスを配置 2.親windowのヘッダファイルに追加したもの private: dialogA *pDlg; 3.親windowのソースファイルに追加したもの BOOL CModlessDialogApp::InitInstance() にコードを追加 …… // フレームをリソースからロードして作成します pFrame->LoadFrame(IDR_MAINFRAME, WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, NULL, NULL); //↓↓ここから追加↓↓ pDlg = NULL; pDlg = new dialogA(); if(pDlg) { pDlg->Create(IDD_DIALOGA); pDlg->ShowWindow(SW_SHOWNA /*SW_SHOW|SW_RESTORE*/); } //↑↑ここまで追加↑↑ // メイン ウィンドウが初期化されたので、表示と更新を行います。 pFrame->ShowWindow(SW_SHOW); pFrame->UpdateWindow(); …… スタイルを「オーバーラップ」「ポップアップ」にするとマウスクリックでフォーカスが移動します。

  • ダイアログボックスで指定したサイズどおり表示されない

    ダイアログボックスで指定したサイズがメイン上では約2倍の大きさになって表示されてしまい、困っています。 メニューリソースは以下のとおりです。 MYDLG DIALOG DISCARDABLE 25, 50, 100, 150 STYLE WS_VISIBLE | WS_CHILD | DS_CONTROL CAPTION "Dialog" FONT 9, "MS Pゴシック" BEGIN END WndProc内にダイアログを貼り付けています。 if(hDlgWnd) break; hDlgWnd = CreateDialog((HINSTANCE)GetWindowLong(hWnd,GWL_HINSTANCE),"MYDLG",hWnd,DialogProc); それが実際にウィンドウを開くとダイアログがだいたいですが(50,115,200,340)のように表示されてしまいます。 VC++ Ver.6.0です。コンパイラ等の問題でしょうか。 ご存知の方、宜しくお願いします。

  • ダイアログボックスについて。

    ダイアログボックスについての質問です。 開発環境はVisual C++ 2005.netでありSDKを利用しています。 ダイアログボックスにPicture Controlを貼り付け、Combo Boxの内容が変わるたびにそのPicture Controlに画像を表示するようなプログラムを作りたいと考えています。 自分が考える手順としてはまずPicture Controlについてサブクラス化を行い、親のダイアログボックスが表示されると同時にPicture ControlのプロシージャでWM_CREATEメッセージを受け取り描画を行う。 そして親のダイアログボックスに貼り付けたCombo Boxの内容が変更された場合に、Picture ControlのウィンドウハンドルにむけてWM_PAINTメッセージを送信する。 こんな手順で行いたいのですが、少し不安な部分が出てきました。 Combo Boxの内容が変更され、Picture Controlのウィンドウハンドルに向けてWM_PAINTメッセージを送信し、Picture ControlプロシージャではWM_PAINTメッセージがきたとき画像の描画を行う場合、このプロシージャではどの画像を描画してよいか不明です。 そのため何番の画像の表示命令が来たのかを示すために、親のダイアログボックスに貼り付けたCombo Boxが変更された場合、Picture Controlに向けてWM_PAINTメッセージと表示画像番号をパラメータとして送信したいのです。 もちろんグローバル変数を用意すれば簡単なのですが、できるだけ使用しないように記述をしたいのです。そこで考えたのが、 SendMessage(GetDlgItem(hDlgWnd, IDC_PICTURE), WM_PAINT, 0, MAKELPARAM(0, number)); このようにnumberをLPARAMの下位ワードとして送信しようと考えました。 このメッセージ送信を行い、Picture ControlプロシージャでWM_PAINTメッセージが到着したとき、LOWORD(lparam)からnumberを取り出す。 実現したい目的のため、このような方法を考えましたが、エラーなく実行できるでしょうか? もしあやしい部分が見つかった場合はアドバイスをお願いします。そしてこの方法よりも簡単に処理できる方法があれば教えていただきたいです。 自分としてはサブクラス化は面倒なので、Picture Controlをオーナードローとして扱う方法も考えましたが、うまく動きませんでしたTT

  • MFC - ダイアログボックスのPictureControlへの画像表示

    はじめまして。 現在MFCにおいて、ダイアログ形式のアプリケーションを作成しています。環境はVisual Studio 2005になります。 内容はWebカメラからのキャプチャを行い、そのキャプチャされた画像をダイアログ上に配置したPictureControlへ表示するというものです。 キャプチャされた画像は、1チャネルのグレースケールでありunsigned char型の1次元配列で格納されています。よってビットマップとして表示するには自身で構造体BITMAPINFOを作成しなければなりません。現状以下のように作成したのですが、うまく表示されません。 画像サイズは 320×240 です。 PictureControlのIDを IDC_BITMAP と設定し、 画素情報が格納されている配列を m_pbit とします。 int i; CWnd *pWnd = GetDlgItem( IDC_BITMAP ); CDC *Capt = pWnd->GetDC(); BITMAPINFO bmif; bmif.bmiHeader.biBitCount   =8; bmif.bmiHeader.biClrImportant =0; bmif.bmiHeader.biClrUsed    =256; bmif.bmiHeader.biCompression  =0; bmif.bmiHeader.biHeight     =240; bmif.bmiHeader.biPlanes     =1; bmif.bmiHeader.biSize      =sizeof(BITMAPINFOHEADER); bmif.bmiHeader.biSizeImage   =320*240; bmif.bmiHeader.biWidth     =320; bmif.bmiHeader.biXPelsPerMeter =0; bmif.bmiHeader.biYPelsPerMeter =0; for(i=0; i<256; i++){  bmif.bmiColors[i].rgbBlue = i;  bmif.bmiColors[i].rgbGreen = i;  bmif.bmiColors[i].rgbRed  = i;  bmif.bmiColors[i].rgbReserved = 0; } SetDIBitsToDevice(Capt->m_hDC, 0, 0, 320, 240, 0, 0, 0, 240, m_pbit, &bmif, DIB_RGB_COLORS); グレースケール画像なので配列bmiColorsは全て同色としました。 また、PictureControlのTypeをオーナ描画など全てのTypeを試しましたが、表示されませんでした。 必ずPictureControlに描画しなければならないという決まりはないのですが、ダイアログボックスにビットマップを表示するにはPictureControlだと考え、それに表示するようプログラムを組みました。 画素情報(グレースケールの輝度情報)のみ既知である状態からビットマップをダイアログに表示するためには他に方法があるのでしょうか? 上記のプログラムにおける間違い、またその他の方法についてアドバイスを頂けたらと思います。 よろしくお願いいたします。

  • ダイアログの結果が反映されません…

    はじめまして。 現在、VB2005で画像を使った簡単な距離計測プログラムを製作しています。 そのプログラムの中で、 "2点を指示して、その長さと画像の実際の長さの対比で縮尺・倍率を取得する"ようにしたいのですが、 ダイアログを開いてそこに画像の長さを記述しても、その結果が反映されませんでした。 結果を反映されるようにするにはどうしたらよいのでしょうか。 どなたかよろしくお願いします。 以下が目的のコードの一部になります。 g.DrawLine(Pens.Red, e.X, e.Y, Rs, Rr) "二点間の直線を指示 Dialog2.Show() "ダイアログを表示する "ここから下の結果が反映されない If Dialog2.DialogResult = Windows.Forms.DialogResult.OK Then KYY = Val(Dialog2.textky.Text) "ダイアログのテキストの数字を関数に代入 TextB.Text = KYY "数値を実際に表示

  • AutoLoad()関数の使い方がわかりません。

    VC++6.0 WindowsXPです。 ダイアログベースで作っていますが、ダイアログのボタンをビットマップで表示しようとしてます。 現在のやり方としては 1.ダイアログのスタイルは「オーナー描画」「ビットマップ」にチェックする。 2.リソースに貼り付けたいビットマップ画像を4枚挿入し、ビットマップのIDは対象のボタンのキャプションを「IMAGE」だとすると末尾に「U」「D」「F]「X」をつけたID、つまり「IMAGEU」「IMAGED」、、とする。 3.ダイアログのクラス(xxxDlg)の中で CBitmapButton bitmap1; のようにCBitmapButton型のオブジェクトを作る。 3.xxx::OnInitDialog()の中で bitmap1.AutoLoad(IDIMAGE,this); を追加する。 以上です。コンパイル自体はエラー、警告なしでできました。しかし実行するとエラーがおきます。 エラーの内容は 「例外 unknown software exception (0x8000003)がアプリケーションの0x77f767cdで発生しました。」 となります。 どこが間違いなのかわかりません。 よろしくお願いします。

専門家に質問してみよう