File:  [WindowsNT SDKs] / q_a / samples / printer / toolbar.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Thu Aug 9 18:29:19 2018 UTC (7 years, 9 months ago) by root
Branches: msft, MAIN
CVS tags: ntsdk-jun-1992, HEAD
Microsoft Windows NT Build 297 06-28-1992

/******************************************************************************\
*
*  MODULE:      TOOLBAR.C
*
*  PURPOSE:     Implements toobar for PRINTER sample
*
*  FUNTIONS:    ToolbarProc()           - toolbar dlg proc
*               UpdateToolbarCombobox() - inserts printers in toolbar combobox
*               vDrawBitmap()           - draws toolbar buttons
*               iGetBtn()               - retrieves button index
*               vDoBtnCmd()             - implements button-specific code
*               PrintThread()           - printing thread
*
\******************************************************************************/

#include <windows.h>
#include <commdlg.h>
#include <cderr.h>
#include <winspool.h>
#include <string.h>
#include "lookup.h"
#include "printer.h"
#include "paint.h"
#include "toolbar.h"
#include "vars.h"



/************************************************************************\
*
*  FUNCTION:	ToolbarProc (standard dialog procedure INPUTS/RETURNS)
*
*  GLOBAL VARS: hWndToolbar - toolbar window handle
*               DriverName - of current printer
*               DeviceName - of current printer
*               Port       - of current printer
*
\************************************************************************/

