Link to home
Start Free TrialLog in
Avatar of midnightexpress
midnightexpressFlag for United States of America

asked on

Win95 Printer status polling

I am looking for a true "C" Wizard to answer, with(hopefully) source code examples.

I am looking for a "C"(NO MFC Stuff)  programming that polls a printer that Windows 9x has connected to it and it is its defaulted printer.  The polling routines should do:
   1) polling for printer status
   2) Number of print jobs that are awaiting to be printed.
   3) And cancel any awaiting print jobs.

These routines should work thru the Windows 9x evironment and be device driver independent.   I was supposely told that it could be done via MS's DDK package - which I know nothing about.

 Can this be done?  And help me out please.

  Thanks!!!

  Midnight Express

  RSVP Please
Avatar of mcrider
mcrider

midnightexpress,

Please go to https://www.experts-exchange.com/jsp/qShow.jsp?ta=commspt&qid=10243332 
as soon as you read this...


Cheers!
Avatar of midnightexpress

ASKER

doing as linda and ryanvs has recommeded.
I'm a little busy at the moment, but I will post my file later tonight.  I'm glad we can finally solve this mishap!  Thanks!
Yes, Thanks, Till then.

 Midnightexpress
Hey RYANVS,
                        Dec 18th, 1999

It's been a Long time, and haven't heard a word from you in a while.  What is the status?  Is it lookin' good?

 Midnightexpress

Hi Midnightexpress,

I apologize for not writing sooner, but it has been extremely busy at work.  I do have a solution that works as far as I can tell.  You can get the printer status, the job count, and delete individual jobs on 95/98/NT.  I tested the delete all jobs on NT and it said permission denied even though I had full admin rights, so that was strange but apart from that it looks good.  So I was documenting the file and adding more comments, except I had to stop to try and meet a deadline for work.

Unfortunately, I had to rush and try to get everything ready for vacation (which I'm on right now!) and I was so busy that I never got a chance to post the file.  And since I don't have the file with me I can't post it until Jan. 3 or 4.  Sorry!

Well I hope you have a good time during the holidays and I will post the file when I get back.  Thanks!
Okay,  
  I understand that you have a life of your own and that I will have to be patience and mind my manners.  So when you get back from your well deserved vacation,  drop me an email when you are ready - and we'll work things out then.  As for me, I will be working(it seems like working is an occupational hazard).

 Midnightexpress.
Hello, Ryanvs:

 How was the Vacaction? Kinda of relaxing? Hope all went well.

  Thanks,

  Midnightexpress
ASKER CERTIFIED SOLUTION
Avatar of ryanvs
ryanvs

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Here are some of the files I used in a project to test the program.

The project includes the following files:
  Header Files
    Main.h
    PrinterPoll.h
  Source Files
    Main.c
    PrinterPoll.c
  Resouce Files
    PrinterPoll.rc

And it had a menu that looked like this:
  Printer
    "Select &Printer", IDM_SELECTPRINTER
    --
    "&Delete Job", IDM_DELETEJOB
    "Purge &All Jobs", IDM_PURGEPRINTER
    --
    "&Refresh", IDM_REFRESHPRINTER
    --
    "E&xit", IDM_EXIT

You need to link to the following libraries:
  kernel32.lib
  user32.lib
  gdi32.lib
  shell32.lib
  winspool.lib   Print Library
  comctl32.lib   used ListView
  comdlg32.lib   Intended to use, but never finished

Good Luck!


// Main.h : include file for standard system include files,
//  or project specific include files that are used frequently, but
//      are changed infrequently
//

#if !defined(MAIN_H__INCLUDED_)
#define MAIN_H__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#define WIN32_LEAN_AND_MEAN            // Exclude rarely-used stuff from Windows headers

#include <windows.h>
#include <tchar.h>


#endif // !defined(MAIN_H__INCLUDED_)




This is the resource file: PrinterPoll.rc

//Microsoft Developer Studio generated resource script.
//
#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"

/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS

/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32

/////////////////////////////////////////////////////////////////////////////
//
// Menu
//

IDR_PRINTMENU MENU DISCARDABLE
BEGIN
    POPUP "Printer"
    BEGIN
        MENUITEM "Select &Printer",             IDM_SELECTPRINTER
        MENUITEM SEPARATOR
        MENUITEM "&Delete Job",                 IDM_DELETEJOB
        MENUITEM "Purge &All Jobs",             IDM_PURGEPRINTER
        MENUITEM SEPARATOR
        MENUITEM "&Refresh",                    IDM_REFRESHPRINTER
        MENUITEM SEPARATOR
        MENUITEM "E&xit",                       IDM_EXIT
    END
END


#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//

1 TEXTINCLUDE DISCARDABLE
BEGIN
    "resource.h\0"
END

2 TEXTINCLUDE DISCARDABLE
BEGIN
    "#include ""afxres.h""\r\n"
    "\0"
END

3 TEXTINCLUDE DISCARDABLE
BEGIN
    "\r\n"
    "\0"
END

#endif    // APSTUDIO_INVOKED

#endif    // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////



#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//


/////////////////////////////////////////////////////////////////////////////
#endif    // not APSTUDIO_INVOKED







// Main.c: Defines the entry point for the application.
//

#include "Main.h"
#include "Resource.h"
#include "PrinterPoll.h"
#include <commctrl.h>
#include <commdlg.h>


// Timer for periodically refreshing printer status
#define ID_TIMER    1


// Window Procedure Prototype
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
BOOL             CreatePrintView(HWND, HINSTANCE );
void             RefreshPrintItems();


// Global Variables
static PRINTERPOLL g_prntpoll;
static HWND        g_hwndPrintView;
static HINSTANCE   g_hInstance;


// Main Function
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
  static char           szAppName[] = "PrinterPoll";
  static char           szTitle[]   = "Printer Poll App";
  HWND                  hwnd;
  MSG                   msg;
  WNDCLASSEX            wndclass;
  INITCOMMONCONTROLSEX  iccex;

  // Initialize Printer List View
  g_hwndPrintView = NULL;

  // Initialize Common Controls: ListView
  iccex.dwSize  = sizeof(iccex);
  iccex.dwICC   = ICC_LISTVIEW_CLASSES;
  InitCommonControlsEx(&iccex);

  // Initialize Window Class
  ZeroMemory(&wndclass, sizeof(wndclass));
  wndclass.cbSize         = sizeof(wndclass);
  wndclass.style          = CS_HREDRAW | CS_VREDRAW;
  wndclass.lpfnWndProc    = WndProc;
  wndclass.cbClsExtra     = 0;
  wndclass.cbWndExtra     = 0;
  wndclass.hInstance      = hInstance;
  wndclass.hIcon          = NULL;
  wndclass.hIconSm        = NULL;
  wndclass.hCursor        = LoadCursor(NULL, IDC_ARROW);
  wndclass.hbrBackground  = (HBRUSH) GetStockObject(WHITE_BRUSH);
  wndclass.lpszMenuName   = MAKEINTRESOURCE(IDR_PRINTMENU);
  wndclass.lpszClassName  = szAppName;

  // Save Global Instance
  g_hInstance = hInstance;

  // Create Window
  RegisterClassEx( &wndclass );
  hwnd = CreateWindow(szAppName,
                      szTitle,
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      NULL,
                      NULL,
                      hInstance,
                      NULL
  );

  ShowWindow(hwnd, nCmdShow);
  UpdateWindow(hwnd);

  while (GetMessage(&msg, NULL, 0, 0))
  {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }

  return msg.wParam;
}

