Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / WinForms, .Net Framework Новый топик    Ответить
 А можно как-то подменить hdc принтера на hdc связанное с bitmap с целью сохранить в файл?  [new]
Дмитрий77
Member

Откуда:
Сообщений: 4404
В службе факсов/Fax and Scan есть нехилый такой функционал, связанный с Cover Pages (Титульные страницы).
Озадачился нестандартной задачей: сохранить распечатанную Cover Page в TIFF-файл (дабы использовать ее в другом приложении - не MSFax).

Стандартный алгоритм описан здесь:
Printing a Fax to a Device Context
1.Call the FaxStartPrintJob function to retrieve the handle to a fax printer DC. The function returns the handle in a FAX_CONTEXT_INFO structure.
2.Call the FaxPrintCoverPage function, if a cover page is required, passing a pointer to the FAX_CONTEXT_INFO structure returned by the FaxStartPrintJob function.
3.Print the fax document to the printer DC in the normal manner, passing the handle to the DC returned by the FaxStartPrintJob function. The procedure can include calls to the StartPage and EndPage Win32 GDI functions.
4.Call the EndDoc function or the AbortDoc function, passing the handle to the DC returned by FaxStartPrintJob. This closes the document and ends the fax print job.
5.Call the DeleteDC function to deallocate the handle to the DC.

Т.е. FaxStartPrintJob возвращает hdc в структуре FAX_CONTEXT_INFO (и видимо инициализирует StartDoc), а FaxPrintCoverPage лепит CoverPage в это hdc. EndDoc завершает подготовку факса и факс улетает в Fax and Scan на отправку.
Ну, штатно все работает:
+
  Public Function SendCoverPage(ByRef err_text As String) As Boolean

    SendCoverPage = True

    ' dwFaxId is the fax job id
    Dim dwFaxId As Integer

    ' FaxPrintInfo is the fax print info
    Dim FaxPrintInfo As New FAX_PRINT_INFO
    FaxPrintInfo.SizeOfStruct = Marshal.SizeOf(FaxPrintInfo)
    FaxPrintInfo.RecipientNumber = "500" 'номер не может быть пустой

    ' FaxContextInfo is the fax context
    Dim FaxContextInfo As New FAX_CONTEXT_INFO
    FaxContextInfo.SizeOfStruct = Marshal.SizeOf(FaxContextInfo)

    'FaxContextInfo.hDC - здесь возвращается hdc
    If FaxStartPrintJob(vbNullString, FaxPrintInfo, dwFaxId, FaxContextInfo) = False Then
      SendCoverPage = False
      err_text = "FaxStartPrintJob Error " & RaiseAPIError()
      GoTo ToExit
    End If

    ' CoverPageInfo is the cover page info
    Dim CoverPageInfo As New FAX_COVERPAGE_INFO
    With CoverPageInfo
      .SizeOfStruct = Marshal.SizeOf(CoverPageInfo)
      .UseServerCoverPage = True
      .CoverPageName = "confident" ' "C:\ProgramData\Microsoft\Windows NT\MSFax\Common Coverpages\ru-RU\confident.cov"
      .Subject = "confident"
      '...
    End With

    'печать титульной страницы - FaxContextInfo.hDC определяет куда ее выводить
    If FaxPrintCoverPage(FaxContextInfo, CoverPageInfo) = False Then
      SendCoverPage = False
      err_text = "FaxPrintCoverPage Error " & RaiseAPIError()
      GoTo ToExit
    End If

    ' Сюда можно вставить  StartPage ... EndPage и нарисовать остальные страницы

    If EndDoc(FaxContextInfo.hDC) = 0 Then
      SendCoverPage = False
      err_text = "EndDoc Error " & RaiseAPIError()
      GoTo ToExit
    End If

ToExit:
    DeleteDC(FaxContextInfo.hDC)
  End Function


Но мне надо "угнать" CoverPage картинку в свой файл.
Создаю свою кухню, пытаюсь подсунуть в FaxPrintCoverPage свое hdc, не вызывая предварительно FaxStartPrintJob
    ' FaxContextInfo is the fax context
    Dim FaxContextInfo As New FAX_CONTEXT_INFO
    FaxContextInfo.SizeOfStruct = Marshal.SizeOf(FaxContextInfo)
    FaxContextInfo.hDC = hdcDst 'пытаемся подсунуть свой hdc в FaxPrintCoverPage

+
  Public Function SaveCoverPage1(ByRef err_text As String) As Boolean

    SaveCoverPage1 = True

    Dim bmiDst As BITMAPINFO2
    Dim pBits As IntPtr
    Dim hbmDst As IntPtr
    Dim hdcDst As IntPtr
    Dim hbmOldDst As IntPtr
    Dim nBitmap As Bitmap

    With bmiDst.bmiHeader
      .biSize = Marshal.SizeOf(bmiDst.bmiHeader)
      .biWidth = 1728
      .biHeight = 2339
      .biPlanes = 1
      .biBitCount = 1
      .biCompression = BI_RGB
    End With
    With bmiDst.bmiColors1
      .rgbBlue = 255
      .rgbGreen = 255
      .rgbRed = 255
    End With
    hbmDst = CreateDIBSection(IntPtr.Zero, bmiDst, DIB_RGB_COLORS, pBits, IntPtr.Zero, 0)

    hdcDst = CreateCompatibleDC(IntPtr.Zero)
    hbmOldDst = SelectObject(hdcDst, hbmDst)

    PatBlt(hdcDst, 0, 0, bmiDst.bmiHeader.biWidth, bmiDst.bmiHeader.biHeight, WHITENESS) 'красим белым т.к. он гад черный
    'Using gr As Graphics = Graphics.FromHdc(hdcDst)
    '  gr.Clear(Color.White)
    'End Using

    '=====
    ' FaxContextInfo is the fax context
    Dim FaxContextInfo As New FAX_CONTEXT_INFO
    FaxContextInfo.SizeOfStruct = Marshal.SizeOf(FaxContextInfo)
    FaxContextInfo.hDC = hdcDst 'пытаемся подсунуть свой hdc в FaxPrintCoverPage


    ' CoverPageInfo is the cover page info
    Dim CoverPageInfo As New FAX_COVERPAGE_INFO
    With CoverPageInfo
      .SizeOfStruct = Marshal.SizeOf(CoverPageInfo)
      .UseServerCoverPage = True
      .CoverPageName = "confident" ' "C:\ProgramData\Microsoft\Windows NT\MSFax\Common Coverpages\ru-RU\confident.cov"
      .Subject = "confident"
      '...
    End With

    If FaxPrintCoverPage(FaxContextInfo, CoverPageInfo) = False Then
      SaveCoverPage1 = False
      err_text = "FaxPrintCoverPage Error " & RaiseAPIError()
    End If
    '=====

    SelectObject(hdcDst, hbmOldDst) : hbmOldDst = IntPtr.Zero
    DeleteDC(hdcDst) : hdcDst = IntPtr.Zero

    If SaveCoverPage1 = True Then
      Try
        nBitmap = Bitmap.FromHbitmap(hbmDst)
        nBitmap.SetResolution(204, 196)

        'http://stackoverflow.com/questions/21169217/tiff-file-compression-with-c-sharp
        ' Get an ImageCodecInfo object that represents the TIFF codec.
        Dim myImageCodecInfo As ImageCodecInfo = GetEncoderInfo("image/tiff")
        ' Create an Encoder object based on the GUID for the Compression parameter category.
        Dim myEncoder As Encoder = Encoder.Compression
        ' Create an EncoderParameters object. An EncoderParameters object has an array of EncoderParameter 
        ' objects. In this case, there is only one EncoderParameter object in the array.
        Dim myEncoderParameters As EncoderParameters = New EncoderParameters(1)
        ' Save the bitmap as a TIFF file with eTifCompression compression.
        Dim myEncoderParameter As EncoderParameter = New EncoderParameter(myEncoder, Fix(EncoderValue.CompressionCCITT4))
        myEncoderParameters.Param(0) = myEncoderParameter
        nBitmap.Save("cover_page.tif", myImageCodecInfo, myEncoderParameters)
        nBitmap.Dispose() : nBitmap = Nothing
      Catch
      End Try
    End If

    DeleteObject(hbmDst) : hbmDst = IntPtr.Zero : pBits = IntPtr.Zero
  End Function

