topbanner_forum
  *

avatar image

Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
  • Thursday March 28, 2024, 6:00 am
  • Proudly celebrating 15+ years online.
  • Donate now to become a lifetime supporting member of the site and get a non-expiring license key for all of our programs.
  • donate

Last post Author Topic: DONE: Photo Downloader Kiosk  (Read 42979 times)

NinJA999

  • Supporting Member
  • Joined in 2008
  • **
  • Posts: 79
    • View Profile
    • Donate to Member
DONE: Photo Downloader Kiosk
« on: October 04, 2008, 12:36 PM »
EDIT: Link to the PhotoKiosk made by Skrommel and modded by me:
http://aldwin.us/PhotoKiosk/PhotoKiosk.exe
To the AHK file and other files (the exe extracts the images etc but if you want to play with the AHK here are the files)
http://aldwin.us/PhotoKiosk/

EDIT: I just realized that this post is really long.  I have bolded the idea itself if you want to skip to just that.

Hello,

My robotics team runs a tournament every year for younger kids.  An idea of mine for this year's tournament is to have a continually running slideshow of pictures on one of the projectors.  It would be great if I could have a computer set up with a media reader where people (coaches, spectators, etc) could insert a card and download their pictures to the computer to be immediately added to the slideshow.  So, here's my idea:

a kiosk-like program that allows a user to download all or some photos from a memory card (I've got one of those read-all-card-types readers that maps to four drives) to a folder that I specify in a config file (probably on a networked computer e.g. \\mycomp\slideshow\) in a datetime-stamped folder (to avoid name conflicts) with a minimum of user effort.  Kind of like one of those photo kiosks that can be found at Walgreens, etc, but much simpler.  Just a spash screen, a photo-select screen for once the user has inserted a memory card, a copying screen, and a done screen.  Or something.

I am a programmer, and if nobody is interested I will code this myself, so don't spend a lot of time on it.  But, the members of this forum are much more talented than I am and so I'm sure you could whip something up easier than I could.

Thanks,
Nick

EDIT: I would also be happy if there is already a program which can do this.  I had found xkiosk, but it is too complicated, since it is built for photo processing labs.
EDIT: I just realized that this post is really long.  I have bolded the idea itself if you want to skip to just that.
« Last Edit: November 18, 2008, 01:39 PM by NinJA999 »

mouser

  • First Author
  • Administrator
  • Joined in 2005
  • *****
  • Posts: 40,896
    • View Profile
    • Mouser's Software Zone on DonationCoder.com
    • Read more about this member.
    • Donate to Member
Re: IDEA: Photo Downloader Kiosk
« Reply #1 on: October 06, 2008, 06:31 PM »
This seems like a useful thing to have -- a kiosk type photo interface.. Anyone know of one?

Deozaan

  • Charter Member
  • Joined in 2006
  • ***
  • Points: 1
  • Posts: 9,747
    • View Profile
    • Read more about this member.
    • Donate to Member
Re: IDEA: Photo Downloader Kiosk
« Reply #2 on: October 06, 2008, 06:45 PM »
Picasa works pretty well to import from a digital camera or something. I've never tried directly from a memory card though.

NinJA999

  • Supporting Member
  • Joined in 2008
  • **
  • Posts: 79
    • View Profile
    • Donate to Member
Re: IDEA: Photo Downloader Kiosk
« Reply #3 on: October 06, 2008, 07:49 PM »
Yes, picasa works well to import (even from memory cards), as does Adobe Bridge Downloader (what I personally use).  But, neither has a simple enough interface suitable for a photo downloader kiosk.
« Last Edit: October 06, 2008, 10:25 PM by NinJA999 »

gtoal

  • Supporting Member
  • Joined in 2008
  • **
  • Posts: 22
    • View Profile
    • Donate to Member
Re: IDEA: Photo Downloader Kiosk
« Reply #4 on: October 07, 2008, 11:06 PM »
Canon Camerawindow just downloads from chip to directory, sounds like what you want?

NinJA999

  • Supporting Member
  • Joined in 2008
  • **
  • Posts: 79
    • View Profile
    • Donate to Member
Re: IDEA: Photo Downloader Kiosk
« Reply #5 on: October 07, 2008, 11:14 PM »
Kind of, but I was looking more for something with a super-simplified yet robust interface for a kiosk.

Target

  • Honorary Member
  • Joined in 2006
  • **
  • Posts: 1,832
    • View Profile
    • Donate to Member
Re: IDEA: Photo Downloader Kiosk
« Reply #6 on: October 07, 2008, 11:37 PM »
do you want/need thumbnails?

NinJA999

  • Supporting Member
  • Joined in 2008
  • **
  • Posts: 79
    • View Profile
    • Donate to Member
Re: IDEA: Photo Downloader Kiosk
« Reply #7 on: October 08, 2008, 04:36 PM »
It would probably be a good idea so the person doing the downloading can make sure they're downloading the right pictures.

skrommel

  • Fastest code in the west
  • Developer
  • Joined in 2005
  • ***
  • Posts: 933
    • View Profile
    • 1 Hour Software by skrommel
    • Donate to Member
Re: IDEA: Photo Downloader Kiosk
« Reply #8 on: October 08, 2008, 07:56 PM »
 :) Try PhotoKiosk!

It shows an always on top window with thumbnails from a disk of your choice, and a button to copy the selected files to a folder.

Just change the in and out-lines of the script to watch another folder.

I'll compile and clean it up if it's usable.

Skrommel

;PhotoKiosk.ahk
;Skrommel @ 2008

in:="N:,O:,P:,Q:"   ; Source folders separated by comma
out:="C:\Temp"      ; Targe folder
size:=120           ; Thumbnail size
space:=14           ; Thumbnail space
subfolders:=0       ; Traverse subfolders? 1=Yes 0=No
preview:=400        ; Width of preview window

applicationname=PhotoKiosk

#NoEnv
#SingleInstance,Force
SetBatchLines,-1
SetWinDelay,0
DetectHiddenWindows,On

OnExit,EXIT
pToken:=Gdip_Startup()

StringRight,right,out,1
If (right="\")
  StringTrimRight,out,out,1

START:
Gui,Destroy
Gui,Show,% "X Y W" A_ScreenWidth " H" A_ScreenHeight,%applicationname%
Gui,+Resize +0x300000 +AlwaysOnTop -Resize +OwnDialogs ;WS_VSCROLL | WS_HSCROLL
Gui,+LastFound
guiid:=WinExist()

WinSetUnMovable(guiid)
DllCall("RegisterShellHookWindow",UInt,guiid)
msgnum:=DllCall("RegisterWindowMessage",Str,"SHELLHOOK")
OnMessage(msgnum,"ShellMessage")
GroupAdd,MyGui,ahk_id %guiid%
WinSet,Top,,ahk_id %guiid%
WinSetTitle,ahk_id %guiid%,,% applicationname " - Reading pictures..."

subfolder:=A_Now
counter:=0
x:=space
y:=25+space
Loop,Parse,in,`,
{
  source:=A_LoopField
  StringRight,right,source,1
  If (right="\")
    StringTrimRight,source,source,1

  Loop,%source%\*.*,0,% subfolders
  {
    If A_LoopFileExt Not In GIF,JPG,JPEG,JPE,BMP,ICO,CUR,ANI,PNG,TIF,Exif,WMF,EMF
      Continue
    counter+=1
    path_%counter%:=A_LoopFileLongPath
    pBitmap := Gdip_CreateBitmapFromFile(A_LoopFileLongPath)
    w:=Gdip_GetImageWidth(pBitmap)
    h:=Gdip_GetImageHeight(pBitmap)
    Gdip_DisposeImage(pBitmap)
    If (w>h)
      Gui,Add,Picture,% "X" x " Y" y+(size-size*h/w)/2 " W" size " H-1 GPICTURE AltSubmit V" check%counter%,%A_LoopFileLongPath%
    Else
      Gui,Add,Picture,% "X" x+(size-size*w/h)/2 " Y" y " H" size " W-1 GPICTURE AltSubmit V" check%counter%,%A_LoopFileLongPath%
    Gui,Add,CheckBox,% "X" x-space " Y" y+size " W" space " H" space,% "" ; " W" size+space-1 " H" space*2,% "" ;% A_LoopFileName
    Gui,Add,Edit,% "X" x+1 " Y" y+size " W" size-2 " H" space*2 " -HScroll -VScroll",% A_LoopFileName

    x:=x+size+space*2
    If (x>A_ScreenWidth-size)
    {
      x:=space
      y:=y+size+space*2
    }
  }
}
Gui,Add, Button,W75 Xm Ym GREFRESH Default,&Refresh
Gui,Add, Button,W75 X+5 GSELECTALL,Select &All
Gui,Add, Button,W75 X+5 GINVERT,&Invert
Gui,Add, Button,W75 X+5 GUPLOAD,&Upload

OnMessage(0x115, "OnScroll") ; WM_VSCROLL
OnMessage(0x114, "OnScroll") ; WM_HSCROLL

WinMove,ahk_id %guiid%,,,,,% A_ScreenHeight-1
WinMove,ahk_id %guiid%,,,,,% A_ScreenHeight
WinSetTitle,ahk_id %guiid%,,% "Finished reading pictures"
Return


PICTURE:
MouseGetPos,mx,my,mwin,mctrl
StringTrimLeft,control,mctrl,6
Gui,2:Destroy
Gui,2:+Owner1
Gui,2:Margin,0,0
Gui,2:+AlwaysOnTop +ToolWindow
Gui,2:Add,Picture,% "X" 0 " Y" 0 " W" 400 " H-1 GPREVIEW",% path_%control%
Gui,2:Show
Return


PREVIEW:
Return


REFRESH:
subfolder:=A_Now
Gui,2:+AlwaysOnTop -Border -Resize
Gui,2:Show,X0 Y0 W%A_ScreenWidth% H%A_ScreenHeight%,PhotoKiosk
Gosub,START
Gui,2:Destroy
Return


SELECTALL:
WinGet,controls,ControlList,ahk_id %guiid%
Loop,Parse,controls,`n
{
  If A_LoopField Contains Button
    GuiControl,,% A_LoopField,1
  If (A_LoopField="Button" counter)
    Break
}
Return


INVERT:
WinGet,controls,ControlList,ahk_id %guiid%
Loop,Parse,controls,`n
{
  If A_LoopField Contains Button
  {
    GuiControlGet,checked,,% A_LoopField
    If checked=1
      GuiControl,,% A_LoopField,0
    Else
      GuiControl,,% A_LoopField,1
  }
  If (A_LoopField="Button" counter)
    Break
}
Return


UPLOAD:
FileCreateDir,% out "\" subfolder "\"
WinGet,controls,ControlList,ahk_id %guiid%
Loop,Parse,controls,`n
{
  If A_LoopField Contains Button
  {
    GuiControlGet,checked,,% A_LoopField
    If checked=1
    {
      StringTrimLeft,control,A_LoopField,6
     
      FileCopy,% path_%control%,% out "\" subfolder "\"
      WinSetTitle,ahk_id %guiid%,,% "Copying " path_%control% "..."
    }
  }
  If (A_LoopField="Button" counter)
    Break
}
WinSetTitle,ahk_id %guiid%,,% "Finished copying"
Return


GuiSize:
  UpdateScrollBars(A_Gui,A_GuiWidth,A_GuiHeight)
Return


GuiClose:
Return


^+!e::
EXIT:
Gdip_Shutdown(pToken)
DllCall("CloseHandle",UInt,hDir)
ExitApp
Return


ShellMessage(wParam,lParam)
{
  Global guiid
  If (lParam<>guiid)
  {
    WinSet,Top,,ahk_id %guiid%
    WinActivate,ahk_id %guiid%
  }
}
Return


WinSetUnMovable(hwnd)
{
  hSysMenu:=DllCall("GetSystemMenu","Int",hWnd,"Int",FALSE)
  nCnt:=DllCall("GetMenuItemCount","Int",hSysMenu)
  DllCall("RemoveMenu","Int",hSysMenu,"UInt",nCnt-6,"Uint","0x400")
  DllCall("DrawMenuBar","Int",hWnd)
}
Return


#IfWinActive ahk_group MyGui
WheelUp::
WheelDown::
+WheelUp::
+WheelDown::
  ; SB_LINEDOWN=1, SB_LINEUP=0, WM_HSCROLL=0x114, WM_VSCROLL=0x115
  OnScroll(InStr(A_ThisHotkey,"Down") ? 1 : 0, 0, GetKeyState("Shift") ? 0x114 : 0x115, WinExist())
Return
#IfWinActive


UpdateScrollBars(GuiNum, GuiWidth, GuiHeight)
{
  static SIF_RANGE=0x1, SIF_PAGE=0x2, SIF_DISABLENOSCROLL=0x8, SB_HORZ=0, SB_VERT=1
 
  Gui, %GuiNum%:Default
  Gui, +LastFound
 
  ; Calculate scrolling area.
  Left := Top := 9999
  Right := Bottom := 0
  WinGet, ControlList, ControlList
  Loop, Parse, ControlList, `n
  {
    GuiControlGet, c, Pos, %A_LoopField%
    if (cX < Left)
      Left := cX
    if (cY < Top)
      Top := cY
    if (cX + cW > Right)
      Right := cX + cW
    if (cY + cH > Bottom)
      Bottom := cY + cH
  }
  Left -= 8
  Top -= 8
  Right += 8
  Bottom += 8
  ScrollWidth := Right-Left
  ScrollHeight := Bottom-Top
 
  ; Initialize SCROLLINFO.
  VarSetCapacity(si, 28, 0)
  NumPut(28, si) ; cbSize
  NumPut(SIF_RANGE | SIF_PAGE, si, 4) ; fMask
 
  ; Update horizontal scroll bar.
  NumPut(ScrollWidth, si, 12) ; nMax
  NumPut(GuiWidth, si, 16) ; nPage
  DllCall("SetScrollInfo", "uint", WinExist(), "uint", SB_HORZ, "uint", &si, "int", 1)
 
  ; Update vertical scroll bar.
;     NumPut(SIF_RANGE | SIF_PAGE | SIF_DISABLENOSCROLL, si, 4) ; fMask
  NumPut(ScrollHeight, si, 12) ; nMax
  NumPut(GuiHeight, si, 16) ; nPage
  DllCall("SetScrollInfo", "uint", WinExist(), "uint", SB_VERT, "uint", &si, "int", 1)
 
  if (Left < 0 && Right < GuiWidth)
      x := Abs(Left) > GuiWidth-Right ? GuiWidth-Right : Abs(Left)
  if (Top < 0 && Bottom < GuiHeight)
      y := Abs(Top) > GuiHeight-Bottom ? GuiHeight-Bottom : Abs(Top)
  if (x || y)
      DllCall("ScrollWindow", "uint", WinExist(), "int", x, "int", y, "uint", 0, "uint", 0)
}


OnScroll(wParam, lParam, msg, hwnd)
{
  static SIF_ALL=0x17, SCROLL_STEP=10
 
  bar := msg=0x115 ; SB_HORZ=0, SB_VERT=1
 
  VarSetCapacity(si, 28, 0)
  NumPut(28, si) ; cbSize
  NumPut(SIF_ALL, si, 4) ; fMask
  if !DllCall("GetScrollInfo", "uint", hwnd, "int", bar, "uint", &si)
    return
 
  VarSetCapacity(rect, 16)
  DllCall("GetClientRect", "uint", hwnd, "uint", &rect)
 
  new_pos := NumGet(si, 20) ; nPos
 
  action := wParam & 0xFFFF
  if action = 0 ; SB_LINEUP
    new_pos -= SCROLL_STEP
  else if action = 1 ; SB_LINEDOWN
    new_pos += SCROLL_STEP
  else if action = 2 ; SB_PAGEUP
    new_pos -= NumGet(rect, 12, "int") - SCROLL_STEP
  else if action = 3 ; SB_PAGEDOWN
    new_pos += NumGet(rect, 12, "int") - SCROLL_STEP
  else if action = 5 ; SB_THUMBTRACK
    new_pos := NumGet(si, 24, "int") ; nTrackPos
  else if action = 6 ; SB_TOP
    new_pos := NumGet(si, 8, "int") ; nMin
  else if action = 7 ; SB_BOTTOM
    new_pos := NumGet(si, 12, "int") ; nMax
  else
    return
 
  min := NumGet(si, 8, "int") ; nMin
  max := NumGet(si, 12, "int") - NumGet(si, 16) ; nMax-nPage
  new_pos := new_pos > max ? max : new_pos
  new_pos := new_pos < min ? min : new_pos
 
  old_pos := NumGet(si, 20, "int") ; nPos
 
  x := y := 0
  if bar = 0 ; SB_HORZ
    x := old_pos-new_pos
  else
    y := old_pos-new_pos
  ; Scroll contents of window and invalidate uncovered area.
  DllCall("ScrollWindow", "uint", hwnd, "int", x, "int", y, "uint", 0, "uint", 0)
 
  ; Update scroll bar.
  NumPut(new_pos, si, 20, "int") ; nPos
  DllCall("SetScrollInfo", "uint", hwnd, "int", bar, "uint", &si, "int", 1)
}


; Gdip standard library v1.22 by tic 09/09/08
;
;#####################################################################################
;#####################################################################################
; STATUS ENUMERATION
; Return values for functions specified to have status enumerated return type
;#####################################################################################
; Ok = 0
; GenericError = 1
; InvalidParameter = 2
; OutOfMemory = 3
; ObjectBusy = 4
; InsufficientBuffer = 5
; NotImplemented = 6
; Win32Error = 7
; WrongState = 8
; Aborted = 9
; FileNotFound = 10
; ValueOverflow = 11
; AccessDenied = 12
; UnknownImageFormat = 13
; FontFamilyNotFound = 14
; FontStyleNotFound = 15
; NotTrueTypeFont = 16
; UnsupportedGdiplusVersion = 17
; GdiplusNotInitialized = 18
; PropertyNotFound = 19
; PropertyNotSupported = 20
; ProfileNotFound = 21
;#####################################################################################
;#####################################################################################
; GDI and structure functions
; ########################
; UpdateLayeredWindow
; CreateRectF
; CreateSizeF
; CreateDIBSection

;#####################################################################################
;#####################################################################################
;
; GDI and structure functions
;
;#####################################################################################
;#####################################################################################

; Function:     UpdateLayeredWindow
; Description:  Updates a layered window with the handle to the DC of a gdi bitmap
;   
; hwnd        = Handle of the window to update
; hdc           = Handle to the DC of the GDI bitmap to update the window with
; Layeredx      = x position to place the window
; Layeredy      = x position to place the window
; Layeredw      = Width of the window
; Layeredh      = Height of the window
; Alpha         = Default = 255 : The transparency (0-255) to set the window transparency
;
; Return:      If the function succeeds, the return value is nonzero.
;
UpdateLayeredWindow(hwnd, hdc, x="", y="", w="", h="", Alpha=255)
{
   If ((x != "") && (y != ""))
   VarSetCapacity(pt, 8), NumPut(x, pt, 0), NumPut(y, pt, 4)
   
   If ((w = "") ||(h = ""))
   WinGetPos,,, w, h, ahk_id %hwnd%
   
   Return, DllCall("UpdateLayeredWindow"
   , "UInt", hwnd
   , "UInt", 0
   , "UInt", ((x = "") && (y = "")) ? 0 : &pt
   , "Int64*", w|h<<32
   , "UInt", hdc
   , "Int64*", 0
   , "UInt", 0
   , "UInt*", Alpha<<16|1<<24
   , "UInt", 2)
}
;#####################################################################################
BitBlt(dDC, dx, dy, dw, dh, sDC, sx, sy, Raster="")
{
Return, DllCall("gdi32\BitBlt"
, "UInt", dDC ; handle to destination DC
, "Int", dx ; x-coord of destination upper-left corner
, "Int", dy ; y-coord of destination upper-left corner
, "Int", dw ; width of destination rectangle
, "Int", dh ; height of destination rectangle
, "UInt", sDC ; handle to source DC
, "Int", sx ; x-coordinate of source upper-left corner
, "Int", sy ; y-coordinate of source upper-left corner
, "UInt", Raster ? Raster : 0x00CC0020) ; raster operation code
}
;#####################################################################################
StretchBlt(dDC, dx, dy, dw, dh, sDC, sx, sy, sw, sh, Raster="")
{
Return, DllCall("gdi32\StretchBlt"
, "UInt", dDC ; handle to destination DC
, "Int", dx ; x-coord of destination upper-left corner
, "Int", dy ; y-coord of destination upper-left corner
, "Int", dw ; width of destination rectangle
, "Int", dh ; height of destination rectangle
, "UInt", sDC ; handle to source DC
, "Int", sx ; x-coordinate of source upper-left corner
, "Int", sy ; y-coordinate of source upper-left corner
, "Int", sw ; width of source rectangle
, "Int", sh ; height of source rectangle
, "UInt", Raster ? Raster : 0x00CC0020) ; raster operation code
}
;#####################################################################################
SetImage(hwnd, hBitmap)
{
SendMessage, 0x172, 0x0, hBitmap,, ahk_id %hwnd%
}
;#####################################################################################
Gdip_BitmapFromScreen(Screen=0)
{
If (Screen = 0)
{
Sysget, x, 76
Sysget, y, 77
Sysget, w, 78
Sysget, h, 79
}
Else If (Screen&1 != "")
{
Sysget, M, Monitor, %Screen%
x := MLeft, y := MTop, w := MRight-MLeft, h := MBottom-MTop
}
Else
{
StringSplit, S, Screen, |
x := S1, y := S2, w := S3, h := S4
}

If (x = "") || (y = "") || (w = "") || (h = "")
Return, -1

chdc := CreateCompatibleDC(), hbm := CreateDIBSection(w, h, chdc), obm := SelectObject(chdc, hbm), hhdc := GetDC()
BitBlt(chdc, 0, 0, w, h, hhdc, x, y)
ReleaseDC(hhdc)

pBitmap := Gdip_CreateBitmapFromHBITMAP(hbm)
SelectObject(hhdc, obm), DeleteObject(hbm), DeleteDC(hhdc), DeleteDC(chdc)
Return, pBitmap
}
;#####################################################################################

; Function:    CreateRectF
; Description: Creates a RectF object, containing a the coordinates and dimensions of a rectangle
;
; RectF        = Name to call the RectF object
; x            = x-coordinate of the upper left corner of the rectangle
; y            = y-coordinate of the upper left corner of the rectangle
; w            = Width of the rectangle
; h            = Height of the rectangle
;
; Return:      No return value
;
CreateRectF(ByRef RectF, x, y, w, h)
{
   VarSetCapacity(RectF, 16)
   NumPut(x, RectF, 0, "Float"), NumPut(y, RectF, 4, "Float"), NumPut(w, RectF, 8, "Float"), NumPut(h, RectF, 12, "Float")
}
;#####################################################################################

; Function:    CreateSizeF
; Description:   Creates a SizeF object, containing an 2 values
;
; SizeF         = Name to call the SizeF object
; w            = w-value for the SizeF object
; h            = h-value for the SizeF object
;
; Return:      No Return value
;
CreateSizeF(ByRef SizeF, w, h)
{
   VarSetCapacity(SizeF, 8)
   NumPut(w, SizeF, 0, "Float"), NumPut(h, SizeF, 4, "Float")     
}
;#####################################################################################

; Function:    CreateDIBSection
; Description:   Creates a SizeF object, containing an 2 values
;
; SizeF         = Name to call the SizeF object
; w            = w-value for the SizeF object
; h            = h-value for the SizeF object
;
CreateDIBSection(w, h, hdc="", bpp=32, ByRef ppvBits=0)
{
hdc2 := hdc ? hdc : GetDC(hwnd=0)

VarSetCapacity(bi, 40, 0)       ; BITMAPINFO(HEADER)
NumPut(40, bi,  0)              ; biSize
NumPut(1,  bi, 12, "UShort")    ; biPlanes
NumPut(0,  bi, 16)              ; biCompression = BI_RGB (none)
NumPut(w,  bi,  4)              ; biWidth
NumPut(h,  bi,  8)              ; biHeight
NumPut(bpp,bi, 14, "UShort")    ; biBitCount
       
hbm := DllCall("CreateDIBSection", "UInt" , hdc2, "UInt" , &bi, "UInt" , 0, "UInt*", ppvBits, "UInt" , 0, "UInt" , 0)
;If !hdc
;ReleaseDC(hdc2)
VarSetCapacity(bi, 0)
Return, hbm
}
;#####################################################################################

DestroyIcon(hIcon)
{
   Return, DllCall("DestroyIcon", "UInt", hIcon)
}

CreateCompatibleDC(hdc=0)
{
   Return, DllCall("CreateCompatibleDC", "UInt", hdc)
}     

SelectObject(hdc, hgdiobj)
{
   Return, DllCall("SelectObject", "UInt", hdc, "UInt", hgdiobj)
}

DeleteObject(hObject)
{
   Return, DllCall("DeleteObject", "UInt", hObject)
}

GetDC(hwnd=0)
{
Return, DllCall("GetDC", "UInt", hwnd)
}

ReleaseDC(hdc, hwnd=0)
{
   Return, DllCall("ReleaseDC", "UInt", hwnd, "UInt", hdc)
}

DeleteDC(hdc)
{
   Return, DllCall("DeleteDC", "UInt", hdc)
}
;#####################################################################################
;#####################################################################################
;
; Misc functions
;
;#####################################################################################

Gdip_BitmapFromBRA(ByRef BRAFromMemIn, File)
{
   If (SubStr(File, 1, 4) = "File") && (SubStr(File, 5, StrLen(File)-4) & 1 != "")
   {
      RegExMatch(BRAFromMemIn, ":H:([0-9]+).*?:a:" SubStr(File, 5, StrLen(File)-4) ":b:(.*?):c:([0-9]+):d:([0-9]+)::", FileInfo)
      File := FileInfo2
   }
   Else
   RegExMatch(BRAFromMemIn, ":H:([0-9]+).*?:a:([0-9]+):b:\Q" File "\E:c:([0-9]+):d:([0-9]+)::", FileInfo)
   
   If !FileInfo
   Return, 0
   
   hData := DllCall("GlobalAlloc", "UInt", 2, "UInt", FileInfo3)
   pData := DllCall("GlobalLock", "UInt", hData)
   DllCall("RtlMoveMemory", "UInt", pData, "UInt", &BRAFromMemIn+FileInfo1+FileInfo4, "UInt", FileInfo3)
   DllCall("GlobalUnlock", "UInt", hData)
   DllCall("ole32\CreateStreamOnHGlobal", "UInt", hData, "Int", 1, "UInt*", pStream)
   DllCall("gdiplus\GdipCreateBitmapFromStream", "UInt", pStream, "UInt*", pBitmap)
   DllCall(NumGet(NumGet(1*pStream)+8), "UInt", pStream)
   Return, pBitmap
}

;#####################################################################################
;
; GDI+ functions
;
;#####################################################################################
;#####################################################################################
;#####################################################################################
; Draw shape/line
;#####################################################################################

Gdip_DrawRectangle(pGraphics, pPen, x, y, w, h)
{
   Return, DllCall("gdiplus\GdipDrawRectangle", "UInt", pGraphics, "UInt", pPen
   , "Float", x, "Float", y, "Float", w, "Float", h)
}

Gdip_DrawRoundedRectangle(pGraphics, pPen, x, y, w, h, r)
{
Gdip_SetClipRect(pGraphics, x-r, y-r, 2*r, 2*r, 4)
Gdip_SetClipRect(pGraphics, x+w-r, y-r, 2*r, 2*r, 4)
Gdip_SetClipRect(pGraphics, x-r, y+h-r, 2*r, 2*r, 4)
Gdip_SetClipRect(pGraphics, x+w-r, y+h-r, 2*r, 2*r, 4)
E := Gdip_DrawRectangle(pGraphics, pPen, x, y, w, h)
Gdip_ResetClip(pGraphics)
Gdip_SetClipRect(pGraphics, x-(2*r), y+r, w+(4*r), h-(2*r), 4)
Gdip_SetClipRect(pGraphics, x+r, y-(2*r), w-(2*r), h+(4*r), 4)
Gdip_DrawEllipse(pGraphics, pPen, x, y, 2*r, 2*r)
Gdip_DrawEllipse(pGraphics, pPen, x+w-(2*r), y, 2*r, 2*r)
Gdip_DrawEllipse(pGraphics, pPen, x, y+h-(2*r), 2*r, 2*r)
Gdip_DrawEllipse(pGraphics, pPen, x+w-(2*r), y+h-(2*r), 2*r, 2*r)
Gdip_ResetClip(pGraphics)
Return, E
}

Gdip_DrawEllipse(pGraphics, pPen, x, y, w, h)
{
   Return, DllCall("gdiplus\GdipDrawEllipse", "UInt", pGraphics, "UInt", pPen
   , "Float", x, "Float", y, "Float", w, "Float", h)
}

Gdip_DrawBezier(pGraphics, pPen, x1, y1, x2, y2, x3, y3, x4, y4)
{
   Return, DllCall("gdiplus\GdipDrawBezier", "UInt", pgraphics, "UInt", pPen
   , "Float", x1, "Float", y1, "Float", x2, "Float", y2
   , "Float", x3, "Float", y3, "Float", x4, "Float", y4)
}

Gdip_DrawArc(pGraphics, pPen, x, y, w, h, StartAngle, SweepAngle)
{
   Return, DllCall("gdiplus\GdipDrawArc", "UInt", pGraphics, "UInt", pPen
   , "Float", x, "Float", y, "Float", w, "Float", h, "Float", StartAngle, "Float", SweepAngle)
}

Gdip_DrawPie(pGraphics, pPen, x, y, w, h, StartAngle, SweepAngle)
{
   Return, DllCall("gdiplus\GdipDrawPie", "UInt", pGraphics, "UInt", pPen, "Float", x, "Float", y, "Float", w, "Float", h, "Float", StartAngle, "Float", SweepAngle)
}

Gdip_DrawLine(pGraphics, pPen, x1, y1, x2, y2)
{
   Return, DllCall("gdiplus\GdipDrawLine", "UInt", pGraphics, "UInt", pPen
   , "Float", x1, "Float", y1, "Float", x2, "Float", y2)
}

; Points passed as x1,y1|x2,y2|x3,y3.....
Gdip_DrawLines(pGraphics, pPen, Points)
{
   StringSplit, Points, Points, |
   VarSetCapacity(PointF, 8*Points0)   
   Loop, %Points0%
   {
      StringSplit, Coord, Points%A_Index%, `,
      NumPut(Coord1, PointF, 8*(A_Index-1), "Float"), NumPut(Coord2, PointF, (8*(A_Index-1))+4, "Float")
   }
   Return, DllCall("gdiplus\GdipDrawLines", "UInt", pGraphics, "UInt", pPen, "UInt", &PointF, "Int", Points0)
}

;#####################################################################################
; Fill shape
;#####################################################################################

Gdip_FillRectangle(pGraphics, pBrush, x, y, w, h)
{
   Return, DllCall("gdiplus\GdipFillRectangle", "UInt", pGraphics, "Int", pBrush
   , "Float", x, "Float", y, "Float", w, "Float", h)
}

Gdip_FillRoundedRectangle(pGraphics, pBrush, x, y, w, h, r)
{
Region := Gdip_GetClipRegion(pGraphics)
Gdip_SetClipRect(pGraphics, x-r, y-r, 2*r, 2*r, 4)
Gdip_SetClipRect(pGraphics, x+w-r, y-r, 2*r, 2*r, 4)
Gdip_SetClipRect(pGraphics, x-r, y+h-r, 2*r, 2*r, 4)
Gdip_SetClipRect(pGraphics, x+w-r, y+h-r, 2*r, 2*r, 4)
E := Gdip_FillRectangle(pGraphics, pBrush, x, y, w, h)
Gdip_SetClipRegion(pGraphics, Region, 0)
Gdip_SetClipRect(pGraphics, x-(2*r), y+r, w+(4*r), h-(2*r), 4)
Gdip_SetClipRect(pGraphics, x+r, y-(2*r), w-(2*r), h+(4*r), 4)
Gdip_FillEllipse(pGraphics, pBrush, x, y, 2*r, 2*r)
Gdip_FillEllipse(pGraphics, pBrush, x+w-(2*r), y, 2*r, 2*r)
Gdip_FillEllipse(pGraphics, pBrush, x, y+h-(2*r), 2*r, 2*r)
Gdip_FillEllipse(pGraphics, pBrush, x+w-(2*r), y+h-(2*r), 2*r, 2*r)
Gdip_SetClipRegion(pGraphics, Region, 0)
Gdip_DeleteRegion(Region)
Return, E
}

; Points passed as x1,y1|x2,y2|x3,y3.....
Gdip_FillPolygon(pGraphics, pBrush, Points, FillMode=0)
{
   StringSplit, Points, Points, |
   VarSetCapacity(PointF, 8*Points0)   
   Loop, %Points0%
   {
      StringSplit, Coord, Points%A_Index%, `,
      NumPut(Coord1, PointF, 8*(A_Index-1), "Float"), NumPut(Coord2, PointF, (8*(A_Index-1))+4, "Float")
   }   
   Return, DllCall("gdiplus\GdipFillPolygon", "UInt", pGraphics, "UInt", pBrush, "UInt", &PointF, "Int", Points0, "Int", FillMode)
}

Gdip_FillPie(pGraphics, pBrush, x, y, w, h, StartAngle, SweepAngle)
{
   Return, DllCall("gdiplus\GdipFillPie", "UInt", pGraphics, "UInt", pBrush
   , "Float", x, "Float", y, "Float", w, "Float", h, "Float", StartAngle, "Float", SweepAngle)
}

Gdip_FillEllipse(pGraphics, pBrush, x, y, w, h)
{
   Return, DllCall("gdiplus\GdipFillEllipse", "UInt", pGraphics, "UInt", pBrush
   , "Float", x, "Float", y, "Float", w, "Float", h, "Float")
}

Gdip_FillRegion(pGraphics, pBrush, Region)
{
   Return, DllCall("gdiplus\GdipFillRegion", "UInt", pGraphics, "UInt", pBrush, "UInt", Region)
}

Gdip_FillPath(pGraphics, pBrush, Path)
{
   Return, DllCall("gdiplus\GdipFillPath", "UInt", pGraphics, "UInt", pBrush, "UInt", Path)
}

;#####################################################################################
; Graphics functions
;#####################################################################################

; Points passed as x1,y1|x2,y2|x3,y3 (3 points: top left, top right, bottom left)
Gdip_DrawImagePointsRect(pGraphics, pBitmap, Points, sx="", sy="", sw="", sh="", TransMatrix=1)
{
StringSplit, Points, Points, |
VarSetCapacity(PointF, 8*Points0)   
Loop, %Points0%
{
StringSplit, Coord, Points%A_Index%, `,
NumPut(Coord1, PointF, 8*(A_Index-1), "Float"), NumPut(Coord2, PointF, (8*(A_Index-1))+4, "Float")
}

If (TransMatrix&1 = "")
ImageAttr := Gdip_SetImageAttributesColorMatrix(TransMatrix)
Else
ImageAttr := Gdip_SetImageAttributesColorMatrix("1|0|0|0|0|0|1|0|0|0|0|0|1|0|0|0|0|0|" TransMatrix "|0|0|0|0|0|1")

E := DllCall("gdiplus\GdipDrawImagePointsRect", "UInt", pGraphics, "UInt", pBitmap
, "UInt", &PointF, "Int", Points0, "Float", sx, "Float", sy, "Float", sw, "Float", sh
, "Int", 2, "UInt", ImageAttr, "UInt", 0, "UInt", 0)
If ImageAttr
Gdip_DisposeImageAttributes(ImageAttr)
Return, E
}

Gdip_DrawImage(pGraphics, pBitmap, dx, dy, dw, dh, sx="", sy="", sw="", sh="", Matrix=1)
{
If (Matrix&1 = "")
ImageAttr := Gdip_SetImageAttributesColorMatrix(Matrix)
Else
ImageAttr := Gdip_SetImageAttributesColorMatrix("1|0|0|0|0|0|1|0|0|0|0|0|1|0|0|0|0|0|" Matrix "|0|0|0|0|0|1")

If (sx = "") && (sy = "") && (sw = "") && (sh = "")
sx := 0, sy := 0, sw := dw, sh := dh

E := DllCall("gdiplus\GdipDrawImageRectRect", "UInt", pGraphics, "UInt", pBitmap
, "Float", dx, "Float", dy, "Float", dw, "Float", dh
, "Float", sx, "Float", sy, "Float", sw, "Float", sh
, "Int", 2, "UInt", ImageAttr, "UInt", 0, "UInt", 0)
If ImageAttr
Gdip_DisposeImageAttributes(ImageAttr)
Return, E
}

;MatrixBright = 1.5|0|0|0|0|0|1.5|0|0|0|0|0|1.5|0|0|0|0|0|1|0|0.05|0.05|0.05|0|1
;MatrixGreyScale = 0.299|0.299|0.299|0|0|0.587|0.587|0.587|0|0|0.114|0.114|0.114|0|0|0|0|0|1|0|0|0|0|0|1
;MatrixNegative = -1|0|0|0|0|0|1|0|0|0|0|0|-1|0|0|0|0|0|1|0|0|0|0|0|1
Gdip_SetImageAttributesColorMatrix(Matrix)
{
VarSetCapacity(ColourMatrix, 100, 0)
Matrix := RegExReplace(RegExReplace(Matrix, "^[^0-9-\.]+([0-9\.])", "$1", "", 1), "[^0-9-\.]+", "|")
StringSplit, Matrix, Matrix, |
Loop, 25
{
Matrix := Matrix%A_Index% ? Matrix%A_Index% : Mod(A_Index-1, 6) ? 0 : 1
NumPut(Matrix, ColourMatrix, (A_Index-1)*4, "Float")
}
DllCall("gdiplus\GdipCreateImageAttributes", "UInt*", ImageAttr)
DllCall("gdiplus\GdipSetImageAttributesColorMatrix", "UInt", ImageAttr, "Int", 1, "Int", 1, "UInt", &ColourMatrix, "Int", 0, "Int", 0)
VarSetCapacity(ColourMatrix, 0)
Return, ImageAttr
}

Gdip_GraphicsFromImage(pBitmap)
{
    DllCall("gdiplus\GdipGetImageGraphicsContext", "UInt", pBitmap, "UInt*", pGraphics)
    Return, pGraphics
}

Gdip_GraphicsFromHDC(hdc)
{
    DllCall("gdiplus\GdipCreateFromHDC", "UInt", hdc, "UInt*", pGraphics)
    Return, pGraphics
}

;#####################################################################################
; Bitmap functions
;#####################################################################################

Gdip_BlurBitmap(pBitmap, Blur)
{
If ((Blur > 100) || (Blur < 1))
Return, -1

sWidth := Gdip_GetImageWidth(pBitmap), sHeight := Gdip_GetImageHeight(pBitmap)
dWidth := sWidth//Blur, dHeight := sHeight//Blur

pBitmap1 := Gdip_CreateBitmap(dWidth, dHeight)
G1 := Gdip_GraphicsFromImage(pBitmap1)
Gdip_SetInterpolationMode(G1, 7)
Gdip_DrawImage(G1, pBitmap, 0, 0, dWidth, dHeight, 0, 0, sWidth, sHeight)

Gdip_DeleteGraphics(G1)
Gdip_DisposeImage(pBitmap)

pBitmap2 := Gdip_CreateBitmap(sWidth, sHeight)
G2 := Gdip_GraphicsFromImage(pBitmap2)
Gdip_SetInterpolationMode(G2, 7)
Gdip_DrawImage(G2, pBitmap1, 0, 0, sWidth, sHeight, 0, 0, dWidth, dHeight)

Gdip_DeleteGraphics(G2)
Gdip_DisposeImage(pBitmap1)
Return, pBitmap2
}
;#####################################################################################

; Function:     Gdip_SaveBitmapToFile
; Description:  Saves a gdi+ bitmap to a file in any supported format onto disk
;   
; pBitmap      = Pointer to the gdi+ bitmap object
; sOutput      = The name of the file that the bitmap will eb saved to. Supported extensions are: .BMP,.DIB,.RLE,.JPG,.JPEG,.JPE,.JFIF,.GIF,.TIF,.TIFF,.PNG
; Quality      = If saving as jpg (.JPG,.JPEG,.JPE,.JFIF) then quality can be 1-100 with default at maximum quality
;
; Return:      If the function succeeds, the return value is zero, otherwise:
; -1: Extension supplied is not a supported file format
; -2: Could not get a list of encoders on system
; -3: Could not find matching encoder for specified file format
; -4: Could not get WideChar name of output file
; -5: Could not save file to disk
;

Gdip_SaveBitmapToFile(pBitmap, sOutput, Quality=100)
{
StringSplit, OutputArray, sOutput, .
    Extension := "." . OutputArray%OutputArray0%
If Extension not in .BMP,.DIB,.RLE,.JPG,.JPEG,.JPE,.JFIF,.GIF,.TIF,.TIFF,.PNG
Return, -1
   
DllCall("gdiplus\GdipGetImageEncodersSize", "UInt*", nCount, "UInt*", nSize)
VarSetCapacity(ci, nSize)
DllCall("gdiplus\GdipGetImageEncoders", "UInt", nCount, "UInt", nSize, "UInt", &ci)
If !(nCount && nSize)
Return, -2
   
Loop, %nCount%
{
nSize := DllCall("WideCharToMultiByte", "UInt", 0, "UInt", 0, "UInt", NumGet(ci, 76*(A_Index-1)+44), "Int", -1, "UInt", 0, "Int",  0, "UInt", 0, "UInt", 0)
VarSetCapacity(sString, nSize)
DllCall("WideCharToMultiByte", "UInt", 0, "UInt", 0, "UInt", NumGet(ci, 76*(A_Index-1)+44), "Int", -1, "Str", sString, "Int", nSize, "UInt", 0, "UInt", 0)

If !InStr(sString, Extension)
Continue
pCodec := &ci+76*(A_Index-1)
Break
    }
If !pCodec
Return, -3

If (Quality != 100)
{
If Extension in .JPG,.JPEG,.JPE,.JFIF
{
DllCall("gdiplus\GdipGetEncoderParameterListSize", "UInt", pBitmap, "UInt", pCodec, "UInt*", nSize)
VarSetCapacity(EncoderParameters, nSize, 0)
DllCall("gdiplus\GdipGetEncoderParameterList", "UInt", pBitmap, "UInt", pCodec, "UInt", nSize, "UInt", &EncoderParameters)
Loop, % NumGet(EncoderParameters) ;%
{
If (NumGet(EncoderParameters, (28*(A_Index-1))+20) = 1) && (NumGet(EncoderParameters, (28*(A_Index-1))+24) = 6)
{
p := (28*(A_Index-1))+&EncoderParameters
NumPut(Quality, NumGet(NumPut(4, NumPut(1, p+0)+20)))
Break
}
}
}
}
   
nSize := DllCall("MultiByteToWideChar", "UInt", 0, "UInt", 0, "UInt", &sOutput, "Int", -1, "UInt", 0, "Int", 0)
VarSetCapacity(wOutput, nSize*2)
DllCall("MultiByteToWideChar", "UInt", 0, "UInt", 0, "UInt", &sOutput, "Int", -1, "UInt", &wOutput, "Int", nSize)
VarSetCapacity(wOutput, -1)
If !VarSetCapacity(wOutput)
Return, -4

E := DllCall("gdiplus\GdipSaveImageToFile", "UInt", pBitmap, "UInt", &wOutput, "UInt", pCodec, "UInt", p ? p : 0)
Return, E ? -5 : 0
}

Gdip_GetPixel(pBitmap, x, y)
{
DllCall("gdiplus\GdipBitmapGetPixel", "UInt", pBitmap, "Int", x, "Int", y, "UInt*", ARGB)
Return, ARGB
}

Gdip_SetPixel(pBitmap, x, y, ARGB)
{
   Return, DllCall("gdiplus\GdipBitmapSetPixel", "UInt", pBitmap, "Int", x, "Int", y, "Int", ARGB)
}

