Jump to content


Photo

Changing a directory in an existing script


  • Please log in to reply
2 replies to this topic

#1 abhijith444

abhijith444
  • Members
  • 21 posts

Posted 01 May 2012 - 06:32 AM

I found this fantastic script to save a screenshot to a jpg file directory. However I'm having trouble integrating it with my default Autohotkey script

The script runs fine when I run it individually as test.ahk (Its was on desktop).
A separate directory is created and the images are being saved. But when I copy the same script into my autohotkey.ahk, it won't work.

My Autohotkey.ahk file is in "My Docs". May be it does not have a permission to create a directory there.
Question : Can some one modify the script so that I can give the script a path and it saves the files there.
/*
 *   1. Keep script running.
 *   2. Limit to one running copy.
 *   3. Run script without pauses.
 */
#Persistent
#SingleInstance ignore
SetBatchLines, 10ms



/*
 *-------------------------------------------------------------------------------------
 *       Use hotkey:    Win + PrtScr
 *-------------------------------------------------------------------------------------
 */
#PrintScreen::

   /*
    * Create folder.
    */
   IfNotExist, PrintScreen
   {
      FileCreateDir, PrintScreen
   }


   /*
    * Reset counter.
    */
   countLoop := 1


   /*
    * Repeat until we have unused name for file.
    */
   loopFileName:

      /*
       * Reset string.
       */
      countLoopString := countLoop
      
      /*
       * Add leading zeroes to string.
       */
      loopStringAddZeroes:
         if (StrLen(countLoopString) < 4)
         {
            countLoopString := "0" countLoopString
            Goto, loopStringAddZeroes
         }
      
      /*
       * Form the name of new file.
       */
      newFileName := "PrintScreen\img_" countLoopString ".jpg"
      
      /*
       * Check if file name is taken.
       */
      IfExist, % newFileName
      {
         countLoop++
         Goto, loopFileName
      }

      
   /*
    * Capture screenshot.
    */
   CaptureScreen(0, False, newFileName, 100)
return



/*
 * If the script goes this far...
 */
Exit




/*
 *-------------------------------------------------------------------------------------
 *   Screen Capture with Transparent Windows and Mouse Cursor:
 *         http://www.autohotkey.com/forum/topic18146.html
 *-------------------------------------------------------------------------------------
   CaptureScreen(aRect, bCursor, sFileTo, nQuality)
      1) If the optional parameter bCursor is True, captures the cursor too.
      2) If the optional parameter sFileTo is 0, set the image to Clipboard.
         If it is omitted or "", saves to screen.bmp in the script folder,
         otherwise to sFileTo which can be BMP/JPG/PNG/GIF/TIF.
      3) The optional parameter nQuality is applicable only when sFileTo is JPG. Set it to the desired quality level of the resulting JPG, an integer between 0 - 100.
      4) If aRect is 0/1/2/3, captures the entire desktop/active window/active client area/active monitor.
      5) aRect can be comma delimited sequence of coordinates, e.g., "Left, Top, Right, Bottom" or "Left, Top, Right, Bottom, Width_Zoomed, Height_Zoomed".
         In this case, only that portion of the rectangle will be captured. Additionally, in the latter case, zoomed to the new width/height, Width_Zoomed/Height_Zoomed.

   Example:
      CaptureScreen(0)
      CaptureScreen(1)
      CaptureScreen(2)
      CaptureScreen(3)
      CaptureScreen("100, 100, 200, 200")
      CaptureScreen("100, 100, 200, 200, 400, 400")   ; Zoomed

   Convert:
      Convert(sFileFr, sFileTo, nQuality)
      Convert("C:\image.bmp", "C:\image.jpg")
      Convert("C:\image.bmp", "C:\image.jpg", 95)
      Convert(0, "C:\clip.png")   ; Save the bitmap in the clipboard to sFileTo if sFileFr is "" or 0.
*/

;CaptureScreen()
;Return

