Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

GDI+ standard library 1.45 by tic


  • Please log in to reply
1385 replies to this topic
jleslie48
  • Members
  • 145 posts
  • Last active: Sep 28 2017 07:13 PM
  • Joined: 29 Jun 2010
Well some headway has been made with tutoral10:

in this version when you click 'go' the needle will auto locate to its correct rotation AND locaton even if you move the window.
Kenn demonstrated a cleaner update mechnaism using the slider, which should be worked into the project. A trigger event on
change of position of the gui itself should also trigger the reload of the needle. Actually the start of
moving the GUI should turn off the needle and then redraw it when you are finished with the move of the gui.

Of paramount issue though is still to change the layered window so that its visibilty is the same as the gui.

Here is the new tutorial10 speedometer:

;
; AutoHotkey Version: 1.x
; Language:       English
; Platform:       Win9x/NT
; Author:         A.N.Other <[email protected]>
;
; Script Function:
;	Template script (you can customize this template by editing "ShellNew\Template.ahk" in your Windows folder)
;

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

;---------------------------------

; 120123 JL    set up default image of speedometer-2.png.
;              layeredwindow image now is transposed to the proper position based on the 'speedometer_offset' and 
;              the needle image size.   The trick is that as you rotate the image, the size of the containing 
;              rectangle that is the rotated needle is different (larger) than the original image. It has to do with
;              the hypotenuse of a triangle or something. look for the useage of 'needlex' and needley' 

; gdi+ ahk tutorial 10 written by tic (Tariq Porter)
; Requires Gdip.ahk either in your Lib folder as standard library or using #Include
;
; Tutorial to rotate, flip or mirror an image

#SingleInstance, Force
#NoEnv
SetBatchLines, -1

speedometer_offsetx := 100
speedometer_offsety := 200


; 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 gui where we can select the file we want to rotate, the angle to rotate it by and whether we want to flip it
Gui, 1: +ToolWindow ; +AlwaysOnTop
Gui, 1: Add, Edit, x10 y10 w300 vFile, 
Gui, 1: Add, Button, x+10 20+0 w75 gFileSelect Default, &File...
Gui, 1: Add, Button, x+10 30+0 w75 gGo, Go

; Here is the slider allowing rotation between 0 and 360 degrees
Gui, 1: Add, Slider, x10 40 w300 Tooltip vAngle Range0-360, 0

; Create 2 checkboxes, to select whether we want to flip it horizontally or vertically
Gui, 1: Add, CheckBox, x+10 yp+0 vHorizontal, Flip horizontally
Gui, 1: Add, CheckBox, x+10 yp+0 vVertical, Flip vertically
Gui, 1: Add, Picture, x%speedometer_offsetx% y%speedometer_offsety% , speedometer-0.png

;imgFile2 = speedometer-2.png
;pimgBitmap2 := Gdip_CreateBitmapFromFile(imgFile2)
;himgBitmap2 := Gdip_CreateHBITMAPFromBitmap(pimgBitmap2)
;Gdip_GetImageDimensions(pimgBitmap2, imgWidth2, imgHeight2)

; lets put it so it overlaps the background a bit.  we see that it has lost its transparency. 
;Gui, 1: Add, Picture, x100 y100 w%imgWidth2% h%imgHeight2% 0xE hwndimgMyPic2
;SetImage(imgMyPic2, himgBitmap2)

Gui, 1: Show, x500 y50 w700 h700 ;AutoSize

; Create a layered window (+E0x80000 : must be used for UpdateLayeredWindow to work!) that is always on top (+AlwaysOnTop), has no taskbar entry or caption
; This will be used as the 2nd gui so that we can show our image on it
;Gui, 2: -Caption +E0x80000 +LastFound +OwnDialogs +Owner +AlwaysOnTop
Gui, 2:  +E0x80000 +LastFound +OwnDialogs +Owner +AlwaysOnTop

; Show the window
Gui, 2: Show, NA

; Get a handle to this window we have created in order to update it later
hwnd2 := WinExist()

; By placing this OnMessage here. The function WM_LBUTTONDOWN will be called every time the user left clicks on the gui. This can be used for dragging the image
OnMessage(0x201, "WM_LBUTTONDOWN")
Return

;#####################################################################

Go:

; Submit the variables to see the degress to rotate by and whether to flip the image
Gui, 1: +OwnDialogs
Gui, 1: Submit, NoHide

