I have added some additional code to the Get_PrintDC function of my Sipprt.c code so as to get the print out in landscape rather than the default portrait format.

The code reads as follows (the additional code is inserted after the return CreateDC line):

HDC NEAR Get_PrintDC( void )
  static char szPrinter[80];
  char       *szDevice, *szDriver, *szOutput;

  GetProfileString( "windows", "device", ",,,", szPrinter, 80 );

  if( NULL != (szDevice = strtok (szPrinter, "," )) &&
      NULL != (szDriver = strtok (NULL,      ", ")) &&
      NULL != (szOutput = strtok (NULL,      ", " )))

    return CreateDC( szDriver, szDevice, szOutput, NULL );

      DEVMODE FAR *pDevMode=(DEVMODE FAR *) GlobalLock;
      if (pDevMode->dmOrientation != DMORIENT_LANDSCAPE)
      {pDevMode->dmOrientation = DMORIENT_LANDSCAPE;}

  return 0 ;

This compiles, links and creates an executable withour error or warning, but does not change the printed orientation. Can anyone suggest a modified HDC NEAR Get_PrintDC( void ) - in its entirety please - that would achieve the landscape printout that I would like. Can you also explain the process as my search showed lots of people out there looking at this problem, but with no one giving definitive .c code solution.

I am using Code::Blocks 10.5, mingw32-gcc.exe c compiler, mingw32-g++.exe c++ compiler and dynamic libs linker, ar.exe static libs linker, windres.exe resource compiler and mingw32-make.exe make program. I am creating a 32 bit executable to run on Windows and doing my development on a Windows XP machine.

Best Wishes and thanks if you can help me


3 Years
Discussion Span
Last Post by finston

To print in landscape mode, you can either use a printer feature, or a program like you're talking about, here.

If the printer has a landscape feature, then obviously you want to just send it the code to switch it into landscape mode. That feature is not available on all printers, and the code to activate it, if present, would not be the same for every printer. It should be in the owner's manual.

For a program, you'll want to bring the data you want to print into an array, and then rotate the array either 90° left or 270° to the right.

I have a program that does this rotation - but note that it only rotates arrays that can fit into memory. Larger arrays would need to be rotated in a "block by block" kind of algorithm.

Can you fit your data into one single malloc'd or global array? These are arrays created on the large "heap" memory space. An array created inside a C function is by default, created in a small stack of memory, and should not be used for this.

Looks like you're using FAR memory, so this is Turbo C/C++ with 16 bit compilers? Gruesome! As much as I liked turbo C/C++, it's days are LONG gone - free x32 or x64 C or C++ compilers are out there.

Edit: Now I'm confused - do you use FAR memory (addresses) on your compiler? I thought that was only 16 bit compilers that used it.

I have been using Pelles C, and VERY much enjoy the large flat memory model it gives me. Google it and try it - there is a learning curve for sure, but it's SO worth it. (It also has it's own forum for help).

Edited by Adak


Thanks for the reply. I have found a Microsoft support article about using ExtDeviceMode() to Modify Printer Settings to landscape. I substituted the Handle GetPrinterDC() code, below for the HDC NEAR Get_PrintDC( void ) code, above. It compliled and linked and the .exe now prints in Landscape.

