A replacement for MessageBox.

General FreeBASIC programming questions.
deltarho[1859]
Posts: 4315
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

A replacement for MessageBox.

Post by deltarho[1859] »

Image

If the console is minimized, the message will be centred on the desktop.

Works with Windows GUIs as well, especially within callbacks where the use of MessageBox may be problematic.
Imortis
Moderator
Posts: 1929
Joined: Jun 02, 2005 15:10
Location: USA
Contact:

Re: A replacement for MessageBox.

Post by Imortis »

Interesting. I would be interested in seeing the code for this. :D
deltarho[1859]
Posts: 4315
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: A replacement for MessageBox.

Post by deltarho[1859] »

It started life as a PowerBASIC static link library (sll) by Stuart McLachlan. I started to port it to FreeBASIC and hit snags with propriety methods which would be difficult to emulate in FreeBASIC. Even if we could emulate them, we may have copyright issues.

I decided to compile a dll for FreeBASiC. There would be no copyright issues with that. There were a few problems passing Unicode strings from FreeBASIC to the dll which were incompatible, but they were overcome with help from srvaldez. Whilst doing that, I got involved with improving Stuart's sll with the centring aspect.

The end product was a PowerBASIC dll which worked with FreeBASIC. It takes a few parameters including font, font size, foreground/background colours and time out. The last three are optional, and FreeBASIC's optional parameters' method is compatible with PowerBASIC's OPT method; the FreeBASIC method being more flexible than PowerBASIC's OPT. If the time out is set to zero, there is no time out.

So the source code wouldn't be much good for a FreeBASIC coder, as it wasn't for me. Besides, I haven't got Stuart's permission to publish the source code. I doubt that he would mind, as he hasn't in the past.

The dll is 59.5KiB and comes with a bi file which includes the declaration among other things.

It is undergoing extensive tests, but I think all the wrinkles have been smoothed out. One wrinkle was message clipping if the parent got too close to a screen edge. Now the message is confined to the desktop or the primary monitor for multiple monitor systems. I will be looking at multiple monitor systems as my setup has two.
adeyblue
Posts: 302
Joined: Nov 07, 2019 20:08

Re: A replacement for MessageBox.

Post by adeyblue »

Imortis wrote: Feb 01, 2024 23:57 Interesting. I would be interested in seeing the code for this. :D
I don't know how this works, but you can get 90% of the way there with TaskDialogIndirect. The only thing it lacks is support for changing the colours.
deltarho[1859]
Posts: 4315
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: A replacement for MessageBox.

Post by deltarho[1859] »

The above is not a competitor for the TaskDialog family. They are on a different planet altogether. The above takes only 370 lines of source code. That has just increased because it is now multiple monitor aware. It was getting on my nerves having the message chained to the primary monitor.

I got involved with this when updating some old PowerBASIC code with some new features. I had a structure with two possible outcomes, but only one outcome was happening. A snippet was posted and many came back and said the code was OK but had no idea why only the one outcome. Two of the long-standing members advised me not to use PB's MsgBox in a callback. Unpredictable things may happen, and it is not possible to tell when and if they are likely to occur. This was news to me and, it seems, to many others as well. MsgBox is a wrapper for Microsoft's MessageBox, and I have used it for years in callbacks. MsgBox does not use a Window handle.

Stuart chipped in and pointed me to his MessageBox replacement static link library. I ripped out all the MsgBoxs and my problem vanished. I have gone one further and will not use MsgBox for anything now. I also will not use MessageBox in FreeBASIC code either, favouring the PB dll instead.

Which one is MessageBox?

Image

Well, it is the one on the right. It has a Close button; not that it ever needed one; as a function, it returns the same as MB_OK.

I am now looking at making the font and font size optional, but I am having an issue. :lol:
deltarho[1859]
Posts: 4315
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: A replacement for MessageBox.

Post by deltarho[1859] »

It took a while, but the font and fontsize are now optional; with help from srvaldez. Whilst doing that, the replacement is now multiple monitor aware.

We could have a simple statement with these parameters ( hConsole, "FreeBASIC", "Message", MB_OK ); the same as MessageBox.

After MB_OK we can have up to five optional parameters; Timeout, Font, FontSize, Foreground colour, and Background colour.

An issue has arisen regarding the use of system icons and that is being looked at.
deltarho[1859]
Posts: 4315
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: A replacement for MessageBox.

Post by deltarho[1859] »

Here is a zipped folder which includes DlgMsgBox.dll, a standard DlgMsgBox.bi file, and DlgMsgBox.chm.

DlgMsgBox.dll is only 59.5KiB and the chm is up to my usual standards, which always seem to fall well short of perfection. DlgMsgBox is easy to use, but does need a Help file.

