質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.03%

TextOut、GetStockObjectが見つからないとでる

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 694

yukkuri

score 556

 前提・実現したいこと

Win32APIでウィンドウを表示しようとしたら、エラーが発生しました。

 発生している問題・エラーメッセージ

MBox.cpp: In function 'int WinMain(HINSTANCE__*, HINSTANCE__*, TCHAR*, int)':
MBox.cpp:30:59: error: '_GetStockObject' was not declared in this scope
MBox.cpp: In function 'LRESULT WndProc(HWND__*, UINT, WPARAM, LPARAM)':
MBox.cpp:71:50: error: '_TextOut' was not declared in this scope

 該当のソースコード

#include <windows.h>
#include <tchar.h>

/**
 * ウィンドウプロシージャー
 */
LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );

TCHAR szClassName[] = TEXT( "line" );
/**
 * メイン関数
 */
int WINAPI _tWinMain( HINSTANCE hInstance, HINSTANCE hPreInst, TCHAR* lpsCmdLine, int nCmdShow )
{
/*    if( MessageBox( 0, TEXT( "hello!" ), TEXT( "message" ), MB_YESNO ) == IDYES ){
        MessageBox( 0, TEXT( "yes" ), TEXT( "結果" ), MB_OK );
    }*/
    HWND hWnd;
    MSG lpMsg;
    WNDCLASS wc;

    if( !hPreInst ){
        wc.style = CS_HREDRAW | CS_VREDRAW;
        wc.lpfnWndProc = WndProc;
        wc.cbClsExtra = 0;
        wc.cbWndExtra = 0;
        wc.hInstance = hInstance;
        wc.hIcon = NULL;
        wc.hCursor = LoadCursor( NULL, IDC_ARROW );
        wc.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH );
        wc.lpszMenuName = NULL;
        wc.lpszClassName = szClassName;
        if( !RegisterClass( &wc ) ){
            return -1;
        }
    }

    hWnd = CreateWindow( szClassName,
        _TEXT( "タイトル" ),
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        NULL, NULL,
        hInstance, NULL
    );
    ShowWindow( hWnd, nCmdShow );
    UpdateWindow( hWnd );
    while( GetMessage( &lpMsg, NULL, 0, 0 ) ){
        TranslateMessage( &lpMsg );
        DispatchMessage( &lpMsg );
    }
    return (int)lpMsg.wParam;
}

LRESULT CALLBACK WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    HDC hdc;
    PAINTSTRUCT ps;
    const TCHAR* buf = TEXT( "Sample" );

    switch( msg ){
        case WM_DESTROY:{
            PostQuitMessage( 0 );
            break;
        }
        case WM_PAINT:{
            hdc = BeginPaint( hWnd, &ps );

            TextOut( hdc, 0, 0, buf, (int)_tcslen( buf ) );

            EndPaint( hWnd, &ps );
            break;
        }
        default:{
            return( DefWindowProc( hWnd, msg, wParam, lParam ) );
        }
    }
        return ( 0L );
}

 試したこと

ネットを調べましたが、よくわかりませんでした。

 補足情報(FW/ツールのバージョンなど)

Windows10、MinGWです。どちらも64bitです。
MinGW:gcc (GCC) 4.5.4 20111030 (prerelease) [svn/rev.180676 - mingw-w64/oz]

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+1

こちらも試してみましたが、yukkuri さんとは発生している現象が違うようです。私の方で出たエラーは下図のようにインポートライブラリが足りないエラーですね。
ーlgdi32
こちらのエラーは -lgdi32 で明示的にインポートライブラリを指定してやれば解消します。user32 はデフォルトでインポートライブラリに含まれているのに、gdi32 が含まれていないのは意外でもありますが・・・。

そちらで発生しているエラーはヘッダファイルに関数の定義がないというエラーで、こちらとは発生している現象が異なります。 mingw64 のバージョンを上げてみるなりすれば解消するかもしれません。こちらは久々の mingw でしたので最新バージョン 8.1 まで上げてから試しています。

gcc --version

インクルードファイルを調べるためには -v オプションを付けてコンパイラを起動すると良いです。

gcc -v teratail152662.c


出力は長いので省きますが、以下のようにインクルードディレクトリが表示されますので、正しいヘッダファイルがインクルードされているかどうかを確認することをお勧めします。

includes

2018/10/19 追記
原因はコンパイル環境が正しくないことで間違いないと思うのですが、yukkuri さんと同じ環境を構築することができないため的確な回答を提示することができません。MinGW 4.5.4 が入手できなかったため、再現環境を構築することができませんでした。なお、もともと提示されているエラーのうち TextOut に関するものはリンク時には TextOutA か TextOutW のどちらかに解決する必要があるため、適切なインクルードファイルなしには解決できない問題となります。そのため、オプションでコンパイルが通ったというのは、信じがたい状況となります。

テスト的に #include の下部分の内容を追記してコンパイルと実行ができるか試していただけないでしょうか?

#include <windows.h>
#include <tchar.h>

WINGDIAPI HGDIOBJ WINAPI GetStockObject(int i);
#undef TextOut
#if defined(UNICODE)
#    define TextOut TextOutW
#else
#    define TextOut TextOutA
#endif
WINGDIAPI WINBOOL WINAPI TextOutA(HDC hdc,int x,int y,LPCSTR lpString,int c);
WINGDIAPI WINBOOL WINAPI TextOutW(HDC hdc,int x,int y,LPCWSTR lpString,int c);

/**
 * ウィンドウプロシージャー
 */
LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );

2018/10/21 追記
Mingw64 4.5.4 を入手してやってみましたが、残念ながら yukkuri さんのところで発生している状況を再現することはできませんでした。とは言っても微妙にバージョンは違います。以下のように普通にコンパイルできました。
4.5.4でコンパイル
駄目でもともとですが、上記のように -lgdi32 の後に -Wl,-subsystem,windows を追記して試してみてください。

リンクまでできているならインクルードファイルの問題はなさそうな気がしますが。環境変数 C_INCLUDE_PATH が設定されているかだけ確認してもらった方が良いかもしれません。この環境変数が設定されているのであれば、環境変数を削除した後、コンパイルしてみてください。

なお、

エラーが出る例:gcc -lgdi32 ファイル名
エラーが出ない例:gcc ファイル名 -lgdi32

これは gcc としては標準の動作です。ほとんどの C コンパイラはリンカに渡すオプションはソースファイルの指定より後に記述する必要があります。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/10/20 18:06

    -vを前につけても後につけても一緒でした。

    キャンセル

  • 2018/10/21 01:03

    回答に追記しました。私は、これ以上持ちネタがないのでアドバイスは難しいですね。

    キャンセル

  • 2018/10/21 15:37

    追記していただいた情報(一番下)で解決できました。ありがとうございました。

    キャンセル

0

私の方でもコンパイルしてみましたが、atata0319さんと同じ状態になりました。
ヘッダーファイルが正しくインストールされていれば問題ないとは思うのですが、ヘッダーファイルが見つからないというエラーが出ているわけでもないのでファイル自体はあるような気がします。
また拡張子がcppですが、C++言語ではないので、拡張子はcで大丈夫です。
むしろcにしておかないと、リンクのときに新たなエラーが出てしまいます。

MinGWのバージョン
コンパイル時のgccのオプション

この2つを提示していただけるとよりよい回答が得られるかもしれません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/10/18 21:08

    追加しました

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.03%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る