Page 1 of 1

Printing in a kind'o'way

Posted: Sat Nov 15, 2014 3:04 am
by JB_AU
If i have an image file i can print this from within fs with;
rundll32 C:\WINDOWS\system32\shimgvw.dll,ImageView_PrintTo "c:\myfile.bmp" "Brother DCP-165C Printer"

The thing i am looking for is capturing a part of the fs window, saving it and then pipe of to shimgvw.dll

This is were i am stuck, as the final gui doesn't have separate wHandle's , so my thinking of current is to take the values of a module and launch in a separate window where i can pre format the data & then print.

All ideas appreciated

Re: Printing in a kind'o'way

Posted: Sat Nov 15, 2014 8:21 am
by Tronic
My idea is to grab the screen with simulate the key press of keyboard Print, so save the clipboard data to file, open it in FS, manipulate and send it to Printer.

Re: Printing in a kind'o'way

Posted: Sat Nov 15, 2014 8:27 am
by JB_AU
Problem with send keys, how do you interpret when a user uses the keyboard & how do you edit the image only to include the area you want.

Re: Printing in a kind'o'way

Posted: Sat Nov 15, 2014 8:34 am
by Tronic
using only commnd line thing, or WinAPI you can not do what you want,
with the WinAPI but you may do so:
check the focus of the current window
simulate a keypress button Print
save the image that is now on the clipboard

to have a control over the size and position you should opt for a solution in DLL

Re: Printing in a kind'o'way

Posted: Sat Nov 15, 2014 12:26 pm
by JB_AU
I've already started with gdi , but thanks tho!

Re: Printing in a kind'o'way

Posted: Sat Nov 15, 2014 10:43 pm
by JB_AU
With win32api i am trying to put these pieces together slooooowly

Code: Select all

Win32API.new("user32", "GetWindowDC", "L", "L")
Win32API.new("gdi32", "CreateCompatibleDC", "L", "L")
Win32API.new("gdi32","CreateCompatibleBitmap", ["L", "I", "I"], "L")
Win32API.new("gdi32", "SelectObject", ["L", "L"], "L")
Win32API.new("gdi32", "BitBlt", "L", "I", "I", "I", "I", "L", "I", "I", "L", "B")
#Pipe from mem to printer
#ReleaseDC
#DeleteDC
#DeleteObject

Re: Printing in a kind'o'way

Posted: Sat Nov 15, 2014 11:30 pm
by tulamide
JB_AU wrote:With win32api i am trying to put these pieces together slooooowly

Code: Select all

Win32API.new("user32", "GetWindowDC", "L", "L")
Win32API.new("gdi32", "CreateCompatibleDC", "L", "L")
Win32API.new("gdi32","CreateCompatibleBitmap", ["L", "I", "I"], "L")
Win32API.new("gdi32", "SelectObject", ["L", "L"], "L")
Win32API.new("gdi32", "BitBlt", "L", "I", "I", "I", "I", "L", "I", "I", "L", "B")
#Pipe from mem to printer
#ReleaseDC
#DeleteDC
#DeleteObject

One question: Where do you grab the constants' values from? I was interested in doing some win32api accessing, too, when trying to provide a solution for menus and listboxes, but the neccesssary constants' values are not on msdn, just their names. Are you using the header files? Where did you download them? Questions over questions... :mrgreen:

Re: Printing in a kind'o'way

Posted: Sun Nov 16, 2014 12:03 am
by JB_AU
https://www.google.co.jp/?hl=en&gws_rd=ssl

Which gives more information on ruby & win32api than "EnGoogle" itself :x

Re: Printing in a kind'o'way

Posted: Sun Nov 16, 2014 1:11 pm
by JB_AU
Strolling for more information i came across these goodies

Code: Select all

require 'Win32API'

module GDIP

  CLSID_BMP     = '557CF400-1A04-11D3-9A73-0000F81EF32E'
  CLSID_JPEG    = '557CF401-1A04-11D3-9A73-0000F81EF32E'
  CLSID_GIF     = '557CF402-1A04-11D3-9A73-0000F81EF32E'
  CLSID_TIFF    = '557CF405-1A04-11D3-9A73-0000F81EF32E'
  CLSID_PNG     = '557CF406-1A04-11D3-9A73-0000F81EF32E'
 
  CLSID_QUALITY = '1D5BE4B5-FA4A-452D-9CDD-5DB35105E7EB'
 
  CP_ACP   = 0x0000
  CP_UTF8  = 0xFDE9
 
  MultiByteToWideChar       = Win32API.new('kernel32', 'MultiByteToWideChar', 'iipipi', 'i')
  FindWindow          = Win32API.new('user32', 'FindWindow', 'pp', 'l')
  GetDC          = Win32API.new('user32', 'GetDC', 'i', 'i')
  ReleaseDC          = Win32API.new('user32', 'ReleaseDC', 'ii', 'i')
  BitBlt          = Win32API.new('gdi32', 'BitBlt', 'iiiiiiiii', 'i')
  CreateCompatibleDC       = Win32API.new('gdi32', 'CreateCompatibleDC', 'i', 'i')
  CreateCompatibleBitmap    = Win32API.new('gdi32', 'CreateCompatibleBitmap', 'iii', 'i')
  SelectObject          = Win32API.new('gdi32', 'SelectObject', 'ii', 'i')
  DeleteDC          = Win32API.new('gdi32', 'DeleteDC', 'i', 'i')
  DeleteObject          = Win32API.new('gdi32', 'DeleteObject', 'i', 'i')
 
  GdiplusStartup       = Win32API.new('gdiplus', 'GdiplusStartup', 'ppi', 'i')
  GdipCreateBitmapFromScan0    = Win32API.new('gdiplus', 'GdipCreateBitmapFromScan0', 'iiiipp', 'i')
  GdipCreateBitmapFromHBITMAP    = Win32API.new('gdiplus', 'GdipCreateBitmapFromHBITMAP', 'iip', 'i')
  GdipBitmapConvertFormat    = Win32API.new('gdiplus', 'GdipBitmapConvertFormat', 'piiipi', 'i') rescue nil
  GdipSaveImageToFile       = Win32API.new('gdiplus', 'GdipSaveImageToFile', 'pppp', 'i')
  GdipDisposeImage       = Win32API.new('gdiplus', 'GdipDisposeImage', 'p', 'i')
  GdiplusShutdown       = Win32API.new('gdiplus', 'GdiplusShutdown', 'p', 'v')

  UuidFromString       = Win32API.new('rpcrt4', 'UuidFromString', 'pp', 'i')
   
  GdipBitmapLockBits       = Win32API.new('gdiplus', 'GdipBitmapLockBits', 'ppiip', 'i')
  GdipBitmapUnlockBits       = Win32API.new('gdiplus', 'GdipBitmapUnlockBits', 'pp', 'i')
 
  RtlMoveMemory       = Win32API.new('kernel32', 'RtlMoveMemory', 'ppi', 'v')
   
  PF_RGB  = 0x00021808
  PF_ARGB = 0x0026200A


  WINDOW_TITLE  = load_data("Data/System.rvdata2").window_title.encode('SHIFT_JIS')
  WINDOW_HANDLE = FindWindow.call("RGSS Player", WINDOW_TITLE)
 
