ダイアログのプロシージャからメインウィンドウの子コントロールを作成するには?

解決


ごま  2004-03-21 08:51:16  No: 53333  IP: [192.*.*.*]

超初心者の質問ですみません
色々試してみたんですができなかったので教えてください  おねがいします
(実際はすごく基本的なことのような気がするんですけどわかりませんでした;;)
メインウィンドウが所有しているダイアログから
GetParent関数でメインウィンドウのハンドルを受け取り
CreateWindowを使って
メインウィンドウのコントロールを作ろうとしているんですが
このようにしてもできません

//ダイアログのプロシージャ内

Dhwnd=GetParent(hwnd);

CreateWindow(TEXT("BUTTON"),TEXT("MAIN"),
        WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON ,
        10,300,30,100,
        Dhwnd,NULL,(HINSTANCE)GetWindowLong(Dhwnd,GWL_HINSTANCE),NULL
        );

これではプログラムが何の反応もしてくれませんT T
WindowParentでちゃんとメインウィンドウのハンドルを取得できて
いないんでしょうか


この文をメインウィンドウプロシージャのメッセージ処理部分(WM_CREATE)に
そのままコピぺしてCreateWindow()引数の親ウィンドウハンドルをhwndに
インスタンスハンドルを取得する為のGetWindowLongの引数もhwndに変えて
実行するとボタンコントロールは普通に作成されているのですが・・

自分ひとりでは解決できませんでした  おねがいしますm(_ _)m

編集    削除
ごま  2004-03-21 08:52:44  No: 53334  IP: [192.*.*.*]

関係ないと思うのですが
開発環境は
Visual c++6.0
WindowsXPです
Win32APIで作りました

よろしくおねがいしますです

編集    削除
n  2004-03-21 19:52:01  No: 53335  IP: [192.*.*.*]

ダイアログが親を持っていないとか、
または同じIDを持つボタンが既にあるとかでは。

編集    削除
SELNA  URL  2004-03-21 20:46:18  No: 53336  IP: [192.*.*.*]

>これではプログラムが何の反応もしてくれませんT T
>WindowParentでちゃんとメインウィンドウのハンドルを取得できて
>いないんでしょうか

親ウィンドウのハンドルが正しいハンドルかどうか調べればよいと思います。
調べ方はIsWindow関数でできます。
あるいはデバッグ用に親ウィンドウハンドルをグローバル宣言した変数に格納し、それとチェックするとか、そのハンドルを使ってダイアログプロシージャ内でボタンを作成してみるとか試してみましょう。

編集    削除
ごま  2004-03-22 07:04:49  No: 53337  IP: [192.*.*.*]

こんにちわ!SELNAさん  nさんありがとうございます
IsWindow関数を調べて  使ってチェックしてみましたところ・・

//ダイアログプロシージャ内

Dhwnd=GetParent(hwnd);
  if(!(IsWindow(Dhwnd)))MessageBox(hwnd,TEXT("有効じゃないみたいね"),TEXT("失敗"),MB_OK);
    else MessageBox(hwnd,TEXT("有効みたいね  じゃあなんで?"),TEXT("有効じゃん"),MB_OK);



案の定  ”有効じゃないみたいね”と言われてしまいました
IsWindow関数の解説をしてくれていたサイトに

「IsWindow()はウィンドウがなければFALSE、すなわち0が返るのですが、ウィンドウがあるときはTRUEが返るとは限らないのです。単に0以外としかなってません。」

とかいてあったので10回くらい試してみましたが
やっぱり有効じゃないみたいでした
ということはnさんの言うとおり
ダイアログが親を持ってないっていうなんでしょうか・・

ダイアログはリソーススクリプトで記述して
メインウインドウプロシージャのWM_CREATEを処理する部分で

CreateDialog(
        (HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE),
        TEXT("TOUROKU"),hwnd,DialogProc
        );
として作成していたんですが
もしかしてこれじゃメインウィンドウの子ウィンドウとして
作成されたことにならないのでしょうか
だとしたらGetParentで自らの親ウィンドウのハンドルを
受け取ろうとしても空振りですよね・・

編集    削除
ごま  2004-03-22 07:10:11  No: 53338  IP: [192.*.*.*]

ああっ
ちなみにCreateDialogの第二引数TOUROKUは
リソーススクリプトで定義したダイアログのIDです^^;

編集    削除
シャノン  2004-03-22 07:14:36  No: 53339  IP: [192.*.*.*]

>「IsWindow()はウィンドウがなければFALSE、すなわち0が返るのですが、ウィンドウがあるときはTRUEが返るとは限らないのです。単に0以外としかなってません。」

その通りです。つまり
if( IsWindow( Dhwnd ) == TRUE )
はダメですが、
if( IsWindow( Dhwnd ) != FALSE )
はOKなのです。

で、
>if( ! ( IsWindow( Dhwnd ) ) )
これは
if( IsWindow( Dhwnd ) != FALSE )
これと同じ意味ですので

>10回くらい試してみましたが
1回でよかったりします

