The MASM Forum

General => The Campus => Topic started by: GoneFishing on September 22, 2013, 01:36:21 AM

Title: Using BITMAPS to create borderless window
Post by: GoneFishing on September 22, 2013, 01:36:21 AM
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
Title: Re: Using BITMAPS to create borderless window
Post by: GoneFishing on September 22, 2013, 02:10:53 AM
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

Title: Re: Using BITMAPS to create borderless window
Post by: dedndave on September 22, 2013, 03:04:42 AM
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
Title: Re: Using BITMAPS to create borderless window
Post by: 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 ?
Title: Re: Using BITMAPS to create borderless window
Post by: GoneFishing on September 22, 2013, 03:24:34 AM
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?
Title: Re: Using BITMAPS to create borderless window
Post by: GoneFishing on September 22, 2013, 03:28:52 AM
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

Title: Re: Using BITMAPS to create borderless window
Post by: dedndave on September 22, 2013, 03:33:48 AM
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:
Title: Re: Using BITMAPS to create borderless window
Post by: GoneFishing on September 22, 2013, 03:43:48 AM
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?
Title: Re: Using BITMAPS to create borderless window
Post by: dedndave on September 22, 2013, 03:49:25 AM
right
you pass it the address of a BITMAPINFO structure and the address of a dword that will receive a pointer to the data
Title: Re: Using BITMAPS to create borderless window
Post by: 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
Title: Re: Using BITMAPS to create borderless window
Post by: GoneFishing on September 22, 2013, 04:07:06 AM
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:
Title: Re: Using BITMAPS to create borderless window
Post by: GoneFishing on September 22, 2013, 04:50:10 AM
  FINDSTR /S "BITMAPINFO" *.ASM in  \MASM32\EXAMPLES folder  gave me two excellent results:
+ examples\exampl01\mdidemo\mditest.asm
Now I have all required info

Thank you, Dave and Jochen !
Title: Re: Using BITMAPS to create borderless window
Post by: dedndave on September 22, 2013, 06:13:03 AM
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
Title: Re: Using BITMAPS to create borderless window
Post by: GoneFishing on September 22, 2013, 06:18:39 AM
WOW , Dave
It's wonderful!!!  :t
Those pictures remind me wet sand textures !
Thank you SO MUCH !
Title: Re: Using BITMAPS to create borderless window
Post by: dedndave on September 22, 2013, 06:26:18 AM
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
Title: Re: Using BITMAPS to create borderless window
Post by: GoneFishing on September 22, 2013, 06:36:10 AM
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
Title: Re: Using BITMAPS to create borderless window
Post by: MichaelW on September 22, 2013, 11:36:08 AM
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

Title: Re: Using BITMAPS to create borderless window
Post by: dedndave on September 22, 2013, 11:41:04 AM
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
Title: Re: Using BITMAPS to create borderless window
Post by: 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.

Title: Re: Using BITMAPS to create borderless window
Post by: GoneFishing on September 22, 2013, 06:37:39 PM
 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 ?  ;)
Title: Re: Using BITMAPS to create borderless window
Post by: dedndave on September 22, 2013, 08:36:00 PM
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
Title: Re: Using BITMAPS to create borderless window
Post by: GoneFishing on September 22, 2013, 09:50:09 PM
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
Title: Re: Using BITMAPS to create borderless window
Post by: dedndave on September 22, 2013, 10:31:26 PM
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
Title: Re: Using BITMAPS to create borderless window
Post by: GoneFishing on September 22, 2013, 10:55:12 PM
Well , I made the window 256x256:
invoke MoveWindow, hDlg, 10,10, 272,295,1
Title: Re: Using BITMAPS to create borderless window
Post by: dedndave on September 22, 2013, 11:24:07 PM
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
Title: Re: Using BITMAPS to create borderless window
Post by: GoneFishing on September 22, 2013, 11:58:21 PM
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.
Title: Re: Using BITMAPS to create borderless window
Post by: MichaelW on September 23, 2013, 04:48:46 AM
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.

