ウィンドウを二つ表示して、それぞれにおいて別々の処理を行いたいのですが、方法が分かりません。
ウィンドウの生成方法が間違っているのでしょうか?
どのようにすれば良いのかが分からず行き詰ってしまいました。
ご教授よろしくお願いします。
ウィンドウを別々に制御
-
tk-xleader
Re:ウィンドウを別々に制御
中身は同じウィンドウを2つ作り別々に制御するプログラム(ウィンドウは単なる雛形)
#include<windows.h>
bool AppInit(HINSTANCE,PTSTR);
bool AppInit2(HINSTANCE,PTSTR);
bool MakeBeginWindow(HINSTANCE,PTSTR);
WPARAM Message();
LRESULT CALLBACK WProc1(HWND,UINT,WPARAM,LPARAM);
LRESULT CALLBACK WProc2(HWND,UINT,WPARAM,LPARAM);
bool w1=true,w2=true;
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
WPARAM endcode=0;
PTSTR wcname1=TEXT("window1");
PTSTR wcname2=TEXT("window2");
if(!AppInit(hInstance,wcname1)||!AppInit2(hInstance,wcname2))return -1;
if(!MakeBeginWindow(hInstance,wcname1)||!MakeBeginWindow(hInstance,wcname2))return -1;
endcode=Message();
MessageBox(NULL,TEXT("終わり"),TEXT("終了通知"),MB_OK);
return endcode;
}
bool AppInit(HINSTANCE hInst,PTSTR wcname)
{
WNDCLASS wc;
wc.style =CS_HREDRAW|CS_VREDRAW;
wc.lpfnWndProc=WProc1;
wc.cbClsExtra=0;
wc.cbWndExtra=0;
wc.hInstance=hInst;
wc.hIcon=LoadIcon(hInst,(LPCSTR)100);
wc.hCursor=LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName=NULL;
wc.lpszClassName=wcname;
return (bool)RegisterClass(&wc);
}
bool AppInit2(HINSTANCE hInst,PTSTR wcname)
{
WNDCLASS wc;
wc.style =CS_HREDRAW|CS_VREDRAW;
wc.lpfnWndProc=WProc2;
wc.cbClsExtra=0;
wc.cbWndExtra=0;
wc.hInstance=hInst;
wc.hIcon=LoadIcon(hInst,(LPCSTR)100);
wc.hCursor=LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName=NULL;
wc.lpszClassName=wcname;
return (bool)RegisterClass(&wc);
}
bool MakeBeginWindow(HINSTANCE hInst,PTSTR wcname)
{
HWND hWnd;
bool wndbool;
hWnd=CreateWindow(wcname,TEXT("Window"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT,480,360,
NULL,NULL,hInst,NULL);
wndbool=(bool)hWnd;
if(wndbool==false){
return wndbool;
}
ShowWindow(hWnd,SW_SHOW);
return wndbool;
}
WPARAM Message()
{
MSG msg;
while(1){
if(GetMessage(&msg,NULL,0,0)==0&&!w1&&!w2)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WProc1(HWND hWnd,UINT message,WPARAM wp,LPARAM lp)
{
switch(message){
case WM_DESTROY:
w1=false;
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd,message,wp,lp);
}
LRESULT CALLBACK WProc2(HWND hWnd,UINT message,WPARAM wp,LPARAM lp)
{
switch(message){
case WM_DESTROY:
w2=false;
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd,message,wp,lp);
}
たぶんこんな感じと思います。-
雷
Re:ウィンドウを別々に制御
一度解決したといっておいて何なのですが、
tkmakwins15さんに質問があります。
とても基礎的なことだと思いますがよろしくお願いします。
WPARAM endcode=0;
…
endcode=Message();
この二つは何そしているのかが良く分かりませんでした。
if(!AppInit(hInstance,wcname1)||!AppInit2(hInstance,wcname2))
これあは、どちらかがTrue(0以外)でなかった時という解釈で良いんですよね?
(今必死でC++の勉強中です…)
wndbool=(bool)hWnd;
if(wndbool==false){
return wndbool;
}
これは、ハンドルが生成失敗をした時に0を返すという処理に見えますが、
何故boolを使ってやっているのでしょうか?
boolのfalseは0なので、普通に
if(hWnd == 0)
return hWnd;
とやってしまってはいけないのでしょうか?
一様実行をしてみても問題が無い感じたのですが、後に問題が生じるのでしょうか?
WProc1の中で
w1=false;
とされていますが、他の場所で使用されているのが発見できませんでした。
何故 w1 や w2 が必要なのでしょうか?
他にも理解できていないところがありますが、それはC言語の方でも同じように使われているので、
呪文であると考えて、今わスルーしているので、僕のレベルでは理解できないだろう、
と思われる個所がありましたら、呪文ですで良いので、ご回答の程よろしくお願いします。
最後に、もしC++関係でお勧めの書籍などありましたらお教えいただけるとうれしいです。-
tk-xleader
Re:ウィンドウを別々に制御
上から順に説明します。引用は色を変えて対応します。
これは、Message()関数の戻り値に関係があります。Message()の戻り値は、終了コードになるようにしているのです。
ハンドルのfalseの返し方の問題ですが、これはただbool型であることを明記しているだけです。なので、そのまま返しても大丈夫です。
w1,w2の意味は、ウィンドウの存在フラグです。両方のウィンドウが閉じられたらソフトを終了させるという意味です。
僕のコーディングは教えてもらったものではなく、自分でHP見ながら自分が読みやすいようなコーディングにしてますから読みにくかったと思います。読みにくいプログラムを示してしまい失礼しました。
WPARAM endcode=0;
…
endcode=Message();これは、Message()関数の戻り値に関係があります。Message()の戻り値は、終了コードになるようにしているのです。
ハンドルのfalseの返し方の問題ですが、これはただbool型であることを明記しているだけです。なので、そのまま返しても大丈夫です。
w1,w2の意味は、ウィンドウの存在フラグです。両方のウィンドウが閉じられたらソフトを終了させるという意味です。
僕のコーディングは教えてもらったものではなく、自分でHP見ながら自分が読みやすいようなコーディングにしてますから読みにくかったと思います。読みにくいプログラムを示してしまい失礼しました。
-
tk-xleader
Re:ウィンドウを別々に制御
すいません、回答足りませんね。
>他にも理解できていないところがありますが、それはC言語の方でも同じように使われているので、
>呪文であると考えて、今わスルーしているので、僕のレベルでは理解できないだろう、
>と思われる個所がありましたら、呪文ですで良いので、ご回答の程よろしくお願いします。
そんなことは気にせず、分からなかったら質問していただければいいですよ。
いい本の紹介です、ハーバート・シルト著の「独習C++」や柴田望洋著の「明解C++」がC経験者には最適です。
Windowsプログラミングの入門書であれば粂井康孝著の「猫でも分かるWindowsプログラミング」がいいでしょう。
C++の奥深いところを解説してある本は、Bjarne Stroustrup著の「プログラミング言語C++第3版」がいいと思います。
>他にも理解できていないところがありますが、それはC言語の方でも同じように使われているので、
>呪文であると考えて、今わスルーしているので、僕のレベルでは理解できないだろう、
>と思われる個所がありましたら、呪文ですで良いので、ご回答の程よろしくお願いします。
そんなことは気にせず、分からなかったら質問していただければいいですよ。
いい本の紹介です、ハーバート・シルト著の「独習C++」や柴田望洋著の「明解C++」がC経験者には最適です。
Windowsプログラミングの入門書であれば粂井康孝著の「猫でも分かるWindowsプログラミング」がいいでしょう。
C++の奥深いところを解説してある本は、Bjarne Stroustrup著の「プログラミング言語C++第3版」がいいと思います。
-
雷
Re:ウィンドウを別々に制御
ご回答ありがとうございます。
>僕のコーディングは教えてもらったものではなく、自分でHP見ながら自分が読みやすいような
>コーディングにしてますから読みにくかったと思います。読みにくいプログラムを示してしまい失礼しました。
ぜんぜんそんなことはありません。
参考になります!
>そんなことは気にせず、分からなかったら質問していただければいいですよ。
ありがとうございます。
よろしくお願いします。
>w1,w2の意味は、ウィンドウの存在フラグです。両方のウィンドウが閉じられたらソフトを終了させるという意味です。
どうやって存在フラグが成立しているのでしょうか?
WM_DESTROY の中でfalseにしているので、ほとんど意味が無い様に思うのですがどうなんでしょうか?
w1をw2があるところで宣言すると、ウィンドウが破棄されるのでしょうか?
今学校で試すことができないので、家に帰ったらやってみますが、よろしければお答えお願いします。
>僕のコーディングは教えてもらったものではなく、自分でHP見ながら自分が読みやすいような
>コーディングにしてますから読みにくかったと思います。読みにくいプログラムを示してしまい失礼しました。
ぜんぜんそんなことはありません。
参考になります!
>そんなことは気にせず、分からなかったら質問していただければいいですよ。
ありがとうございます。
よろしくお願いします。
>w1,w2の意味は、ウィンドウの存在フラグです。両方のウィンドウが閉じられたらソフトを終了させるという意味です。
どうやって存在フラグが成立しているのでしょうか?
WM_DESTROY の中でfalseにしているので、ほとんど意味が無い様に思うのですがどうなんでしょうか?
w1をw2があるところで宣言すると、ウィンドウが破棄されるのでしょうか?
今学校で試すことができないので、家に帰ったらやってみますが、よろしければお答えお願いします。
-
tk-xleader
Re:ウィンドウを別々に制御
僕も今学校から帰ってきて見たところです。
グローバル変数ですから、プログラム中のどこからでも見ることができます。宣言時にtrueにしていますね。
なので、ウィンドウが閉じられるまでずっとtrueを指し示すようになります。
閉じられた時には、ウィンドウプロシージャにWM_DESTROYを送りますから、それを捕まえて、falseにすると、ウィンドウがないという状態だと指す事ができます。流れとしては…
最初、フラグ変数2つはtrue(真)で初期化。
↓
※メッセージループの終了条件は二つのフラグがfalse(偽)である事。
↓
(ウィンドウが1つ閉じられた時)
閉じられたほうのウィンドウのプロシージャにWM_DESTROYが来る。
そのときに対応するフラグをfalse(偽)にする。
↓
ウィンドウが2つ閉じていないので終了条件には適合しない。
↓
(2つ目が閉じられた時)
もう一方のウィンドウのプロシージャにWM_DESTROYが来る。
対応するフラグをfalse(偽)にする。
↓
すると※の二つのフラグが偽であるという条件に合致するため、メッセージループの終了となる。
↓
そのときに受け取った終了コードでプログラムを終了する。
という感じになります。
グローバル変数ですから、プログラム中のどこからでも見ることができます。宣言時にtrueにしていますね。
なので、ウィンドウが閉じられるまでずっとtrueを指し示すようになります。
閉じられた時には、ウィンドウプロシージャにWM_DESTROYを送りますから、それを捕まえて、falseにすると、ウィンドウがないという状態だと指す事ができます。流れとしては…
最初、フラグ変数2つはtrue(真)で初期化。
↓
※メッセージループの終了条件は二つのフラグがfalse(偽)である事。
↓
(ウィンドウが1つ閉じられた時)
閉じられたほうのウィンドウのプロシージャにWM_DESTROYが来る。
そのときに対応するフラグをfalse(偽)にする。
↓
ウィンドウが2つ閉じていないので終了条件には適合しない。
↓
(2つ目が閉じられた時)
もう一方のウィンドウのプロシージャにWM_DESTROYが来る。
対応するフラグをfalse(偽)にする。
↓
すると※の二つのフラグが偽であるという条件に合致するため、メッセージループの終了となる。
↓
そのときに受け取った終了コードでプログラムを終了する。
という感じになります。
-
雷
Re:ウィンドウを別々に制御
ご回答ありがとうございます。
>if(GetMessage(&msg,NULL,0,0)==0&&!w1&&!w2)
の一文を探し出せていませんでした。
詳しい説明ありがとうございました。
やっていてわからないところがあったらまた質問させていただきたいと思います。
本当にありがとうございました。
>if(GetMessage(&msg,NULL,0,0)==0&&!w1&&!w2)
の一文を探し出せていませんでした。
詳しい説明ありがとうございました。
やっていてわからないところがあったらまた質問させていただきたいと思います。
本当にありがとうございました。