// Window Procedure Function
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
  static BOOL bTryPrinter = FALSE;
  static int  nRetries    = 0;
  static int  cx, cy;

  static PRINTDLG pd;
  LPDEVNAMES  hDevNames;
  LPDEVMODE   hDevMode;
  DWORD       dwBytes;
  TCHAR      *szName;

  PAINTSTRUCT ps;
  HDC         hdc;


  HMENU       hMenu;
  LVITEM      lvi;
  int         nIndex;
  int         i;

  switch (iMsg)
  {
  case WM_COMMAND:
    hMenu = GetMenu(hwnd);
    switch ( LOWORD(wParam) )
    {
    case IDM_SELECTPRINTER:
      MessageBox(hwnd, _T("This does not work yet..."), _T("Printer Poll App"), MB_OK);
      break;

      ZeroMemory(&pd, sizeof(pd));
      pd.lStructSize = sizeof(pd);
      pd.hwndOwner   = hwnd;
      pd.Flags       = PD_PRINTSETUP;

      // Show Print Setup Dialog
      if ( PrintDlg(&pd) )
      {
        // Close current printer
        CleanupPrinterPoll(&g_prntpoll);

        // Copy Printer Name
        if ( !pd.hDevNames )
          return 0;

        hDevMode = (LPDEVMODE) pd.hDevMode;
        hDevNames = (LPDEVNAMES) pd.hDevNames;
        szName = (TCHAR *) (hDevNames + hDevNames->wDriverOffset);
        dwBytes = _tcsclen(szName) + sizeof(TCHAR);
        g_prntpoll.szName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwBytes);
        if ( !g_prntpoll.szName ) return FALSE;
        _tcscpy(g_prntpoll.szName, szName);

        GetPrinterStatus(&g_prntpoll);
        GetPrintAllJobsInfo(&g_prntpoll);
      }

      break;

    case IDM_DELETEJOB:
      // Delete Selected Print Job
      nIndex = ListView_GetNextItem(g_hwndPrintView, -1, LVNI_SELECTED);
      if (nIndex >= 0)
      {
        lvi.mask = LVIF_PARAM;
        lvi.iItem = nIndex;
        lvi.iSubItem = 0;
        ListView_GetItem(g_hwndPrintView, &lvi);
        for (i = 0; i < (int) g_prntpoll.dwJobCount; ++i)
        {
          if ((DWORD) lvi.lParam == g_prntpoll.pJobInfo1[i].JobId)
          {
            DeletePrintJob(&g_prntpoll, lvi.lParam);
            return 0;
          }
        }
      }
      return 0;

    case IDM_PURGEPRINTER:
      // Delete All Print Jobs
      DeleteAllPrintJobs(&g_prntpoll);
      return 0;

    case IDM_REFRESHPRINTER:
      ListView_DeleteAllItems(g_hwndPrintView);
      RefreshPrintItems();
      return 0;

    case IDM_EXIT:
      SendMessage(hwnd, WM_CLOSE, 0, 0L);
      return 0;
    }
    break;

  case WM_CREATE:
    CreatePrintView(hwnd, g_hInstance);

    ZeroMemory(&g_prntpoll, sizeof(g_prntpoll));
    GetDefaultPrinterName(&g_prntpoll);

    SetTimer(hwnd, ID_TIMER, 1000, NULL);
    return 0;

  case WM_PAINT:
    hdc = BeginPaint(hwnd, &ps);
    EndPaint(hwnd, &ps);
    return 0;

  case WM_SIZE:
    cx = LOWORD(lParam);
    cy = HIWORD(lParam);
    MoveWindow(g_hwndPrintView, 0, 0, cx, cy, TRUE);
    return 0;

  case WM_TIMER:
    if ( !bTryPrinter )
    {
      bTryPrinter = TRUE;
      GetPrinterStatus(&g_prntpoll);
      GetPrintAllJobsInfo(&g_prntpoll);
      RefreshPrintItems();
      bTryPrinter = FALSE;
    }
    return 0;

  case WM_DESTROY:
    KillTimer(hwnd, ID_TIMER);
    CleanupPrinterPoll(&g_prntpoll);
    PostQuitMessage(0);
    return 0;
  }

  return DefWindowProc(hwnd, iMsg, wParam, lParam);
}

