Jump to content

MetroGUI UDF v5.1 - Windows 10 style buttons, toggles, radios, menu etc.


BBs19
 Share

Recommended Posts

On 10.12.2017 at 2:22 PM, Miliardsto said:

where is effect responsible for slower appearing from toolbar (restoring) .

 

I got 2 guis on program and u know when I restore program from toolbar then metro gui appears slower (with fade effect) than normal gui.

 

I want to assign this effect to second gui or delete this

bump

Edited by Miliardsto
Link to comment
Share on other sites

  • 3 weeks later...

Great UDF, looks nice and runs fast. Sadly the lack of accelerator and tabstop support is a deal breaker, and I've opted to stick with the bare Win32 style of controls.

I did try to implement this myself, however. First I wanted to add accelerator support to the MsgBox. I decided to parse the string for ampersand hint character and manually draw the underline:

;Parse text for ampersand (&) to draw an underline
    Local $iAmpPos = StringInStr($Text, "&")
    If $iAmpPos > 0 Then
        $Text = StringReplace($Text, "&", "")
        Local $iTextSize = _StringSize($Text, $Fontsize, 700, 0, $Font)
        Local $iAccelChar = StringMid($Text, $iAmpPos, 1)
        Local $iAccelCharSize = _StringSize($iAccelChar, $Fontsize, 700, 0, $Font)
        Local $iAccelCharPre = StringLeft($Text, $iAmpPos - 1)
        Local $iAccelCharPreSize = _StringSize($iAccelCharPre, $Fontsize, 700, 0, $Font)
        Local $iAccelCharPixPos = _StringSize($iAccelChar, $Fontsize, 700, 0, $Font)

        Local $iLineStartX = $Width / 2 - $iTextSize[2] / 2 + $iAccelCharPreSize[2] + 1
        Local $iLineEndX = $iLineStartX + $iAccelCharSize[2] - 2
        Local $iLineY = $Height / 2 + $Fontsize / 2 + 1

        Local $Pen_BTN_AccelUnderline = _GDIPlus_PenCreate($FrameColor, 1)
        _GDIPlus_GraphicsDrawLine($Button_Graphic1[0], $iLineStartX, $iLineY, $iLineEndX, $iLineY, $Pen_BTN_AccelUnderline)
        _GDIPlus_GraphicsDrawLine($Button_Graphic1[0], $iLineStartX, $iLineY, $iLineEndX, $iLineY, $Pen_BTN_AccelUnderline)
    EndIf

 

It looked OK, for the most part (I did test it with other characters too, alignment is as best as it could be based on the reported character width/position calcualtion):

RestartShutdownMsg.png

 

This is shown permanently, however. I couldn't figure out how to show the the bitmap as an overlay on the existing one when I wanted (i.e. when ALT is held down), this GDI graphics work is all magic to me.

 

Second, the desire for tabstops was blocked by the same thing. I couldn't figure out how to actually draw the tabstop based on your existing system, since it's all heavily nested in the hover code. The drawing part was fine, I just made a new pen for dotted outline; but actually getting it to draw on the right button on-demand.

 

I'm hopeful that these features can be added one day by someone more skilled than I. Thanks.

Edited by JonusC
Link to comment
Share on other sites

I managed to solve the accelerator/tabstop issue for the moment, but now I've found an outright bug - When enabling or disabling a button, the hovers become unresponsive - if you click on the GUI however they work again. Re-activating the GUI does not solve it.

I traced this cause to the GUICtrlSendMsg function. It's sending a message of code 0x172. I see that you're using raw numbers instead of constants all over the place. Wtf? How is anybody supposed to figure this out?

This is not the first bug I've encountered, either, but the code in this UDF is too difficult to read. I think I'll just go and make my own implementation from scratch.

Edited by JonusC
Link to comment
Share on other sites

On 2.1.2018 at 7:17 PM, CosmicDan said:

I managed to solve the accelerator/tabstop issue for the moment, but now I've found an outright bug - When enabling or disabling a button, the hovers become unresponsive - if you click on the GUI however they work again. Re-activating the GUI does not solve it.

I traced this cause to the GUICtrlSendMsg function. It's sending a message of code 0x172. I see that you're using raw numbers instead of constants all over the place. Wtf? How is anybody supposed to figure this out?

This is not the first bug I've encountered, either, but the code in this UDF is too difficult to read. I think I'll just go and make my own implementation from scratch.

As stated before, im planning on rewriting the UDF to throw out all the unnecessary trash that makes adding new things and fixing problems too difficult. It started out as a simple script for modern buttons with hover effects and grew over time into a huge mess.