Gdip_GetImageWidth(pBitmap)
{
   DllCall("gdiplus\GdipGetImageWidth", "UInt", pBitmap, "UInt*", Width)
   Return, Width
}

Gdip_GetImageHeight(pBitmap)
{
   DllCall("gdiplus\GdipGetImageHeight", "UInt", pBitmap, "UInt*", Height)
   Return, Height
}

Gdip_GetDpiX(pGraphics)
{
DllCall("gdiplus\GdipGetDpiX", "UInt", pGraphics, "Float*", DPIx)
Return, DPIx
}

Gdip_GetDpiY(pGraphics)
{
DllCall("gdiplus\GdipGetDpiY", "UInt", pGraphics, "Float*", DPIy)
Return, DPIy
}

Gdip_CreateBitmapFromFile(sFile)
{
   VarSetCapacity(wFile, 1023)
   DllCall("kernel32\MultiByteToWideChar", "UInt", 0, "UInt", 0, "UInt", &sFile, "Int", -1, "UInt", &wFile, "Int", 512)
   DllCall("gdiplus\GdipCreateBitmapFromFile", "UInt", &wFile, "UInt*", pBitmap)
   Return, pBitmap
}

Gdip_CreateBitmapFromHBITMAP(hBitmap, Palette=0)
{
DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", "UInt", hBitmap, "UInt", Palette, "UInt*", pBitmap)
Return, pBitmap
}

Gdip_CreateHBITMAPFromBitmap(pBitmap, Background=0xffffffff)
{
DllCall("gdiplus\GdipCreateHBITMAPFromBitmap", "UInt", pBitmap, "UInt*", hbm, "Int", Background)
Return, hbm
}

Gdip_CreateBitmapFromHICON(hIcon)
{
DllCall("gdiplus\GdipCreateBitmapFromHICON", "UInt", hIcon, "UInt*", pBitmap)
Return, pBitmap
}

Gdip_CreateHICONFromBitmap(pBitmap)
{
DllCall("gdiplus\GdipCreateHICONFromBitmap", "UInt", pBitmap, "UInt*", hIcon)
Return, hIcon
}

Gdip_CreateBitmap(Width, Height, Format=0x26200A)
{
    DllCall("gdiplus\GdipCreateBitmapFromScan0", "Int", Width, "Int", Height, "Int", 0, "Int", Format, "UInt", 0, "UInt*", pBitmap)
    Return pBitmap
}

Gdip_CloneBitmapArea(pBitmap, x, y, w, h, Format=0x26200A)
{
DllCall("gdiplus\GdipCloneBitmapArea", "Float", x, "Float", y, "Float", w, "Float", h
, "Int", Format, "UInt", pBitmap, "UInt*", pBitmapDest)
Return, pBitmapDest
}

;#####################################################################################
; Create resources
;#####################################################################################

Gdip_CreatePen(ARGB, w)
{
   DllCall("gdiplus\GdipCreatePen1", "Int", ARGB, "Float", w, "Int", 2, "UInt*", pPen)
   Return, pPen
}

Gdip_BrushCreateSolid(ARGB=0xff000000)
{
   DllCall("gdiplus\GdipCreateSolidFill", "Int", ARGB, "UInt*", pBrush)
   Return, pBrush
}

; HatchStyleHorizontal = 0
; HatchStyleVertical = 1
; HatchStyleForwardDiagonal = 2
; HatchStyleBackwardDiagonal = 3
; HatchStyleCross = 4
; HatchStyleDiagonalCross = 5
; HatchStyle05Percent = 6
; HatchStyle10Percent = 7
; HatchStyle20Percent = 8
; HatchStyle25Percent = 9
; HatchStyle30Percent = 10
; HatchStyle40Percent = 11
; HatchStyle50Percent = 12
; HatchStyle60Percent = 13
; HatchStyle70Percent = 14
; HatchStyle75Percent = 15
; HatchStyle80Percent = 16
; HatchStyle90Percent = 17
; HatchStyleLightDownwardDiagonal = 18
; HatchStyleLightUpwardDiagonal = 19
; HatchStyleDarkDownwardDiagonal = 20
; HatchStyleDarkUpwardDiagonal = 21
; HatchStyleWideDownwardDiagonal = 22
; HatchStyleWideUpwardDiagonal = 23
; HatchStyleLightVertical = 24
; HatchStyleLightHorizontal = 25
; HatchStyleNarrowVertical = 26
; HatchStyleNarrowHorizontal = 27
; HatchStyleDarkVertical = 28
; HatchStyleDarkHorizontal = 29
; HatchStyleDashedDownwardDiagonal = 30
; HatchStyleDashedUpwardDiagonal = 31
; HatchStyleDashedHorizontal = 32
; HatchStyleDashedVertical = 33
; HatchStyleSmallConfetti = 34
; HatchStyleLargeConfetti = 35
; HatchStyleZigZag = 36
; HatchStyleWave = 37
; HatchStyleDiagonalBrick = 38
; HatchStyleHorizontalBrick = 39
; HatchStyleWeave = 40
; HatchStylePlaid = 41
; HatchStyleDivot = 42
; HatchStyleDottedGrid = 43
; HatchStyleDottedDiamond = 44
; HatchStyleShingle = 45
; HatchStyleTrellis = 46
; HatchStyleSphere = 47
; HatchStyleSmallGrid = 48
; HatchStyleSmallCheckerBoard = 49
; HatchStyleLargeCheckerBoard = 50
; HatchStyleOutlinedDiamond = 51
; HatchStyleSolidDiamond = 52
; HatchStyleTotal = 53
Gdip_BrushCreateHatch(ARGBfront, ARGBback, HatchStyle=0)
{
   DllCall("gdiplus\GdipCreateHatchBrush", "Int", HatchStyle, "Int", ARGBfront, "Int", ARGBback, "UInt*", pBrush)
   Return, pBrush
}

;#####################################################################################
; Delete resources
;#####################################################################################

Gdip_DeletePen(pPen)
{
   Return, DllCall("gdiplus\GdipDeletePen", "UInt", pPen)
}

Gdip_DeleteBrush(pBrush)
{
   Return, DllCall("gdiplus\GdipDeleteBrush", "UInt", pBrush)
}

Gdip_DisposeImage(pBitmap)
{
   Return, DllCall("gdiplus\GdipDisposeImage", "UInt", pBitmap)
}

Gdip_DeleteGraphics(pGraphics)
{
   Return, DllCall("gdiplus\GdipDeleteGraphics", "UInt", pGraphics)
}

Gdip_DisposeImageAttributes(ImageAttr)
{
Return, DllCall("gdiplus\GdipDisposeImageAttributes", "UInt", ImageAttr)
}

Gdip_DeleteFont(hFont)
{
   Return, DllCall("gdiplus\GdipDeleteFont", "UInt", hFont)
}

Gdip_DeleteStringFormat(hFormat)
{
   Return, DllCall("gdiplus\GdipDeleteStringFormat", "UInt", hFormat)
}

Gdip_DeleteFontFamily(hFamily)
{
   Return, DllCall("gdiplus\GdipDeleteFontFamily", "UInt", hFamily)
}

Gdip_DeleteMatrix(Matrix)
{
   Return, DllCall("gdiplus\GdipDeleteMatrix", "UInt", Matrix)
}

;#####################################################################################
; Text functions
;#####################################################################################

Gdip_TextToGraphics(pGraphics, Text, Options, Font="Arial", Width="", Height="")
{
IWidth := Width, IHeight:= Height

RegExMatch(Options, "i)X([0-9]+)(p*)", xpos)
RegExMatch(Options, "i)Y([0-9]+)(p*)", ypos)
RegExMatch(Options, "i)W([0-9]+)(p*)", Width)
RegExMatch(Options, "i)H([0-9]+)(p*)", Height)
RegExMatch(Options, "i)C(?!(entre|enter))([a-f0-9]{8})", Colour)
RegExMatch(Options, "i)R([0-9])", Rendering)
RegExMatch(Options, "i)S([0-9]+)(p*)", Size)

If !(IWidth && IHeight) && (xpos2 || ypos2 || Width2 || Height2 || Size2)
Return, -1

Style := 0, Styles := "Regular|Bold|Italic|BoldItalic|Underline|Strikeout"
Loop, Parse, Styles, |
{
If InStr(Options, A_loopField)
Style |= (A_LoopField != "StrikeOut") ? (A_Index-1) : 8
}
   
Align := 0, Alignments := "Near|Left|Centre|Center|Far|Right"
Loop, Parse, Alignments, |
{
If InStr(Options, A_loopField)
Align |= A_Index//2.1      ; 0|0|1|1|2|2
}

xpos := (xpos1 != "") ? xpos2 ? IWidth*(xpos1/100) : xpos1 : 0
ypos := (ypos1 != "") ? ypos2 ? IHeight*(ypos1/100) : ypos1 : 0
Width := Width1 ? Width2 ? IWidth*(Width1/100) : Width1 : IWidth
Height := Height1 ? Height2 ? IHeight*(Height1/100) : Height1 : IHeight
Colour := "0x" (Colour2 ? Colour2 : "ff000000")
Rendering := ((Rendering1 >= 0) && (Rendering1 <= 4)) ? Rendering1 : 4
Size := (Size1 > 0) ? Size2 ? IHeight*(Size1/100) : Size1 : 12

hFamily := Gdip_FontFamilyCreate(Font)
hFont := Gdip_FontCreate(hFamily, Size, Style)
hFormat := Gdip_StringFormatCreate(0x4000)
pBrush := Gdip_BrushCreateSolid(Colour)
If !(hFamily && hFont && hFormat && pBrush && pGraphics)
Return, !pGraphics ? -2 : !hFamily ? -3 : !hFont ? -4 : !hFormat ? -5 : !pBrush ? -6 : 0
   
CreateRectF(RC, xpos, ypos, Width, Height)
Gdip_SetStringFormatAlign(hFormat, Align)
Gdip_SetTextRenderingHint(pGraphics, Rendering)
E1 := Gdip_DrawString(pGraphics, Text, hFont, hFormat, pBrush, RC)
E2 := Gdip_MeasureString(pGraphics, Text, hFont, hFormat, RC)
   
VarSetCapacity(RC, 0)
Gdip_DeleteBrush(pBrush)
Gdip_DeleteStringFormat(hFormat)   
Gdip_DeleteFont(hFont)
Gdip_DeleteFontFamily(hFamily)
Return, E1 ? E1 : E2
}

Gdip_DrawString(pGraphics, sString, hFont, hFormat, pBrush, ByRef RectF)
{
   nSize := DllCall("MultiByteToWideChar", "UInt", 0, "UInt", 0, "UInt", &sString, "Int", -1, "UInt", 0, "Int", 0)
   VarSetCapacity(wString, nSize*2)
   DllCall("MultiByteToWideChar", "UInt", 0, "UInt", 0, "UInt", &sString, "Int", -1, "UInt", &wString, "Int", nSize)
   Return, DllCall("gdiplus\GdipDrawString", "UInt", pGraphics, "UInt", &wString, "Int", -1, "UInt", hFont, "UInt", &RectF, "UInt", hFormat, "UInt", pBrush)
}

