子ウィンドウ(コントロールウインドウ?)を常に親ウィンドウの中央に配置したいのですが・・・。 – プログラミング – Home

子ウィンドウ(コントロールウインドウ?...
 
通知
すべてクリア

[解決済] 子ウィンドウ(コントロールウインドウ?)を常に親ウィンドウの中央に配置したいのですが・・・。


リファール
 リファール
(@リファール)
ゲスト
結合: 21年前
投稿: 11
Topic starter  

こんばんわ。
Windowsプログラムを始めたばかりのものです。
WindowsXP, VC++.net, SDKです。

CreateWindow関数でエディットコントロールを20個作りました。
親ウインドウのサイズが変わっても常に親ウインドウの中央に表示したいんです。
 
case WM_PAINT:
 BeginPaint(hWnd, &ps);
  //MessageBox(hWnd,(LPCSTR)前,(LPCSTR)前,MB_YESNO); ---1
  SetEditCenter(hWnd);
 //MessageBox(hWnd,(LPCSTR)後,(LPCSTR)後,MB_YESNO); ---2
 EndPaint(hWnd, &ps);
 break;

void SetEditCenter(HWND hWnd)
{
GetClientRect(hWnd, &rc);
 for(i = 0; i <= 19; i++){
 // ここで20個のエディットコントロールのx, y座標を順番に計算しています。
 SetWindowPos(hEWnd[i], HWND_TOP, x, y, NULL, NULL, SWP_NOSIZE);
 }
}

1と2のメッセージボックスをコメントアウト
プログラム起動
 望み通り中央に配置される
 親ウィンドウのサイズ変更
 エディットコントロールが表示されない ---A
2のみコメントアウト
 プログラム起動時
 メッセージボックス表示
 エディットコントロールが中央へ
 またメッセージボックスが表示される ---B
 親ウィンドウのサイズ変更
 メッセージボックス表示
 エディットコントロールが中央へ
 またメッセージボックス表示 -----------C
1と2両方コメントアウトしない
 2のみコメントアウトの動きの中でエディットコントロールが中央に
 表示された後続けて2回表示される -----D

Aももちろんどうしてだろう?と思うんですが
B, C, Dはさらに混乱しています _ _#

Window作成時などでどこか設定が悪いのでしょうか?
質問の内容が伝わりにくいかもしれませんが
どなたかご教授お願いいたします。


引用未解決
トピックタグ
鷲尾不徳
 鷲尾不徳
(@鷲尾不徳)
ゲスト
結合: 21年前
投稿: 21
 

> case WM_PAINT:
ここが違う。

WM_PAINT でなく WM_SIZE で SetEditCenter(hWnd); を呼ぶ。
SDK ならまず、「よく使う」Windows メッセージを覚えておくといい。


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

エディットウィンドウを動かすタイミングはWM_PAINTじゃなくてWM_SIZEじゃないかな。

WM_PAINT : ウィンドウに再描画領域があると送られる
WM_SIZE : ウィンドウのサイズが変更した時に送られる

あと、void SetEditCenter(HWND hWnd)のxとyって何でしょう?
GetClientRect()で求めた幅と高さからエディットウィンドウの幅と高さを引いて
2で割れば中央に表示する為のの座標が出ます。
それだけです。

エディットウィンドウのサイズを変更しないならDeferWindowPos()等を使った方が
いいかな。

BeginDeferWindowPos()
DeferWindowPos()
EndDeferWindowPos()

の3つを参照してください。


返信引用
PATIO
(@patio)
Famed Member
結合: 4年前
投稿: 2660
 

あと、MessageBoxをWM_PAINT内で読んでしまうと
MessageBoxが表示されていた領域が無効化されて
またWM_PAINTが呼ばれてしまうと思います。

WM_PAINTがどういうときに呼ばれるのかわかっていれば、
WM_PAINTの処理内でMessageBoxを表示すべきでないのはわかると思います。
WM_PAINTの所を通ったことが確認したいのであれば、
TRACEを使ってアウトプットウインドウに表示するようにしてDebugビルドして
IDEから動かしてみた方が良いと思いますよ。


返信引用
リファール
 リファール
(@リファール)
ゲスト
結合: 21年前
投稿: 11
Topic starter  

WM_SIZE で SetEditCenter() を呼んだら一発で解決しました。
お恥ずかしい限りです。

>あと、void SetEditCenter(HWND hWnd)のxとyって何でしょう?
 エディットコントロールを20個作ったのですが
 そのうち10個が120*20 ------A
 後の10個が70*20 -----------B
 なんです。

Aを縦に5個、次の列にBを縦に5個、またA、そしてB
というような感じで配置しました。
 この20個のコントロールがクライアント領域の中央に表示したかったので
 SetEditCenter()で

for(i = 0; i <= 19; i++){
  switch(i){
  case 0:
 case 1:
  case 2:
  case 3:
 case 4:
  x = (rc.right - 400) / 2;
// 400 = 120 + 5(余白) + 70 + 10(余白) + 120 + 5(余白) + 70
 break;
    ・
    ・
    ・
  } 
 switch(i){
  case 0:
 case 5:
 case 10:
 case 15:
 y = (rc.bottom - 120) / 2;
// 120 = 20 + 5(余白) + 20 + 5(余白) + 20 + 5(余白)+ 20 + 5(余白) + 20
 break;
   ・
   ・
   ・
  }
 SetWindowPos(hEWnd[i], HWND_TOP, x, y, NULL, NULL, SWP_NOSIZE);
 }

としていました。
 これだと一つのエディットコントロールの座標を計算しては
 移動、また次のを計算して移動となりますが
 教えていただいた
 BeginDeferWindowPos()
 DeferWindowPos()
 EndDeferWindowPos()
 を使うと先に20個の座標を求めておいてEnd~()で
 一斉に移動ということなんですね。
 大変勉強になりました。ありがとうございます^-^

>TRACEを使ってアウトプットウインドウに表示するようにしてDebugビルドして
>IDEから動かしてみた方が良いと思いますよ。
 ご迷惑でなければもう少し具体的にお教え願えませんか?
 申し訳ありません。

御三方、ご教授ありがとうございました。


返信引用
PATIO
(@patio)
Famed Member
結合: 4年前
投稿: 2660
 

いや、MSDNでTRACEを調べれば一発だと思うんですが。
TRACEは、IDEのアウトプットウインドウにデバッグメッセージを出すための関数です。
ただし、TRACEはDebugモードでビルドしないと動作しないようになっています。
ですから、Debugモードでビルドしてと書いています。
IDEから実行しないとOutputウインドウに出てこないと思ったのでそうかいています。

デバックもに太というフリーソフトがあるのでこれで見てみる手もありますね。

いずれにせよ、WM_PAINT内でMessageBoxを出すのはまずいのでデバッグのやり方を
変えないと駄目です。
MessageBoxを出してやるデバッグ方法も良くやりますけれど、
TPOを考えて使わないとハマリますよ。


返信引用
PATIO
(@patio)
Famed Member
結合: 4年前
投稿: 2660
 

確か、リリースモードでもアウトプットウインドウにメッセージを出すための
関数もあったと思いますが、忘れました。
多分、TRACEも最終的にはこれを呼んでいるんでしょうけれど。


返信引用
isshi
 isshi
(@isshi)
ゲスト
結合: 21年前
投稿: 41
 

すでに「解決」となっていますが。

>確か、リリースモードでもアウトプットウインドウにメッセージを出すための
>関数もあったと思いますが、忘れました。
OutputDebugString ですね。

TRACE は MFC でしか使えません(多分)。


返信引用
リファール
 リファール
(@リファール)
ゲスト
結合: 21年前
投稿: 11
Topic starter  

>TRACE は MFC でしか使えません(多分)。
 ヘルプで検索してみましたが .(ドット)が出てきて
 よく分かりませんでした。

OutputDebugString で文字列を出力するのは出来ました。
今までデバックというものを全く知らないというか
使わなかったのですが変数の中身に何が入っているかが
分かって感動的でした。(大げさかもしれませんが・・・)

これからはメッセージボックスはやめて
デバックモードで実行しますね!!

色々と勉強させていただきありがとうございました。
質問というより 感想のようになってしまって申し訳ありません。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

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