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

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

新規登録して質問してみよう
ただいま回答率
87.20%
Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

解決済

Windows APIでのアイコン設定

BeatStar
BeatStar

総合スコア4609

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

1回答

0評価

0クリップ

468閲覧

投稿2022/01/08 09:07

編集2022/01/08 12:00
[概要] Windows API + C++ でウィンドウにアイコンを設定したいが、なぜか設定されない。 アイコンがちゃんとウィンドウに設定したい。

久しぶりにWin32 APIをやろうとしています。(忘れているところもある…)

標準 Windows APIをもとにやっているのですが、アイコンが設定されません。

自分なりのコード:

C++

// .\src\main.cpp #include<iostream> #include<vector> #include<random> #include<windows.h> #define UNICODE #include"resource/resource.h" LRESULT CALLBACK WindowProc( HWND hWnd, UINT msg, WPARAM wp, LPARAM lp ); int WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, PSTR lpCmdLine, int nCmdShow ){ WNDCLASSEXW winc; std::wstring className = L"test1"; winc.cbSize = sizeof(WNDCLASSEXW); winc.style = CS_HREDRAW | CS_VREDRAW; winc.lpfnWndProc = WindowProc; winc.cbClsExtra = 0; winc.cbWndExtra = 0; winc.hInstance = hInst; winc.hIcon = (HICON)LoadImageW( hInst, MAKEINTRESOURCE(IDI_MAINICONEX), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED ); //winc.hIcon = LoadIconA(hInst , MAKEINTRESOURCE(IDI_MAINICONEX)); winc.hCursor = LoadCursor( NULL, IDC_ARROW ); winc.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH ); winc.lpszMenuName = NULL; winc.lpszClassName = className.c_str(); winc.hIconSm = winc.hIcon; if( winc.hIcon == NULL ){ MessageBoxW( NULL, L"icon is null", L"エラー", MB_OK ); //return 1; } if( !RegisterClassExW( &winc ) ){ MessageBoxW( NULL, L"RegisterClassの失敗", L"エラー", MB_OK ); return 1; } HWND hWnd = CreateWindowW( className.c_str(), L"test1", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100, 100, 200, 200, NULL, NULL, hInst, NULL ); if( hWnd == NULL ){ MessageBoxW( NULL, L"CreateWindowの失敗", L"エラー", MB_OK ); return 2; } ShowWindow( hWnd, SW_SHOW ); UpdateWindow( hWnd ); MSG msg; while( GetMessage( &msg, NULL, 0, 0 ) ){ TranslateMessage( &msg ); DispatchMessage( &msg ); } return msg.wParam; } LRESULT CALLBACK WindowProc( HWND hWnd, UINT msg, WPARAM wp, LPARAM lp ){ switch ( msg ){ case WM_DESTROY: MessageBoxW( hWnd, L"終了するぞ", L"WM_DESTORYメッセージを受け取った", MB_OK ); PostQuitMessage( 0 ); return 0; } return DefWindowProc( hWnd, msg, wp, lp ); }

C++

// .\src\resource\resource.h #ifndef RESOURCE_H #define RESOURCE_H #define IDI_MAINICONEX 102 #endif

C++

#include"resource.h" IDI_MAINICONEX ICON DISCARDABLE "..\..\res\icons\main.ico"

cmd

rem コンパイル方法 g++ -c .\src\main.cpp -o .\src\main.o -DUNICODE windres .\src\resource\resource.rc -o .\src\resource\resource.o g++ -o2 -std=c++11 -o .\bin\Main .\src\main.o .\src\resource\resource.o -mwindows

↑ 追記&修正: リソースファイルをリンクするのを忘れていたらしいです…

コンパイルは通るのですが、いざ起動すると、『icon is null』というメッセージボックスが表示され、
ウィンドウにはアイコンが設定されていません。

アイコンが壊れているのかと思い、C#で組んだもののアイコンを代わりに使っても同じでした。

コードが何か間違っているのかと思い、Windowsアプリケーションのアイコンの指定方法でも試してみましたが同じでした。

[試したこと]

試したこと1: if( winc.hIcon == NULL ) ... を配置し、NULLなのかどうかを調べる 結果: 『icon is null』と表示された。つまりアイコンが読み込まれていないか失敗したか。
試したこと2: アイコンを別のものに変えた 結果: 変える前と同様であった
試したこと3: 参考サイトを『Windowsアプリケーションのアイコンの指定方法』に変えてみて、 LoadIcon関数をLoadImageに変更した 結果: 今までと同様
試したこと4: アイコンがある場所を "....\res\resource" から resource.rc 等があるディレクトリに変えてみる。 もちろん、rcファイルに記述されているファイルパスも変える。 結果: 今までと同様

[情報]
言語: C++
コンパイラ: MinGW (g++ (i686-posix-dwarf-rev0, Built by MinGW-W64 project) 8.1.0)
OS: Windows 8, 10


[追記1]

dodox86さんのおっしゃるように GetError関数&FormatMessage関数を使って取得してみました。

その結果、『指定されたイメージ ファイルはリソース セクションを含んでいません』と出ています…
メッセージからは『リンクされていないことが原因』かと思うのですが、

良い質問の評価を上げる

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

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

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

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

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

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

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

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

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

dodox86

2022/01/08 11:04

> コンパイルは通るのですが、いざ起動すると、『icon is null』というメッセージボックスが表示され、 ウィンドウにはアイコンが設定されていません。 メッセージボックスが表示されるのはBeatStarさんのコードがそうしているからで、それはLoadImage APIがNULLを返しているから、ですよね。LoadImage()を呼んで失敗しているなら、直後にGetLastError() APIを呼んで、エラーの詳細を確認してみてください。 https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-loadimagew
BeatStar

2022/01/08 11:17

コメントありがとうございます。 > メッセージボックスが表示されるのはBeatStarさんのコードがそうしているからで まあ、そうなんですけど… > LoadImage()を呼んで失敗しているなら、直後にGetLastError() APIを呼んで、エラーの詳細を確認してみてください。 あー、そういえばそれもありましたね… 確かめてみます。
BeatStar

2022/01/08 12:12 編集

@ dodox86さん しょーもないミスでした… 単純にリンクし忘れ… (入力したつもりだったんだけどなぁ…)
Bull

2022/01/08 12:26 編集

解決したようなので、必要無かったです。

まだ回答がついていません

会員登録して回答してみよう

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

ただいまの回答率
87.20%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

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

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。