This code:
al_show_native_message_box(0, "Native Message", "Allegro test", "If this works, there will be three buttons.", "A|B|C", ALLEGRO_MESSAGEBOX_WARN);
Produces the attached screenshot.
{"name":"606650","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/a\/aa0fb20013ef645f5ad17249012d1b5c.png","w":319,"h":174,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/a\/aa0fb20013ef645f5ad17249012d1b5c"}
Based on my understanding of the manual I'd expect it to show three buttons, labeled 'A', 'B', and 'C'.
I've tried a few different messagebox flags, and the problem is the same.
I'm using allegro v5.1.2[1], and mingw v4.7.0. (It isn't the latest version of Allegro, but I didn't see anything about this in the changelog.)
I think this was discussed a few weeks ago but I can't find it now. The problem is that nobody has bothered to write a full blown modeless dialog box function for Windows.
And it seems to be not easy at all, compared to OSX/GTK. But yes, if anyone has the code for it and can make a patch it would be added of course.
The current implementation is this btw: https://github.com/elias-pschernig/allegro5/blob/5.1/addons/native_dialog/win_dialog.c#L238
So basically just a call to MessageBoxW.
Ok. I might look into adding that functionality later today. (Or rather, I will look into it, but I might give up before doing anything useful...)
Is there some kind of todo list for Allegro which tracks unfinished features like this? I didn't notice anything in the manual, or any comments in the code, to indicate that this feature is incomplete on Windows.
[edit]
Damn... this Windows dialog stuff looks like a bit of a nightmare. From what I can tell, we'd need to do something like this, but with automatically generated parameters and style etc, and without using C++ features. I haven't been able to find any neat shortcuts.
Surely there must be some libraries or something which already do this stuff. It's a pretty basic and useful task, but the winapi stuff is just too low level.
From what I can tell, we'd need to do something like this [blogs.msdn.com], but with automatically generated parameters and style etc, and without using C++ features.
That looks horribly obtuse, but not too terrible. It's fine to use C++ (I mean the OSX dialogs are implemented in ObjC) but I don't think C++ is necessary here.
I've been writing some code to implement the custom buttons functionality in Allegro. My code isn't quite finished yet, but I've just tried to compile it as part of Allegro and I've run into some problems...
Apparently Allegro is set up to only allow ISO C90 code, and so I'm getting error messages like this:
win_dialog.c:303:4: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement] win_dialog.c:308:4: error: 'for' loop initial declarations are only allowed in C99 mode
Is there some good reason for enforcing C90 rather than C99? In my view, declaring variable where they are needed, and initialing variables when they are declared are both good style, and I'd rather not have to change it.
In case someone is interested, here is the code I've got so far:
As I said though, it isn't quite finished.
Is there some good reason for enforcing C90 rather than C99?
Visual C++.
Visual C++.
he asked if there were any good reasons.
he asked if there were any good reasons.
To annoy the Freetards
Sticking to a 22 year old standard instead of a 13 year old standard is good business practice!
Let me see, what else was new in 1990?
Tim Berners Lee proposes a "hypertext" system, a precursor to the World Wide Wait, er, Web!
Windows 3.0 was brand spanking new!
The Sound Blaster Pro was new!
IBM introduces XGA to extend the VGA standard.
The first 32 bit Amiga is introduced! Yves hasn't been born yet. Or BAF (!)
I'll stop now.
I wouldn't mind dropping Visual C++ support. Not for using Allegro, but for compiling it. We'd of course adjust the DLL creation process so the produced DLLs can be used with VC before doing that.
But it would mean, Allegro itself could be written in proper C11. To compile it you would need to use clang or gcc or the Intel compiler or any other C11 compiler. Most VS users wouldn't compile the library themselves anyway, so nothing would change for them. They get the headers and libraries and can use Allegro.
But it would mean, Allegro itself could be written in proper C11. To compile it you would need to use clang or gcc or the Intel compiler or any other C11 compiler. Most VS users wouldn't compile the library themselves anyway, so nothing would change for them.
Being unable to build and debug Allegro in Visual Studio could mean losing most Windows contributors. And you wouldn't have debug information for Allegro that the MSVC debugger can read. Etc.
I don't see what the big problem is with declaring variables at the top of functions, including loop iterators. Really not worth losing MSVC support over.
Being unable to build and debug Allegro in Visual Studio could mean losing most Windows contributors.
You mean almost none? If not none? We don't really have a windows dev.
I maintain the d3d port and work on opengl too . The only thing I haven't fixed is the topic of this very thread. I use MinGW myself but I may be using VC++ more for Windows 8 stuff. If I have the money to buy a Windows 8 license I intend to "port" Allegro to it (meaning have it feel like a real Windows 8 app with metro and all that, not just a compatibility app, ready for the Windows store etc.)
You mean almost none? If not none? We don't really have a windows dev?
Remember END_OF_MAIN()? That would probably still be there if someone that use MSVC as their main development tool hadn't realized that it's not needed. It would have stayed because "the stupid MSVC crap can't do things in a sane way". And nobody would know that the real reason was just that the Allegro dev team lacked familiarity with the MSVC tool chain.
And this was done by an outside contributor who probably wouldn't bother if he couldn't build and debug Allegro in his beloved MSVC. And I should know, as it was me
I don't see what the big problem is with declaring variables at the top of functions, including loop iterators. Really not worth losing MSVC support over.
Me neither. I see how it's annoying having to get used to a slightly different (and inferior) style of programming if you've never had to do it like this before. And even worse when it's evil Microsoft's fault. But it's still pretty much the same C that we all know and love.
Well, I'd vote in favour of dropping Visual C++ support for building Allegro; but since I'm not a significant contributor to Allegro, I don't think my vote should count for much.
The archaic rules about variable declarations are pretty annoying[1]; but more generally, I just don't think Allegro should allow itself to be held back by just because one compiler is no longer being updated.
There are a bunch of new C features which some Allegro developers may want to use at some point. And although it may not be easy to come up with a priori reasons for using any given feature, I think that the question of whether or not developers can use any given feature should be "is this standard C" rather than "is this supported by Microsoft?" For me, this kind of VC++ stuff is bad for morale. Instead of thinking about making high quality code, I just end up getting frustrated at Microsoft and it makes me want to avoid working in such an environment.
And this was done by an outside contributor who probably wouldn't bother if he couldn't build and debug Allegro in his beloved MSVC. And I should know, as it was me
You are welcome to become the full time windows maintainer
We're not dropping MSVC support over this trivial issue.
You are welcome to become the full time windows maintainer
Thanks, but just the thought of making any commitment to an unpaid project makes me feel a bit stressed right now
Karadoc, most of your reasons are valid but pretty insignificant in practice.
Thanks, but just the thought of making any commitment to an unpaid project makes me feel a bit stressed right now
That busy eh?
Ok. Moving on from that VC++ stuff, and back to implementing this custom buttons functionality...
In the code I posted, one of the big and obvious holes is that the way I've handled the buttons names is broken. I'm going to fix that now; but I'm not familiar with how to handle unicode strings, so I just want to do a quick sanity check here before I write the code. (Somewhat embarrassingly, I didn't even realise that unicode character had variable length until a few minutes ago. I thought UTF-16 just meant all characters were 16 bit numbers or something like that.)
As I understand it, we start with a ALLEGRO_USTR called mb_buttons which contains a list of button names separated by '|' characters. To use this in the Windows API, we'll need to encode the individual button names into the correct places in the dialog template buffer, as UTF-16 strings.
I've just browsed through some of the Allegro API to see how this can be done. I now know how to iterate through the characters in mb_buttons to find the starting position and the size of each button name. But unfortunately I can't see a way to encode one of these substrings directly into the dialog buffer.
What I'd like is to use a function like al_ustr_encode_utf16_substr to encode the button names directly onto the buffer. Unfortunately, that function doesn't exist. So it seems to me that I have to use al_ustr_dup_substr to create separate `ALLEGRO_USTR`s for each button name and then use al_ustr_encode_utf16 to encode each of them into their place in the dialog buffer. Does that sound about right? It sucks a bit, because its a bunch of allocating/copying/freeing just to move data from one API to the other.
al_ref_ustr
Right. al_ref_ustr is the thing to use; and I've worked around the variable declaration problem by putting a bunch of braces all over the place.
I've now finished what I was trying to implement; but I'm pretty disappointed with how it turned out. It doesn't really look 'native' at all. It looks like quite bad.
{"name":"606671","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/b\/a\/ba6f742214ab05bcfd8921e98b5d9082.png","w":466,"h":188,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/b\/a\/ba6f742214ab05bcfd8921e98b5d9082"}
I assumed that if I didn't specify a font, Windows would automatically pick whatever the normal font is – but unfortunately it actually just uses a trashy looking system font.
Also, my current implementation doesn't make any attempt to make the box big enough to fit the text. The height of the box is the same regardless of the text.
So.. I guess the main shortcomings of my implementation are as follows:
The height of the box is not set dynamically, and so long messages may appear underneath the buttons or be truncated.
The size of the buttons is not set dynamically, and so long button names might not fit.
The text is missing the white background that standard dialog boxes have.
Flags such as ALLEGRO_MESSAGEBOX_WARN and ALLEGRO_MESSAGEBOX_ERROR are ignored. (These flags should have a corresponding sound-effect, and an icon inside the dialog box.)
... So the result is pretty ugly, but at least it has the correct buttons!
I'm not intending to work on this again in the near future, but if someone else wants to have a go at it, or if you think this is good enough to put into Allegro, then here's the code:
Unless someone wants to make a better version, I think that this version should be put into Allegro so that at least then the function will do what the manual says it should do. The previous Allegro functionality for the cases without custom buttons is unchanged, so this ugliness wouldn't be a regression.
[edit]
In case anyone is interested in fixing the font problem, I think this is a good place to start. If no one else wants to look at it, I may tackle it again at some point in the future; but for the time being I'm just going to leave it alone. -- I only wanted to use these dialog boxes for debugging anyway...
/* Note: the message box code cannot assume that Allegro is installed. */
That's a PITA, I guess.
Sound effect:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms680356(v=vs.85).aspx
I think maybe it would be most structured to first have a function which determines whether a standard dialog can be used, and then calls either a "normal" message box or "constructs" a dialog.
From what I can tell, if there's only three buttons you can just change their labels...
From what I can tell, if there's only three buttons you can just change their labels...
I have no idea what you are trying to communicate by this statement.
Only three buttons where? Change what labels, and how, and for what goal?
If you had three or less buttons, if the information I've gathered is correct, you can use the built-in message box and just change the button labels. I'm not exactly sure how, but it seems there's something more than MessageBox.
I see. Well, that would be good, but I don't think there is any way to change the button names (or anything else) on any of the standard dialogs. And even if that can be done, we'd still be lacking an implementation for > 3 buttons. Anyway, let us know if you work something out.
I found some information. It's not exactly what I recalled, but it looks simpler than what you've been doing so far. It essentially has you intercept the messages that normally go to a message box and just customize it. http://www.catch22.net/tuts/custom-messagebox
By the sounds of that, it is possible to intercept a standard message box during the creation process, and then use whatever API functions are available to edit pre-existing windows. Maybe that would be easier, but it sounds a bit sketchy to me. I'm sure that's not how the API is meant to be used...
In any case, even with that idea, I still don't know how to rename buttons and stuff - I'd have to learn about some new API functions and so on I suppose. Also, as far as I can tell, the customization of the window has to be done inside the callback function - and so we need to somehow get our data into that callback function. The only ways that come to mind are boost::bind (ie. bind our data with a generalized function to create a unique callback function every time we want to make a custom message box), or global variables (store the data somewhere global so that the callback function can use it). -- Neither of those options sound very attractive to me.
So.. if/when I try to beautify the stuff I've already done, I think I'll just build on the current implementation rather than trying to use these hook/callback tricks. -- But I wouldn't discourage someone else from trying that other stuff if they thought it would turn out better.