mcc2 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data/.autotest +23 -0
  4. data/.gitignore +15 -0
  5. data/.rubocop.yml +3 -0
  6. data/Gemfile +13 -0
  7. data/History.txt +6 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +51 -0
  10. data/Rakefile +12 -0
  11. data/config/i18n-tasks.yml +193 -0
  12. data/exe/mcc2 +18 -0
  13. data/exe/mcc2-generate-preview +17 -0
  14. data/exe/mcc2print +6 -0
  15. data/lib/libguib16.rb +1620 -0
  16. data/lib/mcc2/advanced_data_edit_dlg.rb +139 -0
  17. data/lib/mcc2/cc_dialogbox.rb +52 -0
  18. data/lib/mcc2/constants.rb +154 -0
  19. data/lib/mcc2/dataman/base.rb +61 -0
  20. data/lib/mcc2/dataman/csv.rb +49 -0
  21. data/lib/mcc2/dataman/database.rb +8 -0
  22. data/lib/mcc2/dataman/dbf.rb +45 -0
  23. data/lib/mcc2/dataman/none.rb +25 -0
  24. data/lib/mcc2/dataview.rb +348 -0
  25. data/lib/mcc2/dataview_dlg.rb +232 -0
  26. data/lib/mcc2/debug_tools.rb +20 -0
  27. data/lib/mcc2/fx_colored_item.rb +101 -0
  28. data/lib/mcc2/generate_preview.rb +68 -0
  29. data/lib/mcc2/gui/advanced_data_edit_dlg.rbin +0 -0
  30. data/lib/mcc2/gui/dataview_dlg.pp +522 -0
  31. data/lib/mcc2/gui/layoutview_dlg.pp +5115 -0
  32. data/lib/mcc2/gui/mcc2_mainwin.pp +838 -0
  33. data/lib/mcc2/gui/picture_data_edit_dlg.rbin +0 -0
  34. data/lib/mcc2/gui/printerview_dlg.pp +3311 -0
  35. data/lib/mcc2/images/Image-Arrow-Left.gif +0 -0
  36. data/lib/mcc2/images/Image-Arrow-Right.gif +0 -0
  37. data/lib/mcc2/images/Image-FastArrowLeft.gif +0 -0
  38. data/lib/mcc2/images/Image-FastArrowRight.bmp +0 -0
  39. data/lib/mcc2/images/Image-FastArrowRight.gif +0 -0
  40. data/lib/mcc2/images/application-exit.png +0 -0
  41. data/lib/mcc2/images/copy.png +0 -0
  42. data/lib/mcc2/images/country_de.png +0 -0
  43. data/lib/mcc2/images/country_gb.png +0 -0
  44. data/lib/mcc2/images/country_rs.png +0 -0
  45. data/lib/mcc2/images/cut.png +0 -0
  46. data/lib/mcc2/images/distribute-horizontal-baseline.png +0 -0
  47. data/lib/mcc2/images/distribute-vertical-baseline.png +0 -0
  48. data/lib/mcc2/images/document-close.png +0 -0
  49. data/lib/mcc2/images/document-edit.png +0 -0
  50. data/lib/mcc2/images/document-new.png +0 -0
  51. data/lib/mcc2/images/document-open.png +0 -0
  52. data/lib/mcc2/images/document-print-frame.png +0 -0
  53. data/lib/mcc2/images/document-print.png +0 -0
  54. data/lib/mcc2/images/document-save-as.png +0 -0
  55. data/lib/mcc2/images/document-save.png +0 -0
  56. data/lib/mcc2/images/documentation.png +0 -0
  57. data/lib/mcc2/images/draw-rectangle.png +0 -0
  58. data/lib/mcc2/images/dummy.gif +0 -0
  59. data/lib/mcc2/images/exchange-positions.png +0 -0
  60. data/lib/mcc2/images/insert-image.png +0 -0
  61. data/lib/mcc2/images/insert-text.png +0 -0
  62. data/lib/mcc2/images/libreoffice-oasis-master-document.png +0 -0
  63. data/lib/mcc2/images/measure.png +0 -0
  64. data/lib/mcc2/images/messagebox_warning.png +0 -0
  65. data/lib/mcc2/images/paste.png +0 -0
  66. data/lib/mcc2/images/process-stop.png +0 -0
  67. data/lib/mcc2/images/zoom-in.png +0 -0
  68. data/lib/mcc2/layout.rb +323 -0
  69. data/lib/mcc2/layout_file.rb +794 -0
  70. data/lib/mcc2/layout_object/barcode.rb +33 -0
  71. data/lib/mcc2/layout_object/box.rb +18 -0
  72. data/lib/mcc2/layout_object/chip.rb +54 -0
  73. data/lib/mcc2/layout_object/embed.rb +16 -0
  74. data/lib/mcc2/layout_object/go_attribut.rb +16 -0
  75. data/lib/mcc2/layout_object/graphic.rb +59 -0
  76. data/lib/mcc2/layout_object/magstripe.rb +13 -0
  77. data/lib/mcc2/layout_object/picture.rb +22 -0
  78. data/lib/mcc2/layout_object/text.rb +29 -0
  79. data/lib/mcc2/layout_win.rb +2052 -0
  80. data/lib/mcc2/layoutview.rb +845 -0
  81. data/lib/mcc2/layoutview_dlg.rb +2058 -0
  82. data/lib/mcc2/locales.rb +27 -0
  83. data/lib/mcc2/mcc2_mainwin.rb +453 -0
  84. data/lib/mcc2/mcc2gui.rb +295 -0
  85. data/lib/mcc2/mcc2print.rb +54 -0
  86. data/lib/mcc2/picture_data_edit_dlg.rb +139 -0
  87. data/lib/mcc2/print_dlg.rb +520 -0
  88. data/lib/mcc2/printer/base.rb +148 -0
  89. data/lib/mcc2/printer/card_printer.rb +45 -0
  90. data/lib/mcc2/printer/file_printer.rb +135 -0
  91. data/lib/mcc2/printer/gdi_card_printer.rb +14 -0
  92. data/lib/mcc2/printer/gdi_printer.rb +197 -0
  93. data/lib/mcc2/printer/linux_cups_printer.rb +92 -0
  94. data/lib/mcc2/printer/preview.rb +277 -0
  95. data/lib/mcc2/printer/printer_cab.rb +118 -0
  96. data/lib/mcc2/printer/printer_cx320_direct.rb +286 -0
  97. data/lib/mcc2/printer/printer_epl.rb +118 -0
  98. data/lib/mcc2/printer/printer_ttp34x.rb +124 -0
  99. data/lib/mcc2/printer/printer_zebra.rb +324 -0
  100. data/lib/mcc2/printer/svg_drawer.rb +689 -0
  101. data/lib/mcc2/printerview.rb +604 -0
  102. data/lib/mcc2/printerview_dlg.rb +1248 -0
  103. data/lib/mcc2/version.rb +3 -0
  104. data/lib/mcc2.rb +11 -0
  105. data/locales/de.yml +6 -0
  106. data/locales/en.yml +502 -0
  107. data/locales/rs.yml +502 -0
  108. data/mcc2.gemspec +41 -0
  109. data/test/dummy.rb +19 -0
  110. data/test/layouts/bart_simpson.png +0 -0
  111. data/test/layouts/color_test.xml +151 -0
  112. data/test/layouts/ms.xml +67 -0
  113. data/test/ruby_print.rb +380 -0
  114. data/test/test.csv +4 -0
  115. data/test/test.dbf +0 -0
  116. data/test/test.str +4 -0
  117. data/test/test_mcc2.rb +8 -0
  118. data.tar.gz.sig +6 -0
  119. metadata +421 -0
  120. metadata.gz.sig +0 -0
