On 2019-12-29 18:47, ToddAndMargo via perl6-users wrote:
On 2019-12-29 17:39, ToddAndMargo via perl6-users wrote:
Hi All,

I have been working feverishly on Windows modules to
support a program I have been tasked to write for
a customer.

And after all the wonderful help everyone has given me,
I better show what I have done with it!

So far there are four of them.  I have completed the
windows popup module.  There are test lines at the
top of the module:


<WinMessageBox>

Oops, I have to move constant around to they do not conflict with my other modules.  So, ignore this for now.

Three more to follow in a few days

This what I came up with with all the shared Native
Call constants.

Two modules to follow:  NativeConstants.pm6 and MessageBox.pm6


<NativeConstants.pm6>
# unit module NativeConstants;
# NativeConstants.pm6

#`{

    Constants used across Windows libraries that use Native Call

Reference to types and values: http://dsource.org/projects/tango/ticket/820

https://docs.microsoft.com/en-us/windows/win32/sysinfo/registry-key-security-and-access-rights

https://docs.microsoft.com/en-us/windows/win32/intl/language-identifiers

https://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes--0-499-

    perl6 -I. -c NativeConstants.pm6

    Test one liner:
perl6 -I. -e "use NativeConstants; say FORMAT_MESSAGE_ALLOCATE_BUFFER.base(16);"

}


use NativeCall;

constant BYTE     := uint8;
constant WCHAR    := uint16;
constant DWORD    := int32;
constant REGSAM   := int32;
constant WCHARS   := CArray[WCHAR];
constant BYTES    := CArray[BYTE];
constant CPOINTER := int32;

constant INT      = int32;
constant UINT     = uint32;
constant HANDLE   = Pointer[void];
constant LPWCTSTR = CArray[WCHAR];

constant FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100;
constant FORMAT_MESSAGE_FROM_SYSTEM     = 0x00001000;
constant FORMAT_MESSAGE_IGNORE_INSERTS  = 0x00000200;

constant KEY_QUERY_VALUE   = 1;
constant ERROR_SUCCESS     = 0; # Win-Api  0 = success

constant KEY_READ      = 0x20019;
constant KEY_SET_VALUE = 0x0002;

constant REG_NONE                       = 0;   # No value type
constant REG_SZ = 1; # Unicode nul terminated string constant REG_EXPAND_SZ = 2; # Unicode nul terminated string = (with environment variable references)
constant REG_BINARY                     = 3;   # Free form binary
constant REG_DWORD                      = 4;   # 32-bit number
constant REG_DWORD_LITTLE_ENDIAN = 4; # 32-bit number = (same as REG_DWORD)
constant REG_DWORD_BIG_ENDIAN           = 5;   # 32-bit number
constant REG_LINK                       = 6;   # Symbolic Link = (unicode)
constant REG_MULTI_SZ                   = 7;   # Multiple Unicode strings
constant REG_RESOURCE_LIST = 8; # Resource list in the resource map constant REG_FULL_RESOURCE_DESCRIPTOR = 9; # Resource list in the hardware description
constant REG_RESOURCE_REQUIREMENTS_LIST = 10;
constant REG_QWORD                      = 11;  # 64-bit number
constant REG_QWORD_LITTLE_ENDIAN        = 11;  # same as REG_QWORD
<NativeConstants.pm6>


And this is MessageBox.pm6


<MessageBox.pm6>
# unit module WinMessageBox;
# MessageBox.pm6

#`{

    This Module provides access to Windows "user32" MessageBox function and
give a WinMsg to substitute for Windows Professional's msg.exe program, without
    the networking.

This module is not able to retrieve information from the user other than the buttons

       Test one liners:
perl6 -e "use lib '.'; use WinMessageBox :MessageBox; say MessageBox( 'Some Title', 'Something Cleaver', MB_ICONINFORMATION, MB_OK );" perl6 -e "use lib '.'; use WinMessageBox :MessageBox; say MessageBox( 'Some Title', 'Something Cleaver', MB_ICONQUESTION, MB_YESNOCANCEL ); perl6 -e "use lib '.'; use WinMessageBox :MessageBox; say MessageBox( 'Some Title', 'Something Cleaver', MB_ICONERROR, MB_CANCELTRYCONTINUE );"

perl6 -e "use lib '.'; use WinMessageBox :WinMsg; say WinMsg( 'Some Title', 'Something Cleaver' );"


      References:

https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-messagebox

https://stackoverflow.com/questions/59105696/how-can-i-create-pop-up-windows-for-perl6-in-windows
         https://docs.perl6.org/language/nativecall
}

use NativeCall;
use NativeConstants;


enum Icons (
   MB_ICONEXCLAMATION   => 0x00000030,
   MB_ICONWARNING       => 0x00000030,
   MB_ICONINFORMATION   => 0x00000040,
   MB_ICONASTERISK      => 0x00000040,
   MB_ICONQUESTION      => 0x00000020,
   MB_ICONSTOP          => 0x00000010,
   MB_ICONERROR         => 0x00000010,
   MB_ICONHAND          => 0x00000010
);

enum Buttons (
   MB_ABORTRETRYIGNORE  => 0x00000002,
   MB_CANCELTRYCONTINUE => 0x00000006,
   MB_HELP              => 0x00004000,
   MB_OK                => 0x00000000,
   MB_OKCANCEL          => 0x00000001,
   MB_RETRYCANCEL       => 0x00000005,
   MB_YESNO             => 0x00000004,
   MB_YESNOCANCEL       => 0x00000003
);

enum MessageBoxReturn (
   ABORT     =>  3,
   CANCEL   =>  2,
   CONTINUE => 11,
   IGNORE   =>  5,
   NO       =>  7,
   OK       =>  1,
   RETRY    =>  4,
   TRYAGAIN => 10,
   YES      =>  6
);


sub MessageBoxW(
   HANDLE,
   LPWCTSTR,
   LPWCTSTR,
   UINT
)
   is native("user32")
   is symbol("MessageBoxW")
   returns INT
{ * };


sub MessageBox(
   Str $Title,
   Str $Message,
   Icons $Icon = Icons::MB_ICONINFORMATION,
   Buttons $Button = Buttons::MB_OK
)
   returns MessageBoxReturn is export( :MessageBox )
{

#`{
    Pop up a message box to the user.
    Windows only.
    Return what button was pressed

    See top for test one liners
}

   my Str $SubName = &?ROUTINE.name;
   my Str $OS      = $*KERNEL.name;

   if not $OS eq "win32" {
      say "Sorry, $SubName only work in Windows.";
      exit;
   }

my $lpText = CArray[uint16].new( $Message.encode.list ); $lpText[$lpText.elems] = 0; my $lpCaption = CArray[uint16].new( $Title.encode.list ); $lpCaption[$lpCaption.elems] = 0;
   my $uType     = $Icon +| $Button;   # bitwise OR them together

return MessageBoxReturn( MessageBoxW( my $Handle, $lpText, $lpCaption, $uType ));
}


sub WinMsg( Str $TitleStr, Str $MessageStr ) is export( :WinMsg )  {

#`{
Simple "Ok" pop up with no return value. Thjis as a subsitute for Windows `msg.exe` program
    that only runs in the Professinal version and without the netowrking.

    See top for test one liners
}

   my Str $SubName = &?ROUTINE.name;
   my Str $OS      = $*KERNEL.name;
   if not $OS eq "win32" {
       say "Sorry, $SubName only work in Windows.";
       exit;
   }

   return  MessageBox( $TitleStr, $MessageStr, MB_ICONINFORMATION, MB_OK );
}
</MessageBox.pm6>

Reply via email to