; If the file in the edit field is not a valid image then return

; JL::
;msgbox, file is >%file%<
 file = speedometer-2.png




If !pBitmap := Gdip_CreateBitmapFromFile(File)
Return

; We should get the width and height of the image, in case it is too big for the screen then we can resize it to fit nicely
OriginalWidth := Gdip_GetImageWidth(pBitmap), OriginalHeight := Gdip_GetImageHeight(pBitmap)
Ratio := OriginalWidth/OriginalHeight

; If the image has a width larger than 1/2 of the width of the screen or height larger than 1/2 the screen, then we will resize it to be half of the screen
If (OriginalWidth >= A_ScreenWidth//2) || (OriginalHeight >= A_ScreenHeight//2)
{
	If (OriginalWidth >= OriginalHeight)
	Width := A_ScreenWidth//2, Height := Width*(1/Ratio)
	Else
	Height := A_ScreenHeight//2, Width := Height*Ratio
}
Else
Width := OriginalWidth, Height := OriginalHeight

; Width and Height now contain the new dimensions the image on screen will be

; When rotating a square image, then the bitmap or canvas will need to be bigger as you can imagine that once rotated then a triangle will be wider than a square
; We need to know the new dimensions of the image
; With Gdip_GetRotatedDimensions we can plug in the width and height of the image, and the angle it is to be rotated by
; The last 2 parameters are the variables in which tio store the new width and height of the rotated image
; RWidth and RHeight now contain the dimensions of the rotated image
Gdip_GetRotatedDimensions(Width, Height, Angle, RWidth, RHeight)

; We rotate an image about the top left corner of the image, however this will result in the image moving off the canvas
; We can use Gdip_GetRotatedTranslation to find how much the image should be 'shifted' by in the x and y coordinates in order for it to be back on the canvas
; As with the above function, we plug in the width, height and angle to rotate by
; The function will then make the last 2 parameters the x and y translation (this is the distance in pixels the image must be shifted by)
; xTranslation and yTranslation now contain the distance to shift the image by
Gdip_GetRotatedTranslation(Width, Height, Angle, xTranslation, yTranslation)

; We will now create a gdi bitmap to display the rotated image on the screen (as mentioned previously we must use a gdi bitmap to display things on the screen)
hbm := CreateDIBSection(RWidth, RHeight)

; 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,
; and set the InterpolationMode to HighQualityBicubic = 7 so that when resizing the image still looks good
G := Gdip_GraphicsFromHDC(hdc), Gdip_SetInterpolationMode(G, 7)

; We can now shift our graphics or 'canvas' using the values found with Gdip_GetRotatedTranslation so that the image will be drawn on the canvas
Gdip_TranslateWorldTransform(G, xTranslation, yTranslation)

; We can also rotate the graphics by the angle we desire
Gdip_RotateWorldTransform(G, Angle)

; If we wish to flip the image horizontally, then we supply Gdip_ScaleWorldTransform(G, x, y) with a negative x transform
; We multiply the image by the x and y transform. So multiplying a direction by -1 will flip it in that direction and 1 will do nothing
; We must then shift the graphics again to ensure the image will be within the 'canvas'
; You can see that if we wish to flip vertically we supply a negative y transform
If Horizontal
Gdip_ScaleWorldTransform(G, -1, 1), Gdip_TranslateWorldTransform(G, -Width, 0)
If Vertical
Gdip_ScaleWorldTransform(G, 1, -1), Gdip_TranslateWorldTransform(G, 0, -Height)


; As you will already know....we must draw the image onto the graphics. We want to draw from the top left coordinates of the image (0, 0) to the top left of the graphics (0, 0)
; We are drawing from the orginal image size to the new size (this may not be different if the image was not larger than half the screen)
Gdip_DrawImage(G, pBitmap, 0, 0, Width, Height, 0, 0, OriginalWidth, OriginalHeight)

; Even though this is not necessary in this scenario, you should always reset the transforms set on the graphics. This will remove any of the rotations
Gdip_ResetWorldTransform(G)

; We will update the hwnd  with the hdc of our gdi bitmap. We are drawing it at the new width and height and in the centre of the screen
; UpdateLayeredWindow(hwnd2, hdc, (A_ScreenWidth-RWidth)//2, (A_ScreenHeight-RHeight)//2, RWidth, RHeight)



; ok, so what is happening here? the 0degree rotation square image of the needle is fine, but when you rotate it, 
; the containing square using pixel notation changes based on the hypotenuse of the triangles. whatever, the point is
; the rotated image is bigger than the original so we must shift its position based on half its new size, hence we
; take the default position (which I had to offset the y by 10 for unknown reasons.) by the change in size. I will
; use the variables needlex and needley for that new position for the speedometer needle.  I will also take the time
; here to offset the needle by the current location of the controlling gui, so the needle moves when the gui moves. 
; well at least it does when you hit go.  We will have to fix this so the needle move with a mouse move soon. 

wingetpos,currentx,currenty
needlex := currentx     +speedometer_offsetx  - (rwidth-width)//2
needley := currenty +10 +speedometer_offsety  - (rheight-height)//2

; msgbox, sw %a_screenwidth%  %a_screenheight% `n image = %width%   %height% `n rimage = %rwidth%   %rheight% `n current gui: %currentx%   %currenty% `n needle %needlex%  %needley%

UpdateLayeredWindow(hwnd2, hdc, needlex, needley, RWidth, RHeight)

; As always we will dispose of everything we created
; So we select the object back into the hdc, the delete the bitmap and hdc
SelectObject(hdc, obm), DeleteObject(hbm), DeleteDC(hdc)
; We will then dispose of the graphics and bitmap we created
Gdip_DeleteGraphics(G), Gdip_DisposeImage(pBitmap)
Return

;#####################################################################

; This is a simple subroutine to select images and change the editbox with the image teh user selects
FileSelect:
Gui, 1: +OwnDialogs
Gui, 1: Submit, NoHide

FileSelectFile, File,,, Select image
If Errorlevel
Return
GuiControl,, File, %File%
Return

;#####################################################################

; This is the function to allow the user to drag the image drawn on the screen (this being gui 2)
WM_LBUTTONDOWN()
{
	If (A_Gui = 2)
	PostMessage, 0xA1, 2
}

;#####################################################################

; If the user closes the gui or closes the program then we want to shut down gdi+ and exit the application
;Esc::
GuiClose:
Exit:
Gdip_Shutdown(pToken)
ExitApp
Return


Tutorial 9 from the previous post has a transparent png file showing up actually in the gui, but has other issues: the transparency seems to effect an underlying image of a png rather than just letting the underlying image be seen.

jleslie48
  • Members
  • 145 posts
  • Last active: Sep 28 2017 07:13 PM
  • Joined: 29 Jun 2010
ok here is the latest sources:

<!-- m -->http://jleslie48.com...r/switchbox.zip<!-- m -->


Posted Image
<!-- m -->http://jleslie48.com... ... 120123.jpg<!-- m -->

it is based on tutorial10 with the addition of button controls for the switches and basic picture control for the leds.


the things that are missing are:

1) moving the needle when the gui moves,
2) having the needle take on the same layer as the gui rather than "always on top"
3) use pngs for the switches with transparent colors.


