- ベストアンサー
CALLBACK 内の DefWindowProc の場所
こんにちは、最近 無料版Borland C++Compiler 5.5 を使って WIN32 API の勉強をしています 気にしなければ別に問題ないのですが、どうしても気になって気持ち悪いので、質問させて下さい 参考書や Web でコード例を見ていると、CALLBACK 内の DefWindowProc関数 を switch の default にする例 と switch の default を書かずに CALLBACK の return にする例があります 好みの問題なのでしょうか? switch は、 default を入れた方が正式と思いますが、default に DefWindowProc を記述すると コードが長くなるにつれ DefWindowProc が switch 内でちょこちょこ必要になってきます 私は、switch の default があった方が良いかなと思い DefWindowProc を default に記述していますが、コードが短くなるなら CALLBACK の return に DefWindowProc を記述しようと思っています どちらが良いのでしょうか? 暇な時でかまいませんので、ご教授下さい 宜しくお願い致します ※DefWindowProc の 記述場所を CALLBACK の return にする LRESULT CALLBACK WindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { switch(uMsg){ case WM_DESTROY: PostQuitMessage(0); break; } /*基本的なメッセージの処理*/ return DefWindowProc(hWnd, uMsg, wParam, lParam); } ※DefWindowProc の 記述場所を switch の default にする LRESULT CALLBACK WindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { switch(uMsg){ case WM_DESTROY: PostQuitMessage(0); break; default: /*基本的なメッセージの処理*/ return DefWindowProc(hWnd, uMsg, wParam, lParam); } return 0; }
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
その他の回答 (1)
- toda hiro(@hiro_knigh)
- ベストアンサー率39% (59/151)
関連するQ&A
- 子ウインドウの作成と破棄について
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; }
- ベストアンサー
- C・C++・C#
- 別関数に渡す変数のポインタが難しい
構造体初心者で、ポインタもよく分かっていません。 12, 8 と表示するつもりのソースだけど、実行結果は違っていました。 直してください。 ソースは長いけど、スケルトンに構造体とTextOutを付けたぐらいのものです。 #include <windows.h> struct MYOBJ { int a; int b; }; LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, int) { MSG msg; WNDCLASS wc; 投稿できなかったからここを消しました。 wc.lpszClassName = "x"; if(RegisterClass(&wc) == 0)return 0; HWND hWnd = CreateWindow("x","",WS_OVERLAPPEDWINDOW|WS_VISIBLE,0,0,320,240,NULL,NULL,hInst,NULL); while(GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } void myfunc(struct MYOBJ *obj)//ここが違うかもしれません。 { obj->a += 2; obj->b -= 2; } LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { HDC hDC; PAINTSTRUCT ps; char buf[30]; switch(uMsg) { case WM_CREATE: struct MYOBJ myobj; myobj.a = 10; myobj.b = 10; myfunc(&myobj);//ここが違うかもしれません。 return 0; case WM_PAINT: hDC = BeginPaint(hWnd, &ps); wsprintf(buf, "%d, %d", myobj.a, myobj.b); TextOut(hDC, 0, 0, buf, strlen(buf)); EndPaint(hWnd, &ps); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; default: return DefWindowProc(hWnd, uMsg, wParam, lParam); } return 0; }
- ベストアンサー
- C・C++・C#
- ダイアログのクラス化で仮想関数を用いて派生クラスにしているんです
ダイアログのクラス化で仮想関数を用いて派生クラスにしているんですが・・・ ダイアログを基本クラスで静的プロシージャと派生クラスでオーバーライドしてプロシージャを使いたい のですが、どうしても自身のポインタが取得できません。 以下にソースを載せておきます。 class CBaseWnd { public: // ポインタの設定 void SetPointer( HWND hWnd ); // ウィンドウプロシージャの呼び出し static LRESULT CALLBACK CallProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ); // ウィンドウプロシージャの実装 virtual LRESULT MainProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ); }; [クラスの実装] //===== ポインタの設定 =====// void CBaseWnd::SetPointer( HWND hWnd ) { SetWindowLong( hWnd, GWL_USERDATA, (LONG)this ); } //===== ウィンドウプロシージャの呼び出し =====// LRESULT CALLBACK CBaseWnd::CallProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) { //_プロパティリストからthisポインタを取得 //ここでポインタを取得することができないでいます。値が0です。 //先にSetWindowlongをやっても値が0のままです。 CBaseWnd* thisPtr = (CBaseWnd*)GetWindowLong( hWnd, GWL_USERDATA ); //_thisポインタが取得できなかった場合... if( ! thisPtr ) { //_ウィンドウの作成時の場合... //ここでアクセス違反というエラーが起きる if( message == WM_INITDIALOG ) thisPtr = (CBaseWnd*)((LPCREATESTRUCT)lParam)->lpCreateParams; //_thisポインタが取得できた場合... if( thisPtr ) { //_プロパティリストにオブジェクトハンドル(thisポインタ)を設定する thisPtr->SetPointer( hWnd ); } } //_thisポインタが取得できた場合... if( thisPtr ) { LRESULT lResult = thisPtr->MainProc( hWnd, message, wParam, lParam ); return lResult; } return DefWindowProc( hWnd, message, wParam, lParam ); } //===== ウィンドウプロシージャの実装(継承可能) =====// // ここでの記述はデフォルトの処理 // LRESULT CBaseWnd::MainProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) { switch( message ) { //_ウィンドウが破棄された場合 case WM_DESTROY: PostQuitMessage(0); return 0; //_デフォルトの場合 default: return DefWindowProc( hWnd, message, wParam, lParam ); } } WM_INITDIALOGでダイアログの初期化中にポインタを取得しようとしますが、アクセス違反が起こり失敗します。 どなたか分かる方がいらっしゃったらご指摘お願いします。
- ベストアンサー
- C・C++・C#
- 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使用率が跳ね上がるのは何故でしょうか。 まだ勉強したてでレベルの低い質問でしたらすみません。
- ベストアンサー
- C・C++・C#
- WM_NCLBUTTONUPについて
タイトルバー上でのマウスボタンのアップを検出したいので、 WM_NCLBUTTONUPメッセージを拾うために、単純に以下のようなコードを書きました。 が、このコードではうまくWM_NCLBUTTONUPメッセージを拾えません。 ウィンドウを最大化しているときは問題なくメッセージを拾えるのですが、 それ以外の時(縮小表示)はメッセージを拾えません。 ただ、WM_NCLBUTTONDOWNは正しく拾うことができました。 ウィンドウが縮小表示になっている時にWM_NCLBUTTONUPを取得する場合には何か特殊な処理が必要なんでしょうか? ご存知の方がいらっしゃったら、よろしくお願いします。 // ウィンドウプロシージャ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_NCLBUTTONUP: MessageBox(hWnd, "UP", "LBUTTON", MB_OK); return 0; case WM_DESTROY: // ウインドウが破棄されたときの処理 PostQuitMessage(0); return 0; default: // デフォルトの処理 return DefWindowProc(hWnd, message, wParam, lParam); } }
- ベストアンサー
- C・C++・C#
- なぜ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); }
- ベストアンサー
- C・C++・C#
- CTreeCtrlのCreate関数でエラーになります。
Visual C++ .NET Win32 プロジェクト で、アプリケーションを作成しようと思っています。 #include<afxwin.h> #include<afxcmn.h> // マルチスレッド CTreeCtrl *m_TreeCtrl; LRESULT CALLBACK int WindowProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) { switch(message) { case WM_LBUTTONDOWN: m_TreeCtrl=new CTreeCtrl; m_TreeCtrl->Create(WS_VISIBLE | WS_TABSTOP | WS_CHILD | WS_BORDER | TVS_HASBUTTONS | TVS_LINESATROOT | TVS_HASLINES | TVS_DISABLEDRAGDROP, CRect(10, 10, 300, 100), CWnd::FromHandle(hWnd), 10000); break; case WM_CREATE: break; case WM_DESTROY: PostQuitMessage(0); break; case WM_PAINT: HDC hDC; PAINTSTRUCT Paint; hDC=BeginPaint(hWnd,&Paint); EndPaint(hWnd,&Paint); } return DefWindowProc(hWnd,message,wParam,lParam); } ・・・ と記述すると、エラーになります。 解決方法を教えてください。
- ベストアンサー
- C・C++・C#
- C++ WIN32 ウィドウの表示
プログラミング初心者です。 WIN32APIの勉強を始めたばかりの状態です。 本を見ながら、ウィンドウを表示させるだけのプログラムを書いてみたのですが、エラーになってしまいます。 #include <windows.h> //ウィンドウ・クラス名 #define MYWNDCLSNAME "MyWindowClass" LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow) { WNDCLASS wndcls; HWND hWnd; MSG msg; //ウィンドウ・クラスを登録 ZeroMemory(&wndcls, sizeof(wndcls)); wndcls.lpfnWndProc = WndProc; wndcls.hInstance = hInst; wndcls.hIcon = LoadIcon(0, IDI_APPLICATION); wndcls.hCursor = LoadCursor(0, IDC_ARROW); wndcls.hbrBackground = (HBRUSH)COLOR_BACKGROUND; wndcls.lpszClassName = MYWNDCLSNAME; if(RegisterClass(&wndcls) == 0) return -1; //メイン・ウィンドウを作成 hWnd = CreateWindow(MYWNDCLSNAME, "My Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, hInst, NULL); if(hWnd == 0) return -2; //ウィンドウの表示状態を指定する ShowWindow(hWnd,nCmdShow); UpdateWindow(hWnd); //メッセージループ while(GetMessage(&msg, 0, 0, 0)){ DispatchMessage(&msg); } //WM_QUITメッセージのwParamを終了コードにする return msg.wParam; } LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg){ case WM_DESTROY: PostQuitMessage(0); return 0; } //自分で処理しないメッセージはWindowsに任せる return DefWindowProc(hWnd, uMsg, wParam, lParam); } 本を読み直しても原因がよくわかりません。 どこがいけないのかご指摘いただけるとうれしいです。お願いします。 エラーの内容は error C2440: '=' : 'const char [14]' から 'LPCWSTR' に変換できません。 error C2664: 'CreateWindowExW' : 2 番目の引数を 'const char [14]' から 'LPCWSTR' に変換できません。 です。
- ベストアンサー
- C・C++・C#
- MIDIをBGMとして使いたい
ウインドウズでゲームを作ってみたいと思い立ち、1ヶ月ほど細々とプログラミングしている者です。環境はXPSP2、VC++6.0です。 このサイトの方たちには色々教えて頂いております。 今、BGMとしてMID(MIDI)ファイルを使いたいと思って色々やっているのですが、音を出すことが出来ません。 VCで作成したプロジェクトフォルダに、test.midというファイルを入れてあり、test.mid単独では音は鳴ります。 アプリケーションのクライアント領域上で右ボタンを押すと音が鳴ると思っていたのですが、メッセージボックスしか出ませんでした。 #include "windows.h" #include <mmsystem.h> #pragma comment(lib, "winmm.lib") LRESULT CALLBACK WindowProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam ) { switch(uMsg) { case WM_CREATE: mciSendString("open test.mid type sequencer alias music",NULL,0,NULL); break; case WM_DESTROY: mciSendString("stop music",NULL,0,NULL); mciSendString("close music",NULL,0,NULL); PostQuitMessage(0); return 0; case WM_KEYUP: if(wParam==VK_RIGHT) { MessageBox(NULL,TEXT("MUSIC"),NULL,MB_OK); mciSendString("play music", NULL, 0, NULL); } } return DefWindowProc(hWnd,uMsg,wParam,lParam); } WINMAINは別段変わったことはやっておりません。ご存知の方が居ましたら宜しくお願い致します。
- 締切済み
- C・C++・C#
- プロトタイプが必要な場合
WndProc関数の前にFunc関数を書いているから、WndProc関数の ソースがコンパイルされる時はFunc関数は既に読み込み済みで Func関数のプロトタイプは必要無いと思ったんだけど、必要なんですか? #include <windows.h> int Func(HWND); ←これは必要ですか? LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPInst, LPSTR lpstr, int n) { … } int Func(HWND hWnd) { … } LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { static int i; switch(uMsg){ case WM_CREATE: i = Func(hWnd); break; … }
- ベストアンサー
- C・C++・C#
お礼
anmochi 様 ご回答有難う御座います なるほど~、良く解りました 特に >なんでもかんでも 0 を返せば良いという訳ではない。 >ハンドル後に 0 を返しているのは意味が分かってやっているなら問題ない の所が、私のような初心者の場合は、意味が解ってない事もあると思いますので、CALLBACK の return に DefWindowProc を使った方が良いと思いえました 私の所持する参考書(複数)は、両方の書き方があったので、どちらが良いのか気持ち悪かったのですが、すっきりしました 有難う御座いました それと >switch は、 default を入れた方が正式と思いますが この書き方は良く無かったです、ごめんなさい switch の構文や if 文 など、全部(default や else) を使って完結させた方が、私の個人的な所で、正式っぽい様な感じがする の方が良い表現だったと思います ( あまり深く考えてませんでしたので、スルーでお願い致します )