• ベストアンサー

hInstanceについて(Windowsプログラミング SDK)

いつもお世話になっております。^^) WindowsのSDKで基本を少し勉強しています。 ウインドクラスの定義のところで、アプリケーションのhInstanceを登録しているのですが、CreateWindowでも第10引数で、アプリケーションのhInstanceをいれなくてはいけません。 ウインドウクラスを定義した時点で、hInstanceはわかっているのに、どうして、CreateWindowの引数で必要になってくるのでしょうか?

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

  • ベストアンサー
  • mitoneko
  • ベストアンサー率58% (469/798)
回答No.2

 当時の資料を失ってしまったので、うろ覚えですが・・・  windows 95の頃(確か、98も同じだったかな)は、メモリー空間が、今のwin2k以降のシステムのように完全に分離されていませんでした。また、メモリーもそんなに豊富に使える環境ではありませんでしたから、同じアプリケーションが作成した同じクラスのwindowのクラス定義データは、すべての実行インスタンスで共有していました。ウィンドウクラス定義において同じくラスの登録が2回目以降に実行された時には、前回のものを流用する形にして、同じハンドルを返していた記憶があります。もちろん、この形でクラス定義を登録しても、CreateWindowでは、実行インスタンスごとに、Windowを作成する必要がありますし、インスタンスも識別する必要があります。(でないと、同じプログラムのインスタンスが2つある時に、メッセージの処理が混乱しますから。)そこで、CreateWindowにも、hInstanceが必要になることになります。  win95の時代には、実に多彩なデータを、同時に実行された同じアプリケーション同士では共有していました。それらのデータを利用する際に、違うインスタンスを識別するために、このhInstanceというハンドルが必要だったわけです。(昔、win95の時代には、このhInstanceの特性を利用して、アプリケーションの同時実行の制御(たとえば、同時実行の禁止とか、2回目以降では違う挙動をするとか・・・)が簡単にできました。)  ところが、win2k以降のOSでは、同じアプリケーションを2つ同時に実行しても、お互いのメモリー空間は完全に遮断されるようになりました。いくら同じアプリケーションだからといって、メモリーを共有するなどと言うことはいっさいしていませんから、hInstanceそのものに意味が無くなりました。ですから、まぁ、なぜ必要なのという質問そのものに意味が無くなってます。  ちなみに、windows APIのインターフェースを変えることはアプリケーションの互換性を唱ってしまった限りはできませんでしたので、この引数も依然として残っています。  記憶で書いているので、自信のほどはなしとしておきます。大筋あっているはずですけど・・・

その他の回答 (2)

noname#30727
noname#30727
回答No.3

CreateWindow の lpClassName には、既存クラスの BUTTON や EDIT などが使用できます。 そのことから、理屈の上では、両者の hInstance が同じであるとは限りません。 DLL のメカニズム上、そうするしかなかったんでしょうね。

回答No.1

# 回答になってませんが。 MSDNを見ると、CreateWindow の第十引数は、 「NT/2000 では無視されます」だそうです。 過去の設計を引きずってるんですかねぇ……

参考URL:
http://www.microsoft.com/japan/msdn/library/ja/jpwinui/html/_win32_createwindow.asp

関連するQ&A

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

  • ウィンドウサイズ 変更

    いつもお世話になっております。 初心者ですが、VS2005でC++を利用してWindowsアプリケーションの作成を行っています。 初歩的なことなのかもしれませんが、 Webで調べても良い情報が得られなかったため質問させていただきます。 はじめに CreateWindow で作成したウィンドウのサイズを変更したい場合、 何か関数があるのでしょうか。 それとも再度 CreateWindow でサイズ指定するべきなのでしょうか。 ご教授お願いいたします。

  • ウィンドウクラスの指定について

    いつもお世話になっていますGedankenです。 ウィンドウズプログラムについて素朴な質問があります。 Win32 API プログラミング(C言語)ではRegisterClass などで登録した ウィンドウクラスをCreateWindow を使う時"文字列"で指定すると思いますが なぜそんなに回りくどいことをするのでしょうか。 普通に考えれば構造体へのポインタなどで指定した方がスマートだと 思うのですが、どうなのでしょうか。 多分ちゃんとした理由があると思いますが、そこについて解説お願いします。 よろしくお願いします。

  • スレッド内でのマルチスレッドの作成[WINDOWSプログラミング]

    いつもお世話になっております。 現在WINDOWSプログラムでゲームを最中なのですが、スレッド内でスレッドを作成できなくて困っています。 キャラを動かすスレッドで以下の関数を使い、スレッドを作成しようとしたのですが、 CreateThread(NULL, 0, ATK, (LPVOID)&x, 0, &dwID); 以下のようなエラーメッセージが出てしまいます。 'ATK':定義されていない識別子です '関数' : 間接参照のレベルが 'LPTHREAD_START_ROUTINE' と 'int' で異なっています。 'CreateThread' : の型が 3 の仮引数および実引数と異なります。 わかる方いましたらどうがご指導お願いします。 初歩的なミスでしたらすみません。

  • VCでバッチソフト

    勉強でWindowsで動くテキストを加工するツールを作成したいのですが、 一瞬黒い画面が現れるので、 Visual C++ → Win32 → Win32コンソールアプリケーション → コンソールアプリケーション → 空のプロジェクトではなく Visual C++ → Win32 → Win32コンソールアプリケーション → Windowsアプリケーション → 空のプロジェクトで合っていますよね。 int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR pCmdLine, int showCmd) を宣言するのですが、引数はどうやって渡すのですか? またお勧めのVCでC言語を勉強できる本があれば教えてください。

  • ボタン内の文字サイズ変更

    いつもお世話になっています。 Windowsのアプリケーションを作っていますがCreateWindow()で作った通常ウインドウ上に配置されたボタンの中に書かれた文字のサイズを変更する方法が分かりません。 ご存知の方がいらっしゃいましたらなにとぞご教授下さい。 宜しくお願いします。

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

  • staticコントロール

    CreateWindow( "static", // スタティックコントロールのクラス名 "text is here.", // 表示する文字列 SS_SIMPLE | WS_CHILD | WS_VISIBLE, // 詳細はあとで。 x, y, // 左上の座標 iWidth, iHeight, // 幅と高さ hParent, // 親ウインドウのウインドウハンドル NULL, // メニューハンドル。NULLでよい。 hInstance, // アプリケーションのインスタンスハンドル。 NULL // ウインドウ作成データ。NULLでよい ) ; のメッセージを処理したいのですが既成のwindowなのでどのようにウィンドウ処理関数を指定すればいいのかわかりません。 自分で登録した場合にはウィンドウ処理関数を指定できますが既成の場合どうするのでしょうか。

  • C++プログラミングの手順

    C++を勉強しはじめてすごく基本的な部分は理解できました。 でも、それはあくまで知識であり実践となりますと話は別です。 いままでは、ライブラリという他人の作ったクラスを使用してプログラミングをしてきましたが、 だんだん奥深くに入り込むと、自分のわがままに会ったクラスがほしくなってきます。 でもいざクラスを作ろうとしたら、 プログラマの方々はクラスの定義を先にするか、ソースから作ってゆくのでしょうか? クラスを作る手順を教えてください。

  • MDIでのダイアログ生成

    VC++2005でMDIアプリケーションを作成しています。 ダイアログベースでは、DoModal()にてダイアログを生成していましたが、 MDIでのダイアログ生成の方法が分かりません。。 調べた結果、 (1)CreateWindow()にてクライアントウィンドウを作成 (2)CreateMDIWindow()にて子ウィンドウを作成 の順序で処理を行うことは分かりましたが、 関数の一部の引数に何を設定してやれば良いのかが不明です。。 ※下記はネット上にあったサンプルソースです。  「???」の箇所が不明な引数です。 (1) CreateWindow(   TEXT("MDICLIENT"), //MDICLIENT は固定です   NULL,   WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN,   0, 0, 0, 0,   hWnd,       //メインウィンドウのハンドル←???   (HMENU)1,    //←???   hInst,       //インスタンスハンドル←???   (LPSTR)&ccs    //CLIENTCREATESTRUCT構造体のポインタ←???  ); (2) HWND CreateMDIWindow(  MDI_CHILD ,   //ウィンドウクラス名  TITLE ,     //ウィンドウのタイトルバーテキスト  0 ,       //ウィンドウスタイル。WS_MAXIMIZE(最大化表示)など  CW_USEDEFAULT , //X座標  CW_USEDEFAULT , //Y座標  CW_USEDEFAULT , //幅  CW_USEDEFAULT , //高さ  hClientWindow , //クライアントウィンドウのハンドル ←???  hIns ,      //インスタンスハンドル       ←???  0        //アプリケーション定義の値 ); なお、行いたい処理の流れとしては、 CTestDialogクラスより、CTest2Dialogクラスのダイアログを、 呼び出したいのです。 うまく説明できず申し訳ありませんが、 お詳しい方おられましたら、具体例など交えてご説明頂けると幸いです。 お手数ですが、どうか宜しくお願い致します。

専門家に質問してみよう