Ну и ни фига не работает, FaxPrintCoverPage отрабатывает без ошибки, но на выходе белый лист бумаги. Почему? По идее должен был туда чего-нибудь накалякать.

Но результат таки получил.
Делаем все как в первом случае, т.е. с вызовом FaxStartPrintJob, и с подсовыванием в FaxPrintCoverPage честного hdc (FaxContextInfo.hDC, которое вернула первая ф-ция).
Но далее делаем.
    '!!! в этом месте тупо копируем FaxContextInfo.hDC -> hdcDst
    BitBlt(hdcDst, 0, 0, 1728, 2339, FaxContextInfo.hDC, 0, 0, SRCCOPY)

    '!!!отменяем реальную отправку через MSFax (во первых не отправляется, во вторых не сохраняется в очереди печати)
    AbortDoc(FaxContextInfo.hDC)

Т.е. я вылавливаю-таки желаемую картинку, а затем отменяю "печать" (AbortDoc).
Прокатывает, получаем картинку сохраненную в файле.
+
 Public Function SaveCoverPage(ByRef err_text As String) As Boolean

    SaveCoverPage = True

    Dim bmiDst As BITMAPINFO2
    Dim pBits As IntPtr
    Dim hbmDst As IntPtr
    Dim hdcDst As IntPtr
    Dim hbmOldDst As IntPtr
    Dim nBitmap As Bitmap

    With bmiDst.bmiHeader
      .biSize = Marshal.SizeOf(bmiDst.bmiHeader)
      .biWidth = 1728
      .biHeight = 2339
      .biPlanes = 1
      .biBitCount = 1
      .biCompression = BI_RGB
    End With
    With bmiDst.bmiColors1
      .rgbBlue = 255
      .rgbGreen = 255
      .rgbRed = 255
    End With
    hbmDst = CreateDIBSection(IntPtr.Zero, bmiDst, DIB_RGB_COLORS, pBits, IntPtr.Zero, 0)

    hdcDst = CreateCompatibleDC(IntPtr.Zero)
    hbmOldDst = SelectObject(hdcDst, hbmDst)

    PatBlt(hdcDst, 0, 0, bmiDst.bmiHeader.biWidth, bmiDst.bmiHeader.biHeight, WHITENESS) 'красим белым т.к. он гад черный
    'Using gr As Graphics = Graphics.FromHdc(hdcDst)
    '  gr.Clear(Color.White)
    'End Using

    '=====

    ' dwFaxId is the fax job id
    Dim dwFaxId As Integer

    ' FaxPrintInfo is the fax print info
    Dim FaxPrintInfo As New FAX_PRINT_INFO
    FaxPrintInfo.SizeOfStruct = Marshal.SizeOf(FaxPrintInfo)
    FaxPrintInfo.RecipientNumber = "500" 'номер не может быть пустой

    ' FaxContextInfo is the fax context
    Dim FaxContextInfo As New FAX_CONTEXT_INFO
    FaxContextInfo.SizeOfStruct = Marshal.SizeOf(FaxContextInfo)

    'FaxContextInfo.hDC - здесь возвращается hdc
    If FaxStartPrintJob(vbNullString, FaxPrintInfo, dwFaxId, FaxContextInfo) = False Then
      SaveCoverPage = False
      err_text = "FaxStartPrintJob Error " & RaiseAPIError()
      GoTo ToExit
    End If

    ' CoverPageInfo is the cover page info
    Dim CoverPageInfo As New FAX_COVERPAGE_INFO
    With CoverPageInfo
      .SizeOfStruct = Marshal.SizeOf(CoverPageInfo)
      .UseServerCoverPage = True
      .CoverPageName = "confident" ' "C:\ProgramData\Microsoft\Windows NT\MSFax\Common Coverpages\ru-RU\confident.cov"
      .Subject = "confident"
      '...
    End With

    'печать титульной страницы - FaxContextInfo.hDC определяет куда ее выводить
    If FaxPrintCoverPage(FaxContextInfo, CoverPageInfo) = False Then
      SaveCoverPage = False
      err_text = "FaxPrintCoverPage Error " & RaiseAPIError()
      GoTo ToExit
    End If

    '!!! в этом месте тупо копируем FaxContextInfo.hDC -> hdcDst
    BitBlt(hdcDst, 0, 0, 1728, 2339, FaxContextInfo.hDC, 0, 0, SRCCOPY)

    '!!!отменяем реальную отправку через MSFax (во первых не отправляется, во вторых не сохраняется в очереди печати)
    AbortDoc(FaxContextInfo.hDC)

ToExit:
    DeleteDC(FaxContextInfo.hDC)
    '=====

    SelectObject(hdcDst, hbmOldDst) : hbmOldDst = IntPtr.Zero
    DeleteDC(hdcDst) : hdcDst = IntPtr.Zero

    If SaveCoverPage = True Then
      'сохранение в TIFF титульной страницы
      Try
        nBitmap = Bitmap.FromHbitmap(hbmDst)
        nBitmap.SetResolution(204, 196)

        'http://stackoverflow.com/questions/21169217/tiff-file-compression-with-c-sharp
        ' Get an ImageCodecInfo object that represents the TIFF codec.
        Dim myImageCodecInfo As ImageCodecInfo = GetEncoderInfo("image/tiff")
        ' Create an Encoder object based on the GUID for the Compression parameter category.
        Dim myEncoder As Encoder = Encoder.Compression
        ' Create an EncoderParameters object. An EncoderParameters object has an array of EncoderParameter 
        ' objects. In this case, there is only one EncoderParameter object in the array.
        Dim myEncoderParameters As EncoderParameters = New EncoderParameters(1)
        ' Save the bitmap as a TIFF file with eTifCompression compression.
        Dim myEncoderParameter As EncoderParameter = New EncoderParameter(myEncoder, Fix(EncoderValue.CompressionCCITT4))
        myEncoderParameters.Param(0) = myEncoderParameter
        nBitmap.Save("cover_page.tif", myImageCodecInfo, myEncoderParameters)
        nBitmap.Dispose() : nBitmap = Nothing
      Catch
      End Try
    End If

    DeleteObject(hbmDst) : hbmDst = IntPtr.Zero : pBits = IntPtr.Zero
  End Function


