Author Topic: MasmBasic  (Read 345734 times)

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 11550
  • Assembler is fun ;-)
    • MasmBasic
Re: MasmBasic
« Reply #345 on: November 04, 2016, 11:15:12 AM »
Version 4 November 2016 is available :icon_cool:

New features:

a) GuiImage learned to care for resources, Unicode and the Internet (see attached Avatars.zip for an example using resources; no temp files 8)):

include \masm32\MasmBasic\Res\MbGui.asm
Event Paint
  ; args are imgsrc$ or resource ID, optional: no args=upper left corner, original size, x=fit: use full canvas, or x, y [, w, h]
  GuiImage "\Masm32\examples\exampl04\car\car.jpg", fit                  ; use full canvas
  GuiImage "\Masm32\examples\exampl04\car\car.jpg", 50, 400, 160, 900   ; use specific x, y, w, h
  GuiImage "\Masm32\examples\exampl04\car\car.jpg", 50, 200            ; use x, y, original w, h
  GuiImage "\Masm32\MasmBasic\Res\FileOpen.png", 100, 7, 40, 40      ; use specific x, y, w, h
  GuiImage "\Masm32\MasmBasic\Res\MasmLogo.png"                  ; upper left corner, original size
  GuiImage "http://masm32.com/board/index.php?action=dlattach;attach=6;type=avatar", 7, 7
  GuiImage "Это тест.jpg", fit     ; Unicode is allowed
  GuiImage wCL$(), 315, 7          ; also via the commandline
  GuiImage 125, 84, 7, 70, 70      ; 125 is a RC_DATA resource ID (IDs must be 48...127)
  GuiImage Files$(ecx), 238, 7, 70, 70                  ; you can dynamically load images
GuiEnd


b) MemState for identifying leaks, e.g. in the Paint event:

GuiParas equ "Hello Masm32 Forum", x400, y100, w250, h300
include \masm32\MasmBasic\Res\MbGui.asm
SetGlobals imgCt
void Split$("Hutch\nDednDave\nErol\nqWord\nrrr314159\nSteve\nMarinus\nBaltoro\nYves\njj2007", "\n", name$())
Event Key
  .if wParam==VK_LEFT && imgCt>48
      dec imgCt
  .elseif wParam==VK_RIGHT && imgCt<57
      inc imgCt
  .endif
  GuiRefresh

Event Paint
  If_ imgCt==0 Then add imgCt, 48
  MemState("WorkingSetSize, abs delta: %__i ", abs delta)
  GuiImage imgCt, fit
  GuiTextBox 7, 99.9-25, 80, 18, name$(imgCt-48)

GuiEnd


In Avatar.exe, when you hit the right key to advance in the list of images, changes in memory use will be printed to the console (see \Masm32\MasmBasic\MbGuide.rtf for all MemState() options):
Code: [Select]
WorkingSetSize, abs delta: 3392 2840
WorkingSetSize, abs delta: 3524 132
WorkingSetSize, abs delta: 3636 112
WorkingSetSize, abs delta: 3572 -64
WorkingSetSize, abs delta: 3620 48
WorkingSetSize, abs delta: 4008 388
WorkingSetSize, abs delta: 4020 12

c) SysLink control implemented:

GuiParas equ "SysLink demo", w600, h400, ICC_LINK_CLASS      ; title, height, classes needed
include \masm32\MasmBasic\Res\MbGui.asm            ; this include file ships with MasmBasic
GuiControl MySysLink, "SysLink", FileRead$("http://www.webalice.it/jj2006/MbLinks.htm")
Event Command
  If_ NotifyCode==NM_CLICK Then wShEx Link$()            ; open link in browser
GuiEnd

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 11550
  • Assembler is fun ;-)
    • MasmBasic
Re: MasmBasic
« Reply #346 on: November 07, 2016, 12:02:51 PM »
Update 7 November (download):