Here is the Handle GetPrinterDC() code

   FUNCTION: GetPrinterDC()

    PURPOSE:  Get hDC for default device according to information in the
              "device" entry in the "windows" section of WIN.INI. Set
              the device context to landscape orientation if supported.

    COMMENTS: Calls ExtDeviceMode() in printer driver to set the device
              context to landscape if supported.

              See the documentation for ExtDeviceMode() and the DEVMODE
              structure for more information.

    RETURNS:  hDC > 0 if success
              hDC = 0 if failure



   HANDLE GetPrinterDC()

    char          pPrintInfo[80];
    LPSTR         lpTemp;
    LPSTR         lpPrintType;
    LPSTR         lpPrintDriver;
    LPSTR         lpPrintPort;
    char          pmodule[32];
    HANDLE        hDriver = 0;
    HANDLE        hDevMode = 0;
    LPDEVMODE     lpDevMode = NULL;
    LPFNDEVMODE   lpfnExtDeviceMode;
    HDC           hDC;
    int           count;

    // Get the default printer information from WIN.ini.
    // The string contains the printer name, driver filename, and port.
    if (!GetProfileString("windows", "Device", (LPSTR)"", pPrintInfo, 80))
        return (NULL);

    // Parse the string we just got from WIN.INI.
    // lpPrintDriver will be the driver filename (for example, HPPCL5MS).
    // lpPrintType will be the printer name (for example, HP Laserjet III).
    // lpPrintPort will be the port (for example, LPT1:).

    lpTemp = lpPrintType = pPrintInfo;
    lpPrintDriver = lpPrintPort = 0;

    while (*lpTemp)
        if (*lpTemp == ',')
            *lpTemp++ = 0;
            while (*lpTemp == ' ')
                lpTemp = AnsiNext(lpTemp);
            if (!lpPrintDriver)
                lpPrintDriver = lpTemp;
                lpPrintPort = lpTemp;
            lpTemp = AnsiNext(lpTemp);

    // Build driver name
    wsprintf (pmodule, "%s.drv",(LPSTR)lpPrintDriver);

    // Load driver
    if ((hDriver = LoadLibrary(pmodule)) > 31)
        // Get a function pointer to the ExtDeviceMode() function.
        // ExtDeviceMode() resides in the driver so we can't call it
        // directly.
        if (lpfnExtDeviceMode = (LPFNDEVMODE)GetProcAddress(hDriver,
           // Get the number of bytes in the full DEVMODE buffer.
           // This includes the device-dependent part at the end
           // of the DEVMODE struct.
           count = lpfnExtDeviceMode(0,
                                     0);    // 0 = get buffer size

           if (count != -1)
               // Allocate storage for the DEVMODE buffer.
               hDevMode = GlobalAlloc(GHND, count);

               if (hDevMode)
                  lpDevMode = (LPDEVMODE)GlobalLock(hDevMode);

                  // Get the current printer settings.
                  count = lpfnExtDeviceMode(0,
                                            lpDevMode,   // Output buffer
                                            DM_OUT_BUFFER); // aka DM_COPY

                  // Check to see if this printer supports changing
                  // the orientation. You should check dmFields
                  // before changing any printer setting.

                  if (lpDevMode->dmFields & DM_ORIENTATION)
                     // Pass lpDevMode as both the input and output
                     // DEVMODE buffers. It is important to pass
                     // in the full DEVMODE from the previous call
                     // to ExtDeviceMode() as the input buffer because
                     // it has been completely initialized by the
                     // driver. If you do not do this, the results
                     // are sporadic--sometimes it works and sometimes
                     // it doesn't depending on the printer driver and
                     // the setting you are trying to change.

                     // Zero out all the fields and then set the bit(s)
                     // for the field(s) we want to change.
                     lpDevMode->dmFields = 0;
                     lpDevMode->dmFields = DM_ORIENTATION;

                     // Change to landscape.
                     lpDevMode->dmOrientation = DMORIENT_LANDSCAPE;

                     // Call ExtDeviceMode() once more to allow the driver
                     // to change the device-dependent portion of the
                     // DEVMODE buffer if it needs to.

                     count = lpfnExtDeviceMode(0,
                                             lpDevMode,  //Output buffer
                                             lpDevMode,  // Input buffer
                                             DM_OUT_BUFFER | DM_IN_BUFFER);

                                             // aka DM_COPY | DM_MODIFY

                     hDC = CreateDC(lpPrintDriver,
                                    (void FAR*)lpDevMode);
                     // The printer doesn't support the field you're
                     // trying to change. Just use the current printer
                     // settings.
                     hDC = CreateDC(lpPrintDriver,
                                    (void FAR*)lpDevMode);
                  return hDC;

               } // end hDevMode
           }  // end count != -1
        } // end lpfnExtDeviceMode != 0
    } // end hDriver > 31

// If we got here, an error has occurred so finish cleanup and return NULL.

    if (hDriver)

    return NULL;

   } // end GetPrinterDC

I hope that this is useful to others

Best Wishes


This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.