101 case WM_CLOSE:
102  id = MessageBox(hWnd,"終了する?","",MB_YESNO);
103  if(id == IDYES)DestroyWindow(hWnd);
104 break;
105 case WM_DESTROY:
106  PostQuitMessage(0);
107 break;


103行目が実行されたら、WM_DESTROY が発生します。
そしたらそのまま104、105、106行目が順に実行されるんですか?
それとも、103が実行されたら104が実行される前に、
新しいプロセスで WM_DESTROY が入った WndProc( ) が
実行されて、それと同時に104が実行されて break で
ループが終了するんですか?

このQ&Aに関連する最新のQ&A

キュー 意味」に関するQ&A: キューの意味

A 回答 (3件)

まず、プロセスというのは、この場合は関係なくて、



DestroyWindow を実行すると、内部で WndProc が呼び出されるのと同等な流れになると考えていいです。
DispatchMessage→WndProc(WM_CLOSE)→102→103→WndProc(WM_DESTROY)→106→107→return→104→return
とういうように、WM_CLOSE のメッセージを処理している途中で、WM_DESTROY が実行されます。
    • good
    • 0
この回答へのお礼

ありがとうございます。
プロセスとスレッドがよく分かってないんです。

103行目が実行されたら、そこで、プロセスかスレッドの
ような流れAが止まって、新しい流れBが WndProc(WM_DESTROY) で
動作して、Bによって101から104は読み込まれるけど
実行されず、105で case が当てはまって 106 が実行されて
107が読み込まれて、ソースには書いてないけど WndProc( ) の
最後の return 0 が実行されてBが終了し、Aの続きが再開されて、
104から順に読み込まれて、WndProc( ) の最後の return 0 が
実行されてAが終了する。

これで合っていますか?

お礼日時:2002/02/04 01:23

あまり複雑な事は考えないほうがいいと思います。


実際にはもっと複雑なんでしょうけど、WndProcを呼ぶ形としては
次の種類があると思います。

1.SendMessageのように戻りを取得するもの
2.PostMessageのようにメッセージキューに送信するだけのもの

1の場合には、inthefloiさんが言ってるように間接的にWndProc関数を呼び出す
ような感じになります。
もしWndProc内から行った場合には再起呼び出しと同じようになると思います。
実際には違いますがこう考えてはどうでしょう

