I've been going round and round in circles for the past few days trying to
get this to work right. The intent is for the application to first prompt the user to choose a printer OR suppress the prompt and use the default printer. The application may then change the printer orientation based on its internal criteria. This is what I have so far, in a workspace. It seems to work, though obviously still needs to be wrapped in a method, presumably in PrinterCanvas. If anyone sees any glaring errors, please let me know. BTW, I tried doing this in VB a couple of years ago and wasn't able to do it (at least not without resorting to a third party dll). In addition, Dolphin has been very forgiving about all my experimentation -- I was not knocked out of Dolphin even once, which would certainly have been the case numerous times with VB, it being notoriously intolerant of things being "off" when going into the Windows API. -- Louis "Variables: pd -- a PrintDialog. hDC -- a printer device context. pc -- a PrinterCanvas. dm -- a DEVMODE structure. Note: Add pool Win32Constants to workspace before evaluating lines below." "Create a PrintDialog instance." pd := PrintDialog new. "Set PRINTDLG flags to show Print Setup dialog (instead of Print) and to return a Device Context in winStruct hDC." pd winStruct flags: (PD_PRINTSETUP | PD_RETURNDC). "To bypass user input and use the default printer, evaluate the next line." pd winStruct flags: (PD_RETURNDEFAULT | PD_RETURNDC). "Create a printer device context through Win PrintDlg, which also allocates memory for the DEVMODE structure, initializes its members to indicate user or default input, and returns a handle (in pd winStruct) that identifies it." hDC := pd showModal. "Create references to the returned DEVMODE structure. It seems necessary to 'lock' the returned handle for the rest to work." hDevMode := pd winStruct hDevMode. externalAddressDM := KernelLibrary default globalLock: hDevMode. dm := DEVMODE fromAddress: externalAddressDM. "Cleanup -- not sure this is necessary." KernelLibrary default globalUnlock: hDevMode. "Display current printer name and orientation (1 = Portrait, 2 = Landscape)." devname := dm dmDeviceName asString trimNulls. dm dmOrientation. "Create a PrinterCanvas with device context hDC and print a page." pc := PrinterCanvas withOwnedDC: hDC. pc startDoc; startPage; text: 'Test 1' at: 50@50; endPage; endDoc. "Toggle printer orientation." dm dmOrientation: (dm dmOrientation = 1 ifTrue: [2] ifFalse: [1]). "Create a printer device context and print a page with new orientation." hDC := GDILibrary default createDC: nil lpszDevice: devname lpszOutput: nil lpdvminit: dm. pc := PrinterCanvas withOwnedDC: hDC. pc startDoc; startPage; text: 'Test 2' at: 50@50; endPage; endDoc. "To prompt user with dialog showing changed settings, use this." pd winStruct flags: (PD_PRINTSETUP | PD_RETURNDC). (hDC := pd showModal) notNil ifTrue: [ pc := PrinterCanvas withOwnedDC: hDC. pc startDoc; startPage; text: 'Test 3' at: 50@50; endPage; endDoc] DEVMODE is defined as: Win32Structure subclass: #DEVMODE instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' classInstanceVariableNames: '' DEVMODE class>>defineFields is defined as: defineFields "Define the fields of the Win32 DEVMODE structure. DEVMODE compileDefinition typedef struct _devicemode BCHAR dmDeviceName[CCHDEVICENAME]; WORD dmSpecVersion; WORD dmDriverVersion; WORD dmSize; WORD dmDriverExtra; DWORD dmFields; union { struct { short dmOrientation; short dmPaperSize; short dmPaperLength; short dmPaperWidth; }; POINTL dmPosition; }; short dmScale; short dmCopies; short dmDefaultSource; short dmPrintQuality; short dmColor; short dmDuplex; short dmYResolution; short dmTTOption; short dmCollate; BCHAR dmFormName[CCHFORMNAME]; WORD dmLogPixels; DWORD dmBitsPerPel; DWORD dmPelsWidth; DWORD dmPelsHeight; union { DWORD dmDisplayFlags; DWORD dmNup; } DWORD dmDisplayFrequency; #if(WINVER >= 0x0400) DWORD dmICMMethod; DWORD dmICMIntent; DWORD dmMediaType; DWORD dmDitherType; DWORD dmReserved1; DWORD dmReserved2; #if (WINVER >= 0x0500) || (_WIN32_WINNT >= 0x0400) DWORD dmPanningWidth; DWORD dmPanningHeight; #endif #endif /* WINVER >= 0x0400 */ } DEVMODE; " self defineField: #dmDeviceName type: (ArrayField type: ByteArray length: 32) offset: 0; defineField: #dmSpecVersion type: SWORDField new offset: 32; defineField: #dmDriverVersion type: SWORDField new offset: 34; defineField: #dmSize type: SWORDField new offset: 36; defineField: #dmDriverExtra type: SWORDField new offset: 38; defineField: #dmFields type: SDWORDField new offset: 40; defineField: #dmOrientation type: SWORDField new offset: 44; defineField: #dmPaperSize type: SWORDField new offset: 46; defineField: #dmPaperLength type: SWORDField new offset: 48; defineField: #dmPaperWidth type: SWORDField new offset: 50; defineField: #dmScale type: SWORDField new offset: 52; defineField: #dmCopies type: SWORDField new offset: 54; defineField: #dmDefaultSource type: SWORDField new offset: 56; defineField: #dmPrintQuality type: SWORDField new offset: 58; defineField: #dmColor type: SWORDField new offset: 60; defineField: #dmDuplex type: SWORDField new offset: 62; defineField: #dmYResolution type: SWORDField new offset: 64; defineField: #dmTTOption type: SWORDField new offset: 66; defineField: #dmCollate type: SWORDField new offset: 68; defineField: #dmFormName type: (ArrayField type: ByteArray length: 32) offset: 70; defineField: #dmLogPixels type: SWORDField new offset: 102; defineField: #dmBitsPerPel type: SDWORDField new offset: 104; defineField: #dmPelsWidth type: SDWORDField new offset: 108; defineField: #dmPelsHeight type: SDWORDField new offset: 112; defineField: #dmDisplayFlags type: SDWORDField new offset: 116; defineField: #dmDisplayFrequency type: SDWORDField new offset: 120; defineField: #dmICMMethod type: SDWORDField new offset: 124; defineField: #dmICMIntent type: SDWORDField new offset: 128; defineField: #dmMediaType type: SDWORDField new offset: 132; defineField: #dmDitherType type: SDWORDField new offset: 136; defineField: #dmReserved1 type: SDWORDField new offset: 140; defineField: #dmReserved2 type: SDWORDField new offset: 144. self byteSize: 148 To use DEVMODE, you'll need to evaluate "DEVMODE compileDefinition" which generates the accessors. (All the SDWORDFields should really be DWORDFields -- DEVMODE was generated from a VB type library -- but I don't think that's a problem.) |
Free forum by Nabble | Edit this page |