module_function

  def MultiByteToWideChar(str)
    buffer = [""].pack('Z256')
    MultiByteToWideChar.call(CP_UTF8, 0, str, -1, buffer, buffer.size)
    return buffer
  end

  def GetDC(hwnd)
    return GetDC.call(WINDOW_HANDLE)
  end

  def ReleaseDC(hwnd, hdc)
    ReleaseDC.call(hwnd, hdc)
  end

  def CopyDC(dest, src, width, height)
    BitBlt.call(dest, 0, 0, width, height, src, 0, 0, 0xCC0020)
  end

  def CreateCompatibleDC(hdc)
    return CreateCompatibleDC.call(hdc)
  end

  def CreateCompatibleBitmap(hdc, width, height)
    return CreateCompatibleBitmap.call(hdc, width, height)
  end

  def SelectObject(hdc, obj)
    return SelectObject.call(hdc, obj) != 0
  end

  def DeleteDC(hdc)
    DeleteObject.call(hdc)
  end

  def DeleteObject(obj)
    DeleteObject.call(obj)
  end

  def GdiplusStartup(token)
    ret = GdiplusStartup.call(token, [1, 0, 0, 0].pack("i4"), 0) == 0
    unless ret
      msgbox "GDI+ failed in the initialization."
    end
    return ret
  end

  def GdipCreateImageFromBitmap(bitmap)
    gpbmp = [0].pack("i")
    if GdipCreateBitmapFromScan0.call(
      bitmap.width, bitmap.height, 0, PF_ARGB, 0, gpbmp) == 0
     
      image = gpbmp.unpack("i")[0]
      r = [0, 0, bitmap.width, bitmap.height].pack("i4")
      bd = [0, 0, 0, 0, 0, 0].pack("i6")
      GdipBitmapLockBits.call(image, r, 3, PF_ARGB, bd)
      GdipBitmapUnlockBits.call(image, bd)
      bd = bd.unpack("i*")
      data = Array.new(bitmap.width * bitmap.height * 4, 0).pack("C*")
      RtlMoveMemory.call(data, bitmap.data, data.size)
      data = data.unpack("C*")
      data = Array.new(bitmap.height) do |i|
        data[data.size - bitmap.width * 4 * (i + 1), bitmap.width * 4]
      end.flatten!.pack("C*")
      RtlMoveMemory.call(bd[4], data, bitmap.width * bitmap.height * 4)
     
      return image
    else
      return nil
    end
  end

  def GdipCreateImageFromHBITMAP(hbm)
    gpbmp = [0].pack("i")
    if GdipCreateBitmapFromHBITMAP.call(hbm, 0, gpbmp) == 0
      return gpbmp.unpack("i")[0]
    else
      return nil
    end
  end

  def GdipSaveImageToFile(image, filename, clsid)
    ret = GdipSaveImageToFile.call(image, filename, UuidFromString(clsid), 0)
    msgbox "failed to save." if ret != 0
  end

  def GdipImageConvertPixelFormat(image, pixel_format)
    return unless GdipBitmapConvertFormat
    GdipBitmapConvertFormat.call(image, pixel_format, 0, 0, 0, 0)
  end

  def GdipDisposeImage(image)
    GdipDisposeImage.call(image)
  end

  def GdiplusShutdown(token)
    GdiplusShutdown.call(token)
  end

  def UuidFromString(clsid)
    uuid = [0].pack("i")
    UuidFromString.call(clsid, uuid)
    return uuid
  end
end

class Bitmap

  RtlMoveMemory_pi = Win32API.new('kernel32', 'RtlMoveMemory', 'pii', 'i')
  RtlMoveMemory_ip = Win32API.new('kernel32', 'RtlMoveMemory', 'ipi', 'i')

  def info
    dib = [40, self.width, self.height, 1, 32, 0, 0, 0, 0, 0, 0].pack("i3s2i6")
    return [dib].pack("P").unpack("i")[0]
  end

  def data
    buffer = [0].pack('L')
    RtlMoveMemory_pi.call(buffer, object_id * 2 + 16, 4)
    RtlMoveMemory_pi.call(buffer, buffer.unpack("L")[0] + 8, 4)
    RtlMoveMemory_pi.call(buffer, buffer.unpack("L")[0] + 16, 4)
    return buffer.unpack("L")[0]
  end

  def save(fn, type, back = nil)
    bitmap = Bitmap.new(self.width, self.height)
    case back
    when Color;       bitmap.fill_rect(self.rect, back)
    when Array;       bitmap.fill_rect(self.rect, Color.new(*back))
    when /^white$/i;  bitmap.fill_rect(self.rect, Color.new(255, 255, 255))
    end
    bitmap.blt(0, 0, self, self.rect)
   
    case type
    when /^BMP$/i;    clsid, ext = GDIP::CLSID_BMP,   ".bmp"
    when /^PNG$/i;    clsid, ext = GDIP::CLSID_PNG,   ".png"
    when /^JPE?G$/i;  clsid, ext = GDIP::CLSID_JPEG,  ".jpg"
    when /^GIF$/i;    clsid, ext = GDIP::CLSID_GIF,   ".gif"
    else;             raise ""
    end
    fn += ext if File.extname(fn).empty?
    filename = GDIP::MultiByteToWideChar(fn)
   
    token = [0].pack("i")
    if GDIP::GdiplusStartup(token)
      image = GDIP::GdipCreateImageFromBitmap(bitmap)
      if image
        GDIP::GdipSaveImageToFile(image, filename, clsid)
        GDIP::GdipDisposeImage(image)
      end
      GDIP::GdiplusShutdown(token)
    end
   
    bitmap.dispose
  end

  def save_png(filename, alpha = false)
    save(filename, :PNG, alpha ? nil : :white)
  end
end

module Graphics

  def self.save_screen(fn, type)
    case type
    when /^BMP$/i;    clsid, ext = GDIP::CLSID_BMP,   ".bmp"
    when /^PNG$/i;    clsid, ext = GDIP::CLSID_PNG,   ".png"
    when /^JPE?G$/i;  clsid, ext = GDIP::CLSID_JPEG,  ".jpg"
    when /^GIF$/i;    clsid, ext = GDIP::CLSID_GIF,   ".gif"
    else;             raise ""
    end
    fn += ext if File.extname(fn).empty?
    filename = GDIP::MultiByteToWideChar(fn)
   
    wnddc = GDIP::GetDC(GDIP::WINDOW_HANDLE)
    memdc = GDIP::CreateCompatibleDC(wnddc)
    hbm = GDIP::CreateCompatibleBitmap(wnddc, Graphics.width, Graphics.height)
    if GDIP::SelectObject(memdc, hbm)
      GDIP::CopyDC(memdc, wnddc, Graphics.width, Graphics.height)
      token = [0].pack("i")
      if GDIP::GdiplusStartup(token)
        image = GDIP::GdipCreateImageFromHBITMAP(hbm)
        GDIP::GdipImageConvertPixelFormat(image, GDIP::PF_ARGB)
        if image
          GDIP::GdipSaveImageToFile(image, filename, clsid)
          GDIP::GdipDisposeImage(image)
        end
        GDIP::GdiplusShutdown(token)
      end
    end
    GDIP::ReleaseDC(GDIP::WINDOW_HANDLE, wnddc)
    GDIP::DeleteDC(memdc)
    GDIP::DeleteObject(hbm)
  end
end


And this i like too;

Code: Select all

require 'Win32API'

OpenPrinter     = Win32API.new('winspool.drv','OpenPrinter', ['P', 'P', 'P'], 'L')
StartDocPrinter = Win32API.new('winspool.drv','StartDocPrinter', ['L', 'L', 'P'], 'L')
EndDocPrinter   = Win32API.new('winspool.drv','EndDocPrinter', ['L'], 'L')
WritePrinter    = Win32API.new('winspool.drv','WritePrinter', ['L', 'P', 'L', 'P'], 'L')
ClosePrinter    = Win32API.new('winspool.drv','ClosePrinter', ['L'], 'L')
GetLastError    = Win32API.new('kernel32','GetLastError', [], 'L')

def open_printer(nm, dev=nil)
    hdl = [0].pack("I")
    r = OpenPrinter.call(nm, hdl, nil)
    hdl = hdl.unpack("I")[0]
    [r, hdl]
end

def start_doc_printer(hdl)
    StartDocPrinter.call(hdl, 1, "\0"*4*3)
end

def write_printer(hdl, data)
    sz = [0].pack("I")
    rslt = WritePrinter.call(hdl, data, data.size, sz)
    [rslt, sz.unpack("I")[0]]
end

def end_doc_printer(hdl) EndDocPrinter.call(hdl) end
def close_printer(hdl) ClosePrinter.call(hdl) end

if __FILE__ == $0

    if ARGV.size <= 1
        print "Usage: #{$0} spoolfile printer\n"
        exit
    end

    prn = ARGV[1].dup

    rslt, hdl = open_printer(prn)
    print "OpenPrinter(#{prn}) --> #{rslt}, hdl:#{hdl}\n"
    rslt = start_doc_printer(hdl)
    print "startDocPrinter --> jobnum: #{rslt}\n"

    spldata = ""
    File.open(ARGV[0], "rb") {|fp| spldata = fp.read}

    rslt, sz = write_printer(hdl, spldata)
    print "WritePrinter    --> #{rslt}, size:#{sz}, err:#{GetLastError.call}\n"

    rslt = end_doc_printer(hdl)
    print "endDocPrinter   --> #{rslt}\n"

    rslt = close_printer(hdl)
    print "closePrinter    --> #{rslt}\n"
end


I'm salivating :shock: :o

Re: Printing in a kind'o'way

Posted: Mon Nov 17, 2014 11:30 pm
by Exo
JB_AU wrote:Strolling for more information i came across these goodies

Code: Select all

require 'Win32API'

module GDIP

  CLSID_BMP     = '557CF400-1A04-11D3-9A73-0000F81EF32E'
  CLSID_JPEG    = '557CF401-1A04-11D3-9A73-0000F81EF32E'
  CLSID_GIF     = '557CF402-1A04-11D3-9A73-0000F81EF32E'
  CLSID_TIFF    = '557CF405-1A04-11D3-9A73-0000F81EF32E'
  CLSID_PNG     = '557CF406-1A04-11D3-9A73-0000F81EF32E'
 
  CLSID_QUALITY = '1D5BE4B5-FA4A-452D-9CDD-5DB35105E7EB'
 
  CP_ACP   = 0x0000
  CP_UTF8  = 0xFDE9
 
  MultiByteToWideChar       = Win32API.new('kernel32', 'MultiByteToWideChar', 'iipipi', 'i')
  FindWindow          = Win32API.new('user32', 'FindWindow', 'pp', 'l')
  GetDC          = Win32API.new('user32', 'GetDC', 'i', 'i')
  ReleaseDC          = Win32API.new('user32', 'ReleaseDC', 'ii', 'i')
  BitBlt          = Win32API.new('gdi32', 'BitBlt', 'iiiiiiiii', 'i')
  CreateCompatibleDC       = Win32API.new('gdi32', 'CreateCompatibleDC', 'i', 'i')
  CreateCompatibleBitmap    = Win32API.new('gdi32', 'CreateCompatibleBitmap', 'iii', 'i')
  SelectObject          = Win32API.new('gdi32', 'SelectObject', 'ii', 'i')
  DeleteDC          = Win32API.new('gdi32', 'DeleteDC', 'i', 'i')
  DeleteObject          = Win32API.new('gdi32', 'DeleteObject', 'i', 'i')
 
  GdiplusStartup       = Win32API.new('gdiplus', 'GdiplusStartup', 'ppi', 'i')
  GdipCreateBitmapFromScan0    = Win32API.new('gdiplus', 'GdipCreateBitmapFromScan0', 'iiiipp', 'i')
  GdipCreateBitmapFromHBITMAP    = Win32API.new('gdiplus', 'GdipCreateBitmapFromHBITMAP', 'iip', 'i')
  GdipBitmapConvertFormat    = Win32API.new('gdiplus', 'GdipBitmapConvertFormat', 'piiipi', 'i') rescue nil
  GdipSaveImageToFile       = Win32API.new('gdiplus', 'GdipSaveImageToFile', 'pppp', 'i')
  GdipDisposeImage       = Win32API.new('gdiplus', 'GdipDisposeImage', 'p', 'i')
  GdiplusShutdown       = Win32API.new('gdiplus', 'GdiplusShutdown', 'p', 'v')

  UuidFromString       = Win32API.new('rpcrt4', 'UuidFromString', 'pp', 'i')
   
  GdipBitmapLockBits       = Win32API.new('gdiplus', 'GdipBitmapLockBits', 'ppiip', 'i')
  GdipBitmapUnlockBits       = Win32API.new('gdiplus', 'GdipBitmapUnlockBits', 'pp', 'i')
 
  RtlMoveMemory       = Win32API.new('kernel32', 'RtlMoveMemory', 'ppi', 'v')
   
  PF_RGB  = 0x00021808
  PF_ARGB = 0x0026200A


  WINDOW_TITLE  = load_data("Data/System.rvdata2").window_title.encode('SHIFT_JIS')
  WINDOW_HANDLE = FindWindow.call("RGSS Player", WINDOW_TITLE)
 