CaptureScreen(aRect = 0, bCursor = False, sFile = "", nQuality = "")
{
   If   !aRect
   {
      SysGet, nL, 76
      SysGet, nT, 77
      SysGet, nW, 78
      SysGet, nH, 79
   }
   Else If   aRect = 1
      WinGetPos, nL, nT, nW, nH, A
   Else If   aRect = 2
   {
      WinGet, hWnd, ID, A
      VarSetCapacity(rt, 16, 0)
      DllCall("GetClientRect" , "Uint", hWnd, "Uint", &rt)
      DllCall("ClientToScreen", "Uint", hWnd, "Uint", &rt)
      nL := NumGet(rt, 0, "int")
      nT := NumGet(rt, 4, "int")
      nW := NumGet(rt, 8)
      nH := NumGet(rt,12)
   }
   Else If   aRect = 3
   {
      VarSetCapacity(mi, 40, 0)
      DllCall("GetCursorPos", "int64P", pt)
      DllCall("GetMonitorInfo", "Uint", DllCall("MonitorFromPoint", "int64", pt, "Uint", 2), "Uint", NumPut(40,mi)-4)
      nL := NumGet(mi, 4, "int")
      nT := NumGet(mi, 8, "int")
      nW := NumGet(mi,12, "int") - nL
      nH := NumGet(mi,16, "int") - nT
   }
   Else
   {
      StringSplit, rt, aRect, `,, %A_Space%%A_Tab%
      nL := rt1
      nT := rt2
      nW := rt3 - rt1
      nH := rt4 - rt2
      znW := rt5
      znH := rt6
   }

   mDC := DllCall("CreateCompatibleDC", "Uint", 0)
   hBM := CreateDIBSection(mDC, nW, nH)
   oBM := DllCall("SelectObject", "Uint", mDC, "Uint", hBM)
   hDC := DllCall("GetDC", "Uint", 0)
   DllCall("BitBlt", "Uint", mDC, "int", 0, "int", 0, "int", nW, "int", nH, "Uint", hDC, "int", nL, "int", nT, "Uint", 0x40000000 | 0x00CC0020)
   DllCall("ReleaseDC", "Uint", 0, "Uint", hDC)
   If   bCursor
      CaptureCursor(mDC, nL, nT)
   DllCall("SelectObject", "Uint", mDC, "Uint", oBM)
   DllCall("DeleteDC", "Uint", mDC)
   If   znW && znH
      hBM := Zoomer(hBM, nW, nH, znW, znH)
   If   sFile = 0
      SetClipboardData(hBM)
   Else   Convert(hBM, sFile, nQuality), DllCall("DeleteObject", "Uint", hBM)
}

CaptureCursor(hDC, nL, nT)
{
   VarSetCapacity(mi, 20, 0)
   mi := Chr(20)
   DllCall("GetCursorInfo", "Uint", &mi)
   bShow   := NumGet(mi, 4)
   hCursor := NumGet(mi, 8)
   xCursor := NumGet(mi,12)
   yCursor := NumGet(mi,16)

   VarSetCapacity(ni, 20, 0)
   DllCall("GetIconInfo", "Uint", hCursor, "Uint", &ni)
   xHotspot := NumGet(ni, 4)
   yHotspot := NumGet(ni, 8)
   hBMMask  := NumGet(ni,12)
   hBMColor := NumGet(ni,16)

   If   bShow
      DllCall("DrawIcon", "Uint", hDC, "int", xCursor - xHotspot - nL, "int", yCursor - yHotspot - nT, "Uint", hCursor)
   If   hBMMask
      DllCall("DeleteObject", "Uint", hBMMask)
   If   hBMColor
      DllCall("DeleteObject", "Uint", hBMColor)
}

Zoomer(hBM, nW, nH, znW, znH)
{
   mDC1 := DllCall("CreateCompatibleDC", "Uint", 0)
   mDC2 := DllCall("CreateCompatibleDC", "Uint", 0)
   zhBM := CreateDIBSection(mDC2, znW, znH)
   oBM1 := DllCall("SelectObject", "Uint", mDC1, "Uint",  hBM)
   oBM2 := DllCall("SelectObject", "Uint", mDC2, "Uint", zhBM)
   DllCall("SetStretchBltMode", "Uint", mDC2, "int", 4)
   DllCall("StretchBlt", "Uint", mDC2, "int", 0, "int", 0, "int", znW, "int", znH, "Uint", mDC1, "int", 0, "int", 0, "int", nW, "int", nH, "Uint", 0x00CC0020)
   DllCall("SelectObject", "Uint", mDC1, "Uint", oBM1)
   DllCall("SelectObject", "Uint", mDC2, "Uint", oBM2)
   DllCall("DeleteDC", "Uint", mDC1)
   DllCall("DeleteDC", "Uint", mDC2)
   DllCall("DeleteObject", "Uint", hBM)
   Return   zhBM
}

Convert(sFileFr = "", sFileTo = "", nQuality = "")
{
   If   sFileTo  =
      sFileTo := A_ScriptDir . "\screen.bmp"
   SplitPath, sFileTo, , sDirTo, sExtTo, sNameTo

   If Not   hGdiPlus := DllCall("LoadLibrary", "str", "gdiplus.dll")
      Return   sFileFr+0 ? SaveHBITMAPToFile(sFileFr, sDirTo . "\" . sNameTo . ".bmp") : ""
   VarSetCapacity(si, 16, 0), si := Chr(1)
   DllCall("gdiplus\GdiplusStartup", "UintP", pToken, "Uint", &si, "Uint", 0)

   If   !sFileFr
   {
      DllCall("OpenClipboard", "Uint", 0)
      If    DllCall("IsClipboardFormatAvailable", "Uint", 2) && (hBM:=DllCall("GetClipboardData", "Uint", 2))
      DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", "Uint", hBM, "Uint", 0, "UintP", pImage)
      DllCall("CloseClipboard")
   }
   Else If   sFileFr Is Integer
      DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", "Uint", sFileFr, "Uint", 0, "UintP", pImage)
   Else   DllCall("gdiplus\GdipLoadImageFromFile", "Uint", Unicode4Ansi(wFileFr,sFileFr), "UintP", pImage)

   DllCall("gdiplus\GdipGetImageEncodersSize", "UintP", nCount, "UintP", nSize)
   VarSetCapacity(ci,nSize,0)
   DllCall("gdiplus\GdipGetImageEncoders", "Uint", nCount, "Uint", nSize, "Uint", &ci)
   Loop, %   nCount
      If   InStr(Ansi4Unicode(NumGet(ci,76*(A_Index-1)+44)), "." . sExtTo)
      {
         pCodec := &ci+76*(A_Index-1)
         Break
      }
   If   InStr(".JPG.JPEG.JPE.JFIF", "." . sExtTo) && nQuality<>"" && pImage && pCodec
   {
   DllCall("gdiplus\GdipGetEncoderParameterListSize", "Uint", pImage, "Uint", pCodec, "UintP", nSize)
   VarSetCapacity(pi,nSize,0)
   DllCall("gdiplus\GdipGetEncoderParameterList", "Uint", pImage, "Uint", pCodec, "Uint", nSize, "Uint", &pi)
   Loop, %   NumGet(pi)
      If   NumGet(pi,28*(A_Index-1)+20)=1 && NumGet(pi,28*(A_Index-1)+24)=6
      {
         pParam := &pi+28*(A_Index-1)
         NumPut(nQuality,NumGet(NumPut(4,NumPut(1,pParam+0)+20)))
         Break
      }
   }

   If   pImage
      pCodec   ? DllCall("gdiplus\GdipSaveImageToFile", "Uint", pImage, "Uint", Unicode4Ansi(wFileTo,sFileTo), "Uint", pCodec, "Uint", pParam) : DllCall("gdiplus\GdipCreateHBITMAPFromBitmap", "Uint", pImage, "UintP", hBitmap, "Uint", 0) . SetClipboardData(hBitmap), DllCall("gdiplus\GdipDisposeImage", "Uint", pImage)

   DllCall("gdiplus\GdiplusShutdown" , "Uint", pToken)
   DllCall("FreeLibrary", "Uint", hGdiPlus)
}

CreateDIBSection(hDC, nW, nH, bpp = 32, ByRef pBits = "")
{
   NumPut(VarSetCapacity(bi, 40, 0), bi)
   NumPut(nW, bi, 4)
   NumPut(nH, bi, 8)
   NumPut(bpp, NumPut(1, bi, 12, "UShort"), 0, "Ushort")
   NumPut(0,  bi,16)
   Return   DllCall("gdi32\CreateDIBSection", "Uint", hDC, "Uint", &bi, "Uint", 0, "UintP", pBits, "Uint", 0, "Uint", 0)
}

SaveHBITMAPToFile(hBitmap, sFile)
{
   DllCall("GetObject", "Uint", hBitmap, "int", VarSetCapacity(oi,84,0), "Uint", &oi)
   hFile:=   DllCall("CreateFile", "Uint", &sFile, "Uint", 0x40000000, "Uint", 0, "Uint", 0, "Uint", 2, "Uint", 0, "Uint", 0)
   DllCall("WriteFile", "Uint", hFile, "int64P", 0x4D42|14+40+NumGet(oi,44)<<16, "Uint", 6, "UintP", 0, "Uint", 0)
   DllCall("WriteFile", "Uint", hFile, "int64P", 54<<32, "Uint", 8, "UintP", 0, "Uint", 0)
   DllCall("WriteFile", "Uint", hFile, "Uint", &oi+24, "Uint", 40, "UintP", 0, "Uint", 0)
   DllCall("WriteFile", "Uint", hFile, "Uint", NumGet(oi,20), "Uint", NumGet(oi,44), "UintP", 0, "Uint", 0)
   DllCall("CloseHandle", "Uint", hFile)
}

SetClipboardData(hBitmap)
{
   DllCall("GetObject", "Uint", hBitmap, "int", VarSetCapacity(oi,84,0), "Uint", &oi)
   hDIB :=   DllCall("GlobalAlloc", "Uint", 2, "Uint", 40+NumGet(oi,44))
   pDIB :=   DllCall("GlobalLock", "Uint", hDIB)
   DllCall("RtlMoveMemory", "Uint", pDIB, "Uint", &oi+24, "Uint", 40)
   DllCall("RtlMoveMemory", "Uint", pDIB+40, "Uint", NumGet(oi,20), "Uint", NumGet(oi,44))
   DllCall("GlobalUnlock", "Uint", hDIB)
   DllCall("DeleteObject", "Uint", hBitmap)
   DllCall("OpenClipboard", "Uint", 0)
   DllCall("EmptyClipboard")
   DllCall("SetClipboardData", "Uint", 8, "Uint", hDIB)
   DllCall("CloseClipboard")
}

Unicode4Ansi(ByRef wString, sString)
{
   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   &wString
}

Ansi4Unicode(pString)
{
   nSize := DllCall("WideCharToMultiByte", "Uint", 0, "Uint", 0, "Uint", pString, "int", -1, "Uint", 0, "int",  0, "Uint", 0, "Uint", 0)
   VarSetCapacity(sString, nSize)
   DllCall("WideCharToMultiByte", "Uint", 0, "Uint", 0, "Uint", pString, "int", -1, "str", sString, "int", nSize, "Uint", 0, "Uint", 0)
   Return   sString
}




/*
 *====================================================================================
 *                           END OF FILE
 *====================================================================================
 */


#2 Leef_me

Leef_me
  • Moderators
  • 7704 posts

Posted 01 May 2012 - 07:16 AM

Hi abhijith444, welcome to the forum.

Did you know that the files autohotkey.ahk is just a convenience?
What I mean is that you can have files with other name like "this_is_a_test.ahk"

Have you worked through the tutorials? It would make things easier for you to understand.

Without changing the script, the path of the folder is based on where the script is located.
When you copy the contents in another file such as "autohotkey.ahk" you need to be careful
that you don't use the same variables in other portions of you script.

Instead of making the changes, I'll describe what changes need to be made.
1. you need a variable at the top of the script with your assigned to it.
If you combine the script with others, this line will need to be executed before you start screen-captures.

mypath:="C:\Users\Leef_me\Documents\Autohotkey"
The "" are a precaution in case the path has a space in the name.
That variable would be used like this

;;;FileCreateDir, PrintScreen ; <-- old
FileCreateDir, %mypath%

In one location the %% are not used
;;  newFileName := "PrintScreen\img_" countLoopString ".jpg"
newFileName := mypath "\img_" countLoopString ".jpg"

After you have tested the script and want to combine it with another,
I suggest that you consider the command #include to include the contents
of this file within another script, but you don't have to copy/past the text.

#3 abhijith444

abhijith444
  • Members
  • 21 posts

Posted 01 May 2012 - 07:54 AM

Hi abhijith444, welcome to the forum.

Did you know that the files autohotkey.ahk is just a convenience?
What I mean is that you can have files with other name like "this_is_a_test.ahk"

Have you worked through the tutorials? It would make things easier for you to understand.

Yeah I know that but I have created a batch file to back it up to my Dropbox so I thought I won't change the name.
Anyway I'm now thinking of putting it directly in the Dropbox.

Without changing the script, the path of the folder is based on where the script is located.
When you copy the contents in another file such as "autohotkey.ahk" you need to be careful
that you don't use the same variables in other portions of you script.

Instead of making the changes, I'll describe what changes need to be made.
1. you need a variable at the top of the script with your assigned to it.
If you combine the script with others, this line will need to be executed before you start screen-captures.

mypath:="C:\Users\Leef_me\Documents\Autohotkey"
The "" are a precaution in case the path has a space in the name.
That variable would be used like this

;;;FileCreateDir, PrintScreen ; <-- old
FileCreateDir, %mypath%

In one location the %% are not used
;;  newFileName := "PrintScreen\img_" countLoopString ".jpg"
newFileName := mypath "\img_" countLoopString ".jpg"

After you have tested the script and want to combine it with another,
I suggest that you consider the command #include to include the contents
of this file within another script, but you don't have to copy/past the text.


I just feel its more handy if all my scripts are in a single file. So I'll try to make it work from the same script.
I'll use this variable and modify the code. Thanks for the help.
I'll update the further issues