Hacker News new | past | comments | ask | show | jobs | submit login
Simple Windows GUI Application Written in Go (gist.github.com)
107 points by dsr12 on June 23, 2016 | hide | past | favorite | 63 comments



Pretty basic Window creation and message loop code, but its nice to see a starting example in Go. For comparison here is a C version:

https://github.com/LeZuse/minimal-win32-app/blob/master/main...

The C code does basically the same thing but ends up being smaller because the Go code doesn't have an equivalent of windows.h with function and data type definitions. The Go code might be a little nicer if it used a Win32 API wrapper, but there doesn't seem to be a well supported and documented one out there. This was all I could find https://github.com/AllenDang/w32.


There's something elegant about https://github.com/LeZuse/minimal-win32-app/blob/master/main...

I remember just how painful working with the Win32 API could be (a lifetime ago), but I felt like I really understood how it worked. These days, it's layer upon layer of abstractions. Or bindings from my language of choice to an abstraction layer/framework running on the native OS.

I couldn't begin to explain how many of the popular UI frameworks work, all the way down to the native OS layer.

There was something substantial, concrete in programming at this layer rather than some higher level, fragile abstraction.


I think that sentiment is mostly revisionist nostalgia. Yes it was easier to 'know' what was going on between your code and the OS, but to say that modern UI frameworks are more fragile than the hand-coded win32 code of yore is certainly fallacious.


Actually I would agree that win32 is more stable once you get the hang of it. I have worked with WPF, Winforms, MFC and win32. win32 was by far the most complete, predictable and flexible environment. It takes a lot of learning and you can't just let anybody work on the codebase. But once you know what you are doing and maybe have some simple wrappers for routine stuff it's pretty good.


Coming from MS-DOS and Amiga as background, I was amazed how Win16 was a productivity changer (for the better).

It is funny to see people bashing it nowadays, given how I came to enjoy it.

When I started GUI coding on UNIX, Xlib, Xt and Motif on the other hand were anything but productive.


100% agree. With modern tools, I :

Think the UI the way I code it (declarative)

Don't have to think about screen resolution, colour depth,...

Don't have to bother with non unicode stuff

Have access to well behaved widgets

Can have portability if I need that

Even if I can't control 100% of the rendering process, my productivity has increased...


> Think the UI the way I code it (declarative)

Windows Ressource files exist at least since Windows 3.x

> Don't have to bother with non unicode stuff

Just use the WinAPI functions that are prefixed with W (Unicode) instead of A (ANSI), e.g. CreateWindowExW instead of CreateWindowExA.

> Have access to well behaved widgets

