4

メールアイテムをドロップできるコントロールがあり、正常に動作しますが、選択/アイテムをクリアすることができません。

例:メール1->メール1がリストにあるメール1をリストから削除してOutlookに戻り、メール2をドラッグアンドドロップします。メール
2がリストに表示されますが、メール1も復活します。についての投稿をたくさん見つけましたが、Marshal.ReleaseComObject私はそれを正しい方法でやっていないと思いますか?

仕様:VS2010、4.0フレームワーク。Windows 7 OS、Outlook 2010

これが私のコードの一部です:

私のメソッドの呼び出しSave

ElseIf e.Data.GetDataPresent("FileGroupDescriptor") Then
    Try
        Dim SafeSaveMethod As New dlgCallSaveMails(AddressOf SaveMailsFromSelection)
        Me.BeginInvoke(SafeSaveMethod, Me.FileData.Pad)

Save方法:

Private Sub SaveMailsFromSelection(_path As String)
    ' File uit Outlook
    Dim x As Integer
    Dim xitmndx As Integer = 0
    Dim DestFile As String
    Dim oOutLook As New Outlook.Application
    Dim oExplorer As Outlook.Explorer
    Dim oSelection As Outlook.Selection
    Dim strFile As String

    oExplorer = oOutLook.ActiveExplorer
    oSelection = oExplorer.Selection
    Dim currentFolder As MAPIFolder = oExplorer.CurrentFolder
    Dim folders As Folders = currentFolder.Folders


    Try
        For Each mitem As Object In oSelection
            xitmndx += 1

            Dim mi As Microsoft.Office.Interop.Outlook.MailItem = TryCast(mitem, Microsoft.Office.Interop.Outlook.MailItem)

                        mi.SaveAs(_path & "\" & String.Format("{0:yyyy-MM-dd_hh-mm-ss-tt}", mi.CreationTime) & "-" & CleanInput(mi.Subject) & ".msg", Outlook.OlSaveAsType.olMSG)

                Marshal.ReleaseComObject(mi)
                mi = Nothing
        Next

    Catch ex As System.Exception
        WriteError2EventLog("Error picDropZone_DragDrop 4: " & ex.ToString)
        MsgBox(Err.Description, MsgBoxStyle.Exclamation, "mycontrol")
    Finally
        Marshal.ReleaseComObject(oExplorer)
        Marshal.ReleaseComObject(oSelection)
        Marshal.ReleaseComObject(currentFolder)
        Marshal.ReleaseComObject(folders)
        Marshal.FinalReleaseComObject(oExplorer)
    End Try
End Sub

私も試しoExplorer.ClearSelection()ましたが、countプロパティからわかるように、まったくクリアされません

4

3 に答える 3

6

この問題のさまざまな解決策を何時間も読んだ後、別のプログラムでドラッグアンドドロップを処理できるコントロール上に移動すると、OutlookのEnterイベントの処理方法にバグが発生することになりました。修正できることがわかりました。 1行のコードで、それを広める必要があります。

Microsoftはクリップボードを使用して、特に選択に関する情報を保存します。この目的でOutlookによって使用されるクラスは、RenPrivateMessagesという名前のキーの背後に隠されています。インターフェイスが解放されないため使用できませんが、読み取ることで選択範囲のロックを解除できます。

したがって、コードのdrop-eventで行う必要があるのは、この行を追加することだけです(EventArgの名前がeである場合)。

e.data.GetData( "RenPrivateMessages");

于 2015-08-24T08:36:25.640 に答える
1

ペインを切り替える回避策なしで解決策をWebで検索していました。自分に合った解決策を見つけたら、ここで共有したいと思います。

最後の手がかりは、アクティブなエクスプローラーのRemoveFromSelectionメソッドを使用することでしたが、Marshal.ReleaseComObjectは選択をクリアしないだけです。

Public Sub outlook_drop()
    Try
        get_outlook_application_explorer()
        If IsNothing(oExplorer) = True Then
            MessageBox.Show("Cannot open Outlook.")
            Exit Sub
        End If

        Dim selection As Selection = oExplorer.Selection
        If selection.Count = 0 Then
            Marshal.ReleaseComObject(selection)
            MessageBox.Show("Nothing selected.")
            Exit Sub
        End If

        Dim filename As String
        Dim ext As String = ".msg"

        Dim mail As MailItem                                ' Important, no 'Shadow'-objects, such as "For Each mail as MailItem in selection", cos you need to free it with Marshal.ReleaseComObject()...
        For Each mail In selection
            Dim subtxt As String = mail.Subject
            If Not String.IsNullOrEmpty(subtxt) Then
                If subtxt.Length > 120 Then
                    subtxt = Left(subtxt, 120)
                End If
            End If

            filename = fill_filename(mail.Attachments.Count.ToString, subtxt, mail.SenderName, mail.ReceivedTime.ToShortDateString)

            Dim newFile As String = IO.Path.Combine(fuldir, filename + ext)
            Dim count As Integer = 0
            While IO.File.Exists(newFile)
                count += 1
                If count > 25 Then
                    newFile = Nothing
                    Exit While
                End If

                newFile = IO.Path.Combine(fuldir, filename + "(" + count.ToString + ")" + ext)
            End While

            If String.IsNullOrEmpty(newFile) = False Then
                mail.SaveAs(newFile)
            End If
            oExplorer.RemoveFromSelection(mail) ' Important, to remove the object from Selection, ReleaseComObject() only don't do.
            Marshal.ReleaseComObject(mail)  
        Next

        Marshal.ReleaseComObject(selection)
    Catch ex As System.Exception
        MessageBox.Show(ex.Message)
    End Try
End Sub

よろしく、

カリ

于 2013-08-28T09:25:10.827 に答える
0

デリゲートを使用することはあまり良い考えではありませんでしたが、回避策を実行してOutlookを再アクティブ化できることがわかりました。

メールアイテムをファイルに保存した後、SwitchOutlookPanes()を呼び出します

 Public Sub SwitchOutlookPanes()
    Dim Outlook As Microsoft.Office.Interop.Outlook.Application
    Dim explorer As Microsoft.Office.Interop.Outlook.Explorer = Nothing
    Try
        If Outlook Is Nothing Then
            If Outlook Is Nothing Then Outlook = CType(Microsoft.VisualBasic.Interaction.GetObject("", "Outlook.Application"), Microsoft.Office.Interop.Outlook.Application)
            explorer = Outlook.ActiveExplorer
        End If

        If Outlook IsNot Nothing And explorer IsNot Nothing Then
            Dim nMAPIFOlder As Interop.Outlook.MAPIFolder = explorer.CurrentFolder
            explorer.CurrentFolder = Outlook.OlDefaultFolders.olFolderContacts
            System.Threading.Thread.Sleep(1500)
            explorer.CurrentFolder = nMAPIFOlder
        End If
    Catch ex As System.Exception
    Finally
        Marshal.ReleaseComObject(explorer)
        Marshal.ReleaseComObject(Outlook)
    End Try

End Sub

これにより、選択がクリアされ、Outlookがフリーズ/ハングするのを防ぎます。

よろしく、

マイク

于 2013-01-25T19:22:26.697 に答える