News:

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

¿How to use GdipDrawString?

Started by Airam, May 07, 2009, 01:36:13 PM

Previous topic - Next topic

Airam

Hello, I need to put some text into a label which I use to paint. I need to draw a string specifying the position in the sceen using GdipDrawString.

Invoke SelectObject, StaticHDC, GridPen
Invoke GdipCreateFromHDC, ps.hdc, Addr graphics
Invoke GdipCreatePen1, ARGB(80, 10, 10, 10), FP4(1.0), UNITPIXEL, Addr pen
Invoke GdipCreatePen1, ARGB(255, 255, 0, 0), FP4(1.0), UNITPIXEL, Addr pen2

Invoke GdipDrawString, graphics, ?, ?, .....? <- How do I complete these sentence??

Thanks in advance!!

gwapo


GdipDrawString( GpGraphics *graphics, GDIPCONST WCHAR *string, INT length, GDIPCONST GpFont *font, GDIPCONST RectF *layoutRect, GDIPCONST GpStringFormat *stringFormat, GDIPCONST GpBrush *brush )


1. The first param, you've got it right.
2. The second param, pass the address of your string in wide format.
3. Third param, pass the number of characters you want to draw (not zero-based).
4. Fourth param, address of Font object. CreateFont* API will do. NULL to use UI thread's default font (not recommended to pass NULL though).
5. Fifth param, pass the address of a RECTF struct, containing the Y:X coordinate where to draw the string (rectangle's width and height will be ignored, so don't bother passing width and height).
6. Sixth param, the string format, just pass 0 or NULL if you don't have any format.
7. Seventh param, pass the address of your created brush object.

HTH

Airam

I have the following code:


.Const
UNITPIXEL Equ 2
.Data
Point        DD 0, 0, 100, 100
Brush DWord ?
Font DWord ?
.
.
.


Local FontM:DWord

Invoke SelectObject, StaticHDC, GridPen
Invoke GdipCreateFromHDC, ps.hdc, Addr graphics
Invoke GdipCreatePen1, ARGB(80, 10, 10, 10), FP4(1.0), UNITPIXEL, Addr pen
Invoke GdipCreatePen1, ARGB(255, 255, 0, 0), FP4(1.0), UNITPIXEL, Addr pen2

Invoke GdipCreateFontFamilyFromName, TextAddr("Arial"), NULL, Addr FontM
Invoke GdipCreateFont, Addr FontM, 16, NULL, UNITPIXEL, Addr Font
Invoke GdipCreateSolidFill, 0FF0000FFH, Addr Brush

Invoke GdipDrawString, graphics, TextAddr("text"), 4, Font, Addr Point, 0, Brush



But It doesn't show the text "text".

Any ideas??
Thank you!!!

gwapo

Try to convert your string to wide char format, using MultiByteToWideChar function, or use MASM32 macro WSTR to define your string:


.data
   WSTR szHelloWorld,  "Hello World"


Other than that, I don't see any other problem with your code.
Here's a working piece on one of my program:


GraphicsDrawString proto :HANDLE, :dword, :dword, :HANDLE, :REAL4, :REAL4, :dword

GPRECTF struc
    X REAL4 0
    Y REAL4 0
    W REAL4 0
    H REAL4 0
GPRECTF ends

.data
  hFont dd 0
  blackBrush dd 0

.code
   ; Assuming everything in GDI+ is properly initialized:
   Invoke GdipGetGenericFontFamilySerif, addr hFont
   invoke GdipCreateSolidFill, 0ff000000h, addr blackBrush
   invoke GraphicsDrawString, graphics, addr szHelloWorld, 11, hFont, 1, 1, blackBrush
   

GraphicsDrawString proc graphics:HANDLE, szString:dword, len:dword, lpFont:HANDLE, top:REAL4, left:REAL4, lpBrush:dword
local gdiRect:GPRECTF

mov eax, left
mov gdiRect.X, eax
mov eax, top
mov gdiRect.Y, eax

invoke GdipDrawString, graphics, szString, len, lpFont, addr gdiRect, NULL, lpBrush
ret
GraphicsDrawString endp


If you can't make it work, try to zip your program and I'll take a look at it later.
Maybe you're not initializing GDI+ correctly.

Cheers,

-chris

Airam

I have send you the code to your yahoo e-mail. Thank you very much!!

alax

hello, i'm suffering the same problem with you, and the solution by chris is the only one i can find in asm, thanks so much.
but i cant get my code working, even copying the example to my project file.
here is the part with gdi+:
-------------------------------------------------------------------------------------------------------------------------------
.data?
  ...
   _pGdiPlusToken            dd ?
   _hGdiPlusFontFamily      dd ?
   _hGdiPlusFont              dd ?
   _hGdiPlusPen               dd ?
   _hGdiPlusSolidBrush       dd ?
   _hGdiPlusStringFormat   dd ?
   _hGdiPlusGraphics          dd ?

