2010-02-10 4 views
6

Attualmente sto esplorando l'opzione di trasferire alcune vecchie applicazioni VB6 su WPF con C#. Il piano, nella prima fase, consiste nel portare diverse forme chiave e non tutte le applicazioni. L'obiettivo teorico è di aprire il modulo VB6 in un contenitore di qualche tipo all'interno di WPF tramite una DLL ActiveX.Può/come si ospita un modulo VB6 completo in un'app WPF C#?

È possibile? Ho provato a guardare l'Interop e non riesco a trovare un solido esempio di come farlo funzionare con qualsiasi cosa tranne i controlli Win32, non una forma completa. Ho pieno accesso al vecchio codice VB6 e posso modificarlo in ogni caso.

La seguente immagine del principale WPF servirebbe come l'involucro/contenitore:

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

La corrente schermata di manutenzione VB6 che verrebbe caricata nella sezione “spazio bianco” sul lato destro la schermata precedente.

risposta

11

sono riuscito a realizzare il compito con le seguenti operazioni:

  1. Creato un nuovo progetto di controllo attivo X VB6. Copiato e incollato l'intero contenuto dei controlli di modulo VB6 e codice nel nuovo controllo.Ci sono diversi elementi che devono essere gestite nel passaggio a un controllo:

    1. si perde la possibilità di visualizzare la didascalia del modulo nella maniera precedente. È possibile aggirare lo con i comandi alternativi (label/borderlesstextbox, ecc.) Che realizzi la stessa funzionalità se è necessario . Questa non era una priorità dal ogni schermata veniva ospitata in un sistema di scheda simile a un browser nel nostro nuovo progetto .Net.

    2. Tutti i riferimenti devono MousePointer essere cambiato da Me.Mousepointer a Screen.MousePointer

    3. Non è possibile utilizzare Me.Hide e devono alterne vicende per nascondere il contenitore .Net .

    4. Ogni e tutti i riferimenti a me. [Qualsiasi cosa] devono essere rimossi o sostituiti con UserControl. [Nulla] se sono applicabili.

    5. Se si utilizzano le funzioni che riferimento un [yourcontrol] .Contianer.Property su una forma avranno bisogno di essere modificati per ciclo tra gli UserControl.Controls raccolta invece e “Container” è valida per VB6 controlli ActiveX

    6. Tutte le caselle di forme non-modali/Dialog devono essere rimossi dal progetto come ora non c'è Hwnd per gestire in WPF. Si ottiene un errore di "Moduli non modali non può essere visualizzato in questa applicazione host da una DLL ActiveX, Controllo ActiveX o pagina Proprietà". Nel nostro caso è stata visualizzata una semplice schermata che verrà visualizzata quando determinati processi/rapporti visualizzati su consentono all'utente di sapere cosa è in esecuzione.

  2. sono stato in grado di aggiungere direttamente il controllo VB6 attraverso l'interoperabilità a un progetto WPF. Come tale, è stato creato un nuovo progetto .Net "Libreria di controllo di Windows Form". Un riferimento al VB6 OCX è stato aggiunto al progetto. I controlli VB6 sono stati quindi aggiunti alla toolbox .Net facendo clic con il tasto destro su "->" Aggiungi elemento "e puntando un riferimento com al controllo ocx VB6. Il controllo .Net è stato quindi utilizzato per ospitare/servire il controllo VB6.

  3. Per visualizzare l'host di un modulo nel VB6 e farlo attivare la funzionalità di inizializzazione necessaria, i controlli OCB VB6 erano impostati in modo predefinito in un modo Visible.False in modo che inizialmente fossero aggiunti a .Net OCX come controlli invisibili. Quando necessario, il controllo VB6 è impostato su visible = True che genera l'evento UserControl_Show(). Tutto il codice precedentemente in Form_Load() è stato spostato su questo evento. L'evento show era il metodo più semplice per accedere a Form_Load in base alle esigenze. MSDN: "Il controllo non riceve Mostra eventi se il modulo è nascosto e quindi mostrato di nuovo, o se il modulo è ridotto a icona e quindi ripristinato. La finestra del controllo rimane sul modulo durante queste operazioni e la sua proprietà Visible non cambia. "

  4. Avvolgere i controlli vb6 all'interno di a.Il controllo Net Winform ha risolto il problema con i pulsanti Radio/Opzione resi come neri come indicato altrove in una delle mie risposte a questa domanda senza dover convertire i frame in Picture box come suggerito.

  5. Nell'app WPF come opzione di menu selezionata il codice xaml viene creato e visualizzato dinamicamente tramite un wrapper con un tag WindowsFormsHost. Un oggetto di controllo creato in modo dinamico dall'app. Netform viene quindi inserito nel tag WindowsFormsHost su xaml e il controllo viene reso visibile sul progetto .net che genera vb6 UserControl_Show e quindi carica e visualizza il modulo vb6.