BOOL CreatePrintView(HWND hwndParent, HINSTANCE hInstance)
{
  TCHAR    szDoc[]    = _T("Document");
  TCHAR    szStatus[] = _T("Status");
  LVCOLUMN lvc;
  int      nResult;

  g_hwndPrintView = CreateWindowEx(
      WS_EX_CLIENTEDGE,
      WC_LISTVIEW,
      NULL,
      LVS_REPORT |
      WS_CHILD   |
      WS_VISIBLE |
      WS_CLIPSIBLINGS,
      0, 0, 0, 0,
      hwndParent,
      NULL,
      hInstance,
      NULL
  );

  if (g_hwndPrintView == NULL)
    return FALSE;

  lvc.mask = LVCF_TEXT | LVCF_WIDTH;
  lvc.cx = 120;

  // Column 0
  lvc.pszText = szDoc;
  lvc.cchTextMax = lstrlen(szDoc) + 1;
  nResult = ListView_InsertColumn(g_hwndPrintView, 0, &lvc);

  // Column 1
  lvc.pszText = szStatus;
  lvc.cchTextMax = lstrlen(szStatus) + 1;
  nResult = ListView_InsertColumn(g_hwndPrintView, 1, &lvc);

  return TRUE;
}

void RefreshPrintItems()
{
  LVITEM lvi;
  BOOL bFound;
  int nResult,
      i, j;

  // Check number of print jobs
  if (g_prntpoll.dwJobCount == 0)
  {
    // Delete all visible print jobs in ListView
    i = ListView_GetItemCount(g_hwndPrintView);
    if (i > 0)
      ListView_DeleteAllItems(g_hwndPrintView);
  }
  else
  {
    lvi.pszText    = NULL;
    lvi.cchTextMax = 0;

    // Add Job Information to ListView
    for (i = 0; i < (int) g_prntpoll.dwJobCount; ++i)
    {
      lvi.mask = LVIF_PARAM;
      bFound = ListView_GetItem(g_hwndPrintView, &lvi);
      if (bFound && (DWORD) lvi.lParam == g_prntpoll.pJobInfo1[i].JobId)
      {
        // Update Document, Status, etc.
      }
      else
      {
        // Add/Insert Document, Status, etc.
        lvi.mask = LVIF_TEXT | LVIF_PARAM;
        lvi.iItem = i;
        lvi.iSubItem = 0;
        lvi.pszText = g_prntpoll.pJobInfo1[i].pDocument;
        lvi.cchTextMax = lstrlen(lvi.pszText);
        lvi.lParam = g_prntpoll.pJobInfo1[i].JobId;
        nResult = ListView_InsertItem(g_hwndPrintView, &lvi);
      }
    }

    // Delete any documents beyond the stopping point on the ListView
    nResult = ListView_GetItemCount(g_hwndPrintView);
    for (j = i; j < nResult; ++j)
      ListView_DeleteItem(g_hwndPrintView, j);
  }

}


Thanks RYANVS:   1/12/Y2K

Wow!, It's my turn now.

Midnightexpress... T.T.

I'll RSVP if need be.