Page 1 of 2

Set Gadget Font via Windows API

Posted: Sat Apr 01, 2017 1:34 pm
by bmcs
Hi Folks,

I am relatively new to PB, although I do have some previous Basic coding experience. Currently using PB5.6

A little Windows program I am writing requires a window with a Windowed Screen. The screen has a image background with text overlaid on top of the image. The text needs to have a transparent background, which can't be done with #PB_Gadget_BackColor, so I am using the Windows API for this. So far, so good, everything is working perfectly. Now I want to change the screen's font, but the normal SetGadgetFont(1, LoadFont(0, "Arial", 12)) doesn't appear to work, probably because it needs to be set via the Windows API. Here is a snippet from my code:

The callback procedure:

Code: Select all

Procedure winCB(hWnd, uMsg, wParam, lParam)
  Result = #PB_ProcessPureBasicEvents
  Select uMsg 
    Case #WM_DRAWITEM
      *lpdis.DRAWITEMSTRUCT = lParam
      Select *lpdis\CtlType
        Case #ODT_STATIC
          hdc=GetDC_(GadgetID(1))
          SetBkMode_(hdc, #TRANSPARENT)
          SetTextColor_(hdc,$FFFFFF)
          TextOut_(hdc, 0, 0, @Text$, Len(Text$))
      EndSelect
  EndSelect
  ProcedureReturn Result
EndProcedure
Main code snippet:

Code: Select all

hWin=OpenWindow(10,0,0,sw+2,sw+1, "",#PB_Window_BorderLess)
SetWindowCallback(@winCB())
OpenWindowedScreen(WindowID(10),0,0,sw,sw,0,0,0)
; Other unrelated code...
ImageGadget(0, 0, 0, sw, sh, 0, 0)
TextGadget(1, (sw/2)-(Len(Text$))/2,  5, Len(Text$), 20, "",#SS_OWNERDRAW)
; Other unrelated code...
SetGadgetText(1,Text$) ; Text$ is global
Any code pointers about how to set the gadget font would be much appreciated.

Thanks & Regards
Dave

Re: Set Gadget Font via Windows API

Posted: Sat Apr 01, 2017 2:09 pm
by infratec
Hi,

you don't need API.

You can draw the text on the picture with DrawText() and DrawingMode(#PB_2DDrawing_Transparent)
You need DrawingFont() to activate your loaded text font.

Bernd

Re: Set Gadget Font via Windows API

Posted: Sat Apr 01, 2017 2:42 pm
by RASHAD
Hi bmcs
Welcome to the world of PureBasic
As Infratec said you can use PureBasic native commands easily
But since this is your fist post
And it seems that you want to center the text (Your code is faulty)
Next is the answer and the rest is yours

Code: Select all

#ODT_STATIC  = 5

Global Text$,r.RECT

r\left=5 
r\top=5 
r\right=390
r\bottom=100

LoadFont(0,"Georgia",24)

Procedure winCB(hWnd, uMsg, wParam, lParam)
 Result = #PB_ProcessPureBasicEvents
  Select uMsg  
   Case #WM_DRAWITEM
    *lpdis.DRAWITEMSTRUCT = lParam
      Select *lpdis\CtlType
       Case #ODT_STATIC
        hdc=GetDC_(GadgetID(0))
        SelectObject_(hdc,FontID(0))
        SetBkMode_(hdc, #TRANSPARENT)
        SetTextColor_(hdc,$FFFFFF)
        DrawText_(hdc, @Text$, Len(Text$),r,#DT_CENTER|#DT_VCENTER	)
      EndSelect
  EndSelect
 ProcedureReturn Result
EndProcedure


Re: Set Gadget Font via Windows API

Posted: Sat Apr 01, 2017 5:33 pm
by bmcs
infratec wrote:Hi,

you don't need API.

You can draw the text on the picture with DrawText() and DrawingMode(#PB_2DDrawing_Transparent)
You need DrawingFont() to activate your loaded text font.

Bernd
Thanks for taking the time to reply, but I spent 3+ hours trying to make this work without any progress and gave up.
Uninstalled PB and rewrote the entire program in C and delivered it to the client in under 30 mins.

Dave

Re: Set Gadget Font via Windows API

Posted: Sat Apr 01, 2017 5:38 pm
by bmcs
RASHAD wrote:Hi bmcs
Welcome to the world of PureBasic
As Infratec said you can use PureBasic native commands easily
But since this is your fist post
And it seems that you want to center the text (Your code is faulty)
Next is the answer and the rest is yours

Code: Select all

#ODT_STATIC  = 5

Global Text$,r.RECT

r\left=5 
r\top=5 
r\right=390
r\bottom=100

LoadFont(0,"Georgia",24)

Procedure winCB(hWnd, uMsg, wParam, lParam)
 Result = #PB_ProcessPureBasicEvents
  Select uMsg  
   Case #WM_DRAWITEM
    *lpdis.DRAWITEMSTRUCT = lParam
      Select *lpdis\CtlType
       Case #ODT_STATIC
        hdc=GetDC_(GadgetID(0))
        SelectObject_(hdc,FontID(0))
        SetBkMode_(hdc, #TRANSPARENT)
        SetTextColor_(hdc,$FFFFFF)
        DrawText_(hdc, @Text$, Len(Text$),r,#DT_CENTER|#DT_VCENTER	)
      EndSelect
  EndSelect
 ProcedureReturn Result
EndProcedure

Thanks, but I doubt that I will be in this world for long.
Yes, the code probably was defective, because I plagiarized it from a very old forum post.
I thank you for your correction, which worked perfectly. However, there were way too many other issues with building this program in PB. In the end I uninstalled PB and rewrote the program in C and delivered it to the client in under 30 mins.
Dave

Re: Set Gadget Font via Windows API

Posted: Sun Apr 02, 2017 9:38 am
by infratec
Hi, hi,

and how long takes it to convert your C program that it works in Linux and OS X too?
and...
and...

But what was the reason to give PB a try?

I changed nearly to 99% to PB and use C and asm only for the µC stuff.

Bernd

Re: Set Gadget Font via Windows API

Posted: Sun Apr 02, 2017 11:48 am
by Manuel
bmcs wrote:Thanks for taking the time to reply, but I spent 3+ hours trying to make this work without any progress and gave up.
Uninstalled PB and rewrote the entire program in C and delivered it to the client in under 30 mins.
The demo version of PureBasic doesn't support API calls, which is why you couldn't get it to work.

Re: Set Gadget Font via Windows API

Posted: Mon Apr 03, 2017 7:44 pm
by bmcs
infratec wrote:Hi, hi,

and how long takes it to convert your C program that it works in Linux and OS X too?
and...
and...

But what was the reason to give PB a try?

I changed nearly to 99% to PB and use C and asm only for the µC stuff.

Bernd
Hi Bernd,

There was no need to covert the C program, because in this instance the client had no requirement for anything other than a Windows program and I had already spent too much time (days) trying to create it in PB. In addition to the information given in my original post, I needed to use the Windows DrawShadowText function, but I could not find any code pointers and everything I tried failed. At the end of the day I just needed to get the job done, instead of spending time working out how to use the tool I had chosen to use.

Why did I want to give PB a try? In the dim distant past I was a big fan of GFA and PB looked to be a viable alternative and for exactly your "works in Linux and OS X, and... and..." reasons. No doubt I will give PB another try, but I will write a lot more "fun" code and pester you folks before I tackle a "real" job.

Regards
Dave

Re: Set Gadget Font via Windows API

Posted: Mon Apr 03, 2017 7:45 pm
by bmcs
Manuel wrote:
bmcs wrote:Thanks for taking the time to reply, but I spent 3+ hours trying to make this work without any progress and gave up.
Uninstalled PB and rewrote the entire program in C and delivered it to the client in under 30 mins.
The demo version of PureBasic doesn't support API calls, which is why you couldn't get it to work.
Hi Manuel,

Claims made on assumptions and guesses are very unsafe ground to walk on.

Please show me where I wrote or even indicated that I was using the demo version.

Had you read the rest of this thread you would have seen my reply to someone who provided a correction to my code, where I said "I thank you for your correction, which worked perfectly."

Please feel free to contact Andre Beer and ask him to check PB purchases made by bank transfer at the end of April 2016. Andre has my full permission to confirm or deny that I hold a valid license for this software.

Regards
Dave

Re: Set Gadget Font via Windows API

Posted: Mon Apr 03, 2017 7:51 pm
by firace
@bmcs

Welcome to PB! You will find that one of the best things about it is the great forums.

This is a little DrawShadowText example which I got from the German forum:

Code: Select all


Prototype DrawShadowText(hDC,pszText,cch,p,flags,crText,crShadow,ixOffset,iyOffset) 

libnr = OpenLibrary(#PB_Any, "ComCtl32.dll") 

Global DrawShadowText_.DrawShadowText = GetFunction(libnr, "DrawShadowText") 


Procedure CreateFont(size)
  
  fontid = GetStockObject_(#ANSI_VAR_FONT)      ;Systemfont holen
  GetObject_(fontid,SizeOf(LOGFONT),lg.LOGFONT) ;Eigenschaften holen
  lg\lfHeight = size                            ;Größe setzen
  
  ProcedureReturn CreateFontIndirect_(lg)     ;Font create
  
EndProcedure


br = 300: hh = 50
imgnr = CreateImage(#PB_Any, br, hh) 

hDC = StartDrawing(ImageOutput(imgnr)) 

farbe = #White
Box(0, 0, br, hh, farbe)

fonthh = 35
fontid = CreateFont(fonthh)
DrawingFont(fontid)
DrawingMode(#PB_2DDrawing_Transparent)

SetTextAlign_(hDC, #TA_LEFT)  ;muß sein

r.rect
r\left=0 
r\top=10 
r\right=br 
r\bottom=hh

txt$ = "dies ist ein Test"
lg = Len(txt$)

flags = #DT_CENTER

shadow_x = 4  ;kann auch negative Werte haben
shadow_y = 3

hoehe = DrawShadowText_(hDC, @txt$, lg, r, flags, #Blue, #Gray, shadow_x, shadow_y) 

StopDrawing() 



OpenWindow(0, 0, 0, 400, 300, "", #PB_Window_SystemMenu|#PB_Window_ScreenCentered) 

ButtonImageGadget(1, 50,50,br,hh,ImageID(imgnr))

Repeat 
Until WaitWindowEvent()=#PB_Event_CloseWindow 



Re: Set Gadget Font via Windows API

Posted: Mon Apr 03, 2017 8:14 pm
by bmcs
firace wrote:@bmcs

Welcome to PB! You will find that one of the best things about it is the great forums.

This is a little DrawShadowText example which I got from the German forum:
Duh! Smashes head on keyboard. :oops: I can't believe that I totally overlooked the ComCtl32.dll

Thanks so much for the example.

Regards
Dave

Re: Set Gadget Font via Windows API

Posted: Tue Apr 04, 2017 9:21 am
by Kwai chang caine
Hello at all :D

Someone know why i have an IMA on line, with W7 X86 Pb 5.60 :cry:

Code: Select all

hoehe = DrawShadowText_(hDC, @txt$, lg, r, flags, #Blue, #Gray, shadow_x, shadow_y) 
I have try in admin mode and it's the same thing :oops:

Re: Set Gadget Font via Windows API

Posted: Tue Apr 04, 2017 4:25 pm
by RASHAD
Simplified & fixed code to accept the font size

Code: Select all

OpenLibrary(0, "ComCtl32.dll")

LoadFont(0,"Georgia",32)

w = 300: h = 100
img = CreateImage(#PB_Any, w,h,24,$FFFFFF)
 
hDC = StartDrawing(ImageOutput(img))
    SelectObject_(hdc, FontID(0))
    DrawingMode(#PB_2DDrawing_Transparent)
             
    r.rect
    r\left=0
    r\top=20
    r\right=300
    r\bottom=100
   
    txt$ = "Text Shadow"
    length = Len(txt$)
    txtBuffer = AllocateMemory(length) : PokeS(txtBuffer, txt$, -1, #PB_Unicode) 
   
    shadow_x = 4  
    shadow_y = 3
   
    CallFunction(0,"DrawShadowText",hDC, txtBuffer, length, r, #DT_CENTER, $0000FF, $B2B2B2, shadow_x, shadow_y)
     
  StopDrawing()
 
OpenWindow(0, 0, 0, 400, 300, "", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
 
  ButtonImageGadget(1, 50,50,w,h,ImageID(img))

Repeat
Until WaitWindowEvent()=#PB_Event_CloseWindow
CloseLibrary(0)

End

Re: Set Gadget Font via Windows API

Posted: Mon Apr 10, 2017 2:02 pm
by Kwai chang caine
Now the IMA are disapear, but no text appears always with W7 X86 Pb 5.60 :|

Code: Select all

Debug CallFunction(0,"DrawShadowText",hDC, txtBuffer, length, r, #DT_CENTER, $0000FF, $B2B2B2, shadow_x, shadow_y)
Return 0, i don't know if it's normal ?
Then

Code: Select all

Debug OpenLibrary(0, "ComCtl32.dll")
Debug LoadFont(0,"Georgia",32)
return a value

Re: Set Gadget Font via Windows API

Posted: Mon Apr 10, 2017 2:56 pm
by skywalk
infratec wrote:I changed nearly to 99% to PB and use C and asm only for the µC stuff.
Truth :wink: