# windlg.rb for windows
# TEXCELL '19.06 Ver.1.04  '12.04 Ver.1.0
require 'fiddle/import'
require 'win32ole'

class OPENFILENAME < Struct.new(:sTitle, :sArFilter, :iFilterIndx, :sIniDir, :iFlags, :sFnameFull, :sFname)
  def initialize(sTitle = "", sArFilter = [["all(*.*)", "*.*"]], iFilterIndx = 1, sIniDir = "c:\\", iFlags = 0)
    super(sTitle, sArFilter, iFilterIndx, sIniDir, iFlags, nil, nil)
  end
end

module WDUser32
   extend Fiddle::Importer
   dlload "user32"
   typealias("UINT", "unsigned int")
   extern "int MessageBoxW(int,void*,void*,UINT)",:stdcall
end

module WDComdlg32
   extend Fiddle::Importer
   dlload "comdlg32"
   typealias("BOOL", "int")
   extern "BOOL GetOpenFileNameW(void*)",:stdcall
   extern "BOOL GetSaveFileNameW(void*)",:stdcall
end

module WDKernel32
   extend Fiddle::Importer
   dlload "kernel32"
   typealias("DWORD", "unsigned int")
   extern "int MultiByteToWideChar(unsigned int,DWORD,char*,int,char*,int)",:stdcall
   extern "int WideCharToMultiByte(unsigned int,DWORD,char*,int,char*,int,char*,char*)",:stdcall
end

class WinDlgt

   MB_OK =                0x00000000
   MB_OKCANCEL =          0x00000001
   MB_ABORTRETRYIGNORE =  0x00000002
   MB_YESNOCANCEL =       0x00000003
   MB_YESNO =             0x00000004
   MB_RETRYCANCEL =       0x00000005
   MB_CANCELTRYCONTINUE = 0x00000006

   MB_ICONHAND =          0x00000010
   MB_ICONQUESTION =      0x00000020
   MB_ICONEXCLAMATION =   0x00000030
   MB_ICONASTERISK =      0x00000040
#   MB_USERICON =          0x00000080
   MB_ICONWARNING =       MB_ICONEXCLAMATION
   MB_ICONERROR =         MB_ICONHAND
   MB_ICONINFORMATION =   MB_ICONASTERISK
   MB_ICONSTOP =          MB_ICONHAND

   MB_DEFBUTTON1 =        0x00000000
   MB_DEFBUTTON2 =        0x00000100
   MB_DEFBUTTON3 =        0x00000200
   MB_DEFBUTTON4 =        0x00000300

   IDOK =                 1
   IDCANCEL =             2
   IDABORT =              3
   IDRETRY =              4
   IDIGNORE =             5
   IDYES =                6
   IDNO =                 7
#   IDCLOSE =              8
#IDHELP =               9
   IDTRYAGAIN =          10
   IDCONTINUE =          11

   OFN_OVERWRITEPROMPT = 0x0002
   OFN_FILEMUSTEXIST   = 0x1000
   OFN_PATHMUSTEXIST   = 0x0800

   LStructSize       = 0
   HwndOwner         = 4
   HInstance         = 8
   LpstrFilter       = 12
   LpstrCustomFilter = 16
   NMaxCustFilter    = 20
   NFilterIndex      = 24
   LpstrFile         = 28
   NMaxFile          = 32
   LpstrFileTitle    = 36
   NMaxFileTitle     = 40
   LpstrInitialDir   = 44
   LpstrTitle        = 48
   Flags             = 52
   NFileOffset       = 56
   NFileExtension    = 58
   LpstrDefExt       = 60
   LCustData         = 64
   LpfnHook          = 68
   LpTemplateName    = 72
   PvReserved        = 76
   DwReserved        = 80
   FlagsEx           = 84

   CP_ACP = 0
   CP_UTF8 = 65001

   def initialize(ccode)

      @imcode = -1
      @scode = nil
      sa = ccode.to_s.upcase
      if sa == "SHIFT_JIS" || sa == "WINDOWS-31J"
         @imcode = CP_ACP
      elsif sa == "UTF-8"
         @imcode = CP_UTF8
      end
      if @imcode != -1
         @scode = ccode.to_s
         @iFileNameFsize = 512
         @iFileNamesize = 64
      else
         print "ENCODING error\r\n"
      end
   end

   def msgbox(sMsg, sTitle, iBtnIcon)

      isl = sMsg.bytesize
      idl = isl * 2 + 1
      sms = "\0" * idl
      il = WDKernel32.MultiByteToWideChar(@imcode,0,sMsg,isl,sms,idl)
      isl = sTitle.bytesize
      idl = isl * 2 + 1
      stl = "\0" * idl
      il = WDKernel32.MultiByteToWideChar(@imcode,0,sTitle,isl,stl,idl)
      ir = WDUser32.MessageBoxW(0,sms,stl,iBtnIcon)
      return ir
   end

   def inputBox(sMsg, sTitle)

      sc = WIN32OLE.new("ScriptControl")
      sc.language = "VBScript"
      sa = sc.eval("InputBox(\"" + sMsg + "\",\"" + sTitle + "\")")
      if sa != nil && @imcode == CP_UTF8
         sr = sa.encode("utf-8","Windows-31J")
      else
         sr = sa
      end
      return sr
   end

   def getOpenFileName(ofn)
   
      abuf = "\0" * 5
      ofbuf = "\0" * 88
      abuf = [88].pack("i")
      for ip in 0..3; ofbuf[LStructSize + ip] = abuf[ip]; end
      if ofn.sTitle != nil
         isl = ofn.sTitle.bytesize
         idl = isl * 2 + 1
         stitle = "\0" * idl
         il = WDKernel32.MultiByteToWideChar(@imcode,0,ofn.sTitle,isl,stitle,idl)
         iad = Fiddle::Pointer[stitle].to_i
         abuf = [iad].pack("i")
         for ip in 0..3; ofbuf[LpstrTitle + ip] = abuf[ip]; end
      end
      if ofn.sArFilter != nil && ofn.sArFilter.length > 0
         sa = ""
         ofn.sArFilter.each{|s1,s2|
            sa += s1 + "\0" + s2 + "\0"
         }
         sa += "\0"
         isl = sa.bytesize
         idl = isl * 2 + 1
         sfilter = "\0" * idl
         il = WDKernel32.MultiByteToWideChar(@imcode,0,sa,isl,sfilter,idl)
         iad = Fiddle::Pointer[sfilter].to_i
         abuf = [iad].pack("i")
         for ip in 0..3; ofbuf[LpstrFilter + ip] = abuf[ip]; end
      end
      if ofn.iFilterIndx >= 0 && ofn.iFilterIndx < ofn.sArFilter.length
         abuf = [ofn.iFilterIndx + 1].pack("i")
         for ip in 0..3; ofbuf[NFilterIndex + ip] = abuf[ip]; end
      end
      sfnmf = "\0" * @iFileNameFsize
      iad = Fiddle::Pointer[sfnmf].to_i
      abuf = [iad].pack("i")
      for ip in 0..3; ofbuf[LpstrFile + ip] = abuf[ip]; end
      abuf = [sfnmf.length - 1].pack("i")
      for ip in 0..3; ofbuf[NMaxFile + ip] = abuf[ip]; end
      sfnm = "\0" * @iFileNamesize
      iad = Fiddle::Pointer[sfnm].to_i
      abuf = [iad].pack("i")
      for ip in 0..3; ofbuf[LpstrFileTitle + ip] = abuf[ip]; end
      abuf = [sfnm.length - 1].pack("i")
      for ip in 0..3; ofbuf[NMaxFileTitle + ip] = abuf[ip]; end
      if ofn.sIniDir != nil
         isl = ofn.sIniDir.bytesize
         idl = isl * 2 + 1
         sinidir = "\0" * idl
         il = WDKernel32.MultiByteToWideChar(@imcode,0,ofn.sIniDir,isl,sinidir,idl)
         iad = Fiddle::Pointer[sinidir].to_i
         abuf = [iad].pack("i")
         for ip in 0..3; ofbuf[LpstrInitialDir + ip] = abuf[ip]; end
      end
      if ofn.iFlags == nil then ofn.iFlags = 0 end
      iz = OFN_FILEMUSTEXIST | ofn.iFlags
      abuf = [iz].pack("i")
      for ip in 0..3; ofbuf[Flags + ip] = abuf[ip]; end
      ir = WDComdlg32.GetOpenFileNameW(ofbuf)
      if ir != 0
         il = WDKernel32.WideCharToMultiByte(@imcode,0,sfnmf,-1,nil,0,nil,nil)
         if il > 0
            il -= 1
            sds = "\0" * il
            bi = WDKernel32.WideCharToMultiByte(@imcode,0,sfnmf,-1,sds,il,nil,nil)
            ofn.sFnameFull = sds[0,il].force_encoding(@scode)
         end
         il = WDKernel32.WideCharToMultiByte(@imcode,0,sfnm,-1,nil,0,nil,nil)
         if il > 0
            il -= 1
            sds = "\0" * il
            bi = WDKernel32.WideCharToMultiByte(@imcode,0,sfnm,-1,sds,il,nil,nil)
            ofn.sFname = sds[0,il].force_encoding(@scode)
         end
      end
      return ir
   end

   def getSaveFileName(ofn)
   
      abuf = "\0" * 5
      ofbuf = "\0" * 88
      abuf = [88].pack("i")
      for ip in 0..3; ofbuf[LStructSize + ip] = abuf[ip]; end
      if ofn.sTitle != nil
         isl = ofn.sTitle.bytesize
         idl = isl * 2 + 1
         stitle = "\0" * idl
         il = WDKernel32.MultiByteToWideChar(@imcode,0,ofn.sTitle,isl,stitle,idl)
         iad = Fiddle::Pointer[stitle].to_i
         abuf = [iad].pack("i")
         for ip in 0..3; ofbuf[LpstrTitle + ip] = abuf[ip]; end
      end
      if ofn.sArFilter != nil && ofn.sArFilter.length > 0
         sa = ""
         ofn.sArFilter.each{|s1,s2|
            sa += s1 + "\0" + s2 + "\0"
         }
         sa += "\0"
         isl = sa.bytesize
         idl = isl * 2 + 1
         sfilter = "\0" * idl
         il = WDKernel32.MultiByteToWideChar(@imcode,0,sa,isl,sfilter,idl)
         iad = Fiddle::Pointer[sfilter].to_i
         abuf = [iad].pack("i")
         for ip in 0..3; ofbuf[LpstrFilter + ip] = abuf[ip]; end
      end
      if ofn.iFilterIndx >= 0 && ofn.iFilterIndx < ofn.sArFilter.length
         abuf = [ofn.iFilterIndx + 1].pack("i")
         for ip in 0..3; ofbuf[NFilterIndex + ip] = abuf[ip]; end
      end
      sfnmf = "\0" * @iFileNameFsize
      iad = Fiddle::Pointer[sfnmf].to_i
      abuf = [iad].pack("i")
      for ip in 0..3; ofbuf[LpstrFile + ip] = abuf[ip]; end
      abuf = [sfnmf.length - 1].pack("i")
      for ip in 0..3; ofbuf[NMaxFile + ip] = abuf[ip]; end
      sfnm = "\0" * @iFileNamesize
      iad = Fiddle::Pointer[sfnm].to_i
      abuf = [iad].pack("i")
      for ip in 0..3; ofbuf[LpstrFileTitle + ip] = abuf[ip]; end
      abuf = [sfnm.length - 1].pack("i")
      for ip in 0..3; ofbuf[NMaxFileTitle + ip] = abuf[ip]; end
      if ofn.sIniDir != nil
         isl = ofn.sIniDir.bytesize
         idl = isl * 2 + 1
         sinidir = "\0" * idl
         il = WDKernel32.MultiByteToWideChar(@imcode,0,ofn.sIniDir,isl,sinidir,idl)
         iad = Fiddle::Pointer[sinidir].to_i
         abuf = [iad].pack("i")
         for ip in 0..3; ofbuf[LpstrInitialDir + ip] = abuf[ip]; end
      end
      if ofn.iFlags == nil then ofn.iFlags = 0 end
      iz = ofn.iFlags
      abuf = [iz].pack("i")
      for ip in 0..3; ofbuf[Flags + ip] = abuf[ip]; end
      ir = WDComdlg32.GetSaveFileNameW(ofbuf)
      if ir != 0
         il = WDKernel32.WideCharToMultiByte(@imcode,0,sfnmf,-1,nil,0,nil,nil)
         if il > 0
            il -= 1
            sds = "\0" * il
            bi = WDKernel32.WideCharToMultiByte(@imcode,0,sfnmf,-1,sds,il,nil,nil)
            ofn.sFnameFull = sds[0,il].force_encoding(@scode)
         end
         il = WDKernel32.WideCharToMultiByte(@imcode,0,sfnm,-1,nil,0,nil,nil)
         if il > 0
            il -= 1
            sds = "\0" * il
            bi = WDKernel32.WideCharToMultiByte(@imcode,0,sfnm,-1,sds,il,nil,nil)
            ofn.sFname = sds[0,il].force_encoding(@scode)
         end
      end
      return ir
   end

   attr_accessor :iFileNameFsize
   attr_accessor :iFileNamesize

end