hnzgs 发表于 2011-3-24 17:02:55

ShowModalDialog窗体在打印预览时出现的问题

本帖最后由 hnzgs 于 2011-3-25 07:58 编辑

'环境:VS2008+CAD2010‘启动打印窗体
<CommandMethod("ShowPrint")> Public Shared Sub ShowPrint()
      Dim frm As New FrmPrint
       Application.ShowModalDialog(frm)
    End Sub
用命令行方式(窗体没有运行时)调用过程一切正常
'测试函数
    <CommandMethod("cs")> Public Shared Sub CS()
      MultiSheetPreview()'过程代码见二楼、三楼
    End Sub
但在窗体里用按钮调用的时候会出预览界面鼠标点击无反应的情况,好像无法获得焦点
'预览按钮代码
    Private Sub BtnYuLan_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnYuLan.Click
      Me.Visible = False
      MultiSheetPreview()'过程代码见二楼、三楼
      Me.Visible = True
    End Sub
求助如何解决?

hnzgs 发表于 2011-3-25 07:55:31

本帖最后由 hnzgs 于 2011-3-25 07:57 编辑

附Kean代码
Public Shared Sub MultiSheetPreview()

      Dim doc As Document = Application.DocumentManager.MdiActiveDocument
      Dim ed As Editor = doc.Editor
      Dim db As Database = doc.Database
      Dim layoutsToPlot As New ObjectIdCollection()
      Dim tr As Transaction = db.TransactionManager.StartTransaction()
      Using tr

            ' First we need to collect the layouts to
            ' plot/preview in tab order

            Dim layoutDict As New SortedDictionary(Of Integer, ObjectId)()
            Dim bt As BlockTable = DirectCast(tr.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)

            For Each btrId As ObjectId In bt
                Dim btr As BlockTableRecord = DirectCast(tr.GetObject(btrId, OpenMode.ForRead), BlockTableRecord)
                If btr.IsLayout AndAlso btr.Name.ToUpper() <> BlockTableRecord.ModelSpace.ToUpper() Then
                  ' The dictionary we're using will
                  ' sort on the tab order of the layout
                  Dim lo As Layout = DirectCast(tr.GetObject(btr.LayoutId, OpenMode.ForRead), Layout)
                  layoutDict.Add(lo.TabOrder, btrId)
                End If
            Next

            ' Let's now get the layout IDs and add them to a
            ' standard ObjectIdCollection
            Dim vc As SortedDictionary(Of Integer, ObjectId).ValueCollection = layoutDict.Values
            For Each id As ObjectId In vc
                layoutsToPlot.Add(id)
            Next
            ' Committing is cheaper than aborting
            tr.Commit()
      End Using

      ' PlotEngines do the previewing and plotting
      If PlotFactory.ProcessPlotState = Autodesk.AutoCAD.PlottingServices.ProcessPlotState.NotPlotting Then
            Dim layoutNum As Integer = 0
            Dim isFinished As Boolean = False
            Dim isReadyForPlot As Boolean = False
            While Not isFinished
                ' Create the preview engine with the appropriate
                ' buttons enabled - this depends on which
                ' layout in the list is being previewed
                Dim flags As PreviewEngineFlags = PreviewEngineFlags.Plot
                If layoutNum > 0 Then
                  flags = flags Or PreviewEngineFlags.PreviousSheet
                End If
                If layoutNum < layoutsToPlot.Count - 1 Then
                  flags = flags Or PreviewEngineFlags.NextSheet
                End If
                Dim pre As PlotEngine = PlotFactory.CreatePreviewEngine(CInt(flags))
                Using pre
                  Dim stat As PreviewEndPlotStatus = MultiplePlotOrPreview(pre, True, layoutsToPlot, layoutNum, "")
                  ' We're not checking the list bounds for
                  ' next/previous as the buttons are only shown
                  ' when they can be used
                  If stat = PreviewEndPlotStatus. Then
                        layoutNum += 1
                  ElseIf stat = PreviewEndPlotStatus.Previous Then
                        layoutNum -= 1
                  ElseIf stat = PreviewEndPlotStatus.Normal OrElse stat = PreviewEndPlotStatus.Cancel Then
                        isFinished = True
                  ElseIf stat = PreviewEndPlotStatus.Plot Then
                        isFinished = True
                        isReadyForPlot = True
                  End If
                End Using
            End While

            ' If the plot button was used to exit the preview...
            If isReadyForPlot Then
                Dim ple As PlotEngine = PlotFactory.CreatePublishEngine()
                Using ple
                  Dim stat As PreviewEndPlotStatus = MultiplePlotOrPreview(ple, False, layoutsToPlot, -1, "c:\multisheet-previewed-plot")
                End Using
            End If
      Else
            ed.WriteMessage(vbLf & "Another plot is in progress.")
      End If

    End Sub

hnzgs 发表于 2011-3-25 07:56:11


