- ベストアンサー
WM_CREATE について
Windows API の勉強を始めた者です。 CreateWindow関数を使ったときに発行されるWM_CREATEについて質問させていただきます。 以下のようなプログラムを作りました。このプログラムはウインドウを作るプログラムなのですが、はじめにウインドウを作るかどうかをWindowProcの中で聞いています。 このプログラムでウインドウを作らないという選択肢をとった時が分かりません。 WindowProcでは return -1 をするのでウインドウは作られず、従ってhWndにはNULLが入ります。そして次の文で、 if (hWnd == NULL) { MessageBox(NULL,TEXT("CreateWindow failed"),NULL,MB_OK); return 0; } メッセージボックスが表示されてからプログラムが終了すると思ったのですが、実際にはメッセージボックスは表示されませんでした。 なぜでしょうか。return -1 をした時点で、ウインドウが作られないのでWM_DESTROYがウインドウプロシージャにSendされるのかと考えたのですが、そうなのでしょうか。 よろしくお願いします。 /* 作ったプログラム */ #include <windows.h> LRESULT CALLBACK WindowProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { int YESNO; switch(uMsg) { case WM_DESTROY: PostQuitMessage(0); return 0; case WM_CREATE: YESNO = MessageBox(NULL, TEXT("Create a new window?"), ((LPCREATESTRUCT)lParam)->lpszName, MB_YESNO); if (YESNO == IDYES) return 0; if (YESNO == IDNO) return -1; } return DefWindowProc(hWnd, uMsg, wParam, lParam); } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, int nCmdShow) { WNDCLASS wc; ATOM atom; MSG msg; HWND hWnd; wc.style = CS_HREDRAW| CS_VREDRAW; wc.lpfnWndProc = WindowProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = NULL; wc.hCursor = NULL; wc.hbrBackground = (HBRUSH)COLOR_BACKGROUND + 1; wc.lpszMenuName = NULL; wc.lpszClassName = TEXT("sample_window"); if ((atom = RegisterClass(&wc)) == 0) { MessageBox(NULL,TEXT("RegisterClass failed"),NULL,MB_OK); return 0; } hWnd = CreateWindow((LPCTSTR)atom, TEXT("Sampe window"), WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100, 100, 400, 300, NULL, NULL, hInstance, NULL); if (hWnd == NULL) { MessageBox(NULL,TEXT("CreateWindow failed"),NULL,MB_OK); return 0; } while (GetMessage(&msg, NULL, 0, 0) > 0) { DispatchMessage(&msg); } return msg.wParam; }
- pikacha
- お礼率96% (27/28)
- C・C++・C#
- 回答数4
- ありがとう数6
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
こんばんは。御礼頂きました。 >>WM_CREATEメッセージが送られた後にWM_DESTROYが送られるのは、なぜなのでしょうか?return -1 をすることでウインドウが破棄されるのでDestroyWindow()関数が使われるためなのでしょうか。 に関してですが、流石に当方もWindows OSの実装者では無いので其処までは分かりません・・・。 ただ、想像する分には、そのサイトの一番下にも書いて有る様に、「GetMessage()に到達するまでの間に必要なコールバックはKiUserCallbackDispatcher()を介して行われる」と言うのですから、その中でWM_CREATEを呼び出して戻り値を確認し、エラー値が返された場合は即座にWM_DESTROYを呼び出しているのではないでしょうか。 此れならば、GetMessage()に到達していなくても、WM_DESTROY位は呼び出せる筈です。 単純な関数ポインタの呼び出し見たいな感覚で行われる物なのかもしれません。 >>もう一点に関して 取り敢えずPostQuitMessage()をコメントアウトしてWM_CREATEに失敗させると(メッセージループは無くても同じ)、MessageBox()が表示されました(Windows2000 sp4 VC++6.0で試しています)。 確かにPostQuitMessage()があると、MessageBox()が表示されなかったです(ただしサウンドだけは鳴った)。 今まで色々とWindows関連のサイトなどを見てきましたが、流石にココまでメスを入れていたものは見た事がありません。 海外から輸入されて来ているWindows関連の詳しい書籍であれば、こう言った詳細が書かれているかもしれません。
その他の回答 (3)
MessageBoxは呼ばれてますよ デバッガでステップ実行でもすれば(しなくてもですけど)ifに入ってメッセージボックスが出る音が出てます 戻り値もGetLastErrorもエラー無しな値しか返しませんし表示されない理由もわかりませんけど
お礼
回答をありがとうございます。 回答者様のおっしゃるとおり、メッセージボックスの音が出ていました。 これはつまり、メッセージボックスは表示はされていないが、 if (hWnd == NULL) のところのreturn 0; でプログラムが終了しているのですね。 なぜ表示されないかについてはいろいろ調べてみたいと思います。 回答をありがとうございました。
- machongola
- ベストアンサー率60% (434/720)
こんにちは。 WM_DESTROYの中にMessageBox()を置きます。 また、WM_CREATEはCreateWindow()APIの内部でメッセージループに先立って呼び出される物です。 http://keicode.com/windows/win01.php ですのでWM_CREATEで失敗させる分には while (GetMessage(&msg, NULL, 0, 0) > 0) { DispatchMessage(&msg); } が無くてもWM_DESTROYが呼び出されます。 WM_DESTROYの下にあるPostQuitMessage()が呼び出されて終了したため、MessageBox()が出なかったのだと思います。 また、WM_CREATEが呼び出される順番は、 (1)WM_GETMINMAXINFO (2)WM_NCCREATE (3)WM_NCCALCSIZE (4)WM_CREATE と言う事で、四番目に位置します。
お礼
回答をありがとうございます。 参考ページをありがとうございます。いろいろ細かいところまであり参考になります。 なお、気になった点があるのですが、どうなのでしょうか。 WM_CREATEメッセージが送られた後にWM_DESTROYが送られるのは、なぜなのでしょうか?return -1 をすることでウインドウが破棄されるのでDestroyWindow()関数が使われるためなのでしょうか。 もう一点は、WM_DESTROYメッセージが送られた後、PostQuitMessage()関数が呼びだされます。 これはWM_QUITをメッセージキューにポストします。WM_QUITはGetMessage()関数にメッセージループの終了を通知するもので対象がウインドウプロシージャではないと思うのですが、もしそうするとメッセージキューからWM_QUITメッセージを取り出すにはGetMessage()関数が必要で、このプログラムが終了するにはWM_QUITを取り出さなければなりません(もしくはreturn 0 に到達する)。しかし、それ以前にメッセージボックスを出す命令がありますから、やはりメッセージボックスが出ると思うのですが、どうでしょうか? よろしくお願いします。
- Nitar
- ベストアンサー率23% (5/21)
WindowProc はメッセージループに入ってから呼び出される物として記憶しています。つまりWM_CREATEが生じたときには既に while (GetMessage(&msg, NULL, 0, 0) > 0) { DispatchMessage(&msg); } の中にいるのではないかと。 WM_CREATEで判断している以上、メッセージボックスを出したいのであればWM_DESTROYの分岐で書くのが自然な気がします。
お礼
素早い回答をありがとうございます。 私の方では、CreateWindow()関数はメッセージループに入る前の段階でウインドウプロシージャにメッセージを送ると考えています。 このプログラムではメッセージループの前の段階でコメントボックスを出すように書かれているため、どうやらこのプログラムはメッセージループに入ることなく終了しているようなのです。どうもその辺りの動きが分かりません。 回答をありがとうございました。
関連するQ&A
- win32apiにおける終了処理について
下記のプログラムを実行してウィンドウを閉じるボタンで閉じると、 ウィンドウは消えるのですがなぜかプロセスが残ってしまいます。 正直、お手上げなので教えて頂けると幸いです。 よろしくお願いします。 #include<windows.h> #define APP_NAME TEXT("Sample_MainWindow") /*ウィンドウプロシージャ*/ LRESULT CALLBACK WindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { switch(uMsg) { case WM_DESTROY: PostQuitMessage(0); return 0; } /*基本的なメッセージの処理*/ return DefWindowProc(hWnd, uMsg,wParam,lParam); } /*WinMain*/ int WINAPI WinMain( HINSTANCE hInstance , HINSTANCE hPrevInstance , PSTR lpCmdLine , int nCmdShow) { HWND hWnd; WNDCLASS wc; MSG msg; wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = DefWindowProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL,IDI_APPLICATION); wc.hCursor = LoadCursor(NULL,IDC_ARROW); wc.hbrBackground = (HBRUSH)COLOR_BACKGROUND + 1; wc.lpszMenuName = NULL; wc.lpszClassName = APP_NAME; if (!RegisterClass(&wc)){ MessageBox(NULL,TEXT("ウィンドウクラスの作成に失敗しました"),NULL,MB_OK); return 0; } hWnd = CreateWindow( APP_NAME, TEXT("Window Title"), WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL ); if(hWnd == NULL){ MessageBox(NULL,TEXT("ウィンドウの生成に失敗しました"),NULL,MB_OK); return 0; } /*メッセージループ*/ while(GetMessage(&msg, NULL,0,0)){ DispatchMessage(&msg); } return (int)msg.wParam; }
- 締切済み
- その他(プログラミング・開発)
- 自作関数の使い方
ウインドウの左上に1を表示させたいのに デスクトップの左上に1が表示される。 ソースを直してください。 #include <windows.h> HWND hWnd; void f(); LRESULT CALLBACK WndProc(HWND ,UINT ,WPARAM ,LPARAM); int WINAPI WinMain(HINSTANCE hInstance ,HINSTANCE ,LPSTR , int){ HWND hWnd; MSG msg; WNDCLASS wc; wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; wc.cbClsExtra = wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.lpszMenuName = NULL; wc.lpszClassName = "CNAME"; wc.hIcon = LoadIcon(NULL , IDI_APPLICATION); wc.hCursor = LoadCursor(NULL , IDC_ARROW); wc.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH); if (!RegisterClass(&wc))return 0; hWnd = CreateWindow(wc.lpszClassName , "EXE" , WS_OVERLAPPEDWINDOW | WS_VISIBLE , CW_USEDEFAULT , CW_USEDEFAULT , 200 , 150, NULL , NULL , hInstance , NULL); while(GetMessage(&msg , NULL , 0 , 0)){ TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } LRESULT CALLBACK WndProc(HWND hWnd ,UINT msg ,WPARAM wParam ,LPARAM lParam){ HDC hDC; switch (msg){ case WM_LBUTTONDOWN: f(); break; case WM_DESTROY: PostQuitMessage(0); break; default: return(DefWindowProc(hWnd , msg , wParam , lParam)); } return (0L); } void f(){ HDC hDC; hDC = GetDC(hWnd); TextOut(hDC,0,0,"1",1); ReleaseDC(hWnd, hDC); }
- ベストアンサー
- C・C++・C#
- 子ウインドウの作成と破棄について
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#
- プログラミングでエラーが出ました。教えてください。
Visual C++ 2010で 1>LINK : fatal error LNK1561: エントリー ポイントを定義しなければなりません。 というエラーが出ました。 プログラムは、↓です。 #include <windows.h> LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM); ATOM InitApp(HINSTANCE); BOOL InitInstance(HINSTANCE, int); TCHAR szClassName[] = TEXT("sample01"); int WINAPI WInMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow){ MSG msg; BOOL bRet; if(!InitApp(hCurInst)) return FALSE; if(!InitInstance(hCurInst, nCmdShow)) return FALSE; while((bRet = GetMessage(&msg, NULL, 0, 0))!= 0){ if(bRet == -1){ MessageBox(NULL, TEXT("GetMassageエラー"),TEXT("Error"),MB_OK); break; }else{ TranslateMessage(&msg); DispatchMessage(&msg); } } return (int)msg.wParam; } ATOM InitApp(HINSTANCE hInst){ WNDCLASSEX wc; wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInst; wc.hIcon = (HICON)LoadImage(NULL, MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED); wc.hCursor = (HICON)LoadImage(NULL, MAKEINTRESOURCE(IDC_ARROW), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED); wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = szClassName; wc.hIconSm = (HICON)LoadImage(NULL, MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED); return (RegisterClassEx(&wc)); } BOOL InitInstance(HINSTANCE hInst, int nCmdShow){ HWND hWnd; hWnd = CreateWindow(szClassName,TEXT("猫でもわかるWindowsプログラミング"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInst, NULL); if(!hWnd) return FALSE; ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp){ switch(msg){ case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wp, lp)); } return 0; } 教えてください。 よろしくお願いします。
- ベストアンサー
- C・C++・C#
- ShellAbout(hWnd,"","",LoadIcon(?));
BCC32 で、 ShellAbout(hWnd,"","",LoadIcon(hInst, IDI_APPLICATION)); ShellAbout(hWnd,"","",LoadIcon(NULL, IDI_APPLICATION)); ↑ならアイコンに関してどっちでもできるけど、リソースで MYICONSM ICON DISCARDABLE "ico.ico" として、 ShellAbout(hWnd,"","",LoadIcon(hInst, "MYICON"); ShellAbout(hWnd,"","",LoadIcon(NULL, "MYICON")); ↑はアイコンに関してどっちも無効で旗になります。 BCC32 で ShellAbout( ) で自作アイコンを表示するには どうしたらいいんですか? #include <windows.h> #include <shellapi.h> HINSTANCE hInst; HICON hIcon; LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam){ switch (uMsg){ case WM_LBUTTONDOWN: ShellAbout(hWnd,"","",?; break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd,uMsg,wParam,lParam); } return 0; } int WINAPI WinMain(HINSTANCE hInst,HINSTANCE,LPSTR,int){ HWND hWnd; WNDCLASSEX wc; MSG msg; wc.cbSize =略 wc.style = wc.lpfnWndProc = wc.hInstance = wc.cbClsExtra = wc.cbWndExtra = wc.lpszMenuName = wc.lpszClassName = wc.hIcon = wc.hCursor = wc.hbrBackground = RegisterClassEx(&wc); hWnd = CreateWindow(wc.lpszClassName,"TEST",WS_OVERLAPPEDWINDOW, 0,0,640,480,NULL,NULL,hInst,NULL); ShowWindow(hWnd,SW_SHOWNORMAL); UpdateWindow(hWnd); while(GetMessage( &msg, NULL, 0, 0)){ TranslateMessage( &msg ); DispatchMessage( &msg ); } return 0; }
- 締切済み
- C・C++・C#
- Windowsプログラミングのひな形の段階でエラーが出てしまいます。
指定されたパスが見つかりませんと出てウィンドウが生成されません。 コードが違うのでしょうか・・それともプロジェクトの作り方に問題があるのでしょうか。VisualStudio2005のVisual C++でつくっています。 以下コードです↓ //hinagata.cpp #include<windows.h> LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM); ATOM InitApp(HINSTANCE); BOOL InitInstance(HINSTANCE,int); char szClassName[]="hinagata"; int WINAPIMain(HINSTANCE hCurInst,HINSTANCE hPrevInst,LPSTR lpsCmdline,int nCmdShow) { MSG msg; BOOL bRet; if(!InitApp(hCurInst)) return FALSE; if(!InitInstance(hCurInst,nCmdShow)) return FALSE; while((bRet=GetMessage)&msg,NULL,0,0))!=0){ if(bRet==-1){ MessageBox(NULL,"GetMessageエラー","Error",MB_OK); break; }else{ TranslateMessage(&msg); DispatchMessage(&msg); } } return(int)msg.wParam; } //ウィンドウクラスの登録 ATOM InitApp(HINSTANCE hInst) { WNDCLASSEX wc; wc.cbSize=sizeof(WNDCLASSEX); wc.style=CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc=WndProc; //プロシージャ名 wc.cbClsExtra=0; wc.cbWndExtra=0; wc.hInstance=hInst;//インスタンス wc.hIcon=(HICON)LoadImage(NULL, MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE |LR_SHARED); wc.hCursor=(HCORSOR)Loadimage(NULL, MAKEINTRESOURCE(IDC_ARROW), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED); wc.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH); wc.lpszMenuName=NULL;//メニュー名 wc.lpszClassName=(LPCSTR)szClassName; wc.hIconSm=(HICON)LoadImage(NULL, MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED); return(RegisterClassEx(&wc)); } //ウィンドウの作成 BOOL InitInstance(HINSTANCE hInst,int nCmsShow) { HWND hWnd; hWnd=CreateWindow(szClassName, //タイトルバーにこの名前が表示される "犬でもわかるWindowsプログラミング", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInst, NULL); if(!hWnd) return FALSE; ShowWindow(hWnd,nCmdShow); UpdateWindow(hWnd); return TRUE; } //ウィンドウプロシージャ LRESULT CALLBACK WndProc(HWND hWnd,UINT msg,WPARAM wp,LPARAM lp) { switch(msg){ case WM_DESTROY: PostQuitMessage(0); break; dafault: return(DefWindowProc(hWnd,msg,wp,lp)); } return 0; }
- ベストアンサー
- C・C++・C#
- WinAPIでの画像高速切り替え表示プログラム2
1の続きです。これを先に見た方は1から見てください。 お願いします。 int WINAPI WinMain( HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR lpCmdLine,int nCmdShow) { WNDCLASS wc; MSG msg; wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WindowProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL,IDI_APPLICATION); wc.hCursor = LoadCursor(NULL,IDC_ARROW); wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = __FILE__; if(!RegisterClass(&wc)) return 0; HWND hWnd=CreateWindow( __FILE__," ", WS_POPUP | WS_VISIBLE, 0,0, 1024,768, NULL,NULL,hInstance,NULL); if(hWnd==NULL) return 0; // タイマを作成する SetTimer( hWnd, TIMER_ID, TIMER_ELAPSE, NULL ); BOOL bRet; while((bRet=GetMessage(&msg,NULL,0,0))!=0){ if(bRet==-1) break; DispatchMessage(&msg); } // タイマを破棄する KillTimer( hWnd, TIMER_ID ); return (int)msg.wParam; } 2つに分かれてしまって申し訳ありません。 よろしくお願いします。
- ベストアンサー
- C・C++・C#
- Windowsプログラミング
識別子が無効ですといわれて困ってます。一応打ち込んだものを乗せておきます。VisualC++2008でやりました。 // sample01.cpp #include<windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); ATOM InitApp(HINSTACE); BOOL InitInstance(HINSTANCE); TCHAR szClassName[] = TEXT("sample01"); // ウィンドウクラス int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow) { MSG msg; BOOL bRet; if (!InitApp(hCurInst)) return FALSE; if (!InitInstance(hCurInst, nCmdShow)) return FALSE; while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0) { if (bRet == -1) { MessageBox(NULL, TEXT("GetMessageエラー"), TEXT("Error"), MB_OK); break; } else { TranslateMessage(&msg); DispatchMessage(&msg); } } } // ウィンドウクラスの登録 ATOM InitApp(HINSTANCE hInst) { WNDCLASSEX wc; wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndPrec; // プロシージャ名 wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInst; // インスタンス wc.hIcon = (HICON)LoadImage(NULL, MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED); wc.hCursor = (HCURSOR)LoadImage(NULL, MAKEINTRESOURCE(IDC_ARROW), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED); wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wc.lpszMenuName = NULL; // メニュー名 wc.lpszClassName = szClassName; wc.hIconSm = (HICON)LoadImage(NULL, MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON 0, 0, LR_DEFAULTSIZE | LR_SHARED); return (RegisterClassEx(&wc)); } // ウィンドウの生成 BOOL InitInstance(HINSTANCE hInst, int nCmdShow) { HWND hWnd; hWnd = CreateWindow(szClassName, // タイトルバーにこの名前が表示されます TEXT("猫でもわかるWindowsプログラミング"), WS_OVERLAPPEDWINDOW, // ウィンドウの種類 CW_USEDEFAULT // x座標 CW_USEDEFAULT // y座標 CW_USEDEFAULT // 幅 CW_USEDEFAULT // 高さ NULL, // 親ウィンドウのハンドル、親を作るときはNULL NULL, // メニューハンドル、クラスメニューを // 使うときはNULL hInst, // インスタントハンドル NULL); if (!hWnd) return FALSE; ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } // ウィンドウプロシージャ LRESULT CALLBACK WndProc(HWND hWnd, UNIT msg, WPARAM wp, LPARAM lp) { switch (msg) { case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wp, lp)); } 長いですがよろしくお願いします。 return 0; }
- ベストアンサー
- C・C++・C#
- C言語でWin32APIを使い、子ウィンドウを表示したいのですが。。。
いつもお世話になっております。 小生、只今C言語とWin32APIを使い、WindowsXPSP3上で、BCC5.5.1を使用し、Windowsプログラミングを勉強しています。 今回、子供ウィンドウを表示しようとしたのですが、 下記のコードをコンパイルしても、子供ウィンドウが表示されません。 大変、申し訳ございませんが、先輩方、アドバイス宜しくお願いします。 /* 子供ウィンドウを作成 */ #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); ATOM InitApp(HINSTANCE, LPCSTR); BOOL InitInstance(HINSTANCE, int, LPCSTR); int WINAPI WinMain( HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow) { MSG msg; BOOL bRet; LPCSTR szClassName = "ChildWindow"; if(!InitApp(hCurInst, szClassName)){ return FALSE; } if(!InitInstance(hCurInst, nCmdShow, szClassName)){ return FALSE; } while((bRet = GetMessage(&msg, NULL, 0, 0)) != 0){ if(bRet == -1){ MessageBox(NULL, "GetMessage Error", "Error", MB_OK); break; } else{ TranslateMessage(&msg); DispatchMessage(&msg); } } return (int)msg.wParam; } //ウィンドウクラスの登録 ATOM InitApp(HINSTANCE hInst, LPCSTR szClassName) { WNDCLASSEX wc; wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInst; wc.hIcon = (HICON)LoadImage( NULL, MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED); wc.hCursor = (HCURSOR)LoadImage( NULL, MAKEINTRESOURCE(IDC_ARROW), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED); wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = (LPCSTR)szClassName; wc.hIconSm = (HICON)LoadImage( NULL, MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED); return (RegisterClassEx(&wc)); } //ウィンドウの生成 BOOL InitInstance(HINSTANCE hInst, int nCmdShow, LPCSTR szClassName) { HWND hWnd; hWnd = CreateWindow( szClassName, "Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInst, NULL); if(!hWnd){ return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } //ウィンドウプロシージャ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { static HWND hWndChild; HINSTANCE hInst; switch(msg){ case WM_CREATE: hInst = ((LPCREATESTRUCT)lp)->hInstance; hWndChild = CreateWindow( "Child", "子供ウィンドウ", WS_CHILD | WS_SYSMENU | WS_THICKFRAME | WS_CAPTION | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, 200, 100, hWnd, 0, hInst, NULL); ShowWindow(hWndChild, SW_SHOW); UpdateWindow(hWndChild); break; case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wp, lp)); } return 0; }
- ベストアンサー
- 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#
お礼
回答をありがとうございます。 回答者様のおっしゃる通り、PostQuitMessage()をコメントアウトしてWM_CREATEを失敗させるとMessageBoxが表示されました。ということは確かにWM_DESTROYのケースが行われている訳ですが、PostQuitMessage()が存在する場合でもMessageBoxのサウンドだけなるということは、やはり if (hWnd == NULL) のところのreturn 0; でプログラムが終了しているようです。 なぜ表示されないかについては興味深いのでもう少し他の書籍で勉強してみたいと思います。 何度もの詳しい回答、参考ページの紹介など、いろいろ本当にありがとうございました。