7

現在、古い VB6 アプリケーションを C# を使用して WPF に移植するオプションを検討しています。フェーズ 1 の計画では、すべてのアプリケーションではなく、いくつかの主要なフォームを移植する予定です。理論上の目標は、ActiveX dll を介して WPF 内の何らかのコンテナーで VB6 フォームを開くことです。

これは可能ですか?私は相互運用機能を調べてみましたが、完全な形式ではなく、Win32 コントロール以外で動作させる方法の確かな例を見つけることができないようです。私は古い VB6 コードに完全にアクセスでき、必要に応じて変更できます。

次のメイン WPF アプリのスクリーンショットは、ラッパー/コンテナーとして機能します。

http://www.evocommand.com/junk_delete_me/main_menu_mockup.png

前の画面の右側にある「空白」セクションにロードされる現在の VB6 メンテナンス画面。

4

5 に答える 5

12

次の手順でタスクを達成できました。

  1. 新しい VB6 Active X コントロール プロジェクトを作成しました。VB6 フォーム コントロールとコード ビハインドのコンテンツ全体を新しいコントロールにコピー アンド ペーストしました。コントロールに切り替える際に処理する必要がある要素がいくつかあります。

    1. 以前の方法でフォームのキャプションを表示できなくなります。必要に応じて、同じ機能を実現する別のコントロール (label/borderlesstextbox など) を使用して回避できます。新しい .Net プロジェクトでは、各画面がタブ システムのようなブラウザーでホストされていたため、これは優先事項ではありませんでした。

    2. すべてのマウスポインター参照を Me.Mousepointer から Screen.mousepointer に変更する必要があります。

    3. Me.Hide を使用することはできず、.Net コンテナーを非表示にするためにイベントを交互に実行する必要があります。

    4. Me.[anything] へのすべての参照は、削除するか、該当する場合は UserControl.[anything] に置き換える必要があります。

    5. フォームで [yourcontrol].Contianer.Property を参照する関数を使用する場合は、代わりに UserControl.Controls コレクションをループするように変更する必要があります。「Container」は vb6 ActiveX コントロールでは無効です。

    6. WPF で処理する Hwnd がないため、すべての非モーダル フォーム/ダイアログ ボックスをプロジェクトから削除する必要があります。「このホスト アプリケーションでは、ActiveX DLL、ActiveX コントロール、またはプロパティ ページから非モーダル フォームを表示できません」というエラーが表示されます。私たちの場合、特定の長いプロセス/レポートが表示されたときに表示され、何が実行されているかをユーザーに知らせる単純なスプラッシュ スクリーンがありました。

  2. 相互運用機能を介して VB6 コントロールを WPF プロジェクトに直接追加できませんでした。そのため、.Net の新しい「Windows フォーム コントロール ライブラリ」プロジェクトが作成されました。VB6 OCX への参照がプロジェクトに追加されました。次に、「右クリック」→「項目の追加」を選択し、VB6 コントロール ocx への com 参照を指定して、VB6 コントロールを .Net ツールボックスに追加しました。.Net コントロールは、VB6 コントロールをホスト/提供するために使用されました。

  3. VB6 でホスト フォームを表示し、必要な初期化機能を起動するために、VB6 OCX コントロールは Visible.False 方式でデフォルト設定されたため、最初は非表示コントロールとして .Net OCX に追加されました。必要に応じて、VB6 コントロールを visible = True に設定すると、UserControl_Show() イベントが発生します。以前 Form_Load() にあったすべてのコードは、このイベントに移動されました。show イベントは、必要に応じて Form_Load にアクセスする最も簡単な方法でした。MSDN: 「フォームが非表示になってから再び表示された場合、またはフォームが最小化されてから復元された場合、コントロールは Show イベントを受け取りません。これらの操作中、コントロールのウィンドウはフォーム上に残り、Visible プロパティは変更されません。」</p>

  4. vb6 コントロールを .Net Winform コントロール内にラップすると、この質問に対する私の回答の 1 つで概説されているように、ラジオ/オプション ボタンが黒くレンダリングされるという問題が解決されました。フレームを画像ボックスに変換する必要はありません。

  5. WPF アプリでメニューの選択肢が選択されると、xaml コードが動的に作成され、WindowsFormsHost タグを持つラッパーを介して表示されます。次に、.Net winform アプリから動的に作成されたコントロール オブジェクトが xaml の WindowsFormsHost タグにプッシュされ、.net プロジェクトでコントロールが表示され、vb6 UserControl_Show が起動され、vb6 フォームが読み込まれて表示されます。

于 2010-02-25T23:14:51.510 に答える
3

あなたがしなければならないことは、VB6 フォームの内容を ActiveX コントロールに抽出することだと思います。これを ActiveX dll で公開し、WPF フォームに配置できます。他のタイプのフォーム内で VB6 フォームをホストできるとは思えません。

于 2010-02-10T23:19:53.297 に答える
1

そのVB6フォームを別のVB6フォームにロードすることもできますか?最初にそれを機能させることをお勧めします。

于 2010-02-10T19:54:00.287 に答える
0

VB6 フォームの親を設定する信頼できる方法はありません。いつでもハックするか、VB6 フォームの代わりにプレーンな ActiveX コントロール (VB6 の UserControl) を UI コンテナーとして使用できます。

于 2010-02-10T23:00:02.687 に答える
0

この時点で、WPF ではなく WinForms 内で必要なことを行う方法を見つけました。 http://www.codeproject.com/KB/vb-interop/VB6formsinNET.aspx 100% 動作させることができれば、WPF に移植することも、最悪の場合は WinForm 要素を WPF フォームでホストすることもできます。絶対に持っています(醜い)。

とにかく、もう少し近づいてきましたが、特定のコントロールが画面にも描画されるという非常に奇妙な問題が発生しています。ラジオ/オプション ボタンが黒一色でレンダリングされます。

http://www.evocommand.com/junk_delete_me/optionbuttons.png

コントロールの背景色をボタンフェイスから固定色に明示的に変更しようとしましたが、それでも変更されません。オプションボタンがフレームコントロール内にあるというレイヤーの問題だと思います。オプション ボタンをチェックボックスに変更するために VB6 コンテンツを大幅に変更せずに続行する方法について、私は少し途方に暮れています。これは非常に大きなアプリであり、アプリケーション全体に 600 以上のオプション ボタン コントロールがあり、それらを正確に処理したくありません。

編集: フレーム コントロール内のオプションのレイヤー化と関係があることを確認できました。ベース フォームに引き出された場合、問題は発生しません: http://www.evocommand.com/junk_delete_me/optionbuttons2.png

于 2010-02-12T20:07:16.570 に答える