AutoHotkey Community

It is currently May 26th, 2012, 1:02 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 123 posts ]  Go to page Previous  1, 2, 3, 4, 5 ... 9  Next
Author Message
PostPosted: December 11th, 2007, 4:58 am 
Offline

Joined: November 24th, 2007, 9:07 pm
Posts: 774
New features
-More windows resizable
-Tab support enhanced
-Dock performance enhanced
-Universal volume up/down/mute hotkeys (Vista support w/o UAC!)
-Toggle dock with a hotkey!
-Unlimited custom hotkey support - INI-based (GUI coming soon)

New fixes:
-Exe version Include error fixed
-Dock rollovers work properly
-Dock re-opens and closes properly

Known issues:
-File-running hotkeys not yet implemented, only label-based hotkeys so far
-Some tabs still blank, content coming soon
-Backups never clean themselves up (lists get large fast) - fixed soon

Hotkeys:
Shift+End - Toggle Mute
Shift+PgUp - Vol Up
Shift+PgDn - Volume Dn
Shift+Home - Toggle Steam Dock
Note: By default, Volume_Up, Volume_Down, and Volume_Mute controls are also hotkeys to my volume functions. This can be removed from cfg\hotkeys.ini if you'd like.

_________________
Ben

My Trac projects
My Wiki
[Broken] - My music


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 11th, 2007, 5:13 am 
Offline

Joined: November 24th, 2007, 9:07 pm
Posts: 774
If you downloaded the Exe version in the last 10 minutes, please re-download. It was missing cfg\hotkeys.ini.

Sorry folks... all fixed.

_________________
Ben

My Trac projects
My Wiki
[Broken] - My music


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 11th, 2007, 6:43 am 
Offline

Joined: July 2nd, 2006, 9:04 pm
Posts: 25
It works.. not sure what to do with it since I only play Counter Strike :oops:

I have a suggestion for you, when I hit lock (being a first time user) it asked me for a password.. I didn't want one so I hit Ok (or whatever it said) and then it asked me to repeat it so I left it blank again....

This became a none to fun cycle of the window coming up and asking me for a password.... then to repeat it...

So perhaps a check saying the pw is to short or allowing a null password....

And so what the buttons are ugly on my XP computer, the thing works!


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 11th, 2007, 6:49 am 
Offline

Joined: November 24th, 2007, 9:07 pm
Posts: 774
Thanks a lot for testing, and for the suggestion!

One question I have, which I guess doesn't really matter, is why would you want to lock the steam window if you don't have a password? Well, I suppose that's one password many people wouldn't try technically :)

Regardless, I should add the functionality to allow a blank password, so it is on the list for the next release.

Aside from the buttons does everything seem to match Steam for you? I'm trying to get it as close as possible. I'd really like to figure out the button issue with XP however. The screenshots on the page for AddGraphicButton() in the forum don't show the problem I have, and I'm assuming he took those in XP, so there must be a fix somewhere.

_________________
Ben

My Trac projects
My Wiki
[Broken] - My music


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 11th, 2007, 7:43 am 
Offline

Joined: November 24th, 2007, 9:07 pm
Posts: 774
Unconfirmed issues found with Steam locking that weren't there in old versions:
-When window locked, sometimes the challenge box doesn't seem to come up. Must be a timer issue.
-Window doesn't seem to want to unlock properly, at least for me. Or rather, it unlocks, but it still challenges me for a password.

I must have some timers conflicting or something. The script is becoming quite large :)

I will be releasing a new version with a Hotkey Manager gui (and of course the ability to graphically create unlimited hotkeys for SteamLab functions and for program launching) very soon. I'll try to have these bugs fixed by then as well. I'll incorporate blank password support into the script as soon as I fix this locking bug as well.

_________________
Ben

My Trac projects
My Wiki
[Broken] - My music


Report this post
Top
 Profile  
Reply with quote  
 Post subject: New Version Coming!
PostPosted: December 14th, 2007, 3:31 am 
Offline

Joined: November 24th, 2007, 9:07 pm
Posts: 774
Upcoming Features:
-Hotkey Manager - GUI to create unlimited hotkeys for SteamLab functions, or to run any file you want!
-GUI buttons now generated on the fly - smaller download size!
-Backup Pruning - keep a maximum number of any type of backup

Upcoming Fixes:
-Steam locking works properly, including challenge-on-exit
-Dock showing/hiding performance greatly increased
-Vista volume issue fixed (I think)

Known Issues:
-If Steam locked, you can right-click its tray icon, exit, run it again, and it will work.
-Generated buttons have transparency issue
-When resizable SteamWin windows are opened, they lose focus. I'm trying to figure out what causes this.

In Development (probably the version after this):
-Functional Game backups
-Backup scheduling
-custom game overlay for OSD and SteamLab windows
-Ability to include other windows in the overlay (no more need to purchase Game Overlay software!)

News: Kane & Lynch and Universe at War both released today on Steam!

_________________
Ben

My Trac projects
My Wiki
[Broken] - My music


Last edited by bmcclure on December 18th, 2007, 6:39 am, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 18th, 2007, 6:15 am 
Offline

Joined: November 24th, 2007, 9:07 pm
Posts: 774
The new version, which is going to be released tomorrow or Wednesday, will include the above changes as well as:

-(Optional) Oblivion Mod Manager (OBMM) integration
-Rounded corners on all windows, including the dock (matches Steam)

And behind the scenes:
-Ability to parse Steam's shortcuts.vdf file to get information about your Non-Steam Games. This will allow things like automatic updates, game title auto-completion, and more.

And in active development is the new (related) Automatic Updates feature. It will mimic as closely as possible the auto-update feature of Steam which keeps your games up-to-date behind the scenes, only for all the games Steam doesn't manage (Your shortcuts). On a customizable schedule, SteamLab will be able to:
Quote:
1. Parse your shortcuts file, getting any new games added to the list
2. Try to determine the current version of any game it doesn't already know by parsing readme files and/or looking at the Exe version
3. Display a list of games with unknown versions to allow manual entry (but other updates will continue in the background regardless of this window)
4. Search gameupdates.org for newer patches (best method I can figure so far)
5. Either notify you, or optionally auto-download/install the patch. Update information and patches are downloaded and installed asynchronously to save time and maximize bandwidth usage.
6. Store all the current version numbers in XML format
7. Optionally display an update summary upon completion.


A working version might be coming within the next week or so if I can get my xpath() (the AHK function, not the language) behavior under control so that the gameversions.xml file works properly.

This is (will be) one of the major features and benefits of SteamLab, so I want to do it right!

Any suggestions for changes or features for the upcoming update manager?

(I plan to introduce a bandwidth cap option, just probably not right away)


Also in development:
Crash Detection
SteamLab (optionally) will know when a full-screen game crashes, and will gather as much troubleshooting information as possible and log it / display it for the user.

It will optionally auto-download a CLI memdump analyzer and parse the memdump after a full system crash, displaying the driver or other valuable information in a nice readable format.

This will be another major feature of SteamLab, especially for me since I have such a wide variety of crashes in such a wide variety of games and I get tired of having to hunt down the culprit driver :lol:

_________________
Ben

My Trac projects
My Wiki
[Broken] - My music


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 22nd, 2007, 9:53 pm 
Offline

Joined: November 24th, 2007, 9:07 pm
Posts: 774
Upcoming Release Updates:

Auto-generated GUI Buttons
Auto-generated GUI text buttons are now 100% working. Now I'll only need to include a couple of 3KB button templates with the download, and the rest will be managed within the script. Now that SteamLab is growing larger, this will save an increasing amount of space.
The new buttons are actually Gui Pictures, so they will look properly on Windows 2000+. No more XP button edges showing through!

New OSD
The OSD is no longer green text on a transparent background. It is now white text on a partially-transparent, rounded blue rectangle. This is meant to mimick the OSD in the game Team Fortress 2 (but mine lacks the white border). Trust me, it looks a lot nicer. Depending on feedback, I may add an option for the old version if anyone prefers it. The new version has the added benefit of not having jagged font edges if the OSD is over a colored background.
Image
^ I also plan to make an option to switch it to Red, for those who prefer the Red team in TF2, or red in general :)

Hotkey Manager alpha ready
Included with the upcoming version: A working Hotkey Manager GUI where you can create hotkeys for several SteamLab functions (many more coming soon). You can also create hotkeys that will run applications, but that feature is not fully implemented yet. Those hotkeys will work in an upcoming version of SteamLab.
Image
^ Note the text buttons that look exactly like the old buttons, and the rounded window corners. And yeah, somehow I missed it. I have added a Close button to this window now. It's just not in this screenshot.

Auto-Update Manager Progress
The auto-updater will not be ready for this release, but SteamLab is now able to create a full game version XML file for all of your Steam shortcuts in preparation for the Auto-Updater to check for and download new patches. More updates, info, and screens coming soon...

