MDIウインドウについて

ActiveBasicでのプログラミングでわからないこと、困ったことなどがあったら、ここで質問してみましょう(質問を行う場合は、過去ログやWeb上であらかじめ問題を整理するようにしましょう☆)。
返信する
メッセージ
作成者
今年は受験生

MDIウインドウについて

#1 投稿記事 by 今年は受験生 »

ABは初心者のほう(Ver3あたりから使ってたが、あまりいじってない)です。

では本題に。

コード: 全て選択


'-----------------------------------------------------------------------------
'  イベント プロシージャ
'-----------------------------------------------------------------------------
' このファイルには、ウィンドウ [MainWnd] に関するイベントをコーディングします。
' ウィンドウ ハンドル: hMainWnd

' TODO: この位置にグローバルな変数、構造体、定数、関数を定義します。

Declare Function DefFrameProc Lib "user32" Alias "DefFrameProcA"(hWnd As DWord, hWndMDIClient As DWord, uMsg As DWord, wParam As DWord, lParam As DWord) As DWord
Declare Function CreateMDIWindow Lib "user32" Alias "CreateMDIWindowA"(lpClassName As BytePtr,lpWindowName As BytePtr,dwStyle As DWord,X As Long,Y As Long,nWidth As Long,nHeight As Long,hWndParent As HWND,hInstance As HINSTANCE,lParam As LPARAM) As HWND


Dim hClient As DWord
Dim hStatusWnd As DWord
Dim StatusHight As DWord
Dim rect As RECT

Type CLIENTCREATESTRUCT
    hWindowMenu As DWord
    idFirstChild As DWord
End Type

Const ID_STATUS = 71

'-----------------------------------------------------------------------------
' ウィンドウメッセージを処理するためのコールバック関数

Function MainWndProc(hWnd As HWND, dwMsg As DWord, wParam As WPARAM, lParam As LPARAM) As DWord
	' TODO: この位置にウィンドウメッセージを処理するためのコードを記述します。

	' イベントプロシージャの呼び出しを行います。
	MainWndProc=EventCall_MainWnd(hWnd,dwMsg,wParam,lParam)
End Function


'-----------------------------------------------------------------------------
' ここから下は、イベントプロシージャを記述するための領域になります。

Sub MainWnd_Destroy()
	DestroyWindow(hClient)
	Client_DestroyObjects()
	PostQuitMessage(0)
End Sub

Sub MainWnd_Create(ByRef CreateStruct As CREATESTRUCT)
	Dim ccs As CLIENTCREATESTRUCT

    Dim Statusbar_Sizes[2] As Long

	Dim lpdwp As DWord
	Dim lpdfp As DWord

	'Clientウィンドウを作成
	ccs.hWindowMenu=GetSubMenu(GetMenu(hMainWnd),1)
	ccs.idFirstChild=2000
	hClient = CreateWindowEx(0,"MDICLIENT",NULL, _
				WS_CHILD or WS_VISIBLE or WS_CLIPCHILDREN or _
				WS_HSCROLL or WS_VSCROLL, _
				0,0,0,0, _
				hMainWnd, CreateStruct.hMenu, GetModuleHandle(0),VarPtr(ccs))
	'If hClient Then
	'	MessageBox(hMainWnd,"Client OK!"+Str$(hClient),"",MB_OK)
	'End If


    'ステータスバーを作成
    hStatusWnd = CreateStatusWindow(WS_CHILD or WS_VISIBLE or CCS_BOTTOM or SBARS_SIZEGRIP, _
        NULL, hMainWnd, ID_STATUS)

    'ステータスバーサイズ(横幅)を設定
    Statusbar_Sizes[0]=500
    Statusbar_Sizes[1]=200
    Statusbar_Sizes[2]= -1
    SendMessage(hStatusWnd,SB_SETPARTS,3,Statusbar_Sizes)

	Dim mdic As MDICREATESTRUCT
	mdic.szClass = hright
	mdic.szTitle = "title"
	mdic.x = mdic.y = mdic.cx = mdic.cy = CW_USEDEFAULT
	mdic.style = mdic.lParam = 0
	SendMessage(hClient,WM_MDICREATE , 0 , mdic.lParam)

End Sub

