• ベストアンサー

プロトタイプが必要な場合

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

  • A__
  • お礼率59% (194/328)

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

  • ベストアンサー
  • a-kuma
  • ベストアンサー率50% (1122/2211)
回答No.2

関数の定義は、宣言を兼ねますから、質問にあるソースでは必要ありません。 もちろん、ひとつのファイルに存在すれば、ということですが。 これは、C でも C++ でも同じです。

A__
質問者

お礼

ありがとうございます。

その他の回答 (2)

  • s2t
  • ベストアンサー率79% (47/59)
回答No.3

C++の場合はプロトタイプ宣言は必須というのは初耳ですが、関数の定義が使用される位置よりも前に記述されていれば、CでもC++でもプロトタイプ宣言は省略できます。 どの位置に宣言されていても省略できるというわけではないので注意してください。 質問にあるソースでは、Func()より前に記述している関数で利用していないのでFunc()のプロトタイプ宣言を省略できます。 WndProc()がFunc()よりも前に記述されている場合は、プロトタイプ宣言が必要になります。 もしも、Func()がこのファイル内でしか用いられない関数であればstaticを付けておいた方がいいかもしれません。デフォルトではexternになっていたと記憶しています。

A__
質問者

お礼

ありがとうございます。 違う意見が出たから閉じずに待っていました。 このソースならプロトタイプ宣言は省略できるんですね。 関数にstaticとかexternとかを付けるとどうなるのかについて 知らなかったから勉強しようと思いました。

  • sha-girl
  • ベストアンサー率52% (430/816)
回答No.1

Cの場合は省力可能でしたが C++の場合はプロトタイプ宣言は 必須です。

A__
質問者

お礼

ありがとうございます。

関連するQ&A

  • 何もしないメッセージだけ表示するウィンドウ

    ゲーム用に何もしないメッセージだけ表示するウィンドウを作りたいのですが、 猫でもわかるゲームプログラミングのコードが間違っているのか、 機能しません。 #include <windows.h> LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp); int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow) { return (int)msg.wParam; } LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { switch (msg){ } return 0; } このように、打ち込んだのですが、どこが間違っているのか解りません。 回答お願いいたします。

  • msgが定義されていない

    Visual Studio2019でwindowsアプリケーションでゲームを作っているんですが、 どうやってもmsgが定義されていないが直りません。 #include <windows.h> LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp); //WinMain関数 int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow) { //ウィンドウクラスの登録 //メインウィンドウの生成 //メッセージループ return (int)msg.wParam; } //ウィンドウプロシージャ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) { switch (msg) { //メッセージごとにやりたいことを記述する } return 0; } ご教示お願いします。

  • 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' に変換できません。 です。

  • グローバルで宣言

    HWND g_wnd; のようにグローバルで宣言して1つのウインドウを作った場合、 それに対応するWndProcで LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg ,WPARAM wp, LPARAM lp) { ここでは、hwndとg_wndはどっちを使っても同じですか? }

  • クラス内にWin32APIのコールバック関数がある場合

     Win32APIをC++で作成しようとしているのですが、途中どのようにしたらいいのか分からないのでここで質問させていただきました。  Win32をC++で作成するためクラス内にウィンドウの登録、設定の関数を用意したのはいいのですが、CALLBACK関数を含めて実行しようとするとウィンドウの登録の際に、エラーが起きるようです。 /*////////////////////////////////////////// ウィンドウ・クラスの登録 //////////////////////////////////////////*/ ATOM windCreate::InitApp(void) {         (省略)      wc.lpfnWndProc = WndProc; //ここでエラー         (省略)      return RegisterClassEx(&wc); } エラー内容は下記の通りです。 error C2440: '=' : 'LRESULT (__stdcall windCreate::* )(HWND,UINT,WPARAM,LPARAM)' から 'WNDPROC' に変換できません。  クラスの宣言は以下の通りです。 class windCreate{     // WinMain インスタンスハンドルへのアクセス      public:         HINSTANCE hInst;      private:         WNDCLASSEX wc;         LPSTR szClassName;         HWND hWnd;         RECT w_rect;         SIZE window_size;      public:         ATOM InitApp(void);         BOOL InitInstance(int nCmdLine);       //ここがシステムから呼び出されるコールバック関数                              LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);          ---------(以下省略)--------- };  ウィンドウからのメッセージ受取を行う関数なんですが、どうしたら エラーなく実行できるのでしょうか?

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

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

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

  • 別関数に渡す変数のポインタが難しい

    構造体初心者で、ポインタもよく分かっていません。 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言語でWindowsのプログラミングを学習中ですが あるプロトタイプ宣言した自作の関数がエラーになってしまいます。 エラー内容は「未解決の外部シンボル・・・」といった内容です。 関数の引数をHWNDだけにした場合は問題ありませんでした。 環境はMicrosoft Visual C++ 2008 Express Editionです。 自作関数の引数に型の制限はあるのでしょうか? よろしくお願いします。 以下コード一部です LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM); int MySave(TCHAR *,HWND,int); ・ ・ ・ LRESULT CALLBACK WndProc(HWND hWnd,UINT msg,WPARAM wp,LPARAM lp) { THCAR buffer[1024]; int iCount; ・ ・ ・ MySave(buffer,hWnd,iCount); ・ ・ ・ } int MySave(buffer,hWnd,iCount); ・ ・ ・ }

  • GetModuleFileNameでエラーが出てしまう。

    #include<windows.h> #include<string.h> // 関数のプロトタイプ宣言 VOID CALLBACK TimerProc(HWND hwnd,UINT uMsg,UINT idEvent,DWORD dwTime); BOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM lParam); // エントリポイント int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MSG msg; EnumWindows((WNDENUMPROC)EnumWindowsProc,NULL); while(GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } BOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM lParam) { char Caption[201]; char FileName[1024]=""; char FindList[1][80]={"Microsoft Internet Explorer"}; GetWindowText(hwnd, Caption, 200); for(int i=0;i<=0;i++) if(NULL!=strstr(Caption,FindList[i])) { HINSTANCE hInst; hInst = (HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE); if(GetModuleFileName(hInst, FileName, 1023)!=0) { // ファイル名取得成功したときの動作 MessageBox(NULL,Caption,FileName,MB_OK|MB_SETFOREGROUND); }else{ MessageBox(NULL,Caption,"Error",MB_OK|MB_SETFOREGROUND); } } return true; } 実行するとIEが起動されてたらそのウインドウのキャプションとプログラム名を表示される予定なのですが、 GetModuleFileNameでエラーが返されます。 何が原因なのでしょう?

専門家に質問してみよう