- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for the information. I will give it a try. Also structure DevNames contains an offset to the name of the printer device:
wDeviceOffset -Offset, in characters, from the beginning of this structure to the null-terminated string that contains the name of the device.DevNames is filled inafter the OpenDlg box is closed, but not sure how to retieve the device name. Is it something like this:
character(50) szBuffer
type (T_DEVNAMES) dnstruc
pointer(p_dnstruc, dnstruc)
szBuffer = p_dnstruc+wDeviceOffset
Thanks again.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Offhand, I don't see the context, but are you sure you need it? If I recall correctly, the DEVMODE contains the same information. I've never had to use DEVNAMES... but then, this printing stuff is so complicated that I can't tell for sure.
character(50) szBuffer; pointer(pszBuffer, szBuffer)
type (T_DEVNAMES) dnstruc
pointer(p_dnstruc, dnstruc)
pszBuffer = p_dnstruc+wDeviceOffset
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Have not worked with pointers very much so your example code helps quite a bit. Kind of in the dark about win32 printing and avoiding errors that cannot be recovered from. So, at this point I am not sure what is needed, but I have enough info now to try some code and see what happens.
Than you, JugoslavDujic.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Tried the following code after calling PrintDlg() so code could check on any printer that was selectable in the Printer Dlg box.
GetPrinter() below returns 0 [failure], and GetLastError returns 1780, which is 'a null reference pointer was passed to the stub'Not sure what that means?
pPI2 appears to be a valid positive integer, and not Null before GetPrinter() is called..
Everything seems OK until I get to GetPrinter(), hPrinter appears valid and no other indication of problems.
Not sure if this approach is correct, so any comments would be appreciated.
integer*4 hPrinter
integer*4 iSizePI2
integer*4 iSizeNeeded
Character(Max_Path) szPrinterName ; pointer(pszPrinterName, szPrinterName)type(T_DEVNAMES) DN ; pointer(pDN, DN)
type(T_PRINTER_INFO_2) PI2 ; pointer(pPI2, PI2)
type(T_PRINTDLG) PD
! display print dlg box
Last_Error = PrintDlg(PD)
.....
pDN = GlobalLock(PD%hDevNames)
pszPrinterName = pDN + DN%wDeviceOffset
iret = GlobalUnlock(PD%hDevNames)
iret = OpenPrinter(szPrinterName, hPrinter, Null)
iSizePI2 = SIZEOF(PI2)
iSizeNeeded = 0
iret = GetPrinter(hPrinter, int4(2), pPI2, iSizePI2, loc(iSizeNeeded))
if(iret == 0) iret = GetLastError()
! PRINTER_STATUS_OFFLINE = 128
if(PI2%Status == PRINTER_STATUS_OFFLINE) then
! printer off line
goto 99
end if
Message Edited by halcyong@fcc.net on 02-22-2006 09:16 AM
Message Edited by halcyong@fcc.net on 02-22-2006 01:37 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The general approach with printer-related structures (which are of "variable size") is "query size first, allocate buffer, then requery" (untested):
integer(1), allocatable:: iPI2buf(:)Similar code is required wherever you have a "pcbNeeded" argument (EnumPrinters, GetPrinterData etc.)
...
ret = GetPrinter(hPrinter, 2, NULL, 0, LOC(iSize))
ALLOCATE(iPI2buf(iSize))
pPI2 = LOC(iPI2buf)
ret = GetPrinter(hPrinter, 2, pPI2, iSize, LOC(iSize))
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks. After I posted the last message, I reviewed the Google code again and realized that GetPrinter() needed more than sizeof(PI2) bytes. I was trying to allocate memory with pPI2 = MALLOC(iBytesNeeded)andran into exceptions in the debugger, not sure why. But, your code/method works great.
With the following code the PRINT_INFO_2 stucture (PI2) appears to be filled in correctly, except for the last 4 elements which includes PI2%Status. If the printer isON orOFF line the last 4 elements of the structure are always 0. I noticed in the Google code thattheoutput buffer from GetPrinter() is copied explicitly to the local PI2 structure with the following: Call CopyMemory(pi2, Buffer(0), Len(pi2)) and then laterin the code the PI2%Status element is explicitly copied to StatusCode: Call CopyMemory(StatusCode, Buffer(72), 4). Is it necessary to do something like this in IVF to get the PI2%Status element? I tried Call CopyMemory(pPI2, pBuffer, sizeof(PI2)) but ran into memory access errors. pBuffer was the output buffer for GetPrinter() and was allocated as pBuffer = MALLOC(1600). The actual bytes need by GetPrinter() are 1596.
pDN = GlobalLock(PD%hDevNames)
pszPrinterName = pDN + DN%wDeviceOffset
iret = GlobalUnlock(PD%hDevNames)
iret = OpenPrinter(szPrinterName, hPrinter, Null)
iBytesNeeded = 0
iret = GetPrinter(hPrinter, int4(2), Null, 0, loc(iBytesNeeded))
ALLOCATE(iPI2buf(iBytesNeeded))
pPI2 = LOC(iPI2buf)
iret = GetPrinter(hPrinter, int4(2), pPI2, iBytesNeeded, loc(iBytesNeeded))
! PRINTER_STATUS_OFFLINE = 80
if(PI2%Status == PRINTER_STATUS_OFFLINE) then
! printer off line
goto 99
end if
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
However, I'm worried about those zeros. I Googled a little and found that the most replies to the question are silence. I've just found Q160129 which says:
Note, however, that the default port monitor for Windows does not usually set more than the PRINTER_STATUS_ERROR bit of a Printer's Status member.
D'oh. You might try with some of those GetJob functions and family, but... it might just be impossible. I'm curious, though, as to why StartDoc stalls I don't recall it has ever happened to me.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I did do a call CopyMemory(loc(iStatus), pPI2+72, 4) and iStatus, as expected, was0.
Thanks for the Q160129 article. I will take a close look at that. Also, thanks for the additional Google info on StartDoc() hangs. I will have to start particpating in the Google groups!
When StartDoc() hangs in Win2K it creates an exception (watching with the VSnet debugger)in a header ctl for a List View window. If the printer is attached and is on this does not occur. Possibly, the printer driver or someother code is trying to access memory used by the header ctl.The same code, however, works fine on an XP machine, and if the printer is not on simply spools the print job.
I will try an HP2P printer that is attached to both machines to see what happens when it is not on or disconnected.
Thanks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Are you sure you don't have a silent memory overwrite somewhere? DEVMODE, if you manipulate it directly (as opposed to PrintDlg) has the same properties as DEVNAMES or PRINTER_INFO_2 it takes far more memory than sizeof(T_DEVMODE), so the same query-allocate-requery mechanism is needed if you do e.g. DocumentProperties or CreateDC yourself.
If the printer is off and the printer driver is faulty, then the same hanging should happen in other applications -- does it? If not, you might have some bug hanging around.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I do manipulate the DEVMODE structure, so I will check that out.Thanks.
Also, foundthat Print Direct To The Printer was checked in the properties dlg. box (Advancedsettings tab)for the printer on the Win2k machine. Once the 'Spool Print Document' was checked in the dlg box the Win2k machine did not hang. If the printer was off-line,the print job was simply spooled.
However,thePRINTER_INFO_2 structure (PI2) can be used to check on the PRINT_ATTRIBUTE_DIRECT flag, and if it is set abort the print job as shown below.I tried this and it appears to work. Should be a work around if I can't identify any othertcauses forStartDoc() to hang.
pDN = GlobalLock(PD%hDevNames)
pszPrinterName = pDN + DN%wDeviceOffset
iret = GlobalUnlock(PD%hDevNames)
iret = OpenPrinter(szPrinterName, hPrinter, Null)
iBytesNeeded = 0
iret = GetPrinter(hPrinter, int4(2), Null, 0, loc(iBytesNeeded))
ALLOCATE(iPI2buf(iBytesNeeded))
pPI2 = LOC(iPI2buf)
iret = GetPrinter(hPrinter, int4(2), pPI2, iBytesNeeded, loc(iBytesNeeded))
! check to see if print job is spooled or sent directly tp printer
! if sent directly to printer abort print job
iret = IAND(PI2%ATTRIBUTES, PRINTER_ATTRIBUTE_DIRECT)
! flag PRINTER_ATTRIBUTE_DIRECT = 2
if(iret == PRINTER_ATTRIBUTE_DIRECT) then
! post mesgbox() here and abort print job
go to 99
end if
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page