AutoHotkey Community

It is currently May 26th, 2012, 5:03 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 37 posts ]  Go to page 1, 2, 3  Next
Author Message
PostPosted: February 1st, 2009, 6:40 pm 
Offline

Joined: June 26th, 2008, 3:58 am
Posts: 56
First of all, I want to say thanks a bunch to corrupt for his excellent graphic button functions. I've used them extensively. However, I found a few aspects lacking.

The most glaring problem is the limitations on Windows XP. On XP, buttons with the BM_SETIMAGE message do not assume the OS's visual style, which can end up looking downright ugly if you have both text buttons and image buttons in your app. These buttons also are incapable of displaying an image+text.

BM_SETIMAGE buttons do not have native support for button states (hover, disabled, etc) or image alignment.

So with these flaws in mind, I went searching for a better way to create an image button. What I found was the BCM_SETIMAGELIST message. This attaches an imagelist to a button, and, combined with a few dllcall functions, allows for more flexible and customizable image buttons. I've written a single small function wrapping most of the options that are available.

Features
  • Supports exe, dll, ico, cur, ani, and bmp files
  • Button states: normal, hover, pressed, disabled, focused, and stylushot
  • Supports image+text
  • Supports visual styles on Windows XP
  • Alignment options: left, right, top, bottom, or center - very useful for image+text buttons
  • Image margin options
  • Creates no global variables

Image_Image

Download: ILButton11.ahk
Code:
/*
Title: ILButton
Version: 1.1
Author: tkoi <http://www.autohotkey.net/~tkoi>
License: GNU GPLv3 <http://www.opensource.org/licenses/gpl-3.0.html>

Function: ILButton()
    Creates an imagelist and associates it with a button.
Parameters:
    hBtn   - handle to a buttton
    images - a pipe delimited list of images in form "file:zeroBasedIndex"
               - file must be of type exe, dll, ico, cur, ani, or bmp
               - there are six states: normal, hot (hover), pressed, disabled, defaulted (focused), and stylushot
                   - ex. "normal.ico:0|hot.ico:0|pressed.ico:0|disabled.ico:0|defaulted.ico:0|stylushot.ico:0"
               - if only one image is specified, it will be used for all the button's states
               - if fewer than six images are specified, nothing is drawn for the states without images
               - omit "file" to use the last file specified
                   - ex. "states.dll:0|:1|:2|:3|:4|:5"
               - omitting an index is the same as specifying 0
               - note: within vista's aero theme, a defaulted (focused) button fades between images 5 and 6
    cx     - width of the image in pixels
    cy     - height of the image in pixels
    align  - an integer between 0 and 4, inclusive. 0: left, 1: right, 2: top, 3: bottom, 4: center
    margin - a comma-delimited list of four integers in form "left,top,right,bottom"

Notes:
    A 24-byte static variable is created for each IL button
    Tested on Vista Ultimate 32-bit SP1 and XP Pro 32-bit SP2.

Changes:
  v1.1
    Updated the function to use the assume-static feature introduced in AHK version 1.0.48
*/

