オーナー付きウィンドウと子ウィンドウについて

このQ&Aのポイント
  • オーナー付きウィンドウと子ウィンドウについて詳しく調べた結果、WS_CHILDを消すと終了してしまう理由を知りたいです。
  • サイトで見つけたオーナー付きウィンドウと子ウィンドウについてのコードに関して、WS_CHILDを消すと終了してしまう現象が起きるようです。その理由について調査しました。
  • オーナー付きウィンドウと子ウィンドウのプログラムにおいて、WS_CHILDを消すと終了してしまう現象が発生しますが、その原因について解明したいです。
回答を見る
  • ベストアンサー

オーナー付きウィンドウと子ウィンドウについて

http://web.kyoto-inet.or.jp/people/ysskondo/chap7.html​ のサイトで気になったのですが、 このサイトの hChildWnd=CreateWindow( "SubWindowClass","子ウインドウ", WS_CAPTION|WS_THICKFRAME|WS_CHILD, 10,10,200,100,hwnd,(HMENU)1, cs->hInstance,0); の|WS_CHILDを消すと if((hOwnedWnd==NULL)||(hChildWnd==NULL)) return -1; のところで終了してしまうのですが、 なぜなのでしょうか?

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

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

API のリファレンスを見ると、CreateWindow() 10番目の引数は HMENU hMenu, // メニューハンドルまたは子ウィンドウ ID となっていました。 WS_CHILD ありの場合、メニューハンドルではなく子ウィンドウのIDとして解釈されますので、 (HMENU)1 は ID = 1 を割り当てていることになります。 一方、WS_CHILD を指定せず、(HMENU)1 をセットした場合はメニューハンドルとして解釈されますが、値が 1 のメニューハンドルは作成されていないので、CreateWindow() が失敗して NULL を返します。

その他の回答 (1)

  • jmh
  • ベストアンサー率23% (71/304)
回答No.1

リンクは 404 でした。MSDN には、If the function fails, the return value is NULL. To get extended error information, call GetLastError. とあるので GetLastError() を呼ぶんじゃないでしょうか?

参考URL:
http://msdn.microsoft.com/en-us/library/ms632679%28VS.85%29.aspx

