nicht modaler, schwebender Dialog

  • VB.NET

Es gibt 24 Antworten in diesem Thema. Der letzte Beitrag () ist von petaod.

    nicht modaler, schwebender Dialog

    In MS Word gibt es Dialoge, die über dem Text schweben und gleichzeitig Änderungen im darunter liegenden Dokument zulassen, also nicht modaler, schwebender Dialog. Kann bitte jemand verraten, wie man so etwas programmiertechnisch hin bekommt?
    Grüße
    praetor
    Falls WPF, dann gibt es hierfür das Adorner.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    RodFromGermany schrieb:

    Gugst Du Dialoge: Instanziierung von Forms und Aufruf von Dialogen

    Ich habe gefunden "Bei nicht modalen Dialogen verhindert der Aufruf .Show(Me), dass der Dialog hinter das aufrufende Fenster (Parent) geklickt werden kann, was bei .Show() möglich ist." und werde das ausprobieren.
    Jetzt hoffe ich nur, dass das aufrufende Fenster (Parent) auch die Word-Anwendung sein kann.
    Grüße
    praetor

    praetor schrieb:

    dass das aufrufende Fenster (Parent) auch die Word-Anwendung sein kann.
    Reden wir noch von VB.NET oder hast Du was VBA-artiges am Laufen?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    .Show(Me) klappt bei einem normalen Programm ohne Weiteres. :thumbup:

    Aber ich hab ein Problem, im VSTO-Umfeld auch nur überhaupt ein Form anzuzeigen. ?( Muss da noch etwas importiert werden? Irgenwie wird da ein Objektverweis benötigt. Mir fehlen da echt die Grundlagen und ich bräuchte mal ein paar Tipps für den Einstieg.

    VB.NET-Quellcode

    1. Public Class ThisAddIn
    2. Private Sub ThisAddIn_Startup() Handles Me.Startup
    3. MsgBox("Hallo Welt") ' das klappt noch
    4. Form1.Show() ' das schon nicht mehr! (angelegt habe ich Form1 zunächst)
    5. End Sub
    6. Private Sub ThisAddIn_Shutdown() Handles Me.Shutdown
    7. End Sub
    8. End Class
    Grüße
    praetor
    Funktioniert diese Variante?

    VB.NET-Quellcode

    1. ​Public Class ThisAddIn
    2. Dim MyForm As New Form1
    3. Private Sub ThisAddIn_Startup() Handles Me.Startup
    4. MsgBox("Hallo Welt") ' das klappt noch
    5. MyForm.Show()
    6. End Sub
    7. Private Sub ThisAddIn_Shutdown() Handles Me.Shutdown
    8. End Sub
    9. End Class
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --

    petaod schrieb:

    VB.NET-Quellcode

    1. MyForm.Show()
    Meinst Du

    VB.NET-Quellcode

    1. MyForm.Show(MyForm)
    ?

    ====
    Blödsinn.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „RodFromGermany“ ()

    @petaod, Danke, funktioniert! Eigentlich meine ich, dass ich das gestern so schon probiert hätte. Aber da wohl doch noch irgendwas falsch.

    Was aber dann in dem Kontext nicht funktioniert ist,

    VB.NET-Quellcode

    1. MyForm.Show(Me)

    Es kommt der Fehler "Das Objekt des Typs "WordAddIn_modal.ThisAddIn" kann nicht in Typ "System.Windows.Forms.IWin32Window" umgewandelt werden." Was ist da zu tun?
    Grüße
    praetor

    praetor schrieb:

    Was ist da zu tun?
    Me ist keine Form bzw. ein Fenster.
    Du müsstest da so was wie ein Window-Handle übergeben.
    Wenn Du das von Word hast, kannst Du auch mit SetParent arbeiten.
    pinvoke.net/default.aspx/user32.setparent
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    RodFromGermany schrieb:


    Wenn Du das von Word hast, kannst Du auch mit SetParent arbeiten.

    Lange rumprobiert, aber ich bekomme es leider nicht hin, den ersten Dialog über dem Word-Fenster nichtmodal und schwebend anzuzeigen. ?( ;(
    Mir fehlt da wohl noch zu viel Hintergrundwissen. Für ein funktionierendes Beispiel wäre ich sehr dankbar!
    Grüße
    praetor
    Vielleicht beschreibe ich mal noch etwas genauer, wo es hängt.
    • VSTO-Projekt
    • Form 1 soll im aktuellen Wordfenster als als nichtmodales Fenster angezeigt werden, das über dem Wordfenster sichtbar bleibt, auch wenn es gerade nicht den Fokus hat
    Wird die aktuelle Word-Instanz in Zeile 8 korrekt in eine Variable gepackt?
    Warum funktioniert Zeile 12 so nicht? Was muss ich ändern?

    VB.NET-Quellcode

    1. Imports System.Diagnostics
    2. Imports System.Threading
    3. Public Class Form1
    4. Declare Auto Function SetParent Lib "user32" (ByVal hWndChild As IntPtr, ByVal hWndNewParent As IntPtr) As IntPtr
    5. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    6. ' aktuelles Word-Fenster soll referenziert werden
    7. Dim meinWord As Word.Application = GetObject(, "Word.Application")
    8. Thread.Sleep(100)
    9. ' erster Parameter = eingebettetes nichtmodales Fenster
    10. ' zweiter Parameter = Mutterfenster, in welchem das Fenster eingebettet wird
    11. SetParent(Me.Handle, meinWord)
    12. End Sub
    13. End Class
    Grüße
    praetor
    @praetor Sieh doch mal im Objektbrowser nach, was SetParent() für Parameter erwartet, hier ist der Typ gefragt.
    Danach beschäftigen wir uns damit, woher wir den richtigen Parameter bekommen.
    ====
    Vielleicht probierst Du mal, .TopMost = True zu setzen, das sollte Dein Problem lösen, allerdings ist das nicht ganz elegant.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    RodFromGermany schrieb:


    Sieh doch mal im Objektbrowser nach, was SetParent() für Parameter erwartet, hier ist der Typ gefragt.
    Danach beschäftigen wir uns damit, woher wir den richtigen Parameter bekommen.

    Wenn ich das richtig sehe, wird eine Variable vom Typ IntPtr erwartet, der den Handler der abzusprechenden Komponente repräsentiert. Aber wie kommt man ran?

    Vielleicht probierst Du mal, TopMost = True zu setzen,…

    Funktioniert! Aber die Lösung über SetParent() hätte den Vorteil, dass die Form auf das Word-Fenster beschränkt bleibt. Das wäre natürlich wesentlich besser.
    Grüße
    praetor

    praetor schrieb:

    wird eine Variable vom Typ IntPtr erwartet
    Das ist nur die halbe Miete.
    docs.microsoft.com/en-us/windo…user/nf-winuser-setparent
    Der erste Parameter ist das Handle Deines Dialogs, der zweite Parameter ist das Handle von Word.
    Probier mal dies:

    VB.NET-Quellcode

    1. Imports System.Runtime.InteropServices
    2. Public Class Form1
    3. <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
    4. Public Shared Function SetParent(hWndChild As IntPtr, hWndNewParent As IntPtr) As IntPtr
    5. End Function
    6. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    7. Dim pr() = Process.GetProcessesByName("WINWORD")
    8. If pr.Length > 0 Then
    9. Form1.SetParent(Me.Handle, pr(0).MainWindowHandle)
    10. End If
    11. End Sub
    12. End Class
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @praetor Bei mir funktioniert das wie gewünscht.
    Was hast Du für ein Studio / Word?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    RodFromGermany schrieb:


    Was hast Du für ein Studio / Word?

    Ich nutze VS Community 2017 und Office 365 Pro Plus.

    Wenn ich Deinen Code in ein Windows Forms App ausführe, funktioniert es. Aber in einem VSTO-Add-In läuft es nicht.
    Im Word-Umfeld hatte ich mich etwas verwirren lassen, weil ältere Add-In-Versuche noch mit gestartet wurden. Das hab ich nun bereinigt.
    Der aktuelle Code führte im VSTO-Add,In zu
    ​1>------ Erstellen gestartet: Projekt: WordAddIn_modal, Konfiguration: Debug Any CPU ------
    1>C:\Users\praet\source\repos\WordAddIn_modal\WordAddIn_modal\Form1.vb(9,20): error BC30451: "Process" wurde nicht deklariert. Aufgrund der Schutzstufe ist unter Umständen kein Zugriff möglich.
    ========== Erstellen: 0 erfolgreich, 1 fehlerhaft, 0 aktuell, 0 übersprungen ==========

    den ich mit

    VB.NET-Quellcode

    1. ​Imports System.Diagnostics
    beheben konnte.

    Aber Button1 führt zu keinem Effekt, Form1 wandert nicht in das Word-Fenster.
    Wenn man das ganze mehrfach startet, lässt interessanterweise aber das eine Form1-Fenster aber in das andere einfügen:
    Grüße
    praetor