Anyone know a convenient way to tile an image to fill a GUI? I would have thought there'd be an easy way to do this but I can't find it of so. I could always just use a bunch of picture controls, but if there's a command I've forgotten anyone knows as some DLL wizardry for this, I'd appreciate it.
Tiled GUI background?
Started by
ManaUser
, Dec 23 2007 12:06 AM
6 replies to this topic
#1
Posted 23 December 2007 - 12:06 AM
#2
Guests
Posted 23 December 2007 - 11:38 AM
There is a GDI+ crop function somewhere on the forum
#3
Posted 23 December 2007 - 05:57 PM
The bunch of pictures is really slow on my older system, but it does work:I could always just use a bunch of picture controls, but if there's a command I've forgotten anyone knows as some DLL wizardry for this, I'd appreciate it.
Gui,Margin,0,0
Gui, +resize
Gui,add,picture,x0 y0 w100 h100 hwndhPic,c:\YourPicture.jpg.png.etc
Gui,Show,x0 y0 w%A_ScreenWidth% h%A_ScreenHeight%,Test
x:=0
y:=0
Loop
{
x+=100
if(x >= A_ScreenWidth){
x:=0
y+=100
if(y >= A_ScreenHeight)
break
}
Gui,Add,Picture,x%x% y%y% w100 h100,c:\YourPicture.jpg.png.etc
}
Gui,Show,x100 y100 w400 h400
return
GuiClose:
ExitAppHere is a much faster way using......drum roll please......DllCalls to GDI.w:=100 ;width of individual tile
h:=100 ;height of individual tile
Gui, +resize
Gui,add,picture,x0 y0 w%w% h%h% hwndhPic,c:\YourPicFileHere.jpg.png.etc
SendMessage,0x173,0,0,,ahk_id %hPic% ;0x173 is STM_GETIMAGE
hBMCopy:=ErrorLevel
;Get a copy of the picture
hBM:=DllCall("CopyImage",uint,hBMCopy,uint,0,int,0,int,0,uint,0x2000)
;Get device context for picture
hDC:=DllCall("GetDC",uint,hPic,uint)
;Create compatible device context to put picture in
hCDC:=DllCall("CreateCompatibleDC",uint,hDC,uint)
;Put the picture in the CDC
DllCall("SelectObject",uint,hCDC,uint,hBM)
;Create compatible device context to hold tiled image
hCDC2:=DllCall("CreateCompatibleDC",uint,hDC,uint)
;Create an empty bitmap to trap the tiled image in
hBM2:=DllCall("CreateCompatibleBitmap",uint,hDC,int,A_ScreenWidth,int,A_ScreenHeight,uint)
;Put the empty image in so can draw on it
DllCall("SelectObject",uint,hCDC2,uint,hBM2)
x:=-1*w
y:=0
Loop
{
x+=w
if(x >= A_ScreenWidth){
x:=0
y+=h
if(y >= A_ScreenHeight)
break
}
;Build the tiled image in the compatible heretofore empty bitmap
DllCall("BitBlt",uint,hCDC2,int,x,int,y,int,w,int,h,uint,hCDC,int,0,int,0,uint,0xcc0020)
}
;Cleanup
DllCall("ReleaseDC",uint,hPic,uint,hDC)
DllCall("DeleteObject",uint,hCDC)
DllCall("DeleteObject",uint,hCDC2)
DllCall("DeleteObject",uint,hBM)
;Apply the tiled image to the original picture
SendMessage,0x172,0,hBM2,, ahk_id %hPic% ;0x172 is STM_SETIMAGE message
if(ErrorLevel && hBM2 <> ErrorLevel)
DllCall("DeleteObject",uint,errorlevel)
Gui, Show, x100 y100 w400 h400, Test
return
GuiClose:
ExitApp
This works on Windows Me. I think it should work on XP also. I have found some differences in the way XP handles static images as compared to Me. I believe it was XP that required me to start doing the CopyImage call.Anyway give this a try and see if it works for you.
dmatch
#4
Posted 24 December 2007 - 07:17 AM
Yes, the DLL method works nicely. I wasn't expecting it would take quite that much code, but it does exactly what I wanted. Thanks! Extra thanks for the helpful commends, I am trying to gradually get a handle on how to use these external functions.
#5
Posted 24 December 2007 - 04:56 PM
You're welcome.
Actually, that's not too out of the ordinary for C programming with Windows API and that essentially is what the code is doing.
MSDN.com is a source for info on the Windows API or you can get the SDK helpfile (click here). You would also need a list of Windows constants (such as STM_SETIMAGE used in the code above). Those are in include/header (winuser.h, wingdi.h etc) files so you would either need them or access to these constants. SKAN has posted a useful tool for fetching constants here:
http://www.autohotke...topic19766.html
With the above mentioned stuff you could gradually get a handle on it. :wink:
Good Luck,
dmatch
I wasn't expecting it would take quite that much code
Actually, that's not too out of the ordinary for C programming with Windows API and that essentially is what the code is doing.
I am trying to gradually get a handle on how to use these external functions.
MSDN.com is a source for info on the Windows API or you can get the SDK helpfile (click here). You would also need a list of Windows constants (such as STM_SETIMAGE used in the code above). Those are in include/header (winuser.h, wingdi.h etc) files so you would either need them or access to these constants. SKAN has posted a useful tool for fetching constants here:
http://www.autohotke...topic19766.html
With the above mentioned stuff you could gradually get a handle on it. :wink:
Good Luck,
dmatch
#6
Kiera
Posted 27 May 2010 - 10:21 PM
Dmatch, when I use your code to tile images, I'm running into a small problem.
If I add an image to the GUI before "Gui, Show", it comes up just fine.
But if I add an image afterwards (for example, as a result of pressing a button), it doesn't come up unless I either hit the button a second time, or unless I add "WinSet, Redraw" after the add image line - which causes undesirable flickering when I've got a more complicated GUI.
Is there any way to get it to show up properly the first time that doesn't cause flicker?
Here's some sample code:
If I add an image to the GUI before "Gui, Show", it comes up just fine.
But if I add an image afterwards (for example, as a result of pressing a button), it doesn't come up unless I either hit the button a second time, or unless I add "WinSet, Redraw" after the add image line - which causes undesirable flickering when I've got a more complicated GUI.
Is there any way to get it to show up properly the first time that doesn't cause flicker?
Here's some sample code:
TileImage(TpicOutputVar, TileWidth, TileHeight)
{
Global
; Set the dimensions of each individual tile.
w := TileWidth
h := TileHeight
SendMessage,0x173,0,0,,ahk_id %TpicOutputVar% ;0x173 is STM_GETIMAGE
hBMCopy:=ErrorLevel
;Get a copy of the picture
hBM:=DllCall("CopyImage",uint,hBMCopy,uint,0,int,0,int,0,uint,0x2000)
;Get device context for picture
hDC:=DllCall("GetDC",uint,TpicOutputVar,uint)
;Create compatible device context to put picture in
hCDC:=DllCall("CreateCompatibleDC",uint,hDC,uint)
;Put the picture in the CDC
DllCall("SelectObject",uint,hCDC,uint,hBM)
;Create compatible device context to hold tiled image
hCDC2:=DllCall("CreateCompatibleDC",uint,hDC,uint)
;Create an empty bitmap to trap the tiled image in
hBM2:=DllCall("CreateCompatibleBitmap",uint,hDC,int,A_ScreenWidth,int,A_ScreenHeight,uint)
;Put the empty image in so can draw on it
DllCall("SelectObject",uint,hCDC2,uint,hBM2)
x := -1 * w
y := 0
Loop
{
x += w
if (x >= A_ScreenWidth)
{
x:=0
y+=h
if (y >= A_ScreenHeight)
{
break
}
}
;Build the tiled image in the compatible heretofore empty bitmap
DllCall("BitBlt",uint,hCDC2,int,x,int,y,int,w,int,h,uint,hCDC,int,0,int,0,uint,0xcc0020)
}
; Cleanup
DllCall("ReleaseDC",uint,TpicOutputVar,uint,hDC)
DllCall("DeleteObject",uint,hCDC)
DllCall("DeleteObject",uint,hCDC2)
DllCall("DeleteObject",uint,hBM)
;Apply the tiled image to the original picture
SendMessage, 0x172, 0, hBM2,, ahk_id %TpicOutputVar% ;0x172 is STM_SETIMAGE message
if (ErrorLevel && hBM2 <> ErrorLevel)
{
DllCall("DeleteObject",uint,errorlevel)
}
}
Gui, +Resize
Gui, 1:Add, Pic, x0 y0 w128 h128 hwndTiledPic, %A_WorkingDir%\Images\yukon.jpg
TileImage(TiledPic, 128, 128)
Gui, Add, Button,x10 y10, Show Images
; This images comes up just fine.
Gui, 1:Add, Pic, x500 y500 BackgroundTrans AltSubmit, %A_WorkingDir%\Deck\RD2.png
Gui, Show, Maximize
Return
ButtonShowImages:
; This image won't come up unless you hit the button a second time, or add "WinSet, Redraw" after this line.
Gui, 1:Add, Pic, x100 y100 BackgroundTrans AltSubmit, %A_WorkingDir%\Deck\GD2.png
Return
GuiClose:
ExitApp
#7
Posted 28 May 2010 - 02:03 PM
I don't know what to tell you about the need for a second click to show the image (or winset redraw) except that it might be a Windows message timing issue that might be different from one system to another. The image appears on the first click on my old ME system without Winset, Redraw being used.
I also see a flash (flicker) when a picture is displayed the second and subsequent times but not the first time. I tried using GuiControl to change the picture instead of adding it each time but the flash is still there. I have run into this sort of thing many times when manipulating images in Autohotkey. I am not usually able to resolve that issue so can't be of help on that. Maybe someone else can suggest potential solutions.
dmatch
I also see a flash (flicker) when a picture is displayed the second and subsequent times but not the first time. I tried using GuiControl to change the picture instead of adding it each time but the flash is still there. I have run into this sort of thing many times when manipulating images in Autohotkey. I am not usually able to resolve that issue so can't be of help on that. Maybe someone else can suggest potential solutions.
dmatch