Call CreateWindowEx (https://msdn.microsoft.com/en-us/library/windows/desktop/ms6...) (yes, the name is confusing, accepted) with lpClassName value, say, of BUTTON, COMBOBOX, EDIT, LISTBOX, MDICLIENT, SCROLLBAR (for a more complete list look at the MSDN site that I linked). This creates such a widget.


I'd argue that it's not "fallacious", it's simply a matter of opinion and taste.


Using the message crackers and type safe handles introduced in Windows 3.1 SDK made it somewhat better.

In any case, OWL, VCL and later on MFC were my tools during those days, when given an option.


I'd probably use andlabs/ui or lxn/walk.

https://github.com/andlabs/ui https://github.com/lxn/walk


Yeah, I wouldn't want to touch this with a 10ft pole due to the lack of windows.h. There's so many constants you need to keep track of you're better off using C# + C FFI than trying to use the core win32 api.


You can reference C header files from go. If you include a headerfile defining a constant "foo", then C.foo would give the value to the Go program. It is not overly elegant, but the Go-C interface is pretty usable.


Does that include macro pre-processing as well? There's a lot of stuff like WIN32_LEAN_AND_MEAN in there as well.


Yes, it is ran through C preprocessor. You can define for CFLAGS, CPPFLAGS or LDFLAGS in the form of special comment:

    // #cgo CFLAGS: -DYOUR_DEFINE
    // #cgo LDFLAGS: -lyourlib
    // #include <header.h>
    import "C"


As far as I am aware, yes. Using "cgo" (by importing "C") you can include C header files, and all c source files are compiled together with the Go files in your package. So if you have a foo.c containing int foo(int) you can just call it from Go by

i := C.foo(C.int(j))

Assuming j is a Go int type.


So just some quick googling points to https://github.com/golang/go/issues/9601 which seems like it's still an open issue.

Either way if you're going to build UI for Windows C#/QT with an C FFI is the more sane way to go. Back when I worked on game engines most of the time we had the fast code down in native and used C# for the tools since it's such a productive framework compared to win32.


I've used https://github.com/lxn/walk to make some simple Win GUI apps. It was a couple years ago. Very easy to use.


Can anyone post a screenshot of what the final product is?



While not anything huge it is very interesting to see it coming from Go.

Thank you!


Is it me or is this substantially uglier than the C version?


It is, but that is because it has to refer it directly and import a lot of stuff you get for free in C, when you import windows.h

I don't think it would be that ugly if you compared it C code that didn't include windows.h


This kind of thing is bound to get better as it gets wrapped in with a more idiomatic interface. Things like https://github.com/go-gl/gl started as ugly hacks requiring passing unsafe pointers and stuff around but have made great strides since then. I don't know the details and I'm thinking aloud right now, but the comments about "windows.h", constants, and accessing C via cgo possibly point to an automatically generated solution (possibly leveraging "go generate").

Whatever, native GUI bindings has been a key factor for the adoption (or lack thereof) of some languages where they would have otherwise been perfectly fine.


every beginning is hard, but at least it doesn't deal with resolving DLL procedure addresses by hand, which it would've had to do if syscall.NewLazyDLL wasn't available.

after a while things will settle down and this "hello world" program will boil down to something much simpler, like:

     import "win"
     func PopWin(text string) {
          win.NewWindow(text, ...)
     }
also keep in mind that this is the version that purposely avoids using C and, as a consequence, can be cross compiled for windows on every machine with Go installed. there are benefits to that.


I would expect it would be, for a barebones GUI program. Now make a real program, where 90% of the logic isn't specifically UI stuff, and the benefits of doing it in Go makes more sense.


Very nice. I've not always stayed true to this advice, but for commercial products it is recommended to build software in the native language of the OS. Something like .NET is available but this is supported by the creators of Windows.

Why?

Less bugs, better examples, community support.


>> for commercial products it is recommended to build software in the native language of the OS

I'm not sure I agree with this, it may have been true before VB on windows. People like Dropbox would also disagree, they use(d) python for their UI code on the desktop, I believe.


> Something like .NET is available but this is supported by the creators of Windows.

and .NET isn't?


Within the context of this discussion ... I was meaning that if you don't use C/C++ you could use .NET which "is" supported. So, with Windows you don't have to use the native language since C# is supported by the creators.


I keep hearing how .NET and C# are supposed to be pretty great these days. C# often gets credit for popularizing async/await, although I don't actually know if that's true.

Based on that, and the point you made, I'd definitely go the .NET/C# route if I ever ended up in the unfortunate position of having to develop software for Windows. Barring of course some reason that it had to be written in Go or something else.


Why 'unfortunate'? What is 'unfortunate' is developers having prejudice against any OS / IDE / language / etc; it restricts your creation of solutions for the problems that need to be solved. Keeping up with developments across all platforms - like the fact these days you can use C# for non-Windows targets- helps us be well-rounded and capable developers.


It's only prejudice if it's not based on direct experience. Many of us would rather avoid going back to Windows at all.


After several years using GNU/Linux I have happily returned.

Windows and Mac OS X are the only sane alternatives for developers that care about desktop applications and developer friendly toolchains. Same applies to iOS, Android and WP.

The other alternatives feel like only the CLI and daemons matter, stuck in a PDP-11 view of the world.

Then again, NeXT was the only UNIX based OS with an alternative culture regarding developers tools and UX.

KDE is the only environment that can match in terms of tooling and UX, yet it is lacking some serious love nowadays.

I want my developer and user experience to be a Xerox Star and not a PDP-11.


> KDE is the only environment that can match in terms of tooling and UX, yet it is lacking some serious love nowadays.

KDE? Seriously? It's one of the worst DEs on linux. Any DE which isn't based on gnome is just cheap nowadays.


>Seriously? It's one of the worst DEs on linux. Any DE which isn't based on gnome is just cheap nowadays.

I'll take your hot opinion and replace it with mine: Gnome (3) is hands down the worst DE in the entire Linux ecosystem and is actively harming all others by merely existing due to the mentality driving its development: "fuck everyone that's not us, we set the standards and you will like them".

Currently KDE is the most polished and feature complete of the "batteries included" DEs. And even then as a developer I prefer a bare-bones tiling set-up, picking and choosing what I want and having an experience customized to my preferred workflow.


So which other DE on GNU/Linux does provide the same tooling and platform abstractions as KDevelop/Qt Creator do?

GNOME has a very nice HIG from UX point of view, but it is stuck in C + POSIX as technology stack in what concerns developer experience. Vala is still not there and I don't believe in JavaScript for native UIs.


> So which other DE on GNU/Linux does provide the same tooling and platform abstractions as KDevelop/Qt Creator do?

Same or similar? It doesn't matter what they provide because I'd go with ScalaFX(http://www.scalafx.org/) + IntelliJ or Vala|Genie + Vala IDE. Mono is also an option if you're into it.

> but it is stuck in C + POSIX as technology stack in what concerns developer experience.

Yes, GTK isn't the newest but it isn't hard at all to develop apps with Vala/Genie(https://wiki.gnome.org/Projects/Vala/GTKSample , https://wiki.gnome.org/Projects/Genie/GtkGuiTutorial ?)

> Vala is still not there and I don't believe in JavaScript for native UIs.

What do you mean? Vala is almost the defacto standard language for ubuntu/gnome apps.


ScalaFX(http://www.scalafx.org/) + IntelliJ and Mono are not exposing any GNU/Linux specific feature.

I can use the same toolchain in many other operating systems.

The last time I bothered to check GNOME, there was some ongoing discussion of JavaScript becoming the official language to pair with C.

Just checked Genie and Vala IDE web sites, they still need to do catch up with what Borland was doing in the 90's, let alone modern IDEs.


> ScalaFX(http://www.scalafx.org/) + IntelliJ and Mono are not exposing any GNU/Linux specific feature.

Why would you need specific features? You wanted to develop desktop apps, not gnome plugins, right?

> Just checked Genie and Vala IDE web sites, they still need to do catch up with what Borland was doing in the 90's, let alone modern IDEs.

If you want RAD there's Glade(https://glade.gnome.org/) + GtkBuilder.


> You wanted to develop desktop apps, not gnome plugins, right?

Desktop apps that expose the features that make the platform unique.

> If you want RAD there's Glade(https://glade.gnome.org/) + GtkBuilder.

Not even close to Delphi and C++ Builder and we are talking about 90's here.

If I upgame to Blend + VS, XCode + Playgrounds, Android Studio then there is a lot of catch up to do.


@woflgke you're going off on a tangent: it's about the maturity of tools and not about "exposing" system features. That's unrelated to desktop apps.


No @woflgke is quite right.

Software development stack for desktop apps are all about exposing the features that make a platform desired to be used.


pjmlp asked:

> So which other DE on GNU/Linux does provide the same tooling and platform abstractions as KDevelop/Qt Creator do?

You answered:

> Why would you need specific features? You wanted to develop desktop apps, not gnome plugins, right?

Clearly KDevelop and At Creator expose GNU/Linux specific feature.


Exactly; hence if you were to say it'd be unfortunate for you to have to go back to Linux, I wouldn't say you were prejudiced either, since you know from personal experience.


I still use it of course (it is my travel netbook OS), just not with the same enthusiasm of former times.


What would be a good use case/type of project where you'd use C# to target non-Windows? Over, say, any of the JVM languages?


Cross-plateform mobile apps with Xamarin.


I don't see why someone wouldn't use C#/.Net to build a native Windows app. It's open source, and supported by Microsoft, the makers of Windows as the primary Windows app environment.

One reason would be if you're trying to build a node based app which you would like to use across other platforms.


The problem isn't C#/.NET but what GUI toolkit do you use? Winforms, WPF, UWP and others are either in maintenance mode or incomplete. The only complete toolkit is Win32 which brings you back to C/C++.


All new APIs since Windows 8 are now COM based, yeah it is still Win32, but I guess it is just following their original idea for .NET (COM+ Runtime and not the CLR).

In some future version of Windows, when UWP with its COM foundation becomes prevalent, they can ripoff all the Win32 APIs that aren't required to support WinRT.

Just like Apple has done with Carbon, Quicktime and many others.


We will see how UWP works out. I wouldn't be too surprised if they changed their strategy in the next few years to come out with something different. That seems to be the Microsoft tradition. As soon as something starts working it gets replaced by something else.

The only constants are COM and Win32.


Sure, however I am with high hopes with WinRT, as it is what .NET should have originally been designed instead of the CLR detour.

If you look at what Delphi, Modula-3, Ada, Component Pascal, Oberon variants, Eiffel were already offering before Java took off.

> As soon as something starts working it gets replaced by something else.

Just like everyone else. I can hardly think of any platform owner that has kept their APIs stable.

Not that you are not right to complain, I just get the impression many tend to forget about the other vendors similar practices.


I find this coming back from CLR to COM sad because the CLR support another very good language (F#) which isn't in WinRT and also because the CLR is going really multiplatform with .net core. Also too bad Microsoft didn't pursed a multiplatform framework like Silverlight and go with a solution that didn't even run on its own OSes (previous version of Windows).


Isn't Win32 basically in the same maintenance mode as WinForms? WinForms is mostly just a thin wrapper around Win32 anyway.


Pretty much everything new first gets exposed through Win32 or some COM interface like DirectX.


WTL is also great if you want or need something that doesn't use .NET. Building GUI apps doesn't suck with WTL. What I would like to see is an example of an app where I can build an app using both WTL/C++ and have Go code with channel support...


If you're interested in Win32 development with Go, I've built a small library for personal use, for quick prototyping of WinAPI calls without cgo and without having to pre-declare each function:

https://github.com/akavel/winq

(godoc: https://godoc.org/github.com/akavel/winq)


A couple of days ago I wanted to read the Active Protection Sensor bundled in a ThinkPad by accessing Sensor64.dll under Go 1.6.2. So, after several hours diving in the interwebs/Godocs I came to this issue [0] which suggests the "x/sys/windows" [1] package instead the "syscall" one if you want to load a Windows system DLL.

Note: I'm a total newbie at Go and Windows API so every bit of abstraction was a bless to me.

[0] https://github.com/golang/go/issues/14959 [1] https://github.com/golang/sys/tree/master/windows


I thought walk framework was there to reduce the code.


I'm surprised by the tone of some messages here. It sounds like native GUI programming on Windows has faded away...

Is it just me ?


How long until we see the go equivalent of pinvoke.net ? http://www.pinvoke.net/

Ideally this sort of platform import should be automated so that Win32 specific apps could import the more advanced GUI stuff (comdlg et all).


Very nice... Reminds me of an old good MFC. Happy new year 1996.


But can it backtrace IPs?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: