アプリ版:「スタンプのみでお礼する」機能のリリースについて

こんにちは。
いつもお世話になっております。

小生、只今WindowsXPSP3上で、C言語とWin32APIを使用し、BCC5.5.1でコンパイルしながら、Windowsプログラミングを勉強しています。

度々、質問させて頂き、その都度回答を頂戴し、誠に恐縮ではあるのですが、今回も質問させて下さい。

内容はLoadImage関数を利用した、タイトルバーのアイコン表示です。

以下のコードを試しても、タイトルバーにアイコンが表示されません。
かといって、色々なサイトを見、LoadIconを使用しようとして、MSDNを調べると"この関数は、LoadImage 関数に取って代わられました。"と表記されています。

#if 1
/* タイトルバーにアイコン表示 */
#include <windows.h>

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

int WINAPI WinMain(
HINSTANCE hCurInst,
HINSTANCE hPrevInst,
LPSTR lpsCmdLine,
int nCmdShow)
{
MSG msg;
BOOL bRet;
LPCSTR szClassName = "TitleBarIcon";

if(!InitApp(hCurInst, szClassName)){
return FALSE;
}

if(!InitInstance(hCurInst, nCmdShow, szClassName)){
return FALSE;
}

while((bRet = GetMessage(&msg, NULL, 0, 0)) != 0){
if(bRet == -1){
MessageBox(NULL, "GetMessage Error", "Error", MB_OK);
break;
}
else{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

return (int)msg.wParam;
}

//ウィンドウクラスの登録
ATOM InitApp(HINSTANCE hInst, LPCSTR szClassName)
{
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,
"Linux.ico",
IMAGE_ICON,
0,
0,
LR_LOADFROMFILE | 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 = NULL;
wc.lpszClassName = (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, LPCSTR szClassName)
{
HWND hWnd;

hWnd = CreateWindow(
szClassName,
"TitleBarIcon",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
200,
200,
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)
{
switch(msg){
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return (DefWindowProc(hWnd, msg, wp, lp));
}

return 0;
}

お忙しい中、申し訳ございませんが、
先輩方、アドバイス宜しくお願い致します。
ちなみに読み込んでいるアイコンのサイズは幅、高さとも32ピクセルです。

A 回答 (4件)

>wc.hIcon = (HICON)LoadImage(


>NULL,
>MAKEINTRESOURCE(MYICON),
>IMAGE_ICON,
>0,
>0,
>LR_LOADFROMFILE);

これで読み込みに成功しますか?
なにやらよくわからないファイル名(?)を参照しようとしている…んでしょうか。

//
// Icon resources
//
LANGUAGE LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN
IDI_ICON1 ICON ".\\黒猫01.ico"
# ちなみに、ファイルサイズは766バイト。

WNDCLASSEX wcex = {0};

wcex.cbSize = sizeof(WNDCLASSEX);

wcex.style= CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc= WndProc;
wcex.cbClsExtra= 0;
wcex.cbWndExtra= 0;
wcex.hInstance= hInstance;
wcex.hIcon= (HICON)LoadImage(hInstance, MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
wcex.hCursor= LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground= (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName= MAKEINTRESOURCE(IDC_QA5728505);
wcex.lpszClassName= szWindowClass;

だけです。
VC++2008 ExpressEditionでWin32プロジェクトを作成。
ResEditでリソースに32x32のアイコンを追加して、上記の変更(wcex.hIconの変更とwcex.hIconSmへの設定の削除、wcexのクリア)だけです。
OSが縮小したアイコンがタイトルバーに設定されました。
    • good
    • 1
この回答へのお礼

ご回答頂いたのに、ご返答遅くなってしまい誠に申し訳ございません。

Wr5さんのLoadImageAPIの使い方を拝見させて頂き、
色々と実験させて頂いたところ、今まで、LoadImageの第2引数にインスタンスハンドルを指定していませんでした。

こちらのソース内で、LoadImageの第2引数にインスタンスハンドルを指定すると、タイトルバー、タスクバー、Alt+Tabキーでの切り替え画面で表示したいアイコンが表示されました。

本当に沢山のアドバイス頂き、誠にありがとうございました。
また、ご返答遅れまして、誠に申し訳ございませんでした。
深く反省いたします。

お礼日時:2010/03/18 20:17

ちょこっと試してみました。


32x32のみのアイコン、手元で探すのがちょっと面倒でしたのでネットで適当に探して使いました。

で、その前に確認ですが……
「タイトルバーの左上のアイコンに32x32のアイコンを(縮小されていてでも)使いたい」
ということでよいのでしょうか?

>wc.hIconSm = (HICON)LoadImage(
>NULL,
>MAKEINTRESOURCE(IDI_APPLICATION),
>IMAGE_ICON,
>0,
>0,
>LR_DEFAULTSIZE | LR_SHARED);

でも、表題の「LoadImageを使用し、タイトルバーのアイコンを表示」になっていますので…。
で、wc.hIconに設定しているアイコンではなく、
IDI_APPLICATIONのアイコンが表示されているのではないでしょうか?
# Alt+TABで表示される一覧の方では希望したアイコンが表示されているかと。
wc.hIconSmをNULLにするか、wc.hIconと同じモノを設定してみてはどうでしょう?

# 試したのはwc.hIconSmをNULLにする方法でした。

この回答への補足

ご回答頂き誠にありがとうございます。

言及されておられました、ご質問にお答えさせて頂きます。

>で、その前に確認ですが……
>「タイトルバーの左上のアイコンに32x32のアイコンを(縮小されていてでも)使いたい」
>ということでよいのでしょうか?

はい。
おっしゃる通り、タイトルバーの左上のアイコンに任意のアイコンを表示させたいのです。

># Alt+TABで表示される一覧の方では希望したアイコンが表示されているかと。

いいえ、Alt+Tabで表示した際もデフォルトのアイコンが表示されました。

># 試したのはwc.hIconSmをNULLにする方法でした。

私も試させて頂きましたが、以下に記述するように、タイトルバーのアイコンには変化はなく、タスクバーのアイコンが変更されました。

ご指摘のあったように、wc.hIconSmにwc.hIconと同じ値をセットし、コンパイルし、実行してみたところ、タスクバーのアイコンは希望のアイコンに変更されましたが、タイトルバーのアイコンは変更されませんでした。。。

以下にコードを提示します。
※リソースファイル、リソースヘッダーはmaznobuさんの箇所で書いた物と同じなので割愛させて頂きます。すいません。

#include <windows.h>
#include "ResIcon.h"

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

int WINAPI WinMain(
HINSTANCE hCurInst,
HINSTANCE hPrevInst,
LPSTR lpsCmdLine,
int nCmdShow)
{
MSG msg;
BOOL bRet;
LPCSTR szClassName = "Window";

if(!InitApp(hCurInst, szClassName)){
return FALSE;
}

if(!InitInstance(hCurInst, nCmdShow, szClassName)){
return FALSE;
}

while((bRet = GetMessage(&msg, NULL, 0, 0)) != 0){
if(bRet == -1){
MessageBox(NULL, "GetMessage Error", "Error", MB_OK);
break;
}
else{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

return (int)msg.wParam;
}

//ウィンドウクラスの登録
ATOM InitApp(HINSTANCE hInst, LPCSTR szClassName)
{
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(MYICON),
IMAGE_ICON,
0,
0,
LR_LOADFROMFILE);
wc.hCursor = (HCURSOR)LoadImage(
NULL,
MAKEINTRESOURCE(IDC_ARROW),
IMAGE_CURSOR,
0,
0,
LR_DEFAULTSIZE | LR_SHARED);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = (LPCSTR)szClassName;
wc.hIconSm = (HICON)LoadImage(
NULL,
MAKEINTRESOURCE(MYICON),
IMAGE_ICON,
0,
0,
LR_LOADFROMFILE);

return (RegisterClassEx(&wc));
}

//ウィンドウの生成
BOOL InitInstance(HINSTANCE hInst, int nCmdShow, LPCSTR szClassName)
{
HWND hWnd;

hWnd = CreateWindow(
szClassName,
"Window",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
200,
200,
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)
{
switch(msg){
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return (DefWindowProc(hWnd, msg, wp, lp));
}

return 0;
}

以上です。
お忙しい中、申し訳ございませんが、再度アドバイスの方、宜しくお願いします。

補足日時:2010/03/09 23:20
    • good
    • 0

こんにちは。



タイトルのアイコンはセオリーとしてはリソースファイル内のアイコンです。
アイコンもリソースですが、そういう意味ではないので直接的なファイルは指定しても意味がありません。

LoadImage(NULL, "Linux.ico" ...

という記述がありますが、それはファイルではなくてリソース上の名前である必要があります。
テキストの.rc ファイル(リソースファイル)を作ってその中で以下のようにファイルを指定します。

1 ICON "Linux.ico"

これをリソースコンパイラ(rc.exe)でresファイルにしつつ、
WinMainでは

LoadImage(NULL, MAKEINTRESOURCE(1), ...

と言うようにします。数字は1である必要は無いです。5でも200でも何でもOKですが、既存のリソースとバッティングしないようにします。

なお、rcファイルで

"LINUX_Ico" ICON "Linux.ico"

として

LoadImage(NULL, _T("LINUX_Ico") ...

でもいいですよ。リソースIDは文字列でもOKなのでパラメータがLPCTSTRなんです。
リソース名の頭は英字で、またピリオドは入れないでくださいね。

_T("...")っていうのは TEXT("...")というマクロのショート形。
BCCで実装されているかどうか分からないけども、Windows SDKとして標準のマクロです。
LPCTSTRのTが、コンパイラがワイド文字なのかバイト文字なのかを判断します。
それにあわせて_T("...")とすると、"..." なのか L"..." なのかをコンパイラが自動で設定します。


LoadImage にどうしてもファイルを指定したいならば、
LoadImage のフラグ指定に LR_LOADFROMFILE というフラグを指定してください。
このファイル指定は全てのWindowsで動くわけではありません。
Windows 98 とかで表示させるには先のリソースである必要があります。

RCファイルはそれなりの構文があるので各自調べてください。

この回答への補足

早速、ご回答頂き誠にありがとうございます。

ご指摘のあったとおり、BCCFormを使いリソースファイル、リソースヘッダーを作成し、コードを修正し、以下の手順でコンパイル、実行してみました。

※ソースファイル名はsource.cpp、リソースファイル名はIcon.rcです。

1.bcc32 -W source.cpp

2.brc32 Icon.rc source.exe

とし、出来上がった実行ファイルを実行してみたところ。。。
タイトルバーのアイコンは何も変化せず、実行ファイルのアイコンがLinux.icoに変更されました。

以下にリソースヘッダ、リソースファイル、ソースコードを記します。

※文字制限がある為、必要ではない部分は省略させて頂きます。

<リソースヘッダ>
#defineMYICON100

<リソースファイル>
#include"ResIcon.h"


//--------------------------
// イメージ(MYICON)
//--------------------------
MYICONICONDISCARDABLE"C:\Documents and Settings\ShuNakagawa\My Documents\C\Linux.ico"

<ソースファイル>
#include <windows.h>
#include "ResIcon.h"

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

int WINAPI WinMain(
HINSTANCE hCurInst,
HINSTANCE hPrevInst,
LPSTR lpsCmdLine,
int nCmdShow)
{
MSG msg;
BOOL bRet;
LPCSTR szClassName = "Window";

if(!InitApp(hCurInst, szClassName)){
return FALSE;
}

if(!InitInstance(hCurInst, nCmdShow, szClassName)){
return FALSE;
}

while((bRet = GetMessage(&msg, NULL, 0, 0)) != 0){
if(bRet == -1){
MessageBox(NULL, "GetMessage Error", "Error", MB_OK);
break;
}
else{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

return (int)msg.wParam;
}

//ウィンドウクラスの登録
ATOM InitApp(HINSTANCE hInst, LPCSTR szClassName)
{
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(MYICON),
IMAGE_ICON,
0,
0,
LR_LOADFROMFILE);
wc.hCursor = (HCURSOR)LoadImage(
NULL,
MAKEINTRESOURCE(IDC_ARROW),
IMAGE_CURSOR,
0,
0,
LR_DEFAULTSIZE | LR_SHARED);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = (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, LPCSTR szClassName)
{
HWND hWnd;

hWnd = CreateWindow(
szClassName,
"Window",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
200,
200,
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)
{
switch(msg){
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return (DefWindowProc(hWnd, msg, wp, lp));
}

return 0;
}

以上です。

誠に申し訳ございませんが、再度アドバイスの方宜しくお願いします。

補足日時:2010/03/09 06:16
    • good
    • 0

LoadImage()の戻り値は有効な値になっていますか?


読み込みに失敗してNULLだったりしませんか?

# タイトルバーのアイコンに32x32って設定したこと無いですが。
# 読み込みに問題なければ、OS側でリサイズ…してくれますかね。

この回答への補足

ご回答頂き、誠にありがとうございます。

ご指摘のあった通り、LoadImageの戻り値がNULLになっていないかを調べる為に以下のコードを書き、コンパイルし、実行してみましたが、LoadImageの戻り値はNULLにはなっていないようです。

#include <windows.h>

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

int WINAPI WinMain(
HINSTANCE hCurInst,
HINSTANCE hPrevInst,
LPSTR lpsCmdLine,
int nCmdShow)
{
MSG msg;
BOOL bRet;
LPCSTR szClassName = "TitleBarIcon";

if(!InitApp(hCurInst, szClassName)){
return FALSE;
}

if(!InitInstance(hCurInst, nCmdShow, szClassName)){
return FALSE;
}

while((bRet = GetMessage(&msg, NULL, 0, 0)) != 0){
if(bRet == -1){
MessageBox(NULL, "GetMessage Error", "Error", MB_OK);
break;
}
else{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

return (int)msg.wParam;
}

//ウィンドウクラスの登録
ATOM InitApp(HINSTANCE hInst, LPCSTR szClassName)
{
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,
"Linux.ico",
IMAGE_ICON,
0,
0,
LR_LOADFROMFILE | LR_DEFAULTSIZE | LR_SHARED);
if(wc.hIcon == NULL){
MessageBox(NULL, "アイコンファイル読み込みに失敗",
"エラー", MB_OK);
}
wc.hCursor = (HCURSOR)LoadImage(
NULL,
MAKEINTRESOURCE(IDC_ARROW),
IMAGE_CURSOR,
0,
0,
LR_DEFAULTSIZE | LR_SHARED);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = (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, LPCSTR szClassName)
{
HWND hWnd;

hWnd = CreateWindow(
szClassName,
"TitleBarIcon",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
200,
200,
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)
{
switch(msg){
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return (DefWindowProc(hWnd, msg, wp, lp));
}

return 0;
}

以上です。
ご確認の程、宜しくお願いします。

補足日時:2010/03/09 06:10
    • good
    • 0

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