Jump to content

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

[examples+minituts] The GDI+ Examplecodes thread


  • Please log in to reply
19 replies to this topic
derRaphael
  • Members
  • 872 posts
  • Last active: Mar 19 2013 04:42 PM
  • Joined: 23 Nov 2007
Thx, Chronos for that script.

toc's up to date.

All scripts, unless otherwise noted, are hereby released under CC-BY

Smurth
  • Members
  • 120 posts
  • Last active: Feb 23 2014 09:58 PM
  • Joined: 13 Dec 2006
Layered Taskbar and StartMenu

Screenshot and blabla: http://thesmurth.dev...tMenu-104058008

includes:
readini.ahk
gdip.ahk

SMU-Man.exe:
#NoEnv
#KeyHistory 0
#SingleInstance force
SetWorkingDir %A_ScriptDir%
SetBatchLines,-1
OnExit, Quit

	inifile = %1%

	ReadIni(inifile)

	Menu, Tray, NoStandard
	Menu, Tray, Add, %DlgAutoStart%, AutoStart
	Menu, Tray, Add, %DlgQuit%, Quit
	; Menu, Tray, Icon, icon.ico, , 1
	Menu, Tray, Tip, SMU-D Manager
	RegRead,	AutoStart, HKEY_CURRENT_USER, Software\Microsoft\Windows\CurrentVersion\Run, SMUDaemon
	if AutoStart
		Menu, Tray,Check, %DlgAutoStart%

	pToken := Gdip_Startup()

	TaskbarCreate()
	TaskbarReDraw()

	SetTimer, Main, 100

Return



Main:

	WinSet, Bottom,, ahk_id %TaskbarBgID%
	WinA := WinExist("A")
	if (WinA = WinAl )
		Return
	if (WinA = StartMenuID )
		StartMenuReDraw()
	ifWinNotExist, Ahk_id %TaskbarID%
	{
		TaskbarCreate()
		TaskbarReDraw()
	}

	WinAl := WinA

Return



TaskbarCreate()
{
Global TaskbarID
	, TaskbarBgID
	, StartMenuID
	, StartMenuBgID


	Gui, 1: Destroy
	Gui, 2: Destroy
	WinWait, ahk_class Shell_TrayWnd
	WinGet, TaskbarID, ID
	Gui, 1: -Caption +LastFound +ToolWindow +E0x80020 
	TaskbarBgID := WinExist()
	Gui, 1: Show, NA
	; DllCall("SetParent", "uint", TaskbarBgID, "uint", WinExist("ahk_class Progman") )
	
	Gui, 2: -Caption +LastFound +ToolWindow +E0x80020 +AlwaysOnTop
	StartMenuBgID := WinExist()
	DetectHiddenWindows, On
	StartMenuID := WinExist("ahk_class DV2ControlHost")
	DetectHiddenWindows, Off
	; Control, %TaskbarQuickLaunch%,, ToolbarWindow323, ahk_class Shell_TrayWnd
	; Control, %TaskbarTasks%,, ReBarWindow321, ahk_class Shell_TrayWnd
	; Control, %TaskbarClock%,, TrayClockWClass1, ahk_class Shell_TrayWnd
	; Control, %TaskbarStartButton%,, Button1, ahk_class Shell_TrayWnd

}



TaskbarReDraw()
{
Global TaskbarID
	, TaskbarBgID
	, TaskbarTransColor
	, TaskbarBack
	, TaskbarFront
	, TaskbarStyle
	, TaskbarBorder
	, TaskbarBlur


	WinGetPos, x, y, w, h, ahk_id %TaskbarID%
	WinSet, Transcolor, %TaskbarTransColor%, ahk_id %TaskbarID%

	hbm := CreateDIBSection(w, h)
	hdc := CreateCompatibleDC()
	obm := SelectObject(hdc, hbm)
	G := Gdip_GraphicsFromHDC(hdc)

	if TaskbarBlur {
		pBitmap := Gdip_BitmapFromScreen(x . "|" . y . "|" . w . "|" . h+TaskbarBlur )
		Gdip_BlurBitmap(pBitmap, TaskbarBlur)
		Gdip_DrawImage(G, pBitmap, 0, 0, w, h, 0, 0, w, h)
	}
	pBrush := Gdip_BrushCreateHatch(TaskbarFront, TaskbarBack, TaskbarStyle)
	Gdip_FillRectangle(G, pBrush, 0, 0, w, h)
	Gdip_DeleteBrush(pBrush)
	if TaskbarBorder {

		if y
			y2 := 0
		else
			y2 := h-1

		pPen := Gdip_CreatePen( TaskbarBorder, 0 )
		Gdip_DrawRectangle( G, pPen, 0, y2, w, 1)
		Gdip_DeletePen(pPen)
	}

	UpdateLayeredWindow(TaskbarBgID, hdc, 0, y, w, h)

	SelectObject(hdc, obm)
	DeleteObject(hbm)
	DeleteDC(hdc)
	Gdip_DeleteGraphics(G)
	Gdip_DisposeImage(pBitmap)

}