The GuiImage function got two companions: GuiImageCallback and SaveImageToFile:
Code: [Select]
include \masm32\MasmBasic\Res\MbGui.asm ; simple foto viewer, allows rotation without changing the time stamp
  GuiImageCallback RotateOrSave
  SetGlobals rotatemode, savemode, imgCt, maxCt ; *** use at your own risk, test with less valuable photos! ***
  GetFiles wCL ; translate commandline to Files$() array
  dec eax
  mov maxCt, eax
Event Key
  mov ecx, maxCt
  .if wParam==VK_LEFT && imgCt>0
dec imgCt
  .elseif wParam==VK_RIGHT && imgCt<ecx
inc imgCt
  .elseif wParam==VK_R && rotatemode<=7
.if Zero?
and rotatemode, 0 ; 7->0
.else
inc rotatemode
.endif
  .elseif wParam==VK_L
dec rotatemode
.if Sign?
m2m rotatemode, 3 ; 0->3
.endif
  .elseif wParam==VK_S
dec savemode ; save image
  .endif
  GuiCls ; trigger the Paint event
Event Paint
  mov ecx, Files$(imgCt)
  SetWin$ hWnd=Mid$(ecx, Rinstr(ecx, "\")+1))+" - ImageViewer"
  GuiImage ecx, fit
EndOfEvents ; v v v user-defined callback function v v v
RotateOrSave:
  gdi+ GdipImageRotateFlip, gicbObj, rotatemode ; gicb stands for GuiImageCallBackObject
  .if savemode
Clr savemode, rotatemode
SaveImageToFile wFiles$(imgCt)
  .endif
retn
GuiEnd

Full project attached. Tested on Win10, Win7-64 and XP, but use at your own risk. Make a backup of your marriage photos first 8)

Btw, in contrast to the behaviour of the Windows image viewer, this proggie will keep the timestamp after rotation. Use the left and right arrow keys to scroll through the photos, use the l and r keys to rotate and flip images. If you build it yourself, you may use the s key to save the rotated image.

If you see GetLastError, incorrect parameter, it just means that you didn't drag any images over the exe. You can also open a DOS prompt in the exe's folder and paste ImageViewAndRotate.exe http://masm32.com/board/index.php?action=dlattach;attach=6;type=avatar :eusa_dance:

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 11550
  • Assembler is fun ;-)
    • MasmBasic
Bug warning for MasmBasic
« Reply #347 on: November 08, 2016, 12:19:19 PM »
To all who installed version 7 November: There was a little glitch with SaveImageToFile and Unicode file names. It's fixed, please install version 8 November (thanks to Mike for the inspiration :P).

The update allows also Unicode launches now, e.g. passing Chinese text to a MessageBox.exe in Russian:

include \masm32\MasmBasic\MasmBasic.inc      ; download
  Init
  Launch "Окносообщения.exe 您可以将中文文本传递到应用程序。"
EndOfCode

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 11550
  • Assembler is fun ;-)
    • MasmBasic
Re: MasmBasic
« Reply #348 on: November 09, 2016, 12:13:44 PM »
Attached two new examples - extract to a new folder, launch
Code: [Select]
a) LaunchUnicodeExes.exe (should produce what's shown in the screenshot)
b) ImageViewAndRotate.exe
to test them. Grateful for feedback 8)

Sources are included as *.asc files, building requires Masm32 and the latest November 9 MasmBasic.


jj2007

  • Moderator
  • Member
  • *****
  • Posts: 11550
  • Assembler is fun ;-)
    • MasmBasic
Re: MasmBasic
« Reply #349 on: November 26, 2016, 11:28:12 AM »
Download update 26 Nov 16:

Inter alia, GuiImage handles now animated GIFs automatically; search \Masm32\MasmBasic\MbGuide.rtf for .MbGui

Example (attached):

GuiParas equ "GuiImage demo", x100, y100, w540, h180, bnone, m0, deb0  ; no background, margin zero, debug 0
include \masm32\MasmBasic\Res\MbGui.asm                  ; part of MasmBasic
Event Paint
  GuiImageSpeed 200                  ; animation speed 200%
  GuiImage "\Masm32\examples\exampl04\car\car.jpg", fit            ; background
  GuiImage "http://masm32.com/board/index.php?action=dlattach;attach=6;type=avatar", 300, 64, 40, 40
  GuiImage "\masm32\MasmBasic\icons\Smiley.ico", 118, 40, 32, 32
  GuiImage 48, 170, 56, 64, 64                  ; resID, x y w h
GuiEnd
Rsrc            ; **** during assembly, RichMasm exports this section as filename.rc ****
32512 ICON "\\masm32\\MasmBasic\\icons\\Globe.ico"
48 RCDATA "Shooter.gif"
Rsrc


The demo displays
- a static background car.jpg
- an avatar (members only, sorry :biggrin:)
- a smiley (the car needed a little decoration)
- and an animated GIF from the resources

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 11550
  • Assembler is fun ;-)
    • MasmBasic
Re: MasmBasic
« Reply #350 on: December 01, 2016, 01:11:52 AM »
Version 30.11.16 adds a new functionality to the StringToArray command:

include \masm32\MasmBasic\MasmBasic.inc      ; download
  Init
  Let esi="Open"      ; just an example: Open "O", #1, "somefile.txt"
  StringToArray 123, mbi$()    ; 123 is the resource ID
  .While 1
      Let esi=Input$("Search for macro: ", esi)
      .Break .if Len(Trim$(esi))==0
      push mbi$(?)      ; #elements on stack
      xor ecx, ecx
      Cls
      .Repeat
            .if Instr_(mbi$(ecx), esi, 1)==1      ; case-insensitive search
                  .Break .if Instr_(mbi$(ecx), "macro", 5)      ; case-insensitive, full word
            .endif     
            inc ecx
      .Until ecx>=stack
      dec ecx
      .Repeat
            inc ecx
            PrintLine mbi$(ecx)
      .Until Instr_(mbi$(ecx), "endm", 5)==1 || ecx>=stack
      pop edx
  .Endw
  Print "bye"
  Delay 500
EndOfCode

Rsrc      ; when hitting F6, RichMasm exports this section to [filename].rc
123 RCDATA "\\Masm32\\MasmBasic\\MasmBasic.inc"
Rsrc


In this snippet, StringToArray converts an embedded text file (MasmBasic.inc) to a string array.

Project is attached, including the rc file, which is not needed if you build the source with RichMasm.

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 11550
  • Assembler is fun ;-)
    • MasmBasic
Re: MasmBasic
« Reply #351 on: December 12, 2016, 01:59:09 PM »
Update 12 December features an improved handling of toolbars, see an example in the small editor thread.

One new feature, you can extract a file from resources:

  FileWrite "MyFile.txt", "MyString"            ; opens a file and writes a string to file
  FileWrite "MyFile.txt", "MyString", 2         ; same but writes only first 2 bytes
  FileWrite "MyFile.rtf", stream:hRichEdit      ; save contents of the RichEdit control
  FileWrite "MyFile.uctxt", stream:hRichEdit, SF_TEXT or SF_UNICODE  ; same but specify a format
  If_ Not Exist("build.bat") Then FileWrite "build.bat", res:99      ; extract a file from RCDATA resource #99
  FileWrite "MyFile.txt", "MyString", xmm0      ; sets the timestamp in xmm0
Rem      returns Close retval in eax and bytes written in edx

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 11550
  • Assembler is fun ;-)
    • MasmBasic
Re: MasmBasic
« Reply #352 on: December 16, 2016, 11:52:20 AM »
Update 16 December is inspired by Caballero's Ancient DOS sounds thread and uses the new 'get a string array from resources' feature:

include \masm32\MasmBasic\MasmBasic.inc      ; download (needs version 16 December 2016 or later)
  Init
  StringToArray 123, music$()      ; get an array from resources
  For_ ct=0 To eax-1
      Sound music$(ct)
  Next
EndOfCode


Resources:
Code: [Select]
32512 ICON      "\\Masm32\\MasmBasic\\icons\\Smiley.ico"
123 RCDATA      "Song4MasmBasic.txt"

The attachment contains a Pelles C source (BeepWC01.asc) based on Caballero's version for Tiny C. The switch #define Export2MasmBasic 0 in line 2 allows to export his sound as a text file with entries meaning pitch:duration:pause:
Code: [Select]
1045:250:100
650:250:100
650:250:100
1045:250:100
1045:1000:100
650:250:100
« Last Edit: December 16, 2016, 02:07:32 PM by jj2007 »

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 11550
  • Assembler is fun ;-)
    • MasmBasic
Re: MasmBasic
« Reply #353 on: December 20, 2016, 10:59:43 AM »
Please install update 20 December 2016; inter alia, new events Data and DropFiles were added:

      Event Data      ; WM_COPYDATA
            MsgBox 0, CopyData$, "Received:", MB_OK
      Event DropFiles      ; loads the Files$() array; use wRec$() to convert Utf8 file names to true Unicode
            wMsgBox 0, wCat$(wStr$("%i files dropped, first one is\n[", Files$(?))+wRec$(Files$(0))+"], last one is "+CrLf$+"["+wRec$(Files$(Files$(?)-1))+"]"), "Event Dropfiles:", MB_OK or MB_TOPMOST
            Store "~tmpDropped.txt", Files$()      ; write dropped filenames to a text file in Utf8 format


As with GetFiles, file names obtained in the DropFiles Event are in Utf8 format.

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 11550
  • Assembler is fun ;-)
    • MasmBasic
Re: MasmBasic
« Reply #354 on: December 29, 2016, 11:00:31 AM »
MasmBasic update 29 December 2016 is out, please reinstall.

In honour of the "Editor for testing" thread, I've added a new handy macro:

Print "This application uses ComCtl32.dll version ", ComCtl32$()

Output: This application uses ComCtl32.dll version 6.16 (provided your resources and manifests are 100% ok :icon_mrgreen:)

anta40

  • Member
  • ***
  • Posts: 314
Re: MasmBasic
« Reply #355 on: December 29, 2016, 12:41:15 PM »
Found a weird bug on the latest (29 December 2016) version:
While RichMasm is opened, if you click the "X" button, RichMasm won't quit, but only minimze itself instead.
Gotta terminate it manually using Task Manager.

Happens on 32-bit Windows 10.

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 11550
  • Assembler is fun ;-)
    • MasmBasic
Re: MasmBasic
« Reply #356 on: December 29, 2016, 01:03:01 PM »
It's not a bug, it's a feature :P

Seriously: MbGuide.rtf is a special document, it will only minimise if you try close it. But if you close it while it is minimised, it will indeed close (besides, it will also close if no other docs are open in RichMasm).

The reason for this special behaviour is that it also serves as "F1 help". Select a keyword, then hit F1:
- if it's a MasmBasic keyword like Print, the paragraph on Print will be displayed in MbGuide.rtf
- if it's not found in MbGuide.rtf, e.g. CreateWindowEx, RichMasm will pass on the request to the program that follows in \Masm32\MasmBasic\Res\menus.ini, i.e. Win32.hlp:

Code: [Select]
[&Help]
&Basic,\masm32\MasmBasic\MbGuide.rtf#Mb
&WinHLP32,\Masm32\RichMasm\Help\WIN32.HLP

Thus, you get most of the time the help you expect, simply by selecting the keyword and hitting F1.

Note that for the MasmBasic keywords, about 200, RichMasm has another mechanism: Hover over the keyword, e.g. GetFiles, until the mouse cursor turns into a question mark. Then right-click (I'm afraid this is case-sensitive, so getfiles will work only with F1).

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 11550
  • Assembler is fun ;-)
    • MasmBasic
