include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Dim MyInts() As DWORD
For_ ct=0 To 999
mov MyInts(ct), Rand(100) ; 0...99
Next
Open "O", #0, "even.txt"
Open "O", #1, "odd.txt"
For_ ct=0 To MyInts(?)-1
test MyInts(ct), 1
setne al
movsx ecx, al
Print #ecx, Str$("%__i ", MyInts(ct))
Next
Close
PrintLine "even.txt: ", FileRead$("even.txt"), CrLf$
Inkey "odd.txt: ", FileRead$("odd.txt")
EndOfCode
Output (shortened):even.txt: 86 82 22 78 2 56 36 14 58 46 68 16 84 12 94 42 0 16 90 42 8 94 90 52 92 90 42 60 88 86 10 64 3
8 92 16 24 92 10 46 34 28 66 74 92 88 82 40 44 26 84 94 48 32 8 0 44 68 40 50 0 2 12 38 12 82 80 0 7
2 76 0 74 8 0 76 64 8 28 46 10 48 6 94 90 10 84 68 62 2 82 96 0 98 20 36 12 96 14 98 8 96
odd.txt: 45 7 13 65 51 57 67 25 97 63 23 77 87 95 39 57 33 87 55 99 5 47 69 79 87 67 19 95 83 49 21 85 4
9 53 7 39 25 31 49 83 17 65 29 27 99 61 19 67 67 77 49 61 73 79 29 47 31 95 49 45 55 81 71 29 7 79 65 2
3 89 93 19 81 17 19 87 83 63 93 25 75 51 79 75 99 7 55 17 19 57 45 33 83 81 87 51 75 81 79 55 93
Ever tried to kill the current executable? It's not that straightforward, for security reasons, but it can be done with little helpers:include \masm32\include\masm32rt.inc ; pure Masm32
.data?
ThisExe db MAX_PATH dup(?)
.code
start:
mov edi, offset ThisExe
invoke lstrcpy, edi, chr$("KillMe.exe ")
invoke lstrcat, edi, rv(GetCommandLine) ; this returns the path of the current exe
invoke WinExec, edi, SW_MINIMIZE
add edi, 11 ; advance to compensate for <KillMe.exe >
print "check your disk to see if "
print edi
print " was killed"
exit
end start
Source and binaries attached, must sit in the same folder as the current exe.
Playing with inline assembly in FreeBasic, source attached; see discussion (https://www.freebasic.net/forum/viewtopic.php?f=7&t=25305&p=239205#p239205). Watch out for the red calls below...
Function LeapYearJ(ByVal yea As ULong) As ULong
Asm
mov ecx, dword ptr [yea]
test ecx, 3
setz al
jne 0f
mov eax, ecx
cdq
push 100
idiv dword ptr [esp] ' 0, 4, 8, ..., 96, 0
test edx, edx ' mod 100=0 should set zero flag
jne 1f
mov eax, ecx
cdq
push 400
idiv dword ptr [esp]
pop eax
dec edx '*** invert the zero flag ***
sets dl ' sign set if edx was zero
test dl, dl
1:
pop eax
setnz al
0:
movsx eax, al
mov [function], eax ' MichaelW
End Asm
End Function
...
for i = 1 to years ' assembly function, inlined by compiler
asm int 3 ' forum
lyears=lyears+LeapYearJ(i)
asm nop
asm nop
asm nop
asm nop
next
00407C20 �> �CC �int3
00407C21 �. �8B45 D0 �mov eax, [ebp-30]
00407C24 �. �8945 D8 �mov [ebp-28], eax
00407C27 �. �C745 DC 00000000 �mov dword ptr [ebp-24], 0
00407C2E �. �C70424 24A04000 �mov dword ptr [esp], offset 0040A02 ; ASCII "C:\FreeBasic\tmp\TmpFile.bas"
00407C35 �. �E8 169EFFFF �call 00401A50 ; �TmpFile.00401A50
00407C3A �. �56 �push esi ; �Arg1
00407C3B �. �8945 C0 �mov [ebp-40], eax ; �
00407C3E �. �C70424 80A04000 �mov dword ptr [esp], offset 0040A08 ; �ASCII "LEAPYEARJ"
00407C45 �. �E8 669EFFFF �call 00401AB0 ; �TmpFile.00401AB0
00407C4A �. �57 �push edi
00407C4B �. �8945 BC �mov [ebp-44], eax
00407C4E �. �8B4D D8 �mov ecx, [ebp-28]
00407C51 �. �F7C1 03000000 �test ecx, 00000003
00407C57 �. �0F94C0 �setz al
00407C5A �.�75 22 �jnz short 00407C7E
00407C5C �. �89C8 �mov eax, ecx
00407C5E �. �99 �cdq
00407C5F �. �6A 64 �push 64
00407C61 �. �F73C24 �idiv dword ptr [esp]
00407C64 �. �85D2 �test edx, edx
00407C66 �.�75 12 �jnz short 00407C7A
00407C68 �. �89C8 �mov eax, ecx
00407C6A �. �99 �cdq
00407C6B �. �68 90010000 �push 190
00407C70 �. �F73C24 �idiv dword ptr [esp]
00407C73 �. �58 �pop eax
00407C74 �. �4A �dec edx
00407C75 �. �0F98C2 �sets dl
00407C78 �. �84D2 �test dl, dl
00407C7A �> �58 �pop eax
00407C7B �. �0F95C0 �setnz al
00407C7E �> �0FBEC0 �movsx eax, al
00407C81 �. �8945 DC �mov [ebp-24], eax
00407C84 �. �8B7D BC �mov edi, [ebp-44]
00407C87 �. �893C24 �mov [esp], edi
00407C8A �. �E8 219EFFFF �call 00401AB0 ; �TmpFile.00401AB0
00407C8F �. �50 �push eax ; �Arg1
00407C90 �. �8B45 C0 �mov eax, [ebp-40] ; �
00407C93 �. �890424 �mov [esp], eax ; �
00407C96 �. �E8 B59DFFFF �call 00401A50 ; �TmpFile.00401A50
00407C9B �. �50 �push eax ; �Arg1
00407C9C �. �8B45 DC �mov eax, [ebp-24] ; �
00407C9F �. �0145 D4 �add [ebp-2C], eax ; �
00407CA2 �. �90 �nop ; �
00407CA3 �. �90 �nop ; �
00407CA4 �. �90 �nop ; �
00407CA5 �. �90 �nop ; �
00407CA6 �. �8B45 D0 �mov eax, [ebp-30] ; �
00407CA9 �. �40 �inc eax ; �
00407CAA �. �8945 D0 �mov [ebp-30], eax ; �
00407CAD �. �3D 80969800 �cmp eax, 989680 ; �
00407CB2 �.�0F86 68FFFFFF �jbe 00407C20 ; �
Build it, then drag an archive over the exe:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
UnzipInit CL$()
.if !Sign?
For_ ecx=0 To edx-1
PrintLine Files$(ecx)
Next
.endif
Inkey CrLf$, "Now copy the names from the console menu"
EndOfCode
Output e.g. from the COM interface archive (http://masm32.com/board/index.php?topic=6313.msg71823#msg71823):
GetComInterface.asc
GetComInterface.dll
Quote from: jj2007 on November 10, 2017, 09:39:13 PM
Ever tried to kill the current executable? It's not that straightforward, for security reasons, but it can be done with little helpers:include \masm32\include\masm32rt.inc ; pure Masm32
.data?
ThisExe db MAX_PATH dup(?)
.code
start:
mov edi, offset ThisExe
invoke lstrcpy, edi, chr$("KillMe.exe ")
invoke lstrcat, edi, rv(GetCommandLine) ; this returns the path of the current exe
invoke WinExec, edi, SW_MINIMIZE
add edi, 11 ; advance to compensate for <KillMe.exe >
print "check your disk to see if "
print edi
print " was killed"
exit
end start
Source and binaries attached, must sit in the same folder as the current exe.
Come on, JJ :badgrin: :badgrin:
Try this instead: http://masm32.com/board/index.php?topic=6713.0
This should work but it doesn't :(
It builds fine and returns S_OK, no error, but it does not set the wallpaper. MSDN says it's supported for XP and earlier - seriously? But even on XP it has no effect.
include \masm32\MasmBasic\MasmBasic.inc
include IActiveDesktop.inc ; IActiveDesktop STRUCT, CLSID_ActiveDesktop, IID_IActiveDesktop (attached)
.code
SetMyWallpaper proc pDesktopImg ; adapted from johnsa's code (http://masm32.com/board/index.php?topic=6736.msg72310#msg72310)
LOCAL pAD
invoke CoCreateInstance, addr CLSID_ActiveDesktop, NULL, CLSCTX_INPROC_SERVER, addr IID_IActiveDesktop, addr pAD
.if eax==S_OK
CoInvoke pAD, IActiveDesktop.SetWallpaper, pDesktopImg, 0
deb 4, "SetWp", $Err$() ; OK, operation completed - but no effect
CoInvoke pAD, IActiveDesktop.Release
.endif
ret
SetMyWallpaper endp
Init
If_ Not rv(CoInitializeEx, 0, COINIT_APARTMENTTHREADED) Then invoke SetMyWallpaper, wChr$("\Masm32\examples\exampl04\car\car.jpg")
invoke CoUninitialize
EndOfCode
Hi Jochen,
Can you try the attached sample?
Hi Erol,
Your example changed slightly the position of the existing wallpaper, but the old image remained...
To be continued ;-)
Hi Jochen,
Not sure but maybe specifying the full path of the image can solve the problem.
WSTR DesktopImg,"test.bmp"
.
.
coinvoke pAD,IActiveDesktop,SetWallpaper,OFFSET DesktopImg,0
GetFullPathName can retrieve the full path.
Hi Erol,
Full path works, thanks a lot! Now I'll try my version 8)
P.S.: It works ;)
include \masm32\MasmBasic\MasmBasic.inc
include IActiveDesktop.inc ; IActiveDesktop STRUCT, CLSID_ActiveDesktop, IID_IActiveDesktop
.code
SetMyWallpaper proc pDesktopImg ; adapted from Vortex (http://masm32.com/board/index.php?topic=6483.msg72338#msg72338) and johnsa's code (http://masm32.com/board/index.php?topic=6736.msg72310#msg72310)
LOCAL pAD, wpo:WALLPAPEROPT
ClearLocals
.if !rv(CoCreateInstance, addr CLSID_ActiveDesktop, NULL, CLSCTX_INPROC_SERVER, addr IID_IActiveDesktop, addr pAD)
add wpo.dwSize, WALLPAPEROPT
add wpo.dwStyle, WPSTYLE_CENTER or WPSTYLE_STRETCH
CoInvoke pAD, IActiveDesktop.SetWallpaper, wRec$(pDesktopImg), 0
CoInvoke pAD, IActiveDesktop.SetWallpaperOptions, addr wpo, 0
CoInvoke pAD, IActiveDesktop.ApplyChanges, AD_APPLY_ALL
CoInvoke pAD, IActiveDesktop.Release
.endif
ret
SetMyWallpaper endp
Init
Let esi=wCL$()
.if !rv(CoInitializeEx, 0, COINIT_APARTMENTTHREADED)
wMsgBox 0, esi, "Set as wallpaper?", MB_OKCANCEL or MB_ICONQUESTION
If_ eax==IDOK Then <invoke SetMyWallpaper, Qtrim$(Utf8$(esi))>
invoke CoUninitialize
.endif
EndOfCode
Full project attached, including a really nice wallpaper - a very special view of a European city. Extract all files to a folder, then drag the jpg over the exe :biggrin:
I am testing a new syntax for Delay (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1212) and would appreciate some results for other Windows versions:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
uselib ntdll
SetGlobals resMin, resMax, resCurrent
Init
invoke NtQueryTimerResolution, addr resMin, addr resMax, addr resCurrent
deb 4, "Timer resolution", resMin, resMax, resCurrent
PrintLine CrLf$, "These lines should print about one second after the start, at ", fTime$(0, "HH:mm:??.123"), " millisecs"
For_ ecx=0 To 4
Delay Rand(500) ; sleep 0..499 milliseconds
NanoTimer()
PrintLine fTime$(0, "HH:mm:ss.fff"), Tb$, "started"
Delay until fTime$(s:1, "HH:mm:ss.123") ; use time$(current plus one second)
PrintLine fTime$(0, "HH:mm:ss.fff "), Tb$, NanoTimer$(), " passed", CrLf$
Next
Inkey Str$("This is Windows version %i", MbWinVersion()), Str$(".%i", ecx)
EndOfCode
Output:
Timer resolution
resMin 156001
resMax 5000
resCurrent 10000
These lines should print about one second after the start, at 04:47:??.123 millisecs
04:47:16.057 started
04:47:17.123 1066 ms passed
04:47:17.159 started
04:47:18.123 964 ms passed
04:47:18.191 started
04:47:19.123 932 ms passed
04:47:19.554 started
04:47:20.123 569 ms passed
04:47:20.450 started
04:47:21.123 673 ms passed
This is Windows version 6.1
The new version of the fTime$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1268) macro can display milliseconds using the fff format specifier. See Microsoft: How to: Display Milliseconds in Date and Time Values (https://docs.microsoft.com/en-us/dotnet/standard/base-types/how-to-display-milliseconds-in-date-and-time-values) for details.
Timer resolution
resMin 156250
resMax 5000
resCurrent 156255
These lines should print about one second after the start, at 23:52:??.123 milli
secs
23:52:37.774 started
23:52:38.123 348 ms passed
23:52:38.161 started
23:52:39.123 962 ms passed
23:52:39.193 started
23:52:40.124 930 ms passed
23:52:40.556 started
23:52:41.123 567 ms passed
23:52:41.451 started
23:52:42.123 672 ms passed
This is Windows version 6.3
From windows 8.1
Thanks, Felipe :t
Here are Win10 results:Timer resolution
resMin 156250
resMax 5000
resCurrent 5007
These lines should print about one second after the start, at 09:35:??.123 millisecs
09:35:03.858 started
09:35:04.123 264 ms passed
09:35:04.159 started
09:35:05.123 964 ms passed
09:35:05.191 started
09:35:06.123 931 ms passed
09:35:06.554 started
09:35:07.123 568 ms passed
09:35:07.450 started
09:35:08.123 672 ms passed
This is Windows version 10.0
Note that even after a reboot, the current resolution is 0.5 milliseconds:resMax 5000
resCurrent 5007
Your Windows 8.1 results are still at the 15.6 ms resolution. It seems they changed it definitely with Win10, which makes sense because a) the hardware got faster and b) even an ordinary browser like FF or PaleMoon sets it to 10000 when you visit YouTube.
So has GetTickCount finally become a high resolution timer?
NOPE. Have a look at these GetTickCount results:ticks systime
0 10:02:51.678
0 10:02:51.679
0 10:02:51.681
0 10:02:51.682
0 10:02:51.683
0 10:02:51.684
0 10:02:51.686
15 10:02:51.688
15 10:02:51.689
15 10:02:51.690
15 10:02:51.691
15 10:02:51.692
15 10:02:51.693
15 10:02:51.695
15 10:02:51.696
15 10:02:51.697
15 10:02:51.698
15 10:02:51.700
15 10:02:51.701
15 10:02:51.702
31 10:02:51.703
31 10:02:51.705
31 10:02:51.706
Between each line, there is a Sleep(1), and the high resolution timer shows that the systemtime gets adjusted in one milliseconds increments; but GetTickCount keeps reporting with its low 15.625 ms granularity 8)
Hi Jochen,
Here are my results, XP 64-bit :
Timer resolution
resMin 156250
resMax 10000
resCurrent 156250
These lines should print about one second after the start, at 13:11:??.123 milli
secs
13:11:17.531 started
13:11:18.125 591 ms passed
13:11:18.156 started
13:11:19.125 966 ms passed
13:11:19.187 started
13:11:20.125 935 ms passed
13:11:20.562 started
13:11:21.125 560 ms passed
13:11:21.453 started
13:11:22.109 669 ms passed
This is Windows version 5.2
Thanks, Erol. So it starts always 2 ms later, 125 instead of 123... ::)
Similar for XP-32, a Virtual Machine:Timer resolution
resMin 100144
resMax 10032
resCurrent 100144
These lines should print about one second after the start, at 11:16:??.123 milli
secs
11:16:29.859 started
11:16:30.129 254 ms passed
11:16:30.159 started
11:16:31.121 963 ms passed
11:16:31.191 started
11:16:32.122 931 ms passed
11:16:32.553 started
11:16:33.124 570 ms passed
11:16:33.454 started
11:16:34.125 669 ms passed
This is Windows version 5.1
A little exercise in deleting elements from a string array:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
void NanoTimer() ; start the timer
Recall "TestFile.txt", b$() ;
PrintLine NanoTimer$(), " for loading the file into the b$() text array"
void NanoTimer() ; start the timer
xor ecx, ecx
.Repeat
If_ Instr_(b$(ecx), "devil", 5) Then <mcs Delete b$(ecx) : dec ecx>
inc ecx
.Until ecx>=b$(?)
Inkey NanoTimer$(), " for deleting the devil. Save the file (y)?"
If_ eax=="y" Then Store "NoDevil.txt", b$()
EndOfCode
Result on an i5:3458 µs for loading the file into the b$() text array
4954 µs for deleting the devil. Save the file (y)?
The required text file is here (http://www.webalice.it/jj2006/pics/testfile.zip) - unzip to the folder where the attached exe sits.
Same as above, but not line-based. Words are removed with Replace$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1079):
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
void NanoTimer() ; start the timer
Let esi=FileRead$("TestFile.txt")
PrintLine NanoTimer$(), " for loading the file"
void NanoTimer() ; start the timer
Let esi=Replace$(esi, "devil", 0, 5) ; mode 5: case-insensitive, full word, i.e. devils & devilish still there ;-)
Inkey NanoTimer$(), " for deleting the devil. Save & see the file (y)?"
If_ eax=="y" Then <mcs FileWrite "NoDevil.txt", esi : ShEx "NoDevil.txt">
EndOfCode
2392 µs for loading the file
6269 µs for deleting the devil. Save & see the file (y)?
Work in progress, looks fine so far:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
include uMirror$.inc
SetGlobals a$="Enter text here"
SetGlobals r$="Введите текст здесь" ; "Enter text here" in Russian
SetGlobals cm$, c$="在這裡輸入文字", c4$="<see attached source>" ; "Enter text here" and some 4-byte encoded string in Chinese
Init
PrintLine uMirror$(a$)
PrintLine uMirror$(r$)
Let cm$=uMirror$(c$)
uMsgBox 0, cm$, c$, MB_OK
EndOfCode
ereh txet retnE
ьседз тскет етидевВ
P.S.: For the first time, I see the SMF software (or the browser??) choke over a UTF-8 string, see the red part above. It works fine in RichMasm, see attached *.asc source. This is a rare type of UTF-8 using 4-byte encoding.
Just learned a new trick from deltarho[1859] (https://www.freebasic.net/forum/viewtopic.php?f=7&t=26208&sid=cce04fa09c9fca354830eeb043f64a98#p241539) - clear the file cache for better testing:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
ClearFileCache MACRO fname
push ecx
ClearLastError
invoke CreateFile, repargA(f$), GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN or FILE_FLAG_NO_BUFFERING, 0
invoke CloseHandle, eax
pop ecx
ENDM
SetGlobals f$
Init
PrintLine "with file caching, ", Cpu$(), ":" ; OPT_Arg1 C:\Masm32\MasmBasic\AscUser\FatFile.txt
Let f$=CL$()
PrintLine "Reading ", f$
.if !Exist(f$)
Let f$="\Masm32\include\Windows.inc"
MsgBox 0, Cat$("Commandline empty or invalid - using this file now:"+CrLf$+f$), "Hi", MB_OK
.endif
For_ ecx=0 To 9
NanoTimer()
Recall f$, L$() ; file to array L$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1172)
Print Str$("%i strings, ", eax), NanoTimer$()
NanoTimer()
Let esi=FileRead$(f$) ; file to buffer esi (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1075)
PrintLine Str$("\t%i bytes, ", LastFileSize), NanoTimer$()
Next
PrintLine CrLf$, "no caching:"
For_ ecx=0 To 9
ClearFileCache f$
NanoTimer()
Recall f$, L$()
Print Str$("%i strings, ", eax), NanoTimer$()
ClearFileCache f$
NanoTimer()
Let esi=FileRead$(f$)
PrintLine Str$("\t%i bytes, ", LastFileSize), NanoTimer$()
Next
Inkey "--- hit any key ---"
EndOfCode
The results are pretty clear - upper half uses the cache, lower half doesn't:with file caching, Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz:
Reading C:\Masm32\MasmBasic\AscUser\FatFile.txt
3038300 strings, 294 ms 404739200 bytes, 209 ms
3038300 strings, 354 ms 404739200 bytes, 237 ms
3038300 strings, 337 ms 404739200 bytes, 231 ms
3038300 strings, 346 ms 404739200 bytes, 229 ms
3038300 strings, 328 ms 404739200 bytes, 235 ms
3038300 strings, 332 ms 404739200 bytes, 229 ms
3038300 strings, 339 ms 404739200 bytes, 236 ms
3038300 strings, 337 ms 404739200 bytes, 238 ms
3038300 strings, 339 ms 404739200 bytes, 237 ms
3038300 strings, 334 ms 404739200 bytes, 239 ms
no caching:
3038300 strings, 4999 ms 404739200 bytes, 4903 ms
3038300 strings, 4998 ms 404739200 bytes, 4938 ms
3038300 strings, 5011 ms 404739200 bytes, 5061 ms
3038300 strings, 5010 ms 404739200 bytes, 4919 ms
3038300 strings, 5002 ms 404739200 bytes, 4897 ms
3038300 strings, 5003 ms 404739200 bytes, 4903 ms
3038300 strings, 5025 ms 404739200 bytes, 4923 ms
3038300 strings, 5016 ms 404739200 bytes, 4921 ms
3038300 strings, 4994 ms 404739200 bytes, 4906 ms
3038300 strings, 5038 ms 404739200 bytes, 4904 ms
Project attached. You can drag any plain text or Unicode file over the exe, but note that on Win7-64, for example, HeapAlloc begins to choke at around 900MB. If you haven't used the file for a while, the very first line will show a higher time - it needs to be cached...
Work in progress, an extension of this post. (http://masm32.com/board/index.php?topic=5976.msg72774#msg72774)
Fearless and José put me on the right track, see Select a single cell in a listview (http://masm32.com/board/index.php?topic=6788.msg72804#msg72804). So here is the proof that it is indeed possible to use a listview control as a replacement for Excel :icon_mrgreen:
You may have to click two or three times on a cell to select it. Hitting Return does not work. Saving the edits works, provided that you selected another cell before; the resulting temp file will open with your user-defined *.tab viewer, Excel or LibreOffice, whatever. Note that both Excel and OpenCalc are too dumb to recognise that it's a UTF-8 coded *.tab file. RichMasm shows it correctly, though.
The control is Unicode-aware, as you can see in cell R3C1 ;)
P.S.: There is a little mystery about the order of the header columns. I swear it's not my fault.
return in the listview or return in the editbox doesnt work?
Might be possible to get NM_RETURN and handle last known cell (row,col) to "edit" with the editbox placement. Or maybe some handling of WM_CHAR / WM_KEYDOWN directly in a subclass of listview parent, or NM_RETURN in that subclass. Might require IsDialogMessage in messageloop and handle want all keys or want return thing from dlg message thing (forget exact name of the msg event)
Slow down, man :P
Seriously: I will check what is available. Just discovered a very old article: Easy Navigation Through an Editable List (https://www.codeguru.com/cpp/controls/listview/editingitemsandsubitem/article.php/c937/Easy-Navigation-Through-an-Editable-List-View.htm) Posted by Lee Nowotny on June 19th, 1999 - just a bit over 18 years ago. Good to see that I'm not the first one to attack this. Fortunately I have a nice tool called deb (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1019):Event Message
inc msgCount
deb 4, "main WndProc", chg:msgCount
With another one for the listview subproc, you can wade through tons of stuff like this:main WndProc 810 WM_NOTIFY: -121
SubListview 811 WM_NOTIFY: -121
main WndProc 813 WM_PARENTNOTIFY
SubListview 817 WM_MOUSEACTIVATE
SubListview 819 WM_LBUTTONDOWN
main WndProc 821 WM_MOUSEACTIVATE
main WndProc 823 WM_NOTIFY: NM_TOOLTIPSCREATED
main WndProc 825 WM_KILLFOCUS
SubListview 826 WM_CAPTURECHANGED
SubListview 827 WM_IME_SETCONTEXT
main WndProc 829 WM_IME_SETCONTEXT
SubListview 832 WM_SETFOCUS
main WndProc 874 WM_NOTIFY: -121
main WndProc 881 WM_NOTIFY: -121
main WndProc 888 WM_NOTIFY: -121
main WndProc 895 WM_NOTIFY: -121
main WndProc 902 WM_NOTIFY: -121
main WndProc 909 WM_NOTIFY: -121
main WndProc 911 WM_NOTIFY: -121
main WndProc 913 WM_NCACTIVATE
main WndProc 915 WM_GETTEXT
main WndProc 917 WM_ACTIVATE
SubListview 918 WM_CAPTURECHANGED
main WndProc 920 WM_ACTIVATEAPP
SubListview 921 WM_KILLFOCUS
I will need SubListview 5030 WM_LBUTTONDOWN, the built-in activation is too clumsy. And there are many more interesting messages to exploit...
Playtime :P
The main features are implemented: Loading, editing, navigation and saving. Let me know if it works on your machine.
There will be two ways to create it:
if 0
Recall "FatTable.tab", some$(), tab
GuiControl MyData, "table", y500, h500, some$()
else
GuiControl MyData, "table", y500, h500, "FatTable.tab"
endif
The first one assumes that you have already a two-dimensional array, so you pass it as some$().
The second one simply passed a filename.
Confused source, exe and two other files attached. Extract to a folder and launch the exe.
Working JJ :t
Still don't work ESC nor Ctrl-Z :biggrin:
Quote from: HSE on December 29, 2017, 10:56:12 AM
Still don't work ESC nor Ctrl-Z :biggrin:
Thanks - it's work in progress and needs a lot of cleanup.
Another topic, floating point comparisons:
include \masm32\MasmBasic\MasmBasic.inc
SetGlobals REAL10 MyPI=3.141592653589793238, hiPI=3.141592653589793239, loPI=3.141592653589793237
SetGlobals REAL10 MyPI30=3.141592653589793238e30, hiPI30=3.141592653589793239e30, loPI30=3.141592653589793237e30
SetGlobals REAL10 MyPIm30=3.141592653589793238e-30, hiPIm30=3.141592653589793239e-30, loPIm30=3.141592653589793237e-30
Init
PrintLine Str$("\nPI=%Jf", MyPI), " - top precision:"
Fcmp hiPI, PI, top
.if Zero?
PrintLine "they are equal"
.elseif FcmpGreater
PrintLine "hiPi is greater"
.else
PrintLine "hiPi is lesser"
.endif
Fcmp loPI, PI, top
.if Zero?
PrintLine "they are equal"
.elseif FcmpGreater
PrintLine "loPi is greater"
.else
PrintLine "loPi is lesser"
.endif
PrintLine "---- high precision:"
Fcmp hiPI, PI, hi
.if Zero?
PrintLine "they are equal"
.elseif FcmpGreater
PrintLine "hiPi is greater"
.else
PrintLine "hiPi is lesser"
.endif
Fcmp loPI, MyPI, hi
.if Zero?
PrintLine "they are equal"
.elseif FcmpGreater
PrintLine "loPi is greater"
.else
PrintLine "loPi is lesser"
.endif
PrintLine Str$("\nPI30=%Jf", MyPI30), " - top precision:"
Fcmp hiPI30, MyPI30, top
.if Zero?
PrintLine "they are equal"
.elseif FcmpGreater
PrintLine "hiPi is greater"
.else
PrintLine "hiPi is lesser"
.endif
Fcmp loPI30, MyPI30, top
.if Zero?
PrintLine "they are equal"
.elseif FcmpGreater
PrintLine "loPi is greater"
.else
PrintLine "loPi is lesser"
.endif
PrintLine "---- high precision:"
Fcmp hiPI30, MyPI30, hi
.if Zero?
PrintLine "they are equal"
.elseif FcmpGreater
PrintLine "hiPi is greater"
.else
PrintLine "hiPi is lesser"
.endif
Fcmp loPI30, MyPI30, hi
.if Zero?
PrintLine "they are equal"
.elseif FcmpGreater
PrintLine "loPi is greater"
.else
PrintLine "loPi is lesser"
.endif
PrintLine Str$("\nPI-30=%Jf", MyPIm30), " - top precision:"
Fcmp hiPIm30, MyPIm30, top
.if Zero?
PrintLine "they are equal"
.elseif FcmpGreater
PrintLine "hiPi is greater"
.else
PrintLine "hiPi is lesser"
.endif
Fcmp loPIm30, MyPIm30, top
.if Zero?
PrintLine "they are equal"
.elseif FcmpGreater
PrintLine "loPi is greater"
.else
PrintLine "loPi is lesser"
.endif
PrintLine "---- high precision:"
Fcmp hiPIm30, MyPIm30, hi
.if Zero?
PrintLine "they are equal"
.elseif FcmpGreater
PrintLine "hiPi is greater"
.else
PrintLine "hiPi is lesser"
.endif
Fcmp loPIm30, MyPIm30, hi
.if Zero?
PrintLine "they are equal"
.elseif FcmpGreater
PrintLine "loPi is greater"
.else
PrintLine "loPi is lesser"
.endif
Inkey
EndOfCodeOutput (as expected):
PI=3.141592653589793238 - top precision:
hiPi is greater
loPi is lesser
---- high precision:
they are equal
they are equal
PI30=3.141592653589793238e+30 - top precision:
hiPi is greater
loPi is lesser
---- high precision:
they are equal
they are equal
PI-30=3.141592653589793238e-30 - top precision:
hiPi is greater
loPi is lesser
---- high precision:
they are equal
they are equal
Theoretically, if the source code is a template like in Delphi, then it's time to start writing a good decompiler for a MasmBasic :P
PI=3.141592653589793238 - top precision:
hiPi is greater
loPi is lesser
---- high precision:
they are equal
they are equal
PI30=3.141592653589793238e+30 - top precision:
hiPi is greater
loPi is lesser
---- high precision:
they are equal
they are equal
PI-30=3.141592653589793238e-30 - top precision:
hiPi is greater
loPi is lesser
---- high precision:
they are equal
they are equal
For syntax and options, see Lof() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1036)
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
.if !Exist("GigaTest.txt")
Inkey "Are you sure you want to create a 4 GB file in ", CurDir$(), "(y)?", CrLf$
.if eax=="y"
ClearLastError
Open "O", #1, "GigaTest.txt"
.if eax==INVALID_HANDLE_VALUE
Print "Open: ", Err$()
.else
ClearLastError
Let edi=FileRead$("\Masm32\include\Windows.inc")+FileRead$("\Masm32\include\WinExtra.inc")
PrintLine Str$("Len=%i bytes\n", Len(edi)) ; 2045966 bytes
Print "Read: ", Err$()
ClearLastError
For_ ecx=0 To 2500 ; 2501*2045966=5116960966
PrintLine #1, edi
Next
Print "Write: ", Err$()
Close
.endif
.endif
.endif
Inkey Str$("Filesize = %u bytes", edx::Lof("GigaTest.txt")), Str$(" = %3f GB", edx::Lof("GigaTest.txt")/(1 shl 30))
EndOfCode
Output: Filesize = 5116965968 bytes = 4.77 GB
Hi JJ!
I extract part of the program. Still not working very well, but the main features are there (I think).
Regards
LATER: New file. I forget a little problem if first column is activated.
A lot later: New file. I forget something else.
Very nice work :t
Drag files over the exe and tell me how your mail client reacts. I've tested it on Win7-64 and Win10 Home with Thunderbird.
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
mapiMsg MapiMessage <>
Init
Dll "Mapi32"
Declare MAPISendMail, 5
mov edi, offset mapiMsg
Mapi equ [edi.MapiMessage]
mov Mapi.ulReserved, CP_UTF8 ; does not work *)
mov Mapi.lpszSubject, Chr$("Greetings from Masm")
mov Mapi.lpszNoteText, cfm$("Hi folks,\nNever was sending mails easier!\nSincerely,\njj2007")
GetFiles CL ; get a list of files from the commandline
mov Mapi.nFileCount, eax
xchg eax, ecx
Dim MapiFiles(ecx) As MapiFileDesc
or MapiFiles(ecx, nPosition), -1
For_ ecx=0 To ecx-1
push Files$(ecx)
lea eax, MapiFiles(ecx, lpszPathName)
pop [eax]
Next
lea eax, MapiFiles(0, ulReserved)
mov Mapi.lpFiles, eax
.if MAPISendMail(0, 0, addr mapiMsg, MAPI_DIALOG, 0)
MsgBox 0, Str$("Mapi error %i", eax), "An error occurred:", MB_OK
.endif
EndOfCodeProject attached. Note that there is a blank line before the "Hi folks"; in theory, the nPosition member of the MapiFileDesc structure could influence that, but according to this post on ExpertExchange (https://www.experts-exchange.com/questions/28399412/MapiSendMail-attachments-don%27t-display.html), "It appears that MapiSendMail does not perform as Microsoft has stated in their documentation" 8)
*) MapiMessage structure (https://msdn.microsoft.com/en-us/library/windows/desktop/dd296732%28v=vs.85%29.aspx):
QuoteulReserved
Reserved; must be zero or CP_UTF8. If CP_UTF8, the following are UTF-8 instead of ANSI strings: lpszSubject, lpszNoteText, lpszMessageType, lpszDateReceived, lpszConversationID.
And this is simply not true, Redmond - see https://stackoverflow.com/questions/9943314/windows-mapi-unicode-issue :icon_redface:
Could be useful for testing sort algos etc:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Dll "RandomStrings" ; the DLL must be in the same folder
Declare RandomString
.Repeat
For_ ecx=0 To 5
Print RandomString(), " "
Next
Inkey cfm$("- more (no=n)?\n")
.Until eax=="n" || eax==VK_ESCAPE
EndOfCode
Output:
imprisoning barked channel superstitious practical spectre - more (no=n)?
currants shower agitation lions motherly forces - more (no=n)?
negus proofs devil chose observation individuals - more (no=n)?
quarrelled whistled place commanded stipulation cannot - more (no=n)?
deeds settled taught verdict unsocial goeth - more (no=n)?
nefarious herald extinguishes accounted system military - more (no=n)?
worse colouring attacks transfixed hearts binding - more (no=n)?
instruments rally singly sword until profit - more (no=n)?
tranquilly luring convinced unchecked trade hears - more (no=n)?
violent packet sternly tearing kneeled crumbled - more (no=n)?
... etc ...
i am thinking JJ is the REAL MASM Wizard for sure.
Thanks - too much honour :icon_redface:
Here is version 2, with pseudo and real random modes (and 20,000 words for choice):
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Dll "RandomStrings" ; the DLL must be in the same folder
Declare RandomString, 1
.Repeat
For_ ecx=0 To 5
Print RandomString(0), " " ; 0=pseudo, 1=real random
Next
Inkey cfm$("- more (no=n)?\n")
.Until eax=="n" || eax==VK_ESCAPE
EndOfCode
In mode 0, the sequence is always identical. It looks random, and is random according to some popular measures of randomness, but you'll always see the same strings. This is particular useful if, for example, your sort algo stumbles over a specific word, and you want to debug that event. It's also a bit faster - in "real" mode, one Million strings need almost one second on my i5. The pseudo mode is 70 times faster.
Little demo for image rotation (strangely enough, this GdiPlus function has never been used in this forum ::)):
GuiParas equ "Image rotation demo", w400, h440
include \masm32\MasmBasic\Res\MbGui.asm
GuiImageCallback Rotate ; user-defined function
SetGlobals halfWidth, halfHeight, REAL4:rotateAngle, movX, movY
Event Paint
imul eax, GuiWidth, 100 ; width*100/128
sar eax, 8
add eax, 20
mov halfWidth, eax
imul eax, GuiHeight, 100 ; height*100/128
sar eax, 8
mov halfHeight, eax
GuiImage 99, 0, 0, halfWidth, halfHeight ; res ID, x, y, w, h
GuiCls ; trigger next paint event
EndOfEvents
Rotate:
fild halfWidth ; an integer
fadd FP4(35.0) ; add a fixed x offset
fstp movX ; Gdi+ needs a float
fild halfHeight
fadd FP4(32.0)
fstp movY
gdi+ GdipTranslateWorldTransform, giGraphics, movX, movY, MatrixOrderPrepend ; move to the middle
gdi+ GdipRotateWorldTransform, giGraphics, rotateAngle, MatrixOrderPrepend ; rotate
fld rotateAngle ; add one degree for next paint event
fadd FP4(1.0)
fstp rotateAngle
ret
GuiEnd
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
include Geo.inc
Init
PrintLine "GEO_LCID: ", Tb$, Geo$(GEO_LCID)
PrintLine "GEO_RFC1766:", Tb$, Geo$(GEO_RFC1766), CrLf$
Inkey "I live in ", Geo$(), " (aka ", Geo$(GEO_OFFICIALNAME), ") at ", Geo$(GEO_LATITUDE), " North, ", Geo$(GEO_LONGITUDE), " East"
EndOfCode
Output:GEO_LCID: 00000809
GEO_RFC1766: en-it
I live in Italia (aka Repubblica italiana) at 42.768 North, 12.492 East
Inspired by the Campus post PUSH & POP question (http://masm32.com/board/index.php?topic=7113.msg76861#msg76861) by DayDreamer:
include \Masm32\MasmBasic\Res\JBasic.inc ; ## builds in 32- or 64-bit mode with ML and UAsm
include PushPopXmm.inc
.code
xvalue0 OWORD 11111111222222223333333344444444h
xvalue1 OWORD 55555555666666667777777788888888h
Init ; OPT_64 1 ; put 0 for 32 bit, 1 for 64 bit assembly
PrintLine Chr$("This code was assembled with ", @AsmUsed$(1), " in ", jbit$, "-bit format")
movups xmm0, xvalue0
movups xmm7, xvalue1
usedeb=1
deb 4, "before", x:xmm0, x:xmm7
ppxInit
PushX xmm0
PushX xmm7
PopX xmm0 ; note the order: we
PopX xmm7 ; are swapping values
deb 4, "popped & swapped", x:xmm0, x:xmm7
; PopX xmm0 ; uncomment to see the error handling
MsgBox 0, "Wow, it works!!!!", "Hi", MB_OK or MB_SETFOREGROUND
EndOfCode
Output:
This code was assembled with UAsm64 in 64-bit format
before
x:xmm0 3333333344444444h
x:xmm7 7777777788888888h
popped & swapped
x:xmm0 7777777788888888h
x:xmm7 3333333344444444h
Attached the macro and a standard MasmBasic example.
great macros :t
Quote from: jj2007 on May 03, 2018, 09:39:29 AM
Output:GEO_LCID: 00000809
GEO_RFC1766: en-it
I live in Italia (aka Repubblica italiana) at 42.768 North, 12.492 East
Are tou sure?
:biggrin:
GEO_LCID: 00000C0A
GEO_RFC1766: es-es
I live in España (aka Reino de España) at 40.396 North, -3.551 East
Well, I do live in Italy, but I haven't check how exact the LatLong figures are. Any idea how the OS determines a user's position?
Quote from: jj2007 on May 07, 2018, 08:08:04 AM
Any idea how the OS determines a user's position?
OS don't know user's position. I think it's just a point in country center. You declare country when setting language and location. In spanish language España it's default country. In italian language... let me think... mmh ::)
Quote from: jj2007 on May 07, 2018, 08:08:04 AM
Well, I do live in Italy, but I haven't check how exact the LatLong figures are. Any idea how the OS determines a user's position?
Same as timezone= the capital of your country?cant you check Rome in google maps and see if its same long and latitude?
Quote from: daydreamer on May 07, 2018, 02:47:29 PMSame as timezone= the capital of your country?cant you check Rome in google maps and see if its same long and latitude?
Yes, you can: Enter the result as e.g. 42.768, 12.492 into Google Maps. It seems that the Geo$() function returns the middle of the country. In theory, you can fine-tune your location, but it's a per user setting in the Control Panel, be careful.
QuoteGEO_LCID: 00000416
GEO_RFC1766: pt-us
I live in Estados Unidos (aka Estados Unidos da América) at 39.450 North, -98.908 East
Hey, the little guy placed me in the US!
Curious if masm or masm basic also supports print in hexadecimal like c++ cout has?
Quote from: daydreamer on May 11, 2018, 04:17:15 AM
Curious if masm or masm basic also supports print in hexadecimal like c++ cout has?
Sure:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
mov ecx, 123456789
Print Str$("Decimal:\t%i\n", ecx)
mov esi, 12345678h
PrintLine "Hexadecimal:", Tb$, Hex$(esi)
movd xmm0, esi
pshufd xmm0, xmm0, 0
deb 4, "for debugging", ecx, x:esi, x:xmm0
Inkey "-- hit any key --"
EndOfCodeDecimal: 123456789
Hexadecimal: 12345678
for debugging
ecx 123456789
x:esi 12345678
x:xmm0 12345678 12345678 12345678 12345678
The Masm32 SDK has the hex$() macro, e.g. as print hex$(esi), 13, 10
Sometimes I need to save a webpage but don't want to open it. So I copy the URL and run this proggie (source+exe attached):
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Let esi=Clip$() ; get URL from clipboard, e.g. http://masm32.com/board/index.php?action=unread
.if Instr_(esi, "://")
FileWrite "SaveLinkAsTemp.html", Cat$(Chr$("<html><head><title>Temporary link</title></head>", 13, 10, "<body>", 60, "a href=", 34)+esi+Chr$(34, 62, "Right-click here and choose 'Save Link as...' to download ")+esi+Chr$(60, "/a", 62, "</body></html>"))
ShEx "SaveLinkAsTemp.html" ; launch the browser
.else
MsgBox 0, esi, "No URL found:", MB_OK
.endif
EndOfCode
Attached a little file DownloadMasm32.exe that does something entirely harmless:
include \masm32\MasmBasic\MasmBasic.inc
Init
Let esi="0.75=draob?php.xedni/draob/moc.23msam//:ptth"
PrintLine esi
Let edi=FileRead$(Mirror$(esi))
Inkey NoTag$(edi)
EndOfCode
In addition, the attachment contains a project that finds http:// and https:// in files, even if they are mirrored; just drag a file over SpyWareScanMB.exe 8)
Warning: While SpyWareScanMB.exe finds interesting http:// and https:// matches in exes and dlls, it is not a replacement for an AntiVirus. Malware writers use more sophisticated tricks to hide their URLs.
This snippet
- reads a text file into a RichEdit control (its name is supplied by the commandline)
- formats the first line in bold
- on request via the menu, prints the text.
To test it, extract all files to a temporary folder and drag the text file over the exe (the *.asc file is the source as RTF).
If needed, the whole process can be automated, i.e. eliminate the Event Menu step and just run the exe with the commandline argument, then exit automatically. See PrintRtf (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1384) for printer dialog handling options.
GuiMenu equ @File, &Open, &Print, E&xit
GuiParas equ "Print formatted text demo", x100, y100, w400, h200; , cblack, b00FFFFD0h
include \masm32\MasmBasic\Res\MbGui.asm
MakeFont hMyFont, Height:20, "Lucida Handwriting"
GuiControl MyEdit, "RichEdit", font hMyFont
SetGlobals f$, charfmt:CHARFORMAT2
Let f$=FileRead$(CL$()) ; read the text file passed in the commandline
SetWin$ hMyEdit=f$
.if Instr_(f$, CrLf$)
dec edx ; index of CrLf-1
invoke SendMessage, hMyEdit, EM_SETSEL, 0, edx
m2m charfmt.cbSize, CHARFORMAT2
m2m charfmt.dwMask, CFM_BOLD ; CharFtMask
m2m charfmt.dwEffects, CFE_BOLD ; Character effects
invoke SendMessage, hMyEdit, EM_SETCHARFORMAT, SCF_SELECTION, ADDR charfmt
invoke SendMessage, hMyEdit, EM_SETSEL, 0, 0
.endif
Event Menu
.if MenuID==1
void PrintRtf(hMyEdit, 1) ; 0=use default printer, 1=ask for printer dialog
.endif
GuiEnd
include \masm32\include\masm32rt.inc
.data
txFile db "extracted.exe", 0
bytesWritten dd ?
.code
start:
invoke FindResource, 0, 99, RT_RCDATA
.if eax
xchg eax, ebx ; hRes
push rv(SizeofResource, 0, ebx)
push rv(LoadResource, 0, ebx) ; returns pointer to content in eax
invoke CreateFile, addr txFile, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0
xchg eax, esi
pop eax ; pointer to content
pop ecx ; size in bytes
invoke WriteFile, esi, eax, ecx, addr bytesWritten, 0
invoke CloseHandle, esi
invoke WinExec, addr txFile, SW_SHOW
.endif
exit
end start
:t
Just encountered a case where I had to check if a file was older than dd.month.year, and needed a snippet to perform this check:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
.if Exist(CL$())
sub esp, 2*FILETIME ; create two structures on the stack
movlps QWORD ptr [esp], TimeSF (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1328)("02.07.2018 11:16:50") ; European format!
lea ecx, [esp+QWORD]
movlps QWORD ptr [ecx], GfLastWrite (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1067)(-1) ; the lower QWORD returns the FILETIME
invoke CompareFileTime, ecx, esp
add esp, 2*FILETIME ; correct the stack
.if signed eax<0
wMsgBox 0, wCL$(), "File is older. Process?", MB_YESNOCANCEL
.if eax==IDYES
; ... do stuff ...
.endif
.else
wMsgBox 0, wCL$(), "File is younger:", MB_OK
.endif
.else
wMsgBox 0, wCL$(), "No such file:", MB_OK
.endif
EndOfCode
Create a hundred folders, write a testfile to each of them:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
For_ ecx=0 To 99
Let esi=Str$("New Folder%i", ecx)
MakeDir esi
.Break .if !Zero?
Print "+"
Let esi=esi+"\test.txt"
PrintLine Str$(ecx), Tb$, esi
FileWrite esi, Str$("Test %i", ecx)
Next
EndOfCode
An edit control that allows to enter only valid decimal numbers. Bug feedback welcome :biggrin:
P.S.: PNG_LoadFile à la MasmBasic attached, using GuiImage (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1362). The *.asc source opens in WordPad, but here it is anyway for those who can't find WordPad or RichMasm (http://masm32.com/board/index.php?topic=5314.0):
include \masm32\MasmBasic\Res\MbGui.asm
Event Paint
GuiImage "car.png", fit
GuiEnd
Quote from: jj2007 on July 14, 2018, 05:10:28 AM
An edit control that allows to enter only valid decimal numbers. Bug feedback welcome :biggrin:
oops! :greensml:
You did say 'decimal' numbers, not integers, right?
Also for the png image 'fit' viewer, when resizing from either side or from the top, the image resizes reflecting the new dimensions of the window.
But when resizing the window from the bottom, it crops or cuts off the image.
Quote from: zedd151 on July 19, 2018, 09:20:26 AMYou did say 'decimal' numbers, not integers, right?
Thanks for the feedback. Try 1234567890.123456784 vs 1234567890.123456785 - this is REAL10 precision, and it has its limits, i.e. around 18 digits.
MovVal ST(0), Win$(@hWnd)
SetWin$ hMyResult=Str$("Result=%Jf", ST(0)v)
If you replace the "J" with an "I", it displays one digit less, and all numbers will be correct.
Quotewhen resizing the window from the bottom, it crops or cuts off the image.
Interesting. It works correctly on this Win7-64 machine. Just made a test with my WinXP VM, and you are right: When resizing from left or top, it works (but with tremendous flicker - on Win7, it's smooth); when resizing from right or bottom, it crops. Hmmm :(
Windows XP Pro SP3 in VirtualBox <-- may have something to do with it?
The screen capture shows the top image resized from lower right upward
The bottom shows resized from top left downward.
Windows 7 32 bit works as advertised.
With the newer hardware that is out these days, it's a shame to have to run xp in a virtual machine.
Quote from: zedd151 on July 19, 2018, 10:34:20 AM
Windows XP Pro SP3 in VirtualBox <-- may have something to do with it?
I doubt it, VM and real machine will probably behave the same. Googling for
"wm_sizing" "xp" yields lots of results, it could be a known problem.
Quote from: jj2007 on July 19, 2018, 10:52:06 AM
Googling for "wm_sizing" "xp" yields lots of results, it could be a known problem.
Only way to know for sure is to get someone that has XP installed natively on their system to test the program.
Hi,
Tested the ShowPng on Windows XP. Seems to crop on resizing.
maximize and restore causes the image to fit the window. Is
that what was wanted?
Regards,
Steve
Quote from: FORTRANS on July 20, 2018, 01:12:44 AMon Windows XP. Seems to crop on resizing.... Is that what was wanted?
Steve,
No, not really, see reply #53+#54. It's limited to XP, though. Apparently one message is not being sent correctly in XP.
Hi Jochen,
Okay, how about:
Upper left Resize
Top Resize
Upper right Resize
Right Crop
Lower right Crop
Bottom Crop
Lower left Resize
Left Resize
Cropped to maximize, Resize
Maximum to restore, Resize
More useful I hope? Or am I still missing things as usual?
Regards,
Steve N.
Your analysis is absolutely correct: XP behaves like that. Those resizing attempts that actually move the window trigger the resizing of the image. All others don't. But I would have to dig deep into the code to find a workaround, and I am not sure if XP is important enough to justify that effort :icon_mrgreen:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Let esi="Нажмите на эту кнопку" ; "Click on this button" in Russian
Print Str$("Len(esi)=\t%i\n", Len(esi)) ; treated as Ansi
Print Str$("uLen(esi)=\t%i\n", uLen(esi)) ; treated as Utf8
Print Str$("wLen(esi)=\t%i\n", wLen(wRec$(esi))) ; treated as Unicode (wRec$ (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1381): convert Utf8 to wide string)
Print
Let esi="在這裡輸入文字" ; "Enter text here" in Chinese
Print Str$("Len(esi)=\t%i\n", Len(esi)) ; treated as Ansi
Print Str$("uLen(esi)=\t%i\n", uLen(esi)) ; treated as Utf8
Print Str$("wLen(esi)=\t%i\n", wLen(wRec$(esi))) ; treated as Unicode
EndOfCode
Len(esi)= 39
uLen(esi)= 21
wLen(esi)= 21
Len(esi)= 21
uLen(esi)= 7
wLen(esi)= 7
Note that the uLen macro does not check whether the string is valid Utf8 (credits to PaulSquires (https://www.freebasic.net/forum/viewtopic.php?f=6&t=26888&sid=a194cedab48d078a6e22d2eca6cae2f7#p249682)). Example:
Let esi="Click on this button"+Chr$(169) ; Ansi with one extra character
.if rv(MultiByteToWideChar, CP_UTF8, MB_ERR_INVALID_CHARS, esi, Len(esi), NULL, 0) == 0
PrintLine "[", esi, "] is not a valid Utf8 string"
.else
Print "[", esi, "]", Str$("has %i bytes and is a valid Utf8 string\n", eax)
.endif
[Click on this button©] is not a valid Utf8 string
Len(esi)= 21
uLen(esi)= 21
wLen(esi)= 21
Full project attached.
Hi Jochen
You wondered why strlen for UTF8 should be different proc than regular (single-byte encodings like ASCII/ANSI/ISO/etc) strlen.
Now probably you can review that thread just for fun :biggrin:
http://masm32.com/board/index.php?topic=2369.msg24543#msg24543
Welcome back, my friend! Yes, that thread was interesting - almost 5 years ago. Time flies. In the meantime, I had forgotten that exchange of views, but MasmBasic does have some dedicated macros, like uLen, uLeft$ and uMid$...
Quote from: jj2007 on July 21, 2018, 07:12:05 AM
Welcome back, my friend! Yes, that thread was interesting - almost 5 years ago. Time flies. In the meantime, I had forgotten that exchange of views, but MasmBasic does have some dedicated macros, like uLen, uLeft$ and uMid$...
Yes, that was purpose of that thread and algo research (making utf8 chars walking faster if possible)... strlen is the simplest usage of that implementation, but more important are string-manipulation functions like basic-like ones you mentioned :biggreen: It is harder to Mid$ something from the random dataflow of utf8 string than from other - fixed-width (length/size) - encodings like ASCII/ANSI/UTF16/32/etc are.
So, you implemented those in your MB project, very cool and nice :T :t
I rolled my own, actually. Your code is too complex for my old brain. But we could organise a speed test ;-)
uLen MACRO arg
push esi
push edx
ifdifi <esi>, <arg>
mov esi, repargA(arg)
endif
xor edx, edx
.While 1
lodsb
.Break .if !al
inc edx
.if al>=10000000b ; 128
inc esi
.if al>=11100000b
inc esi
.if al>=11110000b
inc esi
.if al>=11111000b
inc esi
.endif
.endif
.endif
.endif
.Endw
xchg eax, edx
pop edx
pop esi
EXITM <eax>
ENDM
Attached a little demo project; I'd like to get some feedback on the behaviour of the MRU menu. The archive has source code (*.asc), but it won't build with the current MasmBasic version.
I am testing three macros:
- SetMru "somefile.ini": reads recently used files from disk and adds them to the menu
- AddMru SomeFile$: adds opened or saved filename to the menu
- MenuText$(): returns the full file path in response to a menu event
Finally,
Event Close
StoreUtf8 Cat$(MbExeFolder$+"\EditorDemo.ini"), Mru$(), 8 ; write up to 8 strings to file
... serves to store the MRU list to disk. Note that only a few functions of the toolbar are actually implemented - use at your own risk, test it with non-important files 8)
This is work in progress, grateful for feedback, especially also from people using non-Latin alphabets.
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
SetGlobals MyString
Init
PrintLine "You can hit keys as you like, but when the countdown approaches zero, you should stop"
For_ ecx=1000 To 0 Step -1
Print At(0, 3) Str$(ecx), " "
Delay 2
Next
Let MyString=Input$ (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1041)("Your hobby: ", "Basic programming (this string is editable)", flush)
MsgBox 0, MyString, "The string:", MB_OK or MB_SETFOREGROUND
EndOfCode
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
N=500000000 ; 500 Mio
PrintCpu 0
For_ outerloop=0 To 5
NanoTimer()
Dim MyBytes(N) As BYTE
PrintLine "allocating took ", NanoTimer$()
NanoTimer()
For_ ecx=0 To N-1
mov MyBytes(ecx), cl
Next
PrintLine "filling took ", NanoTimer$()
NanoTimer()
% Erase MyBytes()
PrintLine "erasing took ", NanoTimer$(), CrLf$
Next
Inkey
EndOfCode
Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz
allocating took 13 µs
filling took 1228 ms
erasing took 40 ms
allocating took 24 µs
filling took 1229 ms
erasing took 40 ms
allocating took 22 µs
filling took 1228 ms
erasing took 38 ms
allocating took 23 µs
filling took 1227 ms
erasing took 37 ms
allocating took 23 µs
filling took 1229 ms
erasing took 38 ms
allocating took 18 µs
filling took 1232 ms
erasing took 40 ms
Writing the bytes to file costs an extra 7-9 seconds:
NanoTimer()
Open "O", #1, "MyBytes.dat"
Store #1, MyBytes()
Close
PrintLine "writing took ", NanoTimer$()
Usage: Drag a csv file over the attached exe. The required fixed size is calculated automatically, see results below.
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
SetGlobals f$, records, maxcol, record$, endreached ; see FB thread: CSV to fixlength data files (https://www.freebasic.net/forum/viewtopic.php?f=3&t=26946&p=250502&sid=bedd271c83f18dff8305ce58a49aa5fb#p250499)
Init
NanoTimer()
Dim MxLen() As DWORD ; OxPT_Arg1 J:\Masm32\MasmBasic\BugTests\TableControl\FatTable.csv
Dim fix$()
Let f$=CL$()
.if !Exist(f$)
GetFiles *.csv
SortFiles
Let f$=Files$(0)
.endif
Recall f$, L$(), csv
mov records, eax
For_ ct=0 To eax-1
For_ ecx=0 To 99
xchg Len(L$(ct, ecx)), eax
.if eax>MxLen(ecx)
mov MxLen(ecx), eax
Print "*"
.endif
Next
Next
Print CrLf$, "Length of records: "
For_ ecx=0 To 127
mov eax, MxLen(ecx)
.Break .if !eax
add esi, eax
Print Str$(eax), " " ; record length
Next
mov maxcol, ecx
lea esi, [esi+ecx+1]
Print Str$("\nLen of full record=%i", esi), Str$(", %i columns", maxcol)
Let edi=Space$(esi)
ComposeString MACRO maxcol
mov ecx, maxcol
Clr endreached
.Repeat
lodsb
.if !al
inc endreached
.endif
.if endreached || !al || !ecx
mov al, 32
.endif
stosb
dec ecx
.Until Sign?
ENDM
For_ ct=0 To records-1
push edi
mov esi, L$(ct, 0)
ComposeString MxLen(0)
For_ col=1 To maxcol-1
mov esi, L$(ct, col)
ComposeString MxLen(col)
Next
xor eax, eax
stosb
pop edi
Let fix$(ct)=edi
Next
.if Instr_(f$, ".csv", 1)
mov [eax], Mirror$(".fix")
PrintLine CrLf$, "Storing to ", f$
Store f$, fix$()
.endif
Inkey "Converting ", f$, " took ", NanoTimer$()
EndOfCode
For a 19MB csv database, the whole process takes about 2 seconds, but the resulting file gets bloated to >100MB:Length of records: 11 646 348 13 141 82 20 4 10 20 4 10 28 4 10 20 4 10 25 4 10 25 4 11 25 4 11 25 4 11 25 4 11 25 4 11 25 4 10 27 4 11 26 4
11 28 4 11 27 4 11 23 4 11 23 4 15 23 4 15 23 4 15 23 4 15 25 4 15 23 4 15 23 4 11 22 4 10 12 4 6 9 4 4 9 4 4 9 4 4 9 4
Len of full record=2376, 92 columns
Storing to C:\Masm32\MasmBasic\BugTests\TableControl\FatTable.fix
Converting C:\Masm32\MasmBasic\BugTests\TableControl\FatTable.fix took 2367 ms
Numbers only in a RichEdit control (full project attached):
SubEdit proc <cb> uses rbx hWnd, uMsg, wParam, lParam ; <cb> indicates that it is a callback function
mov ebx, wParam ; default: process wParam
cmp uMsg, WM_CHAR
jne @F
cmp wParam, "9"
jle @F
Print Str$("char %i not allowed\n", ebx)
xor ebx, ebx ; don't process
@@: jinvoke CallWindowProc, PreviousWndProc, hWnd, uMsg, ebx, lParam
ret
SubEdit endp
(http://www.webalice.it/jj2006/pics/DosSymbols.png)
Full project attached (the exe includes the fake database). Use cursor up/down to scroll among the records, hit Escape to quit.
Here is the source (50 lines of code):
include \masm32\MasmBasic\MasmBasic.inc ; symbols (https://altcodeunicode.com/windows-alt-codes-symbols/)
include NewAtMacro.inc
SetGlobals TopRecord
Init
invoke ShowWindow, rv(GetConsoleWindow), SW_MAXIMIZE
StringToArray 100, d$(), tab
ConsoleColor cDarkGray, cBlack
Print 0 ; override codepage setting
$Data 11C #, 91C LastName, O1C FirstName, Z1C Street, s1C City, 6+1A ProdCode, A+1A UnitPrice
Read Header$() ; create a string array
invoke SetConsoleOutputCP, 437 ; we need that codepage for the graphic characters
Print ConvertCp$(ResFile$(101), CP_UTF16, 437) ; resource 101 (boxes.txt) is Unicode and needs to be converted
invoke SetConsoleOutputCP, 1252 ; Windows default
For_ ecx=0 To Header$(?)-1
xchg Header$(ecx), esi
Print At(#esi) esi ; the new At() macro has some goodies... it can set xy and colours based on the start of the string
Next
Print At(0, 20) "Use cursor up/down to scroll, Escape to quit" ; override codepage setting
.While 1
m2m ecx, 3 ; start displaying data in row 3
For_ ct=TopRecord To TopRecord+6
mov esi, Cat$(Chr$("1", ecx+48, "F ")+Str$("%______i", ct)) ; right-aligned record number
Print At(#esi) Left$(esi, 19)
mov esi, Cat$(Chr$("9", ecx+48, "F ")+d$(ct, 0)+String$(20, " "))
Print At(#esi) Left$(esi, 19)
mov esi, Cat$(Chr$("O", ecx+48, "F ")+d$(ct, 1)+String$(10, " "))
Print At(#esi) Left$(esi, 10)
mov esi, Cat$(Chr$("Z", ecx+48, "E ")+d$(ct, 2)+String$(20, " "))
Print At(#esi) Left$(esi, 18)
mov esi, Cat$(Chr$("s", ecx+48, "E ")+d$(ct, 3)+String$(10, " "))
Print At(#esi) Left$(esi, 10)
mov esi, Cat$(Chr$("6+", ecx+48, "F9 ")+d$(ct, 4)+String$(10, " "))
Print At(#esi) Left$(esi, 10)
mov esi, Cat$(Chr$("A+", ecx+48, "C ")+d$(ct, 5)+String$(9, " "))
Print At(#esi) Left$(esi, 9)
add ecx, 2 ; next data two rows down
Next
Inkey
.Break .if eax==VK_ESCAPE
mov edx, TopRecord
.if eax==VK_UP
dec edx
.elseif eax==VK_DOWN
inc edx
.endif
mov TopRecord, Max(0, edx)
sub d$(?), 7
mov TopRecord, Min(eax, TopRecord)
.Endw
EndOfCode
How does it work?
mov esi, Cat$(Chr$("z", ecx+48, "EC ")+d$(ct, 3)) ; City: Column z (=10+26+26), row ecx, foregroundcolour E (yellow), bg C (red)
Print At(#esi) Left$(esi, 13, "_") ; for short strings, fill right half with "_"
esi points to a string with a specific format:
ABCD this is a string
A is the print column, where
0 0
9 9
A 10+0=10
Z 10+25=35
a 10+26+0=36
z 10+26+25=61
B is the print row, using the same scheme.
C and B are the foreground and background colours, with
cBlack = 0 ; http://support.microsoft.com/kb/319883
cDarkBlue = 1
cDarkGreen = 2
cDarkCyan = 3
cDarkRed = 4
cDarkMagenta = 5
cDarkYellow = 6
cGray = 7
cDarkGray = 8
cBlue = 9
cGreen = 10 ; A
cCyan = 11 ; B
cRed = 12 ; C
cMagenta = 13 ; D
cYellow = 14 ; E
cWhite = 15 ; F
The attachment contains sources and files to build this; including a new Left$() macro:
Print Left$("some string", 20, "_") ; prints some string_________
The third optional argument is a fill char for padding the string to the right in case it's shorter than 20 chars. Can be quite useful in some situations, inter alia for overwriting the previous field when filling the screen as shown above. In the attached exe, the Street column does not have padding, and when scrolling through the database you can see the effect.
Not exactly perfect here:
Interesting ::)
Which OS version? Console is maximised, I suppose?
Just checked with Win XP, and that looks indeed like what you posted. Unlike Win7 & Win10, the console isn't enlarged enough by the invoke ShowWindow, rv(GetConsoleWindow), SW_MAXIMIZE. You have to enlarge it manually in the console properties, then save "for all future windows with the same name", and restart. Then it works.
On Win7, the display refreshes immediately, i.e. in milliseconds. With Win10, it seemed initially very slow, but now it has become fast. I have yet to find out if there is a pattern - mysteries of Windows 8)
In 7-32 I changed console properties and that look a lot better. Some characters are not intended ones, I think.
Weird, codepage 437 should be pretty standard. Which language is your OS?
Spanish. Selected: Español(España)
UASM v2.46, Jan 8 2018, Masm-compatible assembler.
Portions Copyright (c) 1992-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.
*** MasmBasic version 25.12.2017 ***
** SetProcessUserModeExceptionPolicy
** read Header$()
DosSymbols.asm(69) : Error A2228: Missing right parenthesis in expression
MbFor(218)[MasmBasic.inc]: Macro called from
DosSymbols.asm(69): Main line code
DosSymbols.asm(69) : Error A2228: Missing right parenthesis in expression
MbFor(243)[MasmBasic.inc]: Macro called from
DosSymbols.asm(69): Main line code
DosSymbols.asm(69) : Error A2210: Syntax error: ]
MbFor(256)[MasmBasic.inc]: Macro called from
DosSymbols.asm(69): Main line code
DosSymbols.asm: 100 lines, 1 passes, 199 ms, 0 warnings, 3 errors
There is a problem moving up and down because Quantity doesn't stop when reach limits.
Quote from: HSE on August 20, 2018, 01:43:37 AM
Spanish. Selected: Español(España)
...
There is a problem moving up and down because Quantity doesn't stop when reach limits.
Weird. Sorry for the build errors, it seems the current MasmBasic version is not compatible with my newest one.
Re Quantity, that's by design: It is set by Rand() and does its job even if the position does not change. Just for testing...
Quote from: HSE on August 19, 2018, 10:59:37 AM
In 7-32 I changed console properties and that look a lot better. Some characters are not intended ones, I think.
Can you check the attached version, please? I replaced codepage 437 with another one.
Worst !
Still not posible to assemble :eusa_naughty:
Except first character, I see perfectly boxes.txt with MASM32 Unicode Editor .
Yes, it won't build, sorry. I am working on a major MasmBasic update, and that will take some time.
Still, the exe should work OK. It's now codepage UTF8, and your machine should understand that. Anybody else having such problems?
Ja!
Default font configuration here is "Fuentes de mapas de bits".
Changing that to "Lucida Console" work perfect, also previous version :t
With third option Nidud's "Doszip Console" letters dont' look so well.
Thanks :biggrin:
One day I will find a way to set the console font programmatically ;)
Attached an archive with
- an exe compiled with FreeBasic
- that needs the second file, a DLL using Input$("prompt", "prefilled for editing") (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1041)
All three are brilliant with the FourmiLab ENT (http://www.fourmilab.ch/random/) test, but only the first two have been tested with PractRand. If you need a very good hi-speed PRNG, stick with MasmBasic Rand() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1030).
Testing 32000000 numbers generated, CPU: Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz
833 ms for Pcg32 FB, last result: 817EEE81
390 ms for Pcg32 Asm, last result: 817EEE81
107 ms for MB Rand(), last result: 8E1531E8
771 ms for Pcg32 FB, last result: 15670CA0
378 ms for Pcg32 Asm, last result: 15670CA0
107 ms for MB Rand(), last result: C44145CE
764 ms for Pcg32 FB, last result: D422CFAD
398 ms for Pcg32 Asm, last result: D422CFAD
118 ms for MB Rand(), last result: 2C03A5D1
840 ms for Pcg32 FB, last result: ECD79C2B
377 ms for Pcg32 Asm, last result: ECD79C2B
107 ms for MB Rand(), last result: BFFA6298
766 ms for Pcg32 FB, last result: 5248B397
377 ms for Pcg32 Asm, last result: 5248B397
107 ms for MB Rand(), last result: 675D19A4
766 ms for Pcg32 FB, last result: 54A9248A
382 ms for Pcg32 Asm, last result: 54A9248A
110 ms for MB Rand(), last result: E59BD461
202 bytes for Pcg32
111 bytes for Pcg
26 bytes for MbRand
ENT results:
Testing 8000000 numbers generated, CPU: Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz
############ ENT results Pcg32 (FB):
Entropy = 7.999994 bits per byte.
Optimum compression would reduce the size
of this 32000000 byte file by 0 percent.
Chi square distribution for 32000000 samples is 274.62, and randomly
would exceed this value 25.00 percent of the times.
Arithmetic mean value of data bytes is 127.4936 (127.5 = random).
Monte Carlo value for Pi is 3.141756196 (error 0.01 percent).
Serial correlation coefficient is 0.000371 (totally uncorrelated = 0.0).
############ ENT results Pcg32 (MB):
Entropy = 7.999994 bits per byte.
Optimum compression would reduce the size
of this 32000000 byte file by 0 percent.
Chi square distribution for 32000000 samples is 274.62, and randomly
would exceed this value 25.00 percent of the times.
Arithmetic mean value of data bytes is 127.4936 (127.5 = random).
Monte Carlo value for Pi is 3.141756196 (error 0.01 percent).
Serial correlation coefficient is 0.000371 (totally uncorrelated = 0.0).
############ ENT results MB Rand(-1):
Entropy = 7.999995 bits per byte.
Optimum compression would reduce the size
of this 32000000 byte file by 0 percent.
Chi square distribution for 32000000 samples is 213.24, and randomly
would exceed this value 95.00 percent of the times.
Arithmetic mean value of data bytes is 127.4976 (127.5 = random).
Monte Carlo value for Pi is 3.141366946 (error 0.01 percent).
Serial correlation coefficient is -0.002006 (totally uncorrelated = 0.0).
* PCG32.zip: Comparing SIMD vs FPU-based methods for mapping a QWORD (0...-1) to a double (0.0 ... 1.0)
* GuiTableControl.zip: latest tests with a spreadsheet control
* GetGccVersion.zip: echo a short version string to your FB output window. Source:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Let edi=MbExeFolder$+"Win32\gcc.exe --version"
Let esi=Launch$(edi)
.if dword ptr [esi]==Mirror$("La$?")
PrintLine edi, Chr$(": no answer.", 13, 10, 10, "Check if GetGccVersion.exe sits above the bin\Win32 folder")
.else
PrintLine esi
Let ebx=Extract$(esi, "project)", 0)
Let ecx=Extract$(esi, "(C)", "Free Soft")
PrintLine "gcc version", ebx, " (", Trim$(ecx), ")"
.endif
EndOfCode
Sample output of gcc.exe --version:
gcc.exe (i686-win32-sjlj-rev2, Built by MinGW-W64 project) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Sample output of the attached batch file:
** compiling somefile.bas with -t 2000 -gen gcc -Wc -Ofast -s console **
gcc version 8.1.0 (2018)
This is what I got running it the second time. Could not read the fonts as they were so small, copied it into my text editor first.
-8910786331291756801 0.5169453050529669 0.5169453050529669718
6730337785313497944 0.3648523424199086 0.3648523424199086505
-5974524377861002328 0.6761203844977746 0.6761203844977747243
2695508904680093984 0.1461238305204089 0.1461238305204090194
8502576381364090992 0.4609255892199442 0.4609255892199443155
-385216515766393995 0.9791173708364389 0.9791173708364389530
3034485871582637989 0.1644998087173231 0.1644998087173232765
2286379689918253082 0.1239448913468051 0.1239448913468051986
-4131041815082152639 0.7760557744729732 0.7760557744729734316
-853861575098310801 0.9537120712638256 0.9537120712638258368
7275931949313747423 0.3944290613151327 0.3944290613151328044
7844949285505684199 0.4252755529191934 0.4252755529191934295
140239247804428540 0.007602384856864708 0.007602384856864721546
timings for 100 Mio loops:
280 ms for SIMD
414 ms for FPU
197 ms for SIMD
409 ms for FPU
212 ms for SIMD
431 ms for FPU
223 ms for SIMD
378 ms for FPU
201 ms for SIMD
363 ms for FPU
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Let esi=FileRead$(CL$())
Let edi="SendMessage" ; just a proposal
.While 1
PrintLine "Hit Escape, Return to exit", Space$(40)
Let edi=Input$("Search for ", edi)
.Break .if !Len(edi)
xor ebx, ebx
NextMatch:
inc ebx
.if !Instr_(ebx, esi, edi, 1)
PrintLine "No match for [", edi, "] "
.else
mov ebx, edx
xchg eax, ecx
sub ecx, 4*16
ConsoleColor cBlue
Print HexDump$(ecx, 64)
ConsoleColor cWhite
add ecx, 4*16
.Repeat
PrintLine HexDump$(ecx)
add ecx, 512
Inkey "more? (Return: continue, F3: next match)", Cr$
cmp eax, VK_F3
je NextMatch
.Until eax!=13
ConsoleColor
.endif
.Endw
EndOfCode
Output:
Hit Escape, Return to exit
Search for SendMessage
002A899C 6E 65 64 09 65 71 75 20 73 64 77 6F 72 64 20 70 ned.equ sdword p
002A89AC 74 72 20 0D 0A 73 74 61 63 6B 09 65 71 75 20 3C tr ..stack.equ <
002A89BC 44 57 6F 72 64 20 50 74 72 20 5B 65 73 70 5D 3E DWord Ptr [esp]>
002A89CC 0D 0A 73 6D 09 65 71 75 20 69 6E 76 6F 6B 65 20 ..sm.equ invoke
002A89DC 53 65 6E 64 4D 65 73 73 61 67 65 2C 20 0D 0A 4C SendMessage, ..L
002A89EC 61 73 74 46 69 6C 65 4E 61 6D 65 24 09 65 71 75 astFileName$.equ
002A89FC 20 6F 66 66 73 65 74 20 77 66 64 2E 63 46 69 6C offset wfd.cFil
002A8A0C 65 4E 61 6D 65 0D 0A 4C 61 73 74 46 69 6C 65 53 eName..LastFileS
002A8A1C 69 7A 65 09 65 71 75 20 77 66 64 2E 6E 46 69 6C ize.equ wfd.nFil
002A8A2C 65 53 69 7A 65 4C 6F 77 0D 0A 77 43 72 4C 66 24 eSizeLow..wCrLf$
002A8A3C 09 65 71 75 20 6F 66 66 73 65 74 20 77 43 72 4C .equ offset wCrL
002A8A4C 66 5F 74 78 74 0D 0A 77 4C 66 24 09 65 71 75 20 f_txt..wLf$.equ
002A8A5C 6F 66 66 73 65 74 20 77 4C 66 5F 74 78 74 0D 0A offset wLf_txt..
002A8A6C 77 54 62 24 09 65 71 75 20 6F 66 66 73 65 74 20 wTb$.equ offset
002A8A7C 77 54 61 62 5F 74 78 74 0D 0A 43 72 4C 66 09 65 wTab_txt..CrLf.e
002A8A8C 71 75 20 31 33 2C 31 30 0D 0A 0D 0A 4D 62 45 76 qu 13,10....MbEv
002A8A9C 43 74 3D 30 0D 0A 45 6E 64 4F 66 43 6F 64 65 20 Ct=0..EndOfCode
002A8AAC 4D 41 43 52 4F 20 61 72 67 64 0D 0A 20 20 69 66 MACRO argd.. if
002A8ABC 65 20 4D 62 45 78 69 74 0D 0A 09 45 78 69 74 20 e MbExit...Exit
002A8ACC 61 72 67 64 0D 0A 20 20 65 6E 64 69 66 0D 0A 20 argd.. endif..
002A8ADC 20 69 66 20 54 63 6C 43 74 43 20 67 74 20 31 0D if TclCtC gt 1.
002A8AEC 0A 09 54 72 79 43 61 74 63 68 45 6E 64 0D 0A 20 ..TryCatchEnd..
002A8AFC 20 65 6E 64 69 66 0D 0A 20 20 69 66 20 4D 62 45 endif.. if MbE
002A8B0C 76 43 74 0D 0A 09 47 75 69 45 6E 64 20 30 0D 0A vCt...GuiEnd 0..
002A8B1C 20 20 65 6E 64 69 66 0D 0A 20 20 69 66 20 4D 62 endif.. if Mb
002A8B2C 4E 61 54 69 43 74 20 61 6E 64 20 31 0D 0A 09 65 NaTiCt and 1...e
002A8B3C 63 68 6F 0D 0A 09 65 63 68 6F 20 23 23 23 20 63 cho...echo ### c
002A8B4C 68 65 63 6B 20 79 6F 75 72 20 4E 61 6E 6F 54 69 heck your NanoTi
002A8B5C 6D 65 72 20 63 61 6C 6C 73 20 23 23 23 0D 0A 20 mer calls ###..
002A8B6C 20 65 6E 64 69 66 0D 0A 20 20 65 6E 64 20 73 74 endif.. end st
002A8B7C 61 72 74 0D 0A 45 4E 44 4D 0D 0A 43 6C 65 61 72 art..ENDM..Clear
002A8B8C 4C 61 73 74 45 72 72 6F 72 20 4D 41 43 52 4F 0D LastError MACRO.
002A8B9C 0A 20 20 69 66 20 75 73 65 64 65 62 0D 0A 09 70 . if usedeb...p
002A8BAC 75 73 68 61 64 0D 0A 09 69 6E 76 6F 6B 65 20 53 ushad...invoke S
002A8BBC 65 74 4C 61 73 74 45 72 72 6F 72 2C 20 30 0D 0A etLastError, 0..
002A8BCC 09 70 6F 70 61 64 0D 0A 20 20 65 6E 64 69 66 0D .popad.. endif.
more? (Return: continue, F3: next match)
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
SetGlobals left, right, row ; geeks for geeks: Print string of odd length in 'X' format (https://www.geeksforgeeks.org/print-string-of-odd-length-in-x-format/)
Init
Let edi="Assembly is a great language"
.While 1
Let edi=Input$("\n\n\n\nGimme a string please: ", edi)
.Break .if !Len(edi)
Clr left, row
mov right, eax
Cls
.Repeat
mov edx, left
movzx eax, byte ptr [edi+edx]
Print At(left, row) Chr$(eax)
inc left
dec right
mov edx, right
movzx eax, byte ptr [edi+edx]
Print At(right, row) Chr$(eax)
inc row
.Until right<=0
.Endw
EndOfCode
A e
s g
s a
e u
m g
b n
l a
y l
i t
s a
e
a r
g
g
a r
e
s a
i t
y l
l a
b n
m g
e u
s a
s g
A e
So you spotted G-point with MasmBasic 8)
I've got a video converter (DVDVideoSoft) that works fine but it has the bad habit to set the time stamp of the output file to "right now". Fortunately, it creates new file names that contain the original date and time, e.g. C:\Users\Jochen\Videos\VID_20170621_153022.mp4 meaning original file was created 21 June 2017, 15:30:22
Here is a little program that touches the file and sets the time stamp back (source & exe attached, use at your own risk). Just drag any file from the folder over the exe:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
SetGlobals gfMatch$, pathLeft
Init
Let gfMatch$=CL$()
mov pathLeft, Rinstr(eax, "\")
.Repeat
inc eax
.Until byte ptr [eax]<="."
xchg eax, ecx
Let gfMatch$=Left$(gfMatch$, pathLeft)+"*"+ecx
PrintLine gfMatch$
GetFiles gfMatch$
deb 4, "matches", eax
SortFiles ; optional: latest files first
For_ ecx=0 To eax-1
mov esi, Files$(ecx)
.if InstrOr(esi, ".mp4" or ".avi" or ".gp", 1)
PrintLine GfDate$(ecx), Spc2$, GfTime$(ecx), Tb$, Files$(ecx)
.if Instr_(esi, "201") ; 20160602_170844
xchg eax, esi
.if byte ptr [esi+8]=="_"
Let edi=Mid$(esi, 7, 2)+"."+Mid$(esi, 5, 2)+"."+Left$(esi, 4)+Spc2$+Mid$(esi, 10, 2)+":"+Mid$(esi, 12, 2)+":"+Mid$(esi, 14, 2)
; ClearLastError
Touch Files$(ecx), TimeSF(edi)
; deb 4, "Touch", eax, $Err$()
.if Exist(Files$(ecx))
PrintLine GfDate$(-1), Spc2$, GfTime$(-1)
.endif
.else
PrintLine "skipped, unknown date format: ", Tb$, esi
.endif
.else
PrintLine "skipped, no 201 detected: ", Tb$, esi
.endif
.else
PrintLine "skipped, not a video file: ", Tb$, esi
.endif
Next
Inkey "ok?"
EndOfCode
Typical output (the second, shorter line shows the changed date):
C:\Users\Jochen\Videos\*.mp4
matches eax 18
07.11.2018 12:27:53 C:\Users\Jochen\Videos\20160602_170844.mp4
02.06.2016 17:08:44
07.11.2018 12:27:42 C:\Users\Jochen\Videos\VID_20170531_195446.mp4
31.05.2017 19:54:46
07.11.2018 12:12:22 C:\Users\Jochen\Videos\VID_20170621_153022.mp4
Generates two Million random strings and sorts them using QSort (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1175) (which is an in-place mergesort).
Source & binaries attached: Extract exe and dll to the same folder, then run the exe. Typical result for a Core i5:
11 s for writing 2 Millon strings
106 ms for reading 5 Million strings
3.2 seconds for sorting 5 Million strings
With my slow AMD:62 s for writing 2 Millon strings
383 ms for reading 5 Million strings
12. seconds for sorting 5 Million strings
Where has your code gone? I've tested it (attached), and that's a really fast sort, Timo - interesting :t
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
NoTitleCase$ equ <Chr$(".a.an.and.are.as.but.by.for.is.in.or.the.that.")> ; this is the default, inspired by Lauren Ipsum (https://writing.stackexchange.com/questions/4621/which-words-should-not-be-capitalized-in-title-case), but you can use others
Init
Let ecx="World bank and OECD are organisations that - as a rule - i consider very powerful"
PrintLine ecx
Inkey TitleCase$(ecx)
EndOfCode
Output:
World bank and OECD are organisations that - as a rule - i consider very powerful
World Bank and OECD are Organisations that - as a Rule - I Consider Very Powerful
Inspired by Munair on the FreeBasic forum (https://www.freebasic.net/forum/viewtopic.php?f=7&t=27174) :icon14:
Just for fun, a little demo showing the use of the PSHUFB instruction, and some macro tricks:
include \masm32\MasmBasic\MasmBasic.inc
SwapBytes MACRO pBytes
if type(pBytes) eq REAL8
movlps xmm0, pBytes
else
mov edx, pBytes
movups xmm0, oword ptr [edx]
endif
mov eax, esp
and esp, -16
push 00010203h ; the magic numbers
push 04050607h
push 08090a0bh
push 0c0d0e0fh
PSHUFB xmm0, oword ptr [esp] ; shuffle the bytes! (will crash on very old CPUs, sorry...)
movups oword ptr [esp], xmm0
if type(pBytes) eq REAL8
fld qword ptr [esp]
xchg eax, esp
EXITM <ST(0)> ; leave the double in the FPU
else
xchg eax, esp
EXITM <> ; the bytes are in xmm0, but the macro is not used as a function
endif
ENDM
.data
MyReal8 REAL8 1234567890.1234567890
thestring db "!taerg si 23msaM", 0
.data?
SwappedR8 REAL8 ?
out$ db 20 dup(?)
Init
PrintLine "Original:", Tb$, offset thestring
SwapBytes(offset thestring) ; return 16 bytes in xmm0
movups oword ptr out$, xmm0
PrintLine "Swapped:", Tb$, offset out$
Print Str$("\nMyReal8 \t%Hf", MyReal8), Str$("\nas BigEndian\t%Hf", SwapBytes(MyReal8)) ; SwapBytes leaves the double in the FPU
fstp SwappedR8
Inkey Str$("\nreconverted\t%Hf\n", SwapBytes(SwappedR8)v)
EndOfCode
Note that the macro can be used either as a function:
Print Str$(SwapBytes(MyReal8))
or "standalone":
SwapBytes(offset thestring)
Output:Original: !taerg si 23msaM
Swapped: Masm32 is great!
MyReal8 1234567890.1234567
as BigEndian 3.5842524504192598e+246
reconverted 1234567890.1234567
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Dim My$(tab) ; create a two-dimensional string array
For_ ecx=0 To 7
Let edi=Str$("Test %i\t", ecx)
Let My$(ecx)=String$(8, edi) ; create a string with 8 columns
Next
For_ ecx=0 To 7
Let My$(ecx, ecx)="Hello!!" ; set individual elements
Let My$(ecx, 7-ecx)="*Ciao*"
Next
For_ ecx=0 To 7
For_ ct=0 To 7
Print My$(ecx, ct), Spc2$
Next
Print
Next
EndOfCode
Output:Hello! Test 0 Test 0 Test 0 Test 0 Test 0 Test 0 *Ciao*
Test 1 Hello! Test 1 Test 1 Test 1 Test 1 *Ciao* Test 1
Test 2 Test 2 Hello! Test 2 Test 2 *Ciao* Test 2 Test 2
Test 3 Test 3 Test 3 Hello! *Ciao* Test 3 Test 3 Test 3
Test 4 Test 4 Test 4 *Ciao* Hello! Test 4 Test 4 Test 4
Test 5 Test 5 *Ciao* Test 5 Test 5 Hello! Test 5 Test 5
Test 6 *Ciao* Test 6 Test 6 Test 6 Test 6 Hello! Test 6
*Ciao* Test 7 Test 7 Test 7 Test 7 Test 7 Test 7 Hello!
Purest assembly :bgrin:
Strange - I had forgotten to code the Eof() macro, here it is:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
SOMEUDT STRUCT ; a user-defined type
mydouble REAL8 ?
mydword DWORD ?
myfloat REAL4 ?
SOMEUDT ENDS
MyUDT SOMEUDT <?>
Eof MACRO arg
push Loc(arg)
void Lof(arg)
pop edx
cmp edx, eax
exitm <!Sign?>
ENDM
Init
Open "O", #1, "TypeTest.udt"
For_ ecx=101 To 103
mov MyUDT.mydword, ecx ; 101, 102, ...
lea eax, [ecx+900]
SetFloat MyUDT.myfloat=eax ; 1001, 1002, ...
add eax, 9000
SetFloat MyUDT.mydouble=eax ; 10001, 10002, ...
Store #1, MyUDT ; save UDT to file
Next
Close
Open "I", #1, "TypeTest.udt"
.Repeat
Recall #1, MyUDT
deb 4, "Test", MyUDT.mydouble, MyUDT.myfloat, MyUDT.mydword
.Until Eof(#1)
Close
Inkey CrLf$, "Yep, that's purest assembler ;-)"
EndOfCode
Output:
Test
MyUDT.mydouble 10001.00000000000
MyUDT.myfloat 1001.000
MyUDT.mydword 101
Test
MyUDT.mydouble 10002.00000000000
MyUDT.myfloat 1002.000
MyUDT.mydword 102
Test
MyUDT.mydouble 10003.00000000000
MyUDT.myfloat 1003.000
MyUDT.mydword 103
Yep, that's purest assembler ;-)
P.S.: To get random access to some record, use this before closing the file:
m2m eax, 1 ; get record #1
imul eax, SOMEUDT ; calculate position in file
Seek #1, eax
Recall #1, MyUDT
deb 4, "Test with Seek", MyUDT.mydouble, MyUDT.myfloat, MyUDT.mydword
Close
Quote from: jj2007 on January 13, 2019, 01:58:51 PM
P.S.: To get random access to some record, use this before closing the file:
m2m eax, 1 ; get record #1
imul eax, SOMEUDT ; calculate position in file
I didn't understood that :icon_rolleyes:
mov eax, 1
imul eax, sizeof SOMEUDT
EDIT:
OK
push 1 / pop eax is two bytes shorter.
imul eax, SOMEUDT is same as imul eax, sizeof SOMEUDT
Quote
I didn't understood that :icon_rolleyes:
Code: [Select]
mov eax, 1
imul eax, sizeof SOMEUDT
Hello Timo
1 * size of SOMEUDT structur
Quote from: TimoVJL on January 13, 2019, 11:50:18 PM
push 1 / pop eax is two bytes shorter.
imul eax, SOMEUDT is same as imul eax, sizeof SOMEUDT
Yes, as ragdog already noted. It took me years to realise that mov eax, sizeof SOMESTRUCT is the same as mov eax, SOMESTRUCT ;)
And m2m eax, n is simply some bytes shorter for n=-128 ... +127, so I always use it, except perhaps for a
really speed-critical innermost loop.
include \masm32\MasmBasic\MasmBasic.inc
Init
Inkey NoTag$(FileRead$("https://de.wikipedia.org/wiki/Spezial:Zufällige_Seite"))
EndOfCode
include \masm32\MasmBasic\Res\MbGui.asm
Event Paint
.if !Exist("test.img")
Let esi=FileRead$("https://i.gifer.com/6H3K.gif")
FileWrite "test.img", esi, LastFileSize
.endif
GuiImage "test.img", fit
EndOfCode
This snippet
- generates a 512*512 matrix of random double values
- writes all values to a string array
- saves the strings to disk
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
elements=512
PrintCpu 0
NanoTimer()
Dim matrix(elements,elements) As REAL8
For_ ct=0 To elements-1
For_ ecx=0 To elements-1
Rand(-12345.6789, 12345.6789, matrix(ct, ecx))
Next
Next
PrintLine NanoTimer$(), Str$(" for generating %i random doubles", matrix(?))
NanoTimer()
Dim out$() ; create a zstring array
Let edi=New$(16*elements) ; prepare for long numbers, e.g. 12345.6789
For_ ct=0 To elements-1
push edi
For_ ecx=0 To elements-1
invoke MbCopy, edi, Str$("%9f\t", matrix(ct, ecx)), -2
xchg eax, edi
Next
and dword ptr [edi-1], 0
pop edi
Let out$(ct)=edi
Next
PrintLine NanoTimer$(), Str$(" for %i strings", ct)
Store "Matrix.txt", out$() ; save to disk
Inkey "wanna see the result? (y)"
If_ eax=="y" Then ShEx "Matrix.txt" ; show it in Notepad etc
EndOfCode
Typical output:Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz
5078 µs for generating 262144 random doubles
66 ms for 512 strings
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
DuplicateBits MACRO arg
Local Lb0, Lb1, Lb2
mov edx, arg
xor eax, eax
push ecx
mov ecx, 11000000000000000000000000000000b
Lb0:
rol ecx, 2 ; in the first round, ecx will be 11b
shr edx, 1 ; get the carry flag
je Lb1
jnc Lb0
or eax, ecx
jmp Lb0
Lb1:
jnc Lb2
or eax, ecx
Lb2:
pop ecx
EXITM <eax>
ENDM
Init
m2m ecx, 1
mov edi, 256
.Repeat
mov esi, ecx
shr edi, 1
or esi, edi
Print Right$(Cat$(Replace$(Bin$(esi), "0", " ")), 8 ), Spc4$ ; print the original without the 0s
Print Right$(Cat$(Replace$(Bin$(DuplicateBits(esi)), "0", " ")), 16), CrLf$ ; print the duplicate
shl ecx, 1
.Until ecx>255
Inkey CrLf$, "-- hit any key --"
EndOfCode
Output:1 1 11 11
1 1 11 11
1 1 11 11
11 1111
11 1111
1 1 11 11
1 1 11 11
1 1 11 11
Source attached. The macro will also work for plain Masm32 sources.
The "Fizz-Buzz test" (http://wiki.c2.com/?FizzBuzzTest) is an interview question designed to help filter out the 99.5% of programming job candidates who can't seem to program their way out of a wet paper bag. The text of the programming assignment is as follows:
Quote"Write a program that prints the numbers from 1 to 100. But for multiples of three print "Fizz" instead of the number and for the multiples of five print "Buzz". For numbers which are multiples of both three and five print "FizzBuzz"."
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
For_ ct=1 To 100
xor esi, esi ; flag Fizz or Buzz
mov eax, ct
cdq
mov ecx, 3
div ecx
test edx, edx
.if Zero?
inc esi
Print "Fizz"
.endif
mov eax, ct
cdq
mov ecx, 5
div ecx
test edx, edx
.if Zero?
inc esi
Print "Buzz"
.endif
.if !esi
Print Str$(ct)
.endif
Print " "
Next
Inkey "ok?"
EndOfCode
In C, perhaps it works ::)int __cdecl main(void)
{
char *Fizz = "Fizz";
char *Buzz = "Buzz";
char *pF, *pB;
for (int i=0; i<100; i++) {
pF = 0;
pB = 0;
if (i) {
if (i % 3 == 0) pF = Fizz;
if (i % 5 == 0) pB = Buzz;
}
if (pF || pB) {
if (pF) printf(pF);
if (pB) printf(pB);
printf("\n");
} else printf("%d\n", i);
}
return 0;
}
Another C version (may be can be made shorter ::)):
int main()
{
char buff[16];
for (int i = 1; i <= 100; i++)
printf("%s\n", !(i % 3) && !(i % 5) ? "FizzBuff": (!(i % 5) ? "Buzz": (!(i % 3) ? "Fizz": itoa(i,buff,10))));
}
Nice!
4 bytes shorter, but not C99.
Jose's version unpacked:
#pragma comment(lib, "msvcrt.lib")
char *_itoa(int value, char *dst, int base);
void __cdecl mainCRTStartup(void)
{
__declspec(dllimport) void __cdecl exit(int status);
int __cdecl main(void);
exit(main());
}
int main(void)
{
char buff[16];
char *p;
for (int i = 1; i <= 100; i++) {
if (!(i % 3) && !(i % 5)) p = "FizzBuff";
else if (!(i % 5)) p = "Buzz";
else if (!(i % 3)) p = "Fizz";
else p = _itoa(i,buff,10);
puts(p);
}
return 0;
}
EDIT:#pragma comment(lib, "msvcrt.lib")
char *_itoa(int value, char *dst, int base);
void __cdecl mainCRTStartup(void)
{
__declspec(dllimport) void __cdecl exit(int status);
int __cdecl main(void);
exit(main());
}
int __cdecl main(void)
{
char *Fizz = "Fizz";
char *Buzz = "Buzz";
char *pF, *pB;
char buf[16];
for (int i=0; i<100; i++) {
pF = 0;
pB = 0;
if (i % 3 == 0) pF = Fizz;
if (i % 5 == 0) pB = Buzz;
if (pF || pB) {
if (pF) printf(pF);
if (pB) printf(pB);
puts("");
} else {
puts(_itoa(i, buf, 10));
}
}
return 0;
}
Choose (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1289) is purest Assembly :P
include \masm32\MasmBasic\MasmBasic.inc
Init
For_ ct=1 To 100
xor ebx, ebx ; flag Fizz or Buzz
mov eax, ct
cdq
mov ecx, 3
div ecx
test edx, edx
sete bl
mov eax, ct
mov ecx, 5
div ecx
test edx, edx
sete dl
lea ebx, [ebx+2*edx]
Print Choose(ebx, Str$("%i ", ct), "Fizz ", "Buzz ", "FizzBuzz ")
Next
Inkey "ok?"
EndOfCode
:( itoa :biggrin: _itoa :lol: purest Assembly
Certain similarities should be accepted 8)
printf("%s\n", !(i % 3) && !(i % 5) ? "FizzBuff": (!(i % 5) ? "Buzz": (!(i % 3) ? "Fizz": itoa(i,buff,10))));
Print Choose(ebx, Str$("%i ", ct), "Fizz ", "Buzz ", "FizzBuzz ")
Full version:
include Modulo.inc
Init
For_ ecx=1 To 30
lea ebx, [2*IsModulo(ecx, 5)]
add ebx, IsModulo(ecx, 3)
PrintLine Choose(ebx, Str$("%i ", ecx), "Fizz ", "Buzz ", "FizzBuzz ")
Next
Inkey
EndOfCode
I wonder if it should be called ModZero(src, imm)?
Output:1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
Fizz
19
Buzz
Fizz
22
23
Fizz
Buzz
26
Fizz
28
29
FizzBuzz
;)
include \masm32\MasmBasic\Res\MbGui.asm
ArraySet current() As double=120, 125, 122, 119, 134, 138, 141, 159, 162, 178
ArraySet voltage() As double=250, 210, 180, 155, 140, 125, 110, 100, 90, 80
SetAxisX "Электроток", s 0, d 1/5, grid 1 ; s=start value, d=difference between gridlines
SetAxisY "Voltage", s 0, d 5/5, grid 1
Event Paint
ArrayPlotValues "%i V", 8, -12 ; format$, dx & dy positions
ArrayPlot current():voltage(), RgbCol(0, 0, 255), lines=3
ArrayPlot exit, "繪製科學數據非常容易!"
EndOfCode
(http://www.jj2007.eu/images/PlotVoltageOverCurrent.png)
Impressive Jochen :t
how fast is arrayplot compared to GDI?
is it masmbasic functions used in Lord Adef's game,scrolling and sprite functions included already in masmbasic?
strange if not,because its included GET and PUT in qbasic
Thanks, Daydreamer. Arrayplot is Gdi, actually. Speedwise, check the Sinus plot template (attached). Re GET & PUT: There are ways to do something similar in MasmBasic, but I doubt that LordAdef is using them.
Quote from: jj2007 on May 16, 2019, 01:33:12 PM
include \masm32\MasmBasic\Res\MbGui.asm
ArraySet current() As double=120, 125, 122, 119, 134, 138, 141, 159, 162, 178
ArraySet voltage() As double=250, 210, 180, 155, 140, 125, 110, 100, 90, 80
SetAxisX "Электроток", s 0, d 1/5, grid 1 ; s=start value, d=difference between gridlines
SetAxisY "Voltage", s 0, d 5/5, grid 1
Event Paint
ArrayPlotValues "%i V", 8, -12 ; format$, dx & dy positions
ArrayPlot current():voltage(), RgbCol(0, 0, 255), lines=3
ArrayPlot exit, "繪製科學數據非常容易!"
EndOfCode
(http://www.jj2007.eu/images/PlotVoltageOverCurrent.png)
Hi jj2007,
is it possible to make smoothing lines? the soul requires aesthetics)
Smoothing a curve in VB.Net https://www.codeproject.com/Questions/358853/Smoothing-a-curve-in-VB-Net (https://www.codeproject.com/Questions/358853/Smoothing-a-curve-in-VB-Net)
Quote from: LiaoMi on May 18, 2019, 06:22:21 PMis it possible to make smoothing lines?
Probably, but the CodeProject guy is on the wrong track. For scientific data visualisation, you can't use "shortcuts" of that sort, they must be exact. What you
can do, though, is smoothing a ragged line by anti-aliasing:
(https://joeycamson.files.wordpress.com/2011/11/aliasing.png)
If I find the time, I'll find a way to let GdiPlus draw these lines 8)
Quote from: jj2007 on May 18, 2019, 10:29:03 AM
Thanks, Daydreamer. Arrayplot is Gdi, actually. Speedwise, check the Sinus plot template (attached). Re GET & PUT: There are ways to do something similar in MasmBasic, but I doubt that LordAdef is using them.
if its gdi draw chinese characters,please check in my thread if you can show a smoother solution to this problem Jochen
http://masm32.com/board/index.php?topic=7834.0 (http://masm32.com/board/index.php?topic=7834.0)
The text is not the problem, Gdi draws fonts OK. It is the ragged line. Below an excerpt from the plot where I added a line drawn with Gdi+, using high quality anti-aliasing. It does make a difference, but the extra quality is not overwhelming.
You must zoom in quite a lot to see a difference. On Chrome/SlimJet it's holding Control and pushing the mousewheel forward.
Btw this is line width 3; for finer lines, the difference between plain Gdi and high quality anti-aliased Gdi+ is almost negligible. On the right side of the graph, I added a comparison between 5px and 1px lines. If you zoom to 200 or 250%, the difference becomes evident. Note also how neat the Chinese text looks - it's really fine.
Quote from: jj2007 on May 19, 2019, 05:16:09 AM
The text is not the problem, Gdi draws fonts OK. It is the ragged line. Below an excerpt from the plot where I added a line drawn with Gdi+, using high quality anti-aliasing. It does make a difference, but the extra quality is not overwhelming.
You must zoom in quite a lot to see a difference. On Chrome/SlimJet it's holding Control and pushing the mousewheel forward.
Btw this is line width 3; for finer lines, the difference between plain Gdi and high quality anti-aliased Gdi+ is almost negligible. On the right side of the graph, I added a comparison between 5px and 1px lines. If you zoom to 200 or 250%, the difference becomes evident. Note also how neat the Chinese text looks - it's really fine.
maybe d3d can antialias better and faster with full antialias settings
maybe - post a demo ;-)
Hi,
I take my words back :biggrin: It looks like its just impossible to make normal smoothing with GDI, other technologies have to deal with it.
https://software.intel.com/en-us/articles/mlaa-efficiently-moving-antialiasing-from-the-gpu-to-the-cpu (https://software.intel.com/en-us/articles/mlaa-efficiently-moving-antialiasing-from-the-gpu-to-the-cpu)
SMAA: Subpixel Morphological Antialiasing https://github.com/iryoku/smaa (https://github.com/iryoku/smaa)
Demo - https://web.archive.org/web/20121023110459/http://www.iryoku.com/mlaa/downloads/Jimenez-MLAA-DX10-v1.5.exe (https://web.archive.org/web/20121023110459/http://www.iryoku.com/mlaa/downloads/Jimenez-MLAA-DX10-v1.5.exe)
Below, I gave examples showing the difference between display technologies.
Project upgrade failed (your source is 2007, I tried with Visual Crap 2010) 8)
Quote from: jj2007 on May 19, 2019, 06:18:16 AM
maybe - post a demo ;-)
docs says it doesnt antialias lines,only polys in fullscene antialias
Quote from: jj2007 on May 19, 2019, 08:03:31 PM
Project upgrade failed (your source is 2007, I tried with Visual Crap 2010) 8)
Hi jj2007,
I also have no success in the visual studio 2019, I will try on another machine. The first example shows that in GDI it is not reachable, and the second example shows how ideally it should be, taking into account that another mechanism is used. The speed and processing of both techniques are completely different. I do not think it's worth puzzling over this problem :rolleyes:
Quote from: jj2007 on May 18, 2019, 10:29:03 AM
Thanks, Daydreamer. Arrayplot is Gdi, actually. Speedwise, check the Sinus plot template (attached). Re GET & PUT: There are ways to do something similar in MasmBasic, but I doubt that LordAdef is using them.
you use GDI background color=bitmap? or use background color=null?
for example want to have a moving object,just redraw it together with erase few pixels behind it?
I found this direct2d vs GDI,look below at the images direct2d is smoother curves
https://docs.microsoft.com/sv-se/windows/desktop/direct2d/direct2d-overview (https://docs.microsoft.com/sv-se/windows/desktop/direct2d/direct2d-overview)
Quote from: daydreamer on May 25, 2019, 10:34:45 PMI found this direct2d vs GDI,look below at the images direct2d is smoother curves
The curves are Gdi vs D2D, not Gdi
+. They write "When rendering in software, applications that use Direct2D experience substantially better rendering performance than with GDI+ and with
similar visual quality." - and I bet they mean "almost the same quality".
GuiParas equ "Event Dropfiles demo", x1000, y20, w350, h700, cblack, b00FFFFD0h
include \masm32\MasmBasic\Res\MbGui.asm
Event DropFiles
GfNoPaths=1 ; optional: don't include the paths
For_ ecx=0 To eax-1 ; #files was returned in eax
wPrintLine wRec$(Files$(ecx)) ; show the files in the console window
Next
GuiRefresh ; GuiText needs a WM_PAINT handler
Event Paint
For_ ecx=0 To Files$(?)-1
GuiText 3, ecx*20, Files$(ecx)
Next
GuiEnd
Little problems, it works only partially:
include \masm32\MasmBasic\MasmBasic.inc ; download
uselib WinInet
if 0
URL_COMPONENTSA STRUCT
dwStructSize DWORD ?
lpszScheme LPSTR ?
dwSchemeLength DWORD ?
nScheme DWORD ?
lpszHostName LPSTR ?
dwHostNameLength DWORD ?
nPort INTERNET_PORT <>
lpszUserName LPSTR ?
dwUserNameLength DWORD ?
lpszPassword LPSTR ?
dwPasswordLength DWORD ?
lpszUrlPath LPSTR ?
dwUrlPathLength DWORD ?
lpszExtraInfo LPSTR ?
dwExtraInfoLength DWORD ?
URL_COMPONENTSA ENDS
endif
.data?
UrlComp URL_COMPONENTS <>
HostName db 100 dup(?)
UserName db 100 dup(?)
UrlPath db 1000 dup(?)
ExtraInfo db 100 dup(?)
Init
add UrlComp.dwStructSize, URL_COMPONENTS
mov UrlComp.lpszScheme, Chr$("Whatever suits you")
add UrlComp.dwSchemeLength, c$Len
mov UrlComp.lpszHostName, offset HostName
add UrlComp.dwHostNameLength, 100
add UrlComp.nScheme, INTERNET_SCHEME_UNKNOWN ; INTERNET_SCHEME_DEFAULT
mov UrlComp.lpszUserName, offset UserName
add UrlComp.dwUserNameLength, 100
mov UrlComp.lpszUrlPath, offset UrlPath
add UrlComp.dwUrlPathLength, 1000
mov UrlComp.lpszExtraInfo, offset ExtraInfo
add UrlComp.dwExtraInfoLength, 100
invoke InternetCrackUrl, Chr$("https://docs.microsoft.com/en-us/windows/win32/api/wininet/nf-wininet-internetcrackurla"), 0, ICU_DECODE, addr UrlComp
deb 4, "res", eax, $Err$(), $UrlComp.lpszScheme, $offset HostName, $offset UserName, $UrlPath, $ExtraInfo, UrlComp.nPort
invoke InternetCrackUrl, Chr$("http://www.google.com/test.html"), 0, ICU_DECODE, addr UrlComp
deb 4, "res", eax, $Err$(), $UrlComp.lpszScheme, $offset HostName, $offset UserName, $UrlPath, $ExtraInfo, UrlComp.nPort
EndOfCode
res
eax 1
$Err$() Operazione completata.__
$UrlComp.lpszScheme https
$offset HostName docs.microsoft.com
$offset UserName
$UrlPath 470 <not a pointer>
$ExtraInfo 00 <not a pointer>
UrlComp.nPort 443
res
eax 0
$Err$() Area dati passata ad una chiamata al sistema troppo piccola.__
$UrlComp.lpszScheme http
$offset HostName www.google.com
$offset UserName
$UrlPath 470 <not a pointer>
$ExtraInfo 00 <not a pointer>
UrlComp.nPort 80
Init buffer sizes between calls
Thanks, Timo. Right, even a mov UrlComp.dwUserNameLength, 1 is sufficient. It seems that if you pass a pointer to a buffer, the length must be at least one even if you don't get a text back.
A snippet that allows to copy a table e.g. from Excel and paste it here:
include \masm32\MasmBasic\MasmBasic.inc
Init
Let esi=Clip$()
.if Len(esi)
Let esi=Replace$(esi, CrLf$, Chr$("[/td][/tr]", 13, 10, "[tr][td]"))
Let esi=Replace$(esi, Tb$, "[/td][td]")
Let esi="[table][tr][td]"+esi+"[/td][/table]"
Inkey "Put table on clipboard (y)?"
If_ eax=="y" Then SetClip$ esi ; put table on the clipboard
.else
MsgBox 0, "No text on clipboard, sorry", "Hi", MB_OK
.endif
EndOfCode
Example (see attached SimpleTable.tab):
Name | First name | Street | City |
Ferrell | Aaliyah | 2716 Simpson Street | Belyando |
Oneal | Aaron | 2033 Rosales Street | Port Iatta |
Cooper | Abagail | 1381 Lee Street | Palmers Oaky |
David | Abagail | 2445 Price Street | Popanyinning |
Hampton | Abagail | 35 Boyer Street | Red Range |
|
Quote from: daydreamer on December 14, 2019, 12:00:52 PMAlso seen map drawing,why don't add a Fun quiz to geography and country stats on different things?
Yes, that could be fun. Prepare a file with questions and answers, and we'll add it to the attached template (which requires Europe.zip from the MB extras (http://masm32.com/board/index.php?topic=94.msg265#msg265)).
Here is the source (attached, with exe):
include \masm32\MasmBasic\Res\MbGui.asm
GuiControl MyMap, "canvas", w660 ; define a canvas control using 66% of the client rect width
GuiControl TheManual, "richedit", res:92, x660, w340, bcol RgbCol(255, 255, 240)
GuiControl Sbar, "statusbar"
ArrayLoadMap 0, 90 ; Europe.dmi and Europe.map in resources
MapColours(0, "abcdefghiabcdefghiabcdefghiabcdefghiabcdefghiabcdefghi") ; set colours to map 0 (a=red, i=green)
Event CanvasPaint
ArrayPlot RgbCol(0, 240, 255) ; init and set background colour
PaintMap RgbCol(127, 127, 127), lines=2 ; map with grey borders 2px thick
GuiTextBox 99.0-120, 51.0, 120, auto, "This program requires the file Europe.map", bcol LiteGreen, font -16:FW_NORMAL
ArrayPlot exit, "Europe"
Event Message
.if uMsg_==WM_MAPCLICKED
.if MapRegion>=0
SetWin$ hSbar="You clicked on "+MapRegion$ ; *** add your ideas here ***
.else
SetWin$ hSbar=Time$ ; user clicked into water ;-)
.endif
.endif
GuiEnd
Quote from: jj2007 on December 14, 2019, 01:48:12 PM
Quote from: daydreamer on December 14, 2019, 12:00:52 PMAlso seen map drawing,why don't add a Fun quiz to geography and country stats on different things?
Yes, that could be fun. Prepare a file with questions and answers, and we'll add it to the attached template (which requires Europe.zip from the MB extras (http://masm32.com/board/index.php?topic=94.msg265#msg265)).
Here is the source (attached, with exe):
include \masm32\MasmBasic\Res\MbGui.asm
GuiControl MyMap, "canvas", w660 ; define a canvas control using 66% of the client rect width
GuiControl TheManual, "richedit", res:92, x660, w340, bcol RgbCol(255, 255, 240)
GuiControl Sbar, "statusbar"
ArrayLoadMap 0, 90 ; Europe.dmi and Europe.map in resources
MapColours(0, "abcdefghiabcdefghiabcdefghiabcdefghiabcdefghiabcdefghi") ; set colours to map 0 (a=red, i=green)
Event CanvasPaint
ArrayPlot RgbCol(0, 240, 255) ; init and set background colour
PaintMap RgbCol(127, 127, 127), lines=2 ; map with grey borders 2px thick
GuiTextBox 99.0-120, 51.0, 120, auto, "This program requires the file Europe.map", bcol LiteGreen, font -16:FW_NORMAL
ArrayPlot exit, "Europe"
Event Message
.if uMsg_==WM_MAPCLICKED
.if MapRegion>=0
SetWin$ hSbar="You clicked on "+MapRegion$ ; *** add your ideas here ***
.else
SetWin$ hSbar=Time$ ; user clicked into water ;-)
.endif
.endif
GuiEnd
If you reduce the window, then everything is well rendered, but if you enlarge the window on the left side, especially in large sections, you can see an unusual drawing line from the text container.
is there a nice site to get updated country facts and figures with help of recall?to fill a country array of struct with different categorys
and create quiz similar to this:
http://masm32.com/board/index.php?topic=7834.15
Quote from: LiaoMi on December 14, 2019, 10:34:20 PMIf you reduce the window, then everything is well rendered, but if you enlarge the window on the left side, especially in large sections, you can see an unusual drawing line from the text container.
No such line here :rolleyes:
Does anybody else see a line in the wrong place? Which OS?
Quote from: jj2007 on December 15, 2019, 05:13:59 AMthe picture jumps here and there, photo report can be downloaded here https://www.upload.ee/files/10847594/jj2.zip.html (https://www.upload.ee/files/10847594/jj2.zip.html)
jj2007: Thanks, now I see what you mean: the delay when updating the richedit control. There is a simple explanation for this effect: it can't be done fast enough. Even when sizing the window slowly, cpu usage goes up to 100% for the core of the process. The map is about 18k lines to draw - and this is not done via StretchBlt, it really gets completely drawn for each frame. Watch the Norwegian coastline when sizing the main window very slowly.
In theory, I could switch to StretchBlt, but 1. sizing the window frenetically is not a typical usage and 2. painting a single country to achieve the feedback effect when you click into the country would require more sophisticated code and logic.
P.S.: I just realised that instead of quoting your post, I modified it, and also deleted most of it -
sorry. These are the pros and cons of being the administrator of a sub-forum :cool:
Changing the DC a Control paints on
Hello,
Is it possible to make a control (a richedit control for example) paint onto your own DC instead of the window DC?
http://www.asmcommunity.net/forums/topic/?id=15998 (http://www.asmcommunity.net/forums/topic/?id=15998)
WS_EX_COMPOSITED
0x02000000L
Paints all descendants of a window in bottom-to-top painting order using double-buffering. Bottom-to-top painting order allows a descendent window to have translucency (alpha) and transparency (color-key) effects, but only if the descendent window also has the WS_EX_TRANSPARENT bit set. Double-buffering allows the window and its descendents to be painted without flicker. This cannot be used if the window has a class style of either CS_OWNDC or CS_CLASSDC.
Windows 2000: This style is not supported.
As an option ..
myRichCtrl.ShowWindow(SW_HIDE);
myRichCtrl.DoSomething();
myRichCtrl.ShowWindow(SW_SHOW);
Quote from: LiaoMi on December 15, 2019, 10:08:09 PMWS_EX_COMPOSITED
Looks interesting, thanks :thumbsup:
But when I add this style to an edit or richedit control, CreateWindowEx fails. Raymond Chen writes about another issue, though. (https://devblogs.microsoft.com/oldnewthing/20171018-00/?p=97245)
Attached another one from the life expectancy series, now comparing two countries. The red line gets chosen with the left and right arrows, the blue one by clicking into the map. Source included.
Hi
I used the WS_EX_COMPOSITED style for my own controls and it works fine if you follow the MS rules.
One problem I noticed is that the scrollbar loses the scrollbox transition effects.
It's a trifle if you get rid of the awful flicker.
Biterider
Quote from: Biterider on December 16, 2019, 05:37:45 PM
Hi
I used the WS_EX_COMPOSITED style for my own controls and it works fine if you follow the MS rules.
One problem I noticed is that the scrollbar loses the scrollbox transition effects.
It's a trifle if you get rid of the awful flicker.[/size]
Biterider
Hi Biterider,
:biggrin: Is the font specially size=2px small? Yes :thumbsup:, following the recommendations of Microsoft, it should work.
Hi LiaoMi
Sorry, better now? :biggrin:
It should work, yes, but...
push 0 ; ÚlParam = NULL
push dword ptr [40FA34] ; ³hInst = 00400000
push 2A ; ³ID = 42.
push dword ptr [ebp+8] ; ³hParent
push 28 ; ³Height = 40.
push 5A ; ³Width = 90.
push 0A ; ³Y = 10.
push 0A ; ³X = 10.
push 54A41144 ; ³Style = WS_CHILD|WS_BORDER|WS_THICKFRAME|WS_VISIBLE|WS_CLIPSIBLINGS|WS_VSCROLL|1144
push 0 ; ³WindowName = NULL
push offset 004101DE ; ³ClassName = "RichEdit20W"
push 2000020 ; ³ExtStyle = WS_EX_TRANSPARENT|2000000
call <jmp.&user32.CreateWi ; ÀUSER32.CreateWindowExW
Now that I applied WS_EX_COMPOSITED to the parent window,
1. the control gets created using WS_EX_COMPOSITED = 2000000h
2. but WinID shows exstyle 0x120 for the child (and 2000100 for the parent)
3. and the flicker is as before
It certainly looks nice when dragging the edit over the map :tongue:
:sad:
There are many numbers with matching "mirrored squares", like 13^2=169, 31^2=961:
matches number mirror square mirror
1 11 11 121 121
2 12 21 144 441
3 13 31 169 961
4 21 12 441 144
5 22 22 484 484
6 31 13 961 169
100 numbers tested, 5.9% matches
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
SetGlobals matches
Init
For_ ct=1 To 100000000 ; 100 million iterations
Let esi=Str$(ct) ; e.g. "13"
void Val(esi) ; 13
mul eax ; 169
push Mirror$(Str$(eax)) ; "961"
void Val(Mirror$(esi)) ; 31
mul eax ; 961
xchg Str$(eax), edi ; edi: "961"
pop ecx ; "961"
.if !StringsDiffer(ecx, edi) ; "961"=="961"
inc matches
PrintLine Str$(matches), Tb$, esi, Tb$, Mirror$(esi), Str$("\t%i\t", ct*ct), edi
.endif
Next
Inkey Str$("%i numbers tested", ct-1), Str$(", %5f% matches", matches/ct*100)
EndOfCode
Quote from: jj2007 on December 14, 2019, 01:48:12 PM
Quote from: daydreamer on December 14, 2019, 12:00:52 PMAlso seen map drawing,why don't add a Fun quiz to geography and country stats on different things?
Yes, that could be fun. Prepare a file with questions and answers, and we'll add it to the attached template (which requires Europe.zip from the MB extras (http://masm32.com/board/index.php?topic=94.msg265#msg265)).
so far something to test with
Quote from: jj2007 on December 17, 2019, 01:13:45 AM
It should work, yes, but...
push 0 ; ÚlParam = NULL
push dword ptr [40FA34] ; ³hInst = 00400000
push 2A ; ³ID = 42.
push dword ptr [ebp+8] ; ³hParent
push 28 ; ³Height = 40.
push 5A ; ³Width = 90.
push 0A ; ³Y = 10.
push 0A ; ³X = 10.
push 54A41144 ; ³Style = WS_CHILD|WS_BORDER|WS_THICKFRAME|WS_VISIBLE|WS_CLIPSIBLINGS|WS_VSCROLL|1144
push 0 ; ³WindowName = NULL
push offset 004101DE ; ³ClassName = "RichEdit20W"
push 2000020 ; ³ExtStyle = WS_EX_TRANSPARENT|2000000
call <jmp.&user32.CreateWi ; ÀUSER32.CreateWindowExW
Now that I applied WS_EX_COMPOSITED to the parent window,
1. the control gets created using WS_EX_COMPOSITED = 2000000h
2. but WinID shows exstyle 0x120 for the child (and 2000100 for the parent)
3. and the flicker is as before
It certainly looks nice when dragging the edit over the map :tongue:
:sad:
Hi jj2007,
:sad: everything looks softer, but flicker is noticeable, frame-by-frame recording shows that the frame rate has increased, its not a solution.
Quote from: LiaoMi on December 18, 2019, 07:23:19 AM:sad: everything looks softer, but flicker is noticeable, frame-by-frame recording shows that the frame rate has increased, its not a solution.
I can't see much difference, but in any case there is no solution because the map drawing is so slow that flicker on resize cannot be avoided.
To use it, drag a file (e.g. ...FreeBasic\examples\unicode\hello_UTF32LE.bas) over the attached exe.
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Let esi=FileRead$(CL$()) ; read UTF-32 content into a buffer
.if dword ptr [esi]!=0FEFFh ; no BOM found!
MsgBox 0, CL$(), "Not a UTF-32 file, sorry", MB_OK
.else
mov ecx, LastFileSize
sar ecx, 1
Let edi=New$(ecx) ; create a buffer for UTF-16
sar ecx, 1
push edi
.Repeat
lodsd
stosw
dec ecx
.Until Sign?
pop edi
FileWrite "test.txt", edi
ShEx "test.txt" ; open in your preferred editor
.endif
EndOfCode
Source and exe attached. This snippet generates a text file with integers.
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
SetGlobals total
Init
Dim MyDw() As DWORD
mov ecx, Val(Input$("How many numbers: ", "1000000")) ; suggest one Million
mov total, ecx
sar ecx, 4 ; divide by 16
jle bye
Open "O", #1, "numbers.txt"
For_ ct=1 To ecx
For_ ecx=0 To 15
Print #1, Str$("%i ", Rand(500000)-250000) ; generate numbers from -250000...249999
Next
Print #1
Next
Close #1
NanoTimer()
StringToArray FileRead$("Numbers.txt"), MyDw() ; reload textfile and convert to numbers
PrintLine NanoTimer$(), Str$(" for converting %i numbers", MyDw(?))
NanoTimer()
ArraySort MyDw()
PrintLine NanoTimer$(), " for sorting them"
For_ ecx=0 To 9 ; show the smallest numbers
PrintLine Str$("MyDw(%i)=", ecx), Str$(MyDw(ecx))
Next
PrintLine "..."
For_ ecx=total-9 To total-1 ; show the biggest numbers
PrintLine Str$("MyDw(%i)=", ecx), Str$(MyDw(ecx))
Next
bye:
EndOfCode
Sample output (Intel Core i5):
How many numbers: 1000000
98 ms for converting 1000000 numbers
103 ms for sorting them
MyDw(0)=-250000
MyDw(1)=-249999
MyDw(2)=-249999
MyDw(3)=-249999
MyDw(4)=-249998
MyDw(5)=-249998
MyDw(6)=-249997
MyDw(7)=-249997
MyDw(8)=-249997
MyDw(9)=-249996
...
MyDw(999991)=249994
MyDw(999992)=249994
MyDw(999993)=249995
MyDw(999994)=249996
MyDw(999995)=249997
MyDw(999996)=249997
MyDw(999997)=249998
MyDw(999998)=249999
MyDw(999999)=249999
GuiParas equ "Save all frames of a GIF image to file", w300, h200
include \masm32\MasmBasic\Res\MbGui.asm ; needs MasmBasic 24.1.2020 (http://masm32.com/board/index.php?topic=94.0)
GuiImageCallback MySave ; tell GuiImage to call MySave
Event Paint
GuiImage wCL$(), fit ; load the image specified in the commandline (Unicode is allowed)
EndOfEvents
MySave: If_ Not signed eax<0 Then <SaveImageToFile Str$("frame_%i.gif", eax)> ; saves current frame to frame_0...n.gif
ret
GuiEnd
Project attached. Drag an animated *.gif file over the exe, then check its folder for the component files. The exe will also display jpg, bmp, png and tiff, but only multi-frame gif files will trigger the creation of the frame*.gif components. This works also with animated TIFF files, see second attachment, but the output will be *.gif components. No idea how to join them, though :cool:
What's new?
- GuiImage (http://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1375) now respects the delays of frames in animated GIFs, and also stops looping if the GIF specifies a limit. Simple example (make sure you run it in a folder that contains images; source and exe attached):
include \masm32\MasmBasic\Res\MbGui.asm ; MasmBasic version 1 Feb 2020 needed for building this code (http://masm32.com/board/index.php?topic=94.0)
GetFiles *.gif|*.jpg|*.png|*.jpeg ; load the Files$() array
SortFiles ; latest on top
GuiControl MyList, "listbox", Files$(), x=800, w=200 ; create a listbox to the right, 20% of width; use Files$() to fill it
GuiControl MyCanvas, "canvas", w=800, WS_THICKFRAME ; create the canvas to paint on
GuiImageSpeed 50, 2000 ; 50% speed, 2 seconds pause after an animation
Event CanvasPaint
.if LbSel>=0
GuiImage 99, fit ; background image may be needed for animations with transparency
GuiImage Files$(LbSel) ; draw the selected image, use original size (or use fit as above)
.else
GuiTextBox 0, 0, 200, auto, "Click into the listbox to select a file", bcol RgbCol(255, 255, 255), font 40
.endif
GuiEnd
- new CheckStackBalance macro:
include \masm32\MasmBasic\MasmBasic.inc
Init
CodeSize MyTest
call MyTest
useCsb=1 ; put 0 to see a crash
Exit
MyTest_s:
MyTest proc
CheckStackBalance
PrintLine "Hello World"
pushf ; that's a word, right ;-)
pushad ; <<<<<<<<<<<<<<<< a bug! <<<<<<<<<<<
CheckStackBalance
ret
MyTest endp
MyTest_endp:
CodeSize MyTest, echo
end start
If enabled via useCsb=1, it shows e.g. these lines, plus a MsgBox:
244 bytes for MyTest
Hello World
** line 16: 8 push instructions in excess - stack is 34 bytes off **
If disabled with useCsb=0, no code is generated but the output looks different:
18 bytes for MyTest
Hello World
Plus a "MsgBox" designed by Microsoft :tongue:
- the CodeSize macro may serve to calculate the size of a whole proc or a few instructions between the *_s: and *_endp: labels. In the CodeSize xx, echo variant, the size appears in the output window, and no extra code will be generated
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
SetGlobals backslash, pattern$
Init
.While 1
PrintLine CrLf$, "Press Escape, Return to exit", CrLf$
Let pattern$=Input$("What to search for: ", Cat$(CurDir$()+"*.*"))
.Break .if !Len(eax)
Cls
Dim score() As DWORD
GetFiles pattern$ ; .jpg|*.inc|*.pdf
For_ ct=0 To eax-1
xor ecx, ecx
dec GfAgeHours(ct)
.if !Sign?
shr eax, 2 ; more shifting = less importance for date
push eax
shr GfSize(ct), 7
pop edx
mul edx
shrd eax, edx, 12
xchg eax, ecx
.endif
mov score(ct), ecx
Next
ArraySort score(-), key() As DWORD, fill
PrintLine CrLf$, "Size__", Tb$, "Date______ Time____ Path", String$(60, "_")
fldz
For_ ct=0 To score(?)-1
mov ecx, key(ct)
.if ct<=50
push GfSize(ecx)
fiadd stack
pop edx
.endif
.if ct<20
mov esi, Files$(ecx)
; mov backslash, Rinstr(esi, "\")
PrintLine Str$("%_____i\t", GfSize(ecx)/1024/1024), GfDate$(ecx), Spc2$, GfTime$(ecx), Tb$, Mid$(esi, backslash+1)
.endif
Next
fmul FP4(1.0e-9)
mov ecx, Cat$("\nDeleting the first 50 files in "+Left$(pattern$, Rinstr(pattern$, "\")-1)+" would free %3f GB of disk space")
PrintLine Str$(#ecx, ST(0)v)
.Endw
EndOfCode
Unzip the attachment to some folder and run the exe (or open the *.asc in RichMasm and hit F6). Typical output:
Size__ Date______ Time____ Path____________________________________________________________
2 27.09.2013 02:01:00 C:\Masm32\OllyDbg\ollydbg.exe
0 19.03.1998 07:28:18 C:\Masm32\bin\link.exe
0 13.01.1995 05:10:00 C:\Masm32\bin\link16.exe
1 10.01.2012 00:21:10 C:\Masm32\include\winextra.inc
0 10.01.2012 00:21:10 C:\Masm32\include\windows.inc
0 16.03.2000 15:20:48 C:\Masm32\bin\ml.EXE
0 16.03.2000 15:20:48 C:\Masm32\bin\mlv615.EXE
0 12.11.2011 08:04:41 C:\Masm32\examples\unicode_generic\diskfile\WININC.INC
0 13.03.2004 16:30:08 C:\Masm32\examples\advanced\wrep\winequ.inc
0 16.04.2011 19:09:37 C:\Masm32\bin\poasm.exe
0 25.01.2010 13:18:04 C:\Masm32\bin\dumppe.exe
0 22.12.2008 15:15:08 C:\Masm32\lib\msvcrt.000
Deleting the first 50 files in C:\Masm32 would free 0.0410 GB of disk space
So far, it just shows files, i.e. nothing will get deleted. Of course, it becomes more interesting if your \Masm32 folder is a little bit older. My message is Deleting the first 50 files in C:\Masm32 would free 16.8 GB of disk space :cool:
Here is another interesting folder:
Size__ Date______ Time____ Path____________________________________________________________
272 23.04.2011 21:41:44 C:\Windows\Installer\21386cd2.msp
189 28.03.2011 18:00:22 C:\Windows\Installer\42fec0e.msp
164 28.03.2011 17:45:18 C:\Windows\Installer\42fec0d.msp
114 27.07.2007 09:03:06 C:\Windows\Installer\21386a4c.msp
378 01.09.2017 01:43:52 C:\Windows\Installer\30be8f0e.msi
245 21.06.2016 05:45:27 C:\Windows\Installer\2ad6e39c.msi
207 06.11.2015 16:00:20 C:\Windows\Microsoft.NET\Framework64\v4.0.30319\SetupCache\v4.6.01055\NetFx_Full.mzz
69 22.03.2010 19:36:56 C:\Windows\Installer\$PatchCache$\Managed\00004159FA0090400000000000F01FEC\14.0.4763\MSORES.DLL
63 10.06.2009 23:02:16 C:\Windows\IME\IMESC5\DICTS\PINTLGT.IMD
63 10.06.2009 23:02:16 C:\Windows\winsxs\amd64_microsoft-windows-i..e-trigramdictionary_31bf3856ad364e35_6.1.7600.16385_none_12d6b2e35
55 22.07.2009 10:17:30 C:\Windows\Installer\$PatchCache$\Managed\1D763DBFF246FC747BB9B94EF83B0470\10.0.1600\ENG_RE_sqlservr_exe_64
69 18.01.2012 02:24:38 C:\Windows\Installer\$PatchCache$\Managed\00004159FA0090400000000000F01FEC\14.0.7015\MSORES.DLL
55 22.09.2011 21:07:34 C:\Windows\Installer\$PatchCache$\Managed\1D763DBFF246FC747BB9B94EF83B0470\10.3.5500\ENG_RE_sqlservr_exe_64
37 17.12.2007 14:57:48 C:\Windows\Installer\27f64005.msi
36 17.12.2007 14:57:48 C:\Windows\Installer\27f64006.msp
43 11.06.2010 17:52:10 C:\Windows\Installer\42cdaff.msp
96 21.06.2016 05:44:58 C:\Windows\Installer\2ad6e0ec.msp
32 10.06.2009 22:43:23 C:\Windows\Fonts\mingliub.ttc
32 10.06.2009 22:43:23 C:\Windows\winsxs\amd64_microsoft-windows-font-truetype-mingliub_31bf3856ad364e35_6.1.7600.16385_none_251699455
77 20.09.2015 10:27:56 C:\Windows\Installer\$PatchCache$\Managed\00006109C10000000000000000F01FEC\16.0.4288\MSORES.DLL
Deleting the first 50 files in C:\Windows would free 3.83 GB of disk space
Under the hood of GetFiles (http://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1056), FindFirstFile and FindNextFile are working. Unfortunately, for these API functions, *.xls and *.xlsx are just the same thing. Here is a workaround that filters unwanted *.xlsx files out - it sets the zero flag in a callback function thus telling GetFiles (http://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1056) not to include the file in the Files$() array:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
.code
cbGetFiles: ; the callback function
.if wInstr(edi, ".xlsx")
or ecx, -1 ; combined with the inc ecx below, this sets Zero?
.endif
inc ecx
ret
Init
GfCallback cbGetFiles ; define a callback function
GetFiles *.xls
SortFiles ; latest on top
For_ ebx=0 To eax-1 ; print the results
PrintLine Str$(GfSize(ebx)), Tb$, GfDate$(ebx), Spc2$, GfTime$(ebx), Tb$, Files$(ebx)
Next
EndOfCode
Project attached.
GuiParas equ "adding two numbers", w560, h84, icon Lens
include \masm32\MasmBasic\Res\MbGui.asm
GuiControl MyEdit, "edit", h=0+28, "1234+1000h", font -16:FW_SEMIBOLD
GuiControl MyStatusBar, "statusbar", "Change the number to see the sum in dec, hex and binary format", font -14:FW_MEDIUM
Event Command
.if nCode==EN_CHANGE
mov ecx, Win$(hMyEdit) ; get the text from the edit control
push Val(ecx) ; save first integer to stack
and edx, 127 ; get #chars used
lea ecx, [ecx+edx+1] ; skip the plus sign
void Val(ecx)
If_ edx==-127 Then xor eax, eax ; second value was invalid or empty
pop ecx ; pop first value
add ecx, eax ; sum
SetWin$ hMyStatusBar=Str$("Sum is %i = ", ecx)+Hex$(ecx)+"h = "+Bin$(ecx)+"b"
.endif
GuiEnd
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
SetGlobals num:QWORD=1, num10:REAL10=1
Init
PrintLine "Factorials from 1!!!! to 25!!!!"
For_ ct=1 To 25
fild num
fimul ct
fistp num
fld num10
fimul ct
fstp num10
Print Str$(ct), Tb$, Str$(num)
PrintLine At(40) Str$("%Jf", num10)
Next
EndOfCode
Output (QWORD overflows already at n=21):
Factorials from 1! to 25!
1 1 1.000000000000000000
2 2 2.000000000000000000
3 6 6.000000000000000000
4 24 24.00000000000000000
...
18 6402373705728000 6402373705728000.000
19 121645100408832000 121645100408832000.0
20 2432902008176640000 2432902008176640000.
21 -9223372036854775808 5.109094217170944000e+19
22 -9223372036854775808 1.124000727777607680e+21
23 -9223372036854775808 2.585201673888497664e+22
24 -9223372036854775808 6.204484017332394394e+23
25 -9223372036854775808 1.551121004333098598e+25
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
SetGlobals oldPos, ctDiff
Init
Cls
GetFiles *.a
For_ ecx=0 To eax-1
mov esi, Files$(ecx)
.if Rinstr(esi, "\")!=oldPos ; take one from each folder
mov oldPos, edx
inc ctDiff
PrintLine Str$(GfSize(ecx)), Tb$, GfDate$(ecx), Spc2$, GfTime$(ecx), Tb$, Files$(ecx)
.endif
Next
Inkey Str$("\n%i different folders containing *.a files found", ctDiff)
EndOfCode
To test it, just run the exe in your FreeBasic folder. Sample output:
98954 16.03.2019 12:23:26 doc\Print_to_Pdf-master\version_1.1\libPrint2Pdf_32.a
45108 08.03.2019 19:51:06 doc\Print_to_Pdf-master\libPrint2Pdf32.a
647940 31.01.2016 14:47:37 Fb64\lib\freebasic\win64\libfb.a
21808 31.03.2018 17:27:29 Fb64\lib\libLinked_Lists.a
3028 11.08.2008 09:14:00 FbEdit\Projects\Addins\fbShowVars\addins\libfbshowvars.dll.a
38560 21.08.2007 12:00:04 FbEdit\Projects\Addins\fbShowVars\needed\freebasic\lib\win32\libdisasm.a
6256 21.08.2007 12:00:04 FbEdit\Projects\Addins\fbShowVars\sample\libshowvars.a
8918 05.11.2007 08:25:38 FbEdit\Projects\CustCtrl\FBEPictView\libFBEPictView.a
3890 13.05.2007 19:50:32 FbEdit\Projects\CustCtrl\FBEVideo\libFBEVideo.a
3980 13.05.2007 19:50:34 FbEdit\Projects\CustCtrl\FBEWeb\libFBEWeb.a
6256 31.12.2000 23:00:00 FbEdit\Projects\Samples\Debug\libshowvars.a
349806 22.09.2016 16:23:58 lib\pcre-839-static\win32\libpcre.a
24286 27.12.2010 17:47:09 lib\win32\Cairo\libcairo-gobject.dll.a
3658 31.01.2016 12:09:12 lib\win32\libaclui.dll.a
23214 01.04.2013 12:30:12 PngLib\libpnglib2.a
3028 16.12.2008 21:29:25 Projects\Addins\fbShowVars\addins\libfbshowvars.dll.a
38560 16.12.2008 21:29:26 Projects\Addins\fbShowVars\needed\freebasic\lib\win32\libdisasm.a
6256 16.12.2008 21:29:25 Projects\Addins\fbShowVars\sample\libshowvars.a
8918 03.11.2007 22:33:32 Projects\CustCtrl\FBEPictView\libFBEPictView.a
3890 23.08.2007 21:57:18 Projects\CustCtrl\FBEVideo\libFBEVideo.a
3980 23.08.2007 21:57:20 Projects\CustCtrl\FBEWeb\libFBEWeb.a
6256 23.08.2007 21:57:24 Projects\Samples\Debug\libshowvars.a
3658 31.01.2016 11:09:14 WinFBE_Suite\FreeBASIC-1.06.0\lib\win32\libaclui.dll.a
24456 25.03.2019 20:31:49 libminz_32.a
27 different folders containing *.a files found
GuiParas equ "Gdi+ is easy", w400, h300, b DarkGrey
include \masm32\MasmBasic\Res\MbGui.asm ; *** Draw two persons - hit F6 to build & run ***
GuiControl Sbar, "statusbar", "You can size the window"
MakePath Head, Ellipse(150:180) ; w:h
MakePath Person, Polygon(180:160, 420:160, 500:400, 440:420, 380:250, 370:420, 450:750, 370:750, 300:500, 230:750, 160:750, 230:420, 220:250, 160:420, 100:400, 180:160)
MakePen hPen, RgbCol(160, 0, 0, 255), width 9 ; semi transparent blue pen
MakeBrush hBrushRed, RgbCol(255, 255, 0, 0)
MakeBrush hBrushGreen, RgbCol(100, 0, 255, 0)
Event Paint
GuiTextBox 99.9-100, 100.0-60, 98, auto, "Thanks for the inspiration, Nidud", bcol LiteYellow, font -14 ; -> post (http://masm32.com/board/index.php?topic=7000.msg93681#msg93681)
GuiDraw Head, hPen/hBrushRed, 51.0, 13.0 ; big person
GuiDraw Person, hPen/hBrushRed, 22.0, 6.0 ; x, y
GuiDraw Head, hPen/hBrushGreen, 27.0, 8.0, 500, 500 ; small person
GuiDraw Person, hPen/hBrushGreen, 0.0, 6.0, 900, 400 ; x, y, scale x, scale y
GuiEnd
include \masm32\MasmBasic\MasmBasic.inc ; Start a program just one time (http://masm32.com/board/index.php?topic=6483.msg93793#msg93793)
Init
Let esi=CL$(0) ; use the executable name as unique string
.if rv(GlobalFindAtom, esi)
MsgBox 0, Cat$(esi+" is already running"), "Sorry:", MB_OK or MB_TOPMOST
.else
push rv(GlobalAddAtom, esi)
MsgBox 0, Cat$(esi+" successfully started"), "Yeah:", MB_OK or MB_TOPMOST
call GlobalDeleteAtom
.endif
EndOfCode
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
PrintLine "option 1=[", Trim$(Extract$(Cat$(CL$()+"/"), "/opt1", "/")), "]" ; print the option
Let esi="option 2=["+Trim$(Extract$(Cat$(CL$()+"/"), "/opt2", "/"))+"]" ; assign to a string, then print it
Print esi
EndOfCode
OPT_Arg1 /opt1 That's fun /opt2 No problem ; the RichMasm way to test commandlines
Output:
option 1=[That's fun]
option 2=[No problem]
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Let esi=FileRead$("\Masm32\include\Windows.inc")+FileRead$("\Masm32\include\WinExtra.inc")
mov ebx, Len(esi) ; 2045966 bytes
PrintCpu 0
REPEAT 3
push 99
xor edi, edi
.Repeat
NanoTimer()
mov edx, ebx ; FAST with mode 64 needs the size of the buffer in edx
push Instr_(FAST, esi, "Duplicate include file winextra.inc", 64)
add edi, NanoTimer(µs)
pop edx
dec stack
.Until Sign?
pop eax ; stack correction
If_ Not edx Then Print "String not found - "
Print Str$("average: %i µs\n", edi/100)
ENDM
EndOfCode
Typical output:
Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz
average: 495 µs
average: 492 µs
average: 506 µs
Caballero inspired this little demo (http://masm32.com/board/index.php?topic=7109.msg99369#msg99369) showing how the old-fashioned question mark next to the close box works. Source + exe attached.
GuiParas equ "Context help demo", w500, h320, icon Star, b GreenBlue, s WS_SYSMENU or WS_CAPTION or WS_THICKFRAME
GuiMenu equ @File, &Open, &Save, -, E&xit, @Edit, Undo, Copy, Paste ; define a menu (only Open is implemented)
GuiWsExMain equ WS_EX_CONTEXTHELP
include \masm32\MasmBasic\Res\MbGui.asm ; hit F6 to build this template
GuiControl RichEdit, "richedit", wCL$(), h900, w1000-60
GuiControl PoorEdit, "edit", "Click into the question mark in the caption, then down here", y900, h100, w1000-60
GuiControl B1, "button", x=1000-60, h=0+30, w=0+60, "Button 1"
GuiControl B2, "button", x=1000-60, y=0+33, h=0+30, w=0+60, "Button 2"
GuiControl B3, "button", x=1000-60, y=0+66, h=0+30, w=0+60, "Button 3"
GuiControl Status, "statusbar", wCat$(wDate$+", "+wTime$) ; GuiControls require Unicode
StringToArray cfm$("richedit\nedit control\n1st button\n2nd button\n3rd button\nstatus bar\nlistbox"), help$()
GuiControl MyList, "listbox", help$(), x=1000-60, w=0+60, y=0+100, h=1000-100
Event Message
.if uMsg_==WM_HELP
mov ecx, lParam_
mov ecx, [ecx.HELPINFO.iCtrlId]
.if signed ecx>40
sub ecx, 41
SetWin$ hStatus="You clicked into the "+help$(ecx)
.endif
.endif
Event Menu
Switch_ MenuID
Case_ 0 ; menu entries start with 0
If_ FileOpen$("Rich sources=*.asc|All sauces=*.as?;*.inc|Resources=*.rc") Then SetWin$ hRichEdit=FileRead$(FileOpen$())
Endsw_
GuiEnd
@jj2007 re reply #2
As I have finally a workable "bare metal" (no WINDOWS whatsoever) environment - where I boot off a usb stick which is now the C:\ drive -
I wish to establish whether or not FreeBASIC DOS version can work with in-line assembly (prefer DOS version at this stage but will also consider windows version which I have used a bit).
Would you be able to supply a very simple FreeBASIC program that uses in-line assembly and I can verify if it is possible? Also advise precisely all the Command Line Switches for fbc.exe sampleprogram.exe that would be needed. I will try to compare things (code size, timings, etc) to calling an external program (that does what the in-line assembly does) via a SHELL like command from within FreeBASIC program.
My laptop is intel i7 x64 with 32 GByte RAM.
Quote from: Richard on January 05, 2021, 02:51:40 PMI wish to establish whether or not FreeBASIC DOS version can work with in-line assembly (prefer DOS version at this stage but will also consider windows version which I have used a bit).
Would you be able to supply a very simple FreeBASIC program that uses in-line assembly
Richard,
That is a question for the FreeBasic forum (https://www.freebasic.net/forum/search.php?search_id=newposts). I have never touched FB for DOS, so I cannot give you advice on that, sorry...
Note this is the bare minimum - just a demo. No checks, no bells and whistles. Use at your own risk.
GuiParas equ "A full-fledged raw Win32 GUI", icon Ball, b Turquoise ; title, icon, background
GuiMenu equ @File, &Open, &Save, -, E&xit, @Edit, Undo, Copy, Paste ; define a menu (only Open & Save are implemented)
include \masm32\MasmBasic\Res\MbGui.asm
GuiControl RichEdit, "richedit", CL$() ; load what you find in the commandline
GuiControl Status, "statusbar"
Event Menu
Switch_ MenuID
Case_ 0 ; Open (menu entries start with 0)
If_ FileOpen$("FB sources=*.bas|Includes=*.bi;*.inc|Resources=*.rc|All files=*.*") Then SetWin$ hRichEdit=FileRead$(FileOpen$())
Case_ 1 ; Save
FileWrite CL$(), stream:hRichEdit ; save contents of the RichEdit control
SetWin$ hStatus=CL$()+" was saved"
Endsw_
GuiEnd
OPT_Arg1 ?:\Masm32\MasmBasic\AscUser\OpenSaveFB.asc ; for testing with RichMasm
Just drag the tabbish source over the attached exe.
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Let esi=FileRead$(CL$())
Let esi=Replace$(esi, Tb$, Space$(8)))
FileWrite "NoMoreTabs.bas", esi
ShEx "NoMoreTabs.bas" ; launch it with ShellExecuteEx
EndOfCode
(I don't recommend it, though - I love my tabs and would never exchange them for spaces :badgrin:)
include \masm32\MasmBasic\MasmBasic.inc
Init
Let esi=FileRead$(99) ; WarAndPeaceChinese.txt from resource
Let edi=Utf8$(esi)
deb 4, "wLen", wLen(esi) ; Utf-16 chars
deb 4, "uLen", uLen(edi) ; Utf-8 chars
deb 4, "Len", Len(edi) ; bytes
uMsgBox 0, edi, "Chinese text as Utf-8:", MB_OK
wMsgBox 0, esi, "Chinese text as Utf-16:", MB_OK
EndOfCode
Rsrc
#include "resource.h"
IDI_APPLICATION ICON "\\Masm32\\MasmBasic\\icons\\Globe.ico" // Calc, Disk, Editor, Eye, Globe, MasmBasic, Smiley
01 RT_MANIFEST "\\Masm32\\MasmBasic\\Res\\XpManifest.xml"
99 RCDATA "WarAndPeaceChinese.txt"
Rsrc
wLen eax 526
uLen eax 525
Len eax 1449
So that is 1449 vs 2*526 bytes, which means that Utf-8 needs 37.7% more space in memory.
When saving the Utf-8 file, and zipping both together, the packed sizes differ by only 5.5%, though.
Project attached, requires MasmBasic. (https://www.jj2007.eu/Masm32_Tips_Tricks_and_Traps.htm)
Lots of people argue on the web whether Utf-16 is "harmful", and what are the pros and cons of Utf-8 vs Utf-16. As a matter of fact, both work just fine, as demonstrated below with two compound characters that are not in the Basic Multilingual Plane. For Chinese text, the space requirements are very similar, as demonstrated above, for English text, Utf-8 clearly wins, of course.
include \masm32\MasmBasic\MasmBasic.inc
Init
Cls
Let edi="aaa שָׁ bbb 𝕥 ccc" ; two compound characters with 6 and 4 bytes in Utf-8
PrintLine "Utf-8:", CrLf$, HexDump$(edi, 32)
Let esi=wRec$(edi) ; convert to Utf-16
PrintLine "Utf-16:", CrLf$, HexDump$(esi, 48)
if 0 ; activate if needed
lea ecx, [2*wLen(esi)]
FileWrite "compound.txt", esi, ecx
endif
uMsgBox 0, edi, "Utf-8:", MB_OK
wMsgBox 0, esi, "Utf-16:", MB_OK
EndOfCode
Output (20 = 32 dec are the spaces):
Utf-8:
002BD2B0 61 61 61 20 20 D7 A9 D7 81 D6 B8 20 20 62 62 62 aaa שָׁ bbb
002BD2C0 20 20 F0 9D 95 A5 20 20 63 63 63 00 00 00 00 00 𝕥 ccc.....
Utf-16:
0028DEF0 61 00 61 00 61 00 20 00 20 00 E9 05 C1 05 B8 05 a.a.a. . .�.�.�.
0028DF00 20 00 20 00 62 00 62 00 62 00 20 00 20 00 35 D8 . .b.b.b. . .5�
0028DF10 65 DD 20 00 20 00 63 00 63 00 63 00 00 00 00 00 e� . .c.c.c.....
Data come from the Allgemeine Ortskrankenkasse (AOK) Berlin (https://www.aok.de/pk/nordost/inhalt/krankschreibungs-analyse-der-aok-nordost-fuer-berlin/). The graph shows how many employees went on sick leave because they tested CoVid-19 positive.
GuiParas equ "Covid by profession", w1200, h630, b Grey, icon Plot
include \masm32\MasmBasic\Res\MbGui.asm
SetGlobals language=2 ; default is English
GuiControl MyCanvas, "canvas"
Recall 99, L$(), tab ; res 99 = CovidAOK.tab
Event CanvasPaint
For_ ct=0 To L$(?)-2
sar Val(L$(ct, 0)), 2 ; /4
xchg eax, ecx
GuiTextBox 20, ct*30+12, ecx, 26, Cat$(" "+L$(ct, language+1)), fcol White, bcol Red, DT_LEFT
Next
GuiTextBox 800, 200, 200, auto, L$(ct, language+1), fcol Black, bcol LiteYellow, DT_WORDBREAK, font -20:FW_BOLD
Event Key
Switch_ VKey
Case_ VK_D: Clr language ; German
Case_ VK_I: m2m language, 1 ; Italian
Case_ VK_E: m2m language, 2 ; English
Case_ VK_F: m2m language, 3 ; French
Endsw_
GuiRefresh
EndOfCode
(http://www.jj2007.eu/pics/CovidAOK.png)
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
StringToArray Launch$("cmd.exe /c dir *.asm"), f$() ; use Launch$ (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1047) to grab the output, translate into a string array
For_ each esi in f$(): <Let f$(ForNextCounter)=Mid$(esi, 35)> ; eliminate date, time, size, e.g. 27.08.17 23:34 16,527 SortAnIntegerArray.asm
QSort f$()
For_ each esi in f$(): PrintLine esi
EndOfCode
An alternative:
include \masm32\MasmBasic\MasmBasic.inc
Init
StringToArray Launch$("cmd.exe /c dir /O-D *.asm"), f$() ; use Launch$ to grab the output, translate into a string array
Delete f$(0), 5 ; eliminate the five strings at the beginning of a dir command
Delete f$(f$(?)-2), 2 ; eliminate the two trailing strings
For_ each esi in f$(): PrintLine esi ; print all files
EndOfCode
Output:
20.03.21 18:53 873 CovidAOK.asm
19.03.21 15:53 12,246 CheckNewPosts.asm
...
29.06.13 00:59 4,687 Win64_3e.asm
25.06.11 11:03 4,276 cids.asm
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
GetRegArray "HKLM\SYSTEM\ControlSet001\Control\Session Manager\Environment", MyEnv$(), MyData$()
QSortMode 1, 0, DataIndex() As DWORD ; case-insensitive, don't skip leading spaces
QSort MyEnv$() ; sort by name of key
Open "O", #1, "Environment.tab"
For_ each esi in MyEnv$(): <PrintLine #1, esi, Tb$, MyData$(DataIndex(ForNextCounter))>
Close #1
ShEx "Environment.tab"
EndOfCode
Output (shortened):
ComSpec %SystemRoot%\system32\cmd.exe
DXSDK_DIR C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\
FP_NO_HOST_CHECK NO
...
VS140COMNTOOLS C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools\
windir %SystemRoot%
Attached a version that writes the variables to a tab-delimited file and opens it in your default *.tab viewer (which might be MS Excel, for example).
The dir command is lousy (https://stackoverflow.com/questions/11215702/cmd-dir-b-s-plus-date), but fortunately we have a handy MasmBasic command: GetFiles (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1056) :thumbsup:
This little proggie should be put into a batch file e.g. as
\Masm32\bin\VS14\ml64.exe /c /Zp8 /Zi /Zd /Zf %1
echo ----------- assembly done --------------------
echo.
\Masm32\bin\VS14\link.exe /subsystem:console /entry:start /debug %~dpn1.obj /out:%~dpn164.exe
echo.
\Masm32\MasmBasic\Res\GetFiles %~dpn1* -time -age:2
Here is the (shortened) output for the source short.asm:
Microsoft (R) Macro Assembler (x64) Version 14.00.24210.0
...
----------- assembly done --------------------
Microsoft (R) Incremental Linker Version 14.00.24215.1
Copyright (C) Microsoft Corporation. All rights reserved.
----- files created 14:50:18
389120 03.04.2021 14:50:18 Short64.pdb
14336 03.04.2021 14:50:18 Short64.exe
77928 03.04.2021 14:50:18 Short64.ilk
309334 03.04.2021 14:50:18 Short.obj
The arguments:
-time show the current time as ----- files created 14:50:18 (see above)
-age:2 show only files that are less than 2 seconds old (i.e. ignore older stuff)
Source & exe attached.
*** Use at your own risk - make a copy of the zip archive before testing this; warning: doesn't work with filenames containing spaces (I still have to find out why) ***
To encrypt:
- Drag a zip archive over the attached exe
- Type a 4-letter password and hit Return
To decrypt:
- Drag the *.encrypted file over the attached exe
- Type the 4-letter password and hit Return
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Let ebx=Input$("Gimme the seed: ", "abcd")
Rand(seed:ebx) ; use e.g. "abcd" as seed (4 letters)
Let esi=CL$() ; get file name from the commandline
Let edi=FileRead$(esi) ; put file content into a buffer
.if Instr_(esi, ".zip")
; **** we got an archive - let's encrypt it: *******
push edi ; save pointer to the buffer
For_ ecx=0 To LastFileSize-1 Step 4
xor [edi+ecx], Rand(-1) ; xor buffer content with random dword
Next
pop edi ; restore start of buffer
Let esi=Left$(esi, Rinstr(esi, "."))+"encrypted"
FileWrite esi, edi, LastFileSize ; save xor'ed content
.else
; **** we got an encrypted archive - let's read it back: *******
Let edi=FileRead$(esi)
push edi
For_ ecx=0 To LastFileSize-1 Step 4
xor [edi+ecx], Rand(-1) ; reverse everything...
Next
pop edi
Let esi=Left$(esi, Rinstr(esi, "."))+"zip"
FileWrite esi, edi, LastFileSize ; save xor'ed content
ShEx esi ; open the archive with ShellExecute
.endif
EndOfCode
:biggrin:
Cheat, rename the file with underscores for the spaces then rename the results to whatever you need. :icon_idea:
Just for fun
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Let esi="123456789012345678901234567890123456789012345678901234567890"
push eax ; create a DWORD slot
xor ecx, ecx
or edx, -1
fld FP10(10.0) ; for multiplication by 10
fldz
.While 1
movzx eax, byte ptr [esi+ecx] ; "1"
.Break .if eax<"."
.if Zero?
mov edx, ecx ; store position of the dot
.else
and eax, 15 ; "1"->1
mov [esp], eax
fiadd dword ptr [esp] ; add 1 to current ST(0)
fmul ST, ST(1) ; multiply by 10
.endif
inc ecx ; advance position in string
.Endw
inc edx
.if !Zero?
sub ecx, edx
void Exp10(ecx) ; 10^position of dot
fdiv ; result/(10^position of dot)
.endif
fxch
fstp st
Inkey Str$("Result: %Jf", ST(0)v)
pop eax ; balance the stack
EndOfCode
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
fld1
fld FP10(0.00998001)
fdiv
PrintLine Str$("Result=%Jf", ST(0)v)
EndOfCode
Just for fun, a full-fledged Scintilla editor in five lines (use at your own risk):
include \masm32\MasmBasic\Res\MbGui.asm ; OPT_Icon Editor
GuiControl MySci, "scintilla", font 14:"Times New Roman", Cat$(FileRead$(CL$()))
Event Close
If_ <Alert("Save file?", "bye", MB_YESNO)>==IDYES Then FileWrite CL$(), Win$(hMySci) ; save it, or don't...
GuiEnd
P.S.: ScintillaPath equ <"\Masm32\wscite\SciLexer.dll">; drag a text file over the executable.
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Inkey Replace$(String$(1000, "x"), "x", cfm$("Hello Masm32\n")), "bye"
EndOfCode
That was easy, no? :tongue:
include \masm32\MasmBasic\MasmBasic.inc
SetGlobals REAL8 min8, max8
Init
PrintCpu 0
elements=2000000 ; two Million elements
Dim MyReal8() As REAL8
For_ ct=0 To 19
.if !Exist("MyReals.dat") || ct<5 ; measure creation times for the first 5
NanoTimer()
For_ ecx=0 To elements-1
Rand(-100, 100, MyReal8(ecx)) ; create a random number between -100 and +100 (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1030)
Next
PrintLine Str$("Creating an array of %i random doubles took ", ecx), NanoTimer$()
ArrayStore "MyReals.dat", MyReal8()
.endif
NanoTimer()
ArrayRead MyReal8(), "MyReals.dat" ; read array from disk
ArrayMinMax MyReal8(), min8, max8 ; assign min+max to two variables
PrintLine Str$("Reading and getting min=%7f", min8), Str$(" and max=%7f took ", max8), NanoTimer$()
Next
Inkey "hit any key"
EndOfCode
Output:
Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz
Creating an array of 2000000 random doubles took 83 ms
Reading and getting min=-99.99998 and max=99.99964 took 29 ms
Creating an array of 2000000 random doubles took 37 ms
Reading and getting min=-99.99989 and max=100.00000 took 43 ms
Creating an array of 2000000 random doubles took 39 ms
Reading and getting min=-99.99983 and max=99.99999 took 31 ms
Creating an array of 2000000 random doubles took 38 ms
Reading and getting min=-99.99996 and max=99.99998 took 32 ms
Creating an array of 2000000 random doubles took 38 ms
Reading and getting min=-99.99998 and max=99.99991 took 28 ms
Reading and getting min=-99.99998 and max=99.99991 took 27 ms
Reading and getting min=-99.99998 and max=99.99991 took 26 ms
Reading and getting min=-99.99998 and max=99.99991 took 27 ms
Reading and getting min=-99.99998 and max=99.99991 took 26 ms
Reading and getting min=-99.99998 and max=99.99991 took 27 ms
Reading and getting min=-99.99998 and max=99.99991 took 28 ms
Reading and getting min=-99.99998 and max=99.99991 took 25 ms
Reading and getting min=-99.99998 and max=99.99991 took 29 ms
Reading and getting min=-99.99998 and max=99.99991 took 29 ms
Reading and getting min=-99.99998 and max=99.99991 took 27 ms
Reading and getting min=-99.99998 and max=99.99991 took 31 ms
Reading and getting min=-99.99998 and max=99.99991 took 29 ms
Reading and getting min=-99.99998 and max=99.99991 took 28 ms
Reading and getting min=-99.99998 and max=99.99991 took 30 ms
Reading and getting min=-99.99998 and max=99.99991 took 29 ms
See also GB32 forum (https://gb32.proboards.com/thread/431/fast-basic-when-compared-basics)
Some benchmarks for GB32 (https://gb32.proboards.com/thread/431/fast-basic-when-compared-basics?page=2)
Hi JJ!
Where are your benmarchs of GB32?
Embedded in the source. The code is based on scalion's alias Nicolas Rey's tests (https://gb32.proboards.com/thread/431/fast-basic-when-compared-basics?page=2).
QuoteThe program consist in 4 test :
Test 1 "Init" - Initialisation of 10000 item of string array with a letter followed by numbers.
Test 2 "Swap" - Swap all items one time with another (not sorting) -> 49 995 000 swaps.
Test 3 "Mid" - Concat each 9999 first items with 2 parts of item+1 : mid(a(i+1),2) + mid(a(i+1),1,1)
Test 4 "Sort" - Sort ascending the array.
Perfect. Thanks :thumbsup:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
SetGlobals buffer[40]:BYTE
Init
lea edi, buffer
invoke GetLogicalDriveStrings, 40, edi
; Print HexDump$(edi, 32)
lea esi, [edi-2] ; to compensate leading 2*inc
.While 1
inc esi
inc esi
m2m edx, 32 ; len of buffer
.Break .if !Instr_(FAST, esi, ":\", 2 or 64) ; 64=len in edx, 2=ignore case of first char
lea esi, [eax-1] ; put esi on the drive letter
xchg rv(GetDriveType, esi), ecx
.if Choose(ecx, "unknown", "no root", "removable", "fixed", "remote", "cdrom", "ramdisk")==ChooseString ; *)
PrintLine esi, " is type ", eax ; Str$(" (value %i)", ecx)
.else
PrintLine "Drive ", esi, Str$(" is type %i", ecx)
.endif
.Endw
EndOfCode
*):
unknown equ 0
no root equ 1
DRIVE_REMOVABLE equ 2
DRIVE_FIXED equ 3
DRIVE_REMOTE equ 4
DRIVE_CDROM equ 5
DRIVE_RAMDISK equ 6
C:\ is type fixed
D:\ is type cdrom
E:\ is type removable
J:\ is type fixed
Just for fun :biggrin:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
MbHexDumpLen=819200 ; let's be generous (default is 8192 bytes)
Let esi=FileRead$(CL$()) ; read the file supplied in the commandline
FileWrite "~testTmp.asm", HexDump$(esi, LastFileSize, dq) ; use QWORD format
ShEx "~testTmp.asm" ; open in your IDE
EndOfCode
Usage: drag any executable (any file, actually) over bin2dq.exe
Output:
.DATA
hdBytes=49152
hdStart LABEL BYTE
.radix 16
dq 00000000300905A4D, 00000FFFF00000004, 000000000000000B8, 00000000000000040, 00000000000000000, 00000000000000000, 00000000000000000, 00000008000000000
dq 0CD09B4000EBA1F0E, 0685421CD4C01B821, 072676F7270207369, 06F6E6E6163206D61, 06E75722065622074, 020534F44206E6920, 00A0D0D2E65646F6D, 00000000000000024
...
dq 00D3E796C626D6573, 0000000000000000A, 00000000000000000, 00000000000000000, 00000000000000000, 00000000000000000, 00000000000000000, 00000000000000000
dq 00000000000000000, 00000000000000000, 00000000000000000, 00000000000000000, 00000000000000000, 00000000000000000, 00000000000000000, 00000000000000000
dq 00000000000000000, 00000000000000000, 00000000000000000, 00000000000000000, 00000000000000000, 00000000000000000, 00000000000000000, 00000000000000000
.radix 10
.code
; FileWrite "test.exe", offset hdStart, hdBytes
P.S., to test your result, you can use, for example:
include \masm32\MasmBasic\MasmBasic.inc
include ~testTmp.asm
Init
FileWrite "bin2test.exe", offset hdStart, hdBytes
Launch "bin2test.exe"
EndOfCode
If you prefer pure Masm32 SDK for testing, use this:
include \masm32\include\masm32rt.inc
include ~testTmp.asm
.code
start:
invoke write_disk_file, chr$("bin2test.exe"), offset hdStart, hdBytes ; re-create the exe
invoke WinExec, chr$("bin2test.exe"), SW_SHOW
exit
end start
Attached a program I am just working on, with several different kinds of buttons.
What is interesting: It behaves differently on Win 7 and Win 10. On the latter OS, some of the buttons receive up to 8 WM_PAINT messages in a row. Something is seriously wrong, and I am trying to find out what. It might have to do with a different behaviour of the CDDS_* messages, but I am not yet sure. I will keep you posted.
Quote from: jj2007 on August 15, 2022, 06:22:16 AM
Something is seriously wrong, and I am trying to find out what....
Thanks, but what I posted in the Campus is not supposed to act like a button exactly. It behaves like I intended it to. :cool:
Well, that's OK. There's no law that says you can't make a static control behave enough like a button to suit your purposes. You won't get a knock on your door in the middle of the night from the Coding Police.
Just for fun - project attached. TinyCalcV2.zip is an advanced version with hex and binary display. It will accept most common number formats as input.
GuiParas equ "Tiny calculator", w200, h130, m4, b LiteBlueGreen ; width+height, margins, background colour
include \masm32\MasmBasic\Res\MbGui.asm
GuiControl Calc, "Edit", bcol LiteYellow, w700, fcol Black, font -14, h0+32 ; colours & fonts have no effect with rtf files
GuiControl Go, "button", "-!!> clipboard", x700, w300, h0+32, bcol LiteYellow
GuiControl Status, "statusbar", "Type a formula"
SetGlobals Result:REAL10, res$
Event Command
.if MenuID==Go && nCode==BN_CLICKED
SetClip$=res$
invoke SendMessage, hWnd_, WM_CLOSE, 0, 0
.elseif MenuID==Calc && nCode==EN_CHANGE
xor ecx, ecx
SetWin$ hStatus=0
mov esi, Win$(hCalc)
.if Instr_(esi, "+")
inc ecx
.else
.if Instr_(esi, "-")
inc ecx
inc ecx
.else
.if Instr_(esi, "*")
dec ecx
.else
.if Instr_(esi, "/")
dec ecx
dec ecx
.endif
.endif
.endif
.endif
.if ecx
mov byte ptr [eax], 0 ; separate left and right halves
inc eax
MovVal ST(0), eax ; right half of expression
.if edx && edx<20
MovVal ST(0), esi
Switch_ ecx
Case_ 1: fadd
Case_ 2: fsubr
Case_ -1: fmul
Case_ -2: fdivr
Endsw_
fstp Result
Let res$=Str$(Result)
xchg eax, ecx
push ecx
add ecx, Len(ecx)
.Repeat
dec ecx
.Until byte ptr [ecx]!="0"
mov byte ptr [ecx+2], 0
pop eax
SetWin$ hStatus=Cat$("Result="+res$)
.endif
.endif
.endif
GuiEnd
This grew quickly, the source is now a whopping 149 lines :biggrin:
Version 3 has a tooltip, knows about 2**3=8 and accepts PI as first parameter. Enjoy :biggrin:
(http://www.jj2007.eu/pics/TinyCalc.png)
P.S.: Binary result and bit descriptor for e.g. 123*456 look like this:
1101101100011000
5432109876543210
It can be helpful to see which bits are set.
Kuron posted a coded message (https://masm32.com/board/index.php?msg=123620), here is how to decipher the text:
include \masm32\MasmBasic\MasmBasic.inc
Init
Let esi=Replace$("01010010 01001001 01010000 00100000 01001000 01110101 01110100 01100011 01101000 00101110 00100000 01011001 01101111 01110101 00100000 01110111 01101001 01101100 01101100 00100000 01000010 01100101 00100000 01001101 01101001 01110011 01110011 01100101 01100100 00100001 ", " ", Chr$("b", 13, 10))
Let edi=""
.While 1
.Break .if Val(esi)==-127 ; -127 flags "invalid string"
and edx, 15 ; isolate #characters used
add esi, edx
Let edi=edi+Chr$(eax)
.Endw
MsgBox 0, edi, "A message from Kuron:", MB_OK
EndOfCode
Let esi=Replace$ (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1079)("01010010 ... 00100001 ", " ", Chr$("b", 13, 10)) translates the string in esi to a valid format suitable for Val (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1202)():
01010010b
01001001b
01010000b
00100000b
01001000b
01110101b
01110100b
01100011b
01101000b
00101110b
00100000b
01011001b
01101111b
01110101b
00100000b
01110111b
01101001b
01101100b
01101100b
00100000b
01000010b
01100101b
00100000b
01001101b
01101001b
01110011b
01110011b
01100101b
01100100b
00100001b
Here is an example of a badly documented MasmBasic function:
include \masm32\MasmBasic\MasmBasic.inc
Init
DlgDefine "Ida is cute", 0, 0, 60, 62
DlgControl dcStatic, "Ida.ico", SS_ICON, 0, 0
DlgShow
EndOfCode
Project attached - extract all files to a folder, then run the exe (or build it with RichMasm).
Hi JJ
I am always willing to learn. As I have told you a few times, I have learnt to much from you.
However it would be quicker for me to drop your .exe into IDA to try and find out what is giong
on then to waddle through a billion lines of MasmBasic's macros.
So maybe a pure MASM demo would be nice.
Thanks.
Quote from: Caché GB on September 15, 2023, 08:30:34 AMHi JJ
I am always willing to learn. As I have told you a few times, I have learnt to much from you.
However it would be quicker for me to drop your .exe into IDA to try and find out what is giong
on then to waddle through a billion lines of MasmBasic's macros.
So maybe a pure MASM demo would be nice.
Thanks.
I would probably have shown how it's done in Win32, but an overly zealous moderator killed my desire to be kind, sorry.
Maybe tomorrow.
Quote from: jj2007 on September 15, 2023, 06:17:00 AMQuote from: NoCforMe on September 15, 2023, 06:10:01 AMThe two are identical. But Jochen, these are 16x16 icons.
Yes and no. It's a 128x128 icon, but Windows scales it down to 16x16 to let it fit into the caption. And it scales it down to 32x32 if you use Alt Tab.
I'd like to see one example where Windows uses the full 128x128. And don't come up with an icon editor, because I would consider that cheating. I mean an actual use of this icon beyond 32x32.
#EDIT# This kind of squabbling is not helpful to the OP. Not in the Campus, please.
Hi JJ
No worries.
Incidentally, how do we get the icons of the two apps on the right to behave
like the four on the left when Explorer is in Extra Large Icons View.
(https://i.postimg.cc/9wTm5CLX/Large-Icons.jpg) (https://postimg.cc/9wTm5CLX)
Good question :thumbsup:
WinMain, wc is WNDCLASSEX:
mov wc.hIcon, rv(LoadImage, eax, IDI_APPLICATION, IMAGE_ICON, 0, 0, 0)
mov wc.hIcon, rv(LoadIcon, eax, IDI_APPLICATION)
Both work, but they yield the same result. In contrast, as mentioned here (https://masm32.com/board/index.php?msg=123898), LoadImage behaves much better with a static control. Demo attached - you can actually size it!
Hi JJ
The only way I've bean able to achieve a solution to this Extra Large Icons View quetion.
1. The icon must be a 256x256 bmp or png. (To reduce binary bloatware, use png),
2. If this 256x256 icon is in an ICON GROUP, it mush be the first icon in the group.
3 This icon / icon group's Resource ID must be the lowest value (numeral) in the
Resource File's (*.rc) ICON listings.
What makes testing cumbersome is that Windows Explorer builds an icon caché. Therefore even if you
change the icon that Windows Explorer uses to display your app's Icon, the first icon you weiwed
that *.exe file with is the one that will be displayed. Until you, a) restart your PC, b) restart
Windows Explorer or delete Windows Explorer's icon caché file (Not recomended).
To avoid doing any of the above, for testing this icon qustion, you could create a head folder called "TEST ICON".
Within this folder "TEST ICON" create a bunch of folders calling them say "AA", "AB", ->, "AZ". Now each time you
reassemle your *.exe file, you copy this file and past it in a new ABC folder to veiw. When done testing new icon
arangments, remove all ABC folders.
The two runtime icons set in wc.hIcon and wc.hIconSm of your window class (WNDCLASSEX) are not affected by the Windows
Explorer's icon caché.
If you have two separate icon files, the one you set in the .hIcon member of WNDCLASSEX is the icon that will be displayed
in the Desktop's Taskbar at runtime. The icon file you set in .hIconSm, will be displayed in the your app's Window Title Bar.
Note:
Testing was performed using the Resource Compiler supplied by Visual Studio.
Quote from: Caché GB on September 17, 2023, 10:26:04 PMHi JJ
The only way I've bean able to achieve a solution to this Extra Large Icons View quetion.
1. The icon must be a 256x256 bmp or png. (To reduce binary bloatware, use png),
2. If this 256x256 icon is in an ICON GROUP, it mush be the first icon in the group.
3 This icon / icon group's Resource ID must be the lowest value (numeral) in the
Resource File's (*.rc) ICON listings...
Thanks, Caché - interesting stuff :thumbsup:
I don't normally use Explorer for file operations (I use FreeCommander XE (https://freecommander.com/en/downloads/)). If I use it, it's with the
details view, i.e. with the smallest possible icons. But it's good to know how to display one's icons in the XXL view, thanks :thup:
Not so small ?
With Setup program
FreeCommanderXE-32-public_setup.zip 16.12.2022 14.36 MB 9330AED7FA563A76C489FB0445905153CAE93CC591DE3B98B30C84DD468E75E4
Yes, Timo, it's a bit bloated. But it offers ten times as many functions as the SASM "IDE" at 20% of its size. Ok for me. If you have a better alternative, please let me know.
I am Pelles C user, so i poide have been best for me.
I am now retired from all work, so now i just try keep nature around me in good condition.
I just spend my time with lawnmower and grass trimmers, and shovel and scythe before a scythe man release me from this ugly world :biggrin: