SDIで包含関係のない子ウインドウを作りたい – プログラミング – Home

SDIで包含関係のない子ウインドウを作...
 
通知
すべてクリア

[解決済] SDIで包含関係のない子ウインドウを作りたい

固定ページ 1 / 2

yasuda
 yasuda
(@yasuda)
ゲスト
結合: 16年前
投稿: 24
Topic starter  

2003/07/29(火) 18:39:14 の hanabi さんの発言に似ているのですが、
行き詰っているので質問させてください。

MFCベースのSDIアプリケーションで WS_OVERLAPPEDWINDOW な子ウインドウをつくる場合
はどのようにすればよいでしょうか。

hanabi さんの場合は、メインウインドウの中に子ウインドウを作るわけですが、私
は.NET Framework の WindowsForm アプリのように、複数のウインドウに親子関係はあ
っても、包含関係なくデスクトップ上のどこにでもウインドウが位置できるようにした
いのですが、どうすればよいでしょうか。

画像処理ソフトを作っておりまして、親ウインドウ(メニューあり)には処理前画像を表
示し、子ウインドウ(メニューなし、Zオーダ最前面)には処理後画像を表示したいです。
こういうときこそ MDI の出番なのでしょうが、わけあって SDI でウインドウを2個並
べて表示したいのです。


引用未解決
トピックタグ
aetos
(@aetos)
Noble Member
結合: 5年前
投稿: 1480
 

元ネタになっている発言がかなり古いもののようですが、できればリンクを張ってほし
いです。

で、2点、教えてください。
・VisualStudio のバージョンは何ですか?
・全てがメインウィンドウですか?

2点目は、
1:アプリを起動する
2:ウィンドウAが開く
3:ウィンドウBを開く
4:ウィンドウAを閉じる
という操作をした時、アプリは終了するのか、ウィンドウBだけが表示されている状態
で実行が継続されるのか、ということです。


返信引用
yasuda
 yasuda
(@yasuda)
ゲスト
結合: 16年前
投稿: 24
Topic starter  

aetosさん、ご返事ありがとうございます。

元ネタは
http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200307/03070119.txt
のスレッドです。

1点目です。
バージョンは VC++ .NET 2002 です。
すべてがメインウインドウではありません。
メインウインドウと子ウインドウです。

2点目です。
1-2-3-4の動作をすると、アプリは終了します。
ウィンドウAを閉じると、ウィンドウBも閉じます。

今日、会社で色々と試しておりましたがダメでした。

CWnd* MyWnd; とグローバル変数にして
InitInstance部で、下記のようにしても実行時エラーが出たり、
CWnd::CreateEx() の戻り値が 0 になって素通りしたりで、うまくいきませんでした。

BOOL ChogeApp::InitInstance()
{

// メイン ウィンドウが初期化されたので、表示と更新を行います。
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();

MyWnd = new CWnd();
MyWnd->CreateEx (
0,
0,
Window,
WS_POPUP | WS_VISIBLE, // WS_OVERLAPPEDWINDOW | WS_VISIBLE
CRect( 8, 8, 320, 240 ),
m_pMainWnd->GetParent(), // m_pMainWnd
123
);

}


返信引用
wclrp ( 'o')
 wclrp ( 'o')
(@wclrp ( 'o'))
ゲスト
結合: 18年前
投稿: 287
 

子ウインドウっていうとWS_CHILDが付いたウィンドウを想像してしまう。
あなたが作りたいのは子ウィンドウではありませんね。
WS_CHILDなしで親ウィンドウにメインウィンドウを指定すれば
メインウィンドウより手前に表示されるし
メインウィンドウが削除されればともに削除されるなど
あなたの希望のものになると思います。

原因はMFCが特定の使い方以外は優しくないから。

MFCの想定外あるいはもしかしたら間違ったことしてるかもしれないということで
WS_CHILDが付いてないとエラーにしている。
CWndそのままでは利用できない。
派生クラスを作る必要あり。

どうやるかは知らない。


返信引用
bun
 bun
(@bun)
ゲスト
結合: 24年前
投稿: 761
 

もしかして、こんなやつ?

WNDCLASS Wc;
memset(&Wc, NULL, sizeof(WNDCLASS));
Wc.lpfnWndProc = AfxWndProc;
Wc.hInstance = AfxGetInstanceHandle();
Wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
Wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
Wc.lpszClassName = _T(Class);
Wc.hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
Wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW;
AfxRegisterClass(&Wc);

MyWnd = new CWnd;
MyWnd->CreateEx(0, Wc.lpszClassName, _T(Window),
WS_OVERLAPPEDWINDOW | WS_VISIBLE, CRect(8, 8, 320, 240), m_pMainWnd, 0);


返信引用
bun
 bun
(@bun)
ゲスト
結合: 24年前
投稿: 761
 

以下でもよさげ

TCHAR ClassName[256];
int nCnt = ::GetClassName(*m_pMainWnd, ClassName, 256);
WNDCLASS Wc;
::GetClassInfo(AfxGetInstanceHandle(), ClassName, &Wc);

MyWnd = new CWnd;
MyWnd->CreateEx(0, Wc.lpszClassName, _T(Window),
WS_OVERLAPPEDWINDOW | WS_VISIBLE, CRect(8, 8, 320, 240), m_pMainWnd, 0);

要は、 CreateEx() の 第2引数の値が NULL(0) じゃ駄目ってこと。
MFCのウィンドウプロシージャは AfxWndProc() ですので指定してください。

最初のサンプルは、AfxWndProc() を指定したウィンドウプロシージャを作成、
今回のサンプルは、メインフレームのウィンドウプロシージャを取得して同じ
ものを指定しているわけです。


