閉じるボタンを押してもデバッグが終了しない問題について

このQ&Aのポイント
  • フォームアプリケーションで閉じるボタンを押してもデバッグが終了しない問題について質問があります。
  • 右上の閉じるボタン[×]を押すとウィンドウは閉じますが、デバッグは終了しません。
  • プロジェクト名のプロセスは残ったままで、デバッグを手動で停止させると消えます。これは仕様なのでしょうか?
回答を見る
  • ベストアンサー

閉じるを押してもデバッグが終了しません。

プログラム初心者です。よろしくお願いします。 フォームアプリケーションで入門としてクリックやウィンドウの検知を行うプログラムを書いてみたのですが、右上の閉じるボタン[×]を押すとウィンドウは閉じますが、デバックは終了しません。 プロセスを見てもプロジェクト名のプロセスは残ったままで、デバッグを手動で停止させると消えます。 これはこういうものなのでしょうか? 初めて書いたプログラムなので比較対象が無くて分かりません。 以下プログラムコード project1 ------------------------------------------ (略) protected: virtual void WndProc(System::Windows::Forms::Message% m) override { switch(m.Msg) { case WM_TIMER: if(m.WParam.ToInt32()==1) { POINT point; GetCursorPos(&point); Form1::label2->Text="X:"+point.x; Form1::label3->Text="Y:"+point.y; setlocale( LC_ALL, "Japanese" ); TCHAR buff[260]; HWND hWnd; hWnd=WindowFromPoint(point); GetWindowText(hWnd, buff, sizeof(buff)); Form1::label1->Text=gcnew String(buff); }break; case WM_MOVE: Form1::label4->Text="移動しました。";break; case WM_LBUTTONDOWN: Form1::label4->Text="左クリック";break; case WM_RBUTTONDOWN: Form1::label4->Text="右クリック";break; /* default: Form1::label4->Text=m.Msg.ToString();break;*/ } Form::WndProc(m); } private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e) { HWND hmyWnd = static_cast<HWND>(this->Handle.ToPointer()); SetTimer(hmyWnd,1,100,NULL); } }; ------------------------------------------------------------- また、case WM_RBUTTONDOWN:の内部にClose();を書き足して実行すると 「'System.ObjectDisposedException' のハンドルされていない例外が System.Windows.Forms.dll で発生しました。」 と出ます。 何かおかしいところはありますでしょうか? それとも仕様でしょうか? お教えくださいm(_ _)m

質問者が選んだベストアンサー

  • ベストアンサー
回答No.3

以下のようにイベントハンドラが記述されるので・・・ってWM_MOVEでしたね・・・。 上記コードに、WM_MOUSEMOVE通知時のコードがあったとしたらそれをイベント ハンドラに記述します。 という感じで、夫々の処理をイベントハンドラに書いても起きますか?

ikasumiramen
質問者

お礼

回答ありがとうございます。 画像付の説明恐れ入ります。イベントハイドラについてはそういうのがあるということは知っていましたが作ったことは無かったので参考になりました。 早速実装してみたところ、正常にデバッグが終了いたしました。 ウィンドウプロシージャがいけないようですね。 ですが私が今後実装したいと考えているプログラムは、グローバルフックを使い他のプログラム(FireFoxなど)のWM_MOVEを取得したいと考えています。 そのため今回はメッセージの扱いを学ぶためにウィンドウプロシージャを使用しました。 今後もこの分野で何度か質問をさせていただく事があると思います。その時はまたぜひ助けていただければ幸いです。 今回は本当にありがとうございます。

その他の回答 (2)

回答No.2

次に、プロパティーウィンドウの稲妻マークをクリックしてください。 ← (1) 次に、MouseMoveをダブルクリックしてください。 ← (2)

回答No.1

コード見ただけでは、正しい様な気がしますね。 ただ、なぜ、WndProcをオーバーライドするという方法を選んだんですか? 上記の事をやりたいだけならイベントハンドラを書いたらいいだけなんではないでしょうか? 一応、ご存知かもしれませんが、イベントハンドラの追加の仕方を紹介しておきます。 まず、下記画像にある様にメニューからプロパティウィンドウを表示させてください。