.code
    ....
    LOCAL   @gdiplusstartupinput   :GdiplusStartupInput
    LOCAL   @hdc                        :DWORD
    LOCAL   @rectf                       :RectF
    ...
    invoke   RtlZeroMemory, addr @gdiplusstartupinput, sizeof GdiplusStartupInput
    mov      @gdiplusstartupinput.GdiplusVersion, 1
    invoke   GdiplusStartup, addr _pGdiPlusToken, addr @gdiplusstartupinput, NULL

    invoke   GdipCreateFontFamilyFromName, addr _szWCharGdiPlusFontFamilyName, NULL, addr _hGdiPlusFontFamily   
    invoke   GdipCreateFont, _hFontFamily, 16, FontStyleRegular, UnitPoint, addr _hFont
    invoke   MakeARGB,0FFh,64,64,64
    invoke   GdipCreateSolidFill, eax, addr _hGdiPlusSolidBrush
    invoke   GdipCreatePen2, _hGdiPlusSolidBrush, 1, addr _hGdiPlusPen
    invoke   GdipCreateStringFormat, StringFormatFlagsDirectionRightToLeft, LANG_NEUTRAL, addr _hGdiPlusStringFormat

    invoke   GdipCreateFromHWND, hWnd, addr _hGdiPlusGraphics
    ;or use the code below to create gdi+ graphics object:
    ;    invoke   GetDC,hWnd
    ;    mov      @hdc,eax
    ;    .if eax != NULL
    ;        invoke GdipCreateFromHDC,@hdc,addr _hGdiPlusGraphics
    ;        invoke ReleaseDC,hWnd,@hdc
    ;    .endif

    mov      @rectf.Left, 10
    mov      @rectf.Top, 10
    invoke   GdipDrawString, _hGdiPlusGraphics,\
                                       pWStr,nCount,\     ;pWStr - unicode str converted by MultiByteToWideChar, nCount - original string length
                                       _hGdiPlusFont,\
                                       addr @rectf,\
                                       _hGdiPlusStringFormat,\
                                       _hGdiPlusSolidBrush
    invoke   GdipDrawLineI, _hGdiPlusGraphics, _hGdiPlusPen, 10, 20, 100, 50
    ....
-------------------------------------------------------------------------------------------------------------------------------
i use the vkdebug for the error checking and every gdi+ function seems working correctly, except the GdipDrawString, the error code is 2:
eax = 00000002 (GdiPlusFunc.asm, 207)
eax = GpStatusInvalidParameter
eax = Indicates that one of the arguments passed to the method was not valid
i could not find any mismatch with the params, so it is bothering me all the days :dazzled:.
one more thing is, the definition of RectF in the gdiplus_structs.ins supplied with the masm32v10r package is:
RectF STRUCT
    Left      REAL4 ?
    Top      REAL4 ?
    Right    REAL4 ?
    Bottom REAL4 ?
RectF ENDS
while from the msdn library its data members are:
    X        REAL  X-coordinate of the upper-left corner of the rectangle.
    Y        REAL  Y-coordinate of the upper-left corner of the rectangle.
    Width  REAL  Width of the rectangle.
    Height REAL  Height of the rectangle.
i dont know if there is any relationship between the error and the two diffrent definitions
please help with this problem, thank you for your time so much
ps: chris's blog is a a great help with my asm programming study, thank you again

MichaelW

From GdiPlusTypes.h in the Micorosoft SDK:

//--------------------------------------------------------------------------
// Represents a rectangle in a 2D coordinate system (floating-point coordinates)
//--------------------------------------------------------------------------

class RectF
{
public:

    RectF()
    {
        X = Y = Width = Height = 0.0f;
    }

    RectF(IN REAL x,
          IN REAL y,
          IN REAL width,
          IN REAL height)
    {
        X = x;
        Y = y;
        Width = width;
        Height = height;
    }


And from the reference here:

typedef struct RECTF {
  REAL x AS SINGLE
  REAL y AS SINGLE
  REAL width AS SINGLE
  REAL height AS SINGLE
};


So I'm fairly certain that the last two members are supposed to be the width and height. In any case, you need to use floating point initializers, and there are multiple ways of doing this. Considering that the structure is LOCAL, I would use the MASM32 fld4 macro with the FPU, something like this:

fld4 10.0
fstp @rectf.Left
fld4 10.0
fstp @rectf.Top


And case you are not already aware of this, the page I linked has a link to some examples, including several for GdipDrawString.

eschew obfuscation

alax

Still not working...

i correct my initializing of RectF structure with the fld4 & fstp, but the GdipDrawString is not working neither. the error code is 1 - general error...?

here is the piece of code with problem:
;----------------------------------------------------------------------------------
GDIPLUSRECTF struc
    X REAL4 ?
    Y REAL4 ?
    W REAL4 ?
    H REAL4 ?
GDIPLUSRECTF ends

.data?

