How get private Device context GDI in QB64?
#1
Is it possible to get private GDI device context in QB64?

When working with OpenGL I need to use
HDC hDC = NULL - due to the subsequent call to the C BuildFont command (it is available in gdi32.dll, I have it declared, it works, and then I need to convert its output using the C SelectObject function to the Windows wglUseFontBitmaps function.

Analogously, it goes like this:

after all #include C calls:
HDC hDC = NULL;
.
.
.
CreateFont (-24, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_IT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, FF_DONTCARE And DEFAULT_PITCH, "Courier New")

.
.
SelectObject(hDC, font%&)

.

wglUseFontBitmaps(hDC, 32, 96, base)
.
.
.
_gl statements
.
.


I found all the definitions, constants for all three C functions, but i must stop work, because i am not sure - i dont know how get hDC  device content. Is it possible under H file, or with next libraries, or this is not possible in QB64?


Reply
#2
Search DuckDuckGo with:

"createdc device context"

This is one of the results:

https://learn.microsoft.com/en-us/window...-functions
(Device Context Functions - Win32 apps | Microsoft Learn)

But there is "worry" around that it doesn't work as well anymore on Windows10 and later than it used to.
Reply
#3
Thank you, i try if can continue with it Smile


Reply
#4
There is no "worry" at all , all GDI functions and HDC buffers you can create on Windows10
>>>TESTED<<<

but i tested with o2 not with qb64 ..but if other GDI work then why should not work with it.
Reply
#5
I found myself in a strange situation. Everything is declared. The constants are correct. The problem mentioned - the first three functions declared all returning non-null values, so I assume that's correct. The last wglUseFontBitmapsA function called from the OpenGL32.dll library sometimes returns zero (failure), sometimes returns 1 (everything OK), but the screen is still black. I do not know what do with it. I have done everything I can think of and the result is a black screen. Um. Well, that's OpenGL.

I tried using GetDC and also GetWindowDC to get the DC, it works. Then is declared CreateFont, it returns a handle to the font. Next is declared a SelectObject, it also returns a handle. And that last wglUseFontBitmapsA function from OpenGL killed it all  Big Grin really it is.....  Angry  


Thank for reply  Wink


Reply
#6
Does OpenGL have a screen update call like _Display? or a Graphics draw routine its expecting to update screen within a loop?
b = b + ...
Reply
#7
@BPlus
It has, but it depends on the matrix settings, otherwise it is initialized for 2D and differently for 3D, the rendering will take place after _glEnd or after _glFlush (maybe there are other commands, but I am not that far yet), the problem described above seems that the command does not create displaylists.


Reply
#8
Petr

I don't get it why you use HDC or DC which is GDI and then you use openGL
i think that you must use openGL wrapper functions to set font and other things
not font created with HDC

this subroutine i use in o2 to select font i want but it is pure GDI
:
Code: (Select All)
Sub WindowFont(int height, width, flag, string fontname) 
int hFont
'hDC=GetDC(win)
ReleaseDC( win, hdcMem)
'SelectObject hdcMem, hFont
hFont = CreateFont height,width,0,0,flag,0,0,0,0,0,0,0,0,fontname
SelectObject hdcMem, hFont
'without SetBkMode BCOLOR r,g,b,.. work ?
SetBkMode hdcMem,1

'BitBlt(hDC, 0, 0, ww, wh, hdcMem, 0, 0, SRCCOPY)
DeleteObject hFont
'ReleaseDC( win, hdcMem)
End Sub
Reply
#9
Thank you all for your efforts, I am attaching the still broken source code, there must be some little thing missing somewhere that I still miss. I've been trying to get it running for 5 days...

This is QB64 source (based on C source) 

Code: (Select All)
Declare Dynamic Library "gdi32"
    Function CreateFont& Alias CreateFontA (ByVal cHeight As Long, Byval cWidth As Long, Byval cEscapement As Long, Byval cOrientation As Long, Byval cWeight As Long, Byval bItalic As _Unsigned Long, Byval bUnderline As _Unsigned Long, Byval bStrikeOut As _Unsigned Long, Byval iCharSet As _Unsigned Long, Byval iOutPrecision As _Unsigned Long, Byval iClipPrecision As _Unsigned Long, Byval iQuality As _Unsigned Long, Byval iPitchAndFamily As _Unsigned Long, pszFaceName As String)
    Function SelectObject& (ByVal HDC&&, Byval HGDI&&) 'select object nefunguje
End Declare

Declare Dynamic Library "User32"
    Function GetDC& (ByVal Hwnd As _Integer64)
End Declare

Declare Dynamic Library "Opengl32"
    Function wglUseFontBitmapsW& (ByVal HDC As _Unsigned Long, unnp1 As _Unsigned Long, unnp2 As _Unsigned Long, unnp3 As _Unsigned Long)
End Declare

Dim Shared GL_InitInfo As _Byte '  is need for OpenGL init
Dim Shared ExitSignal As _Byte '   is need for correct OpenGL exit when program end
Dim Shared Baze As Long

'constants for CreateFont
Const FW_DONTCARE = 0
Const FW_THIN = 100
Const FW_EXTRALIGHT = 200
Const FW_ULTRALIGHT = 200
Const FW_LIGHT = 300
Const FW_NORMAL = 400
Const FW_REGULAR = 400
Const FW_MEDIUM = 500
Const FW_SEMIBOLD = 600
Const FW_DEMIBOLD = 600
Const FW_BOLD = 700
Const FW_EXTRABOLD = 800
Const FW_ULTRABOLD = 800
Const FW_HEAVY = 900
Const FW_BLACK = 90
Const TRUE = 1 'tu -1 a v glprintu nebylo baze - 32 ale jen 32
Const FALSE = Not TRUE
Const FW_DONTCARE = 0
Const FW_THIN = 100
Const FW_EXTRALIGHT = 200
Const FW_ULTRALIGHT = 200
Const FW_LIGHT = 300
Const FW_NORMAL = 400
Const FW_REGULAR = 400
Const FW_MEDIUM = 500
Const FW_SEMIBOLD = 600
Const FW_DEMIBOLD = 600
Const FW_BOLD = 700
Const FW_EXTRABOLD = 800
Const FW_ULTRABOLD = 800
Const FW_HEAVY = 900
Const ANSI_CHARSET = 0
Const ARABIC_CHARSET = 178
Const BALTIC_CHARSET = 186
Const CHINESEBIG5_CHARSET = 136
Const DEFAULT_CHARSET = 1
Const EASTEUROPE_CHARSET = 238
Const GB2312_CHARSET = 134
Const GREEK_CHARSET = 161
Const HANGEUL_CHARSET = 129
Const HEBREW_CHARSET = 177 'http://www.jasinskionline.com/windowsapi/ref/c/createfont.html
Const JOHAB_CHARSET = 130
Const MAC_CHARSET = 77
Const OEM_CHARSET = 255
Const RUSSIAN_CHARSET = 204
Const SHIFTJIS_CHARSET = 128
Const SYMBOL_CHARSET = 2
Const THAI_CHARSET = 222
Const TURKISH_CHARSET = 162
Const OUT_DEFAULT_PRECIS = 0
Const OUT_DEVICE_PRECIS = 5
Const OUT_OUTLINE_PRECIS = 8
Const OUT_RASTER_PRECIS = 6
Const OUT_STRING_PRECIS = 1
Const OUT_STROKE_PRECIS = 3
Const OUT_TT_ONLY_PRECIS = 7
Const OUT_TT_PRECIS = 4
Const CLIP_DEFAULT_PRECIS = 0
Const CLIP_EMBEDDED = 128
Const CLIP_LH_ANGLES = 16
Const CLIP_STROKE_PRECIS = 2
Const ANTIALIASED_QUALITY = 4
Const DEFAULT_QUALITY = 0
Const DRAFT_QUALITY = 1
Const NONANTIALIASED_QUALITY = 3
Const PROOF_QUALITY = 2
Const DEFAULT_PITCH = 0
Const FIXED_PITCH = 1
Const VARIABLE_PITCH = 2
Const FF_DECORATIVE = 80
Const FF_DONTCARE = 0
Const FF_ROMAN = 16
Const FF_SCRIPT = 64
Const FF_SWISS = 32

Dim Shared hDC As _Integer64
'source: https://learn.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-createfonta

Screen _NewImage(1024, 768, 32) 'this all before = 5 rows in C

Do
    If ExitSignal Then System
    _Limit 20
Loop

Sub _GL
    If GL_InitInfo = 0 Then
        _glShadeModel _GL_SMOOTH
        _glClearColor 0.0F, 0.0F, 0.0F, 0.5F
        _glClearDepth 1.0F
        _glEnable _GL_DEPTH_TEST
        _glDepthFunc _GL_LEQUAL
        _glHint _GL_PERSPECTIVE_CORRECTION_HINT, _GL_NICEST
        BuildFont
        GL_InitInfo = 1
        Exit Sub
    End If

    _glShadeModel _GL_SMOOTH
    _glClearColor 0.0F, 0.0F, 0.0F, 0.5F
    _glClearDepth 1.0F
    _glEnable _GL_DEPTH_TEST
    _glDepthFunc _GL_LEQUAL
    _glHint _GL_PERSPECTIVE_CORRECTION_HINT, _GL_NICEST


    _glClear _GL_COLOR_BUFFER_BIT And _GL_DEPTH_BUFFER_BIT
    _glLoadIdentity
    _glTranslatef 0.0F, 0.0F, -1.0F
    _glColor3f 1.0 * Cos(cnt1), 1.0 * Sin(cnt2), 1.0 - 0.5 * Cos(cnt1 + cnt2)
    _glRasterPos2f -0.45 + 0.05 * Cos(cnt1), 0.32F * Sin(cnt2)


    _glCallList 1
    '    glPrint "Test text"
    cnt1 = cnt1 + 0.051
    cnt2 = cnt2 + 0.005
    _glEnd

    If _Exit Then
        KillFont
        ExitSignal = 1
        Exit Sub
    End If
End Sub

Sub BuildFont
    'HFONT = font 'in C - how write this in QB64?

    Baze = _glGenLists(96)
    Font& = CreateFont(-24, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, FF_DONTCARE And DEFAULT_PITCH, "Courier New")
    hDC& = GetDC(_WindowHandle)
    SO& = SelectObject(hDC&, Font&)
    status = wglUseFontBitmapsW(hDC&, 32, 96, Baze) 'bool

    Print "Display list BAZE handle:"; Baze
    Print "Font handle: "; Font&
    Print "hDC handle: "; hDC&
    Print "Select Object handle: "; SO&
    Print "wglUseFontBitmapsW handle: "; status
End Sub

Sub KillFont
    _glDeleteLists 96, Baze
End Sub

Sub glPrint (text As String)
    If text = "" Then Exit Sub


    _glPushAttrib _GL_LIST_BIT
    _glListBase (Baze - 32)

    _glCallLists Len(text$), _GL_UNSIGNED_BYTE, _Offset(text$)
    _glPopAttrib
End Sub


and this is original C source:

Code: (Select All)
#include <windows.h>
#include <math.h>
#include <stdio.h>
#include <stdarg.h>
#include <gl\gl.h>
#include <gl\glu.h>
#include <gl\glaux.h>
HDC hDC = NULL;
HGLRC hRC = NULL;
HWND hWnd = NULL;
HINSTANCE hInstance
bool keys[256];
bool active = TRUE;
bool fullscreen = TRUE;

GLuint base; //because BASE is statement in QB64, i use BAZE word in QB64 version
GLfloat cnt1;
GLfloat cnt2;

GLvoid BuildFont(GLvoid)

{

HFONT font; // must this be defined in QB64? How?
base = glGenLists (96)
font = CreateFont (-24, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, FF_DONTCARE | DEFAULT_PITCH, "Courier New")
SelectObject (hDC, font)
wglUseFontBitmaps(hDC, 32, 96, base)

}

GLvoid KillFont(GLvoid)

{

glDeleteLists(base, 96);

}

GLvoid glPrint (const char *fmt, ...)

{

char text[256]
va_list ap;
if (fmt == NULL)
return;

va_start(ap, fmt);
vsprintf(text, fmt, ap);
va_end(ap);

glPushAttrib (GL_LIST_BIT);
glListBase(base - 32);
glCallLists(strlen(text), GL_UNSIGNED_BYTE, text);
glPopAttrib();

}

int InitGL(GLvoid)

{

glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
BuildFont();

return TRUE;

}

int DrawGLScene(GLvoid)

{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0f,0.0f,-1.0f);
glColor3f(1.0f*float(cos(cnt1)),1.0f*float(sin(cnt2)),1.0f-0.5f*float(cos(cnt1+cnt2)));
glRasterPos2f(-0.45f+0.05f*float(cos(cnt1)), 0.32f*float(sin(cnt2)));
glPrint("Test text", cnt1);
cnt1+=0.051f;

cnt2+=0.005f;

return TRUE;

}

if(!UnregisterClass("OpenGL",hInstance))

{

MessageBox(NULL,"Could Not Unregister Class.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);

hInstance=NULL;

}

KillFont();

}


If someone managed to get it up and running, I'd like to learn what's missing and why it doesn't work.


Reply
#10
Might have to check around "libqb.cpp" or (shiver):

.../qb64pe/internal/c/parts/video/font/ttf/src/freetypeamalgam.c

which is over 6MB long.

Match the exact uppercase-lowercase for search for "Font" (without double-quotation marks) in "libqb.cpp".

Trying to help. (shrugs)

Indeed it is shrouded in mystery (or rather too many "LOC's") because it has to work for Linux and MacOS as well as Windows.
Reply




Users browsing this thread: 4 Guest(s)