返信引用
bun
 bun
(@bun)
ゲスト
結合: 24年前
投稿: 761
 

あ、クラス名だけ分かればいいから、後者のサンプルはもっと短くなりますね(^-^;

TCHAR ClassName[256];
::GetClassName(*m_pMainWnd, ClassName, 256);

MyWnd = new CWnd;
MyWnd->CreateEx(0, ClassName, _T(Window),
WS_OVERLAPPEDWINDOW | WS_VISIBLE, CRect(8, 8, 320, 240), m_pMainWnd, 0);

以上


返信引用
仲澤@失業者
(@uncle_kei)
Prominent Member
結合: 5年前
投稿: 828
 

大昔に「ポップアップチャイルド」と言われてたやつかも。
基本的にはwclrp ( 'o') さんの言うとおりで、
「MFC + ドキュメントビューアーキテクチャ」を使った段階で
「実現不能」に極めて近いですね。
んで、実現方法としての一本道は、「子と称する窓はSDKで作る」な
わけですが、MFC+DocViewで、むりやりやる方法としては

FrameのPreCreateWindow()でcs.styleを設定して
WNDCLASS wndcls;
GetClassInfo( AfxGetInstanceHandle(), cs.lpszClass, &wndcls);
AfxRegisterWndClass( 0, wndcls.hCursor, wndcls.hbrBackground, NULL);

とやってみる手はあります。
まぁ、MFCのチェックコードとの戦いになりますが、
上手くすり抜けるといけちゃうかもしれませんね。
かなり上級の知識と腕が必要と思われます。
できなかったらあしからず。がんばってください。


返信引用
デゴルガン
 デゴルガン
(@デゴルガン)
ゲスト
結合: 16年前
投稿: 20
 

WS_CHILD を使わないウィンドウなら、
CWnd の代わりに CFrameWnd を使ってみてはどうかな?


返信引用
仲澤@失業者
(@uncle_kei)
Prominent Member
結合: 5年前
投稿: 828
 

あっとSDIかぁ。もっと普通にできるかも。失礼しました。


返信引用
rin
 rin
(@rin)
ゲスト
結合: 18年前
投稿: 112
 

モードレスダイアログに画像表示させる
では駄目なんかな?


返信引用
とおりすがり
 とおりすがり
(@とおりすがり)
ゲスト
結合: 23年前
投稿: 180
 

aetosさんが仰った

>1:アプリを起動する
>2:ウィンドウAが開く
>3:ウィンドウBを開く
>4:ウィンドウAを閉じる

の4実行時にWindowBが残ることを希望って意味であれば
俺なら別アプリにしてしまうかもしれない。

>かなり上級の知識と腕が必要と思われます。
残念ながら自分はこのような知識がないので・・。


返信引用
rin
 rin
(@rin)
ゲスト
結合: 18年前
投稿: 112
 

>>1:アプリを起動する
>>2:ウィンドウAが開く
>>3:ウィンドウBを開く
>>4:ウィンドウAを閉じる
>の4実行時にWindowBが残ることを希望って意味であれば

これをやるなら
私は、メインアプリウィンドウを隠しておき
ウィンドウAを別個に開いて、メインウィンドウに見せかける方法かな


返信引用
yasuda
 yasuda
(@yasuda)
ゲスト
結合: 16年前
投稿: 24
Topic starter  

家に帰って覗いてみたら、皆様がいろいろ書き込んでおられてびっくりしました。
今日も会社でいろいろやってたんですが、ぜんぜんダメでめげておりました。

今、bun さんのコードをやってみたらスンナリコンパイルがとおって、
思ったようなウインドウができ、動作もそのとおりでした。

rinさんのモードレスダイアログに...、
という書き込みも検討してみます。

仲澤さんの方法は難しそうで、
今の私には無理かもしれません。

とりあえず、bunさんをはじめ皆様ありがとうございました。

さて、本スレッドの題名とやや外れてくるのですが、再質問させてください。
(もし新しいスレッドを作ったほうがいいのでしたらご指摘ください)

SDIウインドウのメインのほうは CScrollView の OnDraw で描画をしているのですが、
CreateEx したほうのウインドウは、どこに描画コードを書けばよいのでしょうか?

SDKのメッセージループだと WM_PAINT のところに書けばよいと思いますが、
MFC で CreateEx したウインドウの OnDraw(WM_PAINT) 的なことは
どうすればいいのでしょうか?

/* 動きました、ありがとうございました。****/
BOOL CaaaApp::InitInstance()
{

// いろいろウィザードコードあり。省略.

// メイン ウィンドウが初期化されたので、表示と更新を行います。
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();

WNDCLASS Wc;
memset(&Wc, NULL, sizeof(WNDCLASS));
Wc.lpfnWndProc = AfxWndProc;
Wc.hInstance = AfxGetInstanceHandle();
Wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
Wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
Wc.lpszClassName = _T(Class);
Wc.hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
Wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW;
AfxRegisterClass(&Wc);

MyWnd = new CWnd;
MyWnd->CreateEx(
0,
Wc.lpszClassName,
_T( Window ),
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
CRect(8, 8, 320, 240),
m_pMainWnd,
0
);

m_pMainWnd->SetFocus();

// いろいろウィザードコードあり。省略.

}


返信引用
wclrp ( 'o')
 wclrp ( 'o')
(@wclrp ( 'o'))
ゲスト
結合: 18年前
投稿: 287
 

ウィンドウクラスでWS_CHILDを回避できるとは知らんかった。

WM_PAINTはOnPaintだよ。
CPaintDC dc(this);を使う規則。


返信引用
固定ページ 1 / 2

返信する

投稿者名

投稿者メールアドレス

タイトル *

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