Jump to content

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

Achieve Rainmeter-style gui via gdip library?


  • Please log in to reply
15 replies to this topic
njciancio
  • Members
  • 141 posts
  • Last active: Sep 14 2014 06:31 PM
  • Joined: 31 May 2012

I would like to achieve a Rainmeter-style gui. I have been looking at gdip to achieve this, particularly the Gdip main thread - Example 8, which shows how to draw text onto the gdip gui. I've searched around to see what the best approach will be, to no effect - I've been getting mixed messages.

 

Essentially I'm trying to replicate this:

47U585i.png

 

Simply, a nice-looking GUI with transparency, and draggable. Sits on the desktop, on the bottom of other windows, and you can click the links.

  • each text item must be clickable
  • the GUI must be draggable
  • the 'foreground/background' window position of the GUI must be precisely controlled

I played around - In order to allow the dragging of the window as well as clickable links, I tried to create a couple windows with gdip as in Example 8, and then set one (displaying text and transparent bg) as a child of the other (displaying a square shape with rounded corners, to serve as the grey background), via Gui, 2: +Parent%Gui1Id%. That way, each window could have its own 'click()' function and treat a mouse click differently, but that failed completely. I don't really have any code to post, I just added a couple lines to the example, and I have no idea if this is even close to the correct approach.

 

Can anyone point me in the right direction here? Has anyone written similar code? Is it possible to use regular controls for this? Will I need to have child/parent windows? What's going to be involved here?


LiveRegExTester - an ahk RegEx testing tool with live result highlighting


Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006

Windows with standard controls can only have the type of transparency allowed by WinSet Transparent/TransColor.  This only works with top-level windows, so using +Parent will cause the child to have the same properties as the parent.  For smooth alpha blending, you need to render an image (e.g. draw some text and lines) into a GDI bitmap and pass it to UpdateLayeredWindow.  This is a GDI (not GDI+) function, but I think it is defined in Gdip.ahk anyway.  It is possible to use GDI+ to draw onto a GDI bitmap.

 

You can search the forum for "UpdateLayeredWindow", or check out my example from 2007, which apparently still works.  I learnt the technique from a CodeProject article.  There are probably better examples around that use Gdip.ahk.



njciancio
  • Members
  • 141 posts
  • Last active: Sep 14 2014 06:31 PM
  • Joined: 31 May 2012

Thanks for the advice Lexikos. I saw your example while searching, but I guess I wasn't really sure what I was looking for. I'm going to see if I can apply this to my task. Cheers!


LiveRegExTester - an ahk RegEx testing tool with live result highlighting


njciancio
  • Members
  • 141 posts
  • Last active: Sep 14 2014 06:31 PM
  • Joined: 31 May 2012

After poking around with this some more, I've realized that your suggestion to use UpdateLayeredWindow, as in your example, is precisely what's being done in tic's GDI+ Tutorial 8 (code below), which was what I was looking at before asking for help.  While I have an example of drawing text onto the layered window, which allows me to closely replicate the Rainmeter example pictured above, my issue is then how to treat the text differently than the background when it is hovered over or clicked by the mouse. When the background is clicked, the window must be dragged. When the text hovered or clicked, I'll need to run some code such as underlining the text or opening a URL in the default browser.

 

My first thought is to simply add code to the WM_LBUTTONDOWN() function which tracks the position of the mouse and then triggers different behaviours based on the position of the pointer (eg. If the text is at x50,y50 to x100,y100, and the mousepos falls in this range at the time of the click, then run some URL, otherwise PostMessage, 0xA1, 2).

 

Are you aware of a better way to achieve this effect? I fear my proposed solution will be cumbersome when there a simple way to refer mouseclicks to either the background or the text.

 

 tic's GDI+ Tutorial 8:

; gdi+ ahk tutorial 8 written by tic (Tariq Porter)
#SingleInstance, Force
#NoEnv
SetBatchLines, -1
If !pToken := Gdip_Startup()
   ExitApp
