![Smile :)](./images/smilies/icon_e_smile.gif)
@tic can't wait for the class based lib to be complete
![Very Happy :D](./images/smilies/icon_e_biggrin.gif)
Using latest AHK_L/HGdip wrote:File loading error!, Could not load the image specified
Code: Select all
mc := new MyClass()
mc.MyMethod
mc.MyMethod1()
class ErrorClass
{
__Call(method)
{
throw Exception("Non-existent method", -1, method)
}
}
class MyClass extends ErrorClass
{
MyMethod()
{
MsgBox, MyMethod
}
}
Heh sorry...I did know that, but it was 2 am. My mind must be goingGeekDude wrote:tic
I'm not joedf, but thanks for the info anyways
Code: Select all
; gdi+ ahk tutorial 3 written by tic (Tariq Porter)
; Requires Gdip.ahk either in your Lib folder as standard library or using #Include
;
; Tutorial to take make a gui from an existing image on disk
; For the example we will use png as it can handle transparencies. The image will also be halved in size
#SingleInstance, Force
#NoEnv
SetBatchLines, -1
; Uncomment if Gdip.ahk is not in your standard library
;#Include, Gdip.ahk
; Start gdi+
If !pToken := Gdip_Startup()
{
MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
ExitApp
}
OnExit, Exit
; Create a layered window (+E0x80000 : must be used for UpdateLayeredWindow to work!) that is always on top (+AlwaysOnTop), has no taskbar entry or caption
Gui, 1: -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs
; Show the window
Gui, 1: Show, NA
; Get a handle to this window we have created in order to update it later
hwnd1 := WinExist()
; If the image we want to work with does not exist on disk, then download it...
If !FileExist("background.png")
UrlDownloadToFile, http://www.autohotkey.net/~tic/background.png, background.png
; Get a bitmap from the image
pBitmap := Gdip_CreateBitmapFromFile("background.png")
; Check to ensure we actually got a bitmap from the file, in case the file was corrupt or some other error occured
If !pBitmap
{
MsgBox, 48, File loading error!, Could not load the image specified
ExitApp
}
; Get the width and height of the bitmap we have just created from the file
; This will be the dimensions that the file is
Width := Gdip_GetImageWidth(pBitmap), Height := Gdip_GetImageHeight(pBitmap)
; Create a gdi bitmap with width and height of what we are going to draw into it. This is the entire drawing area for everything
; We are creating this "canvas" at half the size of the actual image
; We are halving it because we want the image to show in a gui on the screen at half its dimensions
hbm := CreateDIBSection(Width//2, Height//2)
; Get a device context compatible with the screen
hdc := CreateCompatibleDC()
; Select the bitmap into the device context
obm := SelectObject(hdc, hbm)
; Get a pointer to the graphics of the bitmap, for use with drawing functions
G := Gdip_GraphicsFromHDC(hdc)
; We do not need SmoothingMode as we did in previous examples for drawing an image
; Instead we must set InterpolationMode. This specifies how a file will be resized (the quality of the resize)
; Interpolation mode has been set to HighQualityBicubic = 7
Gdip_SetInterpolationMode(G, 7)
; DrawImage will draw the bitmap we took from the file into the graphics of the bitmap we created
; We are wanting to draw the entire image, but at half its size
; Coordinates are therefore taken from (0,0) of the source bitmap and also into the destination bitmap
; The source height and width are specified, and also the destination width and height (half the original)
; Gdip_DrawImage(pGraphics, pBitmap, dx, dy, dw, dh, sx, sy, sw, sh, Matrix)
; d is for destination and s is for source. We will not talk about the matrix yet (this is for changing colours when drawing)
Gdip_DrawImage(G, pBitmap, 0, 0, Width//2, Height//2, 0, 0, Width, Height)
; Update the specified window we have created (hwnd1) with a handle to our bitmap (hdc), specifying the x,y,w,h we want it positioned on our screen
; So this will position our gui at (0,0) with the Width and Height specified earlier (half of the original image)
UpdateLayeredWindow(hwnd1, hdc, 0, 0, Width//2, Height//2)
; Select the object back into the hdc
SelectObject(hdc, obm)
; Now the bitmap may be deleted
DeleteObject(hbm)
; Also the device context related to the bitmap may be deleted
DeleteDC(hdc)
; The graphics may now be deleted
Gdip_DeleteGraphics(G)
; The bitmap we made from the image may be deleted
Gdip_DisposeImage(pBitmap)
Return
;#######################################################################
Exit:
; gdi+ may now be shutdown on exiting the program
Gdip_Shutdown(pToken)
ExitApp
Return
Interest level =tic wrote:I have integrated this by default into Gdip2 so that custom controls can be added and handled easily, but I am unsure of the level of interest in this project.
OnMessage for WM_LBUTTONDOWN and WM_MOUSEMOVE are a lot more graceful than pollingtic wrote:Hi samardac
You will need to draw the controls yourself and handle user interaction. I have posted examples around that demonstrate this.
A simple way to handle an image that has a click handler is to create an object with the image, and its coordinates, then poll the mouses position and lbutton state, and perform actions based upon the result.
I have integrated this by default into Gdip2 so that custom controls can be added and handled easily, but I am unsure of the level of interest in this project.
I recommend to not use this for gdi+ layered window manipulation unless the user is requiring very simple triggers. Neither of those messages will play nicely with other actions as they are not intended to interact with a custom window that does not implement standard controls, and also you will have to muddy your scope by implementing global variables.GeekDude wrote:OnMessage for WM_LBUTTONDOWN and WM_MOUSEMOVE are a lot more graceful than polling
[v1.1.20+]: If not a valid label name, this parameter can be the name of a function, or a single variable reference containing a function object. For example, SetTimer %funcobj%, 1000 or SetTimer % funcobj, 1000. Other expressions which return objects are currently unsupported.
GeekDude wrote:Could you explain the scope issues a bit more in depth? I'm not sure what you mean by that.
Code: Select all
#SingleInstance Force
myc := new MyClass()
return
class MyClass
{
LButtonDown := false
LastMousePos := { X: -1, Y: -1 }
LastClickPos := { X: -1, Y: -1 }
__New()
{
Gui, 1: Show, w400 h400 ; Not like this. Would actually create a window contained in this class. Just for testing
fn := this.MsgHandler.Bind(this, {})
OnMessage(0x200, fn) ;WM_MOUSEMOVE
OnMessage(0x201, fn) ;WM_LBUTTONDOWN
OnMessage(0x202, fn) ;WM_LBUTTONUP
}
MsgHandler(t, wParam, lParam, msg, hwnd)
{
if (msg = 0x200)
{
this.LastMousePos := { X: lParam & 0xFFFF, Y: lParam >> 16 }
}
else if (msg = 0x201)
{
this.LButtonDown := true
this.LastClickPos := this.LastMousePos
}
else if (msg = 0x202)
{
this.LButtonDown := false
}
if (this.LastClickPos.X != -1)
Tooltip, % "Last clicked position: (" this.LastClickPos.X ", " this.LastClickPos.Y ")"
}
}
Quite a while ago I asked for help doing just this. just me calculated the new structure, see here. Note that in his next post he made a small correction: offIcon := offFlags + 4 + A_PtrSize.tic wrote:Someone will need to work out the new structure size of NOTIFYICONDATA to get it to work in AHK_L
Code: Select all
#NoEnv
If !pToken := Gdip_Startup()
{
MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
ExitApp
}
OnExit, Exit
NotifyIcon := new Notify()
Sleep, 1000
loop, 10
{
NotifyIcon.SetText(A_Index-1)
Sleep, 500
}
return
Exit:
Gdip_Shutdown(pToken)
ExitApp
return
Class Notify
{
__New(IconFont="Verdana", IconSize=16)
{
this.IconFont := IconFont, this.IconSize := IconSize
;this.pBitmapIcon := Gdip_CreateBitmapFromFile(A_AhkPath)
DllCall("shell32.dll\SHExtractIconsW", "Str", A_AhkPath
, "Int", 0, "Int", IconSize, "Int", IconSize
, "Ptr*", hIcon, "UInt*", 0, "UInt", 1, "UInt", 0)
this.pBitmapIcon := Gdip_CreateBitmapFromHICON(hIcon)
DestroyIcon(hIcon)
this.pBitmap := Gdip_CreateBitmap(IconSize, IconSize)
this.G := Gdip_GraphicsFromImage(this.pBitmap)
this.pBrush := Gdip_BrushCreateSolid(0xFF5555FF)
}
SetText(String)
{
Gdip_GraphicsClear(this.G, 0x00000000)
Gdip_DrawImage(this.G, this.pBitmapIcon)
; Draw the "bubble"
Gdip_FillRectangle(this.G, this.pBrush, 5, 6, 11, 9)
Gdip_FillRectangle(this.G, this.pBrush, 6, 5, 9, 11)
Gdip_TextToGraphics(this.G, String, "x7 y5 s8 cFFFFFFFF", this.IconFont)
hIcon := Gdip_CreateHICONFromBitmap(this.pBitmap)
this.SetIcon(hIcon)
DestroyIcon(hIcon)
}
SetIcon(hIcon)
{
static NIM_MODIFY := 1, NIF_ICON := 2, NOTIFYICONDATA
, Size := VarSetCapacity(NOTIFYICONDATA, (A_PtrSize == 8) ? 976 : 956, 0)
Addr := NumPut(Size, NOTIFYICONDATA, 0, "UInt") ; UINT cbSize
Addr := NumPut(A_ScriptHwnd, Addr+0, A_PtrSize-4, "UPtr") ; HWND hWnd
Addr := NumPut(1028, Addr+0, 0, "UInt") ; UINT uID
Addr := NumPut(NIF_ICON, Addr+0, 0, "UInt") ; UINT uFlags
Addr := NumPut(hIcon, Addr+0, A_PtrSize, "UPtr") ; HICON hIcon
DllCall("shell32.dll\Shell_NotifyIcon", "UInt", NIM_MODIFY, "UPtr", &NOTIFYICONDATA)
}
__Delete()
{
Gdip_DeleteBrush(this.pBrush)
Gdip_DeleteGraphics(this.G)
Gdip_DisposeImage(this.pBitmap)
Gdip_DisposeImage(this.pBitmapIcon)
}
}
Return to “Scripts and Functions (v1)”
Users browsing this forum: Dean36 and 186 guests