I recently purchased an Intel 3.06Ghz w/hyperthreading technology.. 256Mb ram, windowsXP home edition, etc..

I installed masmv8.0 from hutch's website (the US link from list of links).

In example2/showbmp the only way I could get the bitmap and icon to show was to take out the xor eax,eax completely from the winproc callback.. If I tried mov eax,0 then the application would run in the background and I had to task-remove it via ctrl-alt-del - processes

In my own example (I'm working on a drawing pad thingy), I get a white client background although I do a FillRect() with a LTGRAY_BRUSH.. I remove the xor eax,eax and I get the same thing.. It runs ok on the 500+ Mhz (intel) machine at work. What am I doing wrong?

<EDIT> Ok.. I figured out why, my video card only supports modes of 16bits or 32 bits.. no 24bit colors darnit which was what I was using for CreateBitmap.... I will try the 32bits at work and see what happens..

What impact will I have when trying to get other things to compile and run on my machine.. It is a GeForce4 MX440 that came with the system.. and what if a user at home has an older video card that supports only up to 24bits???

I'm almost tempted to put that ATI Radeon 9600 on my shelf in here..
Posted on 2003-09-05 16:01:11 by drarem
I hate those cards that don't support 24 bit, whoever thought of that deserves a kick in the head. I had the same problem with Toolbar Paint, on one of my machines it would go all funny. You can also just create a DDB bitmap then use CreateDIBSection when you need a DIB section. This will allow you to edit on machines that don't support 32 bits. My main display bitmap is device dependant (to guarantee compatibility), but all of the drawing is done on a 32 bit DIB backbuffer, makes it easier when I save stuff to have the higher resolution. The really dumb thing is that the upper byte of a 32bit RGBQUAD structure is ignored except when you alpha blend.
Posted on 2003-09-05 16:41:30 by donkey
thnx Donkey, on the work machine I tried setting CreateBitmap to 32 bits on a 24bit desktop and I got same bad results as 24bit createbitmap on the 32bit desktop..

I'll be searching the forums, but is there something similar in code to this to create the DC for the DDB/DIB?

invoke CreateCompatibleDC,NULL
mov backDC,eax
invoke CreateBitmap,1600,1200,1,24,0
mov backBM,eax
invoke SelectObject,backDC,eax

I supposed I try GetDC() then CreateCompatibleBitmap to get around it..
Posted on 2003-09-05 22:14:26 by drarem
CreateCompatibleBitmap will adjust the color depth to match the capacity of the device context. Just do not create it using a memory DC or it will be B&W. In your example it would be:
[b][i]Creates a DDB to match the capacity of the DC[/i][/b]


invoke GetDesktopWindow
push eax
invoke GetDC,eax
mov hDC,eax
invoke CreateCompatibleDC,hDC
mov backDC,eax
invoke CreateCompatibleBitmap,hDC,1600,1200
mov backBM,eax
pop eax
invoke ReleaseDC,eax,hDC
invoke SelectObject,backDC,eax

Since you are creating a DDB anyway (CreateBitmap is a DDB function) it will work exactly as before. You should think about creating a DIB section for your backbuffer as you can write directly to the bitmap bits.
[b][i]Creates a 32bit DIB section the offset of the bitmap bits is in pDisplayBits[/i][/b]


LOCAL bmi :BITMAPINFO
LOCAL pDisplayBits :DWORD

mov imageX,1600
mov imageY,1200

invoke GetDesktopWindow
push eax
invoke GetDC,eax
mov hDC,eax
invoke CreateCompatibleDC,hDC
mov backDC,eax

mov bmi.bmiHeader.biSize,SIZEOF BITMAPINFOHEADER
mov eax,imageX
mov bmi.bmiHeader.biWidth,eax
mov eax,imageY
mov bmi.bmiHeader.biHeight,eax
mov bmi.bmiHeader.biPlanes,1
mov bmi.bmiHeader.biBitCount,32
mov bmi.bmiHeader.biCompression,BI_RGB
mov eax,imageY
mul imageX
mov ecx,4
mul ecx
mov bmi.bmiHeader.biSizeImage,eax
invoke CreateDIBSection,hDC,ADDR bmi,DIB_RGB_COLORS,ADDR pDisplayBits,NULL,NULL
mov backBM,eax
pop eax
invoke ReleaseDC,eax,hDC

invoke SelectObject,backDC,backBM
Posted on 2003-09-05 23:22:07 by donkey
thanks those will help me out immensely :)

I attempted to put your first one into a function as below. I'm trying to populate the backDC and backBM with valid data and use them thruout the proggy.. only problem is, it isn't. I am needing to pass the variables via address I'm thinking..



--globals---
backDC dd ?
backBM dd ?

then....
invoke createdcs,backDC,backBM,1600,1200

createdcs PROC BDC:DWORD, BBM:DWORD, SX:DWORD, SY:DWORD

LOCAL hdc :DWORD
invoke GetDesktopWindow
push eax
invoke GetDC,eax
mov hdc,eax
invoke CreateCompatibleDC,hdc
mov BDC,eax
invoke CreateCompatibleBitmap,hdc,SX,SY
mov BBM,eax
pop eax
invoke ReleaseDC,eax,hdc
invoke SelectObject,BDC,BBM

ret
createdcs endp
Posted on 2003-09-06 00:46:26 by drarem
Glad I could help. You should not create too many device contexts at the same time, in WinNT,2K and Xp there isn't much of a problem but in 9x there is only 64K of memory available to GDI objects and DC's can eat that memory. All applications on your PC must share this memory so if you hog it another application may not be able to create a DC handle. The same thing applies to properly disposing of your GDI objects, they must be destroyed (or released) using the appropriate function when they are no longer needed. The misuse of the limited GDI memory is what is commonly referred to as a GDI leak. Google for MemProof, it is a freeware application that though it does not guarantee no GDI leaks, it catches a few of the common problems. And always select an object out of the DC before releasing or deleting it, failure to do so will cause a huge GDI leak on Win98SE.
Posted on 2003-09-06 01:01:21 by donkey
I could have 3 dcs - an hdc for window, maindc for accesssing bitmap, and a backdc for drawing/flipping..

select the maindc into the appropriate loaded bitmap and use bitblt to copy a section to the backdc which is already pointing to a bitmap which holds the drawings before flipping..

I can set that up into a reusable function for the global values to keep it simple; but still, as an example, how would I pass a global variable as a parameter and have it changed to something else?

;before, backDC=NULL

invoke createdcs,backDC,backBM,1600,1200

;now, backDC should equal some value which is where I want it to..


createdcs PROC BDC:DWORD, BBM:DWORD, SX:DWORD, SY:DWORD
::
mov backDC,eax ; backDC=BDC
::
mov backBM,eax ; backBM=BBM
::
createdcs endp
Posted on 2003-09-06 04:45:34 by drarem
Pass a pointer to the variable if you want to change it:

invoke createdcs,OFFSET backDC,OFFSET backBM,1600,1200

createdcs PROC pBDC:DWORD, pBBM:DWORD, SX:DWORD, SY:DWORD
::
mov ecx,pBDC
mov ,eax ; backDC=BDC
::
mov ecx,pBBM
mov ,eax ; backBM=BBM
::
createdcs endp
Posted on 2003-09-06 05:37:23 by donkey

I hate those cards that don't support 24 bit...

I'm avoid using 24BPP, because it's _very_ slow. If I'll need compatability with old hardware, then I'll use 32BPP and convert this before moving to the screen. Though, this sometimes isn't good with GDI...
Posted on 2003-09-07 20:25:21 by S.T.A.S.


I'm avoid using 24BPP, because it's _very_ slow. If I'll need compatability with old hardware, then I'll use 32BPP and convert this before moving to the screen. Though, this sometimes isn't good with GDI...

Hi S.T.A.S.

Yeah, that's what I do as well. In my example code I showed how to make a 32 bit backbuffer bitmap for drawing regardless of the video cards color depth and a compatible bitmap for display. But the fact remains that if a card supports 32 bit it should also support 24 bit, it makes it faster to copy the standard 24bit DIB sections directly into the DC, since most bitmap files are 24bit (32 is useless bloat as a bitmap file) a 24 bit DC would be nice for displaying bitmaps without having to translate to RGBQUAD first. But I agree that for drawing funcitons it is better to use DWORDS.
Posted on 2003-09-07 20:39:22 by donkey
Hello donkey !
Programmers at nVidia have no time, they are making cheats for 3D Mark instead :grin:
Posted on 2003-09-07 20:58:16 by S.T.A.S.
Hi, Donkey,
you wrote that the 4th byte from the 32-bit bitmap can be used only for alphablending. I also think so, but I wonder if there's a way to make alphablending in hardware with something as simple as GDI or DirectDraw. I will soon need to make a video engine that supports alpha blend, and for now I am thinking of making use of BitRake's alphablend function. I'd really like to have alpha in hardware, though :/
I'm on Win98SE, btw - don't have GDI+
Posted on 2003-09-08 04:20:32 by Ultrano
Hi Ultrano,

I really don't know enough about hardware or alpha-blending to say one way or the other. But I would assume that it would be possible if you had two image buffers on the card. You could blend the two based on the alphablend byte (0-255 = 0-100% transparency). For myself I am not using Alphablending in Toolbar paint because I want to maintain NT4 compatibility.
Posted on 2003-09-08 04:34:51 by donkey
Ultrano, I'm afraid you'll have to go DDraw. As for GDI+, I stay away from it. (Btw, can't you get a GDI+ redistributable for 9x?)
Posted on 2003-09-08 08:44:58 by f0dder
Maybe I need to start a new thread, but here is my test function below, thanx to Donkey :) Is there a link I can research how this works...


