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

解決


ごま  2004-03-21 08:51:16  No: 53333

超初心者の質問ですみません
色々試してみたんですができなかったので教えてください  おねがいします
(実際はすごく基本的なことのような気がするんですけどわかりませんでした;;)
メインウィンドウが所有しているダイアログから
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

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

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


n  2004-03-21 19:52:01  No: 53335

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


SELNA  URL  2004-03-21 20:46:18  No: 53336

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

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


ごま  2004-03-22 07:04:49  No: 53337

こんにちわ!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

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


シャノン  2004-03-22 07:14:36  No: 53339

>「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

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

>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

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

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

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


ごま  2004-03-22 08:55:50  No: 53343

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

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

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

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


ごま  2004-03-22 22:44:42  No: 53345

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


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加