Druckfenster / Savefiledialog Sendmessage

  • VB.NET

Es gibt 4 Antworten in diesem Thema. Der letzte Beitrag () ist von r0tzi.

    Druckfenster / Savefiledialog Sendmessage

    Hallo Zusammen,

    ich möchte einen Druck automatisieren von SAP heraus. Funktioniert auch soweit ganz gut bis auf eine einzige Sache, bei der ich nicht weiterkomme und im internet nichts gefunden habe.
    Folgendes passiert, das Druckfenster öffnet sich, es wird eine Message gesendet, dass es OK ist und dann erscheint der Savefiledialog wo die PDF (als druck) gespeichert werden soll. Und hier mein Thema...

    ich bekomme es nicht hin, den Dateinamen festzulegen... es wird immer nur der erste Buchstabe in die editierbare Combobox geschrieben. Hier der code.

    VB.NET-Quellcode

    1. Imports System.Runtime.InteropServices
    2. Imports System.Text
    3. Public Class Class1
    4. Private Const SW_RESTORE As Integer = 9
    5. Private Const WM_COMMAND As Integer = &H111
    6. Private Const WM_SETTEXT As UInteger = &HC
    7. Private Const IDOK As Integer = 1 ' ID der OK-Schaltfläche oder Save
    8. <DllImport("user32.dll")>
    9. Private Shared Function SendMessage(hWnd As IntPtr, msg As Integer, wParam As IntPtr, lParam As IntPtr) As IntPtr : End Function
    10. <DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
    11. Private Shared Function SendMessageA(hWnd As IntPtr, Msg As Integer, wParam As IntPtr, lParam As IntPtr) As IntPtr : End Function
    12. <DllImport("user32.dll", CharSet:=CharSet.Auto)>
    13. Private Shared Function FindWindowEx(hWndParent As IntPtr, hWndChildAfter As IntPtr, lpszClass As String, lpszWindow As String) As IntPtr : End Function
    14. <DllImport("user32.dll")>
    15. Private Shared Function ShowWindow(hWnd As IntPtr, nCmdShow As Integer) As Boolean : End Function
    16. <DllImport("user32.dll", CharSet:=CharSet.Auto)>
    17. Private Shared Function SetForegroundWindow(hWnd As IntPtr) As Boolean : End Function
    18. <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
    19. Private Shared Function FindWindow(lpClassName As String, lpWindowName As String) As IntPtr : End Function
    20. <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
    21. Private Shared Function GetClassName(hWnd As IntPtr, lpClassName As StringBuilder, nMaxCount As Integer) As Integer : End Function
    22. Public Async Sub PrintSAPQuote(QuoteNo As String)
    23. Dim windowTitle As String = "Print"
    24. Dim windowClass As String = "#32770"
    25. Dim printWindowHandle As IntPtr
    26. Dim ActualTime As DateTime = DateTime.Now
    27. Do Until printWindowHandle <> IntPtr.Zero
    28. printWindowHandle = FindWindow(windowClass, windowTitle)
    29. If ActualTime.AddSeconds(10) < DateTime.Now Then Exit Do
    30. Loop
    31. If printWindowHandle <> IntPtr.Zero Then
    32. Else
    33. MessageBox.Show("Druckfenster nicht gefunden.")
    34. Exit Sub
    35. End If
    36. ShowWindow(printWindowHandle, SW_RESTORE)
    37. SetForegroundWindow(printWindowHandle)
    38. SendMessage(printWindowHandle, WM_COMMAND, IDOK, IntPtr.Zero)
    39. Await Task.Delay(2000)
    40. Dim dialogHandle As IntPtr
    41. ActualTime = DateTime.Now
    42. Do Until dialogHandle <> IntPtr.Zero
    43. dialogHandle = FindWindowEx(IntPtr.Zero, IntPtr.Zero, "#32770", "Save Print Output As")
    44. If ActualTime.AddSeconds(8) < DateTime.Now Then Exit Do
    45. Loop
    46. If dialogHandle <> IntPtr.Zero Then
    47. Else
    48. MessageBox.Show("Druckfenster nicht gefunden.")
    49. Exit Sub
    50. End If
    51. If dialogHandle <> IntPtr.Zero Then
    52. Dim comboBoxHandle As IntPtr = FindComboBox(dialogHandle)
    53. If comboBoxHandle <> IntPtr.Zero Then
    54. ShowWindow(dialogHandle, SW_RESTORE)
    55. SetForegroundWindow(dialogHandle)
    56. Dim newText As IntPtr
    57. newText = Marshal.StringToCoTaskMemUni("Test")
    58. SendMessageA(comboBoxHandle, WM_SETTEXT, IntPtr.Zero, newText)
    59. Marshal.FreeCoTaskMem(newText)
    60. Else
    61. Exit Sub
    62. End If
    63. End If
    64. SendMessage(dialogHandle, WM_COMMAND, 1, IntPtr.Zero)
    65. End Sub
    66. Private Function FindComboBox(parentHandle As IntPtr) As IntPtr
    67. Dim childHandle As IntPtr = IntPtr.Zero
    68. Dim className As New StringBuilder(256)
    69. Do
    70. childHandle = FindWindowEx(parentHandle, childHandle, Nothing, Nothing)
    71. If childHandle <> IntPtr.Zero Then
    72. GetClassName(childHandle, className, className.Capacity)
    73. If className.ToString() = "ComboBox" Then
    74. Return childHandle
    75. End If
    76. Dim subComboBoxHandle As IntPtr = FindComboBox(childHandle)
    77. If subComboBoxHandle <> IntPtr.Zero Then
    78. Return subComboBoxHandle
    79. End If
    80. End If
    81. Loop While childHandle <> IntPtr.Zero
    82. Return IntPtr.Zero
    83. End Function
    84. End Class



    der Fehler liegt hier:

    VB.NET-Quellcode

    1. Dim newText As IntPtr
    2. newText = Marshal.StringToCoTaskMemUni("Test")
    3. SendMessageA(comboBoxHandle, WM_SETTEXT, IntPtr.Zero, newText)
    4. Marshal.FreeCoTaskMem(newText)


    Kann mir jemand helfen wie ich den kompletten Dateinamen in die Combobox einfügen kann?

    Vielen Dank
    @r0tzi Setz mal auf SendMessageA() einen Haltepunkt und überzeuge Dich, dass da der richtige Text ühaupt ankommt.
    Wenn der Text da ist, kannst Du ihn doch auch per VB in die Combobox schreiben.
    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!
    Hi @RodFromGermany,

    SendMessageA() erwartet lParam As IntPtr bedeutet der String wird nicht einfach an die Combobox gesendet sondern muss convertiert in IntPtr werden und das ist das Problem, ich bekomme es nicht hin -.-

    Mit dem obigen code ist newText (Test) -> &H0768DE00

    in der Combobox vom Savefiledialog taucht dann nur "T" auf
    @r0tzi Schau mal hier rein, da kommen einige Zeilen vor, wie aus IntPtr ein String generiert wird.
    Austausch von Daten zwischen einer VB.NET-exe und einer C-DLL, 32 und 64 Bit
    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!