関連するQ&A

  • ウィンドウプロシージャの書き方について

    VC++Expressで開発しています。 このたびWin32APIを使用してみたいと思い以下のようなマウスの座標を常に表示するプログラムを書いてみました。 Form1.h ----------------------------------------------- #pragma once #include <Windows.h> #include <stdio.h> #pragma comment(lib, "user32.lib") //(略) LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wp,LPARAM lp) { switch(msg) { case WM_TIMER: switch(wp) { case 1: POINT point; GetCursorPos(&point); label2->Text="X:"+point.x; label3->Text="Y:"+point.y; break; } default: return DefWindowProc(hwnd,msg,wp,lp); break; } } private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e) { HWND hmyWnd = static_cast<HWND>(this->Handle.ToPointer()); SetTimer(hmyWnd,1,100,NULL); } ----------------------------------------------- コレを実行してみると warning C4441: '__stdcall ' の呼び出し規約が無視されました。代わりに、'__clrcall ' を使用しました という警告が出た後、ウィンドウが表示されますがラベルの内容は変化しません。 そこで質問させてください。 まず、この様な警告が出る理由はなんでしょうか? 私はウィンドウプロシージャの使い方が間違っていると思うのですが、それより先は調べることが出来ませんでした。 次に前述の疑問に関連してですが、「イベント駆動型のプログラムを書く際はメッセージキューにたまったメッセージをそれぞれ適切なウィンドウプロシージャへ送る」と言う風に理解しているのですが、どのサイトでプログラム例を見てもLRESULT CALLBACK WndProc(略)という受け取る側の関数を書いているだけで、肝心の送る側の関数を記述していません。 そのため、私も見よう見真似で受け取る側の関数だけ書いたのですが、これではもちろんどこに書かれているかも分からない送り側の関数と関連付けは出来ませんよね? 実際にウィンドウプロシージャやその他メッセージ処理ではどのようにして関連付けを行っているのですか? また、私はプロジェクトを作成したときに最初に出てきたForm1.hと言うファイルにコードを書き込んでいるのですが、これは後々問題になるでしょうか? 少しまとまりの無い質問となってしまいましたが、どうかお答えください。 お願いしますm(_ _)m

  • WindowsSDKのCALLBACK内について

    猫でも分かるWindowsSDKを参考にして、とりあえずウィンドウプロシージャの関数内を下のようにしてプログラムを組んでみました。 //ウィンドウプロシージャ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { switch (msg) { case WM_CREATE: break; case WM_TIMER: break; case WM_PAINT: break; case WM_COMMAND: break; case WM_CLOSE: SendMessage(hWnd, WM_DESTROY, wp, lp); break; case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wp, lp)); } return 0L; } しかし、これで何もないWindow表示をさせるとCPU使用率が80%くらいまで跳ね上がります。 調べてみたところcase WM_PAINT:を削ったらCPU使用率が下がりました。 普通にクライアント領域に文字を表示したり画像を表示したりするだけだったら、それほどCPU使用率が上がらないのに、上のようにあらかじめ用意しておいたらCPU使用率が跳ね上がるのは何故でしょうか。 まだ勉強したてでレベルの低い質問でしたらすみません。

  • TextOut( ) が動かない

    LRESULT CALLBACK WndProc( HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam){ PAINTSTRUCT ps; HDC hdc; switch(msg){ case WM_KEYDOWN:  if( wParam == VK_ESCAPE ){   hdc = BeginPaint(hWnd, &ps);   TextOut(hdc,0,0,str,strlen(str));   EndPaint(hWnd, &ps);  }  break; case WM_PAINT:  break; エスケープキーで文字表示をやりたいけど TextOut( ) が動作していないみたいでした。 switch(msg){ case WM_KEYDOWN:  if( wParam == VK_ESCAPE ){   hdc = BeginPaint(hWnd, &ps);   TextOut(hdc,0,0,str,strlen(str));   EndPaint(hWnd, &ps);  }  break; case WM_PAINT:  hdc = BeginPaint(hWnd, &ps);  TextOut(hdc,0,0,str,strlen(str));  EndPaint(hWnd, &ps);  break; とすると、常に文字が表示されたから、やっぱり case WM_KEYDOWN: の中の TextOut( ) が 動作していないんだと思いました。 TextOut( ) は case WM_PAINT: からのつながりが ある場合でないと実行されないんですか? ソースのおかしいところがあったら教えてください。

  • WM_KEYDOWNでPrtScを捕まえる方法??

    ごく普通のウィンドウプロシージャでキーの判別を行っています 下記のように条件(1)が WM_KEYUP の際には(2)、(3)ともに検出します LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { switch (msg) { case WM_KEYUP: ............ (1) switch(wp) { case VK_RETURN: { break; } ..... (2) case VK_SNAPSHOT: { break; } ..... (3) default: { break; } } break; } return; ところが条件(1)を WM_KEYDOWN に変更すると(2)の Enter は検出しますが、(3)の PrtSc を検出してくれません 質問1 なぜ PrtSc を WM_KEYDOWN では検出しないのですか? 質問2 WM_KEYUP WM_KEYDOWN のいずれか一方にしか反応しないキーはまだありますか? 質問3 どのようにしたら PrtSc の WM_KEYDOWN を捕まえることが出来ますか? 自分でも調べてみましたが、どうも判然と致しません 宜しくご指導のほどお願い申し上げます

  • なぜCreateHatchBushの設定が途中で喪失するのか

    いつもお世話になります。 縦縞の四角形を表示するプログラムですが、ある一定の四角形を描画すると四角形の中の縦縞がなくなり、白色になります。 原因が分かりません。アドバイスをお願い致します。 (四角形をマウスドラッグ中に小さくすると黒い線がたくさんでてきますが、これはアプリケーションの仕様です) プロシージャソースは以下の通り。 LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { HDC hDC; PAINTSTRUCT ps; static POINT start, end; static bool push; switch(msg) { case WM_CREATE: push = false; break; case WM_LBUTTONDOWN: start.x = LOWORD(lParam); start.y = HIWORD(lParam); push = true; break; case WM_MOUSEMOVE: if(push){ end.x = LOWORD(lParam); end.y = HIWORD(lParam); InvalidateRect(hWnd, NULL, FALSE); } break; case WM_LBUTTONUP: end.x = LOWORD(lParam); end.y = HIWORD(lParam); push = false; InvalidateRect(hWnd, NULL, FALSE); break; case WM_PAINT: HBRUSH hBrush; hDC = BeginPaint(hWnd, &ps); hBrush = CreateHatchBrush(HS_VERTICAL, RGB(255, 0, 0)); SelectObject(hDC, hBrush); Rectangle(hDC, start.x, start.y, end.x, end.y); DeleteObject(hBrush); EndPaint(hWnd, &ps); break; case WM_DESTROY: PostQuitMessage(0); break; } return DefWindowProc(hWnd, msg, wParam, lParam); } よろしくお願い致します。

  • ウィンドウプロシージャで無限再帰

    VC++6.0 Windows2000です。 #define EDITBOX 1234 LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {  switch (msg)  {   case WM_COMMAND:    switch (LOWORD(wp))    {     case EDITBOX:      GetDlgItemText(hWnd, EDITBOX, str, 32);      ---- ここでstrの文字列を改変 ----      SetDlgItemText(hWnd, EDITBOX, str);      break;    }    break;  } } みたいなことをすると無限再帰が発生してしまうのですが、無限再帰を防ぎつつ等価な動作をさせる方法をよろしくお願いします。

  • wsprintf( ) でポインタに代入

    wsprintf(p, "%d" , i); を書いたせいで、i の値が変わります。 wsprintf(p, "%d" , i); によってどんなことが起こっているのか詳しく知りたいです。 ポインタのことがまだよく分かってないんです。 #include <windows.h> LPCSTR szStr = "\n char c[255];\n char *p = \"\\0\";\n int i = 12345;\n\n switch (msg){\n case WM_LBUTTONDOWN:\n  wsprintf(c, \"%d\" , i);\n  wsprintf(p, \"%d\" , i);\n  MessageBox(hWnd , c , \"\" , MB_OK);\n break;"; LRESULT CALLBACK WndProc(HWND , UINT , WPARAM , LPARAM); int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE , LPSTR , int){ 省略 return msg.wParam; } LRESULT CALLBACK WndProc(HWND hWnd , UINT msg , WPARAM wParam , LPARAM lParam){ HDC hDC; PAINTSTRUCT ps; RECT rt; char c[255]; char *p = "\0"; int i = 12345; switch (msg){ case WM_LBUTTONDOWN: wsprintf(c, "%d" , i); wsprintf(p, "%d" , i); MessageBox(hWnd , c , "" , MB_OK); break; case WM_PAINT: GetClientRect(hWnd, &rt); hDC = BeginPaint(hWnd, &ps); DrawText(hDC, szStr, lstrlen(szStr), &rt, DT_WORDBREAK); EndPaint(hWnd, &ps); break; case WM_DESTROY: PostQuitMessage(0); break; default: return(DefWindowProc(hWnd , msg , wParam , lParam)); } return (0L); }

  • 自作関数から WndProc( ) を止める

    自作関数から WndProc( ) を止めるにはどうしたらいいんですか? LRESULT CALLBACK WndProc(…){  switch(msg){  case WM_COMMAND:   if(function f( ) == "END")return 0;   処理A;  break;  } } function f( ){  return "END" } こんな流れにしたいけど、WndProc( ) 内からでなく、 外から WndProc( ) を止めたいんです。 LRESULT CALLBACK WndProc(…){  switch(msg){  case WM_COMMAND:   function f( );   処理A;  break;  } } function f( ){  ? // WndProc( ) に return 0 とさせて 処理A を実行させない }

  • wndProcを用いたUSBデバイスの抜差し検知

    現在VC++2008のC++/CLIを用いてwindows form アプリケーションを作成しています。 USBカメラの抜挿しを検知しようと思い,http://d.hatena.ne.jp/shiwork/20100126/1264453129のサイトを参考にさせていただき,下記のコードを書きました。 #include <windows.h> #include <Dbt.h> virtual void WndProc(System::Windows::Forms::Message% m) override {  if(m.Msg == WM_DEVICECHANGE)  {    switch((int)(m.WParam))    {      case DBT_DEVICEREMOVECOMPLETE:        MessageBox::Show("out");        break;      case DBT_DEVICEARRIVAL:        MessageBox::Show("in");        break;    }   }   Form::WndProc(m); } このコードをステップ実行してみたところ,USBカメラを抜いても挿しても,m.WParamの値は '7'のままで変わりません。またswitchで一時停止し,F10で1ステップ実行したところ,すぐにswitchを抜けてしまい,条件式を全く評価していないようでした。 どのようにすれば,USBカメラの抜挿しを正常に検知できるでしょうか?

  • WM_PAINT

    WM_PAINT について教えてほしいのですが、 WM_PAINTがシステムから発行されるタイミングとして、 クライアント領域に無効領域がある時 UpdateWindow()を呼び出した時 InvalidateRect()を呼び出した時があると思いますが 例えば LRESULT CALLBACK WndProc(HWND , UINT , WPARAM , LPARAM) { LPCTSTR  Str = TEXT("Kitty"); switch (msg) { case WM_CREATE:    hdc = GetDC(hwnd);    SetTextColor(hdc , RGB(255, 0 , 0));    ReleaseDC(hwnd , hdc);    return 0; case WM_PAINT:    hdc = BeginPaint(hwnd , &ps);    TextOut(hdc, 10 , 10 , Str, lstrlen(Str));    EndPaint(hwnd , &ps);    return 0; } return DefWindowProc(hwnd , msg , wp , lp); } の場合, WM_PAINTはどのタイミングでシステムから呼び出されるんですか? WinMain()でUpdateWindow()もInvalidateRect()もつかっていないのですが。 いつシステムから送られるかご教授をお願いします。

専門家に質問してみよう