In future, I will no longer use MessageBox favouring DlgMsgBox especially with Windows callbacks were MessageBox may be problematic. I had a major issue using PowerBASICs MsgBox recently; which is a wrapper for Microsoft's MessageBox.

I say 'standard DlgMsgBox.bi file'. This can be customized regarding the optional parameters. My default bi file is very different to the standard.

DlgMsgBoxForum
deltarho[1859]
Posts: 4315
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: A replacement for MessageBox.

Post by deltarho[1859] »

Multiple monitor awareness:

I have two monitors: A primary monitor in front of me and a secondary monitor, extended, to its left.

Image

The left image is when the console straddles the two monitors. My taskbar is on the left of my primary monitor for easy access from whichever monitor I am currently using. The nearest window to the console is the secondary monitor, and that is where the message is displayed. However, it is not clipped but shown in full.

The right image has the nearest monitor as my primary monitor, so the message is displayed there. It is not clipped and does not 'sit' on the taskbar.

No matter where the console window is located, north, south, top, or bottom and whether displayed in full or not, the message will always be displayed in full.

If you only have a single monitor system, the message will always be displayed in full on your desktop's work area, no matter how the console is displayed. For console window, read GUI window.

Centring on the parent and multiple monitor awareness was my contribution to Stuart McLachlan's code.

If the first parameter of DlgMsgBox is zero centring will be on the desktop or the primary monitor; if it exists.

Added: That is also true if the parent is minimized.
deltarho[1859]
Posts: 4315
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: A replacement for MessageBox.

Post by deltarho[1859] »

I found a bug in the dll.

With the bi file we have 'As WString Ptr' corresponding to 'As Wstringz' in the PowerBASIC's Export. That was srvaldez's suggestion and it worked.

With the optional font in the bi file, we have ' ByRef w As Wstring = "Segoe UI" ' corresponding to 'As Wstring' in the PowerBASIC's Export. That was also srvaldez's suggestion and that worked also, but not all the time.

Occasionally the default was coming back as gibberish and a console opened and closed immediately. It crashed. I think we have an analogy with a buffer overrun. We can get away with it, memory permitting, but it can backfire on us.

It took a lot of experimenting, but I had to control the buffer by using 'As Wstringz*256' in the PowerBASIC Export. The bi file remained unchanged.

I did a heck of a lot of testing on the default font being used, and it came back correctly each time. Far too many to be lucky. I never had an issue when a specific font was used in DlgMsgBox's parameter list. With string literals, FreeBASIC sorts the memory allocation for us and with string variables, we define the memory allocation via '*256' or whatever. With an empty parameter, effectively requesting the default font, Windows does what? No idea. :)

It is not a classic buffer overrun issue, but it clearly had something to do with memory allocation, and being specific in the PowerBASIC Export seems to have done the trick.

Here is an updated dll.

DMB.zip
deltarho[1859]
Posts: 4315
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: A replacement for MessageBox.

Post by deltarho[1859] »

Would you like 'posh' buttons on your messages?

Silly question - of course you would.

Save these two files

ConsoleXPTheme.rc

Code: Select all

1 24 "XPTheme.xml"
XPTheme.xml

Code: Select all

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
 
    <assemblyIdentity
        version="1.1.2.0"
        processorArchitecture="*"
        name="Encrypternet.exe"
        type="win32"
    />
    <description>Optional MyDescription for MyAppName.exe</description>
 
    <asmv3:application>
        <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
        <dpiAware>true</dpiAware>
        </asmv3:windowsSettings>
    </asmv3:application>
 
    <!-- Compatibility section for Program Compatibility Assistant (PCA) -->
    <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
        <application>
            <!-- Windows Vista -->
            <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
            <!-- Windows 7 -->
            <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
            <!-- Windows 8 -->
            <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
            <!-- Windows 8.1 -->
            <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
            <!-- Windows 10 & 11-->
            <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
        </application>
    </compatibility>
 
    <!-- Trustinfo section for User Account Control (UAC) -->
    <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
        <security>
            <requestedPrivileges>
                <!-- level   = "asInvoker"            -->
                <requestedExecutionLevel
                    level    = "asInvoker"
                    uiAccess = "false"
                />
            </requestedPrivileges>
        </security>
    </trustInfo>
 
    <!-- Dependency section -->
    <dependency>
        <dependentAssembly>
            <assemblyIdentity
                type="win32"
                name="Microsoft.Windows.Common-Controls"
                version="6.0.0.0"
                processorArchitecture="*"
                publicKeyToken="6595b64144ccf1df"
                language="*"
            />
        </dependentAssembly>
    </dependency>
 
</assembly>
With WinFBE I would simply use '#Resource "ConsoleXPTheme.rc"

