News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

TextOut

Started by Jackal, August 06, 2006, 04:09:32 AM

Previous topic - Next topic

Jackal

When placing text in memory and then coping it to the interface i cant seem to get the colors corrent. What happens is the font is the right color and the background right behind the text is correct however the background of the entire area is not right. The area without the text show up black. I was wondering if there is a way to fix this? the code i am using is as follows.



      invoke BeginPaint, hWnd, ADDR ps
      invoke CreateCompatibleDC, ps.hdc
      mov memDC, eax
      invoke CreateCompatibleBitmap, ps.hdc, 150, 90
      mov hBmp,  eax
      invoke SelectObject, memDC, hBmp
      RGB 235,235,230
      invoke SetTextColor,memDC,eax
      RGB 57,88,41
      invoke SetBkColor,memDC,eax

      mov rect.top, 20
      mov rect.bottom, 40
      mov rect.left, 0
      mov rect.right, 185
      invoke DrawText, memDC ,ADDR GameName,-1, ADDR rect,  DT_SINGLELINE or DT_CENTER or DT_VCENTER


      invoke BitBlt, ps.hdc, 0, 0, 150, 90, memDC, 0, 0, SRCCOPY
      invoke DeleteObject, hBmp
      invoke DeleteDC, memDC
      invoke EndPaint, hWnd, ADDR ps

RotateRight

#1
[]

Jackal

here is my hbrBackground

    RGB 57,88,41
    Invoke CreateSolidBrush, eax
    mov   wc.hbrBackground, eax



Its only black where the source rectangle is copied to the destination area except for behind the text. Its like it does not fill the rectangle.

Jackal

ok i figured it out but still if there is a better way then pls let me now.. Anyway here is what i did that fixed it.

      mov rect.top, 0
      mov rect.bottom, 250
      mov rect.left, 0
      mov rect.right, 187
      RGB 57,88,41
      Invoke CreateSolidBrush, eax
      Invoke FillRect, memDC, addr rect, eax

RotateRight

#4
[]

raymond

Even easier, BitBlt the area of your main window to the memDC before you put the text and BitBlt back to the main window.

In your case, since you are deleting that memDC immediately after you use it, you shouldn't even bother with it. Simply put the text directly on the main DC. By setting the background to transparent for the text, you could then have clean text on any part of the main window, regardless of its current background.

Raymond
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

Jackal

by doing that my text is unreadable when it updates since the text behind the new text is still showing. Also with writing to memory it seems to reduce or get rid of the flicker. I have run into another problem however. After a period of time i loose all my colors still. They go back to default colors and stay that way. (black on grey)  Does anyone happen to know why this is and how to fix it? I know i have asked this a long time back but no one ever was able to answer it.

TNick

Jackal,

here is what I propose to you:

------> IF you think and you want and you need a back DC


- after you INVOKE CreateWindow(Ex) and before your message loop create the compatible DC like this:

INVOKE GetDC,hWndMain
mov    hDCMain, eax
INVOKE CreateCompatibleDC, hDCMain
mov    hDCBack, eax
INVOKE SaveDC, hDCBack
mov    hSaveDCBack, eax
INVOKE CreateCompatibleBitmap, hDCMain,20,150
mov    hBTMBack,   eax
INVOKE ReleaseDC,hWndMain, hDCMain
INVOKE SelectObject,hDCBack, hBTMBack
INVOKE GetStockObject,NULL_PEN
INVOKE SelectObject,hDCBack,eax
INVOKE CreateSolidBrush,00FF66CCh
mov    hBrsBack,  eax
INVOKE SelectObject, eax
INVOKE Rectangle, hDCBack,0,0,20,150


- in your WinProc, when WM_DESTROY arrives, don't forget to:

INVOKE RestoreDC,hDCBack,hSaveDCBack
INVOKE DeleteDC,hDCBack
INVOKE DeleteObject,hBTMBack
INVOKE DeleteObject, hBrsBack


- in your WinProc, when WM_PAINT arrives, you should:

LOCAL PS:PAINTSTRUCT