関連するQ&A

  • ListBoxコントロール

    hLB1=CreateWindow ("LISTBOX","",WS_CHILD|WS_VISIBLE|LBS_STANDARD, 0,0,300,150,hwnd,(HMENU)1,cs->hInstance,NULL); hLB2=CreateWindow ("LISTBOX","",WS_CHILD|WS_VISIBLE|LBS_STANDARD, 0,160,300,150,hwnd,(HMENU)2,cs->hInstance,NULL); という風に2つのListBoxコントロールを作っているサンプルを見たのですが (HMENU)1と(HMENU)2のところをともにNULLにしたら問題なのでしょうか。

  • 1つのウィンドウに2つのエディット

    case WM_CREATE:  GetClientRect(hWnd, &rc);  EditL = CreateWindow(  TEXT("EDIT") , NULL ,  WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL |  ES_AUTOHSCROLL | ES_AUTOVSCROLL |  ES_LEFT | ES_MULTILINE ,  0 , 0 , rc.right / 2 , rc.bottom , hWnd , (HMENU)1 ,  ((LPCREATESTRUCT)(lParam))->hInstance , NULL);  EditR = CreateWindow(  TEXT("EDIT") , NULL ,  WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL |  ES_AUTOHSCROLL | ES_AUTOVSCROLL |  ES_LEFT | ES_MULTILINE ,  rc.left / 2 , 0 , rc.right , rc.bottom , hWnd , (HMENU)2 ,  ((LPCREATESTRUCT)(lParam))->hInstance , NULL);  return FALSE; とすると、1つのエディットしか表示されません。 また、 case WM_SIZE:  GetClientRect(edit, &rc); MoveWindow(edit, rc.left, rc.top, rc.right, rc.bottom, TRUE); として、ウィンドウサイズが変更された時に どちらのエディットもクライアント領域にあわせたつもりなのですが、 サイズ変更で左側のエディットがスクロールバーの幅の分だけ 縮小されてしまいます。 どこをどのように直したらよろしいのでしょうか? 宜しくお願いします。 #Win98 & VC++6.0 & SDK で作成しています。

  • 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; }

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

    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; }

  • Tabでのフォーカス(win32)

    edit = CreateWindow( TEXT("EDIT") , NULL , WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_NUMBER | ES_LEFT , 0 , 0 , 35 , 18 , hWnd , (HMENU)1 , ((LPCREATESTRUCT)(lParam))->hInstance , NULL ); でエディットコントロールを作成しました。 フォーカスがエディットコントロールにある時、TABキーで フォーカスをなくしたいのですが、どうしたらよいでしょうか? デバッガーで追ってみると、WM_KEYDOWNがウィンドウに送られていませんでした。

  • Windowハンドルを再利用できない

    hPushBox=CreateWindow("BUTTON","a",WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,0,0,0,0,hW,HMENU(0), ((LPCREATESTRUCT)lP)->hInstance,NULL);DestroyWindow(hPushBox); hPushBox=CreateWindow("BUTTON","a",WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,0,0,0,0,hW,HMENU(0), ((LPCREATESTRUCT)lP)->hInstance,NULL);DestroyWindow(hPushBox); Window処理関数で上記のようにするとコンパイルは通るのに実行がエラーになります 1度使ったハンドルをウィンドを破棄した後使えるようにするにはどうしたらいいのでしょうか?

  • ボタンの文字の大きさを変更したい

    CreateWindow によるボタンを作成してみたのですが、 ボタンラベルとして貼る以下の "明朝" という文字の大きさを 変えるにはどうすればいいのでしょうか。 hButtonWnd1 = CreateWindow("BUTTON", "明朝",               S_CHILD | WS_VISIBLE | BS_PUSHBUTTON,               20, 20, 100, 30,               hWnd,               (HMENU)ID_MI,               hInst,               NULL);

  • ウィンドウ枠をいちいち作るのがめんどくさい

    ウィンドウの作成の部分を書き出してみました。 BOOL InitInstance(HINSTANCE hInst,int nCmdShow) { HWND hWnd; hWnd=CreateWindow(szClassName, TEXT("文字列を表示する"); 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; } 毎回やるのはめんどくさいのでコピー&ペーストでもいいでしょうか? または、覚えた方がいいのでしょうか?

  • 再起動したとき前起動分を強制終了するには?

    WINAPI WinMain(HINSTANCE hI,HINSTANCE,LPSTR,int nCS) { WNDCLASS wc; HWND hW; MSG ms; wc.lpszClassName ="goo"; wc.lpfnWndProc =(WNDPROC)WinProcedure; wc.hInstance =hI; wc.style =CS_HREDRAW|CS_VREDRAW; wc.cbClsExtra =NULL; wc.cbWndExtra =NULL; wc.hIcon =LoadIcon(NULL,IDI_EXCLAMATION); wc.hCursor =LoadCursor(NULL,IDC_ARROW); wc.hbrBackground =(HBRUSH)(COLOR_WINDOW+1); wc.lpszMenuName =NULL; RegisterClass(&wc); hW=CreateWindow ( "goo", "教えてgoo", WS_OVERLAPPED|WS_CAPTION|WS_THICKFRAME |WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_SYSMENU, 0, 0, 640, 480, NULL, NULL, hI, NULL ); ShowWindow(hW,nCS); UpdateWindow(hW); while(GetMessage(&ms,NULL,NULL,NULL)) { TranslateMessage(&ms); DispatchMessage(&ms); } return (ms.wParam); } のプログラムが2回目に起動したとき1回目の起動を強制終了するにはどうしたらいいのでしょうか?

  • 子ウィンドウの作成方法

    #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); ATOM InitApp(HINSTANCE); BOOL InitInstance(HINSTANCE, int); TCHAR szClassName[] = TEXT("Window01"); TCHAR szClassName2[] = TEXT("Window02"); 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) { break; } else { TranslateMessage(&msg); DispatchMessage(&msg); } } return (int)msg.wParam; } ATOM InitApp(HINSTANCE hInst) { WNDCLASSEX wc; WNDCLASSEX wc2; 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 = szClassName; wc.hIconSm = (HICON)LoadImage( NULL, MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED); wc2.cbSize = sizeof(WNDCLASSEX); wc2.style = CS_HREDRAW | CS_VREDRAW; wc2.lpfnWndProc = WndProc; wc2.cbClsExtra = 0; wc2.cbWndExtra = 0; wc2.hInstance = hInst; wc2.hIcon = (HICON)LoadImage( NULL, MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED); wc2.hCursor = (HCURSOR)LoadImage( NULL, MAKEINTRESOURCE(IDC_ARROW), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED); wc2.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); wc2.lpszMenuName = NULL; wc2.lpszClassName = szClassName; wc2.hIconSm = (HICON)LoadImage( NULL, MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED); if((RegisterClassEx(&wc)||RegisterClassEx(&wc2)==0)) return 0; return TRUE; } BOOL InitInstance(HINSTANCE hInst, int nCmdShow) { HWND hWnd; HWND hWnd2; hWnd = CreateWindow(szClassName, TEXT("親ウィンドウ"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInst, NULL ); if(!hWnd) return FALSE; hWnd2 = CreateWindow(szClassName2, TEXT("子ウィンドウ"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hWnd, NULL, hInst, NULL ); if(!hWnd2) return FALSE; ShowWindow(hWnd, nCmdShow); ShowWindow(hWnd2, nCmdShow); UpdateWindow(hWnd); UpdateWindow(hWnd2); 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; } 子ウィンドウの作り方を理解したく、ただウィンドウを表示するプログラムを作ろうとしました。 しかし、うまくいきません。 一体なにがダメなんでしょうか?

専門家に質問してみよう