OnExit, Exit
width:=300, height:=150
Gui, 1: -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs
Gui, 1: Show, NA
hwnd1 := WinExist()
hbm := CreateDIBSection(Width, Height)
hdc := CreateCompatibleDC()
obm := SelectObject(hdc, hbm)
G := Gdip_GraphicsFromHDC(hdc)
Gdip_SetSmoothingMode(G, 4)
pBrush := Gdip_BrushCreateSolid(0xaa000000)
Gdip_FillRoundedRectangle(G, pBrush, 0, 0, Width, Height, 20)
Gdip_DeleteBrush(pBrush)
Font = Arial
If !Gdip_FontFamilyCreate(Font)
   ExitApp
Options = x10p y30p w80p Centre cbbffffff r4 s20 Underline Italic
Gdip_TextToGraphics(G, "Tutorial 8`n`nThank you for trying this example", Options, Font, Width, Height)
UpdateLayeredWindow(hwnd1, hdc, (A_ScreenWidth-Width)//2, (A_ScreenHeight-Height)//2, Width, Height)
OnMessage(0x201, "WM_LBUTTONDOWN")
SelectObject(hdc, obm)
DeleteObject(hbm)
DeleteDC(hdc)
Gdip_DeleteGraphics(G)
Return 
;#######################################################################
WM_LBUTTONDOWN()
{
   PostMessage, 0xA1, 2
}
;#######################################################################
esc::
Exit:
Gdip_Shutdown(pToken)
ExitApp
Return

LiveRegExTester - an ahk RegEx testing tool with live result highlighting


Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006

You might be able to "hit test" by retrieving the colour of the pixel under the mouse.  If you remove these three lines...

SelectObject(hdc, obm)
DeleteObject(hbm)
DeleteDC(hdc)

...you can use GetPixel to retrieve a specific pixel from the bitmap.

clr := DllCall("GetPixel", "ptr", hdc, "int", x, "int", y, "uint")

Co-ordinates are relative to the top-left of the window (i.e. the top-left of the bitmap).

 

If you used PixelGetColor, the result would depend on what's behind the window.



njciancio
  • Members
  • 141 posts
  • Last active: Sep 14 2014 06:31 PM
  • Joined: 31 May 2012

That will be quite useful in some cases - Perhaps not for text, since I will prefer not to make the user click precisely on a letter of the text, and because different text items will need to be differentiated anyway. Thanks for clarifying all of this... you've probably saved me hours of grief. I'll start coding a couple methods to match  mouse positions to text positions. I began doing this yesterday, but, as I am writing all of this into a class, I ran into the issue of passing text position information to the function or method called by OnMessage(), as posited in my other post you answered. I suppose, if I reject the hardcoding the text positions I may have to get a bit complex with global variables. Cheers!


LiveRegExTester - an ahk RegEx testing tool with live result highlighting


just me
  • Members
  • 1496 posts
  • Last active: Nov 03 2015 04:32 PM
  • Joined: 28 May 2011

Not equal, but coming close:

 

#NoEnv
SetBatchLines, -1
Gui, +LastFound
WinSet, Transparent, 180
Gui, Color, 808080
Gui, Margin, 0, 0
Gui, Font, s11 cD0D0D0 Bold
Gui, Add, Progress, x-1 y-1 w212 h31 Background404040 Disabled hwndHPROG
Control, ExStyle, -0x20000, , ahk_id %HPROG% ; probably only needed on Win XP
Gui, Add, Text, x0 y0 w210 h30 BackgroundTrans Center 0x200 gGuiMove vCaption, LIFEHACKER
Gui, Font, s8 Underline
Gui, Add, Text, x7 y+10 w196 r1 +0x4000 vTX1 gGuiClicked, Internet Explorer 10 Now Available
Gui, Add, Text, x7 y+10 w196 r1 +0x4000 vTX2 gGuiClicked, Google+ Adds Sign-In, Allowing Things
Gui, Add, Text, x7 y+10 w196 r1 +0x4000 vTX3 gGuiClicked, Internet Explorer 10 Now Available
Gui, Add, Text, x7 y+10 w196 r1 +0x4000 vTX4 gGuiClicked, Internet Explorer 10 Now Available
Gui, Add, Text, x7 y+10 w196 r1 +0x4000 vTX5 gGuiClicked, Internet Explorer 10 Now Available
Gui, Add, Text, x7 y+10 w196 r1 +0x4000 vTX6 gGuiClicked, Internet Explorer 10 Now Available
Gui, Add, Text, x7 y+10 w196 h5 vP
GuiControlGet, P, Pos
H := PY + PH
Gui, -Caption
WinSet, Region, 0-0 w210 h%H% r6-6
Gui, Show, w210 NA
WinSet, Bottom
Return
Esc::
GuiClose:
ExitApp
GuiMove:
   PostMessage, 0xA1, 2
Return
GuiClicked:
   MsgBox, 0, Clicked!, Click on %A_GuiControl%!
Return

Prefer ahkscript.org for the time being.


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

I have an example that I've used if you find it helpful

 

http://pastebin.com/enTaAD60



flyingDman
  • Spam Officer
  • 2186 posts
  • Last active: Nov 07 2015 08:15 AM
  • Joined: 27 Feb 2009

@just me: good job, I removed the WinSet, Bottom. Any specific reason why you want to send to the bottom?


Marine Corps Gen. Joseph Dunford told senators at his Joint Chiefs of Staff confirmation hearing : “If you want to talk about a nation that could pose an existential threat to the United States, I'd have to point to Russia. And if you look at their behavior, it's nothing short of alarming.”


just me
  • Members
  • 1496 posts
  • Last active: Nov 03 2015 04:32 PM
  • Joined: 28 May 2011

@just me: good job, I removed the WinSet, Bottom. Any specific reason why you want to send to the bottom?

 

Sits on the desktop, on the bottom of other windows, ...


Prefer ahkscript.org for the time being.


njciancio
  • Members
  • 141 posts
  • Last active: Sep 14 2014 06:31 PM
  • Joined: 31 May 2012

Very nice examples! just me's looks almost identical to the rainmeter example pictured above. Tic's will bold text as the mouse hovers over a link. You guys have made it tough to move forward... what is one to do? Continue coding with gdip (as tic), or change course to use just me's very simple ahk-familiar method?

In order -  just me, tic, and what I've coded thusfar:

 

3WFpiR9.pngrTuQ3FA.pngMhqfTIW.png


LiveRegExTester - an ahk RegEx testing tool with live result highlighting


njciancio
  • Members
  • 141 posts
  • Last active: Sep 14 2014 06:31 PM
  • Joined: 31 May 2012

just me - how is it that your example is cutting off the text that is too long and appending an elipse ( ... ) for display? I don't see any code in your example that I would use for this task - how is it being done? I'm always blown away when things are done with 1/3 of the lines I would have used.


LiveRegExTester - an ahk RegEx testing tool with live result highlighting


just me
  • Members
  • 1496 posts
  • Last active: Nov 03 2015 04:32 PM
  • Joined: 28 May 2011

SS_ENDELLIPSIS   :=   0x4000


Prefer ahkscript.org for the time being.


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

Mine is just an example. You can obviously do much fancier things with the gdi+ library and have animations and effects, antialiasing of corners so they are actually rounded etc.

If you aren't as concerned with these things then you could just use inbuilt methods.



njciancio
  • Members
  • 141 posts
  • Last active: Sep 14 2014 06:31 PM
  • Joined: 31 May 2012

I've built on just me's example - the complexity of my application, assuming I use it for scraping data found in places other than RSS/Atom feeds, ought to remain in the scraping and not the display. I'll post my work soon. Thanks for the help everyone!


LiveRegExTester - an ahk RegEx testing tool with live result highlighting