INVOKE BeginPaint, hWndMain,addr PS
INVOKE BitBlt,PS.hDC,0,0,20,150,hDCBack,0,0
INVOKE EndPaint,hWndMain,addr PS


now that we know this things, you should also know that DrawText is much better, even if TextOut is a bit faster. I use DrawText, so I will use it in this example:
- this must be done just once, after you had created the DC if you don't plan to change this mode, or before any call to text functions if you do.
INVOKE SetBkMode,hDCBack,TRANSPARENT

- this must be done just once, after you had created the DC if you don't plan to change this color, or before any call to text functions if you do.
INVOKE SetTextColor,hDCBack,0033FF77h

- this must be done just when you want to set/ change the text

mov Rect1.left, 0
mov Rect1.right, 20
mov Rect1.top, 0
mov Rect1.bottom, 150
INVOKE Rectangle, hDCBack, Rect1.left, Rect1.top, Rect1.right, Rect1.bottom
INVOKE DrawText,hDCBack, addr SomeString,-1,addr Drept1,DT_CENTER or DT_SINGLELINE or DT_VCENTER
INVOKE InvalidateRect,hWndMain,addr Rect1,TRUE



----> IF you don't need, ...,  a back DC
-when your WM_PAINT arrives

LOCAL TmpBrs:DWORD
LOCAL PS:PAINTSTRUCT
LOCAL Rect1:RECT

INVOKE BeginPaint, hWndMain,addr PS
INVOKE CreateSolidBrush,00FF66CCh
INVOKE SelectObject, eax
mov    TmpBrs, eax
INVOKE SetTextColor,PS.hDC,0033FF77h
INVOKE SetBkMode,PS.hDC,TRANSPARENT
mov Rect1.left, 0
mov Rect1.right, 20
mov Rect1.top, 0
mov Rect1.bottom, 150
INVOKE Rectangle, PS.hDC, Rect1.left, Rect1.top, Rect1.right, Rect1.bottom
INVOKE DrawText, PS.hDC, addr SomeString,-1,addr Drept1,DT_CENTER or DT_SINGLELINE or DT_VCENTER

INVOKE SelectObject, TmpBrs
INVOKE DeleteObject, eax
INVOKE EndPaint,hWndMain,addr PS



This pices of code are not commented. This is because I don't have enough time. If you have questions or you think there is something wrong with this code, make a new post and tell us.

QuoteI know i have asked this a long time back but no one ever was able to answer it.
We were able, be shure of that. We didn't want to, that's all. :lol


Jackal

there was a few things wrong there but i got it working and i wrote a test application for it which is working perfect so now i get to put it in my app. Thanks for the help and i see what you did different that i have not tried.  :cheekygreen:

TNick

My pleasure! There may be mistakes, I really writed it in a big hurry.  :8)

Jackal

ok now the only question i have left on this topic is how can i make it so my listview is either placed in this dc or how can i make it so that my listview does not flash? I tried to bitblt my window to the dc and back but that did not work and i put the memory dc in my createwindowex for the listview but this also did not solve the problem. Got any ideas?

TNick

If possible, don't use CS_VREDRAW and CS_HREDRAW in the style member of the  WNDCLASS structure, assuming thet your listview flashes when you resize the window. If not, consider using a sizing rectangle for your window (it will flash only once).

Maybe I didn't understand the question well, and this is not the answer?
Nick

Jackal

you see the window flash when the app redraws i belive it is. This is caused by using Invoke InvalidateRect, hWnd, 0, 0 which is needed to force the window to update.

TNick

I thing that if you strip the code and you post it, it would be much easier for us.

asmfan

Hi, all. It was quite interesting to read once again about implementation of double buffering. Some questions appeared. When we make compatible DC & Bitmap we have memDC that have exactly the same attributes that are selected in the original one, right? And we have the memBitmap that's have the dimensions of the original DC and filled with some trash, i.e. completely uninitialized, right?
Why to SaveDC and RestoreDC? It's unneeded i think...
Russia is a weird place