Private Shared Function MultiplePlotOrPreview(ByVal pe As PlotEngine, ByVal isPreview As Boolean, ByVal layoutSet As ObjectIdCollection, ByVal layoutNumIfPreview As Integer, ByVal filename As String) As PreviewEndPlotStatus
      Dim doc As Document = Application.DocumentManager.MdiActiveDocument
      Dim ed As Editor = doc.Editor
      Dim db As Database = doc.Database
      Dim ret As PreviewEndPlotStatus = PreviewEndPlotStatus.Cancel
      Dim layoutsToPlot As ObjectIdCollection

      If isPreview AndAlso layoutNumIfPreview >= 0 Then
            ' Preview is really pre-sheet, so we reduce the
            ' sheet collection to contain the one we want
            layoutsToPlot = New ObjectIdCollection()
            layoutsToPlot.Add(layoutSet(layoutNumIfPreview))
      Else
            ' If we're plotting we need all the sheets,
            ' so copy the ObjectIds across
            Dim ids As ObjectId() = New ObjectId(layoutSet.Count - 1) {}
            layoutSet.CopyTo(ids, 0)
            layoutsToPlot = New ObjectIdCollection(ids)
      End If

      Dim tr As Transaction = db.TransactionManager.StartTransaction()
      Using tr
            ' Create a Progress Dialog to provide info
            ' and allow thej user to cancel
            Dim ppd As New PlotProgressDialog(isPreview, layoutsToPlot.Count, True)
            Using ppd
                Dim numSheet As Integer = 1
                For Each btrId As ObjectId In layoutsToPlot
                  Dim btr As BlockTableRecord = DirectCast(tr.GetObject(btrId, OpenMode.ForRead), BlockTableRecord)
                  Dim lo As Layout = DirectCast(tr.GetObject(btr.LayoutId, OpenMode.ForRead), Layout)
                  ' We need a PlotSettings object
                  ' based on the layout settings
                  ' which we then customize
                  Dim ps As New PlotSettings(lo.ModelType)
                  ps.CopyFrom(lo)
                  ' The PlotSettingsValidator helps
                  ' create a valid PlotSettings object
                  Dim psv As PlotSettingsValidator = PlotSettingsValidator.Current
                  ' We'll plot the extents, centered and
                  ' scaled to fit
                  psv.SetPlotType(ps, Autodesk.AutoCAD.DatabaseServices.PlotType.Extents)
                  psv.SetUseStandardScale(ps, True)
                  psv.SetStdScaleType(ps, StdScaleType.ScaleToFit)
                  psv.SetPlotCentered(ps, True)
                  ' We'll use the standard DWFx PC3, as
                  ' this supports multiple sheets
                  psv.SetPlotConfigurationName(ps, "DWFx ePlot (XPS Compatible).pc3", "ANSI_A_(8.50_x_11.00_Inches)")
                  ' We need a PlotInfo object
                  ' linked to the layout
                  Dim pi As New PlotInfo()
                  pi.Layout = btr.LayoutId
                  ' Make the layout we're plotting current
                  LayoutManager.Current.CurrentLayout = lo.LayoutName
                  ' We need to link the PlotInfo to the
                  ' PlotSettings and then validate it
                  pi.OverrideSettings = ps
                  Dim piv As New PlotInfoValidator()
                  piv.MediaMatchingPolicy = MatchingPolicy.MatchEnabled
                  piv.Validate(pi)
                  ' We set the sheet name per sheet

                  ppd.PlotMsgString(PlotMessageIndex.SheetName) = (doc.Name.Substring(doc.Name.LastIndexOf("\") + 1) & " - ") + lo.LayoutName
                  If numSheet = 1 Then
                        ' All other messages get set once
                        ppd.PlotMsgString(PlotMessageIndex.DialogTitle) = "Custom Preview Progress"
                        ppd.PlotMsgString(PlotMessageIndex.CancelJobButtonMessage) = "Cancel Job"
                        ppd.PlotMsgString(PlotMessageIndex.CancelSheetButtonMessage) = "Cancel Sheet"
                        ppd.PlotMsgString(PlotMessageIndex.SheetSetProgressCaption) = "Sheet Set Progress"
                        ppd.PlotMsgString(PlotMessageIndex.SheetProgressCaption) = "Sheet Progress"

                        ppd.LowerPlotProgressRange = 0
                        ppd.UpperPlotProgressRange = 100
                        ppd.PlotProgressPos = 0
                        ' Let's start the plot/preview, at last
                        ppd.OnBeginPlot()
                        ppd.IsVisible = True
                        pe.BeginPlot(ppd, Nothing)
                        ' We'll be plotting a single document
                        pe.BeginDocument(pi, doc.Name, Nothing, 1, Not isPreview, filename)
                  End If

                  ' Which may contains multiple sheets
                  ppd.LowerSheetProgressRange = 0
                  ppd.UpperSheetProgressRange = 100
                  ppd.SheetProgressPos = 0
                  Dim ppi As New PlotPageInfo()
                  pe.BeginPage(ppi, pi, (numSheet = layoutsToPlot.Count), Nothing)
                  ppd.OnBeginSheet()
                  pe.BeginGenerateGraphics(Nothing)
                  ppd.SheetProgressPos = 50
                  pe.EndGenerateGraphics(Nothing)
                  ' Finish the sheet
                  Dim pepi As New PreviewEndPlotInfo()
                  pe.EndPage(pepi)
                  ret = pepi.Status
                  ppd.SheetProgressPos = 100
                  ppd.OnEndSheet()
                  numSheet += 1
                  ' Update the overall progress
                  ppd.PlotProgressPos += (100 / layoutsToPlot.Count)
                Next

                ' Finish the document
                pe.EndDocument(Nothing)
                ' And finish the plot
                ppd.PlotProgressPos = 100
                ppd.OnEndPlot()
                pe.EndPlot(Nothing)
            End Using
      End Using

      Return ret

    End Function

羊羊羊 发表于 2023-6-29 19:50:29

ShowModalDialog窗体在打印预览时出现的问题

羊羊羊 发表于 2023-8-6 23:59:25

有答案了吗

羊羊羊 发表于 2023-8-7 19:12:34

搞定了,采用StartUserInteraction 就可以了
页: [1]
查看完整版本: ShowModalDialog窗体在打印预览时出现的问题