[環境]Windows2000Server,VS.NET2003
[開発]WindowsSDK(MFC及びC++は使用してません。Cのみ)
ハトです。質問よろしいでしょうか?
ダイアログベースのツールを作っていて。
ツールそのものは完成してるのですが、左上のアイコンが
リソースで作ったものに変わらなくて困っています。
実行ファイルのアイコンは変わってるのに、ダイアログの
左上に表示されるアイコンだけが、Windowsのデフォルト?
のアイコンのままで変更されません。
以下に問題のリソースとソースを提示します。
VC++のプロジェクトの扱い方が悪いのか?
と思って入門書もあさってみたのですが、
プロセスとしては間違った方法は取っていない
みたいなんですが。。
原因がおわかりの方いましたら、
ご指摘ください。
よろしくお願い致します。m(__)m
-アイコンリソース-
IDI_ICON1 → 32×32
IDI_ICON2 → 16×16
-mainソース-
int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine,
int nCmdShow)
{
MSG msg;
HWND hWnd;
WNDCLASSEX wcl;
wcl.cbSize = sizeof(WNDCLASSEX);
wcl.hInstance = hCurInst;
wcl.lpszClassName = WIN_NAME;
wcl.lpfnWndProc = (WNDPROC)SynchroProc;
wcl.style = 0;
wcl.hIcon = LoadIcon(hCurInst, (LPCTSTR)IDI_ICON1);
wcl.hCursor = LoadCursor(NULL, IDC_ARROW);
wcl.lpszMenuName = NULL;
wcl.cbClsExtra = 0;
wcl.cbWndExtra = 0;
wcl.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcl.hIconSm = LoadIcon(wcl.hInstance, (LPCTSTR)IDI_ICON2);
if(!RegisterClassEx(&wcl)) return 0; // OSメッセージに0を受け取った場合終了
hWnd = CreateDialog(hCurInst, MAKEINTRESOURCE(DLG_MAIN), NULL, SynchroProc);
ShowWindow(hWnd, SW_SHOWNORMAL);
UpdateWindow(hWnd);
hInst = hCurInst;
while(GetMessage(&msg, NULL, 0, 0)) {
if (IsDialogMessage(hWnd, &msg)) continue;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
-ダイアログのリソース-
DLG_MAIN DIALOGEX 0, 0, 331, 171
STYLE DS_SETFONT | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION |
WS_SYSMENU
CAPTION ツール
FONT 9, MS Pゴシック, 400, 0, 0x80
BEGIN
PUSHBUTTON Start,BT_START,274,6,50,16,NOT WS_TABSTOP
PUSHBUTTON End,BT_END,274,24,50,16,NOT WS_TABSTOP
END
ん?
まずRegisterClassEx()は必要ないでしょ。
つまりここ(WNDCLASSEXの中)でアイコン指定しても無意味です。
アイコンはダイアログプロシージャにWM_SETICON送ればいいのではないかな。
WM_INITDIALOGでSendMessage(hDlgWnd, WM_SETICON, 0, hIcon)すればいけるかと。
LoadIconの第2引数って、IDをキャストするだけでいいんでしたっけ?
MAKEINTRESOURCEを使った方が・・・
失礼しました。
MAKEINTRESOURCEの定義をたどってみたら、結局キャストしてました。
レスありがとうございます。
→ SendMessage(hDlgWnd, WM_SETICON, 0, hIcon)
なんですが、これってMFCでこういった書き方した
ことはあったんですが、(サンプルで)そのままSDKに
書いてみたら WM_SECTIONは定義されていない・・・
っていうコンパイルエラーがでてしまいました。
インクルードすべきヘッダファイルが足りていないんでしょうか?
自己レスです。
ごめんなさい。
↑は、Registerをしていたので出ていたんですよね。
失礼しました。
--ソース--
hIcon = LoadIcon(NULL, (LPCTSTR)IDI_ICON2);
SendMessage(hDlg, WM_SETICON, 0, (LPARAM)hIcon);
---------
上記をWM_INITDIALOG:に書いたらいけました。
こう書いたらとりあえずアイコンは変わったんですが、
もくろんでいるアイコンに変わらないです。。
アイコンの部分に、MessageBoxのパラメータ指定で出てくる
MB_ICONQUESTION ?
MB_ICONSTOP ×
のアイコンどちらかが出てきました。
アイコンの作り方の問題ならいいんですが。。
重ね重ねすみません。
よろしくお願いします。m(__)m
LoadIcon()の第一引数がNULLではダメじゃないかな。
ちゃんとHINSTANCEを渡しましょう。
お早いレスありがとうございますレス。
アイコンの大きさに問題があるのかと思い、
LoadImageに変更してみたんですが、それでも
上手くいきませんでした。。。
頭パニくってきたので、今日はこのへんでやめて
頭を冷やしてから、もっかいやってみます。。
以下ソースです。
HINSTANCE hInst;
HICON hIcon;
int WINAPI WinMain(...) {
hInst = hInstance;
hIcon = (HICON)LoadImage(hCurInst,(LPCTSTR)
IDI_ICON2 ,IMAGE_ICON,16,16,LR_DEFAULTCOLOR);
}
CALLBACK内(...){
switch...
WM_INITDIALOG:
SendMessage(hDlg, WM_SETICON, 0, (LPARAM)hIcon);
}
アイコンファイルって中に16×16と32×32をもてると思いますけれど、
両方とも作っておいた方が良いです。
状況によって使い分けられているようですから。
あと、ロードできているかのチェックを入れた方が良いような。
こういう細かいチェックをやっておくとどこでしくじっているか追いかけやすいです。
皆さんいろいろとありがとうございます。
問題の切り分けを考えてると、下記が怪しいのかなぁと
いう気がしてきました。
・リソースの作成の仕方がそもそも間違っている。
・アイコンを16×16で作ったが、ちゃんと保存?されてない。
(ソリューションのリソースとして)
なぜこう思ったかというと、ソリューションからWindows SDKの
スケルトン(空ではないやつ)を作ると、上手くいくんですが、
一から空プロジェクトを作って、コードをガリガリ書いていった
場合だけ失敗してます。
→つまりVC++の環境をしっかり使えていない。
ということなのかなぁと。。
gccなどの経験のほうが長いもので、
いまいちその辺を大雑把に考えすぎているのかも知れません。。
リソースの作り方から、もう一度おさらいしてきます。。
Legolasです。
私はCを始めてまだ2~3週間ぐらいなんですが、
実は私も一回だけつまったことがあります。
恐らく過去履歴には MFCとかC++関連の情報は
ありましたが、SDKベースの情報は無かったような
気がします。もちろんVC++ラウンジだし・・・(汗)
とはいうものの、自分も今のところは SDK派なので、
ちょっとお手伝いしたいと思います。
順を追って説明してみますので、一度この手順でチャレンジ
してみてください。(^^;
--Legolas流のやり方--
(1)ワークスペースを作ります(.NETならソリューション)
※もちろん32BitApplicationですよ♪
(2)Main.cppを追加して下記ソースをコピペ(Main.cppの名前は任意)
一応ハトさんのソースを意識したつもりです。。
---ココカラ---
#include <windows.h>
#include resource.h
// 変数
HINSTANCE gInst;
HICON hIcon;
// プロトタイプ
BOOL CALLBACK MyDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
// WinMain
int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpCmdLine,
int nShowCmd)
{
MSG msg;
HWND hDlg;
//インスタンスをグローバルへ
gInst = hCurInst;
//ダイアログ作成
hDlg = CreateDialog(gInst, MAKEINTRESOURCE(MYDLG), NULL, DlgProc);
//ウィンドウ
ShowWindow(hDlg, nShowCmd);
//アイコンロード
//→私の経験ではそのアイコンが16×16と32×32を両方持ってたらこれだけで
// 良かったはずですよ。
hIcon = (HICON)LoadImage(gInst, MAKEINTRESOURCE(ICO_MAIN), IMAGE_ICON, 32,
32, 0);
//SendMessageでアイコンを登録
SendMessage(hDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
while (GetMessage(&msg, NULL, 0, 0)) {
if (IsDialogMessage(hDlg, &msg)) continue;
TranslateMessage (&msg);
DispatchMessage (&msg);
}
return msg.wParam;
}
BOOL CALLBACK DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg){
// ダイアログ初期化
case WM_INITDIALOG:
break;
// コマンド
case WM_COMMAND:
switch(LOWORD(wParam)) {
//[シンクロ開始]
case IDOK:
MessageBox(hDlg, テスト, テストダイアログ, MB_OK);
return TRUE;
case IDCANCEL:
DestroyWindow(hDlg);
return TRUE;
}
return FALSE;
case WM_CLOSE:
DestroyWindow(hDlg);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return FALSE;
}
---ココマデ---
(3)リソーススクリプトを追加します
(4)xxxx.rcを選択した状態で挿入→[ダイアログ]
(5)リソースエディタを開いて、アイコンをインポートするか新規作成する。
(6)IDをそれぞれ以下のように変えてください。
アイコン → ICO_MAIN
ダイアログ → MYDLG
(7)ビルドします。
これで出来上がりのはずです。
ダイアログのOKボタンとキャンセルボタンは、それぞれ
サンプルソースのIDOKとIDCANCELのままだと思うので、
問題ないはずです。
最低でもダイアログがでて、OKボタンをクリックしたら
メッセージボックスが出るはず(^^;アセアセ
もし上手くいったら、これをベースにしてハトさんがおつくりに
なられたコードをコピペするなりつぎはぎするなりしてみては
いかがでしょうか??
あと、いろいろと偉そうなこと言うてますが、私のほうが恐らく
C言語のスキルは浅いと思うので、自信持って頑張って下さい。
解決しました。
どうもみなさんありがとうございました。