100 LONG DestroyWindow(...)
101 {
102  return WndProc(WM_DESTROY,...)
103 }
104 
105 LRESULT CALLBACK WndProc(...)
106 {
107  switch( uMsg )
108  {
109  case WM_CLOSE:
110    DestroyWindow(hWnd);
111  break;
112  case WM_DESTROY:
113    PostQuitMessage(0);

そうすると
WndProc(110)
 DestroyWindow(102)
  WndProc(113)
 DestroyWindow(103)
WndProc(111)

みたいな感じになると思います。
    • good
    • 0
この回答へのお礼

ありがとうございます。

お礼日時:2002/02/05 22:50

>これで合っていますか?



なぜスレッドにこだわるのかがわかりません。
DestroyWindow の中でカレントスレッドを一時停止させて、新しいスレッドを作成して、WndProc を呼び出すのなら、カレントスレッドがそのまま WndProc を呼び出した方が無駄な事をしないぶんだけ有利です。

>Bによって101から104は読み込まれるけど実行されず

申し訳ないのですが、読み込まれるというのが何を意味しているのか私にはわかりません。switch-case を別の書き方をしてみると、

switch (m)
{
case WM_CLOSE:
 // 処理A
 break;
case WM_DESTROY:
 // 処理B
 break;
}



if (m == WM_CLOSE) {
 // 処理A
}
else if (m == WM_DESTROY) {
 // 処理B
}

となるわけだから、スレッドが作成されるかどうかに関係なく、実行されない部分は実行されません。
    • good
    • 0
この回答へのお礼

ありがとうございます。
if に置きかえるやつを見て分かりました。

お礼日時:2002/02/05 22:50

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aと関連する良く見られている質問

QWM_PAINTとWM_MOVEで同じ事をしたいけど

VC.NETにて、
ウィンドウプロシージャでWM_PAINTとWM_MOVEを拾って、テキストを書き直す関数に飛ばしているのですが、WM_MOVEでは書き直してくれません。
書き直し関数はウインドウの座標の絶対と相対をGetClientRectとGetWindowRectで得て表示をするだけです。
WM_MOVEでも関数に飛んで、座標を得てはいるようですが、表示しなおしてくれません。
ウインドウの大きさを変えると表示し直してくれます。
何故でしょうか?

Aベストアンサー

>hdc = BeginPaint(hWnd, &paint);
と、
>EndPaint(hWnd, &paint);

これはWM_PAINTの中でしか使用できません。

WM_MOVEで描画を行うのでしたらGetDC()、ReleaseDC()を使用してください。

QWM_SIZEとWM_SIZINGの違い (Win32API)

Windowsプログラミングで、画面のサイズを変更したときに送られてくるメッセージで、
WM_SIZEで処理するのとWM_SIZINGで処理するのとでは何が違うのでしょうか?
WM_SIZEとWM_SIZINGの違いは何なのでしょうか?

また、似たようなものでWM_MOVEとWM_MOVINGの違いも教えてもらいたいです。

Aベストアンサー

実際にプログラムを書いてみれば、両者の違いは明白になるでしょう。

WM_SIZE は「サイズの変更後に」メッセージがアプリケーションに飛んでくるので、
ウィンドウのコーナーからマウスを離した時に文字がビョンと移動します。

Windows98 くらいまではウィンドウのサイズの変更はまずは輪郭だけサイズが変って
マウスをコーナーから離した時にウィンドウの中身が再描画されていたので、
WM_SIZE のメッセージハンドラを実装することになったでしょう。

しかし最近のインターフェイスはサイズ変更中もズリズリとウィンドウの中身が
再描画され続けます。これには WM_SIZING のメッセージハンドラを実装して、
サイズ変更中常に文字列の再描画を繰り返す必要があるでしょう。

QなぜhButton1ボタンからのWM_COMMANDはフックできてクライアントエリアのWM_RBUTTONDOWNはフックできないのでしょうか?

#define STRLBUTTON TEXT("マウス左ボタンが押されました from mainProc")
#define STRRBUTTON TEXT("マウス右ボタンが押されました from my_HookProc")
#define STRCOMMAND TEXT("ボタンが押されました")


HWND hButton1;



LRESULT CALLBACK my_HookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
CWPRETSTRUCT *pcwpRetStruct = (CWPRETSTRUCT *)lParam;
HDC hDC;

if(nCode==HC_ACTION)
{
hDC = GetDC(pcwpRetStruct->hwnd);
switch(pcwpRetStruct->message)
{
case WM_COMMAND:
TextOut(hDC, 10, 10, STRCOMMAND, strlen(STRCOMMAND));
break;
case WM_RBUTTONDOWN:
TextOut(hDC, 10, 10, STRRBUTTON, strlen(STRRBUTTON));
break;
}

ReleaseDC(pcwpRetStruct->hwnd, hDC);
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}



LRESULT CALLBACK mainProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static HHOOK hHook;
HDC hDC;

switch(uMsg)
{
case WM_DESTROY:
UnhookWindowsHookEx(hHook);
PostQuitMessage(0);
return 0;

case WM_CREATE:
hHook = SetWindowsHookEx(WH_CALLWNDPROCRET, my_HookProc, NULL, GetCurrentThreadId() );
if(!hHook)
MessageBox(NULL, "hooking failed", NULL, MB_OK);

hButton1 = CreateWindow(
"BUTTON", "hButton1",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
10, 40, 100, 20,
hWnd, NULL,
((LPCREATESTRUCT)lParam)->hInstance, NULL
);
return 0;

case WM_LBUTTONDOWN:
hDC = GetDC(hWnd);
TextOut(hDC, 10, 10, STRLBUTTON, strlen(STRLBUTTON));
ReleaseDC(hWnd, hDC);
return 0;
}

return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

#define STRLBUTTON TEXT("マウス左ボタンが押されました from mainProc")
#define STRRBUTTON TEXT("マウス右ボタンが押されました from my_HookProc")
#define STRCOMMAND TEXT("ボタンが押されました")


HWND hButton1;



LRESULT CALLBACK my_HookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
CWPRETSTRUCT *pcwpRetStruct = (CWPRETSTRUCT *)lParam;
HDC hDC;

if(nCode==HC_ACTION)
{
hDC = GetDC(pcwpRetStruct->hwnd);
switch(pcwpRetStruct->message)
{
case WM_COMMAND:
Tex...続きを読む

Aベストアンサー

WH_CALLWNDPROCRETはSendMessageで送られたメッセージのみを対象とし、WM_xBUTTONDOWNはPostMessageで送られるからです。WH_GETMESSAGEならばWM_xBUTTONDOWNをフックすることができます。

QWM_CHAR or WM_KEYDOWN の「wParam」について

よくわかっていないのですが、

switch (message)
{
case WM_CHAR:
というところで、wParamから、文字の情報取得して、
HDC宣言して、TextOut関数使用…、の途中で、
wParamの文字情報は、どのようにすれば
TextOut関数に渡せるのでしょうか?
Visual C++を勉強したてで、勉強の成果をと思い、
テキストエディタを作ってみたいと思ったのですが、
さて、どうしたらよいのでしょうか?
エラー内容は、unsigned int → const char *
にできません、ということなのですが、
じゃぁ、型の変換の仕方は?という感じです。
初心者なので、簡単な例をつけて説明してくださると助かります。よろしくお願いします。

Aベストアンサー

TextOut(~, (char*)wParam, ~);

と、char*型に型変換すると良い気がします。

--
TextOut関数の宣言、

TextOut(~, (const char*)szText, ~);

のconstキーワードは、
「TextOut関数に渡したwParamの値をTextOut関数の内部で書き換えることはありませんので安心してね。」
という意味ですので、

unsigned int
long double

などの2つの単語で宣言される「型」とは意味合いが異なります。
ヘルプの説明ですと釈然としませんが、参考URLなどを読んでみてください。

プログラマの正体!? - 誰が為にconst
http://www.asahi-net.or.jp/~vx2t-andu/lets/20020203.html

参考URL:http://www.asahi-net.or.jp/~vx2t-andu/lets/20020203.html

QhDC=::GetDC(m_hWnd)とhDC=GetDC(m_hWn

hDC=::GetDC(m_hWnd)とhDC=GetDC(m_hWnd)の違いについて

表題について,お伺いします。
ビットマップをダイアログに表示するソースコードを
書いてますが,参考書やさまざまなHPでは,
ウィンドウハンドルをゲットする際に

hDC=::GetDC(m_hWnd) ○
↑と書かれております。

hDC=GetDC(m_hWnd)  ×
↑はなぜだめなのでしょう。

 ●このスコープ演算子::は何の為につけているのですか?

::が無いとエラーになるので必要みたいですが・・

Aベストアンサー

どういうエラー(リンクエラー、コンパイルエラー)なのかがわからないので、
あくまで憶測ですが、
Windows.hで定義されているGetDC()の他に、
別のスコープに(例えばクラスのメソッドとして)、
GetDC()が定義されているのではないでしょうか?

上記の状態でスコープ演算子がないときには、
同じクラス(スコープ)にあるGetDC()を先に呼ぶことになるので、
目的のWindows.hのGetDC()を呼ぶことができないのだと思います。

参考URL:http://wisdom.sakura.ne.jp/programming/cpp/cpp7.html


人気Q&Aランキング

おすすめ情報