module_function

  def MultiByteToWideChar(str)
    buffer = [""].pack('Z256')
    MultiByteToWideChar.call(CP_UTF8, 0, str, -1, buffer, buffer.size)
    return buffer
  end

  def GetDC(hwnd)
    return GetDC.call(WINDOW_HANDLE)
  end

  def ReleaseDC(hwnd, hdc)
    ReleaseDC.call(hwnd, hdc)
  end

  def CopyDC(dest, src, width, height)
    BitBlt.call(dest, 0, 0, width, height, src, 0, 0, 0xCC0020)
  end

  def CreateCompatibleDC(hdc)
    return CreateCompatibleDC.call(hdc)
  end

  def CreateCompatibleBitmap(hdc, width, height)
    return CreateCompatibleBitmap.call(hdc, width, height)
  end

  def SelectObject(hdc, obj)
    return SelectObject.call(hdc, obj) != 0
  end

  def DeleteDC(hdc)
    DeleteObject.call(hdc)
  end

  def DeleteObject(obj)
    DeleteObject.call(obj)
  end

  def GdiplusStartup(token)
    ret = GdiplusStartup.call(token, [1, 0, 0, 0].pack("i4"), 0) == 0
    unless ret
      msgbox "GDI+ failed in the initialization."
    end
    return ret
  end

  def GdipCreateImageFromBitmap(bitmap)
    gpbmp = [0].pack("i")
    if GdipCreateBitmapFromScan0.call(
      bitmap.width, bitmap.height, 0, PF_ARGB, 0, gpbmp) == 0
     
      image = gpbmp.unpack("i")[0]
      r = [0, 0, bitmap.width, bitmap.height].pack("i4")
      bd = [0, 0, 0, 0, 0, 0].pack("i6")
      GdipBitmapLockBits.call(image, r, 3, PF_ARGB, bd)
      GdipBitmapUnlockBits.call(image, bd)
      bd = bd.unpack("i*")
      data = Array.new(bitmap.width * bitmap.height * 4, 0).pack("C*")
      RtlMoveMemory.call(data, bitmap.data, data.size)
      data = data.unpack("C*")
      data = Array.new(bitmap.height) do |i|
        data[data.size - bitmap.width * 4 * (i + 1), bitmap.width * 4]
      end.flatten!.pack("C*")
      RtlMoveMemory.call(bd[4], data, bitmap.width * bitmap.height * 4)
     
      return image
    else
      return nil
    end
  end

  def GdipCreateImageFromHBITMAP(hbm)
    gpbmp = [0].pack("i")
    if GdipCreateBitmapFromHBITMAP.call(hbm, 0, gpbmp) == 0
      return gpbmp.unpack("i")[0]
    else
      return nil
    end
  end

  def GdipSaveImageToFile(image, filename, clsid)
    ret = GdipSaveImageToFile.call(image, filename, UuidFromString(clsid), 0)
    msgbox "failed to save." if ret != 0
  end

  def GdipImageConvertPixelFormat(image, pixel_format)
    return unless GdipBitmapConvertFormat
    GdipBitmapConvertFormat.call(image, pixel_format, 0, 0, 0, 0)
  end

  def GdipDisposeImage(image)
    GdipDisposeImage.call(image)
  end

  def GdiplusShutdown(token)
    GdiplusShutdown.call(token)
  end

  def UuidFromString(clsid)
    uuid = [0].pack("i")
    UuidFromString.call(clsid, uuid)
    return uuid
  end
end

class Bitmap

  RtlMoveMemory_pi = Win32API.new('kernel32', 'RtlMoveMemory', 'pii', 'i')
  RtlMoveMemory_ip = Win32API.new('kernel32', 'RtlMoveMemory', 'ipi', 'i')

  def info
    dib = [40, self.width, self.height, 1, 32, 0, 0, 0, 0, 0, 0].pack("i3s2i6")
    return [dib].pack("P").unpack("i")[0]
  end

  def data
    buffer = [0].pack('L')
    RtlMoveMemory_pi.call(buffer, object_id * 2 + 16, 4)
    RtlMoveMemory_pi.call(buffer, buffer.unpack("L")[0] + 8, 4)
    RtlMoveMemory_pi.call(buffer, buffer.unpack("L")[0] + 16, 4)
    return buffer.unpack("L")[0]
  end

  def save(fn, type, back = nil)
    bitmap = Bitmap.new(self.width, self.height)
    case back
    when Color;       bitmap.fill_rect(self.rect, back)
    when Array;       bitmap.fill_rect(self.rect, Color.new(*back))
    when /^white$/i;  bitmap.fill_rect(self.rect, Color.new(255, 255, 255))
    end
    bitmap.blt(0, 0, self, self.rect)
   
    case type
    when /^BMP$/i;    clsid, ext = GDIP::CLSID_BMP,   ".bmp"
    when /^PNG$/i;    clsid, ext = GDIP::CLSID_PNG,   ".png"
    when /^JPE?G$/i;  clsid, ext = GDIP::CLSID_JPEG,  ".jpg"
    when /^GIF$/i;    clsid, ext = GDIP::CLSID_GIF,   ".gif"
    else;             raise ""
    end
    fn += ext if File.extname(fn).empty?
    filename = GDIP::MultiByteToWideChar(fn)
   
    token = [0].pack("i")
    if GDIP::GdiplusStartup(token)
      image = GDIP::GdipCreateImageFromBitmap(bitmap)
      if image
        GDIP::GdipSaveImageToFile(image, filename, clsid)
        GDIP::GdipDisposeImage(image)
      end
      GDIP::GdiplusShutdown(token)
    end
   
    bitmap.dispose
  end

  def save_png(filename, alpha = false)
    save(filename, :PNG, alpha ? nil : :white)
  end