BOOL APIENTRY ToolbarProc (HWND hDlg,UINT message,UINT wParam,LONG lParam)
{
  static HBITMAP ahbmUpBtn[MAXBUTTONS], ahbmDnBtn[MAXBUTTONS];

  static int	 iCurrBtn, iLastBtn;

  int i;

  switch (message)
  {
    case WM_INITDIALOG:

      hWndToolbar = hDlg;

      ahbmUpBtn[DID_PRTDLG] = LoadBitmap (hInst, "prtdlgup");
      ahbmUpBtn[DID_PRINT]  = LoadBitmap (hInst, "printup");
      ahbmUpBtn[DID_ENUM]   = LoadBitmap (hInst, "enumup");
      ahbmUpBtn[DID_DEVCAP] = LoadBitmap (hInst, "devcapup");
      ahbmUpBtn[DID_DELTA]  = LoadBitmap (hInst, "deltaup");

      ahbmDnBtn[DID_PRTDLG] = LoadBitmap (hInst, "prtdlgdn");
      ahbmDnBtn[DID_PRINT]  = LoadBitmap (hInst, "printdn");
      ahbmDnBtn[DID_ENUM]   = LoadBitmap (hInst, "enumdn");
      ahbmDnBtn[DID_DEVCAP] = LoadBitmap (hInst, "devcapdn");
      ahbmDnBtn[DID_DELTA]  = LoadBitmap (hInst, "deltadn");

      SetWindowPos (hDlg, HWND_TOP, -1, 0,
		    GetSystemMetrics (SM_CXFULLSCREEN) + 2,
		    TOOLBARHEIGHT, SWP_SHOWWINDOW);
      SetWindowPos (GetDlgItem (hDlg, DID_TOOLBARCOMBO),
		    HWND_TOP, 11*BUTTONWIDTH/2, 6, BUTTONWIDTH*8,
		    BUTTONWIDTH*4, SWP_SHOWWINDOW);

      UpdateToolbarCombobox (hDlg);

      break;

    case WM_PAINT:
    {
      PAINTSTRUCT ps;

      BeginPaint (hDlg, &ps);
      FillRect (ps.hdc, &ps.rcPaint, GetStockObject (GRAY_BRUSH));

      for (i = 0; i < MAXBUTTONS; i++)
	vDrawBitmap (ps.hdc, ahbmUpBtn[i], i*BUTTONWIDTH, 0);

      MoveToEx (ps.hdc, BUTTONWIDTH*5, 0, NULL);
      LineTo   (ps.hdc, BUTTONWIDTH*5, TOOLBARHEIGHT);
      EndPaint (hDlg, &ps);
      break;
    }

    case WM_LBUTTONDOWN:

      if ((iCurrBtn = iGetBtn (lParam)) >= 0)
      {
	HDC hdc = GetDC (hDlg);
	iLastBtn = iCurrBtn;
	vDrawBitmap (hdc, ahbmDnBtn[iCurrBtn], iCurrBtn*BUTTONWIDTH, 0);
	ReleaseDC (hDlg, hdc);
	SetCapture (hDlg);
      }
      break;

    case WM_MOUSEMOVE:

      if (GetCapture() == hDlg)
      {
	HDC hdc = GetDC (hDlg);

	if ((iCurrBtn = iGetBtn (lParam)) >= 0 && iCurrBtn != iLastBtn)

	  vDrawBitmap (hdc, ahbmDnBtn[iCurrBtn], iCurrBtn*BUTTONWIDTH, 0);

	if ((iCurrBtn != iLastBtn) && (iLastBtn >= 0))

	  vDrawBitmap (hdc, ahbmUpBtn[iLastBtn], iLastBtn*BUTTONWIDTH, 0);

	ReleaseDC (hDlg, hdc);
	iLastBtn = iCurrBtn;
      }
      break;

    case WM_LBUTTONUP:

      if (GetCapture() == hDlg)
      {
	if ((iCurrBtn = iGetBtn (lParam)) >= 0)
	{
	  HDC hdc = GetDC (hDlg);

	  vDrawBitmap (hdc, ahbmUpBtn[iCurrBtn], iCurrBtn*BUTTONWIDTH, 0);

	  ReleaseDC (hDlg, hdc);

	  vDoBtnCmd (iCurrBtn);
	}
	ReleaseCapture ();
      }
      break;

    case WM_COMMAND:

      switch (LOWORD(wParam))
      {
	case DID_TOOLBARCOMBO:

          switch (HIWORD(wParam))
	  {
	    case CBN_SELCHANGE:
	    {
	      DWORD dwIndex;
	      char  buf[256];

	      /****************************************************************\
              *  User clicked on one of the items in the toolbar combobox;
              *  figure out which item, then parse the text apart and
              *  copy it to the DriverName, DeviceName, and Port
              *  variables.
	      \****************************************************************/

              dwIndex = (DWORD) SendMessage ((HWND) lParam,
                                             CB_GETCURSEL, 0, 0);
              SendMessage ((HWND) lParam, CB_GETLBTEXT, dwIndex,
                           (LONG) buf);

              if (!strcmp (buf, "Display"))
              {
                strcpy (DeviceName, "Display");
                EnableWindow (GetDlgItem (hDlg, DID_PRINT), FALSE);
              }
              else
              { int i = -1, j = 0;

                while (buf[++i] != ';') DeviceName[i] = buf[i];
                DeviceName[i] = '\0';
                while (buf[++i] != ';') Port[j++] = buf[i];
                Port[j] = '\0';
                j = 0;
                while (buf[++i] != '\0') DriverName[j++] = buf[i];
                DriverName[j] = '\0';
                EnableWindow (GetDlgItem (hDlg, DID_PRINT),    TRUE);
              }
              break;
            }
          }
          break;
      }
      break;

    default:

      return FALSE;
  }
  return (TRUE);
}



/******************************************************************************\
*
*  FUNCTION:    UpdateToolbarCombobox
*
*  GLOBAL VARS: hWndToolbar - toolbar window handle
*
*  LOCAL VARS:  dwEnumFlags   - which printers to enumerate
*               dwBytesNeeded - # of bytes required to contain
*                               PRINTER_INFO_2 info for all printers
*               pwPrtRet      - number of printers (info) returned
*               pPrtInfo2     - pointer to PRINTER_INFO_2 structs
*               i             - loop variable
*
*  COMMENTS:    The idea here is to enumerate all printers & list them in
*               then combobox in the form: "DEVICE_NAME;PORT;DRIVER_NAME".
*               Then later, when a user selects one of these, we just
*               query out the string & parse it apart, sticking the
*               appropriate parts into the DriverName, DeviceName, and
*               Port variables.
*
*               Also, the "Display" option is added to the combobox so
*               that user can get DevCaps info about it.
*
\******************************************************************************/