Now try this (I'm using "MyDlgMsgBox.bi")

Code: Select all

'#console on
'#Resource "ConsoleXPTheme.rc"
#include "MyDlgMsgBox.bi"
Dim AS Long lReturn
Dim As hWnd hConsole = GetConsoleWindow
lReturn = DlgMsgBox( hConsole, "Testing choices.", "Message", MB_CANCELTRYCONTINUE + _
  MB_DEFBUTTON2 + MB_TASKMODAL, 0 )
 
Select Case As Const lReturn
  Case IDCONTINUE
    DlgMsgBox( hConsole, "You pressed Continue", "Message", MB_OK )
  Case IDRETRY
     DlgMsgBox( hConsole, "You pressed Try Again", "Message", MB_OK )
  Case IDCANCEL
     DlgMsgBox( hConsole, "You pressed Cancel", "Message", MB_OK )
End Select
I get: (Notice that I am using MB_DEFBUTTON2 and TASKMODAL with no timeout (5th parameter = 0)
Image

I pressed Cancel and got this:

Image

Too much like hard work? If you were selling a console application, I don't think so. Your users would buy more if you had more to sell. :)

Don't like my colour scheme? Write your own bi file. :D
deltarho[1859]
Posts: 4315
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: A replacement for MessageBox.

Post by deltarho[1859] »

I keep talking about the console. My Encrypternet application uses TaskDialog and I used a hook to centre the messages. I never could get perfect centring, and I was not that confident it would work properly on a multiple monitor system. TaskDialog is feature rich, but I used very little of its power. Encrypternet has 21 possible messages.

I ripped them all out and replaced them with DlgMsgBox. On the opening form at the bottom left is a deltarho icon. Clicking on that, I get:

Image

The message will time out in 10 seconds unless we click on OK before then. Using a pixel ruler, the centring is pixel perfect and using DlgMsgBox was easy.
deltarho[1859]
Posts: 4315
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: A replacement for MessageBox.

Post by deltarho[1859] »

Stuart McLachlan, the author of the SLL version, had an issue with his SLL and spent sometime trying to figure it out and spotted that he had misspelled a font name. I use a font checker by Michael Mattias at the PowerBASIC forum in another application. Stuart incorporated that in his SLL. So I have as well in my DLL.

Code: Select all

DlgMsgBox( hConsole, "FreeBASIC", "Message", MB_OK, 0, "BadSpelling" )
As is DlgMsgBox will not be happy with that. The message gets seriously clipped.

On failing a font check, "Segoe UI" will be used.

The binary now stands at 61952 bytes rather than 60928. :o

DMB
adeyblue
Posts: 302
Joined: Nov 07, 2019 20:08

Re: A replacement for MessageBox.

Post by adeyblue »

deltarho[1859] wrote: Feb 02, 2024 0:41 It started life as a PowerBASIC static link library (sll) by Stuart McLachlan. I started to port it to FreeBASIC and hit snags with propriety methods which would be difficult to emulate in FreeBASIC. Even if we could emulate them, we may have copyright issues.
Ironically, as I've recently found out after going through the PB help file with a toothcomb*, repackaging PB code for other programming languages to use is far closer to falling foul of the licensing agreement than simply rewriting its procedures in said languages (see License Agreement/Restrictions in the PBWin10 help)

* I thought it'd be fun to see if I can leisurely implement a new PB compiler from scratch before the owners could produce a new version with all the code in hand. But now they seem to have buggered off and the site's in disrepair, it's not much of a fun competition any more. (Yes, I know there's already a cross platform 64-bit PB compiler, kind of)

Did you know you can't specify the last seven max quad values as a decimal literal in PB? Somebody faithful needs to file a bug so they can definitely fix it when they definitely put out the definitive new version they're definitely full steam ahead on making. Honest guv.

Code: Select all

Function PBMain() As Long '' PBWin 10.04
Local q as quad
q = 9223372036854775807 '' this is &h7FFFFFFFFFFFFFFF, does the same for any last digit between 1-7
? Dec$(q) & $spc & Hex$(q, 16) '' where'd my 7 and my F go?
End Function
deltarho[1859]
Posts: 4315
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: A replacement for MessageBox.

Post by deltarho[1859] »

I have just asked the admin to remove this thread. I am in breach of PowerBASIC's licence agreement. I really thought I was safe compiling a dll. I would be if a PowerBASIC propriety command was not used, but I am using one. :(

Ignorantia juris non excusat.

If anyone has downloaded DlgMsgBox please destroy it. You cannot even use it for personal use. I have destroyed all my work and will not use it in Encrypternet; I haven't done that yet. Well, I had but not changed my website yet.
deltarho[1859]
Posts: 4315
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: A replacement for MessageBox.

Post by deltarho[1859] »

@imortis

I have sent you two private messages, but they are not showing as being sent in my Control Panel.

This thread needs to be removed - see my last post.
Post Reply