Along with fixing the above issues, I would still like to know what is going on with the tutorial 9 mods.

- Jon

tic
  • Members
  • 1934 posts
  • Last active: May 30 2018 08:13 PM
  • Joined: 22 Apr 2007
I think you will be best drawing everything into 1 bitmap and setting that to your control rather than drawing with separate windows. There are some errors with the offsets when rotating that I have never got round to fixing, and nobody else has chimed in with the correct math for the function. jleslie48, I think you might be better as well moving this to a separate topic and keeping all of the up to date resources in the top post, rather than re-posting new code and images each time

Thanks

Deo
  • Members
  • 199 posts
  • Last active: Jan 31 2014 03:19 PM
  • Joined: 16 May 2010
hey, guys
please check this post, hope someone can help
<!-- m -->http://www.autohotke...pic.php?t=81901<!-- m -->

gemisigo
  • Members
  • 94 posts
  • Last active: Apr 02 2015 02:36 PM
  • Joined: 10 Sep 2010

So far, all (non-BRA) examples are working perfectly :D


Yes, the exapmles are :) I have trouble with Gdip_SetBitmapToClipboard. It does not copy the image to the clipboard. Can you check this, please?

tic
  • Members
  • 1934 posts
  • Last active: May 30 2018 08:13 PM
  • Joined: 22 Apr 2007
Seems to work fine

