【VB6】印刷ダイアログの表示を繰り返すと異常終了
開発言語:VB6
お世話になります。
DEVMODE構造体とDEVNAME構造体に、プリンタや用紙サイズ、印刷の向きなどを指定し、Win32APIのPrintDialogで印刷ダイアログを表示しています。
この処理を何回か呼び出すと、プログラムが異常終了します。
異常終了する場所は、PrintDialogを呼び出した直後だと思われます。
いろいろ調べたのですが、原因がわかりません。
長くなりますが、ソースコードの一部を添付させて頂きます。
ご覧頂き、おかしい点などございましたらご指摘いただけるとありがたいです。
よろしくお願いします。
以下ソースコード
-----------------------------------------------------------------------------------
PrintDlg.lStructSize = Len(PrintDlg)
PrintDlg.hwndOwner = phwnd
PrintDlg.flags = plngPrintFlags
strDeviceName = Printer.DeviceName
strDriverName = Printer.DriverName
sngPaperBin = Printer.PaperBin
strPortNo = Printer.Port
If mstrDriverName <> "" And _
mstrDeviceName <> "" And _
mstrPortNo <> "" Or _
msngDefaultSource <> 0 Then
For Each objPrinter In Printers
If objPrinter.DeviceName = mstrDeviceName Then
strDeviceName = mstrDeviceName
strDriverName = mstrDriverName
sngPaperBin = msngDefaultSource
strPortNo = mstrPortNo
Exit For
End If
Next
End If
udtPrinterDefaults.DesiredAccess = PRINTER_ACCESS_USE
If OpenPrinter(Trim(strDeviceName), hPrinter, udtPrinterDefaults) <> 0 Then
bufSize = DocumentProperties(NULLPTR, hPrinter, Trim(strDeviceName), NULLPTR, NULLPTR, 0)
If bufSize < 1 Then
MsgBox "プリンタ情報の取得に失敗しました。", vbCritical
GoTo Exit_Proc
Else
ReDim aDevMode(bufSize - 1)
Call DocumentProperties(NULLPTR, hPrinter, Trim(strDeviceName), aDevMode(0), NULLPTR, DM_OUT_BUFFER)
Call CopyMemory(DevMode, aDevMode(0), Len(DevMode))
End If
Call ClosePrinter(hPrinter)
Else
MsgBox Err.LastDllError
MsgBox "プリンタの取得に失敗しました。", vbCritical
GoTo Exit_Proc
End If
DevMode.dmPaperSize = mintPaperSize
DevMode.dmOrientation = mintPaperOrnt
DevMode.dmDefaultSource = sngPaperBin
PrintDlg.hDevMode = GlobalAlloc(GMEM_MOVEABLE Or GMEM_ZEROINIT, Len(DevMode))
lpDevMode = GlobalLock(PrintDlg.hDevMode)
If lpDevMode > 0 Then
CopyMemory ByVal lpDevMode, DevMode, Len(DevMode)
bReturn = GlobalUnlock(lpDevMode)
End If
With DevName
.wDriverOffset = 8
.wDeviceOffset = .wDriverOffset + 1 + Len(strDriverName)
.wOutputOffset = .wDeviceOffset + 1 + Len(strDeviceName)
.wDefault = 0
.extra = strDriverName & Chr(0) & strDeviceName & Chr(0) & strPortNo & Chr(0)
End With
PrintDlg.hDevNames = GlobalAlloc(GMEM_MOVEABLE Or _
GMEM_ZEROINIT, Len(DevName))
lpDevName = GlobalLock(PrintDlg.hDevNames)
If lpDevName > 0 Then
CopyMemory ByVal lpDevName, DevName, Len(DevName)
bReturn = GlobalUnlock(lpDevName)
End If
If PrintDialog(PrintDlg) Then
mhDC = PrintDlg.hdc
lpDevName = GlobalLock(PrintDlg.hDevNames)
CopyMemory DevName, ByVal lpDevName, Len(DevName)
bReturn = GlobalUnlock(lpDevName)
GlobalFree PrintDlg.hDevNames
lpDevMode = GlobalLock(PrintDlg.hDevMode)
CopyMemory DevMode, ByVal lpDevMode, Len(DevMode)
bReturn = GlobalUnlock(PrintDlg.hDevMode)
GlobalFree PrintDlg.hDevMode
mstrDriverName = Mid(DevName.extra, DevName.wDriverOffset - 8 + 1)
mstrDriverName = Left(mstrDriverName, InStr(mstrDriverName, Chr(0)) - 1)
mstrDeviceName = Mid(DevName.extra, DevName.wDeviceOffset - 8 + 1)
mstrDeviceName = Left(mstrDeviceName, InStr(mstrDeviceName, Chr(0)) - 1)
mstrPortNo = Mid(DevName.extra, DevName.wOutputOffset - 8 + 1)
mstrPortNo = Left(mstrPortNo, InStr(mstrPortNo, Chr(0)) - 1)
msngDefaultSource = DevMode.dmDefaultSource
mintPaperOrnt = DevMode.dmOrientation
mintPaperSize = DevMode.dmPaperSize
gfShowPrinter = True
End If
お礼
アドバイスありがとうございます。 無事解決しましたので、締め切らせて頂きます。 有難うございました。
補足
アドバイスありがとうございます。 vDevMode.dmDriverExtra の値ですが、設定していませんので、0になっています。 あれから色々調べた所、他のプリンタではきちんと設定が反映されていて、 特定のプリンタのみが反映されていないようです。 jmhさんの推測通り、プリンタの拡張機能の部分に問題があるように思います。 vDevMode.dmDriverExtraの値の設定の仕方が現在わからず、調べております。 DEVMODE構造体の定義は、下記になっています。 Public Type DEVMODE dmDeviceName As String * CCHDEVICENAME dmSpecVersion As Integer dmDriverVersion As Integer dmSize As Integer dmDriverExtra As Integer dmFields As Long dmOrientation As Integer dmPaperSize As Integer dmPaperLength As Integer dmPaperWidth As Integer dmScale As Integer dmCopies As Integer dmDefaultSource As Integer dmPrintQuality As Integer dmColor As Integer dmDuplex As Integer dmYResolution As Integer dmTTOption As Integer dmCollate As Integer dmFormName As String * CCHFORMNAME dmLogPixels As Integer dmBitsPerPel As Long dmPelsWidth As Long dmPelsHeight As Long dmDisplayFlags As Long dmDisplayFrequency As Long End Type 話は変わりますが、PRINTDLGEXであれば上手くいくのではないかと試していたのですが、参考となるサンプルがなく、模索中です。 また何かアドバイスがございましたら、よろしくお願いします。