void UpdateToolbarCombobox (HWND hDlg)
{
  DWORD            dwFlags = PRINTER_ENUM_FAVORITE | PRINTER_ENUM_LOCAL;
  LPPRINTER_INFO_2 pPrinters;
  DWORD		   cbPrinters;
  DWORD		   cReturned, i;
  char		   buf[256];

  EnumPrinters (dwFlags, NULL, 2, NULL, 0, &cbPrinters,
                &cReturned);

  pPrinters = (LPPRINTER_INFO_2) LocalAlloc (LPTR, cbPrinters + 4);

  EnumPrinters (dwFlags, NULL, 2, (LPBYTE) pPrinters,
                cbPrinters, &cbPrinters, &cReturned);

  SendDlgItemMessage (hDlg, DID_TOOLBARCOMBO, CB_RESETCONTENT, 0, 0);

  for (i = 0; i < cReturned; i++)
  {
    /**************************************************************************\
    * for each printer in the PRINTER_INFO_2 array: build a string that
    * looks like "DEVICE_NAME;PORT;DRIVER_NAME"
    \**************************************************************************/

    strcpy (buf, (pPrinters + i)->pPrinterName);
    strcat (buf, ";");
    strcat (buf, (pPrinters + i)->pPortName);
    strcat (buf, ";");
    strcat (buf, (pPrinters + i)->pDriverName);

    SendDlgItemMessage (hDlg, DID_TOOLBARCOMBO, CB_INSERTSTRING, (UINT)-1,
                        (LONG) buf);
  }

  SendDlgItemMessage (hDlg, DID_TOOLBARCOMBO, CB_INSERTSTRING, (UINT)-1,
                      (LONG) "Display");

  SendDlgItemMessage (hDlg, DID_TOOLBARCOMBO, CB_SELECTSTRING, (UINT)-1,
		      (LONG) buf);

  SendMessage (hDlg, WM_COMMAND,
               (UINT) MAKELONG (DID_TOOLBARCOMBO, CBN_SELCHANGE),
               (LONG) GetDlgItem (hDlg, DID_TOOLBARCOMBO));
}



/******************************************************************************\
*
*  FUNCTION:	vDrawBitmap
*
*  INPUTS:      hdc    - device context in which to draw bitmap
*               hbm    - handle of bitmap to draw
*               xStart - x-coordinate of upper-left corner of destination
*                        rectangle
*               yStart - y-coordinate of upper-left corner of destination
*                        rectangle
*
*  LOCAL VARS:  bm     - BITMAP info of "hbm"
*               hdcMem - a memory DC used for blt-ing
*
*  COMMENTS:    Draws a bitmap "hbm" in a DC "hdc" given the upper-left
*               corner "xStart,yStart" of a destination rectangle.
*
\******************************************************************************/

void vDrawBitmap (HDC hdc, HBITMAP hbm, int xStart, int yStart)
{
  BITMAP bm;
  HDC    hdcMem;

  hdcMem = CreateCompatibleDC (hdc);
  SelectObject (hdcMem, hbm);
  SetMapMode (hdcMem, GetMapMode(hdc));

  GetObject (hbm, sizeof(BITMAP), (LPSTR)&bm);
  BitBlt (hdc, xStart, yStart, bm.bmWidth, bm.bmHeight,
          hdcMem, 0, 0, SRCCOPY);

  DeleteDC(hdcMem);
}



/******************************************************************************\
*
*  FUNCTION:    iGetBtn
*
*  INPUTS:      lParam - lParam of a WM_MOUSEMOVE/WM_LBUTTON* msg
*
*  RETURNS:     Index of button, or
*               -1 if no button in specified position
*
*  LOCAL VARS:  xPos - x position of mouse
*
*  COMMENTS:    Given an x,y position (in an lParam) finds the corresponding
*               toolbar button
*
\******************************************************************************/

int iGetBtn (LONG lParam)
{
  int xPos = (int) LOWORD (lParam), i;

  for (i = 1; i <= MAXBUTTONS; i++)

    if (xPos <= i*BUTTONWIDTH)

      return i-1;

  return -1;
}



