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

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

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

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

C++

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

Q&A

解決済

1回答

3123閲覧

Windows APIでのアイコン設定

BeatStar

総合スコア4962

Win32 API

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

C++

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

0グッド

0クリップ

投稿2022/01/08 09:07

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

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

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

自分なりのコード:

C++

1// .\src\main.cpp 2 3#include<iostream> 4#include<vector> 5#include<random> 6#include<windows.h> 7 8#define UNICODE 9 10#include"resource/resource.h" 11 12LRESULT CALLBACK WindowProc( HWND hWnd, UINT msg, WPARAM wp, LPARAM lp ); 13 14int WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, PSTR lpCmdLine, int nCmdShow ){ 15 WNDCLASSEXW winc; 16 17 std::wstring className = L"test1"; 18 19 winc.cbSize = sizeof(WNDCLASSEXW); 20 winc.style = CS_HREDRAW | CS_VREDRAW; 21 winc.lpfnWndProc = WindowProc; 22 winc.cbClsExtra = 0; 23 winc.cbWndExtra = 0; 24 winc.hInstance = hInst; 25 winc.hIcon = (HICON)LoadImageW( hInst, MAKEINTRESOURCE(IDI_MAINICONEX), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED ); 26 //winc.hIcon = LoadIconA(hInst , MAKEINTRESOURCE(IDI_MAINICONEX)); 27 winc.hCursor = LoadCursor( NULL, IDC_ARROW ); 28 winc.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH ); 29 winc.lpszMenuName = NULL; 30 winc.lpszClassName = className.c_str(); 31 winc.hIconSm = winc.hIcon; 32 33 if( winc.hIcon == NULL ){ 34 MessageBoxW( NULL, L"icon is null", L"エラー", MB_OK ); 35 //return 1; 36 } 37 38 if( !RegisterClassExW( &winc ) ){ 39 MessageBoxW( NULL, L"RegisterClassの失敗", L"エラー", MB_OK ); 40 return 1; 41 } 42 43 HWND hWnd = CreateWindowW( 44 className.c_str(), 45 L"test1", 46 WS_OVERLAPPEDWINDOW | WS_VISIBLE, 47 100, 100, 200, 200, 48 NULL, 49 NULL, 50 hInst, 51 NULL 52 ); 53 54 if( hWnd == NULL ){ 55 MessageBoxW( NULL, L"CreateWindowの失敗", L"エラー", MB_OK ); 56 return 2; 57 } 58 59 ShowWindow( hWnd, SW_SHOW ); 60 UpdateWindow( hWnd ); 61 62 MSG msg; 63 while( GetMessage( &msg, NULL, 0, 0 ) ){ 64 TranslateMessage( &msg ); 65 DispatchMessage( &msg ); 66 } 67return msg.wParam; 68} 69 70LRESULT CALLBACK WindowProc( HWND hWnd, UINT msg, WPARAM wp, LPARAM lp ){ 71 switch ( msg ){ 72 case WM_DESTROY: 73 MessageBoxW( hWnd, L"終了するぞ", L"WM_DESTORYメッセージを受け取った", MB_OK ); 74 PostQuitMessage( 0 ); 75 return 0; 76 } 77return DefWindowProc( hWnd, msg, wp, lp ); 78}

C++

1// .\src\resource\resource.h 2 3#ifndef RESOURCE_H 4#define RESOURCE_H 5 6#define IDI_MAINICONEX 102 7 8#endif

C++

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

cmd

1rem コンパイル方法 2g++ -c .\src\main.cpp -o .\src\main.o -DUNICODE 3windres .\src\resource\resource.rc -o .\src\resource\resource.o 4g++ -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関数を使って取得してみました。

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

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

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 編集

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

回答1

0

自己解決

すみません……(汗
ショーもないミスでした…

単純にリソースファイルをリンクし忘れていただけのようです…

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 -mwindows

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

に変更するとうまくできました。

投稿2022/01/08 12:04

BeatStar

総合スコア4962

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問