- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have been translating the sample code in C++ for the subroutine GetPrinterDevice that is listed in Microsoft Knowledge Base Article 166129 ?HOWTO: Print Directly to a Non-Default Printer in MFC? and it works correctly (on one system at least).
However, whereas the original C++ code is able to allocate using a single command the memory required for the DEVMODE structure plus the private driver-data, I have been unable in CVF to do so, so have been forced to take two bites at the cherry. Does anyone know of a way of doing it in one? I append my CVF code, from which I have removed the tests for success of the operations.
The C++ code that is used where commented above is:
Regards
Alan
However, whereas the original C++ code is able to allocate using a single command the memory required for the DEVMODE structure plus the private driver-data, I have been unable in CVF to do so, so have been forced to take two bites at the cherry. Does anyone know of a way of doing it in one? I append my CVF code, from which I have removed the tests for success of the operations.
! Allocate a global handle for DEVMODE structure dm. ! When dm.dmDriverExtra is available, resize memory. ! nLen = sizeof(dm) hDm = GlobalAlloc(GHND, nLen) ! See C++ code line below. p_dm = GlobalLock(hDm) call CopyMemory(p_dm, p2.pDevMode, nLen) ! ! Now dm.dmDriverExtra is available, so memory can be freed and reallocated ! with the correct size. ! nLen = sizeof(dm) + dm.dmDriverExtra p_dm = GlobalFree(p_dm) hDm = GlobalAlloc(GHND, nLen) p_dm = GlobalLock(hDm) call CopyMemory(p_dm, p2.pDevMode, nLen) LastError = GlobalUnlock(hDm)
The C++ code that is used where commented above is:
HGLOBAL hDevMode = GlobalAlloc(GHND, sizeof(*p2->pDevMode) + p2->pDevMode->dmDriverExtra);
Regards
Alan
Link Copied
7 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Alan,
DocumentProperties (ain't the name intuitive? ;-) ) API returns size of DEVMODE+extra stuff structure for given printer if fMode argument is zero (i.e. it works in similar manner as GetPrinter -- first call returns number of bytes, then you allocate it and give it a regular buffer).
Oh, I found the Q166129. You can mimic that code using Cray (aka Integer) pointers, which are quite similar to C pointers (and you'll hardly avoid them when dealing with such ugly low-level printer stuff):
HTH
Jugoslav
DocumentProperties (ain't the name intuitive? ;-) ) API returns size of DEVMODE+extra stuff structure for given printer if fMode argument is zero (i.e. it works in similar manner as GetPrinter -- first call returns number of bytes, then you allocate it and give it a regular buffer).
Oh, I found the Q166129. You can mimic that code using Cray (aka Integer) pointers, which are quite similar to C pointers (and you'll hardly avoid them when dealing with such ugly low-level printer stuff):
TYPE(T_PRINTER_INFO_2):: PI2; POINTER(pPI2, PI2) TYPE(T_DEVMODE):: DM; POINTER(pDM, DM) ... GetPrinter(hPrinter, 2, NULL, 0, LOC(dwBytesNeeded)) hPI2 = GlobalAlloc(GHND, dwBytesNeeded) pPI2 = GlobalLock(hPI2) GetPrinter(hPrinter, 2, pPI2, dwBytesNeeded, LOC(dwBytesReturned)) pDM = PI2%pDevMode dmDriverExtra = DM%dmDriverExtra ...Side note: I prefer ALLOCATEing a INTEGER(1) buffer array than using GlobalAlloc/GlobalLock, and then "equivalence" it to a DEVMODE or whatever using Cray pointer. Simpler & more flexible.
HTH
Jugoslav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Jugoslav,
Many thanks for your help - as usual there are several ways of skinning the cat and I could only think of the hard way. Now I can get onto my next problem.
Alan
Many thanks for your help - as usual there are several ways of skinning the cat and I could only think of the hard way. Now I can get onto my next problem.
Alan
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
And my next problem is that my program is now working reasonably well, but one user has a problem with network printers that have long filenames. The printer name is stored in the dmDeviceName element of the DEVMODE structure, and this is declared as a character(32) string in dfwinty. However, the printer names are longer than 32 characters ? indeed the first 32 characters of all of their names are the same.
There is no trouble with standard print dialog boxes, but it does not work with my customised version ? it will only print on the default printer for these long file names. Does anyone know of a fix?
Regards
Alan
There is no trouble with standard print dialog boxes, but it does not work with my customised version ? it will only print on the default printer for these long file names. Does anyone know of a fix?
Regards
Alan
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Alan,
Just to get the Society for the Prevention of Cruelty to Animals (US version, may be Royal Humane Society in Britain) off your back "more the one way to skin a 'cat'" refers to a catfish, not the furry ones (except in eastern Asia) :)
Keith
Owned by 3 furry cats.
Just to get the Society for the Prevention of Cruelty to Animals (US version, may be Royal Humane Society in Britain) off your back "more the one way to skin a 'cat'" refers to a catfish, not the furry ones (except in eastern Asia) :)
Keith
Owned by 3 furry cats.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Alan,
Attached is an actual source of mine, which is tested rather thoroughly -- it's also a custom print dialog. Unfortunately, it's not rich with comments and not compilable as-is (API calls are interspersed with dialog handling). I don't think it has 32-char limit problem, since it uses EnumPrinters and DocumentProperties APIs, which use pointers-to-strings, not character*32. Contents of IDC_COMBO_PRINTER are used as storage for printer names as obtained from EnumPrinters. I know it's too complicated for your needs, but I think you'll be able to extract the interesting parts.
[nDMBuffer is INTEGER(1) array sized enough to hold the biggest DEVMODE+extrastuff of all printers installed (iMaxBufSize). It is not deallocated anymore, and few variables are global/SAVEd in order to retain the dialog settings for eventual invocations. (bWasHere, bPrinterSet)]
(Attachment in the followup)
Jugoslav
Attached is an actual source of mine, which is tested rather thoroughly -- it's also a custom print dialog. Unfortunately, it's not rich with comments and not compilable as-is (API calls are interspersed with dialog handling). I don't think it has 32-char limit problem, since it uses EnumPrinters and DocumentProperties APIs, which use pointers-to-strings, not character*32. Contents of IDC_COMBO_PRINTER are used as storage for printer names as obtained from EnumPrinters. I know it's too complicated for your needs, but I think you'll be able to extract the interesting parts.
[nDMBuffer is INTEGER(1) array sized enough to hold the biggest DEVMODE+extrastuff of all printers installed (iMaxBufSize). It is not deallocated anymore, and few variables are global/SAVEd in order to retain the dialog settings for eventual invocations. (bWasHere, bPrinterSet)]
(Attachment in the followup)
Jugoslav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
...here it is. I attached also a screenshot so that you get the idea how it looks like -- I hope control ID names are descriptive enough.
P.S. I'll be back September 1...
P.S. I'll be back September 1...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Jugoslav,
Welcome back, and many thanks for the code. I have been sidetracked by priority work & holidays, but will be implementing it soon.
Regards
Alan
Welcome back, and many thanks for the code. I have been sidetracked by priority work & holidays, but will be implementing it soon.
Regards
Alan

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