Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Draw and Erase Text

Brooks_Van_Horn
New Contributor I
741 Views

OK,

I've failed miserably but how do you write text to a gui window and later erase that text.   I've been using TextOut with

         ret = SetROP2(hDC, R2_XORPEN)
         iret = SetBkMode(hDC,TRANSPARENT)

but that just doesn't work. My gui window is MM_TEXT. Any suggestions will be greatly appreciated. Everything is being done in IVF 2016 with help from MSVS 2013.

Thanks,

Brooks

0 Kudos
1 Solution
Paul_Curtis
Valued Contributor I
741 Views

Assuming you have created and selected the text font into the screen device context (DC), you can retrieve the avg. character width and height, and then paint a rectangle in solid background color over the previously written text, based on the known string length.  I suspect this brute-force method will prove a bit easier than attempting to overwrite the text a second time with a pixel logic which will reset the foreground pixels to the background color.

SUBROUTINE fontsizes (hdc, width, height)
	IMPLICIT NONE 
	INTEGER(HANDLE),INTENT(IN)     :: hdc
	INTEGER,INTENT(OUT)            :: width, height
	INTEGER				           :: lret
	TYPE(T_TEXTMETRIC)             :: tm
	lret   = GetTextMetrics (hdc, tm)
	width  = tm%tmAveCharWidth
	height = tm%tmHeight
END SUBROUTINE fontsizes 


RECURSIVE SUBROUTINE fill_rectangle (hdc, color, rect, edge)
	IMPLICIT NONE
	INTEGER(HANDLE), INTENT(IN)		:: hdc
	INTEGER, INTENT(IN)             :: color
	TYPE(T_RECT), INTENT(IN)		:: rect
	INTEGER, INTENT(IN), OPTIONAL	:: edge
	INTEGER(HANDLE)					:: hbrush, hold
	INTEGER                         :: rval 

	!	these statements always go together,
	!	and this routine ensures that a brush
	!	resource is always destroyed after use

	hbrush = CreateSolidBrush (color)
	hold   = SelectObject     (hdc, hbrush)
	rval   = FillRect		  (hdc, rect, hbrush)
	rval   = SelectObject     (hdc, hold)
    rval   = DeleteObject     (hbrush)

	IF (PRESENT(edge)) THEN
		IF (edge == 1) rval = DrawEdge (hdc, rect, EDGE_SUNKEN, BF_RECT)
	END IF

END SUBROUTINE fill_rectangle

 

 

View solution in original post

0 Kudos
8 Replies
Paul_Curtis
Valued Contributor I
742 Views

Assuming you have created and selected the text font into the screen device context (DC), you can retrieve the avg. character width and height, and then paint a rectangle in solid background color over the previously written text, based on the known string length.  I suspect this brute-force method will prove a bit easier than attempting to overwrite the text a second time with a pixel logic which will reset the foreground pixels to the background color.

SUBROUTINE fontsizes (hdc, width, height)
	IMPLICIT NONE 
	INTEGER(HANDLE),INTENT(IN)     :: hdc
	INTEGER,INTENT(OUT)            :: width, height
	INTEGER				           :: lret
	TYPE(T_TEXTMETRIC)             :: tm
	lret   = GetTextMetrics (hdc, tm)
	width  = tm%tmAveCharWidth
	height = tm%tmHeight
END SUBROUTINE fontsizes 


RECURSIVE SUBROUTINE fill_rectangle (hdc, color, rect, edge)
	IMPLICIT NONE
	INTEGER(HANDLE), INTENT(IN)		:: hdc
	INTEGER, INTENT(IN)             :: color
	TYPE(T_RECT), INTENT(IN)		:: rect
	INTEGER, INTENT(IN), OPTIONAL	:: edge
	INTEGER(HANDLE)					:: hbrush, hold
	INTEGER                         :: rval 

	!	these statements always go together,
	!	and this routine ensures that a brush
	!	resource is always destroyed after use

	hbrush = CreateSolidBrush (color)
	hold   = SelectObject     (hdc, hbrush)
	rval   = FillRect		  (hdc, rect, hbrush)
	rval   = SelectObject     (hdc, hold)
    rval   = DeleteObject     (hbrush)

	IF (PRESENT(edge)) THEN
		IF (edge == 1) rval = DrawEdge (hdc, rect, EDGE_SUNKEN, BF_RECT)
	END IF

END SUBROUTINE fill_rectangle

 

 

0 Kudos
IanH
Honored Contributor II
741 Views

I agree that redrawing the text using a different raster mode is likely to be problematic, or at best counter-productive.

I'd got further than Paul though, and put all painting code in the one place - whatever ultimately gets called in response to WM_PAINT.  In that handler you can test for the extent of the update rectangle and be selective about what gets drawn as a result (e.g. if the update region doesn't intersect the rectangle occupied by a complicated chart drawing, then don't draw the complicated chart, if it does intersect the little rectangle that might hold the text being discussed here, then draw the relevant contents of that little rectangle).

So the approach to take when you decide that you no longer need the text is to set the appropriate flags in the application state that indicate the text should no longer be drawn, then invalidate the bounding rectangle of the text.  WM_PAINT handling then blanket erases and draws what is required.

(GDI and GDIplus are practically somewhat deprecated API's these days :( .  They still have their place, but most "graphics intensive" applications have moved to using DirectX/Direct2D or OpenGL as their underlying graphics API.  These API's don't offer things such as raster operations on the final display, because it is somewhat incompatible with the hardware acceleration approaches used - raster operations require querying what the GPU has rendered, so later drawing operations that possibly require involvement of the CPU must wait until earlier operations are complete, while ideally the GPU is told "draw this" without there being any further CPU interaction.  Moving away from raster operations today will make your life easier in future if you decide to move to these newer API's.)

0 Kudos
Brooks_Van_Horn
New Contributor I
741 Views

I thank all of you and wish to express my lack of appreciation foor the designers of Windows. I now know how to solve this problem/

Thanks,

Brooks

0 Kudos
Brooks_Van_Horn
New Contributor I
741 Views

Paul,

What do you use to list your code?

Brooks

0 Kudos
Paul_Curtis
Valued Contributor I
741 Views

The (...) code button in the new-comment dialog summons a text box with language-specific formatting, and you simply paste in code directly from the VS editor:

IFF1.jpg

 

 

0 Kudos
Steven_L_Intel1
Employee
741 Views

And when you want to copy code out of that box, move your mouse to the upper-right of the code display window and you'll see a button appear labeled "Copy Source". This opens up a new window with just the source text, no line numbers.

0 Kudos
Brooks_Van_Horn
New Contributor I
741 Views

Thank you very much. Also, Steve, I am a disabled/retired analyst and I am developing a statistical program that I'd like to sell if possible. I am almost there and lack only a few optics to make it nicer. I could really appreciate someone using the code and telling me what I need for a better user interface. I can zip the exe and/or code (all Fortran) if you or someone would please look at it. I need to finish the user's guide first so you'll understand what to do. I also have a pdf document that goes into detail about the actual statistics involved. It currently only runs in x64 mode because potentially it can have a lot of data.

Again, that you very much for the helpful comments.

Brooks

 

0 Kudos
Steven_L_Intel1
Employee
741 Views

Sorry, I can't help you with evaluating your code. Perhaps others can.

0 Kudos
Reply