invoke createbmp,offset testDC,...

createbmp proc BDC:DWORD,.....
:: ::
mov ecx,BDC
move ,eax

how does moving the offset address of BDC into the ecx register affect eax? Does this happen for every register, or do I have no clue on what I am talking about?




createbmp proc BDC:DWORD,BBP:DWORD,SX:DWORD,SY:DWORD
local hdc:DWORD
invoke GetDesktopWindow
push eax
invoke GetDC,eax
mov hdc,eax
invoke CreateCompatibleDC,hdc
mov ecx,BDC
mov ,eax
invoke CreateCompatibleBitmap,hdc,SX,SY
mov ecx,BBP
mov ,eax
mov BBP,eax
pop eax
invoke ReleaseDC,eax,hdc
invoke SelectObject,backDC,BBP
ret
createbmp endp
Posted on 2003-09-08 11:56:18 by drarem
nevermind, if I would read the code...

the invoke to createcompatibledc populates eax,then

move ecx,BDC ; why is this needed? move value of BDC to ecx, which would contain an offset address?
move ,eax ;moves eax into address of ecx ?

I'm still slightly confused tho..

why are the push and pop's needed.. works without it or is it correct programming style?
Posted on 2003-09-08 12:16:04 by drarem
Is there a link I can research how this works...

Hi drarem,

The GDI is a pretty big section of Windows, there are a few books on the subject but I get my info from MSDN. There isn't a single link as device contexts, bitmaps and colors are three different subjects that all merge in your little sniplet. I would start with the MSDN primer on the GDI and move on from that.

http://www.msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/wingdistart_9ezp.asp
Posted on 2003-09-08 12:19:02 by donkey
mov ,eax isn't needed in your example it is just there incase you use a local address in the next invoke, eax would have given a "register value overwritten by invoke" error.

EDIT: actually this is wrong and will crash your program at some point:

mov ecx,BDC
mov ,eax

just use:

mov BDC,eax

The same applies to the other places you did it.

The push and pop just save the temporary value of the window handle on the stack until it is needed, that way you don't have to create a variable to hold it. It is only used to get the DC and release it, you can easily replace it with a local var if you want to.
Posted on 2003-09-08 12:22:02 by donkey
I hate to be a pain, but one more for the road please..

I updated the function with some comments which helped me.. see comments/questions below..



createbmp proc BDC:DWORD,BBP:DWORD,SX:DWORD,SY:DWORD
local hdc:DWORD
local hwnd:DWORD

invoke GetDesktopWindow ; return HWND into eax
mov hwnd,eax

invoke GetDC,eax ; GetDC of value in eax register eg.. dc=GetDC(hwnd);
mov hdc,eax

invoke CreateCompatibleDC,hdc ; equiv to bkDC=CreateCompatibleDC(dc);
mov ecx,BDC ;what's up with this? if this and next line are commented out, it doesn't
mov ,eax ;work.. if I leave these in it does work.. tried edx reg also which worked
mov BDC,eax ;this is required also..

invoke CreateCompatibleBitmap,hdc,SX,SY
mov BBP,eax ;now this works by itself for some strange reason

invoke ReleaseDC,hwnd,hdc
invoke SelectObject,BDC,BBP ; select BDC into BBP
ret
createbmp endp


PROTO DEFINITION:
createbmp proto :DWORD,:DWORD,:DWORD,:DWORD

INVOKE METHOD:
invoke createbmp, OFFSET backDC, OFFSET backBM, 800,600 (In WM_CREATE message)
Posted on 2003-09-08 13:16:02 by drarem
There is way too much for me to read there.
createbmp proc BDC:DWORD,BBP:DWORD,SX:DWORD,SY:DWORD

LOCAL hDC :DWORD
LOCAL hWin :DWORD

invoke GetDesktopWindow ; return HWND into eax
mov hWin ,eax

invoke GetDC,hWin ; Get a screen DC any one is good
mov hDC,eax

invoke CreateCompatibleDC,hDC ; you seem to want a memory DC
; this memory dc is not necessary to create the bitmap however
mov ecx,BDC ; this moves the address of the pointer passed in BDC to ecx
mov [ecx],eax ; this moves the handle of the memory DC into the address pointed to by BDC

invoke CreateCompatibleBitmap,hDC,SX,SY
mov ecx,BBP ; this moves the address of the pointer passed in BBP to ecx
mov [ecx],eax ; this moves the value of hBmp into the address pointed to by BBP

push eax ; this is used to preserve the bitmap handle so we can return it after the next invoke

invoke ReleaseDC,hWin ,hDC ; you must release the screen DC

pop eax ; pop the bitmap handle and return it
ret
createbmp endp
Posted on 2003-09-08 14:01:54 by donkey