end

module Graphics

  def self.save_screen(fn, type)
    case type
    when /^BMP$/i;    clsid, ext = GDIP::CLSID_BMP,   ".bmp"
    when /^PNG$/i;    clsid, ext = GDIP::CLSID_PNG,   ".png"
    when /^JPE?G$/i;  clsid, ext = GDIP::CLSID_JPEG,  ".jpg"
    when /^GIF$/i;    clsid, ext = GDIP::CLSID_GIF,   ".gif"
    else;             raise ""
    end
    fn += ext if File.extname(fn).empty?
    filename = GDIP::MultiByteToWideChar(fn)
   
    wnddc = GDIP::GetDC(GDIP::WINDOW_HANDLE)
    memdc = GDIP::CreateCompatibleDC(wnddc)
    hbm = GDIP::CreateCompatibleBitmap(wnddc, Graphics.width, Graphics.height)
    if GDIP::SelectObject(memdc, hbm)
      GDIP::CopyDC(memdc, wnddc, Graphics.width, Graphics.height)
      token = [0].pack("i")
      if GDIP::GdiplusStartup(token)
        image = GDIP::GdipCreateImageFromHBITMAP(hbm)
        GDIP::GdipImageConvertPixelFormat(image, GDIP::PF_ARGB)
        if image
          GDIP::GdipSaveImageToFile(image, filename, clsid)
          GDIP::GdipDisposeImage(image)
        end
        GDIP::GdiplusShutdown(token)
      end
    end
    GDIP::ReleaseDC(GDIP::WINDOW_HANDLE, wnddc)
    GDIP::DeleteDC(memdc)
    GDIP::DeleteObject(hbm)
  end
end


And this i like too;

Code: Select all

require 'Win32API'

OpenPrinter     = Win32API.new('winspool.drv','OpenPrinter', ['P', 'P', 'P'], 'L')
StartDocPrinter = Win32API.new('winspool.drv','StartDocPrinter', ['L', 'L', 'P'], 'L')
EndDocPrinter   = Win32API.new('winspool.drv','EndDocPrinter', ['L'], 'L')
WritePrinter    = Win32API.new('winspool.drv','WritePrinter', ['L', 'P', 'L', 'P'], 'L')
ClosePrinter    = Win32API.new('winspool.drv','ClosePrinter', ['L'], 'L')
GetLastError    = Win32API.new('kernel32','GetLastError', [], 'L')

def open_printer(nm, dev=nil)
    hdl = [0].pack("I")
    r = OpenPrinter.call(nm, hdl, nil)
    hdl = hdl.unpack("I")[0]
    [r, hdl]
end

def start_doc_printer(hdl)
    StartDocPrinter.call(hdl, 1, "\0"*4*3)
end

def write_printer(hdl, data)
    sz = [0].pack("I")
    rslt = WritePrinter.call(hdl, data, data.size, sz)
    [rslt, sz.unpack("I")[0]]
end

def end_doc_printer(hdl) EndDocPrinter.call(hdl) end
def close_printer(hdl) ClosePrinter.call(hdl) end

if __FILE__ == $0

    if ARGV.size <= 1
        print "Usage: #{$0} spoolfile printer\n"
        exit
    end

    prn = ARGV[1].dup

    rslt, hdl = open_printer(prn)
    print "OpenPrinter(#{prn}) --> #{rslt}, hdl:#{hdl}\n"
    rslt = start_doc_printer(hdl)
    print "startDocPrinter --> jobnum: #{rslt}\n"

    spldata = ""
    File.open(ARGV[0], "rb") {|fp| spldata = fp.read}

    rslt, sz = write_printer(hdl, spldata)
    print "WritePrinter    --> #{rslt}, size:#{sz}, err:#{GetLastError.call}\n"

    rslt = end_doc_printer(hdl)
    print "endDocPrinter   --> #{rslt}\n"

    rslt = close_printer(hdl)
    print "closePrinter    --> #{rslt}\n"
end


I'm salivating :shock: :o


Very cool JB_AU :)

I might have to look into this more myself ;)