Gdip_MeasureString(pGraphics, sString, hFont, hFormat, ByRef RectF)
{
   nSize := DllCall("MultiByteToWideChar", "UInt", 0, "UInt", 0, "UInt", &sString, "Int", -1, "UInt", 0, "Int", 0)
   VarSetCapacity(wString, nSize*2)   
   DllCall("MultiByteToWideChar", "UInt", 0, "UInt", 0, "UInt", &sString, "Int", -1, "UInt", &wString, "Int", nSize)
   VarSetCapacity(RC, 16)   
   DllCall("gdiplus\GdipMeasureString", "UInt", pGraphics, "UInt", &wString, "Int", -1, "UInt", hFont, "UInt", &RectF, "UInt", hFormat, "UInt", &RC, "UInt*", Chars, "UInt*", Lines)
   Return, &RC ? NumGet(RC, 0, "Float") "|" NumGet(RC, 4, "Float") "|" NumGet(RC, 8, "Float") "|" NumGet(RC, 12, "Float") "|" Chars "|" Lines : 0
}

; Near = 0
; Center = 1
; Far = 2
Gdip_SetStringFormatAlign(hFormat, Align)
{
   Return, DllCall("gdiplus\GdipSetStringFormatAlign", "UInt", hFormat, "Int", Align)
}

Gdip_StringFormatCreate(Format=0, Lang=0)
{
   DllCall("gdiplus\GdipCreateStringFormat", "Int", Format, "Int", Lang, "UInt*", hFormat)
   Return, hFormat
}

; Regular = 0
; Bold = 1
; Italic = 2
; BoldItalic = 3
; Underline = 4
; Strikeout = 8
Gdip_FontCreate(hFamily, Size, Style=0)
{
   DllCall("gdiplus\GdipCreateFont", "UInt", hFamily, "Float", Size, "Int", Style, "Int", 0, "UInt*", hFont)
   Return, hFont
}

Gdip_FontFamilyCreate(Font)
{
   nSize := DllCall("MultiByteToWideChar", "UInt", 0, "UInt", 0, "UInt", &Font, "Int", -1, "UInt", 0, "Int", 0)
   VarSetCapacity(wFont, nSize*2)
   DllCall("MultiByteToWideChar", "UInt", 0, "UInt", 0, "UInt", &Font, "Int", -1, "UInt", &wFont, "Int", nSize)

   DllCall("gdiplus\GdipCreateFontFamilyFromName", "UInt", &wFont, "UInt", 0, "UInt*", hFamily)
   Return, hFamily
}

;#####################################################################################
; Matrix functions
;#####################################################################################

Gdip_CreateAffineMatrix(m11, m12, m21, m22, x, y)
{
   DllCall("gdiplus\GdipCreateMatrix2", "Float", m11, "Float", m12, "Float", m21, "Float", m22, "Float", x, "Float", y, "UInt*", Matrix)
   Return, Matrix
}

Gdip_CreateMatrix()
{
   DllCall("gdiplus\GdipCreateMatrix", "UInt*", Matrix)
   Return, Matrix
}

;#####################################################################################
; GraphicsPath functions
;#####################################################################################

; Alternate = 0
; Winding = 1
Gdip_CreatePath(BrushMode=0)
{
DllCall("gdiplus\GdipCreatePath", "Int", BrushMode, "UInt*", Path)
Return, Path
}

Gdip_AddPathEllipse(Path, x, y, w, h)
{
   Return, DllCall("gdiplus\GdipAddPathEllipse", "UInt", Path, "Float", x, "Float", y, "Float", w, "Float", h)
}

Gdip_DeletePath(Path)
{
Return, DllCall("gdiplus\GdipDeletePath", "UInt", Path)
}

;#####################################################################################
; Quality functions
;#####################################################################################

; SystemDefault = 0
; SingleBitPerPixelGridFit = 1
; SingleBitPerPixel = 2
; AntiAliasGridFit = 3
; AntiAlias = 4
Gdip_SetTextRenderingHint(pGraphics, RenderingHint)
{
   Return, DllCall("gdiplus\GdipSetTextRenderingHint", "UInt", pGraphics, "Int", RenderingHint)
}

; Default = 0
; LowQuality = 1
; HighQuality = 2
; Bilinear = 3
; Bicubic = 4
; NearestNeighbor = 5
; HighQualityBilinear = 6
; HighQualityBicubic = 7
Gdip_SetInterpolationMode(pGraphics, InterpolationMode)
{
   Return, DllCall("gdiplus\GdipSetInterpolationMode", "UInt", pGraphics, "Int", InterpolationMode)
}

; Default = 0
; HighSpeed = 1
; HighQuality = 2
; None = 3
; AntiAlias = 4
Gdip_SetSmoothingMode(pGraphics, SmoothingMode)
{
   Return, DllCall("gdiplus\GdipSetSmoothingMode", "UInt", pGraphics, "Int", SmoothingMode)
}

;GpStatus WINGDIPAPI GdipSetCompositingMode(GpGraphics *graphics, CompositingMode compositingMode)

; CompositingModeSourceOver = 0 (blended)
; CompositingModeSourceCopy = 1 (overwrite)
Gdip_SetCompositingMode(pGraphics, CompositingMode=0)
{
   Return, DllCall("gdiplus\GdipSetCompositingMode", "UInt", pGraphics, "Int", CompositingMode)
}

;#####################################################################################
; Extra functions
;#####################################################################################

Gdip_Startup()
{
   If !DllCall("GetModuleHandle", "Str", "gdiplus")
   DllCall("LoadLibrary", "Str", "gdiplus")
   VarSetCapacity(si, 16, 0), si := Chr(1)
   DllCall("gdiplus\GdiplusStartup", "UInt*", pToken, "UInt", &si, "UInt", 0)
   VarSetCapacity(si, 0)
   Return, pToken
}

Gdip_Shutdown(pToken)
{
   DllCall("gdiplus\GdiplusShutdown", "UInt", pToken)
   If hModule := DllCall("GetModuleHandle", "Str", "gdiplus")
   DllCall("FreeLibrary", "UInt", hModule)
   Return, 0
}

; Prepend = 0; The new operation is applied before the old operation.
; Append = 1; The new operation is applied after the old operation.
Gdip_RotateWorldTransform(pGraphics, Angle, MatrixOrder=0)
{
Return, DllCall("gdiplus\GdipRotateWorldTransform", "UInt", pGraphics, "Float", Angle, "Int", MatrixOrder)
}

Gdip_ScaleWorldTransform(pGraphics, x, y, MatrixOrder=0)
{
Return, DllCall("gdiplus\GdipScaleWorldTransform", "UInt", pGraphics, "Float", x, "Float", y, "Int", MatrixOrder)
}

Gdip_TranslateWorldTransform(pGraphics, x, y, MatrixOrder=0)
{
Return, DllCall("gdiplus\GdipTranslateWorldTransform", "UInt", pGraphics, "Float", x, "Float", y, "Int", MatrixOrder)
}

Gdip_ResetWorldTransform(pGraphics)
{
Return, DllCall("gdiplus\GdipResetWorldTransform", "UInt", pGraphics)
}

Gdip_GetRotatedTranslation(Width, Height, Angle, ByRef xTranslation, ByRef yTranslation)
{
pi := 4*ATan(1), TAngle := Angle*(pi/180)

Bound := (Angle >= 0) ? Mod(Angle, 360) : 360-Mod(-Angle, -360)
If ((Bound >= 0) && (Bound <= 90))
xTranslation := Height*Sin(TAngle), yTranslation := 0
Else If ((Bound > 90) && (Bound <= 180))
xTranslation := (Height*Sin(TAngle))-(Width*Cos(TAngle)), yTranslation := -Height*Cos(TAngle)
Else If ((Bound > 180) && (Bound <= 270))
xTranslation := -(Width*Cos(TAngle)), yTranslation := -(Height*Cos(TAngle))-(Width*Sin(TAngle))
Else If ((Bound > 270) && (Bound <= 360))
xTranslation := 0, yTranslation := -Width*Sin(TAngle)
}

Gdip_GetRotatedDimensions(Width, Height, Angle, ByRef RWidth, ByRef RHeight)
{
pi := 4*ATan(1), TAngle := Angle*(pi/180)
If !(Width && Height)
Return, -1
RWidth := Ceil(Abs(Width*Cos(TAngle))+Abs(Height*Sin(TAngle)))
RHeight := Ceil(Abs(Width*Sin(TAngle))+Abs(Height*Cos(Tangle)))
}

; Replace = 0
; Intersect = 1
; Union = 2
; Xor = 3
; Exclude = 4
; Complement = 5
Gdip_SetClipRect(pGraphics, x, y, w, h, CombineMode=0)
{
   Return, DllCall("gdiplus\GdipSetClipRect", "UInt", pGraphics, "Float", x, "Float", y, "Float", w, "Float", h, "Int", CombineMode)
}

Gdip_SetClipPath(pGraphics, Path, CombineMode=0)
{
   Return, DllCall("gdiplus\GdipSetClipPath", "UInt", pGraphics, "UInt", Path, "Int", CombineMode)
}

Gdip_ResetClip(pGraphics)
{
   Return, DllCall("gdiplus\GdipResetClip", "UInt", pGraphics)
}

Gdip_GetClipRegion(pGraphics)
{
Region := Gdip_CreateRegion()
DllCall("gdiplus\GdipGetClip", "UInt" pGraphics, "UInt", Region)
Return, Region
}

Gdip_SetClipRegion(pGraphics, Region, CombineMode=0)
{
Return, DllCall("gdiplus\GdipSetClipRegion", "UInt", pGraphics, "UInt", Region, "Int", CombineMode)
}

Gdip_CreateRegion()
{
DllCall("gdiplus\GdipCreateRegion", "UInt*", Region)
Return, Region
}

Gdip_DeleteRegion(Region)
{
Return, DllCall("gdiplus\GdipDeleteRegion", "UInt", Region)
}
« Last Edit: October 18, 2008, 12:52 PM by skrommel »

NinJA999

  • Supporting Member
  • Joined in 2008
  • **
  • Posts: 79
    • View Profile
    • Donate to Member
Re: IDEA: Photo Downloader Kiosk
« Reply #9 on: October 08, 2008, 09:14 PM »
Wow, thanks Skrommel!  I have a couple of issues with it, though:
  • folder creation - if the folder does not exist (C:\Temp), it creates a file Temp in the C: drive rather than creating a folder named Temp with pictures inside it.
  • date/time folders or file renaming with date/time prefix/suffix
  • multiple sources (4-drive card reader)
  • key to exit - it might be better to have it be some obscure key combo like ctrl+alt+shift+e or something rather than just esc (it would be too easy to exit out of)
  • reading indication - the reading indication doesn't seem to work all the time - when I attempted to refresh, it said reading then the reading tooltip disappeared while it was still reading
  • upload done indication - would it be possible to have an upload done indicator / remove the shown photos when done uploading?

Wow, just finished reading over what I wrote and realized I sound like a whiny dictator.  I'm sorry and I don't mean it to be taken that way.  These are just my suggestions.  Other than those, it works great.

P.S. The interface is also a bit sparse.  Is there an easy way to make the buttons slightly bigger / with pictures?