編集    削除
シャノン  2004-03-22 07:18:42  No: 53340  IP: [192.*.*.*]

CreateWindow の第9引数。
これはトップレベルウィンドウの場合はメニューのハンドルですが、子ウィンドウの場合はコントロール ID です。

>CreateWindow(TEXT("BUTTON"),TEXT("MAIN"),
>                WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON ,
>                10,300,30,100,
>                Dhwnd,NULL,(HINSTANCE)GetWindowLong(Dhwnd,GWL_HINSTANCE),NULL
>                );

NULL = 0 って有効な ID だっけ?

編集    削除
SELNA  URL  2004-03-22 07:49:03  No: 53341  IP: [192.*.*.*]

>CreateDialog(
>                (HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE),
>                TEXT("TOUROKU"),hwnd,DialogProc
>                );
>として作成していたんですが
>もしかしてこれじゃメインウィンドウの子ウィンドウとして
>作成されたことにならないのでしょうか
>だとしたらGetParentで自らの親ウィンドウのハンドルを
>受け取ろうとしても空振りですよね・・

CreateDialogの第3引数は親ウィンドウのハンドルです。
即ち、この場合ダイアログには親ウィンドウが指定されていることになります。
ダイアログハンドルからGetParentで取得しても有効なウィンドウハンドルが返るはずです。
この時有効なハンドルが返らないとすれば、

①すでに親ウィンドウが破棄されている。
②CreateDialogでダイアログ作成時の第3引数が有効でないハンドルが指定されている。

とゆうことが考えられると思います。

全体的なソースがわからないのでこの辺りしか私にはわかりません。

編集    削除
SELNA  URL  2004-03-22 08:00:48  No: 53342  IP: [192.*.*.*]

>NULL = 0 って有効な ID だっけ?

子ウィンドウ(ボタン)を作成することはできますが、何らかのアクション(WM_COMMAND)が発生したときに上手く処理できないかもしれません。

無難に100、101、…とか重複しないように指定するのが普通だと思います…。

編集    削除
ごま  2004-03-22 08:55:50  No: 53343  IP: [192.*.*.*]

CreateDialogの前で同じように

if(!(IsWindow(hwnd)))MessageBox(hwnd,TEXT("有効じゃないみたいね"),TEXT("失敗"),MB_OK);
    else MessageBox(hwnd,TEXT("有効みたいね  じゃあなんで?"),TEXT("有効じゃん"),MB_OK);
      hdlg = CreateDialog(
        (HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE),
        TEXT("TOUROKU"),hwnd,DialogProc
        );
としてみましたが
どうも有効みたいなので
GetParentで取得することを一度見送って
またまた新しく知ったFindWindowで取得してみました




//ダイアログのプロシージャ内

Dhwnd=GetParent(hwnd);
    hdc=GetDC(Dhwnd);
    GetTextMetrics(hdc,&tm);
    ReleaseDC(Dhwnd,hdc);
  if(!(IsWindow(Dhwnd)))MessageBox(hwnd,TEXT("有効じゃないみたいね"),TEXT("失敗"),MB_OK);
    else MessageBox(hwnd,TEXT("有効みたいね  じゃあなんで?"),TEXT("有効じゃん"),MB_OK);

    Dhwnd=FindWindow(TEXT("JISAKU"),TEXT("JISAKUWINDOW"));

    if(!(IsWindow(Dhwnd)))MessageBox(hwnd,TEXT("有効じゃないみたいね"),TEXT("失敗"),MB_OK);
    else MessageBox(hwnd,TEXT("有効みたいね  じゃあなんで?"),TEXT("有効じゃん"),MB_OK);



こうして実行してみたところ
はじめのハンドルは”有効ではない”
FindWindowで取得したハンドルは”有効”でした。
そしてボタンを作ることが出来ました
やはりSELNAさんが言うとおり一部分の問題ではなく
ほかの気づきにくいところに問題があるんでしょうかTT
もうちょっと頑張ってソースと睨み合ってみます
超初心者のダラダラ長いソースを丸投げは悪いですし
(というよりタブーでしょうか^^;)
解決ボタンはちょっとまだチェックしないで投稿させてください
できるだけ早く見つけようと思うのでごめんなさい
アドバイスありましたらよろしくおねがいします

編集    削除
ごま  2004-03-22 09:34:16  No: 53344  IP: [192.*.*.*]

GetParentは失敗すると0を返すということを知ったので


if(!(Dhwnd=GetParent(hwnd)))MessageBox(hwnd,TEXT("関数失敗\nハンドル取得できません"),TEXT("GetParent"),MB_OK);


こうしてみました
メッセージボックスは出てきました

編集    削除
ごま  2004-03-22 22:44:42  No: 53345  IP: [192.*.*.*]

本来の子コントロールの作成は達成できましたし
FindWindowでも支障きたすことなく作れるので
やはり解決しましたということで
新しい疑問がわいてきたのでまた質問させてください
解決へ導いてくださったみなさんありがとうございました^^

編集    削除