ILButton(hBtn, images, cx=16, cy=16, align=4, margin="1,1,1,1") {
   static
   static i = 0
   local himl, v0, v1, v2, v3, ext, hbmp, hicon
   i ++

   himl := DllCall("ImageList_Create", "UInt",cx, "UInt",cy, "UInt",0x20, "UInt",1, "UInt",5)
   Loop, Parse, images, |
      {
      StringSplit, v, A_LoopField, :
      if not v1
         v1 := v3
      v3 := v1
      SplitPath, v1, , , ext
      if (ext = "bmp") {
         hbmp := DllCall("LoadImage", "UInt",0, "Str",v1, "UInt",0, "UInt",cx, "UInt",cy, "UInt",0x10)
         DllCall("ImageList_Add", "UInt",himl, "UInt",hbmp, "UInt",0)
         DllCall("DeleteObject", "UInt", hbmp)
         }
      else {
         DllCall("PrivateExtractIcons", "Str",v1, "UInt",v2, "UInt",cx, "UInt",cy, "UIntP",hicon, "UInt",0, "UInt",1, "UInt",0)
         DllCall("ImageList_AddIcon", "UInt",himl, "UInt",hicon)
         DllCall("DestroyIcon", "UInt", hicon)
         }
      }
   ; Create a BUTTON_IMAGELIST structure
   VarSetCapacity(struct%i%, 24)
   NumPut(himl, struct%i%, 0, "UInt")
   Loop, Parse, margin, `,
      NumPut(A_LoopField, struct%i%, A_Index * 4, "UInt")
   NumPut(align, struct%i%, 20, "UInt")
   ; BCM_FIRST := 0x1600, BCM_SETIMAGELIST := BCM_FIRST + 0x2
   PostMessage, 0x1602, 0, &struct%i%, , ahk_id %hBtn%
   Sleep 1 ; workaround for a redrawing problem on WinXP
   }

Download: ilbuttondemo.ahk
Code:
#SingleInstance force
#NoEnv

#Include %A_ScriptDir%\ILButton.ahk

Gui, +ToolWindow +AlwaysOnTop
Loop 5 {
   Gui, Add, Button, w64 h32 xm hwndhBtn
      ILButton(hBtn, "user32.dll:" A_Index-1, 16, 16, A_Index-1)
   Gui, Add, Button, w100 h32 x+10 hwndhBtn, text
      ILButton(hBtn, "user32.dll:" A_Index-1, 16, 16, A_Index-1)
   }
Gui, Add, Button, xm w174 h48 vStates hwndhBtn, pushbuttonstates
   ILButton(hBtn, "user32.dll:0|:1|:2|:3|:4|:5", 32, 32, 0, "16,1,-16,1")
Gui, Add, Button, w100 h26 xm+74 gToggle, Enable/disable

Gui, Show, , ILButton demo
return

Toggle:
   GuiControlGet, s, Enabled, States
   GuiControl, Disable%s%, States
   return

GuiClose:
GuiEscape:
   ExitApp
   return

Please post any bugs you find!

Regards,
tkoi


Last edited by tkoi on February 26th, 2009, 2:31 am, edited 3 times in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 2nd, 2009, 1:44 am 
Thanks for sharing your script(s). Much appreciated :D


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: February 2nd, 2009, 3:13 pm 
Online
User avatar

Joined: December 26th, 2005, 4:40 pm
Posts: 8776
Great! Thanks. :)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 2nd, 2009, 4:33 pm 
Offline

Joined: February 14th, 2005, 4:05 pm
Posts: 4710
Location: Boulder, CO
Very nice!
Could you extend it, such that the associated system icon of the file would be shown, e.g. when the icon number is -1?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 2nd, 2009, 7:06 pm 
Offline

Joined: February 14th, 2005, 4:05 pm
Posts: 4710
Location: Boulder, CO
The command VarSetCapacity(structs, c+24) looks suspicious:

It allocates larger and larger memory blocks, but each time the previous data can be lost. In this script the old data might be preserved, because struct is the last static variable, so its memory is just increased, but this behavior might change in a future AHK version or when the memory pool dries out. Since we have no static arrays, we probably have to use an array of global structs.

To demonstrate the problem, add VarSetCapacity(c, c+24) to the code. Now the struct variable cannot be just enlarged, and the script breaks.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 4th, 2009, 3:44 pm 
Great discovery. I traversed all API places around for the solution regarding system bug with button images but I didn't see this one.

IT works in XP too, but here icons appear only when i mouse over them. Seems like an easy thing to solve anyway.

Thx.


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: February 5th, 2009, 5:16 pm 
Offline

Joined: February 14th, 2005, 4:05 pm
Posts: 4710
Location: Boulder, CO
majkinetor ! wrote:
IT works in XP too, but here icons appear only when i mouse over them.
On my XP laptop changing Sleep -1 to Sleep 1 (last line) fixes the problem.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 5th, 2009, 8:24 pm 
Offline

Joined: May 24th, 2006, 2:49 pm
Posts: 4511
Location: Belgrade
:)

Thx

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 6th, 2009, 1:50 am 
Offline

Joined: October 1st, 2005, 9:55 pm
Posts: 775
Location: Texas, USA
Looks useful. Thanks for sharing. :)


Report this post
Top
 Profile  
Reply with quote  
 Post subject: image not returned
PostPosted: February 24th, 2009, 12:31 am 
Offline

Joined: August 25th, 2005, 9:40 pm
Posts: 129
testing this tool but I'm unable to use a specific icon. the icon image is in the same folder as script

can someone tell me why this line fails to return an image ?


Code:
Gui, 2:Add, Button, x16 y50  w100 h30 hwndhBtn gButtonTool_1, Tool_2
      ILButton(hBtn, "icon6-16x16C.ico:0" 1, 16, 16, 0)


________
DRUGTEST


Last edited by webber on March 11th, 2011, 12:29 am, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 24th, 2009, 3:55 am 
Offline

Joined: June 26th, 2008, 3:58 am
Posts: 56
What's that 1 doing there? :D
Code:
Gui, 2:Add, Button, x16 y50  w100 h30 hwndhBtn gButtonTool_1, Tool_2
      ILButton(hBtn, "icon6-16x16C.ico:0" 1, 16, 16, 0)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 24th, 2009, 4:30 am 
Offline

Joined: August 25th, 2005, 9:40 pm
Posts: 129
image is not appearing on the button - that's what I doing there.

so the question is, why no image from the code ?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 24th, 2009, 5:01 am 
Offline

Joined: June 26th, 2008, 3:58 am
Posts: 56
I tested it - it works if you remove the 1.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 25th, 2009, 7:00 am 
Offline

Joined: August 25th, 2005, 9:40 pm
Posts: 129
:oops:
________
Chevrolet colorado


Last edited by webber on March 11th, 2011, 12:29 am, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 26th, 2009, 2:32 am 
Offline

Joined: June 26th, 2008, 3:58 am
Posts: 56
Updated - the function now uses the assume-static mode introduced in 1.0.48


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

All times are UTC [ DST ]


Who is online

Users browsing this forum: Google [Bot] and 8 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