+0

Wow, questo è incredibilmente attraverso. –

+0

Solo cercando di salvare un po 'di povera anima alcuni lividi cranici, dal battere la testa, che ho passato per le ultime due settimane a risolverlo. – jasonk

1

È possibile caricare anche tale modulo VB6 in un altro modulo VB6? Ti suggerisco di farlo funzionare prima.

+0

Desidero caricare il modulo VB6 in un modulo WPF. – jasonk

+1

@jasonk: so cosa vuoi fare. Suggerisco di ottenere prima il modulo VB6 caricato in un modulo VB6. Una volta fatto, saprai che il modulo può essere caricato in qualche tipo di modulo. _Then_ lavoro su come caricarlo in un modulo WPF. Potrebbe essere necessario modificare il modulo per consentirne il caricamento in un altro modulo. Avresti anche fatto quel lavoro in VB6, che ti è familiare. –

0

Non esiste un modo affidabile per impostare il padre di un modulo VB6. Puoi sempre modificarlo o utilizzare il semplice controllo ActiveX (UserControl in VB6) come contenitore UI anziché moduli VB6.

+0

Non ho molta familiarità con la creazione di controlli OCX. Significa che ogni schermo in VB6 dovrebbe essere il controllo di se stesso o esiste un modo per ospitare più schermi all'interno del singolo controllo? – jasonk

3

Penso che quello che dovrete fare è estrarre il contenuto del modulo VB6 in un controllo ActiveX. È quindi possibile esporlo nella DLL ActiveX e posizionarlo nel modulo WPF. Dubito che sia possibile ospitare un modulo VB6 all'interno di qualsiasi altro tipo di modulo.

+0

+1, sebbene il controllo debba essere esposto in un OCX ActiveX anziché in una DLL. – MarkJ

+0

Non ho molta familiarità con la creazione di controlli OCX. Significa che ogni schermo in VB6 dovrebbe essere il proprio controllo? – jasonk

+1

Sì, in pratica si rimuove tutto dallo schermo e lo si posiziona in un controllo ActiveX. Quindi è possibile posizionare questo controllo sul modulo VB6 (o ospitarlo nell'applicazione .NET). Ho appena trovato questo articolo MSDN che potrebbe aiutarti. http://msdn.microsoft.com/en-us/library/ms742735.aspx –

0

Ho trovato un metodo per eseguire ciò che era necessario in WinForms piuttosto che in WPF. http://www.codeproject.com/KB/vb-interop/VB6formsinNET.aspx Immagino che se riesco a farlo funzionare al 100%, posso portarlo su WPF o, peggio, ospitare l'elemento WinForm nel modulo WPF se ne ho anche troppo (U-G-L-Y).

In ogni caso, mi sono avvicinato un po ', ma sto avendo un problema molto strano con alcuni controlli che dipingono anche lo schermo. I pulsanti di opzione/opzione sono rendering come nere:

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

Ho provato a cambiare il colore di sfondo in modo esplicito i controlli da ButtonFace ad un colore fisso e lo fa ancora. Presumo che si tratti di un problema di stratificazione con i pulsanti di opzione all'interno del controllo del frame. Sono un po 'in perdita su come procedere senza una rielaborazione massiccia del contenuto VB6 per cambiare i pulsanti delle opzioni in caselle di controllo. È un'app pesante e ci sono oltre 600 pulsanti di opzione in tutta l'applicazione che non voglio esattamente gestire.

MODIFICA: Sono stato in grado di confermare che ha qualcosa a che fare con la stratificazione dell'opzione all'interno di un controllo Frame. Se tirato fuori la forma di base il problema non si verifica: http://www.evocommand.com/junk_delete_me/optionbuttons2.png

+0

trovato un soluzione strano che se metti i OptionButtons all'interno di un PictureBox piuttosto che un frame verrà visualizzato senza lo sfondo nero. – jasonk