Printing the content of an edit control on paper
« Reply #357 on: January 05, 2017, 01:12:48 PM »
Just found a lengthy article on Printing text in Win32 can be a little complicated posted by Paul Brennick over 8 years ago - I wish I had seen it earlier, it would have saved me a lot of work :(

Anyway, here is a simple method to print the content of a RichEdit control. This snippet reads a file from the commandline, and if you hit Ctrl P, its contents get printed - not in the sense of console print, but in the sense of: on real paper. Here is the source:

include \masm32\MasmBasic\Res\MbGui.asm      ; download (version 5 January 2017 or later)
  GuiControl MyEdit, "RichEdit"             ; create a RichEdit control
  If_ wExist(wCL$()) Then <SetWin$(hMyEdit)=wFileRead$(wExist$)>
Event Key
  If_ KeyCtrl && (VKey==VK_P || VKey==-VK_P) Then <MsgBox 0, Str$("%i pages printed", PrintRtf(hMyEdit, 2)), "PrintRtf:", MB_OK>
GuiEnd


Full project attached. The PrintRtf() macro needs a handle to a RichEdit control, and takes optional parameters as follows (excerpt from \Masm32\MasmBasic\MbGuide.rtf):

 - if text is selected, then only the selection will be printed
 - optional second arg: 0=use default printer, 1=use once the printer dialog, 2=use it always
 - optional: margins in mm, e.g. void PrintRtf(hMyEdit, 0, 20, 20, 15, 20)       ; left, top, right, bottom
 - printer settings like orientation etc are kept for the program's duration

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 11550
  • Assembler is fun ;-)
    • MasmBasic
Download & Unzip
« Reply #358 on: January 11, 2017, 12:42:48 PM »
include \masm32\MasmBasic\MasmBasic.inc      ; download (version 11 January 2017 required)
  Init
  UnzipInit "http://www.terraspace.co.uk/hjwasm217_x86.zip"
  .if Sign?
      Print eax            ; print an error message
  .else
      For_ ecx=0 To edx-1      ; #files returned in edx
            mov esi, Files$(ecx)
            .if Rinstr(esi, "/")     ; zipfiles use forward slashes
                  xchg eax, esi      ; we don't display the full path
                  inc esi
            .endif
            PrintLine Str$(GfSize(ecx)), Tb$, GfDate$(ecx), Spc2$, GfTime$(ecx), Tb$, esi
            .if Instr_(esi, ".pdf", 1)
                  UnzipFile(ecx, Cat$(Left$(MbExeFolder$)+":\Masm32\bin\"))
                  ShEx Cat$("\Masm32\bin\"+esi)
            .endif
      Next
      UnzipExit
  .endif
EndOfCode

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 11550
  • Assembler is fun ;-)
    • MasmBasic
Bugfix for Recall
« Reply #359 on: January 27, 2017, 10:30:53 AM »
With certain types of Unicode text files, Recall added garbage to the last string read. This is fixed with MasmBasic version 27 Jan 2017 - please reinstall. The following will work properly now:

include \masm32\MasmBasic\Res\MbGui.asm      ; download
  Recall "http://www.webalice.it/jj2006/DemoChinese.dat", L$()
Event Paint
  For_ ct=0 To L$(?)-1
      GuiText 7, ct*16+7, Str$("# %i ", ct+1)
      GuiText 90, ct*16+7, L$(ct)
  Next
GuiEnd


The snippet above downloads the text from my personal website. Here is a variant where Chinese text is used in $Data statements:

GuiParas equ "A Chinese Poem", x300, y70, w300, h125, bRgbCol(255, 255, 222)
include \masm32\MasmBasic\Res\MbGui.asm
$Data 月夜
$Data 霜风呼呼地吹着,
$Data 月光明明地照着。
$Data 我和一株顶高的树并排立着
$Data 却没有靠着  。
Read poem$()            ; translate $Data elements to a string array
Event Paint
  For_ ct=0 To poem$(?)-1
      GuiText 7, ct*16+7, Str$("# %i ", ct+1)      ; display the array elements
      GuiText 60, ct*16+7, poem$(ct)
  Next
GuiEnd


The screenshot shows how it looks like in RichMasm and in the little window created by the above code.
Projects attached, feedback welcome of course.