Title: Re: Using BITMAPS to create borderless window
Post by: GoneFishing on September 23, 2013, 04:57:50 AM
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 ...
Title: Re: Using BITMAPS to create borderless window
Post by: MichaelW on September 23, 2013, 05:13:48 AM
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.
Title: Re: Using BITMAPS to create borderless window
Post by: GoneFishing 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
Title: Re: Using BITMAPS to create borderless window
Post by: MichaelW on September 23, 2013, 05:42:59 AM
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.
Title: Re: Using BITMAPS to create borderless window
Post by: GoneFishing on September 23, 2013, 05:44:49 AM
It's OK , Michael
I'll try to find it myself  (tomorrow maybe )
Title: Re: Using BITMAPS to create borderless window
Post by: dedndave on September 23, 2013, 05:48:44 AM
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
Title: Re: Using BITMAPS to create borderless window
Post by: jj2007 on September 23, 2013, 07:58:42 AM
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.
Title: Re: Using BITMAPS to create borderless window
Post by: dedndave on September 23, 2013, 11:35:10 AM
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
Title: Re: Using BITMAPS to create borderless window
Post by: jj2007 on September 23, 2013, 03:45:27 PM
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...
Title: Re: Using BITMAPS to create borderless window
Post by: GoneFishing on September 23, 2013, 08:50:42 PM
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?
Title: Re: Using BITMAPS to create borderless window
Post by: dedndave on September 23, 2013, 09:30:29 PM
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
Title: Re: Using BITMAPS to create borderless window
Post by: jj2007 on September 23, 2013, 09:32:18 PM
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...
Title: Re: Using BITMAPS to create borderless window
Post by: GoneFishing on September 23, 2013, 09:36:55 PM
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
Title: Re: Using BITMAPS to create borderless window
Post by: MichaelW on September 23, 2013, 11:03:53 PM
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.
Title: Re: Using BITMAPS to create borderless window
Post by: GoneFishing on September 23, 2013, 11:57:52 PM
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!
Title: Re: Using BITMAPS to create borderless window
Post by: 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

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
Title: Re: Using BITMAPS to create borderless window
Post by: GoneFishing on September 24, 2013, 03:18:51 AM
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)
Title: Re: Using BITMAPS to create borderless window
Post by: Gunther on September 24, 2013, 07:41:58 AM
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
Title: Re: Using BITMAPS to create borderless window
Post by: dedndave on September 24, 2013, 07:49:03 AM
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
Title: Re: Using BITMAPS to create borderless window
Post by: Gunther on September 24, 2013, 07:52:38 AM
Thank you Dave.

Gunther
Title: Re: Using BITMAPS to create borderless window
Post by: MichaelW on September 24, 2013, 04:20:23 PM
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:
Title: Re: Using BITMAPS to create borderless window
Post by: 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
Title: Re: Using BITMAPS to create borderless window
Post by: GoneFishing on September 24, 2013, 07:48:08 PM
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

   
Title: Re: Using BITMAPS to create borderless window
Post by: dedndave on September 24, 2013, 08:41:56 PM
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)
Title: Re: Using BITMAPS to create borderless window
Post by: GoneFishing on September 24, 2013, 09:41:42 PM
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
Title: Re: Using BITMAPS to create borderless window
Post by: GoneFishing on September 25, 2013, 06:13:11 AM
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?
Title: Re: Using BITMAPS to create borderless window
Post by: dedndave on September 25, 2013, 08:03:01 AM
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
Title: Re: Using BITMAPS to create borderless window
Post by: dedndave on September 25, 2013, 08:10:30 AM
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
Title: Re: Using BITMAPS to create borderless window
Post by: jj2007 on September 25, 2013, 08:23:22 AM
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, eax

Seen by a debugger:
    pop eax
    push eax
    call DeleteObject

Simplified:
    pop eax
    push eax
    call DeleteObject
Title: Re: Using BITMAPS to create borderless window
Post by: GoneFishing on September 25, 2013, 07:07:49 PM
Thank you , Dave  and Jochen!  :t
Now it works