StartMenuReDraw()
{
Global StartMenuID
	, StartMenuBgID
	, StartMenuTransColor
	, StartMenuBack1
	, StartMenuBack2
	, StartMenuFront1
	, StartMenuFront2
	, StartMenuStyle1
	, StartMenuStyle2
	, StartMenuBorder1
	, StartMenuBorder1Sick
	, StartMenuBorder2
	, StartMenuBorder2Sick
	, StartMenuBorder2Radius
	, StartMenuBlur
	, StartMenuPane
	, StartMenuTransColor

	WinSet, Transcolor, %StartMenuTransColor%, ahk_id %StartMenuID%

	WinGetPos, x, y, w, h, ahk_id %StartMenuID%
	hbm := CreateDIBSection(w, h)
	hdc := CreateCompatibleDC()
	obm := SelectObject(hdc, hbm)
	G := Gdip_GraphicsFromHDC(hdc)
	Gdip_SetSmoothingMode(G, 4)

	if StartMenuBlur {
		pBitmap := Gdip_BitmapFromScreen(x . "|" . y . "|" . w . "|" . h)
		Gdip_BlurBitmap(pBitmap, StartMenuBlur)
		Gdip_DrawImage(G, pBitmap, 0, 0, w, h, 0, 0, w, h)
	}
	pBrush := Gdip_BrushCreateHatch( StartMenuFront1, StartMenuBack1, StartMenuStyle1)
	Gdip_FillRectangle(G, pBrush, 0, 0, w, h)
	Gdip_DeleteBrush(pBrush)

	if StartMenuBorder1 {
		pPen := Gdip_CreatePen( StartMenuBorder1, StartMenuBorder1Sick )
		Gdip_DrawRectangle( G, pPen, 0, 0, w-1, h-1)
		Gdip_DeletePen(pPen)
	}

	StringSplit, s, StartMenuPane, `,
	s3 := w-s3-s1
	s4 := h-s4-s2
	r := StartMenuBorder2Radius

	Gdip_DrawImage(G, pBitmap, s1+r/4, s2+r/4, s3-r/2, s4-r/2, s1+r/4, s2+r/4, s3-r/2, s4-r/2)
	pBrush := Gdip_BrushCreateHatch( StartMenuFront2, StartMenuBack2, StartMenuStyle2)
	Gdip_FillRoundedRectangle(G, pBrush, s1, s2, s3, s4, r)
	Gdip_DeleteBrush(pBrush)
	if StartMenuBorder2 {
		pPen := Gdip_CreatePen( StartMenuBorder2, StartMenuBorder2Sick )
		Gdip_DrawRoundedRectangle( G, pPen, s1, s2, s3, s4, StartMenuBorder2Radius)
		Gdip_DeletePen(pPen)
	}
	UpdateLayeredWindow(StartMenuBgID, hdc, x, y, w, h)
	Gui, 2: Show, X%x% Y%y% W%w% H%h% NoActivate
	SelectObject(hdc, obm)
	DeleteObject(hbm)
	DeleteDC(hdc)
	Gdip_DeleteGraphics(G)
	Gdip_DisposeImage(pBitmap)
	WinWaitClose, ahk_id %StartMenuID%
	Gui, 2: Hide

}



Quit:

	Gdip_Shutdown(pToken)
	DetectHiddenWindows, On
	WinSet, Transcolor, Off, ahk_class Shell_TrayWnd
	WinSet, Transparent, Off, ahk_class Shell_TrayWnd
	WinSet, Transcolor, Off, ahk_class DV2ControlHost
	WinSet, Transparent, Off, ahk_class DV2ControlHost
	ExitApp

Return



AutoStart:

	Menu, Tray, ToggleCheck, %DlgAutoStart%
	if AutoStart {
		AutoStart :=
		RegDelete, HKEY_CURRENT_USER, Software\Microsoft\Windows\CurrentVersion\Run, SMUDaemon
	}
	else {
		AutoStart := true
		RegWrite, REG_SZ, HKEY_CURRENT_USER, Software\Microsoft\Windows\CurrentVersion\Run, SMUDaemon, "%A_ScriptFullPath%"
	}

Return




#Include, %A_ScriptDir%\Gdip.ahk
#Include, %A_ScriptDir%\readini.ahk





^#R::

	ReadIni(inifile)
	TaskbarRedraw()

Return

SMU-Man.ini:
[Taskbar]
TransColor=454647 144
Back=0x80000000
Front=0x80000000
Style=19
Border=0x80202020
Blur=4

[StartMenu]
TransColor=454647 192
Pane=4,5,5,36
Back1=0xF0000000
Front1=0xF0202020
Style1=2
Back2=0xA0202020
Front2=0x80000000
Style2=2
Border1=0x80000000
Border1Sick=2
Border2=0xC0202020
Border2Sick=2
Border2Radius=3
Blur=6

[Dlg]
AutoStart=Start with Windows
Quit=Quit


Krogdor
  • Members
  • 1391 posts
  • Last active: Jun 08 2011 05:31 AM
  • Joined: 18 Apr 2008

Layered Taskbar and StartMenu


Impressive. I would definitely use it if I wasn't using ObjectDock to replace the task bar.

Smurth
  • Members
  • 120 posts
  • Last active: Feb 23 2014 09:58 PM
  • Joined: 13 Dec 2006

Impressive. I would definitely use it if I wasn't using ObjectDock to replace the task bar.


Not so impressive, in fact. It works (most of the time) but it's tricky; very tricky.

derRaphael
  • Members
  • 872 posts
  • Last active: Mar 19 2013 04:42 PM
  • Joined: 23 Nov 2007
Layered GDIP usage without GUI commands

below is a lil example based on my clock code, which generates its own GUI and registers therefor a new window class named GDIP_canvas (can be seen with window spy). since i found the use of GUI commands to add a GDIP layer quite confusing this solution was only the next logical step

The neccessary functions are at the bottom of the code - the initialisation has to be modified a little bit to match the needs of GDIP init.

Posted Image

; gdi+ ahk analogue clock example written by derRaphael

#SingleInstance, Force
#NoEnv
SetBatchLines, -1

; Uncomment if Gdip.ahk is not in your standard library
;#Include, Gdip.ahk

If !(pToken := Gdip_Startup()) {
	MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
	ExitApp
} else {
	GDIP_RegisterClass()
	hwnd1 := GDIP_CreateWindow()
}
OnExit, Exit

SysGet, MonitorPrimary, MonitorPrimary
SysGet, WA, MonitorWorkArea, %MonitorPrimary%
WAWidth := WARight-WALeft
WAHeight := WABottom-WATop

ClockDiameter := 180
Width := Height := ClockDiameter + 2         ; make width and height slightly bigger to avoid cut away edges
CenterX := CenterY := floor(ClockDiameter/2) ; Center x

cBaseColor := "ff8000"  ; Hex of our Clock's Color
cSecHColor := "800000"  ; Hex of Second Hand
cPassColor := "00ff00"  ; Hex of Pie's passed Color

; Dont change unless u know what u're doin ;)
cAlpha_0   := "0xff", cAlpha_1   := "0xc0", cAlpha_2   := "0x66"
cAlpha_3   := "0x80", cAlpha_4   := "0xa0"

; Prepare our pGraphic so we have a 'canvas' to work upon
	hbm := CreateDIBSection(Width, Height), hdc := CreateCompatibleDC()
	obm := SelectObject(hdc, hbm), G := Gdip_GraphicsFromHDC(hdc)
	Gdip_SetSmoothingMode(G, 4)

; Draw outer circle
	Gdip_SetCompositingMode(G, 0)             ; switch off overdraw
	Diameter := ClockDiameter
	pBrush := Gdip_BrushCreateSolid(cAlpha_2 cBaseColor)
	Gdip_FillEllipse(G, pBrush, CenterX-(Diameter//2), CenterY-(Diameter//2),Diameter, Diameter)
	Gdip_DeleteBrush(pBrush)

; Draw inner circle
	Diameter := ceil(ClockDiameter - ClockDiameter*0.08)  ; inner circle is 8 % smaller than clock's diameter
	pBrush := Gdip_BrushCreateSolid(cAlpha_3 cBaseColor)
	Gdip_FillEllipse(G, pBrush, CenterX-(Diameter//2), CenterY-(Diameter//2),Diameter, Diameter)
	Gdip_DeleteBrush(pBrush)
	
	; The OnMessage will let us drag the clock
	OnMessage(0x201, "WM_LBUTTONDOWN")
	UpdateLayeredWindow(hwnd1, hdc, WALeft+((WAWidth-Width)//2), WATop+((WAHeight-Height)//2), Width, Height)
	SetTimer, sec, 1000

sec:
; prepare to empty previously drawn stuff
	Gdip_SetSmoothingMode(G, 1)   ; turn off aliasing
	Gdip_SetCompositingMode(G, 1) ; set to overdraw
	
; delete previous graphic and redraw background
	Diameter := ceil(ClockDiameter - ClockDiameter*0.08)  ; inner circle is 8 % smaller than clock's diameter

;~ 	Diameter := ceil(ClockDiameter - ClockDiameter*0.18)  ; 18 % less than clock's outer diameter
	tDiameter := ceil(ClockDiameter*0.04)
	
	; delete whatever has been drawn here
	pBrush := Gdip_BrushCreateSolid(0x00000000) ; fully transparent brush 'eraser'
	Gdip_FillEllipse(G, pBrush, CenterX-(Diameter//2), CenterY-(Diameter//2),Diameter, Diameter)
	Gdip_DeleteBrush(pBrush)
	
	Gdip_SetCompositingMode(G, 0) ; switch off overdraw
	pBrush := Gdip_BrushCreateSolid(cAlpha_2 cBaseColor)
	Gdip_FillEllipse(G, pBrush, CenterX-(Diameter//2), CenterY-(Diameter//2),Diameter, Diameter)
	Gdip_DeleteBrush(pBrush)
	pBrush := Gdip_BrushCreateSolid(cAlpha_3 cBaseColor)
	Gdip_FillEllipse(G, pBrush, CenterX-(Diameter//2), CenterY-(Diameter//2),Diameter, Diameter)
	Gdip_DeleteBrush(pBrush)
	
; If Pie Draw one
	Gdip_SetSmoothingMode(G, 4)   ; turn on antialiasing
	
; Draw HoursHand
	t := A_Hour*360//12 + (A_Min*360//60)//12 +90 
	R1 := ClockDiameter//2-ceil((ClockDiameter//2)*0.5) ; outer position
	R2 := ClockDiameter//2-ceil((ClockDiameter//2)*0.90) ; inner position
	pPen := Gdip_CreatePen(cAlpha_4 cBaseColor, floor((ClockDiameter/100)*3.5))
	Gdip_DrawLine(G, pPen
		, ceil(CenterX - (R2 * Cos(t * Atan(1) * 4 / 180)))
		, ceil(CenterY - (R2 * Sin(t * Atan(1) * 4 / 180)))
		, ceil(CenterX - (R1 * Cos(t * Atan(1) * 4 / 180)))
		, ceil(CenterY - (R1 * Sin(t * Atan(1) * 4 / 180))))
	Gdip_DeletePen(pPen)
	
; Draw MinutesHand
	t := A_Min*360//60+90 
	R1 := ClockDiameter//2-ceil((ClockDiameter//2)*0.25) ; outer position
	R2 := ClockDiameter//2-ceil((ClockDiameter//2)*0.92) ; inner position
	pPen := Gdip_CreatePen(cAlpha_4 cBaseColor, floor((ClockDiameter/100)*2.7))
	Gdip_DrawLine(G, pPen
		, ceil(CenterX - (R2 * Cos(t * Atan(1) * 4 / 180)))
		, ceil(CenterY - (R2 * Sin(t * Atan(1) * 4 / 180)))
		, ceil(CenterX - (R1 * Cos(t * Atan(1) * 4 / 180)))
		, ceil(CenterY - (R1 * Sin(t * Atan(1) * 4 / 180))))
	Gdip_DeletePen(pPen)

; Draw SecondsHand
	t := A_Sec*360//60+90 
	R1 := ClockDiameter//2-ceil((ClockDiameter//2)*0.2) ; outer position
	pPen := Gdip_CreatePen(cAlpha_4 cSecHColor, floor((ClockDiameter/100)*1.2))
	Gdip_DrawLine(G, pPen, CenterX, CenterY
		, round(CenterX - (R1 * Cos(t * Atan(1) * 4 / 180)))
		, round(CenterY - (R1 * Sin(t * Atan(1) * 4 / 180))))
	Gdip_DeletePen(pPen)
	
	pBrush := Gdip_BrushCreateSolid(cAlpha_4 cSecHColor)
	Gdip_FillEllipse(G, pBrush, CenterX-(tDiameter//2), CenterY-(tDiameter//2),tDiameter, tDiameter)
	Gdip_DeleteBrush(pBrush)
	
	Gosub, DrawClockMarks2 ; do the funky seconds mark thingy
	
	UpdateLayeredWindow(hwnd1, hdc) ;, xPos, yPos, ClockDiameter, ClockDiameter)
return

DrawClockMarks:
	Loop, % Items
			Gdip_DrawLine(G, pPen
				, CenterX - ceil(R1 * Cos(((a_index-1)*360//Items) * Atan(1) * 4 / 180))
				, CenterY - ceil(R1 * Sin(((a_index-1)*360//Items) * Atan(1) * 4 / 180))
				, CenterX - ceil(R2 * Cos(((a_index-1)*360//Items) * Atan(1) * 4 / 180))
				, CenterY - ceil(R2 * Sin(((a_index-1)*360//Items) * Atan(1) * 4 / 180)) )
return

DrawClockMarks2:
	R1 := Diameter//2-1-ceil(Diameter//2*0.01) ; outer position
	R2 := Diameter//2-1-ceil(Diameter//2*0.05) ; inner position
	
	loop, 10 ; create neccessary pens for this (customizing alpha)
		pen%A_Index%  := Gdip_CreatePen( (0x19 cBaseColor)+(a_index-1)*0x19000000, floor((ClockDiameter/100)*1.2))
	
	Loop, 10 ; draw 10 passed seconds
		n := 10 - a_index, Gdip_DrawLine(G, pen%n%
				, CenterX - ceil(R1 * Cos((((a_sec+a_index-1)*360//60)+90) * Atan(1) * 4 / 180))
				, CenterY - ceil(R1 * Sin((((a_sec+a_index-1)*360//60)+90) * Atan(1) * 4 / 180))
				, CenterX - ceil(R2 * Cos((((a_sec+a_index-1)*360//60)+90) * Atan(1) * 4 / 180))
				, CenterY - ceil(R2 * Sin((((a_sec+a_index-1)*360//60)+90) * Atan(1) * 4 / 180)) )
	Loop, 10 ; draw 10 next seconds
		Gdip_DrawLine(G, pen%A_index%
				, CenterX - ceil(R1 * Cos((((51+a_sec+a_index-1)*360//60)+90) * Atan(1) * 4 / 180))
				, CenterY - ceil(R1 * Sin((((51+a_sec+a_index-1)*360//60)+90) * Atan(1) * 4 / 180))
				, CenterX - ceil(R2 * Cos((((51+a_sec+a_index-1)*360//60)+90) * Atan(1) * 4 / 180))
				, CenterY - ceil(R2 * Sin((((51+a_sec+a_index-1)*360//60)+90) * Atan(1) * 4 / 180)) )

	Loop,10 ; delete pens
		Gdip_DeletePen(pen%A_Index%)
	
	; redraw hour marks
	R1 := Diameter//2-1                       ; outer position
	R2 := Diameter//2-1-ceil(Diameter//2*0.1) ; inner position
	Items := 12                               ; we have 12 hours
	pPen := Gdip_CreatePen(cAlpha_1 cBaseColor, ceil((ClockDiameter//100)*2.3)) ; 2.3 % of total diameter is our pen width
	GoSub, DrawClockMarks
	Gdip_DeletePen(pPen)

return

WM_LBUTTONDOWN() {
	PostMessage, 0xA1, 2
	return
}

esc::
Exit:
	SelectObject(hdc, obm)
	DeleteObject(hbm)
	DeleteDC(hdc)
	Gdip_DeleteGraphics(G)
	Gdip_Shutdown(pToken)
	ExitApp
Return

^r::reload

; additional GDIP functions, to register a new GDIP Canvas class 
; and work on a GUI which is NOT created by Gui* Commands
; initially written by derRaphael for tic's gdip library on nov 30, 2008
; licensed under the terms of gdip.ahk's license

; Inspiration to this came from this thread:
; 	majkinetor's [tutorial] Creating windows without GUI commands
; 	http://www.autohotkey.com/forum/viewtopic.php?t=22904

GDIP_CreateWindow(lpWindowName="dR's GDIP Canvas") { 
   return DllCall("CreateWindowEx" ; This function actually creates the window and returns its hWnd
      , "uInt",dwExStyle:=0x80088, "Str", lpClassName:="GDIP_Canvas"
	  , "Str", lpWindowName, "uInt", dwStyle:=0x940A0000
      , "Int", x, "Int", y, "Int", nWidth, "Int", nHeight, "uInt", hWndParent
      , "uInt",hMenu, "uInt", hInstance, "uInt", lpParam)
}

GDIP_RegisterClass(){ ; needs to be called only once, so it can register the class
   cName := "GDIP_Canvas", WndProc := RegisterCallback("GDIP_WndProc", "F")
   VarSetCapacity(WndClass, 40, 0)
   NumPut(WndProc, WndClass, 4) ; style / lpfnWndProc
   ; If below is NOT specified, the app must take care of assigning proper IDC_* Cursors
   ; the provoded method assigns standard cursor for the window
   NumPut((hCursor := DllCall( "LoadCursor", "Uint",0, "Int", IDC_ARROW:=32512 )), WndClass , 24)
   NumPut(&cName, WndClass, 36) ; lpszClassName
   return DllCall("RegisterClass", "uint", &WndClass )
}

/*
; Additional WndClass - http://msdn.microsoft.com/en-us/library/ms633576(VS.85).aspx
   NumPut(0, WndClass, 0)   ; style see http://msdn.microsoft.com/en-us/library/ms633574(VS.85).aspx
   NumPut(0, WndClass, 8)   ; cbClsExtra
   NumPut(0, WndClass, 12)  ; cbWndExtra
   NumPut(0, WndClass, 16)  ; hInstance
   NumPut(0, WndClass, 20)  ; hIcon
   NumPut(0, WndClass, 28)  ; hbrBackground (brush background)
   NumPut(0, WndClass, 32)  ; lpszMenuName
*/

; The callback for our new registered class
GDIP_WndProc(hwnd, uMsg, wParam, lParam) { ; This one can handle additional WndMsgs
   if (uMsg=0x111) {
      DllCall("DestroyWindow", "uint", hwnd)
   }
   return, DllCall("DefWindowProc", "uint", hwnd, "uint", umsg, "uint", wParam, "uint", lParam)
}


greets
dR

All scripts, unless otherwise noted, are hereby released under CC-BY