using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; using Seagull.BarTender.Print; using System.Data; using System.Runtime.InteropServices; namespace MES接口 { public partial class BarTender : Form { #region Fields // Common strings. //format.BaseName 获取当前文件名,不包括后缀 //format.Title 获取全部文件名,包括后缀 //format.Status 文件是否被加载 [DllImport("user32.dll")] public static extern bool ReleaseCapture(); [DllImport("user32.dll")] public static extern bool SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam); public const int WM_SYSCOMMAND = 0x0112; public const int SC_MOVE = 0xF010; public const int HTCAPTION = 0x0002; private const string appName = "Label Print"; private const string dataSourced = "Data Sourced"; private Engine engine = null; // 新建打印机引擎 private LabelFormatDocument format = null; // 当前打开的BTW文件对象 private bool isClosing = false; // 正在关闭时此选项设置为true,会阻止缩略图加载. // 标签预览 private string[] browsingFormats; // 当前选取的文件夹下的Btw文件 Hashtable listItems; // A hash table containing ListViewItems and indexed by format name. // It keeps track of what formats have had their image loaded. Queue generationQueue; // A queue containing indexes into browsingFormats // to facilitate the generation of thumbnails // 预览文件的索引 int topIndex; // The top visible index in the lstLabelBrowser int selectedIndex; // 预览框选中文件的索引 #endregion #region Enumerations // Indexes into our image list for the label browser. enum ImageIndex { LoadingFormatImage = 0, FailureToLoadFormatImage = 1 }; #endregion #region Constructor /// /// 构造函数初始化 /// public BarTender() { InitializeComponent(); } #endregion #region Delegates delegate void DelegateShowMessageBox(string message); #endregion #region Event Handlers #region Form Event Handlers /// /// 页面启动的时候执行,和打印机进行连接 /// /// /// private void LabelPrint_Load(object sender, EventArgs e) { this.headBar1.MouseDown += new MouseEventHandler(this.headBar1_MouseDown); // 创建一个打印机进程 try { engine = new Engine(true); } catch (PrintEngineException exception) { // 不能打印进程返回错误信息直接退出程序 MessageBox.Show(this, exception.Message, appName); this.Close(); return; } // 获取打印机列表 Printers printers = new Printers(); foreach (Printer printer in printers) { cboPrinters.Items.Add(printer.PrinterName); } if (printers.Count > 0) { // 设置下拉框选中默认打印机 cboPrinters.SelectedItem = printers.Default.PrinterName; } // 设置预览框中的图标 lstLabelBrowser.View = View.LargeIcon; lstLabelBrowser.LargeImageList = new ImageList(); lstLabelBrowser.LargeImageList.ImageSize = new Size(100, 100); lstLabelBrowser.LargeImageList.Images.Add(Properties.Resources.LoadingFormat); lstLabelBrowser.LargeImageList.Images.Add(Properties.Resources.LoadingError); // 初始化一个队列 listItems = new Hashtable(); generationQueue = new Queue(); //设置打印份数的最大值 txtIdenticalCopies.MaxLength = 9; txtSerializedCopies.MaxLength = 9; } /// /// 关闭窗口的时候执行该方法 /// /// /// private void LabelPrint_FormClosed(object sender, FormClosedEventArgs e) { isClosing = true; // 关闭窗口之前向后台请求取消尚未打印的内容 thumbnailCacheWorker.CancelAsync(); while (thumbnailCacheWorker.IsBusy) { Application.DoEvents(); }; // 如果已经启动了打印机,停止打印机并且不保存修改的文件SubString if (engine != null) engine.Stop(SaveOptions.DoNotSaveChanges); } /// ///打开文件夹的时候,选择该文件夹下面后缀名为.BTW的文件进行显示 /// /// /// private void btnOpen_Click(object sender, EventArgs e) { //选择文件的时提示的描述 folderBrowserDialog.Description = "选择一个包含打印文件(*.BTW)的文件夹"; DialogResult result = folderBrowserDialog.ShowDialog(); if (result == DialogResult.OK) { lock (generationQueue) { generationQueue.Clear(); } //清空之前选择的内容 listItems.Clear(); //将文件夹的路径赋值给TextBox txtFolderPath.Text = folderBrowserDialog.SelectedPath; //为选取的时候打印按钮为Disabled btnPrint.Enabled = false; //读取该文件夹下面的BTW文件,browsingFormats是文件名的字符串数组 browsingFormats = System.IO.Directory.GetFiles(txtFolderPath.Text, "*.btw"); // ListView序列化的长度 lstLabelBrowser.VirtualListSize = browsingFormats.Length; } } /// /// 点击打印按钮的时候执行 /// /// /// private void btnPrint_Click(object sender, EventArgs e) { // 正在打印的时候锁定该进程 // 用户点击也不展示SubString lock (engine) { bool success = true; // 设置打印参数 if (format.PrintSetup.SupportsIdenticalCopies) { int copies = 1; success = Int32.TryParse(txtIdenticalCopies.Text, out copies) && (copies >= 1); if (!success) MessageBox.Show(this, "打印的份数必须大于1的整数", appName); else { format.PrintSetup.IdenticalCopiesOfLabel = copies; } } // 数据源是数据库的时候 // Assign number of serialized copies if it is not datasourced. if (success && (format.PrintSetup.SupportsSerializedLabels)) { int copies = 1; success = int.TryParse(txtSerializedCopies.Text, out copies) && (copies >= 1); if (!success) { MessageBox.Show(this, "打印份数必须是大于1的数字", appName); } else { format.PrintSetup.NumberOfSerializedLabels = copies; } } // 所有的验证条件通过执行打印 if (success) { Cursor.Current = Cursors.WaitCursor; // 选择打印机的名称 if (cboPrinters.SelectedItem != null) format.PrintSetup.PrinterName = cboPrinters.SelectedItem.ToString(); //int waitForCompletionTimeout = 10000; // 10 seconds //Result result = format.Print(appName, waitForCompletionTimeout, out messages); //string messageString = "\n\nMessages:"; //foreach (Seagull.BarTender.Print.Message message in messages) //{ // messageString += "\n\n" + message.Text; //} //if (result == Result.Failure) // MessageBox.Show(this, "Print Failed" + messageString, appName); //else // MessageBox.Show(this, "Label was successfully sent to printer." + messageString, appName); } } } #endregion #region List View Event Handlers /// /// 选中预览文件的时候读取SubString /// /// /// private void lstLabelBrowser_SelectedIndexChanged(object sender, EventArgs e) { if (lstLabelBrowser.SelectedIndices.Count == 1) { selectedIndex = lstLabelBrowser.SelectedIndices[0]; EnableControls(false); picUpdatingFormat.Visible = true; // 启动后台加载函数读取内容 // 读取到的数据显示在DataGridView当中 BackgroundWorker formatLoader = new BackgroundWorker(); formatLoader.DoWork += new DoWorkEventHandler(formatLoader_DoWork); formatLoader.RunWorkerCompleted += new RunWorkerCompletedEventHandler(formatLoader_RunWorkerCompleted); formatLoader.RunWorkerAsync(selectedIndex); } else if (lstLabelBrowser.SelectedIndices.Count == 0) { EnableControls(false); picUpdatingFormat.Visible = false; } } /// /// 读取完文件夹的时候展示问价在该区域 /// /// /// private void lstLabelBrowser_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e) { int btwFileIndex = e.ItemIndex; //如果不存在这个项目则设置成默认的图片 if (listItems[browsingFormats[btwFileIndex]] == null) { e.Item = new ListViewItem(browsingFormats[btwFileIndex]); e.Item.ImageIndex = (int)ImageIndex.LoadingFormatImage; listItems.Add(browsingFormats[btwFileIndex], e.Item); } else { e.Item = (ListViewItem)listItems[browsingFormats[btwFileIndex]]; } // 将索引添加到队列. if (e.Item.ImageIndex == (int)ImageIndex.LoadingFormatImage) { lock (generationQueue) { if (!generationQueue.Contains(btwFileIndex)) generationQueue.Enqueue(btwFileIndex); } } // 将东西放进队列的时候,如果队列没有被占用则开始执行任务 if (!thumbnailCacheWorker.IsBusy && (generationQueue.Count > 0)) { thumbnailCacheWorker.RunWorkerAsync(); } } /// /// 缓存读取的文件列表 /// /// /// private void lstLabelBrowser_CacheVirtualItems(object sender, CacheVirtualItemsEventArgs cacheEvent) { topIndex = cacheEvent.StartIndex; lock (generationQueue) { for (int index = cacheEvent.StartIndex; index <= cacheEvent.EndIndex; ++index) { ListViewItem listViewItem = (ListViewItem)listItems[browsingFormats[index]]; if ((listViewItem != null) && (listViewItem.ImageIndex == (int)ImageIndex.LoadingFormatImage)) { if (!generationQueue.Contains(index)) generationQueue.Enqueue(index); } } } // 任务资源可用的时候执行 if (!thumbnailCacheWorker.IsBusy && (generationQueue.Count > 0)) { thumbnailCacheWorker.RunWorkerAsync(); } } #endregion #region Thumbnail Event Handlers /// /// Called when a thumbnail was loaded so it can be shown. /// /// /// void thumbnailCacheWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) { object[] args = e.UserState as object[]; ListViewItem item = (ListViewItem)args[0]; // 100 means we got the image successfully. if (e.ProgressPercentage == 100) { Image thumbnail = (Image)args[1]; lstLabelBrowser.LargeImageList.Images.Add(item.Text, thumbnail); item.ImageIndex = lstLabelBrowser.LargeImageList.Images.IndexOfKey(item.Text); } else if (e.ProgressPercentage == 0) // 0 means we did not successfully get the format image. { item.ImageIndex = (int)ImageIndex.FailureToLoadFormatImage; } item.ListView.Invalidate(item.Bounds); } /// /// 后台启用函数加载缩略图 /// /// /// void thumbnailCacheWorker_DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker worker = (BackgroundWorker)sender; int index; string fileName; // Loop until the queue of items that need to be loaded is empty or the worker was cancelled. while ((generationQueue.Count > 0) && !worker.CancellationPending && !isClosing) { lock (generationQueue) { // Get the index to use. index = generationQueue.Dequeue(); } // If this is way out of our view don't bother generating it. if (Math.Abs(index - topIndex) < 30) { fileName = browsingFormats[index]; // 检查文件是否出缩略图外都已经加载完成了 ListViewItem item = (ListViewItem)listItems[fileName]; if (item == null) { item = new ListViewItem(fileName); item.ImageIndex = (int)ImageIndex.LoadingFormatImage; listItems.Add(fileName, item); } // 没有缩略图的时候就给个默认的 if (item.ImageIndex == (int)ImageIndex.LoadingFormatImage) { try { Console.WriteLine(fileName); Image btwImage = LabelFormatThumbnail.Create(fileName, Color.Gray, 100, 100); object[] progressReport = new object[] { item, btwImage }; worker.ReportProgress(100, progressReport); } catch { object[] progressReport = new object[] { item, null }; worker.ReportProgress(0, progressReport); } } } } } #endregion #region Format Loader Event Handlers /// ///在另一个进程中进行文件的读取,不用占用当前的界面 /// /// /// void formatLoader_DoWork(object sender, DoWorkEventArgs e) { int index = (int)e.Argument; string errorMessage = ""; // 确保安全先锁定打印机,因为可能正在执行打印任务 lock (engine) { //确保用户选中该列表 if (selectedIndex == index) { try { if (format != null) //是否保存对文件的编辑 format.Close(SaveOptions.SaveChanges); format = engine.Documents.Open(browsingFormats[index]); } catch (System.Runtime.InteropServices.COMException comException) { errorMessage = String.Format("Unable to open format: {0}\nReason: {1}", browsingFormats[index], comException.Message); format = null; } } } // 后台执行只能调用MessageBox来显示信息 if (errorMessage.Length != 0) Invoke(new DelegateShowMessageBox(ShowMessageBox), errorMessage); } /// /// 文件加载完的时候执行 /// 填充打印份数默认值为1,如果存在SubString则读取出来 /// /// /// void formatLoader_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { // 确保正在操作的时候不会丢失该文件 lock (engine) { if (format != null) { EnableControls(true); cboPrinters.SelectedItem = format.PrintSetup.PrinterName; picUpdatingFormat.Visible = false; lblFormatError.Visible = false; //支持打印多份的时候 if (format.PrintSetup.SupportsIdenticalCopies == false) { txtIdenticalCopies.Text = dataSourced; txtIdenticalCopies.ReadOnly = true; } else { txtIdenticalCopies.Text = format.PrintSetup.IdenticalCopiesOfLabel.ToString(); txtIdenticalCopies.ReadOnly = false; } //数据源是数据库的时候 if (format.PrintSetup.SupportsSerializedLabels == false) { txtSerializedCopies.Text = dataSourced; txtSerializedCopies.ReadOnly = true; } else { txtSerializedCopies.Text = format.PrintSetup.NumberOfSerializedLabels.ToString(); txtSerializedCopies.ReadOnly = false; } //DataTable dt = new DataTable(); //DataRow row = dt.NewRow(); //dt.Columns.Add(new DataColumn("name")); //dt.Columns.Add(new DataColumn("sex")); //dt.Columns.Add(new DataColumn("age")); //row["name"] = "John"; //row["sex"] = "Smith"; //row["age"] = "18"; //dt.Rows.Add(row); //MessageBox.Show(format.SubStrings[0].Name); //获取具名数据源 if (format.SubStrings.Count > 0){ BindingSource bindingSource = new BindingSource(); bindingSource.DataSource = format.SubStrings; substringGrid.DataSource = bindingSource; substringGrid.AutoResizeColumns(); lblNoSubstrings.Visible = false; }else{ lblNoSubstrings.Visible = true; } substringGrid.Invalidate(); } else // 没有文件的时候,隐藏标签信息 { picUpdatingFormat.Visible = false; lblNoSubstrings.Visible = false; lblFormatError.Visible = true; } } } #endregion #endregion #region Methods /// ///打开的文件无效禁用所有的控件 /// /// void EnableControls(bool enable) { txtIdenticalCopies.Enabled = enable; txtSerializedCopies.Enabled = enable; btnPrint.Enabled = enable; if (!enable) { txtIdenticalCopies.Text = ""; txtSerializedCopies.Text = ""; substringGrid.DataSource = null; lblFormatError.Visible = false; lblNoSubstrings.Visible = false; } } /// /// 重写一个展示消息的方法 /// /// 展示的信息 void ShowMessageBox(string message) { MessageBox.Show(this, message, appName); } #endregion private void headBar1_MouseDown(object sender, MouseEventArgs e) { ReleaseCapture(); SendMessage(this.Handle, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0); } } }