However this UDF is currently not on my prio list and I am not sure when I will have the time to finish it.

As @Earthshine stated, there are better solutions for modern apps. Creating everything from scratch is just too time consuming.

Another project I started ended up in a mess with hundreds of workarounds where I spend days trying to make basic things work and all of it just to get a "modern" looking app. It worked out eventually but so much time was wasted that I could have just used to learn other languages :D 

AutoIt seems a bit dead to me, just look at the time it was last updated, no more updates, no new features, no multitasking. ..

Link to comment
Share on other sites

2 hours ago, BBs19 said:

As stated before, im planning on rewriting the UDF to throw out all the unnecessary trash that makes adding new things and fixing problems too difficult. It started out as a simple script for modern buttons with hover effects and grew over time into a huge mess.

However this UDF is currently not on my prio list and I am not sure when I will have the time to finish it.

As @Earthshine stated, there are better solutions for modern apps. Creating everything from scratch is just too time consuming.

Another project I started ended up in a mess with hundreds of workarounds where I spend days trying to make basic things work and all of it just to get a "modern" looking app. It worked out eventually but so much time was wasted that I could have just used to learn other languages :D 

AutoIt seems a bit dead to me, just look at the time it was last updated, no more updates, no new features, no multitasking. ..

Fair enough. I've actually restarted my project from scratch since discovering guinness's "OOP-like approach in AutoIt" concept which is really clever, hopefully it helps keep things neat as the program grows in scale!

[Rant time...]

Yeah, other languages may be better for making "apps", but AutoIt remains very valuable and relevant when you're creating a tool that needs to be "very native", self-contained and reliable but don't have time doing it in C(++). Granted, it's more and more of a niche these days - what with workflows moving more into the cloud and all that stuff - but C#/CLR is still pretty trash when you want to be close to the Win32 API WinAPI. C#/CLR is also much slower than AutoIt in some cases. Or maybe "laggy" is a more accurate description, what with the JIT-compiling VM layer and all.... AutoIt is just FAR less bloated than CLR or Java thanks to it being closer to the metal (just compare the startup time and RAM consumption of a "Hello World" message box between those languages)...

...but yeah, C# or even Java is probably better for an "app". In my case I'm making something that augments the Windows Shell (Explorer) to fill the void since ClassicShell was retired. And it would of been nice to have a modern-looking UI for the configuration screens is all. I've since opted to stick to the native Win32/GDI GUI's though that AutoIt does internally though. Faster and more reliable, anyway.

As for AutoIt being dead, well... just because something hasn't been updated, that doesn't mean it's "dead". This idea people have gotten of software needing regular and constant updates to be considered "alive" is a result of lousy programmers writing lousy code. I suppose it helps that the Win32 API WinAPI is extremely mature, backwards compatible and maintained by some of the best darn software engineers in the world....

There really is no need for new features in AutoIt beyond what UDF's and/or DllCall's can do already. I consider AutoIt as "finished" and "mature" rather than dead. If it can't do something in AutoIt then I could just fire up a C(++) IDE and write a new function from scratch. I've not had a need to yet, though. AutoIt is very suitable for a couple of my projects, the only other alternative would be to do it all from scratch in C(++).

By "multitasking" I assume you mean multithreading...? Because that's perfectly possible right now, you can use pipes and various other IPC methods available in the WinAPI. Works fine. The reason why it never came into AutoIt proper is because it just makes no sense to have multithreading in AutoIt. It's not a game engine, dbms or video encoder... I mean really, even if AutoIt DID have a native and fast asynchronous I/O framework built-in I would have to seriously question any developer who chose AutoIt over another language for a multithreaded app.

Programming languages are like tools, not race cars. There rarely is a "best" language - just some languages being more suitable than others at certain tasks. The fact that the forums here still have some active posts is pretty clear proof that AutoIt isn't dead. Even if it is an old man in a retirement home, it' still alive :D In many cases, C#, Java or any other third-generation/VM language is simply not possible because they all had the design goal of abstracting-away the underlying environment. That kind of thing is great if you want to make an "app" of course, but not if you want to make a "tool" for OS-level tasks.

I will say one thing - it would be really nice if AutoIt was open-sourced. Development has of course been stagnant, and there are some nice QoL suggestions that could be made that'd eliminate the need for UDF's.

[/Rant]

Edited by CosmicDan
Link to comment
Share on other sites

C# is EXTREMELY Fast. All windows come with .net as well

you want OOP? Use a real OOP language 

