シェルアイコンがイメージリストに登録できない??

このQ&Aのポイント
  • Visual C++においての質問です。APIで関連づけられたアイコンを取得したあと、イメージリストに登録しようとしてるのですが、「不正な処理」とかで落ちてしまいます。なんか…マズい処理をやってるんでしょうか??
  • 以下のコードでは、C++でアイコンを取得し、イメージリストに登録する処理を行っています。しかし、何らかのエラーが発生してしまい、「不正な処理」というエラーメッセージが表示されます。どこが間違っているかご教授いただけないでしょうか?
  • Visual C++でアイコンを取得し、イメージリストに登録する処理を行っていますが、「不正な処理」というエラーメッセージが表示されてしまいます。正しい処理方法を教えていただけないでしょうか?
回答を見る
  • ベストアンサー

シェルアイコンがイメージリストに登録できない??

Visual C++においての質問です。 APIで関連づけられたアイコンを取得したあと、イメージリストに登録しようとしてるのですが、 「不正な処理」とかで落ちてしまいます。なんか…マズい処理をやってるんでしょうか?? 大まかなソースは以下の通りです。 超初心者ですので、とんでもない間違いをしてるだけだと思うんですが…。どなたかご教授をお願いします。 CImageList IconList; CString FilePath = "C:\\test.txt"; SHFILEINFO FileInfo; IconList.Create(32,32,ILC_COLORDDB|ILC_MASK,1,1000); ::CoIntialise(NULL); SHGetFileInfo(FilePath,NULL,&FileInfo,sizeof(FileInfo),SHGFI_ICON|SHGFI_SMALLICON);

質問者が選んだベストアンサー

  • ベストアンサー
  • cocky
  • ベストアンサー率57% (232/402)
回答No.3

スペルミスの件は、「CoInitialize」と「CoInitialise」の差(zとsの違いのこと)を言ったつもりだったんですけど。 だいたい最初の発言では「CoIntialise」でiも落ちてますし。 で、ImageList.Add()のASSERTで落ちている、ということは、hIconにアイコンハンドルがきちんと渡ってない、ということですよね? とりあえずSHGetFileInfoの返値を見てみて、 if( SHGetFileInfo(...) ) {  IconList.Add( hIcon ); } という風にすれば、とりあえず落ちることはないと思いますけど。 あと、念のために確認しますが、FilePathで示されているファイルは実在しますよね?

f_a_k_e
質問者

お礼

if抜けは試してたんですが、Add処理に移ってしまい落ちてしまいました。 値もデバッグで張り巡らして監視したのですが、ポインタの類は見てもサッパリですし…。 自作アイコンでハンドルを取って、ではちゃんと追加してくれるんですけどね。 パスももちろん実在する物を使っています。 明日からの予定で、しばらくの間ネットから離れます。 今回はこの件を取り下げて、COM系統レベルから書籍を片端から見てみることにします。 未解決ですが、cockyさん、本当にありがとうございました。

その他の回答 (2)

  • cocky
  • ベストアンサー率57% (232/402)
回答No.2

CoInitializeのスペルが違うのは単なるタイプミスですよね? あと、よく考えたら、SHGetFileInfoの中のdwFileAttributesはあくまで値を入れるところであってポインタを入れるところではないので、そこがNULLなのはまずいような気がしますが。 VC++なら統合環境のデバッガで命令のトレース実行ができるでしょうから、具体的にどこで落ちてるかを特定できるとアドバイスもしやすいんですが。

f_a_k_e
質問者

補足

デバッグで見たところ、イメージリストでのAddで落ちているようでした。 MFCヘッダーファイル内のASSERTで落ちるようです…。 スペルミスはCointialiseとCoIntialiseのスペルですかね? SDKヘルプでCoIntialiseとあるし、Cointialiseにすると「定義されてない」と怒られてしまうんです。 dwFileAttributesのNULLですが、どこかのページでのサンプルがこういった使い方をしてたので見よう見まねです…。 ちなみに、FILE_ATTRIBUTE_NORMALなども試してもダメでした。 FileInfoのmemset、イメージリストを関連づけたリストビューの描画停止など、いろいろ組み合わせて試してるんですけど…。(xox)

  • cocky
  • ベストアンサー率57% (232/402)
回答No.1

SHGFI_SMALLICONであれば、ImageListのイメージサイズは32x32ではなく16x16ではないか、という気がしますけど。 ただ、それを除けばここまでの処理には不都合は見あたらないですが、SHGetFileInfoを実行したあとで、FileInfo.hIconをIconListに登録する部分の処理が書かれてないですよね。 そこを見ないと「不正な処理」で落ちる原因はつかめないと思います。

f_a_k_e
質問者

補足

ありゃりゃ、Createは(16,16…)ですね。 Addも書き忘れてました。(T△T) そりゃー分からんわ…。すみませんです。 追加: IconList.Add(FileInfo.hIcon); やはりハンドルの渡し方がマズイんかなーと…。

関連するQ&A

  • ファイルに関連付けられているアイコンについて

    ファイルに関連付けられているアイコン取得について質問です。 開発環境 OS:XP Visual Studio 2005 言語:C、C++ 調べると、SHGetFileInfo()を使ってアイコンを 取得出来るらしいのですが、 取得するアイコンではなく違うアイコンが取得(表示)されます。 架空のファイル名(実際にないファイル名)でやってみると、 同じアイコンが取得(表示)されます。 ●ソース ーーーーーーーーーーーーーーーーー //アイコン取得部分 SHGetFileInfo("C:/WINDOWS/notepad.exe", 0, &icon, sizeof(icon), SHGFI_PIDL | SHGFI_ICON | SHGFI_SMALLICON); //アイコン表示部分 DrawIcon(hdc, 10, 10, icon.hIcon); ーーーーーーーーーーーーーーーーー SHGetFileInfo()の戻り値は、「1」でした。 間違っている所があるのでしょうか?

  • SHGetFileInfoでアイコンが取得できない場合がある

    VC++にてエクスプローラもどきを作成しています。 ListViewへファイルアイコンを表示するために、 SHGetFileInfoを使用し、 // 大きいアイコンのハンドル取得 // fnameは拡張子だけの文字列です SHGetFileInfo( fname, NULL, &shfInfo, sizeof(SHFILEINFO), SHGFI_ICON | SHGFI_LARGEICON | SHGFI_USEFILEATTRIBUTES ); licon = shfInfo.hIcon; 上記のようにしてファイルアイコンを取得し、 CImageListへ追加した上で、描画しています。 そして、ダイアログのサイズが変更された際に、 OnSize関数にて、ListView内のアイコンを再度取得し、 再描画しているのですが、 何度もOnSizeで再描画を行っているうちに、 SHGetFileInfoにて取得したshfInfo.hIconが NULLになってしまいます。 一度、shfInfo.hIconがNULLになると、 何度、SHGetFileInfoを呼んでも、返ってくるhIconは 毎回NULLになってしまい、ListView内に アイコンが表示されません。 SHGetFileInfo関数を呼ぶ際の制約等があるのでしょうか?

  • C# FTPサーバ アイコン取得

    FTPサーバからファイル名とアイコンを取得してListViewに表示させたいのですが アイコンの取得がうまくいきません。ファイル名のみは出来ました。 SHGetFileInfo("ftp://localhost/test.txt", 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), SHGFI_ICON | SHGFI_LARGEICON); みたいな感じで取得できないかと試してみましたが駄目でした。 詳しい方ご教授お願いします。

  • WinAPI SHGetFileInfoでICONファイル名の取得方法?

    SHGetFileInfoでExplorerに表示されるICONのファイル名を取得したいのですが うまくいきません。 int main(int argc, char* argv[]) { SHFILEINFO sfi; ::CoInitialize(NULL); if(0 == ::SHGetFileInfo("C:\\hogehoge.txt", FILE_ATTRIBUTE_NORMAL, &sfi, sizeof(sfi), SHGFI_ICONLOCATION)) return -1; printf("Icon location file = %s\n", sfi.szDisplayName); return 0; } SHGFI_TYPENAMEを指定するとsfi.szTypeNameファイルタイプ名が入るのは確認できたのですが、SHGFI_ICONLOCATIONを指定してもsfi.szDisplayNameにアイコンファイル名が入ってくれません。(sfi.szDisplayName[0]='\0'で終わりになっている...) MSDNを見る限りはこれであっているようなのですが、正しい使い方を教えてください。

  • C#でウィンドウのアイコン取得する方法

    タスクマネージャのアプリケーションタブに 起動しているアプリケーション名とアイコンが一覧で表示されている部分のように 小さいアイコンを取得したいんですがなかなかうまくいきません。 ファイルに紐付くアイコンと解釈していただいても構いません。 とりあえず、下記のWin32 APIの処理を利用してみましたが SHGetFileInfoだけしかうまくいきませんでした。 しかし、SHGetFileInfoも、アイコンは取得できますがこれはファイルに紐付くアイコンではなく 実行体(EXE)に紐付くアイコンで表示されてしまいました。 開いているウィンドウ情報からだと実行プロセスのEXEのパスしか分からないからです。 ★質問★: ファイルに紐付く小さいアイコンの取得方法を教えてください!できればサンプルソース込みだと助かります。 #region 小さいアイコンを取得するためのWin32 API(ファイルパスから) // SHGetFileInfo関数 [DllImport("shell32.dll")] private static extern IntPtr SHGetFileInfo( string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags); // SHGetFileInfo関数で使用するフラグ private const uint SHGFI_ICON = 0x100; // アイコン・リソースの取得 private const uint SHGFI_LARGEICON = 0x0; // 大きいアイコン private const uint SHGFI_SMALLICON = 0x1; // 小さいアイコン private const uint SHGFI_TYPENAME = 0x400;//ファイルの種類 // SHGetFileInfo関数で使用する構造体 private struct SHFILEINFO { public IntPtr hIcon; public IntPtr iIcon; public uint dwAttributes; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string szDisplayName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)] public string szTypeName; }; #endregion #region 小さいアイコンを取得するためのWin32 API(ウィンドウハンドルからその1) [DllImport("user32.dll", EntryPoint = "GetClassLong")] public static extern IntPtr GetClassLongPtr32(IntPtr hWnd, int nIndex); [DllImport("user32.dll", EntryPoint = "GetClassLongPtr")] public static extern IntPtr GetClassLongPtr64(IntPtr hWnd, int nIndex); const int GCL_HICON = (-14); const int GCL_HICONSM = (-34); #endregion #region 小さいアイコンを取得するためのWin32 API(ウィンドウハンドルからその2) [DllImport("User32.dll", EntryPoint = "SendMessage")] public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam); public const int WM_GETICON = 0x7F; public const int WM_SETICON = 0x80; public const int ICON_SMALL = 0; public const int ICON_BIG = 1; #endregion

  • 特殊文字「\」の変換の方法

    VC++2005のMFCにてプログラムを作成しています。 CFileDialogにてテキストファイルを読み込み、 読込んだファイルパスの「\」を「\\」になるように変換したいのですが、 実装の方法が分かりません。 ===================================== 例)C:\test\hoge.txt ⇒ C:\\test\\hoge.txt と変換する。 ===================================== 下記にファイルパスをCstring型で読み込み、 char型に変換するまでのプログラムを記載します。 理想としては、char型配列の中に、 「C:\\test\\hoge.txt」のような変換後のファイルパスを 入れたいのです。 解決方法をご存知の方おられましたら、ご教示お願いできませんでしょうか。 【プログラム】 /* ファイルオープンダイアログを表示 */ CFileDialog ReadDlg( TRUE, NULL, "*.txt", OFN_HIDEREADONLY | OFN_FILEMUSTEXIST, "txtファイル(*.txt)", this ); CString filepath; if( ReadDlg.DoModal() == IDOK ) { filepath = ReadDlg.GetPathName(); // ファイルのフルパス名を取得 } CFile cfile; CFileException ex; if( !cfile.Open( filepath, CFile::modeRead , &ex ) ) { AfxMessageBox( "ファイルを開くのに失敗しました" ); // エラーメッセージを表示 return; } char st[255] = ""; strcpy( st, filepath );

  • ファイルサイズを変更したい

    visualstudio2010を使用しています。 c言語で書いているのですが、 test.txt ←abcdefg ファイルサイズ1KB Wtest.txt←書き込み用ファイル 上記のようなファイルがあり、バイナリでtest.txtを読み込みWtest.txtに書き込みたいと思っています。 その際に、1KBのtest.txtを5KBになるまでバイナリで「abcdefg」の後に0を代入したいのですがどう書けば良いのかわかりません。 FILE *fp, *fpw; char *fname = "test.txt"; char *fname_w = "Wtest.txt"; unsigned char buf[10000]; int size; fp = fopen( fname, "rb" ); if( fp == NULL ){ printf( "%sファイルが開けません\n", fname ); return -1; } fpw = fopen(fname_w, "wb"); if(fpw == NULL){ printf( "%sファイルが開けません\n", fname_w ); return -1; } size = fread( buf, sizeof( unsigned char ), sizeof (fp), fp ); /*ここに処理を追加したい*/ fwrite( buf, sizeof( unsigned char ), size, fpw);

  • OCXのメソッドの引数に文字列を返したい

    こんにちは。いつもお世話になっております。 早速ですが質問させて下さい。 VisualC++のClassWizardにて作成したメソッドの引数に文字列を返したいのですがどうすればよいでしょうか。 例えば、「test.ocx」というOCXにGetFileNameというメソッドを追加したとします。 ---<GetFileName>--- UINT GetFileName( LPCTSTR FilePath, //ファイルフルパス LPCTSTR FileName //ファイル名 ) ------------------- ---<VBからの呼び出し>--- FilePath = "C:\Program Files\test.txt" ret = obj.GetFileName(FilePath, FileName) 'ここでFileNameに値を返したい ------------------------ ここでFileNameにOCXから値を返すようにしたいのですが、型(ClassWizardパラメータリストの「タイプ」)は何になるのでしょうか。 数値を返す場合は、「long*」でできたのですが、 文字列を返す方法が分かりません。(「LPCTSTR*」というのもないですし) どうかご教示下さい。 <環境> Windows 2000, Visual C++ 6.0, Visual Basic 6.0

  • Unicodeのファイル読み込みがうまくいきません。。

    下のようなコードで読もうとしているんですが、どうしても文字化けしてしまいます。原因が何なのかさっぱりわかりません。。 分かる方どうかお願いします!開発環境はVC++.NETです。 FILE* fin; wchar_t c; CString ss; if( (fin = fopen( "temp.txt", "r" )) == NULL ){ AfxMessageBox("temp.txtファイルオープンエラー"); exit(1); } fgetws( &c, 2, fin ); ss += c; AfxMessageBox(ss);

  • critical error c0000005

    Visual C++ 2012 でファイルにデータを書き込む処理を組んでみた所、アプリケーション側にて下記のエラーが出てきます。 [Application side] -- log --------- function 'FuncTest' call from dll 'Test.dll' critical error c0000005 at 77D3F44D. ---------------- Test.cpp内の※1をコメントアウトすると、取り敢えずはエラーは発生しないのですが、どこが間違っているのかがわかりません。 よろしくお願いします。 下記は、VC++のソース部分です。 [Source of C++] --- Test.h ----- #define Test_API __declspec(dllexport) Test_API void WINAPI FuncTest(void); ---------------- --- Test.cpp --- #include "stdafx.h" #include "Test.h" Test_API void WINAPI FuncTest(void) { HANDLE hFile = NULL; __try { _EXCEPTION_POINTERS ep = {NULL}; __try { CHAR filePath[MAX_PATH]; sprintf(filePath, "filename.csv"); hFile = CreateFileA(fileName, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); <--- (※1) if(hFile == INVALID_HANDLE_VALUE) throw; ...(snip) } __except (ep = *GetExceptionInformation(), EXCEPTION_EXECUTE_HANDLER) {) { PEXCEPTION_RECORD per = ep.ExceptionRecord; CHAR eBuff[1024]; sprintf_s(eBuff, 1024, "%d (code:%x flag:%x addr:%p params:%d)", err, eRec->ExceptionCode, eRec->ExceptionFlags, eRec->ExceptionAddress, eRec->NumberParameters); free(eRec); MessageBoxA(NULL, eBuff, "FuncTest Error!", MB_OK); } } __finally { CloseHandle(hFile); } } ---------------- --- Test.def --- LIBRARY Test EXPORTS FuncTest ----------------

専門家に質問してみよう