mbrandt Posted August 22, 2003 Posted August 22, 2003 I have been attempting to trap printer events via the FindFirstPrinterChangeNotification and the FindNextPrinterChangeNotifcation. I am able to trap the event properly if a new job is added to the print queue, but I am unable to retrieve the PRINTER_NOFIFY_INFO and the PRINTER_NOTIFY_INFO_DATA properly after calling the FindNextPrinterChangeNotification. I have been looking at some of the samples in VB, but I am unable to get them to successfully work in C#. I believe the problem may be related to how I have my PRINTER_NOTIFY_INFO wrapper class layed out, in particular its association with the PRINTER_NOTIFY_INFO_DATA class. Any help is greatly appreciated....I have been struggling with this for more hours than I can count. Here is the code....... [structLayout(LayoutKind.Sequential)] public class PrinterNotifyOptionsType { public Int16 Type; public Int16 wReserved0; public Int32 dwReserved1; public Int32 dwReserved2; public Int32 FieldCount; public IntPtr pFields; public PrinterNotifyOptionsType(PrinterConstants.ChangeNotificationTypes printerNotificationTypes) { this.Type = (short) printerNotificationTypes; pFields = Marshal.AllocHGlobal((16 * 2) - 1); Marshal.WriteInt16(pFields, 0, (short) PrinterConstants.PrinterNotifyField.PRINTER_NOTIFY_FIELD_CJOBS); FieldCount = 1; } } [structLayout(LayoutKind.Sequential)] public class PrinterNotifyOptions { public Int32 dwVersion; public Int32 dwFlags; public Int32 Count; public IntPtr lpTypes; public PrinterNotifyOptions() { dwVersion = 2; Count = 1; PrinterNotifyOptionsType pNotifyType = new PrinterNotifyOptionsType (PrinterConstants.ChangeNotificationTypes.PRINTER_NOTIFY_TYPE); lpTypes = Marshal.AllocHGlobal(Marshal.SizeOf(pNotifyType)); Marshal.StructureToPtr(pNotifyType, lpTypes, true); } } [structLayout(LayoutKind.Sequential)] public class PRINTER_NOTIFY_INFO_DATA { public Int16 wType; public Int16 wField; public Int32 dwReserved; public Int32 dwId; public Int32 cbBuff; public Int32 pBuff; } [structLayout(LayoutKind.Sequential)] public class PrinterNotifyInfoData { private PRINTER_NOTIFY_INFO_DATA printerNotifyInfoData = new PRINTER_NOTIFY_INFO_DATA(); public PrinterNotifyInfoData(IntPtr lpAddress) { if ( lpAddress.ToInt32() != 0) { Marshal.PtrToStructure(lpAddress, printerNotifyInfoData); } } public Int16 Flags { get { return printerNotifyInfoData.wField; } set { printerNotifyInfoData.wField = value; } } } [structLayout(LayoutKind.Sequential)] public class PRINTER_NOTIFY_INFO { public Int16 wType; public Int16 wField; public Int32 dwReserved; public Int32 version; public Int32 Flags; public Int32 Count; } [structLayout(LayoutKind.Sequential)] public class PrinterNotifyInfo { private PRINTER_NOTIFY_INFO printerNotifyInfo = new PRINTER_NOTIFY_INFO(); public PrinterNotifyInfo(IntPtr lpAddress) { if ( lpAddress.ToInt32() != 0) { Marshal.PtrToStructure(lpAddress, printerNotifyInfo); int lOffset = lpAddress.ToInt32() + Marshal.SizeOf(printerNotifyInfo); for (int nInfoDataItem = 0; nInfoDataItem < 2; nInfoDataItem++) { PrinterNotifyInfoData printerNotifyInfoData = new PrinterNotifyInfoData(new IntPtr(lOffset)); lOffset = lOffset + Marshal.SizeOf(printerNotifyInfoData); } } } public Int32 Flags { get { return printerNotifyInfo.Flags; } set { printerNotifyInfo.Flags = value; } } public Int32 Count { get { return printerNotifyInfo.Count; } set { printerNotifyInfo.Count = value; } } } //Registering for the event............. IntPtr printerHandle = new IntPtr(); IntPtr eventHandle; // Get the printer handle by opening the printer if (Win32.OpenPrinter( printer.Name, ref printerHandle, IntPtr.Zero )) { //Specify what we want to be notified about... printerNotifyOptions = new PrinterNotifyOptions(); Int32 flags = (int) PrinterConstants.PrinterChangeNotifications. PRINTER_CHANGE_ADD_JOB; // register the object for events eventHandle = Win32.FindFirstPrinterChangeNotification( printerHandle, flags, 0, printerNotifyOptions); if (!eventHandle.Equals(null)) { printer.EventHandle = eventHandle; this.ListenForEvents(); } else { Marshal.GetLastWin32Error()); } } //Get the event details long evtTriggered = new long(); PrinterNotifyInfo printerNotifyInfo; IntPtr pPrinterNotifyInfo = Marshal.AllocHGlobal( Marshal.SizeOf(typeof(PrinterNotifyInfo)) ); //A printer change notification has occured..... if (Win32.FindNextPrinterChangeNotification(printer.EventHandle, evtTriggered, printerNotifyOptions, pPrinterNotifyInfo) ) { if (pPrinterNotifyInfo.ToInt32() != 0) { printerNotifyInfo = new PrinterNotifyInfo(pPrinterNotifyInfo); //If the flags indicate that there was insufficient space to store all //the changes we need to ask again if ( (printerNotifyInfo.Flags & PrinterConstants.PRINTER_NOTIFY_INFO_DISCARDED) == 0) { printerNotifyOptions.dwFlags = printerNotifyOptions.dwFlags | PrinterConstants.PRINTER_NOTIFY_OPTIONS_REFRESH; evtTriggered = new long(); pPrinterNotifyInfo = new IntPtr(); Int32 count = printerNotifyInfo.Count; pPrinterNotifyInfo = Marshal.AllocHGlobal( (Marshal.SizeOf(typeof(PrinterNotifyInfo))) + ((Marshal.SizeOf(typeof(PrinterNotifyInfoData))) * printerNotifyInfo.Count) ); Win32.FindNextPrinterChangeNotification(printer.EventHandle, evtTriggered, printerNotifyOptions, pPrinterNotifyInfo); if (!(Win32.FindNextPrinterChangeNotification(printer.EventHandle, evtTriggered, printerNotifyOptions, pPrinterNotifyInfo) ) ) { System.Console.WriteLine(Utilities.GetErrorMessage(Marshal.GetLastWin32Error())); return; } if (pPrinterNotifyInfo.ToInt32() != 0) { printerNotifyInfo = new PrinterNotifyInfo(pPrinterNotifyInfo); } else { System.Console.WriteLine(Utilities.GetErrorMessage(Marshal.GetLastWin32Error())); return; } } } else { System.Console.WriteLine(Utilities.GetErrorMessage(Marshal.GetLastWin32Error())); return; } } else { System.Console.WriteLine(Utilities.GetErrorMessage(Marshal.GetLastWin32Error())); return; } } } Quote
danc Posted October 24, 2005 Posted October 24, 2005 FindFirstPrinterChangetNotification Did you ever get any response on this? Quote
Recommended Posts