(Ну, код субъективен, принтер Fax надо выставлять программно в 200x200,A4,Портрет - на момент выполнения кода (соответствует разрешению 204x198 и размеру картинки 1728x2339. Но это я умею, также без проблем возвращаю к "текущим установкам").

Мне вот не понятно почему не рисует второй код и что тут можно придумать. Третий код как бы рабочий, но он использует ресурсы принтера, хоть я и не довожу штатную процедуру до конца. Т.е. я делаю копию картинки на полпути, а мне бы изначально эту картинку бухнуть в свое hdc и в файл, не обращаясь к принтеру.

P.S hdc и связанный bitmap я готовлю правильно, могу туда без проблем нарисовать какую-нибудь линию через .Net-овскую Grafics и тому подобное, но вот FaxPrintCoverPage туда напрямую рисовать отказывается, хотя BitBlt туда копирует. Понятно что пытаюсь сделать нечто недокументированное, но тем не менее. Должен быть способ его обмануть.
16 авг 18, 05:58    [21643897]     Ответить | Цитировать Сообщить модератору
 Re: А можно как-то подменить hdc принтера на hdc связанное с bitmap с целью сохранить в файл?  [new]
Дмитрий77
Member

Откуда:
Сообщений: 4404
Дмитрий77
Но мне надо "угнать" CoverPage картинку в свой файл.
Создаю свою кухню, пытаюсь подсунуть в FaxPrintCoverPage свое hdc, не вызывая предварительно FaxStartPrintJob
    ' FaxContextInfo is the fax context
    Dim FaxContextInfo As New FAX_CONTEXT_INFO
    FaxContextInfo.SizeOfStruct = Marshal.SizeOf(FaxContextInfo)
    FaxContextInfo.hDC = hdcDst 'пытаемся подсунуть свой hdc в FaxPrintCoverPage

+
  Public Function SaveCoverPage1(ByRef err_text As String) As Boolean

    SaveCoverPage1 = True

    Dim bmiDst As BITMAPINFO2
    Dim pBits As IntPtr
    Dim hbmDst As IntPtr
    Dim hdcDst As IntPtr
    Dim hbmOldDst As IntPtr
    Dim nBitmap As Bitmap

    With bmiDst.bmiHeader
      .biSize = Marshal.SizeOf(bmiDst.bmiHeader)
      .biWidth = 1728
      .biHeight = 2339
      .biPlanes = 1
      .biBitCount = 1
      .biCompression = BI_RGB
    End With
    With bmiDst.bmiColors1
      .rgbBlue = 255
      .rgbGreen = 255
      .rgbRed = 255
    End With
    hbmDst = CreateDIBSection(IntPtr.Zero, bmiDst, DIB_RGB_COLORS, pBits, IntPtr.Zero, 0)

    hdcDst = CreateCompatibleDC(IntPtr.Zero)
    hbmOldDst = SelectObject(hdcDst, hbmDst)

    PatBlt(hdcDst, 0, 0, bmiDst.bmiHeader.biWidth, bmiDst.bmiHeader.biHeight, WHITENESS) 'красим белым т.к. он гад черный
    'Using gr As Graphics = Graphics.FromHdc(hdcDst)
    '  gr.Clear(Color.White)
    'End Using

    '=====
    ' FaxContextInfo is the fax context
    Dim FaxContextInfo As New FAX_CONTEXT_INFO
    FaxContextInfo.SizeOfStruct = Marshal.SizeOf(FaxContextInfo)
    FaxContextInfo.hDC = hdcDst 'пытаемся подсунуть свой hdc в FaxPrintCoverPage


    ' CoverPageInfo is the cover page info
    Dim CoverPageInfo As New FAX_COVERPAGE_INFO
    With CoverPageInfo
      .SizeOfStruct = Marshal.SizeOf(CoverPageInfo)
      .UseServerCoverPage = True
      .CoverPageName = "confident" ' "C:\ProgramData\Microsoft\Windows NT\MSFax\Common Coverpages\ru-RU\confident.cov"
      .Subject = "confident"
      '...
    End With

    If FaxPrintCoverPage(FaxContextInfo, CoverPageInfo) = False Then
      SaveCoverPage1 = False
      err_text = "FaxPrintCoverPage Error " & RaiseAPIError()
    End If
    '=====

    SelectObject(hdcDst, hbmOldDst) : hbmOldDst = IntPtr.Zero
    DeleteDC(hdcDst) : hdcDst = IntPtr.Zero

    If SaveCoverPage1 = True Then
      Try
        nBitmap = Bitmap.FromHbitmap(hbmDst)
        nBitmap.SetResolution(204, 196)

        'http://stackoverflow.com/questions/21169217/tiff-file-compression-with-c-sharp
        ' Get an ImageCodecInfo object that represents the TIFF codec.
        Dim myImageCodecInfo As ImageCodecInfo = GetEncoderInfo("image/tiff")
        ' Create an Encoder object based on the GUID for the Compression parameter category.
        Dim myEncoder As Encoder = Encoder.Compression
        ' Create an EncoderParameters object. An EncoderParameters object has an array of EncoderParameter 
        ' objects. In this case, there is only one EncoderParameter object in the array.
        Dim myEncoderParameters As EncoderParameters = New EncoderParameters(1)
        ' Save the bitmap as a TIFF file with eTifCompression compression.
        Dim myEncoderParameter As EncoderParameter = New EncoderParameter(myEncoder, Fix(EncoderValue.CompressionCCITT4))
        myEncoderParameters.Param(0) = myEncoderParameter
        nBitmap.Save("cover_page.tif", myImageCodecInfo, myEncoderParameters)
        nBitmap.Dispose() : nBitmap = Nothing
      Catch
      End Try
    End If

    DeleteObject(hbmDst) : hbmDst = IntPtr.Zero : pBits = IntPtr.Zero
  End Function

Ну и ни фига не работает, FaxPrintCoverPage отрабатывает без ошибки, но на выходе белый лист бумаги. Почему? По идее должен был туда чего-нибудь накалякать…
.но вот FaxPrintCoverPage туда напрямую рисовать отказывается, хотя BitBlt туда копирует. Понятно что пытаюсь сделать нечто недокументированное, но тем не менее. Должен быть способ его обмануть.

А если заменить
hdcDst = CreateCompatibleDC(IntPtr.Zero)
На вот это
    'FaxContextInfo.hDC - здесь возвращается hdc
    If FaxStartPrintJob(vbNullString, FaxPrintInfo, dwFaxId, FaxContextInfo) = False Then
      SaveCoverPageTest = False
      err_text = "FaxStartPrintJob Error " & RaiseAPIError()
    End If


    hdcDst = CreateCompatibleDC(FaxContextInfo.hDC)
    hbmOldDst = SelectObject(hdcDst, hbmDst)
 
    AbortDoc(FaxContextInfo.hDC)
    DeleteDC(FaxContextInfo.hDC)


    FaxContextInfo.hDC = hdcDst 'пытаемся подсунуть свой hdc в FaxPrintCoverPage

...
    If FaxPrintCoverPage(FaxContextInfo, CoverPageInfo) = False Then
      SaveCoverPageTest = False
      err_text = "FaxPrintCoverPage Error " & RaiseAPIError()
    End If

то все однако срабатывает и FaxPrintCoverPage выводит графику уже напрямую в мое DC (hdcDst).

Осталось сообразить как создать самому правильное hdcDst, чтоб можно было выкинуть FaxStartPrintJob, которое генерирует вспомогательное FaxContextInfo.hDC.

М.б. CreateDCW function?
Вопрос только что в нее пихать...
Ключевой судя по всему является структура DEVMODE structure, которую придется "сочинять".
17 авг 18, 02:26    [21645269]     Ответить | Цитировать Сообщить модератору
 Re: А можно как-то подменить hdc принтера на hdc связанное с bitmap с целью сохранить в файл?  [new]
Дмитрий77
Member

Откуда:
Сообщений: 4404
Ну вот чтоб совсем на абстрактное hdc вывести, что-то не получается.
Можно
1) Получить текущую DEVMODE принтера
2) Подправить эту DEVMODE с учетом желаемого разрешения (а заодно чтоб точно было A4+Портрет), не нарушая при этом текущих системных установок принтера
3) Создать DC принтера через CreateDC (передается имя принтера и кастомизированная DEVMODE)
4) Из нее создать еще одну hdc через CreateCompatibleDC, в нее уже можно рисовать FaxPrintCoverPage и сохранять картинку.
Поприличней конечно, но по сути не отличается от того что в предыдущем посте. Еще иконка принтера в трей выводится как при печати, хоть мусора в очереди печати и не остается. Также используется имя принтера "Fax", а его вообще говоря можно переименовать в "Fax1".


 Public Function SaveCoverPageTestWithResolution(Optional ResFine As Boolean = True, _
   Optional ByRef err_text As String = vbNullString) As Boolean
    'ResFine=True: 204x196,1728x2339 (A4,PORTRAIT)
    'ResFine=False: 204x98,1728x1169 (A4,PORTRAIT)
    SaveCoverPageTestWithResolution = True
    Dim dm As New DEVMODE 'сюда получаем тек. структуру (главное ее шаблон правильный)
    If GetPrinterDevMode("Fax", dm, err_text) = False Then 'ну значит факс хозяйство не установлено, чего дальше стараться
      SaveCoverPageTestWithResolution = False
      Exit Function
    End If
    'подправим (не меняя дефолтные тек. настройки)
    dm.dmPrintQuality = 200
    dm.dmYResolution = IIf(ResFine, 200, 100)
    dm.dmOrientation = DMORIENT_PORTRAIT
    dm.dmPaperSize = DMPAPER_A4

    'рисуем картинку
    Dim bmiDst As BITMAPINFO2
    Dim pBits As IntPtr
    Dim hbmDst As IntPtr
    Dim hdcDst As IntPtr
    Dim hbmOldDst As IntPtr
    Dim nBitmap As Bitmap

    With bmiDst.bmiHeader
      .biSize = Marshal.SizeOf(bmiDst.bmiHeader)
      .biWidth = 1728
      .biHeight = IIf(ResFine, 2339, 1169)
      .biPlanes = 1
      .biBitCount = 1
      .biCompression = BI_RGB
    End With
    With bmiDst.bmiColors1
      .rgbBlue = 255
      .rgbGreen = 255
      .rgbRed = 255
    End With
    hbmDst = CreateDIBSection(IntPtr.Zero, bmiDst, DIB_RGB_COLORS, pBits, IntPtr.Zero, 0)

    'сначала создаем DC принтера (с заданным A4+Портрет+разрешение)
    Dim hdcDst1 As IntPtr = CreateDC(vbNullString, "fax", vbNullString, dm)
    'из него делаем CompatibleDC, куда перенаправим вывод FaxPrintCoverPage
    hdcDst = CreateCompatibleDC(hdcDst1)
    DeleteDC(hdcDst1) 'это можно сразу грохнуть
    hbmOldDst = SelectObject(hdcDst, hbmDst)

    PatBlt(hdcDst, 0, 0, bmiDst.bmiHeader.biWidth, bmiDst.bmiHeader.biHeight, WHITENESS) 'красим белым т.к. он гад черный

    '======распечатка Cover Page=======
    ' FaxContextInfo is the fax context
    Dim FaxContextInfo As New FAX_CONTEXT_INFO
    FaxContextInfo.SizeOfStruct = Marshal.SizeOf(FaxContextInfo)
    FaxContextInfo.hDC = hdcDst 'подсовываем свой hdc в FaxPrintCoverPage

    ' CoverPageInfo is the cover page info
    Dim CoverPageInfo As New FAX_COVERPAGE_INFO
    With CoverPageInfo
      .SizeOfStruct = Marshal.SizeOf(CoverPageInfo)
      .UseServerCoverPage = True
      .CoverPageName = "confident" ' "C:\ProgramData\Microsoft\Windows NT\MSFax\Common Coverpages\ru-RU\confident.cov"
      .Subject = "confident"
      '...
    End With

    'печать титульной страницы: (FaxContextInfo.hDC = hdcDst)
    Try
      If FaxPrintCoverPage(FaxContextInfo, CoverPageInfo) = False Then
        SaveCoverPageTestWithResolution = False
        err_text = "FaxPrintCoverPage Error " & RaiseAPIError()
      End If
    Catch
      SaveCoverPageTestWithResolution = False
      err_text = Err.Description 'если winfax.dll не найдена
    End Try

    SelectObject(hdcDst, hbmOldDst) : hbmOldDst = IntPtr.Zero
    DeleteDC(hdcDst) : hdcDst = IntPtr.Zero

    If SaveCoverPageResolution() = True Then
      'сохранение в TIFF титульной страницы
      Try
        nBitmap = Bitmap.FromHbitmap(hbmDst)
        nBitmap.SetResolution(204, IIf(ResFine, 196, 98))

        'http://stackoverflow.com/questions/21169217/tiff-file-compression-with-c-sharp
        ' Get an ImageCodecInfo object that represents the TIFF codec.
        Dim myImageCodecInfo As ImageCodecInfo = GetEncoderInfo("image/tiff")
        ' Create an Encoder object based on the GUID for the Compression parameter category.
        Dim myEncoder As Encoder = Encoder.Compression
        ' Create an EncoderParameters object. An EncoderParameters object has an array of EncoderParameter 
        ' objects. In this case, there is only one EncoderParameter object in the array.
        Dim myEncoderParameters As EncoderParameters = New EncoderParameters(1)
        ' Save the bitmap as a TIFF file with eTifCompression compression.
        Dim myEncoderParameter As EncoderParameter = New EncoderParameter(myEncoder, Fix(EncoderValue.CompressionCCITT4))
        myEncoderParameters.Param(0) = myEncoderParameter
        nBitmap.Save("cover_page.tif", myImageCodecInfo, myEncoderParameters)
        nBitmap.Dispose() : nBitmap = Nothing
      Catch
      End Try
    End If

    DeleteObject(hbmDst) : hbmDst = IntPtr.Zero : pBits = IntPtr.Zero
  End Function


  Public Function GetPrinterDevMode(ByVal sPrinterName As String, _
   ByRef dm As DEVMODE, Optional ByRef sErrMsg As String = vbNullString) As Boolean

    Dim hPrinter As IntPtr
    Dim pd As New PRINTER_DEFAULTS

    Dim pBufferDevModeData As IntPtr
    Dim nRet As Integer

    GetPrinterDevMode = False

    pd.DesiredAccess = PRINTER_ACCESS_USE
    If OpenPrinter(sPrinterName & Chr(0), hPrinter, pd) = False Then
      sErrMsg = "OpenPrinter failed: " & RaiseAPIErrorByNumber(Err.LastDllError)
      Exit Function
    End If

    nRet = DocumentProperties(IntPtr.Zero, hPrinter, sPrinterName & Chr(0), IntPtr.Zero, IntPtr.Zero, 0)
    If (nRet < 0) Then
      sErrMsg = "DocumentProperties failed: " & RaiseAPIErrorByNumber(Err.LastDllError)
      GoTo cleanup
    End If

    pBufferDevModeData = Marshal.AllocHGlobal(nRet)
    nRet = DocumentProperties(IntPtr.Zero, hPrinter, sPrinterName & Chr(0), _
     pBufferDevModeData, IntPtr.Zero, DM_OUT_BUFFER)
    If (nRet < 0) Then
      sErrMsg = "DocumentProperties failed: " & RaiseAPIErrorByNumber(Err.LastDllError)
      GoTo cleanup
    End If
    dm = Marshal.PtrToStructure(pBufferDevModeData, GetType(DEVMODE))
    GetPrinterDevMode = True

cleanup:
    If (hPrinter <> IntPtr.Zero) Then Call ClosePrinter(hPrinter)

    If Not pBufferDevModeData.Equals(0) Then
      Marshal.FreeHGlobal(pBufferDevModeData)
    End If
  End Function
17 авг 18, 06:39    [21645301]     Ответить | Цитировать Сообщить модератору
Все форумы / WinForms, .Net Framework Ответить