• ベストアンサー

プロセスとか

akinori_sの回答

  • akinori_s
  • ベストアンサー率60% (21/35)
回答No.3

あまり複雑な事は考えないほうがいいと思います。 実際にはもっと複雑なんでしょうけど、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) みたいな感じになると思います。

A__
質問者

お礼

ありがとうございます。

関連するQ&A

  • 自分の書いたプログラムに疑問があります

    よろしくお願いします。 メモ帳を作っています、作成したウィンドウに 『メニュバー』  『ツールバー』 『ポップアップメニュー』 を作り、そこにエディタを貼り付けました。 『右クリック』をすると、windows既成のポップアップメニューが表示されるため、新しいプロシージャで自分用のポップアップメニューを作ったのですが、 メモ帳に何も書かずに終了した時、終了できなかったのでこのプログラムを先頭に加えました。 if(SendMessage(hWnd, EM_GETMODIFY, 0, 0) == FALSE){ id = MessageBox(hWnd, TEXT("終了してもいいですか"), TEXT("確認"), MB_YESNO | MB_ICONQUESTION); if(id == IDYES){ DestroyWindow(hWnd); PostQuitMessage(0); } } 疑問点  この記述は、『文書保存の確認』の所でも使っていますが、 これをつけないと終了できません。 重複しているため、すっきりしないのですが、 今は、これしか思い浮かばないのですが、もっとすっきりしたプログラムにしたいのです。 間違っている所、直したほうがいい所がありましたらアドバイスをお願いします。 //マイプロシージャの終了メッセージ処理 case WM_COMMAND: switch (LOWORD(wp)){ case IDM_END:   if(SendMessage(hWnd, EM_GETMODIFY, 0, 0) == FALSE){ id = MessageBox(hWnd, TEXT("終了してもいいですか"), TEXT("確認"), MB_YESNO | MB_ICONQUESTION); if(id == IDYES){ DestroyWindow(hWnd); PostQuitMessage(0); } //重複するが、ここを付けないと、何も書いていないメモ帳が閉じない } //ここから文書保存のプログラム if(SendMessage(hWnd, EM_GETMODIFY, 0, 0) == TRUE){ id = MessageBox(hWnd, TEXT("文書が更新されています、\n変更を保存しますか?"), TEXT("メモ帳"), MB_YESNOCANCEL | MB_ICONEXCLAMATION); if(id == IDYES){ MySaveAs(hWnd); }else if (id == IDCANCEL){ return IDCANCEL; } /*else if (id ==IDNO){ ここを記述すると  文書保存でキャンセルした時に、『終了しない』     また、何も書いてないと 『終了しない』  id = MessageBox(hWnd, TEXT("終了してもいいですか"), TEXT("確認"), MB_YESNO | MB_ICONQUESTION); if(id == IDYES){ DestroyWindow(hWnd); PostQuitMessage(0); //}//ここもコメントアウト } } } break;   default: return CallWindowProc(OldProc, hWnd, msg, wp, lp); } }  

  • VC++2005での警告について教えてください

    よろしくお願いします。 vc++2005を使ってコンパイルした時、プログラムの『691行目と、689行目』の所に緑色の(∥チェック)が付いていて、次のような警告が出たのですが、 これは、『記述する場所が間違っている』と解釈して良いでしょうか? ------ ビルド開始: プロジェクト: memo, 構成: Release Win32 ------ コンパイルしています... c:\memo\memo\memo.cpp(691) : warning C4715: 'NewProc' : 値を返さないコントロール パスがあります。 コード生成が終了しました。 マニフェストを埋め込んでいます... ビルドログは "file://c:\Visual Studio 2005\Projects\memo\memo\Release\BuildLog.htm" に保存されました。 memo - エラー 0、警告 21 ========== ビルド: 1 正常終了、0 失敗、0 更新、0 スキップ ========== //サブクラス化後のプロシージャ LRESULT CALLBACK NewProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { POINT pt; static HMENU hMenu; static HMENU hSubMenu; int id; switch (msg){ case WM_RBUTTONDOWN: //ポップアップメニューを作る hMenu = LoadMenu(hInst, "MYMENU2"); hSubMenu = GetSubMenu(hMenu, 0); pt.x = LOWORD(lp); pt.y = HIWORD(lp); ClientToScreen(hWnd, &pt); TrackPopupMenu(hSubMenu, TPM_LEFTALIGN, pt.x, pt.y, 0, hWnd, NULL); DestroyMenu(hMenu); break; case WM_COMMAND: switch (LOWORD(wp)){ case IDM_NEW: MyNew(hWnd); break; /*case IDM_SAVE: MySave(hWnd); break;*/ case IDM_SAVEAS: MySaveAs(hWnd); break; case IDM_OPEN: MyOpen(hWnd); break; case IDM_END: if(SendMessage(hWnd, EM_GETMODIFY, 0, 0) == FALSE){ id = MessageBox(hWnd, TEXT("終了してもいいですか"), TEXT("確認"), MB_YESNO | MB_ICONQUESTION); if(id == IDYES){ DestroyWindow(hWnd); PostQuitMessage(0); } } if(SendMessage(hWnd, EM_GETMODIFY, 0, 0) == TRUE){ id = MessageBox(hWnd, TEXT("文書が更新されています、\n変更を保存しますか?"), TEXT("メモ帳"), MB_YESNOCANCEL | MB_ICONEXCLAMATION); if(id == IDYES){ MySave(hWnd); //MySaveAs(hWnd); }else if (id == IDCANCEL){ return IDCANCEL; }/*else if (id ==IDNO){ *///ここを記述すると //文書保存ダイアログでキャンセルした時に、『終了しない』 id = MessageBox(hWnd, TEXT("終了してもいいですか"), TEXT("確認"), MB_YESNO | MB_ICONQUESTION); if(id == IDYES){ DestroyWindow(hWnd); PostQuitMessage(0); } } } break; default: 689行目 return CallWindowProc(OldProc, hWnd, msg, wp, lp); } 691 行目 }

  • 不思議な現象が起こるプログラムで悩んでいます。

    よろしくお願いします。 不思議な現象が起こるプログラムで悩んでいます。 『猫でもわかる第2版』を参考にして、『メモ帳』を作成しているのですが、コンパイルして作られた メモ帳の動作を理解できません。 詳しい方、アドバイスをお願いします。 1、メニューを付けない『メモ帳』の時は、『直接入力、半角入力、全角入力』が可能、漢字変換も可能 問題点 1、メニューを付けない『メモ帳』の時、『コーディングしていないのに』右クリックでポップアップメニューが表示でき、切り取り、削除、貼り付け、その他が使える。 2,メニュー項目を付けると『直接入力が出来ない』、半角入力、全角入力は可能、但し、Enterキーを押すと、入力した文字が消えてしまう 3、コンパイルには、BCC, VC++の両方でテストしたが、結果は同じ /*ウィンドウプロシージャ*/ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { int id; RECT rc; static HWND hEdit; switch (msg){ case WM_CREATE: hEdit = CreateWindow("EDIT", NULL, WS_CHILD | WS_VISIBLE | ES_WANTRETURN | ES_MULTILINE | ES_AUTOVSCROLL | WS_VSCROLL, 0, 0, 0, 0, hWnd, (HMENU)ID_EDIT, hInst, NULL); strcat(szTitle, "「無題」"); SetWindowText(hWnd, szTitle); break; case WM_SIZE: MoveWindow(hEdit, 0, 0, LOWORD(lp), HIWORD(lp), TRUE); break; SetWindowText(GetParent(hEdit), "メモ帳[無題]"); case WM_SETFOCUS: SetFocus(hEdit); break; /*case WM_COMMAND: switch (LOWORD(wp)){ case IDM_NEW: MyNew(hEdit); break; } break;*/ case WM_CLOSE: id = MyConfirm(hEdit); if(id == IDCANCEL) break; id = MessageBox(hWnd, "終了してもいいですか", "確認", MB_YESNO | MB_ICONQUESTION); if(id == IDYES){ DestroyWindow(hEdit); DestroyWindow(hWnd); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wp, lp)); } return 0; } /*新規作成 int MyNew(HWND hEdit) { int id; id = MyConfirm(hEdit); if(id == IDCANCEL){ return -1; } Edit_SetText(hEdit, ""); SetWindowText(GetParent(hEdit), "メモ帳[無題]"); strcpy(szFile, ""); return 0; }*/ //文書保存の確認 int MyConfirm(HWND hEdit) { int id; if(SendMessage(hEdit, EM_GETMODIFY, 0, 0) == TRUE){ id = MessageBox(hEdit, "文書が更新されています。\n変更を保存しますか?", "メモ帳", MB_YESNOCANCEL | MB_ICONEXCLAMATION); if(id == IDYES){ MySaveAs(hEdit); }else if (id == IDCANCEL){ return IDCANCEL; }else if (id == IDNO){ return IDNO; } } return 0; }

  • windowsAPI 画像の表示

    画像が表示できません。   表示は   LoadBitmap() と BitBlt() だと思うんですけど。。。   何回やってもできません。   LRESULT CALLBACK WindowProc ( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { HMENU hMenu, hSubMenu; MENUITEMINFO mii; HDC hdc,hBuffer; RECT rect; TEXTMETRIC tm; PTSTR pstr; PAINTSTRUCT ps; static HFONT hFont; static HDC hMemDC; static HBITMAP hBitmap,hPrevBitmap; static BITMAP bitmap; switch(uMsg) { case WM_DESTROY: PostQuitMessage(0); return 0; case WM_CLOSE: if(MessageBox(hWnd,TEXT("ゲームを終了しますか?"),TEXT("アスパラインフォメーション"),MB_YESNO | MB_ICONINFORMATION) == IDYES){ DestroyWindow(hWnd); } return 0; case WM_COMMAND: //有効なメニューが選択され、メニューの選択が終了した switch(LOWORD(wParam)) { case IDM_NEW: pstr = TEXT("新しくゲームを始めますか?"); if(MessageBox(hWnd , pstr , TEXT("アスパラインフォメーション") , MB_YESNO | MB_ICONINFORMATION) == IDYES){ gamesystem = 1; InvalidateRect(hWnd,NULL,TRUE); } break; case IDM_OPEN: pstr = TEXT("ゲームをロードしますか?"); if(MessageBox(hWnd , pstr , TEXT("アスパラインフォメーション") , MB_YESNO | MB_ICONINFORMATION) == IDYES){ } break; case IDM_CLOSE: pstr = TEXT("ゲームを終了しますか?"); if(MessageBox(hWnd , pstr , TEXT("アスパラインフォメーション") , MB_YESNO | MB_ICONINFORMATION) == IDYES){ DestroyWindow(hWnd); } break; default: return 0; } return 0; case WM_MENUSELECT: //メニュー項目が選択された switch (LOWORD(wParam)) { case IDM_NEW: pstr = TEXT("新しくゲームを開始します"); break; case IDM_OPEN: pstr = TEXT("ゲームをロードします"); break; case IDM_CLOSE: pstr = TEXT("ゲームを終了します"); break; default: pstr = TEXT("ポップアップメニューが選択されています"); break; } hdc = GetDC(hWnd); GetClientRect(hWnd , &rect); GetTextMetrics(hdc , &tm); Rectangle(hdc , 0 , rect.bottom - tm.tmHeight * 2, rect.right , rect.bottom); TextOut(hdc , 5 , rect.bottom - tm.tmHeight * 1.5 , pstr , lstrlen(pstr)); ReleaseDC(hWnd , hdc); return 0; case WM_CREATE: mii.cbSize = sizeof(MENUITEMINFO); mii.fMask = MIIM_TYPE | MIIM_ID; mii.fType = MFT_STRING; hMenu = CreateMenu(); hSubMenu = CreatePopupMenu(); mii.dwTypeData = TEXT("ニューゲーム(&N)"); mii.wID = IDM_NEW; InsertMenuItem(hSubMenu , 0 , TRUE , &mii); mii.dwTypeData = TEXT("ロード(&O)"); mii.wID = IDM_OPEN; InsertMenuItem(hSubMenu , 1 , TRUE , &mii); mii.dwTypeData = TEXT("終了(&X)"); mii.wID = IDM_CLOSE; InsertMenuItem(hSubMenu , 2 , TRUE , &mii); mii.fMask = MIIM_TYPE | MIIM_SUBMENU; mii.hSubMenu = hSubMenu; mii.dwTypeData = TEXT("ファイル(&F)"); InsertMenuItem(hMenu , 0 , TRUE , &mii); SetMenu(hWnd , hMenu); hFont = CreateFont( 40,0,0,0,750, FALSE,FALSE,FALSE, SHIFTJIS_CHARSET,OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, VARIABLE_PITCH | FF_ROMAN,NULL); hBitmap = LoadBitmap( ((LPCREATESTRUCT)lParam)->hInstance , TEXT("KYARA") ); return 0; case WM_KEYDOWN: InvalidateRect(hWnd,NULL,FALSE); gamesystem += 1; return 0; case WM_PAINT: hdc = BeginPaint(hWnd,&ps); hBuffer = CreateCompatibleDC(hdc); SelectObject(hBuffer , hBitmap); BitBlt(hdc , 100 , 100 , 34 , 32 , hBuffer , 70 , 80 , SRCCOPY); DeleteDC(hBuffer); if(gamesystem == 1){ ・・・・・・・・・・・・・・・・・   といった感じです。   間違えがあれば、ご指摘お願いします。   また、わかりやすいサンプルコードを載せていただけたら嬉しいです。

  • 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使用率が跳ね上がるのは何故でしょうか。 まだ勉強したてでレベルの低い質問でしたらすみません。

  • win32apiでの動画出力

    win32apiとopenCVを使った動画出力プログラムを作りたいのですが, フリーズしてしまいます. 詳しい方,力を貸してください. 以下にプログラムを載せます. LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { int x, y; int id; int c; char* szWndName = "camera capture"; CvCapture* capture; // IplImage* img; switch (msg) { case WM_CREATE: hDC = GetDC( hWnd ); return DefWindowProc(hWnd, msg, wParam, lParam); case WM_COMMAND: switch(LOWORD(wParam)){ case IDM_END: SendMessage(hWnd, WM_CLOSE, 0, 0L); break; case IDM_USB: capture = cvCaptureFromCAM(0); if(capture == NULL){ MessageBox(hWnd, (LPCTSTR)TEXT("Not camera"), (LPCTSTR)TEXT("Test"), MB_OK); return -1; } while(1){ img = cvQueryFrame(capture); bmpData = (LPDWORD)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, img->width * img->height * 4); iplTobmp(img, bmpInfo, bmpData); StretchDIBits( hDC, 0, 0, img->width, img->height, 0, 0, img->width, img->height, bmpData, &bmpInfo, DIB_RGB_COLORS, SRCCOPY); } ReleaseDC(hWnd, hDC); cvReleaseCapture(&capture); return 0; break; } break; case WM_LBUTTONDOWN: // マウスカーソルが移動したときに送られてくる // 移動先の座標を取得 x = LOWORD( lParam ); y = HIWORD( lParam ); // 座標をテキストファイルに書き込む _ftprintf( g_fp, _T("(%d %d)\n"), x, y ); return 0; case WM_CLOSE: id = MessageBox(hWnd, TEXT("Close?"), TEXT("Close"), MB_OKCANCEL | MB_ICONQUESTION); if(id == IDOK) DestroyWindow(hWnd); return (0L); case WM_DESTROY: PostQuitMessage(0); break; default: return(DefWindowProc(hWnd, msg, wParam, lParam)); } return (0L); }

  • エディットの文字サイズ変更

    エディットボックスの文字サイズを変更する方法を教えてください。 HFONTを使う方法でやってみたけど、エディットのフォントは デフォルトのままで、フォントが変更されていないように見えました。 LRESULT CALLBACK WndProc( …  static HWND hEdit;  static HFONT hFont;  switch (msg) {  case WM_CREATE:   hEdit = CreateWindow( … );   hFont = CreateFont( … );   if(!hFont)エラー処理 …;   SendMessage(hEdit, WM_SETFONT, (WPARAM)hFont, 0);   break;  case WM_DESTROY:   DeleteObject(hFont);   PostQuitMessage(0);   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); }

  • 子ウインドウの作成と破棄について

    CALLBACK のみを書きました。 メインウインドウを破棄したら 子ウインドウも破棄したいのですが、 うまく出来ません。 どうすればよろしいでしょうか? よろしくお願いします。 #include<windows.h> #include"ChildWindow.h" char MainWindowClassName[]="mainwindow"; LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) { static HWND childWnd; switch(message) { case WM_ACTIVATEAPP: childWnd=Child_CreateWindow(hWnd,message,wParam,lParam); break; case WM_DESTROY: DestroyWindow(childWnd); PostQuitMessage(0); break; default: return DefWindowProc(hWnd,message,wParam,lParam); } } ///////////////////////////////////////////// #include<windows.h> char ChildWindowClassName[]="childwindow"; LRESULT CALLBACK ChildProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) { switch(message) { case WM_LBUTTONDOWN: MessageBox(NULL,"","",MB_OK); break; default: return DefWindowProc(hWnd,message,wParam,lParam); } } ATOM Child_RegistWindow(HINSTANCE hInstance){} HWND Child_InitInstance(HWND hParentWnd,HINSTANCE hInst,int CmdShow){} HWND Child_CreateWindow(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) { int CmdShow=1; Child_RegistWindow(NULL); HWND ChildWnd=Child_InitInstance(hWnd,NULL,CmdShow); MSG msg; while(GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return ChildWnd; }

  • 2重Func禁止。クリセク。セマフォ。

    MyFunc( ) の実行中は WM_LBUTTONDOWN を無視されるように しようと思いました。 LRESULT CALLBACK WndProc(… {  static bool b = TRUE;  switch(msg){  case WM_LBUTTONDOWN:   if(b){    b = FALSE;    MyFunc( ); //  MessageBox(hWnd, "", "", MB_OK);    b = TRUE;   }  break; でもこれでは、例えば MyFunc( ) が実行中に3回クリックすると その後に MyFunc( ) は3回実行されてしまいます。 MessageBox( ) を使えばうまくいくけと、それは使いたくありません。 できるだけ簡単なソースで、 MyFunc( ) の実行中のクリックで、後で MyFunc( ) が 実行されないようにするにはどこを直したらいいですか?