SDIアプリ内からもう一つSDIを作成する方法

このQ&Aのポイント
  • SDIアプリ内で新しいSDIを作成する方法はありますか?
  • Exe側のツールバーがおかしくなる問題が発生しています。
  • 参考になるサイトや書籍、アドバイスを求めています。
回答を見る
  • ベストアンサー

SDIアプリ内からもう一つSDIを作成する方法

開発環境:WindowsXPSp3 + VC++2010 SDIの単純なアプリケーションと、スタティックリンクしているDLL(拡張DLL)があります。 exeのツールバーにあるボタンをクリックすると、DLL内にあるCreateNewWindowという関数を呼ぶようになっています。 このCreateNewWindowでは以下のようなコードが書かれています。 ------------------------------------------------------------------ CSingleDocTemplate* g_pNewWnd ; // グローバル void WINAPI CreateNewWindow() {   if( NULL == g_pNewWnd ) {     g_pNewWnd = new CSingleDocTemplate(       IDR_NEWWINDOW,       RUNTIME_CLASS( CSDIWndDoc ),       RUNTIME_CLASS( CSDIWndFrame ),       RUNTIME_CLASS( CSDIWndView )     );     CDocument* pDocumanet = g_pNewWnd->OpenDocumentFile( NULL ) ;   } } ※初期化や破棄処理は適宜行っているものとします。 ------------------------------------------------------------------ このように、Exeのほうに1つのSDIが存在している状態で、さらにDLL内で別のSDIのウィンドウを作成することは許されるのでしょうか? 実行すると、一応、ウィンドウは作成されるのですが、これらのフレーム内でCMFCToolBarを作成すると、DLLのこの関数でSDIを作成した時点でexe側のツールバーがおかしくなります。 具体的にはDLLのリソースにあるツールバーがexeのツールバーとして不完全な状態で反映され、DLLで作ったSDIウィンドウでは、ツールバーの領域だけ確保されてなにも無い状態です。 この関数を実行するまではexeのツールバーは正常に表示・動作しています。もちろん、リソースIDがユニークになているのは確認済みです。 やりたいことは、SDIやダイアログなどからボタンを押したら動的にSDIのウィンドウを生成して提供するDLLを作成したいのです。 参考になるサイトや書籍、アドバイスを頂けませんでしょうか。 よろしくお願いします。

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

  • ベストアンサー
  • FAY
  • ベストアンサー率49% (95/193)
回答No.1

ID、ほんとうにユニークになっていますか。 デフォルトの実装では省略されている CMFCToolBarCreate()で渡されるIDを確認してみましたか? 下記参考URLのryoさんの回答のようにしてみるとどうなるでしょうか。

参考URL:
http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+201003/10030014.txt
shouko0918
質問者

お礼

FAYさん、ありがとうございます。 参照先にあったようにm_wndToolBar.CreateExの引数にツールバーのリソースIDをセットしましたが、現象は変わらずです。 その後、分かりやすくしようと、DLL側のツールバーのアイコンサイズを16x16から32x32に変更してみました。 すると、新しく生成したSDIのツールバーだけがおかしいのならばリソース関連だろうと思うのですが、親SDIの方のツールバーやメニューなどのPaneサイズまで32x32になるのです。 子SDIウィンドウを生成した後で、親ウィンドウのツールバー全体に影響を与えています。 また、親のSDIをCFrameWndクラスで作り直したところ、問題なく表示されることが確認できました。 つまり、今回の現象は、親、子ともにCFrameWndExのフレームを持つSDIでCMFCToolBarを使ったときに起きています。 なにか、やるべき事、設定すべき事が他にあるのでしょうか?