@@ -0,0 +1,118 @@
1
+ require "mcc2/printer/card_printer"
2
+ require "mcc2/printer/svg_drawer"
3
+ require "socket"
4
+ require "rmagick"
5
+
6
+ module Mcc2
7
+ module Printer
8
+ class PrinterEpl < CardPrinter
9
+ include SvgDrawer
10
+
11
+ # die Ränder außerhalb der Karte, auf den maximal gedruckt werden darf (für vollflächige Bilder notwendig)
12
+ def card_margin_left
13
+ 0
14
+ end
15
+
16
+ def card_margin_right
17
+ 0
18
+ end
19
+
20
+ def card_margin_top
21
+ 0
22
+ end
23
+
24
+ def card_margin_bottom
25
+ 0
26
+ end
27
+
28
+ #--------------------------------------------------------------------------------------------------------------
29
+
30
+ def print_card(layout_file, row)
31
+ self.dpi = layout_file.get_attr_value(S_EPLPRINTER_DPI).to_f
32
+
33
+ page_commands = layout_file.get_attr_value(S_EPLPRINTER_PAGE_COMMANDS)
34
+ page_width = layout_file.get_attr_value(S_WIDTH).to_f
35
+ page_height = layout_file.get_attr_value(S_HEIGHT).to_f
36
+ draw_pos_x = layout_file.get_attr_value(S_X_OFFSET).to_f
37
+ draw_pos_y = layout_file.get_attr_value(S_Y_OFFSET).to_f
38
+ image_width = mm(page_width - draw_pos_x).round
39
+ image_height = mm(page_height - draw_pos_y).round
40
+
41
+ surface = Cairo::ImageSurface.new(Cairo::FORMAT_RGB24, image_width, image_height)
42
+ surface.set_fallback_resolution(dpi, dpi)
43
+ Cairo::Context.new(surface) do |context|
44
+ context.set_source_rgb(1.0, 1.0, 1.0) # make white background
45
+ context.paint
46
+
47
+ svg_data = svg_builder(viewBox: "0 0 #{image_width} #{image_height}") do |svg|
48
+ tra = Transformation.new
49
+ draw(svg, tra, layout_file, false, nil, row, 0)
50
+ end
51
+ svg_handle = RSVG::Handle.new_from_data(svg_data)
52
+ context.render_rsvg_handle(svg_handle)
53
+ end
54
+
55
+ # Convert to ImageMagick image
56
+ # "BGRA" matches the byte ordering of Cairo's FORMAT_ARGB32
57
+ pic = Magick::Image.from_blob(surface.data) do |options|
58
+ options.format = 'BGRA'
59
+ options.size = "#{image_width}x#{image_height}"
60
+ options.depth = 8 # Bits per pixel channel
61
+ end.first
62
+
63
+ page_commands.gsub!("\\e", "\e")
64
+ page_commands.gsub!("\n", "\r\n")
65
+ page_commands.gsub!("%PAGE_WIDTH_MM%", page_width.to_s)
66
+ page_commands.gsub!("%PAGE_HEIGHT_MM%", page_height.to_s)
67
+ page_commands.gsub!("%PAGE_OFFSET_X_MM%", draw_pos_x.to_s)
68
+ page_commands.gsub!("%PAGE_OFFSET_Y_MM%", draw_pos_y.to_s)
69
+ page_commands.gsub!("%PAGE_WIDTH_PX%", mm(page_width).to_i.to_s)
70
+ page_commands.gsub!("%PAGE_HEIGHT_PX%", mm(page_height).to_i.to_s)
71
+ page_commands.gsub!("%PAGE_OFFSET_X_PX%", mm(draw_pos_x).to_i.to_s)
72
+ page_commands.gsub!("%PAGE_OFFSET_Y_PX%", mm(draw_pos_y).to_i.to_s)
73
+
74
+ page_commands.gsub!("%IMAGE_LEN_DATA_PCX%") do
75
+ pic = pic.level2(Magick::QuantumRange / 2, Magick::QuantumRange / 2)
76
+ pic = pic.quantize(2, Magick::RGBColorspace, false)
77
+ pic = pic.level2(Magick::QuantumRange / 2, Magick::QuantumRange / 2)
78
+ pic.class_type = Magick::PseudoClass
79
+ pic.image_type = Magick::BilevelType
80
+ data = pic.to_blob do |image|
81
+ image.format = "pcx"
82
+ end
83
+ # File.write("test.pcx", data)
84
+ "#{data.bytesize}\r\n#{data}"
85
+ end
86
+
87
+ open_socket(layout_file) do |sock|
88
+ sock.write page_commands
89
+ end
90
+
91
+ true
92
+ end
93
+
94
+ #--------------------------------------------------------------------------------------------------------------
95
+
96
+ def open_socket(layout_file)
97
+ dev = layout_file.get_attr_value(S_EPLPRINTER_DEVICE)
98
+ sock = File.open(dev, "wb")
99
+ if block_given?
100
+ begin
101
+ return yield(sock)
102
+ ensure
103
+ sock.close
104
+ end
105
+ end
106
+ sock
107
+ end
108
+ private :open_socket
109
+
110
+ def send_command(layout_file, data, &block)
111
+ open_socket(layout_file) do |sock|
112
+ sock.write data
113
+ yield sock if block
114
+ end
115
+ end
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,124 @@
1
+ require "mcc2/printer/card_printer"
2
+ require "mcc2/printer/svg_drawer"
3
+ require "socket"
4
+ require "rmagick"
5
+
6
+ module Mcc2
7
+ module Printer
8
+ class PrinterTTP34x < CardPrinter
9
+ include SvgDrawer
10
+
11
+ # die Ränder außerhalb der Karte, auf den maximal gedruckt werden darf (für vollflächige Bilder notwendig)
12
+ def card_margin_left
13
+ 0
14
+ end
15
+
16
+ def card_margin_right
17
+ 0
18
+ end
19
+
20
+ def card_margin_top
21
+ 0
22
+ end
23
+
24
+ def card_margin_bottom
25
+ 0
26
+ end
27
+
28
+ #--------------------------------------------------------------------------------------------------------------
29
+
30
+ def print_card(layout_file, row)
31
+ self.dpi = layout_file.get_attr_value(S_TTP34XPRINTER_DPI).to_f
32
+
33
+ page_commands = layout_file.get_attr_value(S_TTP34XPRINTER_PAGE_COMMANDS)
34
+ page_width = layout_file.get_attr_value(S_WIDTH).to_f
35
+ page_height = layout_file.get_attr_value(S_HEIGHT).to_f
36
+ draw_pos_x = layout_file.get_attr_value(S_X_OFFSET).to_f
37
+ draw_pos_y = layout_file.get_attr_value(S_Y_OFFSET).to_f
38
+ image_width = mm(page_width - draw_pos_x).round
39
+ image_height = mm(page_height - draw_pos_y).round
40
+
41
+ surface = Cairo::ImageSurface.new(Cairo::FORMAT_RGB24, image_width, image_height)
42
+ surface.set_fallback_resolution(dpi, dpi)
43
+ Cairo::Context.new(surface) do |context|
44
+ context.set_source_rgb(1.0, 1.0, 1.0) # make white background
45
+ context.paint
46
+
47
+ svg_data = svg_builder(viewBox: "0 0 #{image_width} #{image_height}") do |svg|
48
+ tra = Transformation.new
49
+ draw(svg, tra, layout_file, false, nil, row, 0)
50
+ end
51
+ svg_handle = RSVG::Handle.new_from_data(svg_data)
52
+ context.render_rsvg_handle(svg_handle)
53
+ end
54
+
55
+ # Convert to ImageMagick image
56
+ # "BGRA" matches the byte ordering of Cairo's FORMAT_ARGB32
57
+ pic = Magick::Image.from_blob(surface.data) do |options|
58
+ options.format = 'BGRA'
59
+ options.size = "#{image_width}x#{image_height}"
60
+ options.depth = 8 # Bits per pixel channel
61
+ end.first
62
+
63
+ page_commands.gsub!("\\e", "\e")
64
+ page_commands.gsub!("\n", "\r\n")
65
+ page_commands.gsub!("%PAGE_WIDTH_MM%", page_width.to_s)
66
+ page_commands.gsub!("%PAGE_HEIGHT_MM%", page_height.to_s)
67
+ page_commands.gsub!("%PAGE_WIDTH_PX%", mm(page_width).to_i.to_s)
68
+ page_commands.gsub!("%PAGE_HEIGHT_PX%", mm(page_height).to_i.to_s)
69
+ page_commands.gsub!("%PAGE_OFFSET_X_MM%", draw_pos_x.to_s)
70
+ page_commands.gsub!("%PAGE_OFFSET_Y_MM%", draw_pos_y.to_s)
71
+ page_commands.gsub!("%PAGE_OFFSET_X_PX%", mm(draw_pos_x).to_i.to_s)
72
+ page_commands.gsub!("%PAGE_OFFSET_Y_PX%", mm(draw_pos_y).to_i.to_s)
73
+
74
+ page_commands.gsub!("%IMAGE_LEN_DATA_PCX%") do
75
+ pic = pic.quantize(2, Magick::RGBColorspace, false)
76
+ pic = pic.level2(Magick::QuantumRange / 2, Magick::QuantumRange / 2)
77
+ pic = pic.quantize(2, Magick::RGBColorspace, false)
78
+ pic = pic.level2(Magick::QuantumRange / 2, Magick::QuantumRange / 2)
79
+ pic.class_type = Magick::PseudoClass
80
+ pic.image_type = Magick::BilevelType
81
+ # wir müssen die Farben invertieren, da TTP anscheinend das Negativ druckt !!!
82
+ pic_negate = pic.negate
83
+ data = pic_negate.to_blob do |image|
84
+ image.format = "pcx"
85
+ end
86
+
87
+ # pic_negate.display # bitte NUR unter LINUX aktivieren
88
+ # File.write("TSC-TTP346M.pcx", data)
89
+
90
+ "#{data.bytesize},#{data}"
91
+ end
92
+
93
+ open_socket(layout_file) do |sock|
94
+ sock.write page_commands
95
+ end
96
+
97
+ true
98
+ end
99
+
100
+ #--------------------------------------------------------------------------------------------------------------
101
+
102
+ def open_socket(layout_file)
103
+ dev = layout_file.get_attr_value(S_TTP34XPRINTER_DEVICE)
104
+ sock = File.open(dev, "wb")
105
+ if block_given?
106
+ begin
107
+ return yield(sock)
108
+ ensure
109
+ sock.close
110
+ end
111
+ end
112
+ sock
113
+ end
114
+ private :open_socket
115
+
116
+ def send_command(layout_file, data, &block)
117
+ open_socket(layout_file) do |sock|
118
+ sock.write data
119
+ yield sock if block
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,324 @@
1
+ require "win32api4ruby"
2
+ require "zebra_dll"
3
+ require "mcc2/printer/gdi_card_printer" # die Basisklasse für alle CardPrinter
4
+
5
+ module Mcc2
6
+ module Printer
7
+ # Diese Klasse definiert einen Zebra-Drucker.
8
+ class PrinterZebra < GdiCardPrinter
9
+ attr_accessor :name
10
+
11
+ def initialize
12
+ super
13
+ end
14
+
15
+ def device_name
16
+ layout_file.get_attr_value(S_ZEBRAPRINTER_NAME)
17
+ end
18
+
19
+ def device_initdata
20
+ layout_file.get_binary_attr(S_ZEBRAPRINTER_INITDATA)
21
+ end
22
+
23
+ def move_to_reject_box
24
+ if @type &&
25
+ @type == 420 ||
26
+ @type == 430 ||
27
+ @type == 520 ||
28
+ @type == 720
29
+ # Bei Druckern mit Ausschuss-Fach, Karte in Ausschuss-Fach
30
+ # TODO geht noch nicht richtig, es werden 2 Karten in das Ausschuss-Fach transportiert
31
+ send_command("MRB", "Karte in Ausschuss-Fach")
32
+ else
33
+ # Bei Druckern ohne Ausschuss-Fach, Karte einfach auswerfen
34
+ send_command("MO", "Karte auswerfen (Ausschuss)")
35
+ end
36
+ end
37
+
38
+ def print_card(layout_file, row)
39
+ # Wird für Chip-Perso benötigt
40
+ @layout_file = layout_file
41
+ @chip = layout_file.build_chip_instance
42
+
43
+ # Warte, bis Durck der vorherigen Karte beendet ist.
44
+ st = Time.now
45
+ begin
46
+ puts "Zebra-Drucker: #{send_command_ex("V", "Firmware-Version ermitteln")}"
47
+ rescue ZebraException => e
48
+ raise if Time.now - st > 30
49
+ sleep 1
50
+ retry
51
+ end
52
+
53
+ if chip
54
+ send_command("MCL", "Karte zum Kontaktlos-Leser fahren")
55
+ begin
56
+ # Kartenpersonalisierung
57
+ chip.pers_chip(row)
58
+ rescue => e
59
+ puts "Fehler bei Chip-Personalisierung: #{e} #{e.class} #{e.backtrace.join("\n")}"
60
+ begin
61
+ move_to_reject_box
62
+ rescue => e1
63
+ raise("Fehler bei Chip-Personalisierung, Karte ausgeschleust: #{e}\nFehler beim Ausschleusen: #{e1}")
64
+ end
65
+ raise("Fehler bei Chip-Personalisierung, Karte ausgeschleust: #{e}")
66
+ end
67
+ send_command("MIB", "Karte vom Leser zum Drucken weiter schicken")
68
+ end
69
+
70
+ # Jetzt erst den eigentlichen Druck beginnen
71
+ super
72
+ end
73
+
74
+ # Sendet ein Kommando an den Drucker
75
+ def send_command(command, msg = nil)
76
+ puts("Zebra: Send command '#{command}' #{msg}")
77
+ open_handle
78
+ begin
79
+ send_cmd(command, msg)
80
+ ensure
81
+ close_handle
82
+ end
83
+ end
84
+
85
+ # Sendet ein Kommando an den Drucker
86
+ def send_command_ex(command, msg = nil)
87
+ puts("Zebra: Send command ex '#{command}' #{msg}")
88
+ ret = ""
89
+ open_handle
90
+ begin
91
+ ret = send_cmd_ex(command, msg)
92
+ ensure
93
+ close_handle
94
+ end
95
+ ret
96
+ end
97
+
98
+ def open_handle(name = nil)
99
+ h_printer = DL.malloc(4)
100
+ h_printer.struct!("L", :handle)
101
+
102
+ devicename = name || device_name
103
+
104
+ printer_type = DL.malloc(4)
105
+ printer_type.struct!("L", :type)
106
+
107
+ err = DL.malloc(4)
108
+ err.struct!("L", :err)
109
+
110
+ # puts("---\nGet handle '#{devicename}'")
111
+ Time.now
112
+ result = ZebraDll.get_handle(h_printer, devicename, printer_type, err)
113
+
114
+ @handle = h_printer[:handle]
115
+ @type = printer_type[:type]
116
+ error = err[:err]
117
+
118
+ # puts("result = #{result}, error = #{error}")
119
+ # puts("type = #{@type}")
120
+ # puts("needed: #{Time.now - start}")
121
+
122
+ if result == 0
123
+ raise ZebraException.new(error, "Fehler bei Get Handle")
124
+ end
125
+ end
126
+
127
+ def send_cmd(command, msg = nil)
128
+ if !@handle
129
+ raise StandardError.new("Es muss erst ein Drucker-Handle geöffnet werden!")
130
+ end
131
+ err = DL.malloc(4)
132
+ err.struct!("L", :err)
133
+ # puts("---\nSend command #{command}")
134
+ Time.now
135
+ result = ZebraDll.send_cmd(@handle, @type, "#{command}\r", err)
136
+ error = err[:err]
137
+
138
+ # puts("result = #{result}, error = #{error}")
139
+ # puts("needed: #{Time.now - start}")
140
+
141
+ if result == 0
142
+ raise ZebraException.new(error, "Fehler bei Druckerkommando #{command} #{msg}")
143
+ end
144
+ end
145
+
146
+ def send_cmd_ex(command, msg = nil)
147
+ response = DL.malloc(1024)
148
+ # response.struct!('S', :response)
149
+
150
+ resp_size = DL.malloc(4)
151
+ resp_size.struct!("L", :size)
152
+
153
+ err = DL.malloc(4)
154
+ err.struct!("L", :err)
155
+
156
+ # puts("---\nSend Command Ex: #{command}")
157
+ # result = ZebraDll.send_cmdex(@handle, @type, "#{command.to_s_win32}\r", response, resp_size, err)
158
+ result = ZebraDll.send_cmdex(@handle, @type, "#{command}\r", response, resp_size, err)
159
+
160
+ resp_size[:size]
161
+ error = err[:err]
162
+
163
+ # puts("result = #{result}")
164
+ # puts("response size = #{size}")
165
+ # puts("response = #{response} (#{response[0, size].inspect})")
166
+ # puts("result = #{result}")
167
+ # puts("error = #{error}")
168
+ # puts("needed: #{Time.now - start}")
169
+
170
+ if result == 0
171
+ raise ZebraException.new(error, "Fehler bei Druckerkommando #{command} #{msg}")
172
+ end
173
+ response
174
+ end
175
+
176
+ def close_handle
177
+ if @handle
178
+ err = DL.malloc(4)
179
+ err.struct!("L", :err)
180
+ # puts("---\nClose handle")
181
+ Time.now
182
+ result = ZebraDll.close_handle(@handle, err)
183
+ error = err[:err]
184
+
185
+ # puts("result = #{result}, error = #{error}")
186
+ # puts("needed: #{Time.now - start}")
187
+
188
+ if result == 0
189
+ raise ZebraException.new(error, "Fehler bei Close Handle")
190
+ end
191
+ @handle = nil
192
+ end
193
+ end
194
+ end
195
+
196
+ class ZebraException < RuntimeError
197
+ ERRORS = {
198
+ -1 => "ZBR_ERROR_PRINTER_MECHANICAL_ERROR - Mechanical error",
199
+ 1 => "ZBR_ERROR_BROKEN_RIBBON - Indicates a broken ribbon",
200
+ 2 => "ZBR_ERROR_TEMPERATURE - Print head temperature is too high",
201
+ 3 => "ZBR_ERROR_MECHANICAL_ERROR Mechanical error",
202
+ 4 => "ZBR_ERROR_OUT_OF_CARD Printer is out of cards, or unable to feed the card",
203
+ 5 => "ZBR_ERROR_CARD_IN_ENCODER Unable to encode magnetic or smart card encoder",
204
+ 6 => "ZBR_ERROR_CARD_NOT_IN_ENCODER Unable to encode the card because it is not in the encoder",
205
+ 7 => "ZBR_ERROR_PRINT_HEAD_OPEN Print head is up",
206
+ 8 => "ZBR_ERROR_OUT_OF_RIBBON Out of ribbon",
207
+ 9 => "ZBR_ERROR_REMOVE_RIBBON Ribbon needs to be removed",
208
+ 10 => "ZBR_ERROR_PARAMETERS_ERROR Wrong number of parameters or a value is incorrect",
209
+ 11 => "ZBR_ERROR_INVALID_COORDINATES Invalid coordinates while trying to draw a barcode or graphics",
210
+ 12 => "ZBR_ERROR_UNKNOWN_BARCODE Undefined barcode type",
211
+ 13 => "ZBR_ERROR_UNKNOWN_TEXT Text for magnetic encoding or bar code drawing is invalid",
212
+ 14 => "ZBR_ERROR_COMMAND_ERROR Invalid command",
213
+ 20 => "ZBR_ERROR_BARCODE_DATA_SYNTAX Syntax error in the barcode command or parameters",
214
+ 21 => "ZBR_ERROR_TEXT_DATA_SYNTAX General text data error",
215
+ 22 => "ZBR_ERROR_GRAPHIC_DATA_SYNTAX Syntax error in the graphic command data",
216
+ 30 => "ZBR_ERROR_GRAPHIC_IMAGE_INITIALIZATION Unable to initialize the graphics buffer",
217
+ 31 => "ZBR_ERROR_GRAPHIC_IMAGE_MAXIMUM_WIDTH_EXCEEDED Graphic object to be drawn exceeds the X range",
218
+ 32 => "ZBR_ERROR_GRAPHIC_IMAGE_MAXIMUM_HEIGHT_EXCEEDED Graphic object to be drawn exceeds the Y range",
219
+ 33 => "ZBR_ERROR_GRAPHIC_IMAGE_DATA_CHECKSUM_ERROR Graphic data checksum error",
220
+ 34 => "ZBR_ERROR_DATA_TRANSFER_TIME_OUT Data time-out error, usually happens when the USB cable is taken out while printing",
221
+ 35 => "ZBR_ERROR_CHECK_RIBBON Incorrect ribbon installed",
222
+ 40 => "ZBR_ERROR_INVALID_MAGNETIC_DATA Invalid magnetic encoding data",
223
+ 41 => "ZBR_ERROR_MAG_ENCODER_WRITE Error while encoding a magnetic stripe",
224
+ 42 => "ZBR_ERROR_READING_ERROR Error while reading a magnetic stripe",
225
+ 43 => "ZBR_ERROR_MAG_ENCODER_MECHANICAL Magnetic encoder mechanical error",
226
+ 44 => "ZBR_ERROR_MAG_ENCODER_NOT_RESPONDING Magnetic encoder not responding",
227
+ 45 => "ZBR_ERROR_MAG_ENCODER_MISSING_OR_CARD_JAM Magnetic encoder is missing or the card is jammed before reaching the encoder",
228
+ 47 => "ZBR_ERROR_ROTATION_ERROR Error while trying to flip the card",
229
+ 48 => "ZBR_ERROR_COVER_OPEN Feeder Cover Lid is open (P110 and P120 only)",
230
+ 49 => "ZBR_ERROR_ENCODING_ERROR Error while trying to encode on a magnetic stripe",
231
+ 50 => "ZBR_ERROR_MAGNETIC_ERROR Magnetic encoder error",
232
+ 51 => "ZBR_ERROR_BLANK_TRACK One or more of the tracks of the magnetic stripe are blank",
233
+ 52 => "ZBR_ERROR_FLASH_ERROR Flash memory error",
234
+ 53 => "ZBR_ERROR_NO_ACCESS Cannot access the printer",
235
+ 54 => "ZBR_ERROR_SEQUENCE_ERROR Reception timeout, protocol errors",
236
+ 55 => "ZBR_ERROR_PROX_ERROR Reception timeout, protocol errors",
237
+ 56 => "ZBR_ERROR_CONTACT_DATA_ERROR Parameter error",
238
+ 57 => "ZBR_ERROR_PROX_DATA_ERROR Parameter error",
239
+ 60 => "ZBR_SDK_ERROR_PRINTER_NOT_SUPPORTED Printer not supported",
240
+ 61 => "ZBR_SDK_ERROR_CANNOT_GET_PRINTER_HANDLE Unable to open handle to Zebra printer driver\nIst der Drucker korrekt installiert und eingeschaltet? Falls ja, bitte den Drucker ein- und ausschalten.",
241
+ 62 => "ZBR_SDK_ERROR_CANNOT_GET_PRINTER_DRIVER Cannot open printer driver",
242
+ 63 => "ZBR_SDK_ERROR_INVALID_PARAMETER One of the arguments is invalid",
243
+ 64 => "ZBR_SDK_ERROR_PRINTER_BUSY Printer is in use",
244
+ 65 => "ZBR_SDK_ERROR_INVALID_PRINTER_HANDLE Invalid printer handle",
245
+ 66 => "ZBR_SDK_ERROR_CLOSE_HANDLE_ERROR Error closing printer driver handle",
246
+ 67 => "ZBR_SDK_ERROR_COMMUNICATION_ERROR Command failed due to communication error",
247
+ 68 => "ZBR_SDK_ERROR_BUFFER_OVERFLOW Response too large for buffer",
248
+ 69 => "ZBR_SDK_ERROR_READ_DATA_ERROR Error reading data",
249
+ 70 => "ZBR_SDK_ERROR_WRITE_DATA_ERROR Error writing data",
250
+ 71 => "ZBR_SDK_ERROR_LOAD_LIBRARY_ERROR Error loading SDK",
251
+ 72 => "ZBR_SDK_ERROR_INVALID_STRUCT_ALIGNMENT Invalid structure alignment",
252
+ 73 => "ZBR_SDK_ERROR_GETTING_DEVICE_CONTEXT Unable to create the device context for the driver",
253
+ 74 => "ZBR_SDK_ERROR_SPOOLER_ERROR Print spooler error",
254
+ 75 => "ZBR_SDK_ERROR_OUT_OF_MEMORY Operating system is out of memory",
255
+ 76 => "ZBR_SDK_ERROR_OUT_OF_DISK_SPACE Operating system is out of disk space",
256
+ 77 => "ZBR_SDK_ERROR_USER_ABORT Print job aborted by the user",
257
+ 78 => "ZBR_SDK_ERROR_APPLICATION_ABORT Application aborted",
258
+ 79 => "ZBR_SDK_ERROR_CREATE_FILE_ERROR Error creating file",
259
+ 80 => "ZBR_SDK_ERROR_WRITE_FILE_ERROR Error writing file",
260
+ 81 => "ZBR_SDK_ERROR_READ_FILE_ERROR Error reading file",
261
+ 82 => "ZBR_SDK_ERROR_INVALID_MEDIA Invalid media",
262
+ 8001 => "ZBR_GDI_ERROR_GENERIC_ERROR Window API error, call GetLastError() function from Win32 API for error information",
263
+ 8002 => "ZBR_GDI_ERROR_INVALID_PARAMETER One of the arguments is invalid",
264
+ 8003 => "ZBR_GDI_ERROR_OUT_OF_MEMORY Operating system is out of memory",
265
+ 8004 => "ZBR_GDI_ERROR_OBJECT_BUSY One of the objects specified in the API call is in use",
266
+ 8005 => "ZBR_GDI_ERROR_INSUFFICIENT_BUFFER A buffer specified as an argument in the API call is not large enough",
267
+ 8006 => "ZBR_GDI_ERROR_NOT_IMPLEMENTED Method is not implemented ",
268
+ 8007 => "ZBR_GDI_ERROR_WIN32_ERROR Method generated a Win32 error, call GetLastError() function from Win32 API for error information",
269
+ 8008 => "ZBR_GDI_ERROR_WRONG_STATE Object called by the API is in an invalid state",
270
+ 8009 => "ZBR_GDI_ERROR_ABORTED Method aborted",
271
+ 8010 => "ZBR_GDI_ERROR_FILE_NOT_FOUND File not found",
272
+ 8011 => "ZBR_GDI_ERROR_VALUE_OVERFLOW Arithmetic operation in the method caused a numeric overflow",
273
+ 8012 => "ZBR_GDI_ERROR_ACCESS_DENIED Access denied to the specified file ",
274
+ 8013 => "ZBR_GDI_ERROR_UNKNOWN_IMAGE_FORMAT Specified image file format is unknown",
275
+ 8014 => "ZBR_GDI_ERROR_FONT_FAMILY_NOT_FOUND Specified font is not installed",
276
+ 8015 => "ZBR_GDI_ERROR_FONT_STYLE_NOT_FOUND Invalid font style",
277
+ 8016 => "ZBR_GDI_ERROR_NOT_TRUE_TYPE_FONT Specified font is not a True Type font and cannot be used with GDI+",
278
+ 8017 => "ZBR_GDI_ERROR_UNSUPPORTED_GDIPLUS_VERSION Installed GDI+ version",
279
+ 8018 => "ZBR_GDI_ERROR_GDIPLUS_NOT_INITIALIZED The GDI+ API is not initialized",
280
+ 8019 => "ZBR_GDI_ERROR_PROPERTY_NOT_FOUND Specified property does not exist in the image",
281
+ 8020 => "ZBR_GDI_ERROR_PROPERTY_NOT_SUPPORTED Specified property is not supported by the image format",
282
+ 8021 => "ZBR_GDI_ERROR_GRAPHICS_ALREADY_INITIALIZED Graphic buffer has already been initialized",
283
+ 8022 => "ZBR_GDI_ERROR_NO_GRAPHIC_DATA No data in the graphic buffer to print",
284
+ 8023 => "ZBR_GDI_ERROR_GRAPHICS_NOT_INITIALIZED Graphics buffer has not been initialized",
285
+ 8024 => "ZBR_GDI_ERROR_GETTING_DEVICE_CONTEXT Unable to create the device context for the driver",
286
+ 8025 => "ZBR_DLG_ERROR_DLG_CANCELED User closed or canceled the DLG window",
287
+ 8026 => "ZBR_DLG_ERROR_SETUP_FAILURE PrintDlg function failed to load the required resources",
288
+ 8027 => "ZBR_DLG_ERROR_PARSE_FAILURE PrintDlg function failed to parse the strings in the [devices] section of the WIN.INI file",
289
+ 8028 => "ZBR_DLG_ERROR_RET_DEFAULT_FAILUREPD_RETURNDEFAULT flag was specified in the Flags member of the PRINTDLG structure, but the hDevMode or hDevNames member was not NULL",
290
+ 8029 => "ZBR_DLG_ERROR_LOAD_DRV_FAILURE PrintDlg function failed to load the device driver for the specified printer",
291
+ 8030 => "ZBR_DLG_ERROR_GET_DEVMODE_FAIL Printer driver failed to initialize a DEVMODE structure",
292
+ 8031 => "ZBR_DLG_ERROR_INIT_FAILURE PrintDlg function failed during initialization, and there is no more specific extended error code to describe the failure",
293
+ 8032 => "ZBR_DLG_ERROR_NO_DEVICES No printer drivers were found",
294
+ 8033 => "ZBR_DLG_ERROR_NO_DEFAULT_PRINTER A default printer does not exist",
295
+ 8034 => "ZBR_DLG_ERROR_DN_DM_MISMATCH Data in the DEVMODE and DEVNAMES structures describes two different printers",
296
+ 8035 => "ZBR_DLG_ERROR_CREATE_IC_FAILURE PrintDlg function failed when it attempted to create an information context",
297
+ 8036 => "ZBR_DLG_ERROR_PRINTER_NOT_FOUND The [devices] section of the WIN.INI file did not contain an entry for the requested printer",
298
+ 8037 => "ZBR_DLG_ERROR_DEFAULT_DIFFERENT Error occurs when you store the DEVNAMES structure, and the user changes the default printer by using the Control Panel"
299
+ }
300
+
301
+ def initialize(error_code, message)
302
+ error_message = ZebraException.get_message(error_code)
303
+ super("#{message} (#{error_code} - #{error_message})")
304
+ end
305
+
306
+ def self.get_message(error_code)
307
+ ERRORS[error_code]
308
+ end
309
+ end
310
+
311
+ if __FILE__ == $0
312
+ printer = PrinterZebra.new
313
+ printer.open_handle("Zebra P430i Card Printer USB")
314
+ printer.send_cmd("MCL")
315
+ printer.close_handle
316
+
317
+ sleep(5)
318
+
319
+ printer.open_handle("Zebra P430i Card Printer USB")
320
+ printer.send_cmd("MRB")
321
+ printer.close_handle
322
+ end
323
+ end
324
+ end