/******************************************************************************\
*
*  FUNCTION:    vDoBtnCmd
*
*  INPUTS:      cmd - index of which button pressed
*
*  GLOBAL VARS: hWndMain - main app window handle
*               hInst    - app instance
*
*  COMMENTS:    Implements button-specific code
*
\******************************************************************************/

void vDoBtnCmd (int cmd)
{
  switch (cmd)
  {
    case DID_PRTDLG:
    case DID_PRINT:
    {
      LPVOID lpArg;
      DWORD  threadId;

      /************************************************************************\
      *  Start a print thread, passing it either NULL or 0xffffffff
      *  if we want to call PrintDlg or do a CreateDC, respectively.
      \************************************************************************/

      if (cmd == DID_PRINT)
	lpArg = (LPVOID) 0xffffffff;
      else
	lpArg = NULL;

      if (!CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) PrintThread,
			 lpArg, NULL, &threadId))
	MessageBox (hWndMain,
		    "MainWndProc(): Error creating print thread",
		    "Err! - PRINTX", MB_OK | MB_ICONHAND);
      break;
    }
    case DID_ENUM:

      DialogBox (hInst, "AboutBox", hWndMain, (DLGPROC)EnumDlgProc);
      break;

    case DID_DEVCAP:

      DialogBox (hInst, "AboutBox", hWndMain, (DLGPROC)DevCapDlgProc);
      break;

    case DID_DELTA:

      UpdateToolbarCombobox (hWndToolbar);
      break;
  }
}



/******************************************************************************\
*
*  FUNCTION:    PrintThread
*
*  INPUTS:      arg - if nonzero then open a printer DC using CreateDC,
*                     else call PRintDlg() to get a printer DC.
*
*  GLOBAL VARS: DriverName - of current printer
*               DeviceName - of current printer
*               Port       - of current printer
*               hwndMain   - main app window handle
*               iMapMode   - current map mode
*
*  LOCAL VARS:  hdc  - printer DC
*               di   - required struct for calling PrintDlg()
*               rect - scratch rectangle
*
\******************************************************************************/

void PrintThread (LPVOID arg)
{
  HDC	  hdc;
  DOCINFO di;
  RECT    rect;

  if (arg)
  {
    if (!strcmp (DeviceName, "Display"))
    {
      MessageBox (hWndMain, "You must select a printer",
                  "PRINTER.EXE: Error creating DC", MB_OK);
      return;
    }
    else if (!(hdc = CreateDC (DriverName, DeviceName, Port, NULL)))
    {
      MessageBox (hWndMain, "PrintThread(): CreateDC() failed",
                  "Err! - PRINTX", MB_OK);
      return;
    }
  }
  else
  {
    PRINTDLG  pd;

    /**************************************************************************\
    *  Initialize a PRINTDLG struct and call PrintDlg to allow user to
    *  specify various printing options...
    \**************************************************************************/

    memset (&pd, 0, sizeof(PRINTDLG));

    pd.lStructSize = sizeof(PRINTDLG);
    pd.hwndOwner   = hWndMain;
    pd.Flags	   = PD_RETURNDC | PD_PRINTSETUP;
    pd.hInstance   = NULL;

    PrintDlg(&pd);
    hdc = pd.hDC;
    if (pd.hDevMode)
      GlobalFree (pd.hDevMode);
    if (pd.hDevNames)
      GlobalFree (pd.hDevNames);
    if (!hdc)
      return;
  }

  SetMapMode (hdc, iMapMode);
  rect.right  = GetDeviceCaps (hdc, HORZRES);
  rect.bottom = GetDeviceCaps (hdc, VERTRES);
  di.cbSize = sizeof(DOCINFO);
  di.lpszDocName = "print test";
  di.lpszOutput  = NULL;

  StartDoc  (hdc, &di);
  StartPage (hdc);
    Paint   (hdc, &rect);
  EndPage   (hdc);
  EndDoc    (hdc);
  DeleteDC  (hdc);
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.