skrommel

  • Fastest code in the west
  • Developer
  • Joined in 2005
  • ***
  • Posts: 933
    • View Profile
    • 1 Hour Software by skrommel
    • Donate to Member
Re: IDEA: Photo Downloader Kiosk
« Reply #10 on: October 08, 2008, 10:47 PM »
 :) Updated PhotoKiosk above!

Got any icons in mind?

Skrommel

NinJA999

  • Supporting Member
  • Joined in 2008
  • **
  • Posts: 79
    • View Profile
    • Donate to Member
Re: IDEA: Photo Downloader Kiosk
« Reply #11 on: October 09, 2008, 04:43 PM »
Wow, it works GREAT, thanks!!!

For icons, I was thinking of using a few from this free set:
http://www.silvestre.com.ar/?p=4
the 128x128 or 48x48 (or 24x24, thought they might be a bit small) icons:
refresh: actions/reload.png
download pics: actions/filesave.png
select all: actions/list-add.png
invert (a tough one to find an icon for): actions/list-remove.png

And, just maybe,
EDIT:http://aldwin.us/imgloadbar.gif
(the image really comes from ajaxloader.info but I just realized the link had hotlink protection.  So here's a friendlier link.)
for when reading/downloading?

Also, I noticed that this line was not working:
WinSetTitle,ahk_id %guiid%,,% applicationname - "Reading pictures..."
So when I replaced it with this line it worked fine:
WinSetTitle,ahk_id %guiid%,,% applicationname " - Reading pictures..."

And finally,
ESC still exits -- is there any way to change it to a less guessable key?

EDIT: Oh, and I had another idea (ugh, I'm so embarrassed that I'm asking you so much): some users might try to click on the picture to select it.  Is it possible to make a click on the picture check/uncheck the checkbox?
« Last Edit: October 09, 2008, 08:57 PM by NinJA999 »

skrommel

  • Fastest code in the west
  • Developer
  • Joined in 2005
  • ***
  • Posts: 933
    • View Profile
    • 1 Hour Software by skrommel
    • Donate to Member
Re: IDEA: Photo Downloader Kiosk
« Reply #12 on: October 10, 2008, 02:23 AM »
 :tellme: There must be something wrong with the icons-archive, a lot of the pngs are 0 bytes!

I thought I'd use the click on the thumbnails to show a preview, but maybe it isn't neccesary?

Skrommel

NinJA999

  • Supporting Member
  • Joined in 2008
  • **
  • Posts: 79
    • View Profile
    • Donate to Member
Re: IDEA: Photo Downloader Kiosk
« Reply #13 on: October 10, 2008, 05:53 AM »
That's strange -- I didn't notice that!  Well, a lot of them are duplicates, so if you look in the thumbnails view you should be able to find the refresh, plus, minus, and download to disk icons.

As for the photo preview,
That would be great too!  Maybe have a checkbox on the preview so that they can check it from there too?

Target

  • Honorary Member
  • Joined in 2006
  • **
  • Posts: 1,832
    • View Profile
    • Donate to Member
Re: IDEA: Photo Downloader Kiosk
« Reply #14 on: October 11, 2008, 05:38 AM »
here's another take

I have no idea what crossover there is with Skrommels code 'cos I haven't really looked at it yet, but it was a fun exercise

it's not full screen (6 images across) cos I had no idea what sort of display your using (and I haven't the time to work this part out  :-[) - feel free to amend the script

there are 2 scripts - the first runs all the time and simply polls your removable drives on a 1 second cycle.  As soon as one becomes available it launches (on first launch it prompts you for a target directory and stores it in an ini file)
/*
Author - Target OCT08
script will scan all removable drives on a 1.5 second cycle
found drives will launch the kiosk (kiosk.AHK)
defaults can be set from the tray icon
*/

#persistent
#singleinstance, forced
menu, tray, nostandard
Menu, tray, add, Set_Defaults
menu, tray, add
menu, tray, add, Exit_Script

ifnotexist, kiosk.ini
gosub, Set_Defaults

loop
{
driveget, DrvLst, list, removable
if DrvLst
{
loop, parse, drvlst
{
driveget, drvstat,status, %a_loopfield%:
if drvstat = ready
{
runwait, kiosk.ahk
sleep, 3000
}
}
DrvLst:=
}
sleep, 1500
}

Set_Defaults:
ifexist, kiosk.ini
{
iniread, target, kiosk.ini, HomeDir, target
iniread, foldind, kiosk.ini, folderIndex, foldcount
}
else
foldind:= 0

gui, add, edit, x10 y10 w200 vTarget, %target%
gui, add, button, x220 y10 gPathout,...
gui, add, text, x10 y38, Folder Index:
gui, add, edit, x90 y38 w120 vFoldInd gsave, %FoldInd%

gui, add, button, x10 y65 w230 gSave, Set Defaults ; Output Directory
gui, show
return

FoldCount:
gui, submit, nohide
return

Save:
iniwrite, %target%, kiosk.ini, homedir, target
iniwrite, %foldInd%, kiosk.ini, FolderIndex, foldcount
gui, destroy
return

Pathout:
fileselectfolder, target, ::{20d04fe0-3aea-1069-a2d8-08002b30309d},3,Select the target folder
guicontrol,,target, %target%
return

Exit_Script:
exitapp
As soon as one becomes available it launches the second script (the actual kiosk part)

/*
Author - Target 09OCT08
credits to AHKLerner and Lexikos for the scroll bar code
script will scan all REMOVABLE drives for eligible images then display in a grid
images can be (un)selected by clicking on either the image or the check box
files are copied or moved using the menu options
copied/moved files have their respective controls disabled
*/

#persistent
#singleinstance
menu, tray, nostandard

iniread, target, kiosk.ini, HomeDir, target
iniread, foldind, kiosk.ini, folderIndex, foldcount

pind = 0

splashtexton,,,SCANNING...

driveget, DrvLst, list, removable

loop, parse, drvlst
{
loop, %a_loopfield%:\*.*,0,1
{
if a_loopfilename contains BMP,JPG,PNG,TIF,GIF,JPEG,JPE,WMF,EMF
{
pind++
gui, add, picture, vt%pind% , %a_loopfilelongpath%
guicontrolget,picsize, pos, t%pind%
gui, destroy

if picsizeh > %picsizew%
gui, add, picture, w-1 h125 vt%pind% , %a_loopfilelongpath%
else
gui, add, picture, w125 h-1 vt%pind% , %a_loopfilelongpath%

guicontrolget,picsize, pos, t%pind%
gui, destroy

if picsizeh > %picsizew%
{
off:= 125 - picsizew
picsizew:= -1
}
else
{
off:= 125 - picsizeh
picsizeh:= -1
}

off//=2

FLst.= a_loopfilelongpath . "," . picsizeh . "," . picsizew . "," . off . "," . "#"
}
}
}
pind:=0

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

px = 10
py = 10
cx = 67
cy = 140

looop = 1

OnMessage(0x115, "OnScroll") ; WM_VSCROLL
OnMessage(0x114, "OnScroll") ; WM_HSCROLL

Gui, +Resize +0x300000 ; WS_VSCROLL | WS_HSCROLL

menu, menubar,add, All
menu, menubar,add, None
menu, menubar,add, Copy
menu, menubar,add, Move
menu, menubar,add, Quit
gui, menu, menubar

loop, parse, flst , `#
{
stringsplit, item, a_loopfield , `,

pyy:= py
pxx:= px

if item3 = -1 ;> item%3%
pxx+= item4
else
pyy+= item4

gui, add, picture, w%item3% h%item2% y%pyy% x%pxx% vp%a_index% gclicpic, %item1%
gui, add, checkbox, x%cx% y%cy% vc%a_index% gclicpic check3
p%a_index%:= item1
c%a_index%:= 0

pind++
looop++

if looop < 7
{
px+= 145
cx+= 145
}
else
{
px = 10
py+= 150
cx= 67
cy+= 150
looop = 1
}
}

splashtextoff
gui, show, autosize center
Gui, +LastFound
GroupAdd, MyGui, % "ahk_id " . WinExist()
return

All:
loop, %pind%
{
guicontrol, , c%a_index%, 1
gui, submit, nohide
}
gui, show, autosize ; center
return

None:
loop, %pind%
{
guicontrol, , c%a_index%, 0
gui, submit, nohide
}
gui, show, autosize ; center
return

Copy:
formattime, Folder,, yyMMdd_HHmm
ifnotexist, %mytarget%\%folder%
filecreatedir, %mytarget%\%folder%

loop, %pind%
{
guicontrolget, chk,,c%a_index%
if chk
{
guicontrolget, pth,,p%a_index%
splashtexton,500,30,Copying, %pth%
filecopy, %pth%, %MyTarget%\%folder%
guicontrol,,c%a_index%, -1
guicontrol,disable,c%a_index%
guicontrol,disable,p%a_index%
gui, submit, nohide
}
}
splashtextoff
return

Move:
formattime, Folder,, yyMMdd_HHmm
ifnotexist, %mytarget%\%folder%
filecreatedir, %mytarget%\%folder%

loop, %pind%
{
guicontrolget, chk,,c%a_index%
if chk
{
guicontrolget, pth,,p%a_index%
splashtexton,500,30,Moving, %pth%
filemove, %pth%, %MyTarget%\%folder%
guicontrol,,c%a_index%, -1
guicontrol,disable,c%a_index%
guicontrol,disable,p%a_index%
gui, submit, nohide
}
}
splashtextoff
return

clicpic:
stringtrimleft, tmp, a_guicontrol, 1
if c%tmp%
guicontrol,, c%tmp%,0
else
guicontrol,, c%tmp%,1

gui, submit, nohide
gui, show, autosize
return

Quit:
escape::
guiclose:
msgbox, Remove card then press OK
exitapp

;^R::
;reload
;return

GuiSize:
    UpdateScrollBars(A_Gui, A_GuiWidth, A_GuiHeight)
return

#IfWinActive ahk_group MyGui
WheelUp::
WheelDown::
+WheelUp::
+WheelDown::
up::
Down::
    ; SB_LINEDOWN=1, SB_LINEUP=0, WM_HSCROLL=0x114, WM_VSCROLL=0x115
    OnScroll(InStr(A_ThisHotkey,"Down") ? 1 : 0, 0, GetKeyState("Shift") ? 0x114 : 0x115, WinExist())
return

#IfWinActive
UpdateScrollBars(GuiNum, GuiWidth, GuiHeight)
{
    static SIF_RANGE=0x1, SIF_PAGE=0x2, SIF_DISABLENOSCROLL=0x8, SB_HORZ=0, SB_VERT=1
   
    Gui, %GuiNum%:Default
    Gui, +LastFound
   
    ; Calculate scrolling area.
    Left := Top := 9999
    Right := Bottom := 0
    WinGet, ControlList, ControlList
    Loop, Parse, ControlList, `n
    {
        GuiControlGet, c, Pos, %A_LoopField%
        if (cX < Left)
            Left := cX
        if (cY < Top)
            Top := cY
        if (cX + cW > Right)
            Right := cX + cW
        if (cY + cH > Bottom)
            Bottom := cY + cH
    }
    Left -= 8
    Top -= 8
    Right += 8
    Bottom += 8
    ScrollWidth := Right-Left
    ScrollHeight := Bottom-Top
   
    ; Initialize SCROLLINFO.
    VarSetCapacity(si, 28, 0)
    NumPut(28, si) ; cbSize
    NumPut(SIF_RANGE | SIF_PAGE, si, 4) ; fMask
   
    ; Update horizontal scroll bar.
    NumPut(ScrollWidth, si, 12) ; nMax
    NumPut(GuiWidth, si, 16) ; nPage
    DllCall("SetScrollInfo", "uint", WinExist(), "uint", SB_HORZ, "uint", &si, "int", 1)
   
    ; Update vertical scroll bar.
;     NumPut(SIF_RANGE | SIF_PAGE | SIF_DISABLENOSCROLL, si, 4) ; fMask
    NumPut(ScrollHeight, si, 12) ; nMax
    NumPut(GuiHeight, si, 16) ; nPage
    DllCall("SetScrollInfo", "uint", WinExist(), "uint", SB_VERT, "uint", &si, "int", 1)
   
    if (Left < 0 && Right < GuiWidth)
        x := Abs(Left) > GuiWidth-Right ? GuiWidth-Right : Abs(Left)
    if (Top < 0 && Bottom < GuiHeight)
        y := Abs(Top) > GuiHeight-Bottom ? GuiHeight-Bottom : Abs(Top)
    if (x || y)
        DllCall("ScrollWindow", "uint", WinExist(), "int", x, "int", y, "uint", 0, "uint", 0)
}

OnScroll(wParam, lParam, msg, hwnd)
{
    static SIF_ALL=0x17, SCROLL_STEP=10
   
    bar := msg=0x115 ; SB_HORZ=0, SB_VERT=1
   
    VarSetCapacity(si, 28, 0)
    NumPut(28, si) ; cbSize
    NumPut(SIF_ALL, si, 4) ; fMask
    if !DllCall("GetScrollInfo", "uint", hwnd, "int", bar, "uint", &si)
        return
   
    VarSetCapacity(rect, 16)
    DllCall("GetClientRect", "uint", hwnd, "uint", &rect)
   
    new_pos := NumGet(si, 20) ; nPos
   
    action := wParam & 0xFFFF
    if action = 0 ; SB_LINEUP
        new_pos -= SCROLL_STEP
    else if action = 1 ; SB_LINEDOWN
        new_pos += SCROLL_STEP
    else if action = 2 ; SB_PAGEUP
        new_pos -= NumGet(rect, 12, "int") - SCROLL_STEP
    else if action = 3 ; SB_PAGEDOWN
        new_pos += NumGet(rect, 12, "int") - SCROLL_STEP
    else if action = 5 ; SB_THUMBTRACK
        new_pos := NumGet(si, 24, "int") ; nTrackPos
    else if action = 6 ; SB_TOP
        new_pos := NumGet(si, 8, "int") ; nMin
    else if action = 7 ; SB_BOTTOM
        new_pos := NumGet(si, 12, "int") ; nMax
    else
        return
   
    min := NumGet(si, 8, "int") ; nMin
    max := NumGet(si, 12, "int") - NumGet(si, 16) ; nMax-nPage
    new_pos := new_pos > max ? max : new_pos
    new_pos := new_pos < min ? min : new_pos
   
    old_pos := NumGet(si, 20, "int") ; nPos
   
    x := y := 0
    if bar = 0 ; SB_HORZ
        x := old_pos-new_pos
    else
        y := old_pos-new_pos
    ; Scroll contents of window and invalidate uncovered area.
    DllCall("ScrollWindow", "uint", hwnd, "int", x, "int", y, "uint", 0, "uint", 0)
   
    ; Update scroll bar.
    NumPut(new_pos, si, 20, "int") ; nPos
    DllCall("SetScrollInfo", "uint", hwnd, "int", bar, "uint", &si, "int", 1)
}

copy/move/select all/select none from the menu bar

click on either an image or it's check box to select.  Copied files have their check box greyed out, moved files are disabled

each time a card is inserted and files are copied or moved, a new (sequential) folder is created in the target folder

when your done, select quit from the menu bar - users are prompted to remove their card before proceeding, and the script ends.

one issue that I haven't quite worked out yet is that repeatedly selecting all/selecting none shrinks the window ( :huh:)

EDIT - 28OCT08 09:25
        - amended 'polling' script to work as intended (now correctly detects removable media) 
        - added option to set defaults (from Tray menu)
        - fixed the shrinking GUI behaviour

to do - fix aspect ratio of images

EDIT - 31OCT08 14:35
        - fixed image aspect ratio
        - correctly aligned images

« Last Edit: October 30, 2008, 11:38 PM by Target »

NinJA999

  • Supporting Member
  • Joined in 2008
  • **
  • Posts: 79
    • View Profile
    • Donate to Member
Re: IDEA: Photo Downloader Kiosk
« Reply #15 on: October 11, 2008, 03:43 PM »
Wow, that's great too, Target.  A couple of things:
The polling doesn't work with my card reader, because when you remove the card, the drive itself still exists (it just says Removable Disk whatever), so your script launches the kiosk every second, which says "No images found, remove card and press OK."  Also, the thumbnails were stretched to fit the square rather than keeping the aspect ratio & whitespace.  Also, when I selected all, then none, rather than clearing the checkboxes, it made them all completely colored in.  Wow, bad word choice.  Here's non-checked: [ ], here's checked: [v], here's "colored in":
  • .  When I clicked each individual checkbox, it cycled through those three settings rather than just checked/unchecked.  Finally, I'm not quite sure how to set the destination folder.  Other than that, it's great.

Target

  • Honorary Member
  • Joined in 2006
  • **
  • Posts: 1,832
    • View Profile
    • Donate to Member
Re: IDEA: Photo Downloader Kiosk
« Reply #16 on: October 11, 2008, 08:39 PM »
Wow, that's great too, Target.  A couple of things:
The polling doesn't work with my card reader, because when you remove the card, the drive itself still exists (it just says Removable Disk whatever), so your script launches the kiosk every second, which says "No images found, remove card and press OK."  Also, the thumbnails were stretched to fit the square rather than keeping the aspect ratio & whitespace.  Also, when I selected all, then none, rather than clearing the checkboxes, it made them all completely colored in.  Wow, bad word choice.  Here's non-checked: [ ], here's checked: [v], here's "colored in":
  • .  When I clicked each individual checkbox, it cycled through those three settings rather than just checked/unchecked.  Finally, I'm not quite sure how to set the destination folder.  Other than that, it's great.
hmmm, interesting, but all in all a total failure...

I thought about the aspect ratio but figured that this was just a means of getting it from the card to the HDD and not an image viewer, so it wasn't really that important (it seemed safe to assume that the individuals would already know what the images were, they just needed a means of choosing the ones they wanted)

I also wondered what would happen with your card reader - I don't have one to test with so I used a USB key.  Not sure how to get around this one...

The 'greying' of the checkboxes was supposed to indicate that an image had already been copied, I never thought about the fact that there were now 3 options when you check the boxes (DOH!), I'll have a look and see if I can amend that on a control by control basis.  Actually this isn't really that important so it could be omitted (I've amended my code)

Re the destination folder, you should get a dialog box the first time you run the polling script that lets you select a folder.  This is then stored in the ini file - you can edit the ini file by hand, or delete it and you'll be prompted again (be aware that if you delete it your folder count will be reset) 

I'm off on holdidays for the next couple of weeks so I mightn't be about, but I'll look at this and see if I can solve some of those issues - thanks for the feedback

NinJA999

  • Supporting Member
  • Joined in 2008
  • **
  • Posts: 79
    • View Profile
    • Donate to Member
Re: IDEA: Photo Downloader Kiosk
« Reply #17 on: October 11, 2008, 08:46 PM »
The aspect ratio just seems like a good thing -- what if a naive user thinks the kiosk is changing his photos so people are stretched? (lol)

greying
It wasn't really greying (disabling, I'm assuming you meant?), but instead of a green check it was a green box inside the checkbox.

Only one dialog popped up, and I thought that was for the folder to check, not the destination folder.  Hmm.

jakebass

  • Participant
  • Joined in 2008
  • *
  • default avatar
  • Posts: 2
    • View Profile
    • Donate to Member
Re: IDEA: Photo Downloader Kiosk
« Reply #18 on: October 15, 2008, 01:20 AM »
I'm new here, but looking for code for the same general purpose... Could someone give a newbie a short intro as to how I can compile this code? Thanks.

Deozaan

  • Charter Member
  • Joined in 2006
  • ***
  • Points: 1
  • Posts: 9,747
    • View Profile
    • Read more about this member.
    • Donate to Member
Re: IDEA: Photo Downloader Kiosk
« Reply #19 on: October 15, 2008, 01:51 AM »
Jakebass: Download and install AutoHotKey.

Then you can just right-click the .ahk file and select "Compile to exe" or something similar.

NinJA999

  • Supporting Member
  • Joined in 2008
  • **
  • Posts: 79
    • View Profile
    • Donate to Member
Re: IDEA: Photo Downloader Kiosk
« Reply #20 on: October 15, 2008, 06:10 AM »
or if you just want to run it without making an exe, just double click it (once installing AutoHotKey, of course)

jakebass

  • Participant
  • Joined in 2008
  • *
  • default avatar
  • Posts: 2
    • View Profile
    • Donate to Member
Re: IDEA: Photo Downloader Kiosk
« Reply #21 on: October 15, 2008, 09:51 PM »
thank you.  your coding has saved me hundreds of dollars.... if you're curious, its for a yearbook photo upload kiosk at my school.  i'm a junior. haha

NinJA999

  • Supporting Member
  • Joined in 2008
  • **
  • Posts: 79
    • View Profile
    • Donate to Member
Re: IDEA: Photo Downloader Kiosk
« Reply #22 on: October 15, 2008, 10:17 PM »
haha I'm a junior too, and I already explained my circumstances.

and, is Skrommel still working on it, or has he gone on to better projects?

skrommel

  • Fastest code in the west
  • Developer
  • Joined in 2005
  • ***
  • Posts: 933
    • View Profile
    • 1 Hour Software by skrommel
    • Donate to Member
Re: IDEA: Photo Downloader Kiosk
« Reply #23 on: October 18, 2008, 12:54 PM »
 :) Updated the script above above to show a preview window.

Something's wrong with the icon-gz-archive, though.

Skrommel

NinJA999

  • Supporting Member
  • Joined in 2008
  • **
  • Posts: 79
    • View Profile
    • Donate to Member
Re: IDEA: Photo Downloader Kiosk
« Reply #24 on: October 18, 2008, 01:58 PM »
That's strange--it worked fine for me.  Anyway, I extracted the PNGs I wished to use and put them here:
http://aldwin.us/PKicons/
(in folders by size - 128, 48, 24)
again,
  • refresh: reload.png
  • download pics: filesave.png
  • select all: list-add.png
  • invert (a tough one to find an icon for): list-remove.png
Hopefully you can get the images successfully now.
Also, any idea whether you'd like to use the loading bar image http://aldwin.us/imgloadbar.gif?
The new exit key works great!  Nothing else works, not even Alt+F4.  Awesome!
Everything else looks great.  Thank you so much.