none
CRectTrackerのカーソルが表示されない。 RRS feed

  • 質問

  • いつも大変お世話になっております。

    CRectTrackerをサブクラス化して、矩形選択処理を行っています。

    VC++6.0で開発したソフトを、VS2008に移行させたところ

    カーソルが出なくなりました。

    http://support.microsoft.com/kb/208856/ja

    >[表示] メニューの [インクルード ファイルの設定]をクリックし、次の行を削除します。

    >#define _AFX_NO_TRACKER_RESOUCES

    このページに上記説明があったので、

    [編集] メニューの [リソースファイルのインクルード]を見てみたのですが、

    <#define _AFX_NO_TRACKER_RESOUCES>の記述はありませんでした。

    http://rarara.cafe.coocan.jp/cgi-bin/lng/vc/vclng.cgi?print+200407/04070012.txt

    >私の場合はCRectTrackerのコンストラクタで、
    >うまいことリソースをロードできていないようだったので、
    >サブクラス化したCRectTrackerのコンストラクタで自前でロードしました。

    さらに上記説明を見つけたのですが、方法がわかりません。

    解決策をご存知の方いらっしゃいましたら、

    ご指導よろしくお願いいたします。

    2012年7月20日 2:29

回答

  • MFCは、スタティックリンクでしょうか?DLL利用でしょうか?DLL利用なら、カーソルがロードできないということはないと思うんですが。。。

    MFCをスタティックリンクする場合は、ソリューションエクスプローラでリソースのタブを開き、リソースファイルのコンテキストメニューから「リソースファイルのインクルード...」を選ぶと出てくるダイアログの、下側部分から、_AFX_NOR_TRACKER_RESOURCES を削除することで対応できるはずです。

    もし、DLLを使っていてもロードできないとなると、MFC側のバグってことになるかと。。。

    この場合は、EXEのリソースに AfxRes.rc から CRectTracker 用のデータをコピーしてきて自分で背負うことになります。VS2008のMFCが修正される可能性は極めて低いと言わざるを得ませんので。。。


    わんくま同盟,Microsoft MVP for Visual C++(Oct 2005-) http://blogs.wankuma.com/tocchann/

    • 回答としてマーク kizakura_ui 2012年7月23日 5:32
    2012年7月20日 4:02
  • サンプルではうまくいっていたので、プロジェクト固有の問題の可能性が高いと考えます。もし、プロジェクト固有の問題だとすれば、EXEでリソースを用意すれば解決するということではなくなるため、ソースコード全体をチェックしなおす必要があります。

    CRectTracker のソース(VS2008のもの)を見る限り、失敗の直接的原因は、AfxFindResourceHandle で、CRectTracker 用のカーソルリソースを抱えているインスタンスのハンドルが取れないことにあります。

    なぜ、そうなるのか?は、プロジェクトのソースを精査しないとわかりませんので、ここでは言及できません。ですが、それが原因だとするとAfxFindResourceHandleが失敗するような何かが、初めて CRectTracker のコンストラクタを呼ぶタイミングで発生していると思います。


    わんくま同盟,Microsoft MVP for Visual C++(Oct 2005-) http://blogs.wankuma.com/tocchann/

    • 回答としてマーク kizakura_ui 2012年7月24日 2:46
    2012年7月23日 8:52