   _pGdiPlusToken               dd ?
   _hGdiPlusFontFamily         dd ?
   _hGdiPlusFont                 dd ?
   _hGdiPlusPen                  dd ?
   _hGdiPlusSolidBrush          dd ?
   _hGdiPlusStringFormat      dd ?
   _hGdiPlusGraphics            dd ?

.data
    _szGdiPlusFontFamilyName   db "ARIAL",0
    _szText                                 db "Gdi+ testing bla bla...",0
;...
.code
;...
    local    @gdiplusstartupinput    :GdiplusStartupInput
    local    @pbuffer                    :dword
    local    @rectf                       :GDIPLUSRECTF
;...   
;init gdi+ objs
    invoke   RtlZeroMemory, addr @gdiplusstartupinput, sizeof GdiplusStartupInput
    mov         @gdiplusstartupinput.GdiplusVersion, 1
    invoke   GdiplusStartup, addr _pGdiPlusToken, addr @gdiplusstartupinput, NULL

    invoke   GdipCreateFromHWND,hWnd,addr _hGdiPlusGraphics

    invoke   MultiByteToWideChar,CP_OEMCP,MB_PRECOMPOSED,addr _szGdiPlusFontFamilyName,-1,NULL,0
    push     eax
    inc        eax
    shl        eax,1
    invoke   GlobalAlloc,GPTR,eax
    mov      @pbuffer,eax
    pop       eax
    invoke   MultiByteToWideChar,CP_OEMCP,MB_PRECOMPOSED,addr _szGdiPlusFontFamilyName,-1,@pbuffer,eax
    invoke   GdipCreateFontFamilyFromName,@pbuffer,NULL,addr _hGdiPlusFontFamily
    invoke   GlobalFree,@pbuffer
    mov      @pbuffer,NULL

    invoke   GdipCreateFont,_hGdiPlusFontFamily,16,FontStyleRegular,UnitPoint,addr _hGdiPlusFont
    invoke   GdipCreateStringFormat,StringFormatFlagsDirectionRightToLeft,LANG_NEUTRAL,addr _hGdiPlusStringFormat

    invoke   GdipCreateSolidFill,eax,addr _hGdiPlusSolidBrush
    invoke   GdipCreatePen2,_hGdiPlusSolidBrush,1,UnitPixel,addr _hGdiPlusPen

;...
;prepare the string for unicode format
    invoke MultiByteToWideChar,CP_OEMCP,MB_PRECOMPOSED,addr _szText,-1,NULL,0
    push eax
    inc eax
    shl eax,1
    invoke GlobalAlloc,GPTR,eax
    mov @pbuffer,eax
    pop eax
    invoke MultiByteToWideChar,CP_OEMCP,MB_PRECOMPOSED,addr _szText,-1,@pbuffer,eax

;init the rectf structure
    FLD4 10.0
    FSTP @rectf.X
    FLD4 10.0
    FSTP @rectf.Y
;    FLD4 50.0
;    FSTP @rectf.W
;    FLD4 20.0
;    FSTP @rectf.H

;now call the funtion and here comes the problem
    invoke GdipDrawString,_hGdiPlusGraphics,\
                                   @pbuffer,-1,\
                                   _hGdiPlusFont,\
                                   addr @rectf,\
                                   _hGdiPlusStringFormat\
                                   ,_hGdiPlusSolidBrush

;check the return value using vkdebug
    PrintHex eax
;   eax = 00000001
;   eax = GpStatusGenericError
;   eax = Indicates that there was an error on the method call, which is identified as something other than those defined
;            by the other elements of this enumeration

;now clean up
    invoke GlobalFree,@pbuffer
    mov @pbuffer,NULL
;...
;----------------------------------------------------------------------------------

i attach the zipped project and look for any knid help from this forum, thank you

i am studying the examples from michaelw's link and it is a lot helpful

[attachment deleted by admin]

six_L

alax
try it
gdiRectF STRUCT
xx REAL4 ?
yy REAL4 ?
awidth REAL4 ?
height REAL4 ?
gdiRectF ends

local gdiRect:gdiRectF
local tempVar:dword

...
finit
mov tempVar,320
fild    tempVar
lea eax,gdiRect.xx
fstp real4 ptr [eax]

mov tempVar,50
fild    tempVar
lea eax,gdiRect.yy
fstp real4 ptr [eax]

mov tempVar,420
fild    tempVar
lea eax,gdiRect.awidth
fstp real4 ptr [eax]

mov tempVar,120
fild    tempVar
lea eax,gdiRect.height
fstp real4 ptr [eax]


invoke GdipDrawString,dcGraphics,addr @buf,@nLen,@font,addr gdiRect,0,@Brush
regards