Game Overlay
In the early stages of development (thanks to Sean's great DD overlay proof-of-concept code!) is an overlay to display SteamLab messages (and hopefully other things) over the top of anything, including full-screen games and non-standard resolutions.

Estimated release: 12/23/2007

_________________
Ben

My Trac projects
My Wiki
[Broken] - My music


Last edited by bmcclure on December 23rd, 2007, 1:45 am, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 22nd, 2007, 10:28 pm 
Offline

Joined: October 28th, 2006, 2:14 am
Posts: 297
Location: US
You did an awesome job on this so far, I love the windows too. Have you considered making functions for those windows so that its easy for others to make unique windows like that?

_________________
Changed siggy at request of ahklerner :D


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 22nd, 2007, 10:47 pm 
Offline

Joined: November 24th, 2007, 9:07 pm
Posts: 774
Thanks for the comments!

Actually I have created generic functions for all my windows. I call it collectively SteamWin.

I will work on cleaning up the code, removing all external dependencies that I can, and documenting it better, but this is the current state of the SteamWin code: (Note: the documentation in the comments is somewhat outdated)
Code:
; STEAMWIN
; Written by Ben McClure <ben.mcclure@gmail.com>
; These functions will attempt to make your GUIs match Steam's default UI
; Requires: AddGraphicButton(), AHKArray
; You should probably include this directly and not put it in your stdlib, because I haven't tested that.

/*
   Function: SW_Create
   
   Creates an instance of a SteamWin window that all other SW functions can work on.
   
   Parameters:
   
      pTitle - The window title
      pWidgh - The width (px) of the window
      pHeight - The height (px) of the window
      pGuiNum - The GuiNum to use for the window
      pImgDir - The path (relative or absolute) to your GUI image directory (default: "res\gui")
   
   Returns:
   
      The SteamWin (number of this window for use with other functions), or 0 upon failure
      
   Example:
   
      thisSW := SW_Create("My Window", 640, 480, 15, "res\gui")
   
   Notes:
   
      Create a label for your window closing, if it needs to be special, based on the GuiNum.
      Example: For GuiNum 15, create a label called 15GuiClose
      From within your closing label, GoSub to SWGuiClose if you'd like to fade out the window
      
      Resizing is supported, but you need to manually anchor ALL page elements (see my GUIs for examples of this)
*/
SW_Create(pTitle,pWidth,pHeight,pGuiNum="",pImgDir="") {
   local curNum, GuiCloseLnk
   SteamWin := SteamWin ? SteamWin++ : 1 ; Increase the SteamWin value (last created SteamWin)
   pImgDir := pImgDir ? pImgDir : "res\gui" ; If not specified, use "res\gui" as the image dir
   SteamWin%SteamWin%Title := pTitle ; Set global window title
   SteamWin%SteamWin%H := SteamWin%SteamWin%Height := pHeight ; Set global window height
   SteamWin%SteamWin%W := SteamWin%SteamWin%Width := pWidth ; Set global window width
   SteamWin%SteamWin%GuiNum := pGuiNum ; Set global gui number
   SteamWin%SteamWin%ImgDir := pImgDir ; Set global image dir
   If pGuiNum { ; If a GuiNum was set
      Gui, %pGuiNum%:Default ; Make it the default (future controls won't necessarily know it)
      Gui, %pGUiNum%:+LabelSteamWin%SteamWin% ; Set a window label (considering removing this)
   }
   Gui, Destroy ; Just in case there was another GUI with this number (hope it was saved, heh)
   Gui, Color, 686A65, 5E5E5E ; Actual window background will be 464646
   Gui, -Caption ; Get rid of default title bar
   Gui, Add, Picture, x0 y0 vSW%SteamWin%Bg w%pWidth% h%pHeight% 0x4000000, %pImgDir%\bg\Window.bmp ; Window background
   tbWidth := pWidth - 32 ; Width of the titlebar minus the minimize and close button area
   Gui, Add, Picture, x0 y0 w%tbWidth% h20 vSW%SteamWin%Titlebar gTitlebarClick, %pImgDir%\bg\Titlebar.bmp ; Titlebar
   Gui, Add, Picture, x+0 yp+0 w32 h20 vSW%SteamWin%TitlebarRight, %pImgDir%\bg\Titlebar.bmp ; Titlebar button area
   Gui, Font, S8 CWhite, Tahoma ; Set window/titlebar font
   Gui, Add, Text, x5 y3 +Backgroundtrans vSW%SteamWin%Title, %pTitle% ; Titlebar text
   SW%SteamWin%TitlebarMin_hwnd := "" ; Blank out previous minimize image handle
   SW%SteamWin%TitlebarClose_hwnd := "" ; Blank out previous close image handle
   LoadImage_AGB(SW%SteamWin%TitlebarMinb1, pImgDir . "\btn\TitlebarMin.bmp", 15, 15) ; Preload minimize image
   LoadImage_AGB(SW%SteamWin%TitlebarMinb1_ro, pImgDir . "\btn\TitlebarMin_RO.bmp", 15, 15) ; Preload minimize rollover
   LoadImage_AGB(SW%SteamWin%TitlebarCloseb1, pImgDir . "\btn\TitlebarClose.bmp", 15, 15) ; Preload close image
   LoadImage_AGB(SW%SteamWin%TitlebarCloseb1_ro, pImgDir . "\btn\TitlebarClose_RO.bmp", 15, 15) ; Preload close rollover
   SW%SteamWin%TitlebarMin_bH := SW%SteamWin%TitlebarMin_bW := 15 ; Titlebar minimize button dimensions
   SW%SteamWin%TitlebarMin_bO := "x" . pWidth - 32 . " y3" ; Titlebar min button positioning
   SW%SteamWin%TitlebarMin_bG := "SWGuiMin" ; Titlebar min button label
   SW%SteamWin%TitlebarClose_bH := SW%SteamWin%TitlebarClose_bW := 15 ; Close button dimensions
   SW%SteamWin%TitlebarClose_bO := "x" . pWidth - 16 . " y3" ; Close button position
   GuiCloseLnk := IsLabel(pGuiNum . "GuiClose") ? pGuiNum : "SW" ; Set close button destination
   SW%SteamWin%TitlebarClose_bG := GuiCloseLnk . "GuiClose" ; Close button label
   AddGraphicButton("SW" . SteamWin . "TitlebarMin", SW%SteamWin%TitlebarMinb1, "x" . pWidth - 36 . " y3 w15 h15 gSWGuiMin", 15, 15) ; Steam's minimize (-) button
   AddGraphicButton("SW" . SteamWin . "TitlebarClose", SW%SteamWin%TitlebarCloseb1, "x" . pWidth - 20 . " y3 w15 h15 g" . GuiCloseLnk . "GuiClose", 15, 15) ; Steam's close (x) button
   ActiveTitleButtons .= "SW" . SteamWin . "TitlebarMin|SW" . SteamWin . "TitlebarClose|" ; Keep a list of all titlebar buttons
   Return %SteamWin%
}

/*
   Function: SW_AddButton
   
   Adds a pre-made graphical button to a SteamWin window
   
   Parameters:
   
      pVar - Variable name to assign to the button
      pLabel - The label to jump to when the button is clicked (defaults to %pVar%)
      pName - The filename (without extension) of the button to load.
      pExt - The extension of the button file (defaults to .bmp)
      pOptions: Button options such as positioning (x and y) and anything else, excluding "w" and "h"!
      pSteamWin: The SteamWin to add the button to. (defaults to last-created SteamWin)
   
   Returns:
   
      1 upon success, or 0 upon failure
   
   See Also:
   
      SW_AddTextButton()
*/
SW_AddButton(pVar, pLabel="", pName = "", pExt="", pOptions = "", pSteamWin = "") {
   local thisGuiNum, thisImgDir, thisHandle, thisBitmap, thisW, thisH
   If Not pSteamWin { ; If SteamWin wasn't specified
      If SteamWin ; If there is a last-created SteamWin
         pSteamWin := SteamWin ; Use the last-created window
      Else Return 0 ; Current SteamWin unknown
   }
   pName := pName ? pName : "OK" ; Default to an OK button
   pExt := pExt ? pExt : ".bmp" ; Default to a .bmp extension
   pLabel := pLabel ? pLabel : pVar ; If no label is specified, use the variable name
   thisGuiNum := SteamWin%pSteamWin%GuiNum ; Get the global GuiNum into an internal var
   thisImgDir := SteamWin%pSteamWin%ImgDir ; Get global imgdir into a global var
   If Not FileExist(thisImgDir . "\btn\" . pName . pExt) ; If button file doesn't exist
      Return 0 ; The button file doesn't exist
   ; Check if a rollover button should be used
   ROImage := 0
   If FileExist(thisImgDir . "\btn\" . pName . "_RO" . pExt) {
      ROImage := thisImgDir . "\btn\" . pName . "_RO" . pExt ; Set path to rollover image
   }
   If thisGuiNum ; If there is a GuiNum
      Gui, %thisGuiNum%:Default ; make it the default
   If Not GDIplus_Start() { ; false means command worked
      If Not GDIplus_LoadBitmap(thisBitmap, thisImgDir . "\btn\" . pName . pExt) { ; Load image file
         GDIplus_GetImageDimension(thisBitmap, thisW, thisH) ; Get image dimensions
         GDIplus_DisposeImage(thisBitmap) ; Delete image from running memory
      } Else Gosub, GDIplusError ; There was a problem
      GDIplus_Stop() ; Shut down GDI+
   } Else Gosub, GDIplusError ; There was a problem
   LoadImage_AGB(%pVar%b1, thisImgDir . "\btn\" . pName . pExt, thisH, thisW) ; Pre-load the button
   If ROImage ; If there is a rollover button
      LoadImage_AGB(%pVar%b1_ro, ROImage, thisH, thisW) ; Pre-load the rollover
   Else ; If no rollover
      LoadImage_AGB(%pVar%b1_ro, thisImgDir . "\btn\" . pName . pExt, thisH, thisW) ; Load the original image as a rollover
   %pVar%_hwnd := "" ; Blank any old image handles from the variable
   %pVar%_bH := thisH ; Store global button height
   %pVar%_bW := thisW ; Store global button width
   %pVar%_bO := pOptions ; Store global button options
   %pVar%_bG := pLabel ; Store global button label (destination)
   ActiveButtons .= pVar . "|" ; Add this button to the running list of buttons for rollover evaluation
   SW_AddGraphicButton(pVar, %pVar%b1, pOptions . " w" . thisW . " h" . thisH . " g" . pLabel, thisH, thisW) ; Create the button
   Return 1 ; Success
   GDIplusError: ; GDI+ error label
      If (#GDIplus_lastError != "") { ; Sanity check
         msgbox, 16, GDI+ Error,
         ( LTrim
         There was an error in the GDI+ Wrapper. If the problem continues`, please contact support.
         The following information may be helpful in diagnosing the problem:
         Function Call: %#GDIplus_lastError%
         ) ; Show the error
      }
   Return
}

/*
   Function: SW_AddTextButton
   
   Generates and adds a text button based on a template file
   
   Parameters:
   
      pVar - The variable to assign to the button
      pLabel - The label to jump to when button is clicked
      pName - The text of the button
      pSize - 1 (small), 2 (medium, default), 3 (wide)
      pBg - Background type (Bg for window background, Tab for tab background, default is Bg)
      pOptions - Other options to apply to the element in the GUI
      pSteamWin - SteamWin to add the button to (defaults to last-created SteamWin)
   
   Returns:
   
      1 upon success, 0 upon failure
   
   See Also:
   
      SW_AddButton()
*/
SW_AddTextButton(pVar, pLabel="", pName = "", pSize="", pBg="", pOptions = "", pSteamWin = "") {
; Adds a Steam-like graphical button to the specified Steam window with a graphical text label on it
   local thisGuiNum, thisImgDir, thisHandle, thisBitmap
   If Not pSteamWin {
      If SteamWin
         pSteamWin := SteamWin
      Else Return 0 ; Current SteamWin unknown
   }
   If Not pName
      pName := "OK" ; Default to an OK button
   
   If Not pBg
      pBg := "Bg"
   ; Calculate button size required, if not specified
   If Not pSize {
      thisSize := GetTextSize(pName, "S8", "Tahoma")
      pSize := (thisSize > 53) ? 3 : 2
   }
   If Not pLabel
      pLabel := pVar ; If no label is specified, use the variable name as a label
   thisGuiNum := SteamWin%pSteamWin%GuiNum
   thisImgDir := SteamWin%pSteamWin%ImgDir
   
   ; Check if button already generated
   FileCreateDir,%thisImgDir%\tmp\btn
   thisFile1 := thisImgDir . "\tmp\btn\" . pName . "_" . pSize . ".bmp"
   If Not FileExist(thisFile1) ; generate the button
      TextToImage(thisImgDir . "\btn\Button_" . pSize . "_" . pBg . ".png",pName,thisFile1,"XP=12 YP=7 Height=8.5 Align=Left|Top Weight=100 TextColour=FFFFFF Quality=3", "Tahoma")
   ; Check if rollover already generated
   thisFile2 := thisImgDir . "\tmp\btn\" . pName . "_" . pSize . "_ro.bmp"
   If Not FileExist(thisFile2) ; generate the button
      TextToImage(thisImgDir . "\btn\Button_" . pSize . "_" . pBg . ".png",pName,thisFile2,"XP=12 YP=7 Height=8.5 Align=Left|Top Weight=100 TextColour=C4B550 Quality=3", "Tahoma")
   If thisGuiNum
      Gui, %thisGuiNum%:Default ; If there's a GUI num, make it the default
   hGdiPlus := DllCall("LoadLibrary", "Str", "gdiplus.dll")
   VarSetCapacity(si, 16, 0), si := Chr(1)
   DllCall("gdiplus\GdiplusStartup", "UintP", pToken, "UInt", &si, "Uint", 0)
   Loop, 2 { ; Load button and its rollover
      VarSetCapacity(wFile%A_Index%, StrLen(thisFile%A_Index%)*2+2)
      DllCall("kernel32\MultiByteToWideChar", "UInt", 0, "UInt", 0, "Str", thisFile%A_Index%, "Int", -1, "UInt", &wFile%A_Index%, "Int", VarSetCapacity(wFile%A_Index%)//2)
      DllCall("gdiplus\GdipCreateBitmapFromFile", "UInt", &wFile%A_Index%, "UIntP", pBitmap%A_Index%)
      If pBitmap%A_Index% {
         DllCall("gdiplus\GdipCreateHBITMAPFromBitmap", "UInt", pBitmap%A_Index%, "UIntP", hBM%A_Index%, "UInt", 0)
         DllCall("GDIplus.dll\GdipGetImageDimension", "UInt", pBitmap%A_Index%, "Float *", imageWidth%A_Index%, "Float *", imageHeight%A_Index%)
         hBM%A_Index%W := Floor(imageWidth%A_Index%)
         hBM%A_Index%H := Floor(imageHeight%A_Index%)
         DllCall("gdiplus\GdipDisposeImage", "Uint", pBitmap%A_Index%)
      }
   }
   DllCall("gdiplus\GdiplusShutdown" , "UInt", pToken)
   DllCall("FreeLibrary", "UInt", hGdiPlus)
   Gui, Add, Picture, v%pVar% %pOptions% hwnd%pVar%_hwnd w%hBM1W% h%hBM1H% 0xE g%pLabel%
   SendMessage, 0x172, 0, hBM1,,% "ahk_id " . %pVar%_hwnd  ; STM_SETIMAGE
   If ErrorLevel ; delete previous image
      DllCall("DeleteObject", "uint", ErrorLevel)
   %pVar%b1 := hBM1
   %pVar%b1_ro := hBM2
   %pVar%_bW := hBM1W
   %pVar%_bH := hBM1H
   %pVar%_bO := pOptions
   %pVar%_bG := pLabel
   ActiveTextButtons .= pVar . "|"
   ;Gui,  Add, Picture, w%thisW% h%thisH% g%pLabel% %pOptions% v%pVar%, %thisFile2%
   Return 1
}

/*
   Function: SW_AddTabControl
   
   Creates a custom tab control on a SteamWin window, including its first tab
   
   Parameters:
   
      pVar - The base variable to use to assign to all of this tab's construction elements
      pLabel - The optional label to jump to when a tab is clicked
      pName - The text of the first tab
      pWidth - The width of the overall control
      pHeight - The height of the overall control
      pPos - The x/y position of the control
      pAfterTabs - Not used
      pSteamWin - SteamWin to add control to (defaults to last-created SteamWin)
   
   Returns:
   
      The tab number of the last-added tab (always 1 currently since other tabs need to be added separately)
   
   See Also:
   
      SW_AddTab()
      SW_UpdateTab()
*/
SW_AddTabControl(pVar, pLabel="", pName="", pWidth="", pHeight="", pPos="", pAfterTabs="", pSteamWin="") {
   ; pVar: variable for the tab control (sub-vars will be created for the individual components)
   ; pLabel: label to run when a tab is clicked (pName is appended to this label for each tab), defaults to none
   ; pName: The name of the first tab to create (separate multiple tabs with a pipe, like Tab1|Tab2)
   ; pWidth/pHeight: The w and h coordinates for the entire tab control
   ; pPos: The x/y positioning options for the top left of the tab control
   ; pSteamWin: implied if not specified
   local thisGuiNum, thisImgDir, thisTab
   If Not pSteamWin {
      If SteamWin
         pSteamWin := SteamWin
      Else Return 0 ; Current SteamWin unknown
   }
   If Not pWidth
      pWidth := SteamWin%pSteamWin%W
   If Not pHeight
      pHeight := SteamWin%pSteamWin%H
   If Not SteamWin%pSteamWin%TabNum
      SteamWin%pSteamWin%TabNum := 0 ; sets the last tab number so that you can leave that param blank
   SteamWin%pSteamWin%TabControl := pVar
   SteamWin%pSteamWin%TabNum++
   thisTab := SteamWin%pSteamWin%TabNum
   If Not pName
      pName := "Tab" . SteamWin%pSteamWin%TabNum ; If not specified, make Tab name generic
   If Not pLabel
      pLabel := "SW_TabClick"
   thisGuiNum := SteamWin%pSteamWin%GuiNum
   thisImgDir := SteamWin%pSteamWin%ImgDir
   If thisGuiNum
      Gui, %thisGuiNum%:Default
   thisX := thisY := thisOptions := ""
   If pPos {
      Loop,  Parse, pPos, %A_Space%
      {   If (SubStr(A_LoopField,1,1) = "x") {
            thisX := A_LoopField
         } Else If (SubStr(A_LoopField,1,1) = "y") {
            thisY := A_LoopField
         } Else {
            thisOptions .= " " . A_LoopField
         }
      }
   }
   ;SteamWin%pSteamWin%TabControl%thisTab%
   Gui, Add, Picture, v%pVar%1Left w11 h22 %thisX% %thisY%,res\gui\tab\Tab_Left.bmp
   Gui, Add, Picture, v%pVar%1Top w78 h2 x+0 yp+0,res\gui\tab\Tab_Top.bmp
   newX := "x" . (SubStr(thisX,2) + 11)
   Gui, Add, Picture, v%pVar%1Bg w78 h20 %newX% y+0,res\gui\tab\Tab.bmp
   Gui, Font, S8 CC4B550
   Gui, Add, Text,v%pVar%1 +Backgroundtrans xp+0 yp+2 g%pLabel% %thisOptions%,%pName%
   Gui, Font, S8 CWhite
   Gui, Add, Picture, v%pVar%1Right w9 h22 x+0 yp-4,res\gui\tab\Tab_Right.bmp
   GuiControlGet, namePos, Pos, %pVar%1
   newWidth := namePosW + 16
   GuiControl, Move, %pVar%1Bg, w%newWidth%
   pBHeight := pHeight - 21
   Gui, Add, Picture, v%pVar%Bg w%pWidth% h%pBHeight% %thisX% y+0 Section,res\gui\bg\Tab.bmp
   %pVar%_LastTab := %pVar%1
   %pVar% := thisTab
   Return thisTab
   SW_TabClick:
      thisTab := A_GuiControl
      tabControl := SubStr(thisTab,1,StrLen(thisTab) - 1)
      If Not %tabControl%_LastTab
         %tabControl%_LastTab := tabControl . "1"
      lastTab := %tabControl%_LastTab
      lastTabControl := SubStr(lastTab,1,StrLen(lastTab) - 1)
      ; Change pprevious tab's images to off, and this tab's to on
      GuiControl, +CFFFFFF,%lastTab%
      GuiControl, ,%lastTab%Left, res\gui\tab\Tab_Left_off.bmp
      GuiControl, ,%lastTab%Top, res\gui\tab\Tab_Top_off.bmp
      GuiControl, ,%lastTab%Bg, res\gui\tab\Tab_off.bmp
      GuiControl, ,%lastTab%Right, res\gui\tab\Tab_Right_off.bmp
      GuiControl, +CC4B550,%thisTab%
      GuiControl, ,%thisTab%Left, res\gui\tab\Tab_Left.bmp
      GuiControl, ,%thisTab%Top, res\gui\tab\Tab_Top.bmp
      GuiControl, ,%thisTab%Bg, res\gui\tab\Tab.bmp
      GuiControl, ,%thisTab%Right, res\gui\tab\Tab_Right.bmp
      lastControls := %lastTab%_Controls
      thisControls := %thisTab%_Controls
      Loop,Parse,lastControls,`,
         GuiControl, Hide, %A_LoopField%
      Loop,Parse,thisControls,`,
         GuiControl, Show, %A_LoopField%
      %tabControl%_LastTab := thisTab
      ; Get the var of the tab which was clicked
      ; Tab clicked can be referenced by: A_GuiControl
      ; Jump to user specified pLabel
      ; Change the contents of the tab control based on the tab clicked
   Return
}

/*
   Function: SW_AddTab
   
   Adds a tab to an existing tab control created with SW_AddTabControl
   
   Parameters:
   
      pVar - The variable name of the existing tab control
      pName - The text of the new tab
      pTabNum - The position of the tab in the control, starting from 1 (default adds to the end)
      pOptions - Any options to apply to the tab's text control
      pSteamWin - The SteamWin that the Tab control is on (defaults to last-created SteamWin)
   
   Returns:
   
      The tab number of the new tab, or 0 upon failure
      
   See Also:
   
      SW_AddTabControl()
      SW_UpdateTab()
*/
SW_AddTab(pVar, pName, pTabNum="", pOptions="", pSteamWin="") {
   local lastTabNum, thisPos, newX, thisGuiNum
   If Not pSteamWin {
      If SteamWin
         pSteamWin := SteamWin
      Else Return 0 ; Current SteamWin unknown
   }
   If Not pOptions
      pOptions := "gSW_TabClick"
   thisGuiNum := SteamWin%pSteamWin%GuiNum
   If thisGuiNum
      Gui, %thisGuiNum%:Default
   If Not pVar . "1"
      Return 0 ; No tabs to add on to
   If Not pTabNum {
      Loop {
         If %pVar%%A_Index%
            pTabNum := A_Index + 1
         Else Break
      }
   }
   If %pVar%%pTabNum% {
      GuiControlGet, thisPos, Pos, %pVar%%pTabNum%
      ; Shift other tabs to the right one, then add the new one in place of the old
   } Else {
         lastTabNum := pTabNum - 1
         GuiControlGet, lastPosEnd, Pos, %pVar%%lastTabNum%Right
         thisPosLeftX := lastPosEndX + lastPosEndW
         thisPosLeftY := lastPosEndY
         Gui, Add, Picture, v%pVar%%pTabNum%Left w11 h22 x%thisPosLeftX% y%thisPosLeftY%,res\gui\tab\Tab_Left_off.bmp
         Gui, Add, Picture, v%pVar%%pTabNum%Top w78 h2 x+0 yp+0,res\gui\tab\Tab_Top_off.bmp
         newX := thisPosLeftX + 11
         Gui, Add, Picture, v%pVar%%pTabNum%Bg w78 h20 x%newX% y+0,res\gui\tab\Tab_off.bmp
         Gui, Font, S8 CFFFFFF
         Gui, Add, Text,v%pVar%%pTabNum% +Backgroundtrans xp+0 yp+2 %pOptions%,%pName%
         Gui, Font, S8 CWhite
         Gui, Add, Picture, v%pVar%%pTabNum%Right w9 h22 x+0 yp-4,res\gui\tab\Tab_Right_off.bmp
         SW_UpdateTab(pVar, pTabNum, pName)
   }
   If (pTabNum > %pVar%)
      %pVar% := pTabNum
   GuiControlGet, %pVar%_hwnd, Hwnd, %pVar%
   SetTimer,SW_MouseOverTab,250
   Return
   SW_MouseOverTab:
      MouseGetPos,,,thisWinID, thisControl
      Loop,%SteamWin%
      {   If (thisWinID = SteamWin%A_Index%WinID) {
            thisTabControl := SteamWin%A_Index%TabControl
            GuiControlGet, thisControl, Hwnd, %thisControl%
            If (SubStr(thisControl,1,StrLen(thisTabControl)) = thisTabControl) {
               If (SubStr(thisControl,StrLen(thisControl)-5) = "Right") {
                  thisControl := SubStr(thisControl,1,StrLen(thisControl)-5)
               } Else If (SubStr(thisControl,StrLen(thisControl)-4) = "Left") {
                  thisControl := SubStr(thisControl,1,StrLen(thisControl)-4)
               } Else If (SubStr(thisControl,StrLen(thisControl)-3) = "Top") {
                  thisControl := SubStr(thisControl,1,StrLen(thisControl)-3)
               } Else If (SubStr(thisControl,StrLen(thisControl)-2) = "Bg") {
                  thisControl := SubStr(thisControl,1,StrLen(thisControl)-2)
               }
               GuiControl, +cC4B550, %thisControl%
            } Else {
               ;Turn non-active tabs back to white
            }
            Break
         }
      }
   Return
}

/*
   Function: SW_UpdateTab
   
   Changes the name of and auto-sizes a tab
   
   Parameters:
   
      pVar - the variable of the tab control to work on
      pTabNum - the number of the tab to edit (this is the return value of the SW_AddTab function)
      pNewName - The new text of the tab (enter same text to simply auto-size the tab)
      pSteamWin - The SteamWin the Tab Control is on (defaults to last-created SteamWin)
   
   Returns:
   
      1 upon success, 0 upon failure
   
   See Also
   
      SW_AddTabControl()
      SW_AddTab()
*/
SW_UpdateTab(pVar, pTabNum, pNewName, pSteamWin="") {
   local thisGui, thisSize, thisFactor
   If Not pSteamWin {
      If SteamWin
         pSteamWin := SteamWin
      Else Return 0 ; Current SteamWin unknown
   }
   GuiControlGet, LastSz, Pos, %pVar%%pTabNum%
   prevSize := LastSzW
   thisSize := GetTextSize(pNewName, "S8", "Tahoma")
   GuiControl, Move, %pVar%%pTabNum%, w%thisSize%
   GuiControl,,%pVar%%pTabNum%,%pNewName%
   GuiControlGet, namePos, Pos, %pVar%%pTabNum%
   GuiControl, Move, %pVar%%pTabNum%Bg, w%namePosW%
   GuiControl, Move, %pVar%%pTabNum%Top, w%namePosW%
   GuiControl, Move, %pVar%%pTabNum%Right,% "x" . namePosX + namePosW
   Difference := thisSize - prevSize
   If (pTabNum < %pVar%)
   Loop,% %pVar% {
      If (A_Index > pTabNum) {
         ; Move %pVar%%A_Index% over to the right
         ; Get x position of previous tab's right side, add 9
         GuiControlGet,curLeftPos, Pos, %pVar%%A_Index%Left
         GuiControlGet,curRightPos, Pos, %pVar%%A_Index%Right
         newLeftX := curLeftPosX + Difference
         newRightX := curRightPosX + Difference
         GuiControl, Move, %pVar%%A_Index%Left, x%newLeftX%
         GuiControl, Move, %pVar%%A_Index%Top, % "x" . newLeftX + 11
         GuiControl, Move, %pVar%%A_Index%Bg, % "x" . newLeftX + 11
         GuiControl, Move, %pVar%%A_Index%, % "x" . newLeftX + 11
         GuiControl, Move, %pVar%%A_Index%Right, x%newRightX%
      }
   }
   Return 1
}

/*
   Function: SW_AddSeparator
   
   Adds a graphical separator line to a SteamWin window
   
   Parameters:
   
      pWidth - The width of the separator, in px
      pPos - The x/y positioning elements for the separator
      pSteamWin - The SteamWin to act upon (defaults to last-created SteamWin)
   
   Returns:
   
      1 upon success, 0 upon failure
*/
SW_AddSeparator(pWidth, pPos="", pSteamWin="") {
   local thisGui
   If Not pSteamWin {
      If SteamWin
         pSteamWin := SteamWin
      Else Return 0 ; Current SteamWin unknown
   }
   Gui, %thisGui%Add, Picture, w%pWidth% %pPos% h2,res\gui\bg\Separator.bmp
   Return 1
}

/*
   Function: SW_AddRadio
   
   Adds a custom radio button to a SteamWin window
   
   Parameters:
   
      pV - the variable to assign to the radio button
      pText - The text label of the radio button
      pPos - The x/y positioning elements of the radio button
      pW - The width of the radio button+label
      pH - The height of the radio button/label
      pSteamWin - The SteamWin to add the button to (defaults to last-created SteamWin)
   
   Returns:
   
      1 upon success, 0 upon failure
   
   See Also:
   
      SW_AddCheckbox()
*/
SW_AddRadio(pV="", pText="", pPos="", pW="", pH="", pSteamWin="") {
   local thisGui
   If Not pSteamWin {
      If SteamWin
         pSteamWin := SteamWin
      Else Return 0 ; Current SteamWin unknown
   }
   If SteamWin%SteamWin%GuiNum
      thisGui := SteamWin%SteamWin%GuiNum . ":"
   If Not pPos
      pPos := "xp+0 y+0"
   If pV
      pV = v%pV%
   If pW
      pW = w%pW%
   If pH
      pH = h%pH%
   Gui, %thisGui%Add, Radio, %pW% %pH% %pV% %pPos% 0x8000, %pText%
   Return 1
}

/*
   Function: SW_AddCheckbox
   
   Adds a custom checkbox to a SteamWin window
   
   Parameters:
   
      pV - the variable to assign to the checkbox
      pText - The text label of the checkbox
      pChecked - Initial state of button - 0 (unchecked, default) or 1 (checked)
      pPos - The x/y positioning elements of the checkbox
      pW - The width of the checkbox+label
      pH - The height of the chekbox/label
      pSteamWin - The SteamWin to add the checkbox to (defaults to last-created SteamWin)
   
   Returns:
   
      1 upon success, 0 upon failure
   
   See Also:
   
      SW_AddRadio()
*/
SW_AddCheckbox(pV="", pText="", pChecked=0, pPos="", pW="", pH="", pSteamWin="") {
   local thisGui
   If Not pSteamWin {
      If SteamWin
         pSteamWin := SteamWin
      Else Return 0 ; Current SteamWin unknown
   }
   If SteamWin%SteamWin%GuiNum
      thisGui := SteamWin%SteamWin%GuiNum . ":"
   If Not pPos
      pPos := "xp+0 y+0"
   If pV
      pV = v%pV%
   If pW
      pW = w%pW%
   If pH
      pH = h%pH%
   Gui, %thisGui%Add, Checkbox, %pW% %pH% %pV% %pPos% Checked%pChecked% 0x8000, %pText%
   Return 1
}

/*
   Function: SW_Show
   
   Show a SteamWin window created with SW_Create
   
   Parameters:
   
      pSteamWin - The SteamWin to show (defaults to last-created SteamWin)
   
   Returns:
   
      1 upon success, 0 upon failure
   
   See Also:
   
      SW_Create()
*/
SW_Show(pSteamWin="") {
   local thisH, thisW, thisTitle, thisGui
   If Not pSteamWin {
      If SteamWin
         pSteamWin := SteamWin
      Else Return 0 ; Current SteamWin unknown
   }
   thisTitle := SteamWin%pSteamWin%Title
   thisH := SteamWin%pSteamWin%H
   thisW := SteamWin%pSteamWin%W
   If SteamWin%pSteamWin%GuiNum
      thisGui := SteamWin%pSteamWin%GuiNum . ":"
   Gui, %thisGui%Show, h%thisH% w%thisW% Hide, %thisTitle%
   Gui, %thisGui%+LastFound
   WinMove, ,,,,%thisW%, %thisH%
   DetectHiddenWindows, On
   SteamWin%pSteamWin%WinID := WinGet("ID",thisTitle)
   DllCall("AnimateWindow","UInt",SteamWin%pSteamWin%WinID,"Int",500,"UInt","0xa0000")
   WinSet, Region, 0-0 %thisW%-%thisH% w%thisW% h%thisH% R3-3,% "ahk_id " . SteamWin%pSteamWin%WinID
   SetTimer, SWIsActive, 100
   OnMessage(0x200, "BtnMouseMove")
   OnMessage(0x2A3, "BtnMouseLeave")
   OnMessage(0x202, "BtnMouseLeave")
   OnMessage(0x201, "WM_LBUTTONDOWN")
   OnMessage(0x84, "WM_NCHITTEST")
   OnMessage(0x83, "WM_NCCALCSIZE")
   OnMessage(0x86, "WM_NCACTIVATE")
   Return 1
   
   TitlebarClick:
      PostMessage, 0xA1, 2,,, A
   Return
}

/*
   Function: SW_AnimateWin
   
   Fades a SteamWin window in or out
   
   Parameters:
   
      pHwnd - The window handle (Hwnd) to fade in/out
      pSw - 4 or 5 fades the window in, anything else fades it out
   
   Returns:
   
      nothing
*/
SW_AnimateWin(pHwnd, pSw) {
   If (pSw = 5 or pSw = 4) ;show
      DllCall("AnimateWindow","UInt",pHwnd,"Int",500,"UInt","0xa0000") ; Fade in
   Else DllCall("AnimateWindow","UInt",pHwnd,"Int",500,"UInt","0x90000") ; Fade out
   Return
}

/*
   Function: BtnMouseLeave
   
   Returns a SteamWin button to a non-rollover state if the mouse is not over it
   
   Parameters:
   
      wParam/msg - the message sent
      lParam/hwnd - the hwnd of the current control
   
   Returns:
   
      nothing
   
   See Also:
   
      BtnMouseMove()
*/
BtnMouseLeave(wParam, lParam, msg, hwnd) {
   Global
   theseButtons := ActiveButtons . "|" . ActiveDockButtons
   Loop, Parse, theseButtons,|
      If (hwnd = %A_LoopField%_hwnd) {
         AddGraphicButton(A_LoopField, %A_LoopField%b1, %A_LoopField%_bO . " w" . %A_LoopField%_bW . " h" . %A_LoopField%_bH . " g" . %A_LoopField%_bG,%A_LoopField%_bH,%A_LoopField%_bW)
      }
   Loop, Parse, ActiveTextButtons,|
      If (hwnd = %A_LoopField%_hwnd) {
         SendMessage, 0x172, 0,% %A_LoopField%b1,, ahk_id %hwnd%  ; STM_SETIMAGE
      }
}

/*
   Function: BtnMouseMove
   
   Conditionally shows a rollover button or returns it to its original state
   
   Parameters:
   
      wParam/msg - the message sent
      lParam/hwnd - the hwnd of the current control
   
   Returns:
   
      nothing
   
   See Also:
   
      BtnMouseLeave()
*/
BtnMouseMove(wParam, lParam, msg, hwnd) {
   Global
   Static _LastButtonData = true
   theseButtons := ActiveButtons . "|" . ActiveDockButtons
   btnType := 0
   Loop, Parse, theseButtons,|
   {   If (hwnd = %A_LoopField%_hwnd and _LastButtonData != %A_LoopField%_hwnd) {
         AddGraphicButton(A_LoopField, %A_LoopField%b1_ro, %A_LoopField%_bO . " w" . %A_LoopField%_bW . " h" . %A_LoopField%_bH . " g" . %A_LoopField%_bG,%A_LoopField%_bH,%A_LoopField%_bW)
      }
   }
   Loop, Parse, ActiveTextButtons,|
   {   If (hwnd = %A_LoopField%_hwnd) {
         If (_LastTextButtonData != %A_LoopField%_hwnd) {
            SendMessage, 0x172, 0,% %A_LoopField%b1_ro,, ahk_id %hwnd%  ; STM_SETIMAGE
            ThisTextButtonVar := A_LoopField
            btnType := 1
         }
      }
   }
   If (hwnd != _LastTextButtonData and _LastTextButtonData != "") {
      SendMessage, 0x172, 0,% %_LastTextButtonVar%b1,, ahk_id %_LastTextButtonData%  ; STM_SETIMAGE
      _LastTextButtonData := ""
      _LastTextButtonVar := ""
   }
   If btnType {
      _LastTextButtonData := hwnd
      _LastTextButtonVar := ThisTextButtonVar
   } Else {
      _LastButtonData := hwnd
   }
   Return
}

WM_LBUTTONDOWN() { ; Credit: lexikos
   ; Allow moving the GUI by dragging any point in its client area.
   if A_Gui
      PostMessage, 0xA1, 2 ; WM_NCLBUTTONDOWN
}
WM_NCCALCSIZE() { ; Credit: lexikos
   ; Sizes the client area to fill the entire window.
   if A_Gui
      return 0 ; returning 0 for WM_NCCALCSIZE effectively gives borders zero size.
}
WM_NCACTIVATE() { ; Credit: lexikos
   ; Prevents a border from being drawn when the window is activated.
   if A_Gui
      return 1
}
WM_NCHITTEST(wParam, lParam) { ; Credit: lexikos
   ; Redefine where the sizing borders are.  This is necessary since
   static border_size = 6
   if !A_Gui
      return
   WinGetPos, gX, gY, gW, gH
   x := lParam<<48>>48, y := lParam<<32>>48
   hit_left    := x <  gX+border_size
   hit_right   := x >= gX+gW-border_size
   hit_top     := y <  gY+border_size
   hit_bottom  := y >= gY+gH-border_size
   if hit_top {
      if hit_left
         return 0xD
      else if hit_right
         return 0xE
      else
         return 0xC
   } else if hit_bottom {
      if hit_left
         return 0x10
      else if hit_right
         return 0x11
      else return 0xF
   }
   else if hit_left
      return 0xA
   else if hit_right
      return 0xB
    ; else let default hit-testing be done
}


; *******************************************************************
; SW_AddGraphicButton - modified from AddGraphicButton()
; *******************************************************************
; Version: 2.2 Updated: May 20, 2007
; by corrupt
; Code contributions by: lingoist
; *******************************************************************
; VariableName = variable name for the button
; ImgPath = Path to the image to be displayed
; Options = AutoHotkey button options (g label, button size, etc...)
; bHeight = Image height (default = 32)
; bWidth = Image width (default = 32)
; *******************************************************************
; note:
; - calling the function again with the same variable name will
; modify the image on the button
; *******************************************************************
SW_AddGraphicButton(VariableName, ImgPath, Options="", bHeight=32, bWidth=32) {
   Global
   Local ImgType, ImgType1, ImgPath0, ImgPath1, ImgPath2, hwndmode
   ; BS_BITMAP := 128, IMAGE_BITMAP := 0, BS_ICON := 64, IMAGE_ICON := 1
   Static LR_LOADFROMFILE := 16
   Static BM_SETIMAGE := 247
   Static NULL
   SplitPath, ImgPath,,, ImgType1
   If ImgPath is float
   {
      ImgType1 := (SubStr(ImgPath, 1, 1)  = "0") ? "bmp" : "ico"
      StringSplit, ImgPath, ImgPath,`.
      %VariableName%_img := ImgPath2
      hwndmode := true
   }
   ImgTYpe := (ImgType1 = "bmp") ? 128 : 64
   If (%VariableName%_img != "") AND !(hwndmode)
      DllCall("DeleteObject", "UInt", %VariableName%_img)
   If (%VariableName%_hwnd = "")
      Gui, Add, Button,  v%VariableName% hwnd%VariableName%_hwnd +%ImgTYpe% %Options%
   ImgType := (ImgType1 = "bmp") ? 0 : 1
   If !(hwndmode)
      %VariableName%_img := DllCall("LoadImage", "UInt", NULL, "Str", ImgPath, "UInt", ImgType, "Int", bWidth, "Int", bHeight, "UInt", LR_LOADFROMFILE, "UInt")
   DllCall("SendMessage", "UInt", %VariableName%_hwnd, "UInt", BM_SETIMAGE, "UInt", ImgType,  "UInt", %VariableName%_img)
   Return, %VariableName%_img ; Return the handle to the image
}

SWIsActive:
   OneExists := 0
   Loop %SteamWin%
   {   curGuiNum := SteamWin%A_Index%GuiNum ? SteamWin%A_Index%GuiNum . ":" : ""
      Gui, %curGuiNum%Default
      DetectHiddenWindows, Off
      IfWinExist,% "ahk_id" . SteamWin%A_Index%WinID
      {   OneExists := 1
         IfWinActive,% "ahk_id" . SteamWin%A_Index%WinID
         {   NewFontColor%A_Index% = White
            ro := "" ; show the standard image
         } Else {
            NewFontColor%A_Index% = C0C0C0
            ro :="_ro" ; show the rollover image
         }
         If (NewFontColor%A_Index% != LastFontColor%A_Index%) {
            NewFontColor := NewFontColor%A_Index%
            Gui, Font, c%NewFontColor%
            thisTitleBar := "SW" . A_Index . "Titlebar"
            thisTitle := "SW" . A_Index . "Title"
            thisT := SteamWin%A_Index%Title
            GuiControl, Font, %thisTitle%
            GuiControl, ,%thisTitle%, %thisT%
            Gui, Font, cWhite
            LastFontColor%A_Index% = %NewFontColor%
            ; Update the titlebar buttons
            AddGraphicButton("SW" . A_Index . "TitlebarMin", SW%A_Index%TitlebarMinb1%ro%, "x" . pWidth - 32 . " y3 w15 h15 gSWGuiMin", 15, 15) ; Steam's minimize (-) button
            AddGraphicButton("SW" . A_Index . "TitlebarClose", SW%A_Index%TitlebarCloseb1%ro%, "x" . pWidth - 16 . " y3 w15 h15 g" . SW%A_Index%TitlebarClose_bG, 15, 15) ; Steam's close (x) button
         }
      }
   }
   ;If Dock_Enabled = 1
   ;   OneExists := 1
   If Not OneExists {
      SetTimer, SWIsActive, Off
      If !Dock_Enabled {
         OnMessage(0x200, "")
         OnMessage(0x2A3, "")
         OnMessage(0x202, "")
      }
      OnMessage(0x201, "")
      OnMessage(0x84, "")
      OnMessage(0x83, "") ; WM_NCCALCSIZE
      OnMessage(0x86, "") ; WM_NCACTIVATE
   }
Return

SWGuiMin: ; Automatically used for the minimize button in all SteamWin titlebars
   WinMinimize
Return
   
SWGuiClose: ; Used if you don't have a GuiClose label for your GuiNum.
   ; You can also GoSub this manually to fade out the window
   WinGet, thisID,ID,A ; Get active window ID
   DllCall("AnimateWindow","UInt",thisID,"Int",500,"UInt","0x90000") ; Fade the window out
   WinClose, ahk_id %thisID% ; Close the window altogether
Return


These are some generic GUI functions I created for common windows:
A password window:
Code:
SW_Password(pVar, pLabel="", pTitle="",pText="",pGuiNum="") {
   If pGuiNum {
      GuiNum = %pGuiNum%:
      Gui, %GuiNum%Default
   }
   PasswordLabel = %pLabel%
   If Not pTitle
      pTitle = Enter Password
   If Not pText
      pText = Please enter the password to continue.
   SW_Create(pTitle,300,125,pGuiNum) ; Create the window
   Gui, Add, Text, x8 y27 w280 h25 +backgroundtrans, %pText%
   Gui, Add, Edit, xp y+10 w280 v%pVar% Password
   GuiControl, Focus, %pVar%
   SW_AddTextButton("PasswordSubmit","","Submit",2,"","x+-80 y+5 Default")
   SW_Show()
   WinWaitClose,%pTitle%
   Return %pVar%
   
   PasswordSubmit:
      Gui, %GuiNum%Submit, NoHide
      Gosub, SWGuiClose
      Gui, %GuiNum%Destroy
      If PasswordLabel
         GoSub, %PasswordLabel%
   Return
}


A MsgBox (with button number combinations and all):
Code:
SW_MsgBox(pVar, pText, pTitle="",pButtons=0,pGuiNum="") {
   global thisMsgBoxSW
   If pGuiNum {
      GuiNum = %pGuiNum%:
      Gui, %GuiNum%Default
   }
   If Not pTitle
      pTitle = %ProgramName%
   thisMsgBoxSW := SW_Create(pTitle,300,125,pGuiNum) ; Create the window
   Gui, Add, Text, x8 y27 w280 h60 +backgroundtrans, %pText%
   If (pButtons = 1) {
      SW_AddTextButton("MsgBoxOK","","OK",2,"","x+-156 y+5 Default")
      SW_AddTextButton("MsgBoxCancel","","Cancel",2,"","x+2 yp")
   } Else If (pButtons = 2) {
      SW_AddTextButton("MsgBoxAbort","","Abort",2,"","x+-234 y+5 Default")
      SW_AddTextButton("MsgBoxRetry","","Retry",2,"","x+2 yp+0")
      SW_AddTextButton("MsgBoxCancel","","Cancel",2,"","x+2 yp+0")
   } Else If (pButtons = 3) {
      SW_AddTextButton("MsgBoxYes","","Yes",2,"","x+-234 y+5 Default")
      SW_AddTextButton("MsgBoxNo","","No",2,"","x+2 yp+0")
      SW_AddTextButton("MsgBoxCancel","","Cancel",2,"","x+2 yp+0")
   } Else If (pButtons = 4) {
      SW_AddTextButton("MsgBoxYes","","Yes",2,"","x+-156 y+5 Default")
      SW_AddTextButton("MsgBoxNo","","No",2,"","x+2 yp+0")
   } Else If (pButtons = 5) {
      SW_AddTextButton("MsgBoxRetry","","Retry",2,"","x+-156 y+5 Default")
      SW_AddTextButton("MsgBoxCancel","","Cancel",2,"","x+2 yp+0")
   } Else If (pButtons = 6) {
      SW_AddTextButton("MsgBoxCancel","","Cancel",2,"","x+-234 y+5 Default")
      SW_AddTextButton("MsgBoxTryAgain","","TryAgain",2,"","x+2 yp+0")
      SW_AddTextButton("MsgBoxContinue","","Continue",2,"","x+2 yp+0")
   } Else { ; assume 0
      SW_AddTextButton("MsgBoxOK","","OK",2,"","x+-78 y+5 Default")
   }
   MsgBoxSelected := ""
   SW_Show()
   Gui, -Resize
   SetTimer, HasChosen,10
   WinWaitClose,%pTitle%
   %pVar% := MsgBoxSelected
   Return MsgBoxSelected
   
   MsgBoxOK:
      MsgBoxSelected := "OK"
   Return
   MsgBoxCancel:
      MsgBoxSelected := "Cancel"
   Return
   MsgBoxRetry:
      MsgBoxSelected := "Retry"
   Return
   MsgBoxAbort:
      MsgBoxSelected := "Abort"
   Return
   MsgBoxYes:
      MsgBoxSelected := "Yes"
   Return
   MsgBoxNo:
      MsgBoxSelected := "No"
   Return
   MsgBoxTryAgain:
      MsgBoxSelected := "Try Again"
   Return
   MsgBoxIgnore:
      MsgBoxSelected := "Ignore"
   Return
   MsgBoxContinue:
      MsgBoxSelected := "Continue"
   Return
   HasChosen:
      If MsgBoxSelected {
         SetTimer, HasChosen,Off
         thisGuiNum := SteamWin%thisMsgBoxSW%GuiNum
         If thisGuiNum
            thisGuiNum = %thisGuiNum%:
         Gui, %thisGuiNum%Submit, NoHide
         Gosub, SWGuiClose
         Gui, %thisGuiNum%Destroy
      }
   Return
}


As an example, this is my Backup Manager window which includes multiple working tabs:
Code:
; GUI 15, 16
ShowBackupManager:
   Gui, 14:Default
   bkSteamWin := SW_Create("Backup Manager - " . ProgramName,450,292,14) ; Create the basic window

   ;Tab 1
   BackupNames := ""
   Gui, Add, ListBox, vBackupListBox x8 y27 w157 h229 Sort Choose1 gSelectBackup, %BackupNames%
   Gosub, UpdateBackupList
   SW_AddButton("AddBackup","","+","","x8 y+0")
   SW_AddButton("DelBackup","","-","","x+0 yp+0")

   ;Tab 2
   GameBackupNames := ""
   Gui, Add, ListBox, hidden vGameBackupListBox x8 y27 w157 h229 Sort Choose1 gSelectGameBackup,%GameBackupNames%
   Gosub, UpdateGameBackupList
   SW_AddButton("AddGameBackup","","+","","x8 y+0 hidden")
   SW_AddButton("DelGameBackup","","-","","x+0 yp+0 hidden")
   SW_AddTextButton("SelectGameBackupDir","","SelectDir",2,"","x+27 yp+0 hidden")

   ;Tab 3
   
   
   NewX := SteamWin%SteamWin%W - 30
   SW_AddTabControl("BackupTab","","Files","271","222","x171 y27")
   ;SW_AddLink("EditGameTitle"
   SW_UpdateTab("BackupTab", 1, "Files")
   
   ; Tab 1
   Gui, Add, Text, xs+15 ys+10 w500 +Backgroundtrans vOrigFileInfo,Dir:
   Gui, Add, Text, xp+0 y+5 +Backgroundtrans vBackupVersionsText,Backup Versions
   BackupVersions := ""
   Gui, Add, ListView, vBackupVersionList xp+0 yp+20 w170 h146 gSelectBackupVersion background494E49 -Multi, #|Date|KB|File|Restore Dir|Backup Dir
   SW_AddTextButton("BackupRestoreBt","","Restore",2,"Tab","x+3 yp+0")
   SW_AddTextButton("BackupDeleteBt","","Delete",2,"Tab","xp+0 y+0")
   BackupTab1_Controls := "BackupListBox,AddBackup,DelBackup,OrigFileInfo,BackupVersionsText,BackupVersionList,BackupRestoreBt,BackupDeleteBt"
   
   ; Tab 2
   Gui, Add, Text, xs+15 ys+10 w170 +Backgroundtrans vGameZipFileInfo hidden,Zip File:
   SW_AddTextButton("GameBackupRestoreBt","","Restore",2,"Tab","x+3 yp-5 hidden")
   Gui, Add, Text, xs+15 y+-3 +backgroundtrans vGameDirectoryInfo hidden,Game Dir:
   Gui, Add, Text, xp+0 y+5 +backgroundtrans vNumBackupsText hidden, Number of backups to keep:
   Gui, Add, Edit, x+5 yp-2 cC0C0C0 Number w30 hidden vNumBackupsEdit
   Gui, Add, Text, xs+15 y+0 +backgroundtrans vFilesInBackupText hidden,Files In Backup
   Gui,  Add, ListView, vGameBackupFilesList xp+0 y+5 w170 h108 Grid -Multi hidden, File|KB
   BackupTab2_Controls := "GameBackupListBox,AddGameBackup,DelGameBackup,SelectGameBackupDir,GameZipFileInfo,GameBackupRestoreBt,GameDirectoryInfo,NumBackupsText,NumBackupsEdit,FilesInBackupText,GameBackupFilesList"
   ; Tab 3
   
   
   
   SW_AddTextButton("WinBMClose","14GuiClose","Close",2,"","x367 y258")
   
   SW_AddTab("BackupTab","Games", 2)
   SW_AddTab("BackupTab","Schedule", 3)
   SW_Show()
   Gui, +Resize
Return

14GuiSize:
   WinGetPos,,,thisW,thisH,% "ahk_id " . SteamWin%bkSteamWin%WinID
   WinSet, Region, 0-0 %thisW%-%thisH% w%thisW% h%thisH% R3-3,% "ahk_id " . SteamWin%bkSteamWin%WinID
   Anchor("BackupTabBg","wh")
   Anchor("SW" . bkSteamWin . "Bg","wh")
   Anchor("SW" . bkSteamWin . "Titlebar","w")
   Anchor("SW" . bkSteamWin . "TitlebarRight","x")
   Anchor("SW" . bkSteamWin . "TitlebarMin","x",1)
   Anchor("SW" . bkSteamWin . "TitlebarClose","x",1)
   Anchor("BackupRestoreBt","x")
   Anchor("BackupDeleteBt","x")
   Anchor("BackupListBox","h")
   Anchor("GameBackupListBox","h")
   Anchor("AddBackup","y")
   Anchor("DelBackup","y")
   Anchor("AddGameBackup","y")
   Anchor("DelGameBackup","y")
   Anchor("GameBackupRestoreBt", "x")
   Anchor("NumBackupsEdit","w")
   Anchor("SelectGameBackupDir", "y")
   Anchor("BackupVersionList", "wh")
   Anchor("GameBackupFilesList", "wh")
   Anchor("WinBMClose","xy")
Return

SelectBackup:
   Gui,  14:Default
   Gui, ListView, BackupVersionList
   GuiControlGet, curTitle,,BackupListBox
   curFile := SubStr(curTitle,InStr(curTitle," - ")+3)
   curDir := SubStr(curTitle,1,InStr(curTitle," - ")-1)
   FileRead, thisRestoreDir, backup\%curDir%\.bakinfo
   FileGetSize, OrigFileSize, %thisRestoreDir%\%curFile%,K
   If Not OrigFileSize
      OrigFileSize = 0
   curTabTitle := curFile . " (" . OrigFileSize . "k)"
   SW_UpdateTab("BackupTab", 1, curTabTitle)
   GuiControl, ,OrigFileInfo, Dir: %thisRestoreDir%
   GuiControl, +gOpenOrigDir ,OrigFileInfo
   
   LV_Delete()
   Loop, backup\%curDir%\%curFile%*
   {   DateModified := A_LoopFileTimeModified
      FormatTime,DayModified,%DateModified%,ShortDate
      FormatTime,TodaysDate,,ShortDate
      If DayModified = TodaysDate
         FormatTime, DateModified, %DateModified%, Time
      Else
         FormatTime, DateModified,%DateModified%,M/d/yy h:mm tt
      
      lastNum := LV_Add("",A_Index,DateModified,A_LoopFileSizeKB,A_LoopFileName,thisRestoreDir,A_LoopFileDir)
   }
   ;LV_ModifyCol(2,"Auto")
   LV_ModifyCol()
   GuiControl, +Redraw, BackupVersionList
   GuiControl,,BackupVersionList,|%BackupVersions%
Return

OpenOrigDir:
   Run, Explore %thisRestoreDir%
Return

UpdateBackupList:
   BackupNames :=""
   Loop, backup\*,2
   {   BackupDir = %A_LoopFileName%
      If (BackupDir != "Games") {
         Loop, backup\%BackupDir%\*.bak
         {
            BackupName := SubStr(A_LoopFileName,1,StrLen(A_LoopFileName)-4)
            BackupNames := BackupNames . BackupDir . " - " . BackupName . "|"
         }
      }
   }
   GuiControl, , BackupListBox,|%BackupNames%
Return

UpdateGameBackupList:
   GameBackupNames := ""
   Loop, backup\Games\*.zip
   {   FileDelete, tmp\BakInfo.ini
      RunWait,res\7za.exe e "%A_LoopFileFullPath%" -otmp\ BakInfo.ini -aoa,,Hide
      IniRead, thisBackupName, tmp\BakInfo.ini, BackupInfo, Name, %A_SPACE%
      If thisBackupName
         GameBackupNames .= thisBackupName . "|"
   }
   GuiControl, , GameBackupListBox,|%GameBackupNames%
Return

SelectBackupVersion:
   
Return

UpdateBackupVersionList:

Return

AddBackup:
   OSD("Manual Backups Not Yet Implemented")
Return
DelBackup:
   Gui, 14:Default
   GuiControlGet, curTitle,,BackupListBox
   curFile := SubStr(curTitle,InStr(curTitle," - ")+3)
   curDir := SubStr(curTitle,1,InStr(curTitle," - ")-1)
   DeleteMsgBox := SW_MsgBox("MsgBoxConfirm", "Are you sure you would like to delete all backups of " . curFile . "?" , "Delete Backups",4,22)
   If (DeleteMsgBox = "Yes") {
      FileDelete, backup\%curDir%\%curFile%.bak*
      OSD("Selected Backups Deleted Successfully")
      Gosub, UpdateBackupList
   }
Return

AddGameBackup:
   AddGameKeyWin := SW_Create("Add Game Backup",300,125,79) ; Create the Edit Title window
   Gui, 79:Default
   Gui, Add, Text, x8 y27 w280 h25 +backgroundtrans, Enter the title of the game to back up:
   Gui, Add, Edit, xp y+10 w280 vNewGameBackupTitle ; Edit box for title
   GuiControl, Focus, NewGameBackupTitle ; Focus on the edit box
   SW_AddTextButton("AddGameBackupSubmit","","Submit",2,"","x+-80 y+5 Default") ; Submit the window
   SW_Show() ; Show the Edit Title window
Return

AddGameBackupSubmit: ; Submit the content in the Edit Title window
   Gui, 79:Submit, NoHide
   GoSub,SWGuiClose
   Gui, 79:Destroy ; Free up this GuiNum
   fileName := RegExReplace(NewGameBackupTitle, "[/\\:*?""<>|]", "")
   If FileExist("backup\Games\" . fileName . ".zip") {
      SW_MsgBox("MsgBoxGameExists", "Error: Backup exists for this game. Please use the current backup, or delete it before creating a new one.", "Game Exists",0,23)
   } Else {
      FileCreateDir, backup\Games
      FileDelete, tmp\BakInfo.ini
      IniWrite, %NewGameBackupTitle%, tmp\BakInfo.ini, BackupInfo, Name
      RunWait, res\7za.exe a -tzip "%A_ScriptDir%\backup\Games\%fileName%.zip" BakInfo.ini ,tmp\,Hide
      GuiControl,14:,GameBackupListBox,%NewGameBackupTitle% ; Display the new titles in the main window
      Gosub, SelectGameBackup
   }
Return

DelGameBackup:

Return

SelectGameBackup:

Return

SelectGameBackupDir:

Return

23GuiClose:
   Gui, 23:Submit, NoHide
   Gosub, SWGuiClose
   Gui, 23:Destroy
Return

GameBackupRestoreBt:

Return

BackupRestoreBt:
   rowSelected := LV_GetNext()
   LV_GetText(thisFilename,rowSelected,4)
   LV_GetText(thisRestoredir,rowSelected,5)
   LV_GetText(thisBackupdir,rowSelected,6)
   thisRestoreFilename := curFile
   If FileExist(thisRestoreDir . "\" . thisRestoreFilename) {
      BackupMsgBox := SW_MsgBox("MsgBoxConfirm", "Would you like to make a backup of " . thisRestoreFilename . " before it is overwritten?" , "Restore Confirmation",3,22)
      If (BackupMsgBox = "Yes") {
         BackupFile(thisRestoredir . "\" . thisRestoreFilename,SubStr(thisBackupDir,8),1)
      }
      If (BackupMsgBox = "Yes" or BackupMsgBox = "No") {
         RestoreFile(thisRestoredir . "\" . thisRestoreFilename,thisFilename,thisBackupdir,1)
         OSD("File Successfully Restored")
         Gosub, SelectBackup
      }
   } Else {
      RestoreFile(thisRestoredir . "\" . thisRestoreFilename,thisFilename,thisBackupdir,1)
      OSD("File Successfully Restored")
      Gosub, SelectBackup
   }
Return

22GuiClose:
   Gui, 22:Submit, NoHide
   Gosub, SWGuiClose
   Gui, 22:Destroy
Return

BackupDeleteBt:
   rowSelected := LV_GetNext()
   LV_GetText(thisFilename,rowSelected,4)
   LV_GetText(thisBackupdir,rowSelected,6)
   thisSW := SW_MsgBox("MsgBoxConfirm", "Would you like to delete the backup file " . thisFilename . "?", "Delete Backup File",4,21)
   If (thisSW = "Yes") {
      FileDelete, %thisBackupdir%\%thisFilename%
      OSD("Backup File Deleted")
      Gosub, SelectBackup
   }
Return

21GuiClose:
   Gui, 21:Submit, NoHide
   Gosub, SWGuiClose
   Gui, 21:Destroy
Return

14GuiClose:
14GuiDestroy:
   Gui, 14:Submit, NoHide
   Gosub, SWGuiClose
   Gui, 14:Destroy
Return


Again, my apologies that there are probably several dependencies from my lib directory (download available in first post). I will try to remove the dependencies in the actual functions so that I can distribute them freely.

The code also assumes some button locations. I will post details about this later on. I'll also post my button templates.

_________________
Ben

My Trac projects
My Wiki
[Broken] - My music


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 23rd, 2007, 12:08 am 
Offline

Joined: November 24th, 2007, 9:07 pm
Posts: 774
I just added some documentation to the SteamWin code in the above post (it's long so I don't want to post it again in this reply). If you downloaded it, you may want to re-download.

I have cleaned up a few of the functions a little bit. I have a lot more work to do to make it truly plug-n-play though. I'll keep updating it whenever possible.

_________________
Ben

My Trac projects
My Wiki
[Broken] - My music


Report this post
Top
 Profile  
Reply with quote  
PostPosted: December 23rd, 2007, 12:29 am 
Offline

Joined: November 24th, 2007, 9:07 pm
Posts: 774
I am working on expanding the default options for creating hotkeys in SteamLab and I would really love some suggestions for common functions one might want a hotkey for.

This can be related to SteamLab, Steam itself, or anything else that might be beneficial to gamers.

Current hotkeys:
Quote:
UpdateGames - Starts a game auto-update
RunSteam - Runs Steam if it's closed
LockSteam - Locks or unlocks Steam
ToggleDock - Turns the Steam Dock on or off
CDKeyManager - Opens the CD Key Manager GUI
BackupManager - Opens the Backup Manager GUI
Settings - Opens the Settings GUI
HotkeyManager - Opens the Hotkey Manager GUI
IncreaseVol - Increases system volume by 5%
DecreaseVol - Decreases system volume by 5%
ToggleMuteVol - Mutes/unmutes system volume
TakeScreenshot - Takes a screenshot and organizes it by active window
Run - Runs a program with parameters
Exit - Exits SteamLab

_________________
Ben

My Trac projects
My Wiki
[Broken] - My music


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 23rd, 2007, 11:56 pm 
Offline

Joined: November 24th, 2007, 9:07 pm
Posts: 774
Ecstatic Feature Update

I haven't released the next version yet, but it's for a good reason... I'm nearly complete with the first version of the Non-Steam Game Auto-Updater!

This feature will traverse your Steam shortcuts and automatically keep track of versions and search for new ones.

In its current state, it's not very good at determining the initial version of a game, so it will ask you to confirm all the versions it finds. After you confirm it once, you won't have to do it again.

Regardless, once you set your versions, off it goes... from then on out, it can search for new patches, download them as torrent files, and install them for you.... just like Steam, but for all your other games :)

I've figured out some major hurdles for me. uTorrent will now be auto-installed in a sub-directory of the script (don't worry, it doesn't actually get "installed"), and SteamLab will manage the statuses of all patch files. All files, torrents, and settings are self-contained in SteamLab's directory for convenience and compatibility with multiple installations.

I hope to be done with this by tomorrow (12/24/2007)

Apparently More Features + Nicer Interface = Smaller File Size ... That's right, SteamLab's download will be smaller than it was before and I haven't removed a single feature! Thank you Auto-Generating Text Buttons! (and tic especially!) :)

Update 1: Milestone Number, ah... Several for today :)
Auto-Updater now works all the way through downloading the files to the correct directory.

Next stop: Waiting for the downloads to complete and patching the games as each finishes.
ETA: ...today!

_________________
Ben

My Trac projects
My Wiki
[Broken] - My music


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 27th, 2007, 3:43 am 
Offline

Joined: November 24th, 2007, 9:07 pm
Posts: 774
Running a little behind on the next release while I work to perfect my xpath() code and XML layout and Titan works to perfect his xpath() function :)

I think we're both almost there! I've now got SteamLab creating a generic games.xml file from your Steam shortcuts (and keeping it updated with new shortcuts as they're added). This way I can create a GUI for adding games not in Steam's shortcuts to the file and getting updates for those as well. I can also use it to store other data for your games to add more features to SteamLab. The possibilities are almost endless!

In the meantime, another update on the upcoming release:

I have removed GameShadow from SteamLab in preparation for the new internal Game Updates feature. You'll no longer be prompted to download and install GameShadow, nor will there be any menu items or options for it.

It's nothing against GameShadow, but the reasons are obvious. No more clunky 3rd party software. No more managing a separate game database just for updates. Now all your Steam Shortcuts are checked for patches, which are (optionally) downloaded/installed for you--just like your actual Steam games.

Update: And not that it should matter to users, but the new version will now also use much nicer functions (thanks majkinetor :) ) for loading and saving the settings file which will make it much, much easier for me to add and change settings from here on out.

Update 2: A more flexible "default" file storage system will also allow for simple (and customizable) default file restoration for all major customizable SteamLab files (settings, hotkeys, etc). As these files become more complex, this will allow you to revert an entire file at once, saving time.

_________________
Ben

My Trac projects
My Wiki
[Broken] - My music


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 27th, 2007, 5:30 am 
Offline

Joined: November 24th, 2007, 9:07 pm
Posts: 774
As another update related to my new "default" (template) file structure, I am including a ton more options in the settings files. This will allow even people with the Exe version of SteamLab to customize the program to their liking, and will help to keep everything uniform and consistent.

Going forward, I'll even now be able to save window sizes/positions, the state of various program elements, all submitted form data, etc. directly to the settings file so it is all persistent.

Most "advanced" features won't have GUI options yet, but as the program matures I'll add more and more features and a better tabbed layout to the Settings GUI.

This will be a huge plus for usability and convenience in SteamLab.

It will push the release back another day or so, however, while I replace all my setting variable names. Sorry folks (if anyone's been downloading) :)

_________________
Ben

My Trac projects
My Wiki
[Broken] - My music


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 123 posts ]  Go to page Previous  1, 2, 3, 4, 5 ... 9  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: Bing [Bot], Exabot [Bot], sjc1000, Yahoo [Bot] and 46 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group