LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Print 2 panels with one comfirm?

Solved!
Go to solution

I want to print 2 panels, one portrait, one landcape.

Is it possible to comfirm one, print to the same printer ?

 

PrintPanel doesn't return the printer used.

 

George Zou
0 Kudos
Message 1 of 12
(4,901 Views)

@zou wrote:

I want to print 2 panels, one portrait, one landcape.

Is it possible to comfirm one, print to the same printer ?

 

PrintPanel doesn't return the printer used.

 


Well, it does give the user a printer selector box if you pass '1' as the last parameter.

0 Kudos
Message 2 of 12
(4,885 Views)

Then user has to comfirm twice.  That's what I try to avoid.

 

George Zou
0 Kudos
Message 3 of 12
(4,878 Views)

Call it the 2nd time with 0...

 

But why do you need it both in landscape and portrait ? For maximal page occupancy ? Can't you just get the heigh and width of the panel and print in landscape if Width>Height and portrait otherwise ?

0 Kudos
Message 4 of 12
(4,873 Views)

> Call it the 2nd time with 0...

Then it prints to the default printer.

Might not be the one user wants.

 

> But why do you need it both in landscape and portrait ?

I'm printing TWO different panels.

So I have to call prent panel twice.

There fore two comfirm ?!

 

George Zou
0 Kudos
Message 5 of 12
(4,867 Views)
Solution
Accepted by zou

You can enumerate printers in the system by using some Win32API calls this way (here I am filling a listbox with printer names on a button callback):

 

int CVICALLBACK EnumeratePrinters (int panel, int control, int event,
		void *callbackData, int eventData1, int eventData2)
{
  int            error = 0;
  int            i, numPrt, needed;
  PRINTER_INFO_1 *pi = NULL;
  char           *z = NULL;

  if (event != EVENT_COMMIT) return 0;

  //BOOL EnumPrinters(
  //	DWORD Flags,         // printer object types
  //	LPTSTR Name,         // name of printer object
  //	DWORD Level,         // information level
  //	LPBYTE pPrinterEnum, // printer information buffer
  //	DWORD cbBuf,         // size of printer information buffer
  //	LPDWORD pcbNeeded,   // bytes received or required
  //	LPDWORD pcReturned   // number of printers enumerated
  //);

  // Get required memory size
  EnumPrinters (
    PRINTER_ENUM_LOCAL,      // enumerate local printers
    NULL,                    // name of printer object
    1,                       // general printer info
    NULL,                    // printer information buffer
    0,                       // size of printer information buffer
    &needed,                 // bytes required
    NULL                     // number of printers enumerated
  );

  // Allocate memory
  z = malloc (needed);
  memset (z, 0, needed);

  // Enumerate printers
  if (!EnumPrinters (
    PRINTER_ENUM_LOCAL,      // enumerate local printers
    NULL,                    // name of printer object
    1,                       // general printer info
    z,                       // printer information buffer
    needed,                  // size of printer information buffer
    &needed,                 // bytes required
    &numPrt                  // number of printers enumerated
  )) {
    MessagePopup ("Error", "Error in EnumPrinters.");
    error = GetLastError ();
    goto Error;
  }

  // Allocate structured memory
  pi = calloc (numPrt, sizeof (PRINTER_INFO_1));
  memcpy (pi, z, numPrt * sizeof (PRINTER_INFO_1));

  for (i = 0; i < numPrt; i++) {
    InsertListItem (panel, PANEL_LISTBOX, -1, pi[i].pName, i);
  }

  SetInputMode (panel, PANEL_PRINT, 1);

Error:
  if (z) free (z);
  if (pi) free (pi);
  return 0;
}

 

The list of printers can be shown in a "options" panel where the user can select the printer to be used, next you can print with that printer this way:

 

int CVICALLBACK PrintSome (int panel, int control, int event,
      void *callbackData, int eventData1, int eventData2)
{
  int  idx;
  char name[64];

  if (event != EVENT_COMMIT) return 0;

  GetCtrlIndex (panel, PANEL_LISTBOX, &idx);
  GetLabelFromIndex (panel, PANEL_LISTBOX, idx, name);

  SetPrintAttribute (ATTR_PRINTER_NAME, name);   // Specify which printer to use
  SetPrintAttribute (ATTR_PRINT_AREA_WIDTH, VAL_INTEGRAL_SCALE);
  SetPrintAttribute (ATTR_PRINT_AREA_HEIGHT, VAL_USE_ENTIRE_PAPER);

  PrintPanel (panel, "", 1, VAL_FULL_PANEL, 1);

  return 0;
}

 

Nevertheless, this is somewhat not intuitive and you need to dig and study some of Win32APIs to obtain it. You may want to support this CVI idea for an independent command that displays the print dialog.

 



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
Message 6 of 12
(4,855 Views)

I forgot to say that:

 

  • You must #include <windows.h> to all source code where you are using this function
  • You must add winspool.lib to your project
  • You must delete "/DWIN32_LEAN_AND_MEAN" from the compiler defines in Options >> Build Options... panel or #undef the same string in source code before defining windows.h


Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
Message 7 of 12
(4,850 Views)

> SetPrintAttribute (ATTR_PRINTER_NAME, name);   // Specify which printer to use

This function is great !

 

I was working on PrintDlg last night.

Try to alter the default printer 😉

Enum printer is better.

 

I've some Windows API experience.

 

> You must delete "/DWIN32_LEAN_AND_MEAN"

Why is that ?

 

 

George Zou
0 Kudos
Message 8 of 12
(4,837 Views)

The amount of resources added to the IDE when including windows API can considerably increment compile time. For this reason that macro is provides: it defines a reasonable subset of the APIs which is worth for the majority of applications. In this particular case you cannot use it as it masks out commdlg.h from the compile, so you are missing necessary definitions and you get compile errors.



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
Message 9 of 12
(4,824 Views)

By the way, the NI Report function panel (nireport.fp) included with CVI has a function for getting the names of all the printers:

 

int NIReport_GetPrinters (char **Default_Printer, char ***All_Printers);

 

--
Martin
Certified CVI Developer
0 Kudos
Message 10 of 12
(4,802 Views)