gemisigo
  • Members
  • 94 posts
  • Last active: Apr 02 2015 02:36 PM
  • Joined: 10 Sep 2010
Sorry, I should have been more comprehensive. Here is a small code below that creates a "screenshot" of the 100, 100, 500 500 rectangle.

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
;#Warn

SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
FileEncoding, UTF-16-RAW


return
^MButton::
	captured_screen_file := A_ScriptDir . "\screen_capture.png"
	;Area := SelectArea("cLime msw")
	Area := "100|100|500|500"
	StringSplit, scc, Area, |, %A_Space%%A_Tab%
	
	If !pToken := Gdip_Startup()
	{
		MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
		ExitApp
	}
	
	pCapturedBitmap := Gdip_BitmapFromScreen(Area)
	Gdip_SetBitmapToClipboard(pCapturedBitmap)
	Gdip_SaveBitmapToFile(pCapturedBitmap, captured_screen_file)

	Gdip_DisposeImage(pCapturedBitmap)
	Gdip_ShutDown(pToken)
	
	Gui, captured_image: +LastFound +AlwaysOnTop +ToolWindow
	sx := scc1 - 3, sy := scc2 - 21
	Gui, captured_image: Add, Picture, x0 y0, %captured_screen_file%
	Gui, captured_image: Show, x%sx% y%sy% w%scc3% h%scc4% 
	
return

;#Include Gdip_tic.ahk
#Include Gdip_fincs.ahk


I tried both Gdips, the one created by you, tic, and the one modified by fincs. The AHK versions were 1.1.5.6 for both 32 and 64 bits.
Both Gdip_tic and Gdip_fincs worked as expected with 32 bit AHK exe. The file was saved, loaded and shown in the Toolwindow and the image was copied to the Clipboard.

With 64 bit AHK exe there were some issues.
Gdip_tic did not create the screenshot (though it loaded and displayed the file if there was one). No images could be fetched from the Clipboard.
Gdip_fincs did create the correct screenshot. It was able to load and display the image but did not put it on the Clipboard.

I'm clueless... :?

nioncode
  • Members
  • 19 posts
  • Last active: Apr 15 2013 03:01 PM
  • Joined: 03 Nov 2011
Hi tic,
thanks for this awesome library :)
I have modified your version to better suite my needs, following was changed:
[*:2foohz5r]Gdip_TextToGraphics: don't treat the color parameter in the options as a hex value if it is not preceded by "0x". This allows you to use a color from Gdip_ToARGB without converting it to hex first. If you want to use a hex color, just pass "c0xffffffff" for example.
[*:2foohz5r]Gdip_MeasureString: return an object with attributes (left, top, right, bottom, chars, lines) instead of a list separated by a "|". This was done because of my laziness and to avoid StringSplit.Patch file:
--- C:/Gdip_org.ahk	Sun Feb 19 01:35:01 2012
+++ C:/Gdip.ahk	Sun Feb 19 01:32:34 2012
@@ -1882,14 +1882,14 @@
 	RegExMatch(Options, "i)Y([\-\d\.]+)(p*)", ypos)
 	RegExMatch(Options, "i)W([\-\d\.]+)(p*)", Width)
 	RegExMatch(Options, "i)H([\-\d\.]+)(p*)", Height)
-	RegExMatch(Options, "i)C(?!(entre|enter))([a-f\d]+)", Colour)
+	RegExMatch(Options, "i)C(?!(entre|enter))(0x)?([a-f\d]+)", Colour)
 	RegExMatch(Options, "i)Top|Up|Bottom|Down|vCentre|vCenter", vPos)
 	RegExMatch(Options, "i)NoWrap", NoWrap)
 	RegExMatch(Options, "i)R(\d)", Rendering)
 	RegExMatch(Options, "i)S(\d+)(p*)", Size)
 
-	if !Gdip_DeleteBrush(Gdip_CloneBrush(Colour2))
-		PassBrush := 1, pBrush := Colour2
+	bColour := (Colour2 ? "0x" : "") . (Colour3 ? Colour3 : "ff000000")
+	pBrush := Gdip_DeleteBrush(Gdip_CloneBrush(bColour)) ? Gdip_BrushCreateSolid(bColour) : bColour
 	
 	if !(IWidth && IHeight) && (xpos2 || ypos2 || Width2 || Height2 || Size2)
 		return -1
@@ -1912,8 +1912,6 @@
 	ypos := (ypos1 != "") ? ypos2 ? IHeight*(ypos1/100) : ypos1 : 0
 	Width := Width1 ? Width2 ? IWidth*(Width1/100) : Width1 : IWidth
 	Height := Height1 ? Height2 ? IHeight*(Height1/100) : Height1 : IHeight
-	if !PassBrush
-		Colour := "0x" (Colour2 ? Colour2 : "ff000000")
 	Rendering := ((Rendering1 >= 0) && (Rendering1 <= 5)) ? Rendering1 : 4
 	Size := (Size1 > 0) ? Size2 ? IHeight*(Size1/100) : Size1 : 12
 
@@ -1921,7 +1919,6 @@
 	hFont := Gdip_FontCreate(hFamily, Size, Style)
 	FormatStyle := NoWrap ? 0x4000 | 0x1000 : 0x4000
 	hFormat := Gdip_StringFormatCreate(FormatStyle)
-	pBrush := PassBrush ? pBrush : Gdip_BrushCreateSolid(Colour)
 	if !(hFamily && hFont && hFormat && pBrush && pGraphics)
 		return !pGraphics ? -2 : !hFamily ? -3 : !hFont ? -4 : !hFormat ? -5 : !pBrush ? -6 : 0
    
@@ -1932,16 +1929,14 @@
 
 	if vPos
 	{
-		StringSplit, ReturnRC, ReturnRC, |
-		
 		if (vPos = "vCentre") || (vPos = "vCenter")
-			ypos += (Height-ReturnRC4)//2
+			ypos += (Height-ReturnRC.bottom)//2
 		else if (vPos = "Top") || (vPos = "Up")
 			ypos := 0
 		else if (vPos = "Bottom") || (vPos = "Down")
-			ypos := Height-ReturnRC4
+			ypos := Height-ReturnRC.bottom
 		
-		CreateRectF(RC, xpos, ypos, Width, ReturnRC4)
+		CreateRectF(RC, xpos, ypos, Width, ReturnRC.bottom)
 		ReturnRC := Gdip_MeasureString(pGraphics, Text, hFont, hFormat, RC)
 	}
 
@@ -1993,7 +1988,7 @@
 		DllCall("gdiplus\GdipMeasureString", "uint", pGraphics
 		, "uint", &sString, "int", -1, "uint", hFont, "uint", &RectF, "uint", hFormat, "uint", &RC, "uint*", Chars, "uint*", Lines)
 	}
-	return &RC ? NumGet(RC, 0, "float") "|" NumGet(RC, 4, "float") "|" NumGet(RC, 8, "float") "|" NumGet(RC, 12, "float") "|" Chars "|" Lines : 0
+	return &RC ? Object("left", NumGet(RC, 0, "float"), "top", NumGet(RC, 4, "float"), "right", NumGet(RC, 8, "float"), "bottom", NumGet(RC, 12, "float"), "Chars", Chars, "Lines", Lines) : 0
 }
 
 ; Near = 0


realre
  • Members
  • 38 posts
  • Last active: Aug 24 2016 01:14 PM
  • Joined: 10 Jul 2011
for some case, how the GDI capture screen in the background, save to a file, and read the color in that file (run in background), is that possible?

nimda
  • Members
  • 4368 posts
  • Last active: Aug 09 2015 02:36 AM
  • Joined: 26 Dec 2010

for some case, how the GDI capture screen in the background, save to a file, and read the color in that file (run in background), is that possible?

Gdip_BitmapFromScreen()
Gdip_SaveBitmapToFile()
Gdip_GetPixel()

tic
  • Members
  • 1934 posts
  • Last active: May 30 2018 08:13 PM
  • Joined: 22 Apr 2007
Thanks nion....I had intended to make the change to Gdip_TextToGraphics but didn't get round to it, so will add it to the next release shortly.

Yeh I do like the idea of using objects in functions as it means you don't need to declare loads of variables and you can pass back a single object rather than stringsplitting, but this would need to be a separate AHK_L fork so can't include it just yet.

realre
  • Members
  • 38 posts
  • Last active: Aug 24 2016 01:14 PM
  • Joined: 10 Jul 2011

for some case, how the GDI capture screen in the background, save to a file, and read the color in that file (run in background), is that possible?

Gdip_BitmapFromScreen()
Gdip_SaveBitmapToFile()
Gdip_GetPixel()


thats great!! any example code, like this:
get bmp>save to file>get pixel/picture in specified rectangle/coord>then click in specified coord>delete the bmp>back to get bmp

i try to get pixel ingame but test always give me 0x0 result so maybe this can solved my prob.
this is my old script from my ask for help thread http://www.autohotke...ht=pixel search



f8::Suspend 
$F12:: 
SoundPlay, %A_WinDir%\Media\Windows XP Error.wav 

CoordMode, ToolTip, Screen 
CoordMode, Pixel, Screen 
CoordMode, Mouse, Screen 

Color1 = 0xB98718
Color2 = 0xFA4F95
Color3 = 0xF5DA00


Loop 
   { 
PixelSearch, Px1,Py1, 306,184, 788,406, %Color1%, 5, fast, RGB  
PixelSearch, Px2,Py2, 306,184, 788,406, %Color2%, 5, fast, RGB 
PixelSearch, Px3,Py3, 306,184, 788,406, %Color3%, 5, fast, RGB 

if %Color1% 
      
      MsgBox, you found 1            
      
if %Color2% 
      
      MsgBox, you found 2 
      
if %Color3% 
      
      MsgBox, you found 3 
      
      else 
         return
   } 


f11:: 
Pause 
$f9::Suspend

so where about to put the code and forget about search pixel ingame, lets do it in the background,put gdi+ get pixel coord from bmp and back to game click it. im new to AHK, sorry if can learn fast. :?

Leef_me
  • Moderators
  • 8510 posts
  • Last active: Sep 10 2015 05:50 AM
  • Joined: 08 Apr 2009
I'm curious if it is possible with GDIP to perform a specfic function similar to what Paint can do.

It is possible in Paint, given well-defined solid color areas, to "fill" solid areas with a replacement color.

Can GDIP do this?

I found this function, but I have no idea how to use it.
The ExtFloodFill function fills an area of the display surface with the current brush.
<!-- m -->http://msdn.microsof... ... 09(v=vs.85<!-- m -->).aspx


My purpose is to use the image searching and pixel color detecting of AHK on an image like this.

Posted Image

nimda
  • Members
  • 4368 posts
  • Last active: Aug 09 2015 02:36 AM
  • Joined: 26 Dec 2010
ExtFloodFill(hDC, XStart, YStart, Color, FillType=0){
	/* ExtFloodFill wrapper by nimda

	Fills an area with the current brush

	Filltypes:
	FloodFillBorder  = 0
	FloodFillSurface = 1
	

	Per MSDN [ http://msdn.microsoft.com/en-us/library/dd162709 ]:
	If the fuFillType parameter is FLOODFILLBORDER, the system assumes that
	the area to be filled is completely bounded by the color specified by
	the crColor parameter. The function begins filling at the point specified
	by the nXStart and nYStart parameters and continues in all directions
	until it reaches the boundary.

	If fuFillType is FLOODFILLSURFACE, the system assumes that the area to
	be filled is a single color. The function begins to fill the area at the
	point specified by nXStart and nYStart and continues in all directions,
	filling all adjacent regions containing the color specified by crColor.
	*/
	
	return DllCall( "GDI32\ExtFloodFill", (A_PtrSize ? "UPtr" : "UInt"), hDC
		 , int, XStart, int, YStart, UInt, Color ; color is in ARGB form
		 , UInt, FillType, "int" )
}
While I'm pretty sure I wrapped it correctly, it keeps failing on me when I use this code:
CoordMode, Mouse
CoordMode, Pixel
KeyWait, LButton, D
MouseGetPos, X, Y
PixelGetColor, color, X, Y
Color |= 0xFF000000

up := (A_PtrSize ? "UPtr" : "UInt")

hDC := DllCall("GetDC", up, 0, up)
hBrushRed := DllCall("CreateSolidBrush", UInt, 0xFFFF0000, up)
DllCall("SelectObject", up, hDC, up, hBrushRed, up)
r := ExtFloodFill(hDC, X, Y, Color, 0)
DllCall("DeleteObject", up, hBrushRed, "int")
DllCall("ReleaseDC", up, 0, up, hDC, "int")

MsgBox % r
:?

teadrinker
  • Members
  • 11 posts
  • Last active: Feb 24 2019 02:57 PM
  • Joined: 21 Nov 2010
Hi, tic!
How can I get such effect via GDI+?
Posted Image