Sub MainWnd_Resize(SizeType As Long, cx As Integer, cy As Integer)
	Dim buf[20] As Byte

	'ステータスバーの大きさを取得
	GetWindowRect(hStatusWnd,rect)
	StatusHight=rect.bottom-rect.top

	'Client Window のサイズ調整
	MoveWindow(hClient,0,0,cx,cy-StatusHight,TRUE)
    'ステータスバーにサイズ変更情報を送る
    SendMessage(hStatusWnd,WM_SIZE,cx,cy)
End Sub

ここまで、ActiveBasicFanさんのと、プラスしてやってたんですがどうしても、子ウインドウが出ません。
どうしてでしょうか?教えてください!

一応、私が役立てているサイトを載せておきます。私が役立てているサイト

-----------------------
AB Ver 4.24
7
記事: 473
登録日時: 2005年5月31日(火) 18:51
お住まい: 新潟県
連絡する:

Re: MDIウインドウについて

#2 投稿記事 by 7 »

codeをhideで挟むとスッキリしますよ。
ページが横長になっちゃってて読み辛いです...。

> ここまで、ActiveBasicFanさんのと、プラスしてやってたんですがどうしても、子ウインドウが出ません。
> どうしてでしょうか?教えてください!
>
> 一応、私が役立てているサイトを載せておきます。私が役立てているサイト
役立てているサイトを読むと分かりますが、子ウィンドウを作るにはCreateMDIWindow()関数を使います。
今年は受験生さんのコードを見てみるとCreateMDIWindow()関数が呼ばれてるような記述がどこにも見当たらないので、子ウィンドウが出ないのは普通だと思います。

それとも、クライアントウィンドウが出なくて困ってるんでしょうか?

どうでもいいことですが、僕も受験生みたいなことをしていて毎日情報カードと戦ってます...。
お互い遊んでばかりじゃなく勉強も頑張りましょうね。
今年は受験生

Re: MDIウインドウについて

#3 投稿記事 by 今年は受験生 »

> codeをhideで挟むとスッキリしますよ。
> ページが横長になっちゃってて読み辛いです...。
>
すみません。知りませんでした・・・
>私が役立てているサイト
> 役立てているサイトを読むと分かりますが、子ウィンドウを作るにはCreateMDIWindow()関数を使います。
> 今年は受験生さんのコードを見てみるとCreateMDIWindow()関数が呼ばれてるような記述がどこにも見当たらないので、子ウィンドウが出ないのは普通だと思います。
ここでは、上のやり方で行われているではないでしょうか。
CreateMDIWindow()関数はいろいろ設定をしてからじゃないと使えないそうなので・・・
出来れば、こっちをまとめて関数化したいと思っています。
よくわからなかったので、こっちのやり方にしたのですが違反が起きてしまいます。
> それとも、クライアントウィンドウが出なくて困ってるんでしょうか?
>
そうです。
> どうでもいいことですが、僕も受験生みたいなことをしていて毎日情報カードと戦ってます...。
> お互い遊んでばかりじゃなく勉強も頑張りましょうね。
がんばりましょうo(^▽^)o
ゲスト

Re: MDIウインドウについて

#4 投稿記事 by ゲスト »

ここでは、上のやり方で行われているではないでしょうか。

すみません。こっちです。間違えました。
7
記事: 473
登録日時: 2005年5月31日(火) 18:51
お住まい: 新潟県
連絡する:

#5 投稿記事 by 7 »

いまなんとかやろうとしてるんですが、面倒なので今日はここら辺で辞めます。

とりあえずMDIウィンドウをなんとかしようとしている所です。
7
記事: 473
登録日時: 2005年5月31日(火) 18:51
お住まい: 新潟県
連絡する:

#6 投稿記事 by 7 »

見事にプロジェクトをMDI化(?)することができました。
ちゃんと WM_MDICREATE メッセージで子ウィンドウを作ってます。

まずMDIを作るにあたってしなければならないこと。
  • 1.ABが作ってくれるウィンドウをMDIのフレームウィンドウに仕立てあげる
    2.するとウィンドウメッセージを拾わなくなるので自分で処理する必要がある
こんな感じです。
この後、僕の分からない問題のある部分はイグトランスさんがフォローしてくれると思います。(他人任せ)

とりあえず的なプロジェクトを置いていくのでどうぞ参考にしてください。
http://dev.activebasic.com/nana/software/MDI.zip

僕が参考にしたページも紹介、いつも通り猫プロさん。
第83章 MDIの基礎
今年は受験生

ありがとうございます!!

#7 投稿記事 by 今年は受験生 »

やりたいことはできたのですが、 MDIウインドウ上でのCreateWindowEx() などの関数の親ウインドウには、なにを指定すればいいのでしょうか?

hMainWnd や hClient を指定しても出ません。
教えてください!!
7
記事: 473
登録日時: 2005年5月31日(火) 18:51
お住まい: 新潟県
連絡する:

Re: ありがとうございます!!

#8 投稿記事 by 7 »

> やりたいことはできたのですが、 MDIウインドウ上でのCreateWindowEx() などの関数の親ウインドウには、なにを指定すればいいのでしょうか?
>
> hMainWnd や hClient を指定しても出ません。
そこの部分は hWnd を指定しておけば大丈夫です。
WM_MDICREATE メッセージでクライアントの子ウィンドウ(以下ドキュメントウィンドウ)が作られた時にDocProcプロシージャに WM_CREATE が飛んで来るんですけど、その際の hWnd には作られたドキュメントウィンドウのハンドルが格納されているからです。

ウィンドウの親子関係を図にすると以下のようになります。

コード: 全て選択

フレームウィンドウ(メインウィンドウ)
     └クライアントウィンドウ
          ├ドキュメントウィンドウ1
          │     └エディットボックス
          ├ドキュメントウィンドウ2
          │     └エディットボックス
          ├省略

一丁前にMDIテキストエディターよろしく!
今年は受験生

Re: ありがとうございます!!

#9 投稿記事 by 今年は受験生 »

ありがとうございます。

息抜き中に英語の勉強を兼ねてホームページ作成ソフトを作っていて、どうしてもMDIにしたかったので本当に助かりました。

近々、また質問をするかも知れないのでその時はよろしくお願いします(^-^)/
今年は受験生

たびたびすみません

#10 投稿記事 by 今年は受験生 »

今度は、親ウインドウから子ウインドウへメッセージを送る場合がわかりません


たとえば、親ウインドウのメニューから子へ文字の貼り付けを行うとき 自分の調べ方が悪いのか、いい情報が見つかりません。

たびたびすみませんが、教えてくださいm(__)m
7
記事: 473
登録日時: 2005年5月31日(火) 18:51
お住まい: 新潟県
連絡する:

Re: たびたびすみません

#11 投稿記事 by 7 »

> 今度は、親ウインドウから子ウインドウへメッセージを送る場合がわかりません
>
>
> たとえば、親ウインドウのメニューから子へ文字の貼り付けを行うとき

> 自分の調べ方が悪いのか、いい情報が見つかりません。
前に僕が紹介したページを読んでいけば見つかりますよ。ちゃんと読みましょう。

まずアクティブ状態になっているドキュメントウィンドウのハンドルを取得するにはクライアントウィンドウにWM_MDIGETACTIVEを送信すると分かります。

で、エディットボックスのハンドルを取得するには、GetWindow()関数でドキュメントウィンドウの子ウィンドウを取得するか、GetDlgItem()関数で直接エディットボックスのハンドルを取得するかの二つのやり方があります。

関数化してこんな感じのコードにしてみました。

コード: 全て選択

Function GetDocChild(ByVal hClient As HWND) As HWND
	GetDocChild=GetWindow(SendMessage(hClient,WM_MDIGETACTIVE,0,0),GW_CHILED)
End Function

Function GetDocItem(ByVal hClient As HWND,ByVal nIDDlgItem As Long) As HWND
	GetDocItem=GetDlgItem(SendMessage(hClient,WM_MDIGETACTIVE,0,0),nIDDlgItem)
End Function
これらのいずれかを使ってエディットボックスにWM_PASTEを送信するだけでペーストを実装できます。

ごく一部抜粋。

コード: 全て選択

				Case IDM_PASTE
					SendMessage(GetDocItem(hClient,ID_EDIT),WM_PASTE,0,0)
今年は受験生

Re: たびたびすみません

#12 投稿記事 by 今年は受験生 »

ありがとうございました。

あとは、なんとか自力でやってみます。
返信する