Autoit is for quick and dirty stuff to me. Not real applications. Too many limitations. 

So you go right ahead and waste your time when you could be getting real stuff done really fast

Metro Forms are WPF XAML forms. It’s child’s play in C#.  You can write the XML yourself or you can do it with a designer

Edited by Earthshine

My resources are limited. You must ask the right questions

 

Link to comment
Share on other sites

9 hours ago, CosmicDan said:

Fair enough. I've actually restarted my project from scratch since discovering guinness's "OOP-like approach in AutoIt" concept which is really clever, hopefully it helps keep things neat as the program grows in scale!

[Rant time...]

Yeah, other languages may be better for making "apps", but AutoIt remains very valuable and relevant when you're creating a tool that needs to be "very native", self-contained and reliable but don't have time doing it in C(++). Granted, it's more and more of a niche these days - what with workflows moving more into the cloud and all that stuff - but C#/CLR is still pretty trash when you want to be close to the Win32 API WinAPI. C#/CLR is also much slower than AutoIt in some cases. Or maybe "laggy" is a more accurate description, what with the JIT-compiling VM layer and all.... AutoIt is just FAR less bloated than CLR or Java thanks to it being closer to the metal (just compare the startup time and RAM consumption of a "Hello World" message box between those languages)...

...but yeah, C# or even Java is probably better for an "app". In my case I'm making something that augments the Windows Shell (Explorer) to fill the void since ClassicShell was retired. And it would of been nice to have a modern-looking UI for the configuration screens is all. I've since opted to stick to the native Win32/GDI GUI's though that AutoIt does internally though. Faster and more reliable, anyway.

As for AutoIt being dead, well... just because something hasn't been updated, that doesn't mean it's "dead". This idea people have gotten of software needing regular and constant updates to be considered "alive" is a result of lousy programmers writing lousy code. I suppose it helps that the Win32 API WinAPI is extremely mature, backwards compatible and maintained by some of the best darn software engineers in the world....

There really is no need for new features in AutoIt beyond what UDF's and/or DllCall's can do already. I consider AutoIt as "finished" and "mature" rather than dead. If it can't do something in AutoIt then I could just fire up a C(++) IDE and write a new function from scratch. I've not had a need to yet, though. AutoIt is very suitable for a couple of my projects, the only other alternative would be to do it all from scratch in C(++).

By "multitasking" I assume you mean multithreading...? Because that's perfectly possible right now, you can use pipes and various other IPC methods available in the WinAPI. Works fine. The reason why it never came into AutoIt proper is because it just makes no sense to have multithreading in AutoIt. It's not a game engine, dbms or video encoder... I mean really, even if AutoIt DID have a native and fast asynchronous I/O framework built-in I would have to seriously question any developer who chose AutoIt over another language for a multithreaded app.

Programming languages are like tools, not race cars. There rarely is a "best" language - just some languages being more suitable than others at certain tasks. The fact that the forums here still have some active posts is pretty clear proof that AutoIt isn't dead. Even if it is an old man in a retirement home, it' still alive :D In many cases, C#, Java or any other third-generation/VM language is simply not possible because they all had the design goal of abstracting-away the underlying environment. That kind of thing is great if you want to make an "app" of course, but not if you want to make a "tool" for OS-level tasks.

I will say one thing - it would be really nice if AutoIt was open-sourced. Development has of course been stagnant, and there are some nice QoL suggestions that could be made that'd eliminate the need for UDF's.

[/Rant]

I disagree in some parts.. AutoIt might be complete/finished for what it was intended for, but it is simply not perfect for big projects due to lack of native OOP and even though there are many workarounds for this, I would still prefer native support.. But this is not something you can blame the developers for, it is their choice and they have reached more than they probably ever intended for AutoIT.

And yes ofc I ment multithreading :lol: Also disagree here. Just because you didn't need multithreading in your projects, doesn't mean that others don't need it. As a simple example: When you do a HTTP request to a server that requires authentication and Windows fires up the "Enter your Pin" message, your script will become completely unresponsive, no matter if you use the asynchronous for the HTTP object or not. Now you would need yet another instance running in order to auto-enter the PIN. And I am sure others would also disagree here, especially those who like playing around with GDI+.

I have not much experience in C# but I usually hear that AutoIt is pretty slow compared to it.

So let's be honest, we are all just using AutoIt because it is pretty easy and allows fast development because there are already so many UDFs :)

Link to comment
Share on other sites

3 hours ago, BBs19 said:

I disagree in some parts.. AutoIt might be complete/finished for what it was intended for, but it is simply not perfect for big projects due to lack of native OOP and even though there are many workarounds for this, I would still prefer native support.. But this is not something you can blame the developers for, it is their choice and they have reached more than they probably ever intended for AutoIT.

And yes ofc I ment multithreading :lol: Also disagree here. Just because you didn't need multithreading in your projects, doesn't mean that others don't need it. As a simple example: When you do a HTTP request to a server that requires authentication and Windows fires up the "Enter your Pin" message, your script will become completely unresponsive, no matter if you use the asynchronous for the HTTP object or not. Now you would need yet another instance running in order to auto-enter the PIN. And I am sure others would also disagree here, especially those who like playing around with GDI+.

I have not much experience in C# but I usually hear that AutoIt is pretty slow compared to it.

So let's be honest, we are all just using AutoIt because it is pretty easy and allows fast development because there are already so many UDFs :)

Yeah, when it comes down to it AutoIt just wasn't designed with these things in mind. That's fair enough.

AutoIt is slow in raw speed, e.g. loops of arithmetic, but it's extremely fast in e.g. GUI's (when designed properly) because it's all actually drawn by the underlying WinAPI.

Some faux-concurrency can be achieved by using event mode (why anybody uses message loop mode is beyond me, it's so much slower and more fragile) but yeah it's far from ideal. Probably wouldn't help with web requests.

I'm using AutoIt because for these kinds of tools the only other choice I have is to re-learn C++ and MFC to do a lot of stuff from scratch in tens of lines that AutoIt can do in one. I'd essentially have to re-write AutoIt from scratch! OOP would be nice, but if I have to trade automatic memory management then nah no thanks lol. But again, if only AutoIt was open source :(

EDIT: I think, actually, I can do what I want with Java + JNA (JNA allows calling the WinAPI). But I am worried about performance, and I like that AutoIt is so self-contained and low memory usage.... *sigh* first-world problems!

Edited by CosmicDan
Link to comment
Share on other sites

BBs19, Do you mind if I'm copying all your code, reuse as much as I find useful, and continues the project as a new example. You'll of course get full credit for your part of the code. I see no reason why such a project cannot be implemented in AutoIt.

Link to comment
Share on other sites

7 hours ago, LarsJ said:

BBs19, Do you mind if I'm copying all your code, reuse as much as I find useful, and continues the project as a new example. You'll of course get full credit for your part of the code. I see no reason why such a project cannot be implemented in AutoIt.

I think that is a great idea. I started this project back in 2014 when I was still learning the basics and it grew bigger every year with all the new features. The time for a complete rewrite is overdue. At least 1/4 of the code can probably be removed easily.

I am sure that you will also be able to easily implement many of the requested features given your previous projects :)  I wish I had the time now to rewrite it with the DllStructs we talked about,  to save you the time of trying to understand it, but I guess that will take some time and might take a few weeks or months depending on my motivation and freetime.

I have attached the latest unfinished version with multiple bug fixes and some new features that I added while working on another project. Let me know if you need anything.

MetroGUI-UDF.zip

Edited by BBs19
Link to comment
Share on other sites

Double draw close button.

Untitled3.png

;Create Close Button==========================================================================================================
    If $ButtonsToCreate_Array[0] Then
        If $CloseButtonOnStyle Then
            _GDIPlus_GraphicsDrawLine($Button_Close_Graphic1[0], 17 * $cbDPI, 9 * $cbDPI, 27 * $cbDPI, 19 * $cbDPI, $hPen3)
            _GDIPlus_GraphicsDrawLine($Button_Close_Graphic1[0], 17 * $cbDPI, 9 * $cbDPI, 27 * $cbDPI, 19 * $cbDPI, $hPen3)
            
            _GDIPlus_GraphicsDrawLine($Button_Close_Graphic1[0], 27 * $cbDPI, 9 * $cbDPI, 17 * $cbDPI, 19 * $cbDPI, $hPen3)
            _GDIPlus_GraphicsDrawLine($Button_Close_Graphic1[0], 27 * $cbDPI, 9 * $cbDPI, 17 * $cbDPI, 19 * $cbDPI, $hPen3)
            
            _GDIPlus_GraphicsDrawLine($Button_Close_Graphic3[0], 17 * $cbDPI, 9 * $cbDPI, 27 * $cbDPI, 19 * $cbDPI, $hPen5)
            _GDIPlus_GraphicsDrawLine($Button_Close_Graphic3[0], 17 * $cbDPI, 9 * $cbDPI, 27 * $cbDPI, 19 * $cbDPI, $hPen5)
            
            _GDIPlus_GraphicsDrawLine($Button_Close_Graphic3[0], 27 * $cbDPI, 9 * $cbDPI, 17 * $cbDPI, 19 * $cbDPI, $hPen5)
            _GDIPlus_GraphicsDrawLine($Button_Close_Graphic3[0], 27 * $cbDPI, 9 * $cbDPI, 17 * $cbDPI, 19 * $cbDPI, $hPen5)
        Else
            _GDIPlus_GraphicsDrawLine($Button_Close_Graphic1[0], 17 * $cbDPI, 9 * $cbDPI, 27 * $cbDPI, 19 * $cbDPI, $hPen)
            _GDIPlus_GraphicsDrawLine($Button_Close_Graphic1[0], 17 * $cbDPI, 9 * $cbDPI, 27 * $cbDPI, 19 * $cbDPI, $hPen)
            
            _GDIPlus_GraphicsDrawLine($Button_Close_Graphic1[0], 27 * $cbDPI, 9 * $cbDPI, 17 * $cbDPI, 19 * $cbDPI, $hPen)
            _GDIPlus_GraphicsDrawLine($Button_Close_Graphic1[0], 27 * $cbDPI, 9 * $cbDPI, 17 * $cbDPI, 19 * $cbDPI, $hPen)
            
            _GDIPlus_GraphicsDrawLine($Button_Close_Graphic3[0], 17 * $cbDPI, 9 * $cbDPI, 27 * $cbDPI, 19 * $cbDPI, $hPen4)
            _GDIPlus_GraphicsDrawLine($Button_Close_Graphic3[0], 17 * $cbDPI, 9 * $cbDPI, 27 * $cbDPI, 19 * $cbDPI, $hPen4)
            
            _GDIPlus_GraphicsDrawLine($Button_Close_Graphic3[0], 27 * $cbDPI, 9 * $cbDPI, 17 * $cbDPI, 19 * $cbDPI, $hPen4)
            _GDIPlus_GraphicsDrawLine($Button_Close_Graphic3[0], 27 * $cbDPI, 9 * $cbDPI, 17 * $cbDPI, 19 * $cbDPI, $hPen4)
        EndIf
        _GDIPlus_GraphicsDrawLine($Button_Close_Graphic2[0], 17 * $cbDPI, 9 * $cbDPI, 27 * $cbDPI, 19 * $cbDPI, $hPen3)
        _GDIPlus_GraphicsDrawLine($Button_Close_Graphic2[0], 17 * $cbDPI, 9 * $cbDPI, 27 * $cbDPI, 19 * $cbDPI, $hPen3)
        
        _GDIPlus_GraphicsDrawLine($Button_Close_Graphic2[0], 27 * $cbDPI, 9 * $cbDPI, 17 * $cbDPI, 19 * $cbDPI, $hPen3)
        _GDIPlus_GraphicsDrawLine($Button_Close_Graphic2[0], 27 * $cbDPI, 9 * $cbDPI, 17 * $cbDPI, 19 * $cbDPI, $hPen3)
    EndIf
    ;=============================================================================================================================

 

Link to comment
Share on other sites

Good to see someone is interested in carrying on the torch :) This was a nice project.

I myself decided to move on to Java + JNA, which is really fun and exciting. In a few days I'm already where I was at with the original AutoIt version. My original concerns regarding memory consumption were inflated - with G1GC and a small initial heap size, the program is only consuming about 60MB of RAM - considering that's with the whole Java 8 classpath available and JNA + JavaFX active, that's pretty decent.

Thanks for convincing me to move on @BBs19 :D

Edited by CosmicDan
Link to comment
Share on other sites

  • 3 weeks later...

@BBs19

Thanks for sharing. I would like to use MetroGUI UDF to create the menu for my software. What are the license requirements ?

The newest version is blocked by Defender SmartScreen. I have sent it to Microsoft as a false positive.:)

Edit.

Analysis completed (no malware). The last MetroGUI UDF was renamed by me to metrogui-udf_5.1.zip (see attachment)


 

SubmissionResults.png

Edited by AndyFul
added link to the UDF author
Link to comment
Share on other sites

On 26.1.2018 at 9:49 PM, AndyFul said:

@BBs19

Thanks for sharing. I would like to use MetroGUI UDF to create the menu for my software. What are the license requirements ?

The newest version is blocked by Defender SmartScreen. I have sent it to Microsoft as a false positive.:)

Hi, you can use it however you like in your project..You also don't need to set any link in your program.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...