GDI GUI issues

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Therobotmd
Posts: 7
Joined: 06 Jan 2014, 03:50

GDI GUI issues

07 Jan 2014, 01:35

Hello all! First post in the new forum and happy to be making it! A functioning forum is critical to AHK so I'm glad you guys took that step, no matter how hard it was. I see a lot of familiar names around which is reassuring especially because the names I recognize are the ones I've been helped by the most (in general of coarse). I still run tons of the code you guys have created from scratch and want it to be known that the work you guys do and the help you give are, as always, appreciated greatly.

Anywho... my question.

I've been trying to create gui's with GDI for the aesthetics you can achieve but have been struggling to get the results I've been hoping for. I'll try to elaborate properly.

What I am trying to achieve is to draw a transparent image on screen an use it as a traditional gui by overlaying other gdi images and using them as controls. There are a number of ways to try and go about that. I've tried to draw multiple individual layered windows and the appearance is excellent as expected. I can obviously see which control is clicked and pass the events back to the script in an efficient way. The issue with this scenario is not being able to create child windows from a layered window and hence not be able to attach the 'control' guis to the 'background' gui and have them be drag-able as a single object. The z order of windows also obviously would change if you click the 'background'.

The second way I tried to go about it was to follow tic's example of replacing images in an actual picture control using send message. The issues with that are when you try to set the background image AND keep the transparency of thee overlayed 'controls' (picture controls drawn onto by GDI) the z order of the controls goes a little screwy and the controls are sometimes displayed behind the background and the only way I know how to fix the z order is to append WS_CLIPSIBLINGS to the background pictures style BUT that forces the overlayed controls to loose there transparency.

The third option I tried was to use GDI to draw all the controls and background into one bitmap to display on a layered window which solve the aesthetics and moving as well as z order problem but than how can I detect which control the user clicked without having to write an ugly 'if_Click_in_Region' function and try and find the control that way or use a dynamic image search?? Neither of which will operate efficiently enough to allow the rest of the app to function well.

What I am really trying to do is create some generic functions I can use to create a GDI window and use it EFFICIENTY for almost any program I can think of creating, whether it be a network IP scanner or just minimalist app to show some values.

This is one of the many tests I have tried to run to demonstrate what I am trying to achieve so I will post below. You will need to include tic's GDIP.ahk of coarse as well as AHK_L though it could easily be rewritten for basic. I just added the objects for future use and just for practice :). I've been using AHK for a couple of years but only for very basic things as I have a day job. (See username).

apologies to the scripter of odlg(). I can't remember who wrote it to give them credit but it was definitely not me.

If you can 'attach' the control to the 'background' WHILE keeping it draggle and transparent AND notify the script of control events(efficiently) I will love you forever and ever.

Any thoughts on thee below code or other means of achieving the goal?

Code: Select all


;http://www.autohotkey.com/board/topic/29449-gdi-standard-library-145-by-tic/page-1
#SingleInstance, Force
#NoEnv
SetBatchLines, -1
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
OnExit, Exit
;===Prepare menu=======================================================================
Gdip_Startup()

;Gui_Add_BG(ImageName,X="",Y="",H="",W="",S="",Trans="") x,y centered with original image h,w if not specified with no transparancy
Gui_Add_BG("Images\sun.png","","","","","",200)