関連するQ&A

  • MFC オリジナルDLLからエクスポートしたビュークラスを CMultiDocTemplate で登録すると Assert Failed! が出る

    環境はVisualStudio2005、MDIプロジェクトと拡張DLLプロジェクトを1つのソリューションに作成しています。 MDIアプリを作成していますが InitInstance() 関数内の CMultiDocTemplateの引数 RUNTIME_CLASS() 実行時にAssert Failed!が出ます。 CMultiDocTemplate に登録するビュークラスはオリジナルの拡張DLL内でCFormViewクラスから派生させたクラスです。 特に変わったことをしている訳ではなく、ほとんどウィザードがソースを吐いた状態のままです。 "COriginalView" をデフォルトの "CMyView" にするとエラーは出ません。 また、"COriginalView" もコントロールを1ヶ置いてビューフォームとクラスを作成し、 AFX_EXT_CLASS でエクスポートして参照できています。 また、MDI側でフォームとクラスを作成しそれを使用した場合はエラーは出ません。 ドキュメント/ビューアーキテクチャの理解が足りない為起きている問題だと思います。 宜しくお願い致します。 --- 詳細 ------------------------------------------------ CMultiDocTemplate* pDocTemplate; pDocTemplate = new CMultiDocTemplate(IDR_MAINFRAME,   RUNTIME_CLASS(CMyDoc),   RUNTIME_CLASS(CChildFrame),   RUNTIME_CLASS(CDllView)); ←これ実行時に Assert が出る AddDocTemplate(pDocTemplate); ---------------------------------------------------------

  • C#で実行可能なdllの作成方法

    現在、C#でアプリケーションを作成していますが、exe形式ではなくdll形式で実行可能な モジュールを作成したいです。 しかし、単に[STAThread]のMain関数を作ったり、staticコンストラクタを作成しただけでは 起動できません。 どうしたら実行可能なdllを作成できるのでしょうか。 最終的にやりたいことは、C++のCreateRemoteThread()からこのdllを起動することです。 どうぞよろしくお願いします。

  • SDIウィンドウを動的に複数生成する方法

    ダイアログベースのアプリケーションに配置したボタンを押すたびに、 SDIのウィンドウを動的に生成・表示したいと思っています。 しかし、なにをどうすればいいのかわかりません。 とっかかりでもよいので、なにかヒントが欲しいと思って質問します。 生成するSDIウィンドウには以下のような必要条件があります。 1.CMfcToolBarがある 2.CMfcRibbonStatusBarとスライダーバーがある。 3.独自に作成したCScrollViewクラスの派生クラスを使用する 4.1アプリケーション内で複数のSDIを生成する 開発環境 VC2010, WindowsXP よろしくお願いします。 <背景> 以前、CSingleDocTemplateを使用してウィンドウを作成しが、なぜかツールバーのボタンにUPDATE_COMMAND_UIがこない事が判明。 四苦八苦したが解決できないため、別アプローチを検討したいと思った。

  • VB2005で作成したDLLの呼び出し方

    はじめまして、VB2005(.NET)初心者です。 現在、各プログラムを実行するためのメニュー プログラムを作成しています。 .net以前では、各プログラムをEXEで作成し API関数を利用し、メニューより実行させて いましたが、今回、各プログラムをEXEではなく dllで作成し実行する方法で作ることになりました。 各プログラムのdllを実行する方法がわかりません。 参考書等みてみましたが、見当たりません。 どのようにしていらっしゃるか教えて下さい。 宜しくお願いいたします。

  • VC++6.0からVBで作成したActiveX.DLL内の関数が呼出しできない

    VB6.0で作成したActiveX.DLLをVC++6.0(Win32SDK)側で 呼び出すプログラムを作成中です。 VB側(DLL)では問題なく作成できています。 Classに1つPublic関数を作成しただけです。 (Instancingは5MultiUseにしてあります) しかし、VC++側の呼出しでDLL内の関数が 呼び出せないのです。 LoadLibraryExでDLL自体のハンドルは取得できるのですが GetProcAddressで関数の取得時にNULLが返ってきてしまいます。 今まで試したことは ・VBからの呼出しはOK ・MFCだとOK ・SDKでもuser32.dll呼出しのサンプルは関数も実行できる です。 今からMFCへ以降するのは厳しいのでSDkでの方法を 知りたいです。 VB側が悪いのかもしれませんが、関数1つですし、 いじるところもほとんどないので多分VC++側だと 思っています。 なにか注意点とか確認するところをおしえていただければ 幸いです。 環境 Windows2000 SP3 VB6.0 SP5 VC++6.0 SP5 Win32SDK

  • VC++で作成したDLLについて

    すみません、 VC++6.0で作成したDLLについて教えていただきたいのですが。 TEST_A.DLLというDLLと、TEST_B.DLLというDLLファイルを作成したとして これをC:\TEST\DLL\に格納してるとします。 このとき、TEST_B.DLLからはTEST_A.DLLの関数を呼び出しています。 次に、TEST_B.DLLの関数を使用しているTEST.EXEという実行ファイルを VB6.0で作成します。 このファイルをC:\TEST\EXE\に格納します。 そして、TEST.EXEを実行すると、 「TEST_B.EDLLが見付かりません」と言って怒られてしまいます。 VBでは、TEST_B.DLLをフルパスで指定しております。 しかし、TEST_A.DLLをEXEと同じ場所に置いてあげると 正常に動きます。 これは、TEST_B.DLLからTEST_A.DLLが見えていないということなのでしょうか? TEST_B.DLLの設定がおかしいのでしょうか? それとも、TEST.EXEでもTEST_A.DLLをフルパス指定してあげないといけないのでしょうか? ちなみに今回、プロジェクトマネージャーから「環境変数(PATH)の設定はしたくない」と言われていますので、PATHの指定はしてません。 すみませんが、どなたか教えていただけますでしょうか?

  • VB6で作成したDLLをVC6で使用する方法

    VB6で作成したDLLをVC6で使用できなくて困っています。 以下にトライしたことを示します。 (1) VB6でTRUEを返すだけの関数を入れたActiveX DLLを作成 (2) VC6のLoadLibraryに成功(戻り値がNULL以外) (3) VC6のGetProcAddressに失敗(戻り値がNULL) (4) VC.NET付属のDumpbinユーティリティでは(1)で作成した関数が表示されない。 何が悪いのでしょうか。 宜しくお願いします。

  • Microsoft Visual C++ 6.0でダイアログボックス作成後のEXE作成方法

    Microsoft Visual C++ 6.0を新規で開いて、「挿入」-「リソース」のリソースの挿入画面で、2つダイアログ(Dialog)を作りました。新規作成で作りましたので「Script1 – IDD_DIALOG1(Dialog)」「Script1 – IDD_DIALOG2(Dialog)」と2ウィンドウのタイトルバーに書かれてあります。さて、これらを保存しようとした時にプロジェクト名を決めないといけないみたいで、適当にtestと名づけました。プロジェクトを作成すると、「test.dsw」というプロジェクトワークスペースが出来ました。ここで、「Debug」というフォルダが作成されましたので、このフォルダ内にEXEファイルを作成して、EXEを実行して2つのウィンドウを上手く機能も付けてアプリケーションを作ろうと思っているのですが、コンパイルすると 『 プロジェクト 'test - Win32 Debug' 用の中間ファイルおよび出力ファイルを削除しています。 --------------------構成: test - Win32 Debug-------------------- リソースをコンパイル中... リンク中... LINK:error LNK2001:外部シンボル "_WinMainCRTStartup" は未解決です Debug/test.exe : fatal error LNK1120: 外部参照 1 が未解決です。 link.exe の実行エラー 』 と、ドッキングビューに表示されています。 どのようにしたら、EXEを作成できて実行できるか、対策案をお願いいたします。

  • 32bitアプリから16bitのEXEやDLLのバージョン情報が読めるか?

    ものすごく趣味レベルの質問なので、余裕のある方、教えてください。 32bitイメージのEXEやDLLでバージョン情報リソースを持つファイルは、 VerQueryValue関数でバージョン情報を取得できますが、 16bitイメージのEXEやDLLの場合は、関数自体がエラーを返すので取得できません。 いまさら16bitイメージのEXEを視野に入れるのもどうかな?とは思いますが、 簡単に取得可能であれば32/16bitのどちらでも読めるようにロジックを書きたい、というわけです。 リソースを直接読み出そうとがんばったんですが、結局LoadLibrary関数なども 16bitイメージは開けないようで・・・。 やっぱりサンクとか使うんでしょうか?・・・面倒だなぁw

  • C#のビルド方法について質問です。

    IDEをつかわず、コマンドプロンプト上でC#のソースをビルドする時の方法について質問です。 まず以下のようなコードがあるとします。 まずC:\の直下に以下のソースを作成しました。 =================================================== using System; using System.IO; using System.Windows.Forms; namespace Add.TestClass{ public class LibraryClass{ public LibraryClass(){ MessageBox.Show("クラスライブラリコンストラクタの実行"); } } } =================================================== 上記クラスをdllファイルとしてビルドします。 csc /t:library /out:Add.TestClass library.class  と上記のようにビルドしました。するとAdd.TestClass.dllというファイルが確かにできあがりました。 次にこれを実際に実行するためのファイルをつくりました。 それが以下になります。 同じくC:\直下に以下のようなソースを作成します。 =================================================== using System; using System.IO; using System.Windows.Forms; using Add.TestClass; public class MainClass{ public static void Main(String [] args){ LibraryClass obj = new LibraryClass(); } } =================================================== このファイルをビルドします。 csc /r:Add.TestClass.dll main.cs としてビルドし、その後 mainというファイルを実行しました。 するとキチンとMessageBoxで MessageBox.Show("クラスライブラリコンストラクタの実行");が実行されました。 ここまでは問題ないのですが、この場合 main.exeファイルとAdd.TestClass.dllというファイルが 同じ階層に存在するような状態になっているのですが、これを main.exeファイルのある階層にdllというディレクトリを作成し そのdllの中にAdd.TestClass.dllというファイルをおいた階層状況でmain.exeファイルを実行したいのです。 そのためにまず、 csc /r:”C:\dll\Add.TestClass.dll" main.cs 上記のようなビルドオプションでビルドしてみたのですが、ビルドはとおりましたが -------------------------------------------------------------------------------------------------------------------- ハンドルされていない例外: System.IO.FileNotFoundException: ファイルまたはアセン ブリ 'Add.TestClass, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'、ま たはその依存関係の 1 つが読み込めませんでした。指定されたファイルが見つかりませ ん。 場所 MainClass.Main(String[] args) -------------------------------------------------------------------------------------------------------------------- というエラーがでました。 このdllファイルを特定の任意のディレクトリ内において、main.exeを実行してうまく動くようにするためには どのようなビルドオプションをつけたらいいのでしょうか? よろしくご教授お願いいたしま。

専門家に質問してみよう