Recently I've got an idea to experiment with random numbers ...
I want to create gray scale bitmaps from arrays of 256x256 bytes each and show them as borderless windows inside parent MDI window.
Is it possible to show custom windows in MDI ? (note - all of them will use different bitmaps )
How am I to create bitmap from array?
I've found GDICreateBitmapFromScan0 in MSDN treasury ... is it what I need for this purpose?
Just don't know how to start ...
give me a hint , please
Thanks old forum (http://www.masmforum.com/board/index.php?topic=11889.0) I've found something to start with:
invoke CreateBitmap, width, height, 1, 24, array
the bitmap is easy enough
what you really want is called a "DIB Section"
DIB sections have HBITMAP handles AND you can alter the pixel data, directly
generally, i find myself creating either 256-color or 24-bit types
once in a while, you might also want to create monochrome, 16-color, or 32-bit (or a couple other types)
either way, you start off with a BITMAPINFO structure
you initialize the values in the structure, then use CreateDIBSection
the structures for 256-color and 24-bit are a little different
256-color structures contain a palette, 24-bit structures do not
give me a little time, and i will post code for 256-color and 24-bit DIB Sections
as for the "borderless windows in an MDI"
well - if you want borderless windows, maybe you don't want an MDI
MDI child windows have borders, as far as i know
but - you don't need an MDI to create a borderless child window
in fact, you may not need a child window, at all
depending on what you want to do, you might be able to just create a rectangle in the client area and use that to draw on
question...
are you using an MDI window for other reasons
or were you thinking of using an MDI just for these windows ?
It makes sense what you said about MDI
All I want is to draw several different bitmaps ...
Ok, first I must learn how to create bitmaps and draw them to client area ( but in the future I want to make every of those bitmaps selectable and resizable - that's why I mentioned MDI)
As I told all the bitmaps will be in gray scale :
R = G = B
Now I try to fill the array with random numbers:
.data
arrsize dd 256*4*256 ; bitmap 256x256 pixels , B,G,R,0 bytes for each pixel
.code
...
mov hMem,alloc(arrsize)
is it right?
Quote from: dedndave on September 22, 2013, 03:22:04 AM
question...
are you using an MDI window for other reasons
or were you thinking of using an MDI just for these windows ?
just for these windows, Dave
well - 3 things...
an MDI window is somewhat complicated - lol
although, it may be what you want, in the end - each MDI child has a border and a title bar, though
it's a little difficult to make a sizable window without borders, but it can be done
if R=G=B (i.e. all gray-shades), then 256-color bitmaps are ideal
you may not need to allocate memory for the array
just use the DIB Section data area as the array :biggrin:
Quote from: dedndave on September 22, 2013, 03:33:48 AM
if R=G=B (i.e. all gray-shades), then 256-color bitmaps are ideal
you may not need to allocate memory for the array
just use the DIB Section data area as the array :biggrin:
Ok, let's forget about MDI for now :biggrin:
I will make it simple
So CreateDIBSection function is what I must call firstly to get an offset to bitmap bits ... am I right?
right
you pass it the address of a BITMAPINFO structure and the address of a dword that will receive a pointer to the data
Quote from: vertograd on September 22, 2013, 01:36:21 AM
Is it possible to show custom windows in MDI ? (note - all of them will use different bitmaps )
Maybe?
\Masm32\examples\exampl01\mdidemo\mditest.asm
MakeMDIwin proc
..
mov mdihWnd, eax
invoke SetWindowLong, eax, GWL_STYLE, WS_CHILD or WS_THICKFRAME
invoke ShowWindow,mdihWnd,SW_SHOW
invoke MoveWindow, mdihWnd, 9, 9, 300, 200, 1
ret
Quote from: jj2007 on September 22, 2013, 03:58:35 AM
Quote from: vertograd on September 22, 2013, 01:36:21 AM
Is it possible to show custom windows in MDI ? (note - all of them will use different bitmaps )
Maybe?
\Masm32\examples\exampl01\mdidemo\mditest.asm
MakeMDIwin proc
..
mov mdihWnd, eax
invoke SetWindowLong, eax, GWL_STYLE, WS_CHILD or WS_THICKFRAME
invoke ShowWindow,mdihWnd,SW_SHOW
invoke MoveWindow, mdihWnd, 9, 9, 300, 200, 1
ret
JOCHEN
It works!!! :t
Though the windows seem to be semi-transparent . I can't figure out is it intentionally or not :redface:
FINDSTR /S "BITMAPINFO" *.ASM in \MASM32\EXAMPLES folder gave me two excellent results:
- exampl01\showdib\showdib2.asm:
- exampl04\pascal\pascal.asm:
+ examples\exampl01\mdidemo\mditest.asm
Now I have all required info
Thank you, Dave and Jochen !
try this out....
notice that rows in bitmaps are inverted
that is, the bottom row of the image is the first row of data
you can invert this behaviour by negating the image height in the header
however, inverted bitmaps cannot be compressed (not within the ms bitmap RLL spec, at least)
this is part of the very old windows bitmap specification, dating back to before windows 3 :P
seeing as we are filling the bitmap with random data, it doesn't matter
WOW , Dave
It's wonderful!!! :t
Those pictures remind me wet sand textures !
Thank you SO MUCH !
i had fun writing it :t
and - when i first got it up and running, i saw a flaw in my random generator code
a good random generator should create nice "blended" bitmaps
mine had a streak in it of darker columns :redface:
now fixed, and generating better random data :t
I must say it's the best MASM example I've ever seen!
I never thought the source code may be so artistically formatted :t
Now I looked at your source and saw that you used your own random number generator
It would be interesting to test the default MASM nrandom routine in such a way
Quote from: dedndave on September 22, 2013, 06:26:18 AM
when i first got it up and running, i saw a flaw in my random generator code
It's easy to make a mistake when rolling your own RNG. I did a scatter-plot test of your code using the same method I used to find the problem in the original nrandom, and problems in multiple other generators, and in the 10 minutes or so I spent trying various resolutions I could see no non-random patterns.
;==============================================================================
include \masm32\include\masm32rt.inc
.686
;==============================================================================
.data
qwRnd64 QWORD ?
dwAsCnt dd 1
hInstance dd 0
hDlg dd 0
hdc dd 0
msg MSG <>
rc RECT <>
sz db 30 dup(0)
ctr dd 0
.code
;==============================================================================
ASeed PROC base:DWORD
;Auto-Seeding Unscaled Random QWORD Generator - DednDave
;version 1, 11-2010
;version 2, 5-2013
;version 3, 6-2013
;------------------------------
mov ecx,dwAsCnt
mov edx,dword ptr qwRnd64+4
dec ecx
.if ZERO?
rdtsc
mov cl,al
mov dword ptr qwRnd64,eax
mov ch,1
xor edx,eax
.endif
mov eax,1517746329
mov dwAsCnt,ecx
mul edx
add eax,dword ptr qwRnd64
adc edx,0
xor edx,eax
mov dword ptr qwRnd64+4,eax
mov dword ptr qwRnd64,edx
; mov eax, edx ; uncomment this to test low-order dword
xor edx, edx
div base
mov eax, edx
ret
ASeed ENDP
;==============================================================================
DialogProc proc hwndDlg:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD
SWITCH uMsg
CASE WM_CTLCOLORDLG
invoke GetStockObject, WHITE_BRUSH
ret
CASE WM_SIZE
invoke InvalidateRgn, hwndDlg, NULL, TRUE
CASE WM_COMMAND
SWITCH wParam
CASE IDCANCEL
invoke DestroyWindow, hwndDlg
ENDSW
CASE WM_CLOSE
invoke DestroyWindow, hwndDlg
CASE WM_DESTROY
invoke PostQuitMessage, NULL
ENDSW
xor eax, eax
ret
DialogProc endp
;==============================================================================
start:
;==============================================================================
invoke GetModuleHandle, NULL
mov hInstance, eax
Dialog "Test", \
"FixedSys", 11, \
WS_VISIBLE or WS_OVERLAPPEDWINDOW or \
DS_CENTER, \
0, \
0,0,100,75, \
1024
CallModelessDialog hInstance, 0, DialogProc, NULL
mov hDlg, eax
invoke GetDC, hDlg
mov hdc, eax
invoke Sleep, 1000
msgLoop:
invoke PeekMessage, ADDR msg, NULL, 0, 0, PM_REMOVE
.IF msg.message != WM_QUIT
.IF eax != 0
invoke IsDialogMessage, hDlg, ADDR msg
.ELSE
invoke GetClientRect, hDlg, ADDR rc
inc ctr
cmp ctr, 1000
jb @f
invoke szappend, addr sz, chr$(" "), 0
mov esi, eax
invoke szappend, addr sz, str$(rc.right), esi
mov esi, eax
invoke szappend, addr sz, chr$(" x "), esi
mov esi, eax
invoke szappend, addr sz, str$(rc.bottom), esi
invoke SetWindowText, hDlg, addr sz
mov ctr, 0
@@:
invoke ASeed, rc.right
mov ebx, eax
invoke ASeed, rc.bottom
mov esi, eax
invoke ASeed, 1 SHL 24
mov edi, eax
invoke SetPixel, hdc, ebx, esi, edi
.ENDIF
jmp msgLoop
.ENDIF
invoke ExitProcess, eax
;==============================================================================
end start
if you comment out the XOR EDX,EAX from my ASeed routine, you will see the flaw it had :P
as for it being a good example - well, i could have added a lot more comments, but thanks :redface:
i found a small error in the RC file...
#define IDI_ICON 501
was supposed to be
#define IDI_ICON 101
i updated the attachment, above
My test showed no problem without the XOR EDX,EAX even after I converted the colors to monochrome.
commented out the XOR EDX,EAX in ASeed proc - really there was a flaw (see the screenshot below)
Quote from: MichaelW on September 22, 2013, 12:04:55 PM
My test showed no problem without the XOR EDX,EAX even after I converted the colors to monochrome.
the ASeed proc code in the Dave's attachment slightly differs from that in your post
changed RC file to:
#define IDI_ICON 101
and rebuild the program . Now you can see your icon on the screenshot
about comments ... maybe one day you will add them to complete this example ? ;)
yup - that's the flaw - lol
it's only the 3rd byte in each qword, but the easy fix was to alter the entire lower dword
Michael - not sure which program you are running, but this is already monochrome
the ASeed routine has evolved a little bit - with the XOR, it's the 4th version, now
i may add some comments - some of the graphics stuff is probably a little tricky for beginners
I also tested nrandom routine with Michael's code (see screenshot below) :
msgLoop:
...
@@:
; invoke ASeed, rc.right
invoke nrandom,0ffffffffh
invoke nseed,eax
invoke nrandom,rc.right
mov ebx, eax
; invoke ASeed, rc.bottom
invoke nrandom,0ffffffffh
invoke nseed,eax
invoke nrandom,rc.bottom
mov esi, eax
; invoke ASeed, 1 SHL 24
; mov edi, eax
invoke nrandom,0ffffffffh
invoke nseed,eax
invoke nrandom,256
mov ah,al
shl eax,8
mov al,ah
mov edi,eax
invoke SetPixel, hdc, ebx, esi, edi
...
Michael: your code is very nice for testing various RNGs !
One minor problem that I could not solve is to set client area to 256x256 pixels (the height can be either 255 or 257 but not 256) :
Quote
Dialog "Test", \
"FixedSys", 11, \
WS_VISIBLE or WS_OVERLAPPEDWINDOW or \
DS_CENTER, \
0, \
0,0,128,136, \ ; original size : 100,75
1024
when you create a dialog in resource, it is sized by "dialog base units"
dialog base units are based on the system font size ::)
if you set the size with MoveWindow or SetWindowPos, you can specify the size in pixels
of course, you have to add the border and title bar widths
nothing is ever easy - lol
Well , I made the window 256x256:
invoke MoveWindow, hDlg, 10,10, 272,295,1
you could do something like this.....
SetClientSize PROTO :HWND,:DWORD,:DWORD
.CODE
INVOKE SetClientSize,hWindow,256,256
;
;
SetClientSize PROC USES EDI hWnd:HWND,dwClientWidth:DWORD,dwClientHeight:DWORD
LOCAL _rcClient :RECT
LOCAL _rcWindow :RECT
;--------------------------------
INVOKE GetClientRect,hWnd,addr _rcClient
INVOKE GetWindowRect,hWnd,addr _rcWindow
mov ecx,dwClientWidth
mov edx,dwClientHeight
mov eax,_rcWindow.left
mov edi,_rcWindow.top
add ecx,_rcWindow.right
add edx,_rcWindow.bottom
add ecx,_rcClient.left
add edx,_rcClient.top
sub ecx,_rcClient.right
sub edx,_rcClient.bottom
sub ecx,eax
sub edx,edi
INVOKE MoveWindow,hWnd,eax,edi,ecx,edx,TRUE
ret
SetClientSize ENDP
it gets the current window and client sizes, and adjusts the window size to match the desired client size
Thank you, Dave
very useful routine
Just tested nrandom,2 i.e. only Black and White (see screenshot):
@@:
; invoke ASeed, rc.right
invoke nrandom,0ffffffffh
invoke nseed,eax
invoke nrandom,rc.right
mov ebx, eax
; invoke ASeed, rc.bottom
invoke nrandom,0ffffffffh
invoke nseed,eax
invoke nrandom,rc.bottom
mov esi, eax
; invoke ASeed, 1 SHL 24
; mov edi, eax
invoke nrandom,0ffffffffh
invoke nseed,eax
; invoke nrandom,256
; mov ah,al
; shl eax,8
; mov al,ah
; mov edi,eax
invoke nrandom,2
.if eax == 0
mov edi,0
.elseif
mov edi, 0ffffffh
.endif
invoke SetPixel, hdc, ebx, esi, edi
Now I 'm thinking of drawing a grid (let's say 64x64) of small rectangles ( 8x8 pixels or so) which will be randomly filled only with black and white brushes.
Client area background is meant to be gray.
Dave,
I was trying to use a modification of my code to see the problem with your generator when the:
xor edx,eax
is commented out. I could not see the problem using random colors, so I changed the code to use random monochrome colors, but still could not see the problem. AFAICT the problem in your code sets the color for every eighth pixel to zero. If I change the code in FillDIBRandGray to use the low-order dword of qwRnd64 in both statements, then every fourth pixel has the color set to zero. If I change the code to use the high-order dword of qwRnd64 in both statements, then there are no vertical bands, but I can see a large number of small-scale repetitive patterns.
Here it is , based on \MASM32\examples\exampl06\barchart demo (requires barchart.inc)
Thank you Dave for your SetClientSize routine , I used it in this demo:
.486 ; create 32 bit code
.model flat, stdcall ; 32 bit memory model
option casemap :none ; case sensitive
include barchart.inc ; local includes for this file
DrawRect PROTO :DWORD,:DWORD,:DWORD,:DWORD
SetClientSize PROTO :HWND,:DWORD,:DWORD
.code
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
; ------------------
; set global values
; ------------------
mov hInstance, FUNC(GetModuleHandle, NULL)
mov CommandLine, FUNC(GetCommandLine)
mov hIcon, FUNC(LoadIcon,hInstance,500)
mov hCursor, FUNC(LoadCursor,NULL,IDC_ARROW)
mov sWid, FUNC(GetSystemMetrics,SM_CXSCREEN)
mov sHgt, FUNC(GetSystemMetrics,SM_CYSCREEN)
call Main
invoke ExitProcess,eax
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
Main proc
LOCAL Wwd:DWORD,Wht:DWORD,Wtx:DWORD,Wty:DWORD
STRING szClassName,"BlacknWhite_class"
; --------------------------------------------
; register class name for CreateWindowEx call
; --------------------------------------------
invoke RegisterWinClass,ADDR WndProc,ADDR szClassName,
hIcon,hCursor,COLOR_BTNSHADOW+1;COLOR_APPWORKSPACE ;COLOR_BTNFACE+10
mov Wwd, 512
mov Wht, 512
invoke TopXY,Wwd,sWid
mov Wtx, eax
invoke TopXY,Wht,sHgt
mov Wty, eax
invoke CreateWindowEx,WS_EX_LEFT,
ADDR szClassName,
ADDR szDisplayName,
WS_OVERLAPPED or WS_SYSMENU,
Wtx,Wty,Wwd,Wht,
NULL,NULL,
hInstance,NULL
mov hWnd,eax
INVOKE SetClientSize,hWnd,512,512
; ---------------------------
; macros for unchanging code
; ---------------------------
DisplayWindow hWnd,SW_SHOWNORMAL
call MsgLoop
ret
Main endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
RegisterWinClass proc lpWndProc:DWORD, lpClassName:DWORD,
Icon:DWORD, Cursor:DWORD, bColor:DWORD
LOCAL wc:WNDCLASSEX
mov wc.cbSize, sizeof WNDCLASSEX
mov wc.style, CS_BYTEALIGNCLIENT or \
CS_BYTEALIGNWINDOW
m2m wc.lpfnWndProc, lpWndProc
mov wc.cbClsExtra, NULL
mov wc.cbWndExtra, NULL
m2m wc.hInstance, hInstance
m2m wc.hbrBackground, bColor
mov wc.lpszMenuName, NULL
m2m wc.lpszClassName, lpClassName
m2m wc.hIcon, Icon
m2m wc.hCursor, Cursor
m2m wc.hIconSm, Icon
invoke RegisterClassEx, ADDR wc
ret
RegisterWinClass endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
MsgLoop proc
LOCAL msg:MSG
push esi
push edi
xor edi, edi ; clear EDI
lea esi, msg ; Structure address in ESI
jmp jumpin
StartLoop:
invoke TranslateMessage, esi
invoke DispatchMessage, esi
jumpin:
invoke GetMessage,esi,edi,edi,edi
test eax, eax
jnz StartLoop
mov eax, msg.wParam
pop edi
pop esi
ret
MsgLoop endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
WndProc proc hWin:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
Switch uMsg
Case WM_PAINT
invoke Paint_Proc,hWin
return 0
Case WM_DESTROY
invoke PostQuitMessage,NULL
return 0
Endsw
invoke DefWindowProc,hWin,uMsg,wParam,lParam
ret
WndProc endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
TopXY proc wDim:DWORD, sDim:DWORD
mov eax, [esp+8]
sub eax, [esp+4]
shr eax, 1
ret 8
TopXY endp
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
Paint_Proc proc hWin:DWORD
LOCAL hDC :DWORD
LOCAL Rct :RECT
LOCAL Ps :PAINTSTRUCT
LOCAL x :DWORD
LOCAL y :DWORD
LOCAL recX :DWORD
LOCAL recY :DWORD
mov hDC, rv(BeginPaint,hWin,ADDR Ps)
mov x,0
mov recY,40
mov y,0
nextY:
.WHILE x<24
mov ebx,40
mov eax,18
mul x
add ebx,eax
invoke nrandom,0ffffffffh
invoke nseed,eax
invoke nrandom,2
.if eax == 0
invoke DrawRect,hDC,ebx,recY, 000000h
.elseif
invoke DrawRect,hDC,ebx,recY, 0ffffffh
.endif
xor ebx,ebx
inc x
.ENDW
mov x,0
inc y
.WHILE y<24
mov recY,40
mov eax,18
mul y
add recY,eax
jmp nextY
.ENDW
invoke FrameWindow,hWnd,4,1,1
invoke FrameWindow,hWnd,7,1,0
; ----------------------------------------
invoke EndPaint,hWin,ADDR Ps
ret
Paint_Proc endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
DrawRect proc hDC:DWORD,tx:DWORD,ty:DWORD,bruchcol:DWORD
LOCAL rct :RECT
m2m rct.left, tx ; set top X and Y to structure members
m2m rct.top, ty
m2m rct.right, tx
m2m rct.bottom, ty
mov eax, 16
add rct.right, eax
add rct.bottom, 16
invoke FillRect, hDC,ADDR rct, ; fill rect with fill colour
rv(CreateSolidBrush,bruchcol)
ret
DrawRect endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
SetClientSize PROC USES EDI hwnd:HWND,dwClientWidth:DWORD,dwClientHeight:DWORD
LOCAL _rcClient :RECT
LOCAL _rcWindow :RECT
;--------------------------------
INVOKE GetClientRect,hWnd,addr _rcClient
INVOKE GetWindowRect,hWnd,addr _rcWindow
mov ecx,dwClientWidth
mov edx,dwClientHeight
mov eax,_rcWindow.left
mov edi,_rcWindow.top
add ecx,_rcWindow.right
add edx,_rcWindow.bottom
add ecx,_rcClient.left
add edx,_rcClient.top
sub ecx,_rcClient.right
sub edx,_rcClient.bottom
sub ecx,eax
sub edx,edi
INVOKE MoveWindow,hwnd,eax,edi,ecx,edx,TRUE
ret
SetClientSize ENDP
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start
Now I'm planning to add some interaction with the user but don't know how to do it yet ...
Here is a version that can optionally center the window on the screen:
;---------------------------------------------------------------------
; This procedure sizes the specified window so the client area is the
; specified width and height and optionally centers the window on the
; the screen.
;
; Note that AdjustWindowRect cannot be used to calculate the required
; window rectangle here because it does not support windows with the
; WS_OVERLAPPED style.
;
; Not tested in combination with a status bar, menu bar, etc.
;---------------------------------------------------------------------
SetClientSize proc hwnd:HWND, pixelWidth:DWORD, pixelHeight:DWORD, fCenter:DWORD
LOCAL _x:DWORD, _y:DWORD, nWidth:DWORD, nHeight:DWORD
LOCAL rcc:RECT, rcw:RECT
invoke GetClientRect, hwnd, ADDR rcc
invoke GetWindowRect, hwnd, ADDR rcw
mov ecx, rcw.right
sub ecx, rcw.left ; ecx = window width - 1
mov eax, pixelWidth
dec eax ; eax = pixelWidth - 1
mov edx, rcc.right ; edx = client width - 1
sub edx, eax ; edx = difference
sub ecx, edx ; adjust width
mov nWidth, ecx
mov ecx, rcw.bottom
sub ecx, rcw.top ; ecx = window height - 1
mov eax, pixelHeight
dec eax ; eax = pixelHeight - 1
mov edx, rcc.bottom ; edx = client height - 1
sub edx, eax ; edx = difference
sub ecx, edx ; adjust height
mov nHeight, ecx
.IF fCenter
invoke GetSystemMetrics, SM_CXSCREEN
shr eax, 1
mov edx, nWidth
shr edx, 1
sub eax, edx
mov _x, eax
invoke GetSystemMetrics, SM_CYSCREEN
shr eax, 1
mov edx, nHeight
shr edx, 1
sub eax, edx
mov _y, eax
.ELSE
m2m _x, rcw.left
m2m _y, rcw.top
.ENDIF
invoke MoveWindow, hwnd, _x, _y, nWidth, nHeight, TRUE
ret
SetClientSize endp
And just in case it might be useful here, the attachment contains the most recent test of some code for a Minesweeper clone that uses a bitmap button grid. It's barely functional, and has multiple unsolved problems, but it might provide some useful information or ideas.
Michael,
I've just tested your routine. It works fine .One detail though:
if I specify 512 as width/height your window's title becomes 511x511, and 512x512 if I pass 513,513 as parameters
Quote from: vertograd on September 23, 2013, 05:33:44 AM
One detail though:
if I specify 512 as width/height your window's title becomes 511x511, and 512x512 if I pass 513,513 as parameters
Sorry, I must have made an error somewhere, that unfortunately I don't have time to fix any time soon.
It's OK , Michael
I'll try to find it myself (tomorrow maybe )
Michael...
it is interesting to note that looking at the data in different ways accentuates different repeat patterns
if i had looked at it in terms of a series of individual bits, i might not have noticed a pattern that was byte related
some time ago, there was a thread where we were using a series of tests to check randomness
many of the tests used were designed to examine data on a byte-by-byte basis
we were using them to look at several generators that spit out dword and qword data
i just don't think these byte-size tests are a valid way to examine qword data
the results we are seeing here seem to validate that view
Quote from: dedndave on September 23, 2013, 05:48:44 AM
many of the tests used were designed to examine data on a byte-by-byte basis
we were using them to look at several generators that spit out dword and qword data
i just don't think these byte-size tests are a valid way to examine qword data
Bytes should be as "random" as their longer brothers, and vice versa. But it seems we discussed this already (http://masm32.com/board/index.php?topic=1346.msg13620#msg13620) ;-)
Quote from: KeepingRealBusy on December 06, 2012, 10:32:12 AM
Test several different RNGs, save the results to a file, then run ENT (http://www.fourmilab.ch/random/) to check the randomness.
of course they should be
but, examining everything as bytes (as ENT does) is like taking all your pictures with a telephoto lens
i have known a few women that required a wide-angle lens :lol:
not the wife, of course
If the BYTEs inside a DWORD show a different degree of randomness, it means that e.g. low values or negative values of the DWORD are overrepresented. Consider a bitstream with n bytes....
A good RNG (like Alex' Rand() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1030) :P) does not show such bias. But there are many bad ones around (http://www.cacert.at/cgi-bin/rngresults), of course, including highly "official" ones from CRT etc...
that's an advanced stuff, guys
I don't quite understand what you're talking about :biggrin:
Jochen, thank you for the useful links
A link to AxRand algo (http://www.masm32.com/board/index.php?topic=11679.msg122749#msg122749) from your page (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1030) didn't work for me :(
*** *** ***
One question still remains very unclear :
Is it possible to create borderless window using an image
There's a splash example in \MASM32\examples\exampl01\splash folder . It uses a brush ... but I want a BITMAP ...
Does anybody here know how to do it?
first, create a class structure and register it with RegisterClassEx
then use CreateWindowEx to create a child window
create the child window in the WndProc, WM_CREATE handler of the main window
CreateWindowEx has a dwStyle parameter that allows you to set up borders, title bars, etc
use
WS_CHILD or WS_VISIBLE or WS_CLIPCHILDREN
Quote from: vertograd on September 23, 2013, 08:50:42 PM
A link to AxRand algo (http://www.masm32.com/board/index.php?topic=11679.msg122749#msg122749)
http://www.masmforum.com/board/index.php?topic=11679
Re Bitmap: WM_PAINT handler & BitBlt are the starting points...
Now I'm recalling I saw an example of custom windows in the previous MASM pack ...
must switch to another computer for it :(
Ok , thank you all
Now I'm unplugging from this system for ah hour or two
Quote from: vertograd on September 23, 2013, 05:33:44 AM
Michael,
I've just tested your routine. It works fine .One detail though:
if I specify 512 as width/height your window's title becomes 511x511, and 512x512 if I pass 513,513 as parameters
I have now verified that this code:
invoke GetClientRect, hDlg, ADDR rc
inc ctr
cmp ctr, 1000
jb @f
invoke szappend, addr sz, chr$(" "), 0
mov esi, eax
invoke szappend, addr sz, str$(rc.right), esi
mov esi, eax
invoke szappend, addr sz, chr$(" x "), esi
mov esi, eax
invoke szappend, addr sz, str$(rc.bottom), esi
invoke SetWindowText, hDlg, addr sz
Displays the correct size in the title bar, so the error is probably in my SetClientSize procedure. Try Dave's version.
Quote from: MichaelW on September 23, 2013, 11:03:53 PM
Displays the correct size in the title bar, so the error is probably in my SetClientSize procedure. Try Dave's version.
Tried Dave's version. It works correctly : if I specify 512x512 in the parameters I get 512x512 in the title bar.
I'll try to find the error ...
EDIT: Commenting out "DEC EAX" solved the problem but it unlikely to be the ERROR because your comment shows that you intentionally decremented it for some unknown for me reason (sorry, I'm newbie) :
Quote
SetClientSize proc hwnd:HWND, pixelWidth:DWORD, pixelHeight:DWORD, fCenter:DWORD
LOCAL _x:DWORD, _y:DWORD, nWidth:DWORD, nHeight:DWORD
LOCAL rcc:RECT, rcw:RECT
invoke GetClientRect, hwnd, ADDR rcc
invoke GetWindowRect, hwnd, ADDR rcw
mov ecx, rcw.right
sub ecx, rcw.left ; ecx = window width - 1
mov eax, pixelWidth
;dec eax ; eax = pixelWidth - 1
mov edx, rcc.right ; edx = client width - 1
sub edx, eax ; edx = difference
sub ecx, edx ; adjust width
mov nWidth, ecx
mov ecx, rcw.bottom
sub ecx, rcw.top ; ecx = window height - 1
mov eax, pixelHeight
;dec eax ; eax = pixelHeight - 1
mov edx, rcc.bottom ; edx = client height - 1
sub edx, eax ; edx = difference
sub ecx, edx ; adjust height
mov nHeight, ecx
The possibility to center the window on the screen is very nice :t
*** *** ***
I've found that example in old MASM32 pack:
\masm32\examples\exampl06\mob\cws (i.e. CUSTOM WINDOWS SHAPE )
Again , thank you all for the help!
here is another version that sets the window size by client size and centers the window on the screen
SetClientSizeCntr PROTO :HWND,:DWORD,:DWORD
SetClientSizeCntr PROC USES EDI hWnd:HWND,dwClientWidth:DWORD,dwClientHeight:DWORD
LOCAL _rcClient :RECT
LOCAL _rcWindow :RECT
;--------------------------------
INVOKE GetClientRect,hWnd,addr _rcClient
INVOKE GetWindowRect,hWnd,addr _rcWindow
INVOKE GetSystemMetrics,SM_CXSCREEN
xchg eax,edi ;EDI = screen width
INVOKE GetSystemMetrics,SM_CYSCREEN ;EAX = screen height
mov edx,dwClientHeight
mov ecx,dwClientWidth
add edx,_rcWindow.bottom
add ecx,_rcWindow.right
add edx,_rcClient.top
add ecx,_rcClient.left
sub edx,_rcClient.bottom
sub ecx,_rcClient.right
sub edx,_rcWindow.top
sub ecx,_rcWindow.left
sub eax,edx
sub edi,ecx
sar eax,1
sar edi,1
INVOKE MoveWindow,hWnd,edi,eax,ecx,edx,TRUE
ret
SetClientSizeCntr ENDP
Dave:
tnank you for new version of SetClientSize procedure, I'll try it in my next test
Michael:
thank you for the attached well commented code
In my case "Black and White" test doesn't have any controls , only rectangles which I want to redraw if the user hits the hot key ("r" for example)
Hi Dave,
Quote from: dedndave on September 24, 2013, 01:47:15 AM
here is another version that sets the window size by client size and centers the window on the screen
good idea. :t Can I incorporate it into my code repository?
Gunther
you sure may, Gunther
anything i put in here is pretty much do-as-you-like
i might mention.....
you can create the main window with width and height = 0
then, call SetClientSizeCntr with the desired client dimensions in the WM_CREATE code
windows are not displayed until after WM_CREATE exits
Thank you Dave.
Gunther
Quote from: vertograd on September 23, 2013, 11:57:52 PM
EDIT: Commenting out "DEC EAX" solved the problem but it unlikely to be the ERROR because your comment shows that you intentionally decremented it for some unknown for me reason (sorry, I'm newbie) :
The reason is unknown for me too :lol:
possibly related to the inclusive/exclusive nature of windows rectangles ?
there are times when an INC or DEC are necessary
Quote from: dedndave on September 24, 2013, 07:15:27 PM
possibly related to the inclusive/exclusive nature of windows rectangles ?
there are times when an INC or DEC are necessary
I thought so ...
I made a simple test executing GetClientRect after the window had been moved (256x256, with commented out "DEC EAX") : see the screenshot of locals window
yes - the left and top members of a rectangle are inclusive
the right and bottom members are exclusive
they do that so that (right-left = width) and (bottom-top = height)
another test:
I uncommented those two "DEC EAX" lines of code and rebuild an app, ran it, took screenshot, opened it in mspaint and pasted a sample image 256x256 pixels to it.
Then I used ZoomIt utility from Sysinternals suite
P.S.: I made sure that the left sides of the client area and of the sample image matched
Strange behavior of the app (I think it's somehow related to not-releasing the memory) :
press "r" 17-18 times
what is your opinion?
one problem....
every time you INVOKE DrawRect, you create a new solid brush
brushes are GDI objects - you only get so many - lol
1) in the WM_CREATE code, create 1 solid brush of that color
2) store the handle in a global variable
3) in DrawRect, use that global handle
4) in the WM_DESTROY code, use DeleteObject to delete the GDI object
my mistake.....
you are using a different color each time, so.....
after you do the fill, delete the brush handle
invoke CreateSolidBrush,bruchcol
push eax
invoke FillRect, hDC,ADDR rct,eax ; fill rect with fill colour
pop eax
invoke DeleteObject,eax
that can be simplified a little....
invoke CreateSolidBrush,bruchcol
push eax
invoke FillRect, hDC,ADDR rct,eax ; fill rect with fill colour
call DeleteObject
the parameter for DeleteObject is already on the stack
Quote from: dedndave on September 25, 2013, 08:10:30 AM
push eax
invoke FillRect, hDC,ADDR rct,eax ; fill rect with fill colour
pop eax
invoke DeleteObject,eax
Dave is perfectly right, but since we are in the Campus, let's be explicit...:
pop eax
invoke DeleteObject, eaxSeen by a debugger:
pop eax
push eax
call DeleteObjectSimplified:
pop eax
push eax
call DeleteObject
Thank you , Dave and Jochen! :t
Now it works