;GUI_Set_Text_Otions(Options="Centre Bottom cbfffffff r4 s20 Bold Italic",Font="Arial"){
GUI_Set_Text_Otions("Bottom Centre  FFffFFff r4 s12 Bold Italic","Arial")

;Gui_Add_BTN(iPath, iText="",X="",Y="",H="",W="",S="",Trans=""){
Gui_Add_BTN("Images\moon.png","This is the first button","","","","",0.2,220)
OnMessage(0x201,"WM_LUTTONDOWN")	;Allow the Gui to be dragable
Return

WM_LUTTONDOWN(){					;Allow the Gui to be dragable
	PostMessage, 0xA1, 2,,, 
	;PostMessage, 0xA1, 2,,, 99 
}

#Include GDIP.ahk					;http://www.autohotkey.com/board/topic/29449-gdi-standard-library-145-by-tic/page-1


Escape::
Exit:
; gdi+ may now be shutdown on exiting the program
Gdip_Shutdown(pToken)
ExitApp
Return

F2::
Reload
Return

~^RButton:: 
~+RButton::
~!RButton::
~RButton::
~^LButton::
~+LButton::
~!LButton::
~LButton::
EventHandler(cWin(A_ThisHotKey))
Return




EventHandler(o){
	
	global Buttons
	If (o.Class <> "AutoHotKeyGui") or If (o.Title = 99) or If (o.Style <> 0x00080088)	;;If Not AHK Win or if background or if not GDI Layered Window
		Return	
	
	;o.Btn:= Buttons[o.Title]
	
	;handle GUI button event
	;oDlg(o) ;show object
	

	return
}

;Collect current mouse positions window and return object
cWin(Event){
	
	MouseGetPos, X, Y, WinID,CtrlID
	WinGetTitle,   WinTitle, ahk_id %WinID%\
	WinGetClass,   WinClass, %WinTitle%
	WinGet, Style, ExStyle, %WinTitle%
	o:= {}
	o.X:= 		X
	o.Y:= 		Y
	o.WinID:= 	WinID
	o.CtrlID:= 	CtrlID
	o.Title:= 	WinTitle
	o.Class:= 	WinClass
	o.Style:= 	Style
	o.Event:= 	Event
	return o
}
GUI_Set_Text_Otions(Options="Centre Bottom cbfffffff r4 s20 Bold Italic",Font="Arial"){
	
	global Buttons
	
	If !IsObject(Buttons)
		Buttons:={}
	If !IsObject(Buttons.Text)
		Buttons.Text:={}

	Buttons.Text.Options:= Options
	Buttons.Text.Font:= Font
	
	return
}

Gui_Add_BTN(iPath, iText="",X="",Y="",H="",W="",S="",t=""){
	
	global Buttons

	static BtnCount = 0 , Btn
	
    BtnCount += 1  ; Maintain a tally locally (its value is remembered between calls).
	
	If !IsObject(Buttons)
		Buttons:={}
	If !IsObject(Buttons[BtnCount])
		Buttons[BtnCount]:={}
	
	Gui, %BtnCount%: -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs
	Gui, %BtnCount%: Show,, %BtnCount%         
	Buttons[BtnCount].hwnd := WinExist()
	
	pBitmap := Gdip_CreateBitmapFromFile(iPath)
	
	Buttons[BtnCount].iPath  := iPath
	Buttons[BtnCount].ImageS := (S>0) ? S : 1
	Buttons[BtnCount].ImageW := (W>=0) ? W : Gdip_GetImageWidth(pBitmap)  * Buttons[BtnCount].ImageS
	Buttons[BtnCount].ImageH := (H>=0) ? H : Gdip_GetImageHeight(pBitmap) * Buttons[BtnCount].ImageS
	Buttons[BtnCount].ImageX := (X>=0) ? X : Buttons.BG.ImageXC - (Buttons[BtnCount].ImageW // 2)
	Buttons[BtnCount].ImageY := (Y>=0) ? Y : Buttons.BG.ImageYC - (Buttons[BtnCount].ImageH // 2)
	Buttons[BtnCount].ImageXC:= Buttons[BtnCount].ImageX + (Buttons[BtnCount].ImageW//2)
	Buttons[BtnCount].ImageYC:= Buttons[BtnCount].ImageY + (Buttons[BtnCount].ImageH//2)	
	Buttons[BtnCount].ImageT := (T>=0) ? T : 255
	
	
	
	hbm := CreateDIBSection(Buttons[BtnCount].ImageW/Buttons[BtnCount].ImageS, Buttons[BtnCount].ImageH/Buttons[BtnCount].ImageS)
	hdc := CreateCompatibleDC()
	obm := SelectObject(hdc, hbm)
	G := Gdip_GraphicsFromHDC(hdc)
	Gdip_SetInterpolationMode(G, 7)
	Gdip_DrawImage(G, pBitmap, 0, 0,  Buttons[BtnCount].ImageW, Buttons[BtnCount].ImageH, 0, 0,Gdip_GetImageWidth(pBitmap), Gdip_GetImageHeight(pBitmap))
	If iText
	{
		Gdip_SetInterpolationMode(G, 4)
		;Gdip_TextToGraphics(pGraphics, Text, Options, Font="Arial", Width="", Height="", Measure=0)
		Gdip_TextToGraphics(G, iText, Buttons.Text.Options, Buttons.Text.Font, Buttons[BtnCount].ImageW, Buttons[BtnCount].ImageH)
	}	
	UpdateLayeredWindow(Buttons[BtnCount].hwnd, hdc, Buttons[BtnCount].ImageX, Buttons[BtnCount].ImageY, Buttons[BtnCount].ImageW, Buttons[BtnCount].ImageH, Buttons[BtnCount].ImageT)
	
	SelectObject(hdc, obm)
	DeleteObject(hbm)
	DeleteDC(hdc)
	Gdip_DeleteGraphics(G)
	
	 
	return true
}

Gui_Add_BG(iPath,X="",Y="",H="",W="",S="",T=""){
	
	global Buttons
	
	
	If !IsObject(Buttons)
		Buttons:={}
	If !IsObject(Buttons.BG)
		Buttons.BG:={}
	
	Gui, 99: -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs
	Gui, 99: Show,, 99         
	pBitmap := Gdip_CreateBitmapFromFile(iPath)
	;pBitmap2 := Gdip_CreateBitmapFromFile("Images\sun.png")

	Buttons.BG.hwnd := WinExist()
	Buttons.BG.iPath  := iPath
	Buttons.BG.ImageS := (S>0) ? S : 1
	Buttons.BG.ImageW := (W>=0) ? W : Gdip_GetImageWidth(pBitmap)  * Buttons.BG.ImageS
	Buttons.BG.ImageH := (H>=0) ? H : Gdip_GetImageHeight(pBitmap) * Buttons.BG.ImageS
	Buttons.BG.ImageX := (X>=0) ? X : (A_ScreenWidth // 2)  - (Buttons.BG.ImageW // 2)
	Buttons.BG.ImageY := (Y>=0) ? Y : (A_ScreenHeight // 2) - (Buttons.BG.ImageH // 2)
	Buttons.BG.ImageXC:= Buttons.BG.ImageX + (Buttons.BG.ImageW//2)
	Buttons.BG.ImageYC:= Buttons.BG.ImageY + (Buttons.BG.ImageH//2)	
	Buttons.BG.ImageT := (T>=0) ? T : 255
	
	hbm := CreateDIBSection(Buttons.BG.ImageW, Buttons.BG.ImageH)
	hdc := CreateCompatibleDC()
	obm := SelectObject(hdc, hbm)
	G := Gdip_GraphicsFromHDC(hdc)
	Gdip_SetInterpolationMode(G, 7)
	
	Gdip_SaveBitmapToFile(pBitmap, sOutput, Quality=75)
	
	Gdip_DrawImage(G, pBitmap, 0, 0,  Buttons.BG.ImageW, Buttons.BG.ImageH, 0, 0,Gdip_GetImageWidth(pBitmap), Gdip_GetImageHeight(pBitmap))
	;Gdip_DrawImage(G, pBitmap2, 25, 75,  Buttons.BG.ImageW, Buttons.BG.ImageH, 0, 0,Gdip_GetImageWidth(pBitmap), Gdip_GetImageHeight(pBitmap))
	
	
	UpdateLayeredWindow(Buttons.BG.hwnd, hdc, Buttons.BG.ImageX, Buttons.BG.ImageY, Buttons.BG.ImageW, Buttons.BG.ImageH, Buttons.BG.ImageT)
	;WinSet, Disable
	
	SelectObject(hdc, obm)
	DeleteObject(hbm)
	DeleteDC(hdc)
	Gdip_DeleteGraphics(G)
	Gdip_DisposeImage(pBitmap)
	
	Gdip_DisposeImage(pBitmap2)
	return true
}







;	oDlg - Object Dialog - shows a TreeView of an object's contents
oDlg(o, title="Object Dialog", wait=false) {
	gui, oDlg:new,,%title%
	gui, oDlg:+labeloDlg
	gui, add, treeview, w800 r32
	oDlgAdd(o)
	gui, oDlg:Show
	if wait
		WinWaitClose, %title%
}

oDlgAdd(o, p=0, ByRef ancestry="") {
	if !ancestry
		ancestry:=[]
	
	if (isObject(o))
		for k, v in o {
			l:= k (IsObject(v) ? (v.name ? ":" v.name : "") : (":""" v """"))
			circular:= findItem(ancestry, v)
			n:= TV_Add(l (circular ? " (circular)" : ""), p)
			nodeObject[n]:= {k:v}
			if (isObject(v) && !circular) {
				ancestry.insert(v)
				oDlgAdd(v, n, ancestry)
			}
		}
	else
		nodeObject[TV_Add(o, p)]:= o
}

findItem(a, i) {
	for k, v in a
		if (v==i)
			return k
	return false
}



oDlgEscape:
oDlgClose:
gui, oDlg:destroy
return
edit: this would need to work on xp and up

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Billykid, haomingchen1998, Oblomov228 and 265 guests