すべての返信

  • MFCは、スタティックリンクでしょうか?DLL利用でしょうか?DLL利用なら、カーソルがロードできないということはないと思うんですが。。。

    MFCをスタティックリンクする場合は、ソリューションエクスプローラでリソースのタブを開き、リソースファイルのコンテキストメニューから「リソースファイルのインクルード...」を選ぶと出てくるダイアログの、下側部分から、_AFX_NOR_TRACKER_RESOURCES を削除することで対応できるはずです。

    もし、DLLを使っていてもロードできないとなると、MFC側のバグってことになるかと。。。

    この場合は、EXEのリソースに AfxRes.rc から CRectTracker 用のデータをコピーしてきて自分で背負うことになります。VS2008のMFCが修正される可能性は極めて低いと言わざるを得ませんので。。。


    わんくま同盟,Microsoft MVP for Visual C++(Oct 2005-) http://blogs.wankuma.com/tocchann/

    • 回答としてマーク kizakura_ui 2012年7月23日 5:32
    2012年7月20日 4:02
  • ご指導、ありがとうございます。

    ・MFCをDLL利用に変更しても結果は同じでした。

    ・「リソースファイルのインクルード...」には、下記2行しかありませんでした。

     #define _AFX_NO_SPLITTER_RESOURCES
     #define _AFX_NO_PROPERTY_RESOURCES

    ・>この場合は、EXEのリソースに AfxRes.rc から CRectTracker 用のデータをコピーしてきて自分で背負うことになります。

     この方法がわからないのですが、いろいろTRYしてみます。ありがとうございました。

    2012年7月23日 0:15
  • ちょっと気になったので、VS付属のサンプルで試してみました(サンプルは、VSインストール先のSamplesフォルダに圧縮された形で格納されています)。

    んと、サンプルは、DLLを利用になっているのでとりあえずそのままビルド&実行してみましたが、問題なくリソースがロードされ、意図したカーソルが表示されました。

    また、スタティックリンクも試してみましたが(サンプルには、_AFXDLL が不必要にセットされているので消さないとうまくビルドできません)、こちらも問題なく表示されています。

    ってことは、何かもっと別の理由でうまくいっていないのだと思います。それが何かまでは、わかりません。

    あと、当初読み落としていたのですが、CRectTracker のサブクラス化とは派生したクラスを作った。。。でいいんですよね?サブクラス化って言わない気がしますが。。。

    ま、それはともかく、CRectTrackerをそのまま使う場合は問題がないのでしょうか?一度チェックしてみるといいかもしれません。


    わんくま同盟,Microsoft MVP for Visual C++(Oct 2005-) http://blogs.wankuma.com/tocchann/

    2012年7月23日 1:32
  • いろいろと試していただきありがとうございました。

    >CRectTracker のサブクラス化とは派生したクラスを作った。。。でいいんですよね?

    すみません、派生クラスです。

    矩形の拡張範囲を規制したかったので、サブクラス化して、AdjustRect()をオーバーライドしています。

    テスト的に、CRectTrackerをそのまま使うようにしてみましたが、やはりカーソルは出ませんでした。

    (<共有DLLでMFCを使う>設定です)

    「リソースファイルのインクルード...」に、<#define _AFX_NO_TRACKER_RESOUCES>の記述がないなど

    VC++6.0で開発したソフトを移行させたことが問題なのかもしれませんね。

    >EXEのリソースに AfxRes.rc から CRectTracker 用のデータをコピーしてきて自分で背負うことになります。

    挑戦してみます。

    ありがとうございました。

    2012年7月23日 4:15
  • リソースファイルのインクルードのところは、MFCをDLL利用ではなく、スタティックリンクする場合に参照するか所になります。DLLでリンクする場合は影響しません。

    と、それはともかくDLLを使っていて、CRectTracker をそのままとしてもうまくいかないとなると、何か別の要因がありそうです。それが何かはわかりませんが...


    わんくま同盟,Microsoft MVP for Visual C++(Oct 2005-) http://blogs.wankuma.com/tocchann/

    2012年7月23日 4:40
  • >この場合は、EXEのリソースに AfxRes.rc から CRectTracker 用のデータをコピーしてきて自分で背負うことになります。

    EXEのリソースに下記部分を追加し、Microsoftのインクルードフォルダから

    直下のresフォルダに、<*.cur>をコピーしたのですが、うまくいきませんでした。

    方法は、ここでご教授していただけるほど簡単なものではないのでしょうか?

    大雑把なことで結構ですので、何かヒントをいただけるとありがたいです。

    どうかよろしくお願いいたします。


    /////////////////////////////////////////////////////////////////////////////
    //
    // Cursol
    //

    AFX_IDC_TRACKNWSE       CURSOR  DISCARDABLE     "res\\trcknwse.cur"
    AFX_IDC_TRACKNESW       CURSOR  DISCARDABLE     "res\\trcknesw.cur"
    AFX_IDC_TRACKNS         CURSOR  DISCARDABLE     "res\\trckns.cur"
    AFX_IDC_TRACKWE         CURSOR  DISCARDABLE     "res\\trckwe.cur"
    AFX_IDC_TRACK4WAY       CURSOR  DISCARDABLE     "res\\trck4way.cur"
    AFX_IDC_MOVE4WAY        CURSOR  DISCARDABLE     "res\\move4way.cur"

    2012年7月23日 8:20
  • サンプルではうまくいっていたので、プロジェクト固有の問題の可能性が高いと考えます。もし、プロジェクト固有の問題だとすれば、EXEでリソースを用意すれば解決するということではなくなるため、ソースコード全体をチェックしなおす必要があります。

    CRectTracker のソース(VS2008のもの)を見る限り、失敗の直接的原因は、AfxFindResourceHandle で、CRectTracker 用のカーソルリソースを抱えているインスタンスのハンドルが取れないことにあります。

    なぜ、そうなるのか?は、プロジェクトのソースを精査しないとわかりませんので、ここでは言及できません。ですが、それが原因だとするとAfxFindResourceHandleが失敗するような何かが、初めて CRectTracker のコンストラクタを呼ぶタイミングで発生していると思います。


    わんくま同盟,Microsoft MVP for Visual C++(Oct 2005-) http://blogs.wankuma.com/tocchann/

    • 回答としてマーク kizakura_ui 2012年7月24日 2:46
    2012年7月23日 8:52
  • 重ね重ね、ありがとうございます。

    何から手をつけていいのかわからない状態ですが、いろいろ調べてみたいと思います。

    ご指導、ありがとうございました。

    2012年7月24日 1:39
  • できました!!!

    >CRectTracker のソース(VS2008のもの)を見る限り、失敗の直接的原因は、AfxFindResourceHandle で、CRectTracker 用のカーソルリソースを抱えているインスタンスのハンドルが取れないことにあります。

    このご指摘で、CRectTrackerがカーソルをロードしている部分をデバッガーで追っかけてみたところ、なぜかハンドルは取れておりカーソルもがでるようになりました。

    (実は、デバッグモードだとカーソルは元々表示されていただけでした)

    リリースモードでは相変わらず表示されないので、CRectTrackerで行っているロード処理を自前のソースで行い、

    カーソルを変更する必要がある場合に限り、::SetCursor(_Cursors[hit]) <Cursors:ロードしたカーソルのハンドル hit:CRectTracker::HitTest()の結果>

    を行った結果、カーソルが表示されるようになりました。

    根本的な原因はわかりませんが、これで解決としたいと思います。

    お陰様で大変助かりました。

    本当にありがとうございました。

    P.S. この方法に、何か問題はありますでしょうか?

    2012年7月24日 2:46
  • デバッグ版でうまくいっていて、リリース版ではうまくいかないとすると、ほぼ間違いなくリリース版のプロジェクトの設定のどこかに問題があると仮定できますね。

    例えば、リリース版はMFCをスタティックリンクしていて、なおかつ _AFXDLL をデファインしているとか(これがリソースのコンパイルオプションにあるとafxres.rcは取り込まれません)。

    ま、これは、先日テストで試してみたときに見つけたものなので違うかもしれません。

    いずれにしても、デバッグ版ではうまくいくということなので、違いを調べていけば、自前で処理する必要はなくなると思います。


    わんくま同盟,Microsoft MVP for Visual C++(Oct 2005-) http://blogs.wankuma.com/tocchann/

    2012年7月24日 3:02
  • たびたび、申し訳ありません。

    デバッグ版とリリース版の違いですが、うまくカーソルが表示できるのは、デバッグ版の<共有 DLL で MFC を使う>の時だけです。

    そのモードの時だけ、リソースのコマンドラインに</D "_AFXDLL">の記述があります。

    コンパイルオプションに</D "_AFXDLL">を付加するにはどうしたらよいのでしょうか?

    それから、できれば<スタティック ライブラリで MFC を使用する>にしたいのですが。

    よろしくお願いいたします。

     

    ----------------------------------------------------------------------------------------------------------

    デバッグ版:

     共有 DLL で MFC を使う : カーソルが出る ・ リソースのコマンドラインに</D "_AFXDLL">の記述がある 。

     スタティック ライブラリで MFC を使用する : カーソルが出ない ・ </D "_AFXDLL">の記述がない 。

     

    リリース版:

     共有 DLL で MFC を使う : カーソルが出ない ・ </D "_AFXDLL">の記述がない 。

     スタティック ライブラリで MFC を使用する : カーソルが出ない ・ </D "_AFXDLL">の記述がない 。

    ----------------------------------------------------------------------------------------------------------

    <リソースファイルのインクルード>

    #define _AFX_NO_SPLITTER_RESOURCES
    #define _AFX_NO_PROPERTY_RESOURCES

    #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_JPN)
    #ifdef _WIN32
    LANGUAGE 17, 1
    #pragma code_page(932)
    #endif
    #include "res\nwp32.rc2"  // Microsoft Visual C++ 以外のツールで編集されたリソース
    #include "l.jpn\afxres.rc"          // 標準のコンポーネント
    #include "l.jpn\afxolecl.rc"        // OLE コンテナ リソース
    #include "l.jpn\afxolesv.rc"        // OLE サーバー リソース
    #endif

     

    2012年7月24日 5:01
  • VC6からのコンバートに絡む問題っぽいですね。細かなところはプロジェクトを見てみないとわかりませんが、一度、新規にプロジェクトを作って、それと vcproj 自身を比べてみるといいかもしれません。

    ということで、_AFXDLL に関する部分だけ。

    _AFXDLL は、MFCのDLLを利用するというコンパイルオプションです。そのため、スタティックリンクの場合このオプションは定義されません。

    設定は、プロパティの全般のページで設定します。「MFCの利用」のコンボで

    「共有DLLでMFCを使う」にすると、MFCのDLL用のインポートライブラリをリンクするようにして、ソースコードとリソースのコンパイルオプションに"_AFXDLL"を追加します(ビルド時に自動追加)。

    「スタティックライブラリでMFCを使う」にすると、MFCのスタティックリンク用ライブラリをリンクするようにします。この時、_AFXDLL などは追加されません。

    そのあたりも含めてチェックしてみてください。


    わんくま同盟,Microsoft MVP for Visual C++(Oct 2005-) http://blogs.wankuma.com/tocchann/

    2012年7月24日 5:22
  • 詳しいご解説、ありがとうございます。

    >VC6からのコンバートに絡む問題っぽいですね。細かなところはプロジェクトを見てみないとわかりませんが、一度、新規にプロジェクトを作って、それと vcproj 自身を比べてみるといいかもしれません。

    はい、そうしてみます。ありがとうございました。

    2012年7月24日 5:55