dポイントプレゼントキャンペーン実施中!

「猫でもわかるC言語プログラミング」で独習しております。
深い意味などは分からないところも多いのですが
慣れるためにひたすらコーディングしております。
質問が要領を得ないかもしれませんがお許しください。
補足が必要でしたら教えてください。

第11章の最後の課題なのですが、Windowsのウィンドウを作成する課題になります。
いろいろ調べましたがエラーの原因がわかりません。

45、51、59行目でエラーがでており、
データのサイズ違いのようなのですが
そのあとの「undefined reference to `GetStockObject@4'」
の部分が調べてみたのですが、わかりません。


エラー内容と、コードを以下に記します。
もしよろしければどなたかアドバイスお願いします。
よろしくお願いいたします。

***環境***
エディタ:サクラエディタ
コンパイラ:MinGW

***エラー内容***
C:\source2\c11>g++ -Wall template01.cpp
template01.cpp: In function `ATOM InitApp(HINSTANCE__*)':
template01.cpp:45: warning: cast from pointer to integer of different size
template01.cpp:51: warning: cast from pointer to integer of different size
template01.cpp:59: warning: cast from pointer to integer of different size
C:\Users\****\AppData\Local\Temp/ccgXbaaa.o(.text+0x14f):template01.cpp: undefin
ed reference to `GetStockObject@4'

***実際のコード***
// template.cpp

#include <windows.h>

LRESULT CALLBACK WndProc(HWND, UINT ,WPARAM, LPARAM);
ATOM InitApp(HINSTANCE);
BOOL InitInstance(HINSTANCE, int);

char szClassName[] = "template";//ウィンドウクラス


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;
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 = (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)
{
HWND hWnd;

hWnd = CreateWindow(szClassName,
//タイトルバーにこの名前が表示されます
"windowを作成",
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, UINT msg, WPARAM wp, LPARAM lp)
{
int id;

switch(msg) {
case WM_CLOSE:
id = MessageBox(hWnd,
"終了してもよろしいですか",
"確認",
MB_YESNO | MB_ICONQUESTION);
if (id == IDYES)
DestroyWindow(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return (DefWindowProc(hWnd, msg, wp, lp));
}
return 0;
}

A 回答 (3件)

ソースコードの検証をしてないので当てずっぽうですが


0の代わりにNULLとしてみたらどうでしょう。

NULLはポインタが何も指していない状態です。
(ちなみにHINSTANCEはvoid*やint*と同じようにポインタ)
VisualStudioだと0もNULLも一緒なんですが、MinGWでは0とNULLを区別しているのでは?
    • good
    • 0
この回答へのお礼

お礼が大変遅くなってしまいました。

実は試してみましたが、残念ながらうまくいきませんでした。

しかし、大変参考になっております。

もう少しレベルアップしたのちに改めて試してみたいと思います。
ありがとうございました。

お礼日時:2010/04/25 15:43

MinGW でWindowsアプリケーションをコンパイルする場合に、


GetStockObjectが見つからないなら、
「-mwindows」オプションを指定してみると良いかも。

C:\source2\c11>g++ -Wall template01.cpp -mwindows
のような感じです。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます!

「-mwindows」オプション指定で見事に
「GetStockObject」が見つからないエラーはなくなりました。

オプション指定の意味もぐっと理解が深まりました!
ありがとうございます。

「 warning: cast from pointer to integer of different size」
の方が未だ未解決ですが、いろいろ試行錯誤してみたいと思います。
ひとまずお礼まで。。

お礼日時:2010/04/10 11:05

> C:\source2\c11>g++ -Wall template01.cpp


> template01.cpp: In function `ATOM InitApp(HINSTANCE__*)':
> template01.cpp:45: warning: cast from pointer to integer of different size
> template01.cpp:51: warning: cast from pointer to integer of different size
> template01.cpp:59: warning: cast from pointer to integer of different size

これはコンパイラがtemplate01.cppをコンパイルしたら関数InitApp()で3つのwarningがあったということです。
行番号の確認が取れないので分かりませんが、おそらくこの3つのwarningはLoadImageの第1引数がNULLで書かれているために出ているものと思われます。(HINSTANCE)でキャストすれば良いのではないでしょうか。
もっとも、エラーの本体はこれではありません。

> C:\Users\****\AppData\Local\Temp/ccgXbaaa.o(.text+0x14f):template01.cpp: undefin
ed reference to `GetStockObject@4'

これはリンク時に「GetStockObject@4」というシンボル名が見つからないというエラーが出ているようですね。関数GetStockObject()の実体が無いということです。コンパイル時のリンクオプションで該当するライブラリが指定されていないということです。

この回答への補足

質問を重ねて申し訳ないのですが、
warning: cast from pointer to integer of different size
のエラーが改善しません。

以下試してみましたが、LoadImageを3つとも
(HINSTANCE)でキャストしてみましたが
以下のエラーが出てしまいました。

template01.cpp:55: error: cannot convert `HINSTANCE__*' to `HICON__*' in assignment

もしよろしければアドバイスお願いします。

完全理解までは遠いですが、おかげさまで
「これをわかるためにはこれが」
「これをわかるためにはこれが」と芋づる式に
理解が深まりました。
考えるより手を動かすのがやっぱりいいみたいですね!
質問してよかったです。
それぞれのアドバイスの意味が分かるよう
復習に勤しみます。本当にありがとうございました。

再質問が再びお目に留まるかもしれませんので、
しばらく締め切らずに置いておきたいと思います。

補足日時:2010/04/10 11:05
    • good
    • 0
この回答へのお礼

分かりやすい解説ありがとうございました。
正直まだ知識が追い付いていませんが、
何がわからないかが見えただけでも大きな進歩です。
今後も何度も見返して確認しながら学びたいと思います。

ホントにうれしいです。
ありがとうございました!

お礼日時:2010/04/10 10:19

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!