Why I cannot check OpenGL version in this fake OpenGL context? - c++

I'm trying to check OpenGL version creating a fake OpenGL context, but always I'm getting version 0. I create a fake context with this code:
PIXELFORMATDESCRIPTOR pfd;
ZeroMemory( &pfd, sizeof( pfd ) );
pfd.nSize = sizeof( pfd );
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL |
PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 16;
pfd.iLayerType = PFD_MAIN_PLANE;
WINDOWINFO info;
HWND mHWND;
info.cbSize = sizeof(WINDOWINFO);
GetWindowInfo(mHWND,&info);
HDC mDC;
mDC = GetDC(mHWND);
int fmt = ChoosePixelFormat( mDC, &pfd );
SetPixelFormat( mDC, fmt, &pfd );
HGLRC mOGLCtx;
mOGLCtx = wglCreateContext( mDC );
wglMakeCurrent(mDC, mOGLCtx);
And try to check version with this:
glGetString(GL_VERSION)

Try to get (GetActiveWindow, GetForegroundWindow) or create (CreateWindowEx) window handle before getting its DC or try to GetDC(0).

Can create minimal OpenGL context with that:
HWND wnd = CreateWindow(
"STATIC",
"GL",
WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
0, 0, 16, 16,
NULL, NULL,
NULL, NULL );
HDC dc = GetDC( wnd );
PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR), 1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL,
PFD_TYPE_RGBA, 32,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,
16, 0,
0, PFD_MAIN_PLANE, 0, 0, 0, 0
};
int fmt = ChoosePixelFormat( dc, &pfd );
SetPixelFormat( dc, fmt, &pfd );
HGLRC rc = wglCreateContext( dc );
wglMakeCurrent( dc, rc );
Check OpenGL version with the same manner:
glGetString(GL_VERSION)
To be more efficient, after all:
// Clean GL context
wglDeleteContext( rc );
ReleaseDC( wnd, dc );
DestroyWindow( wnd );

Related

How to create custom slider control in win32 in C++?

I am learning WIN32 API in C/C++ and want to know how to create custom slider/trackbar control with custom shaped thumb that is a child of a dialog. An example would be of benefit on how to do it as there is very low information about WIN32 programming on the internet, especially for customizing your own child controls.
Please do not post MFC examples.
Here is the code example I am trying to complete:
#pragma comment(linker,"\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#include <string>
#include <Windows.h>
#include <CommCtrl.h>
using namespace std;
HWND window = nullptr;
HWND trackBar = nullptr;
HWND progressBar = nullptr;
HWND staticText = nullptr;
WNDPROC defWndProc = nullptr;
static HBITMAP hBitmapThumb, hBitmapBar;
static BITMAP bm;
LRESULT OnWindowClose(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
PostQuitMessage(0);
return CallWindowProc(defWndProc, hwnd, message, wParam, lParam);
}
LRESULT OnTrackBarChanged(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
LRESULT value = SendMessage(trackBar, TBM_GETPOS, 0, 0);
SendMessage(progressBar, PBM_SETPOS, value, 0);
SendMessage(staticText, WM_SETTEXT, 0, reinterpret_cast<LPARAM>(to_wstring(value).c_str()));
return CallWindowProc(defWndProc, hwnd, message, wParam, lParam);
}
void DrawBitmapTransparent(HDC hDCDest, int nXDest, int nYDest, int nBitmapWidth, int nBitmapHeight, HBITMAP hBitmap, int nXSrc, int nYSrc, int nTransparentColor)
{
HDC hDCSrc;
HBITMAP hBitmapOld;
HDC hDCMask;
HBITMAP hBitmapMask;
HBITMAP hBitmapMaskOld;
HDC hDCMem;
HBITMAP hBitmapMem;
HBITMAP hBitmapMemOld;
int nBkColorOld;
int nTextColorOld;
BITMAP bm;
GetObject( hBitmap, sizeof( BITMAP ), &bm );
if (!nBitmapWidth) {
nBitmapWidth = bm.bmWidth;
}
if (!nBitmapHeight) {
nBitmapHeight = bm.bmHeight;
}
hDCSrc = CreateCompatibleDC( hDCDest );
hBitmapOld = reinterpret_cast<HBITMAP>(SelectObject( hDCSrc, hBitmap ));
hDCMask = CreateCompatibleDC( hDCDest );
hBitmapMask = CreateBitmap( nBitmapWidth, nBitmapHeight, 1, 1, 0 );
hBitmapMaskOld = reinterpret_cast<HBITMAP>(SelectObject( hDCMask, hBitmapMask ));
hDCMem = CreateCompatibleDC( hDCDest );
hBitmapMem = CreateCompatibleBitmap( hDCDest, nBitmapWidth, nBitmapHeight );
hBitmapMemOld = reinterpret_cast<HBITMAP>(SelectObject( hDCMem, hBitmapMem ));
nBkColorOld = SetBkColor( hDCSrc, nTransparentColor );
BitBlt( hDCMask, 0, 0, nBitmapWidth, nBitmapHeight, hDCSrc, nXSrc, nYSrc, SRCCOPY );
SetBkColor( hDCSrc, nBkColorOld );
nBkColorOld = SetBkColor( hDCDest, RGB(255,255,255) );
nTextColorOld = SetTextColor( hDCDest, RGB(0,0,0) );
BitBlt( hDCMem, 0, 0, nBitmapWidth, nBitmapHeight, hDCDest, nXDest, nYDest, SRCCOPY );
BitBlt( hDCMem, 0, 0, nBitmapWidth, nBitmapHeight, hDCSrc, nXSrc, nYSrc, SRCINVERT );
BitBlt( hDCMem, 0, 0, nBitmapWidth, nBitmapHeight, hDCMask, 0, 0, SRCAND );
BitBlt( hDCMem, 0, 0, nBitmapWidth, nBitmapHeight, hDCSrc, nXSrc, nYSrc, SRCINVERT );
BitBlt( hDCDest, nXDest, nYDest, nBitmapWidth, nBitmapHeight, hDCMem, 0, 0, SRCCOPY );
SetBkColor( hDCDest, nBkColorOld );
SetTextColor( hDCDest, nTextColorOld );
SelectObject( hDCMem, hBitmapMemOld );
DeleteDC( hDCMem );
DeleteObject( hBitmapMem );
SelectObject( hDCMask, hBitmapMaskOld );
DeleteDC( hDCMask );
DeleteObject( hBitmapMask );
SelectObject( hDCSrc, hBitmapOld );
DeleteDC( hDCSrc );
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch(message) {
case WM_NOTIFY :
{
LPNMHDR lpNmhdr = reinterpret_cast<LPNMHDR>(lParam);
if (lpNmhdr->code == NM_CUSTOMDRAW)
{
LPNMCUSTOMDRAW lpNMCustomDraw = reinterpret_cast<LPNMCUSTOMDRAW>(lParam);
if (lpNMCustomDraw->dwDrawStage == CDDS_PREPAINT) {
return CDRF_NOTIFYITEMDRAW;
}
else if (lpNMCustomDraw->dwDrawStage == CDDS_ITEMPREPAINT)
{
long nLeft = lpNMCustomDraw->rc.left;
long nTop = lpNMCustomDraw->rc.top;
long nRight = lpNMCustomDraw->rc.right;
long nBottom = lpNMCustomDraw->rc.bottom;
if (lpNMCustomDraw->dwItemSpec == TBCD_THUMB && hBitmapThumb)
{
long nWidth = nRight - nLeft;
long nHeight = nBottom - nTop;
if (nWidth - bm.bmWidth > 0)
{
nLeft += (nWidth - bm.bmWidth)/2;
nWidth = bm.bmWidth;
}
if (nHeight - bm.bmHeight > 0)
{
nTop += (nHeight - bm.bmHeight) / 2;
nHeight = bm.bmHeight;
}
DrawBitmapTransparent(lpNMCustomDraw->hdc , nLeft, nTop, nWidth, nHeight, hBitmapThumb, 0, 0, RGB( 255, 0, 255 ));
return CDRF_SKIPDEFAULT ;
}
}
}
}
break;
}
if (message == WM_CLOSE && hwnd == window) return OnWindowClose(hwnd, message, wParam, lParam);
if (message == WM_HSCROLL && hwnd == window && reinterpret_cast<HWND>(lParam) == trackBar) return OnTrackBarChanged(hwnd, message, wParam, lParam);
return CallWindowProc(defWndProc, hwnd, message, wParam, lParam);
}
int main() {
window = CreateWindowEx(0, WC_DIALOG, L"TrackBar example", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, nullptr, nullptr, nullptr, nullptr);
trackBar = CreateWindowEx(0, TRACKBAR_CLASS, nullptr, WS_CHILD | TBS_HORZ | TBS_BOTTOM | WS_VISIBLE | TBS_FIXEDLENGTH, 150, 10, 250, 70, window, nullptr, nullptr, nullptr);
progressBar = CreateWindowEx(0, PROGRESS_CLASS, nullptr, WS_CHILD | PBS_SMOOTH | WS_VISIBLE, 20, 100, 200, 23, window, nullptr, nullptr, nullptr);
staticText = CreateWindowEx(0, WC_STATIC, L"100", WS_CHILD | WS_VISIBLE, 20, 150, 100, 23, window, nullptr, nullptr, nullptr);
defWndProc = reinterpret_cast<WNDPROC>(SetWindowLongPtr(window, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(WndProc)));
hBitmapThumb = reinterpret_cast<HBITMAP>(LoadImage(NULL, reinterpret_cast<LPCWSTR>("pink.bmp"), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE));
GetObject( hBitmapThumb, sizeof( BITMAP ), &bm );
SendMessage(trackBar, TBM_SETRANGEMIN, 1, 0);
SendMessage(trackBar, TBM_SETRANGEMAX, 1, 200);
SendMessage(trackBar, TBM_SETTHUMBLENGTH, bm.bmWidth*2, 0);
SendMessage(progressBar, PBM_SETRANGE32, 0, 200);
SendMessage(progressBar, PBM_SETPOS, 100, 0);
ShowWindow(window, SW_SHOW);
MSG message = { 0 };
while (GetMessage(&message, nullptr, 0, 0))
DispatchMessage(&message);
}
In the example I am trying to replace the trackbar thumb with a bitmap image but obviously nothing is happening, it compiles but the trackbar is very small and not replaced by the image. Please I need advice on how to solve this problem.
I copy/pasted your code and ran it and saw the missing thumb too. Started tracing it and found that hbitmapThumb was null.... of course, because I didn't have pink.bmp! I changed that to load it from an absolute path... and noticed you missed the L on the thing:
hBitmapThumb = reinterpret_cast<HBITMAP>(LoadImage(NULL, reinterpret_cast<LPCWSTR>(L"c:\\users\\me\\Documents\\pink.bmp"), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE));
You might not need the absolute path, depends on where you have the files on your computer.
But you absolutely do need that L before the quote - otherwise you are reinterpret casting a narrow string as a wide string, which will be an invalid filename!
So yeah, I think you did the harder part of getting the custom draw etc right, but just made a char vs w_char mistake there. Let me know if fixing that L fixes the issue for you too.

Create Modern OpenGL context using WGL?

I'm trying to create an OpenGL context (Modern Version) using Windows functions.
Basically the code is just:
Create window class
Register the class
create a Window
choose PIXELFORMATDESCRIPTOR & set it
Create a legacy OpenGL context
Make context current
glewInit()
Create new window
Create a modern pixel format attrib array
Set the format
Create modern OpenGL context
Make context current
After this I try to draw a square (using a VAO & VBO).
The result is: the Windows window works, the glClear(GL_COLOR_BUFFER_BIT) works, but the square is not drawn (display() function).
If I use an OpenGL 2.0 context, it draws the square (using a VAO & VBO as before), so the problem must be on the init of OpenGL 3.2.
Where am I going wrong?
Here is the code:
#include <iostream>
#include <GL/glew.h>
#include <GL/wglew.h>
#include <windows.h>
#include <string>
using namespace std;
bool progRun = false;
void display(){
glUseProgram(shaderProg);
glBindVertexArray(vao[0]);
glDrawArrays(GL_QUADS, 0,4);
}
string errorStr = "none";
PIXELFORMATDESCRIPTOR pfd;
HGLRC hrc; // vars to init glew
HDC hdc;
HWND hwnd;
HGLRC hrc1; //vars for the real window
HDC hdc1;
HWND hwnd1;
LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM ); // window event hadler prototype
//-------------------- INIT OPENGL
int initOpengl(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
)
{
//---- fake Window
WNDCLASSEX wcex;
wcex.cbSize = sizeof( WNDCLASSEX );
wcex.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon( NULL, IDI_APPLICATION );
wcex.hCursor = LoadCursor( NULL, IDC_ARROW );
wcex.hbrBackground = (HBRUSH)( COLOR_WINDOW + 1 );
wcex.lpszMenuName = NULL;
wcex.lpszClassName = "coco";
wcex.hIconSm = NULL;
if( !RegisterClassEx( &wcex ) )
{
errorStr = "RegisterClassEx";
return 0;
}
hwnd = CreateWindow(
"coco",
"dddd",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
500, 500,
NULL,
NULL,
hInstance,
NULL
);
hdc = GetDC( hwnd );
memset( &pfd, 0, sizeof( PIXELFORMATDESCRIPTOR ) );
pfd.nSize = sizeof( PIXELFORMATDESCRIPTOR );
pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 32;
pfd.cDepthBits = 32;
pfd.iLayerType = PFD_MAIN_PLANE;
int nPixelFormat = ChoosePixelFormat( hdc, &pfd );
SetPixelFormat( hdc, nPixelFormat, &pfd );
hrc = wglCreateContext( hdc );
wglMakeCurrent( hdc, hrc );
glewExperimental = true;
glewInit();
//---------------For the real window
if( wglewIsSupported( "WGL_ARB_create_context" ) == 1 )
{
wglMakeCurrent( NULL, NULL );
wglDeleteContext( hrc );
ReleaseDC( hwnd, hdc );
DestroyWindow( hwnd );
hwnd1 = CreateWindow(
"coco",
"ddddd",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
500, 500,
NULL,
NULL,
hInstance,
NULL
);
hdc1 = GetDC( hwnd1 );
const int iPixelFormatAttribList[] = {
WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
WGL_COLOR_BITS_ARB, 32,
WGL_DEPTH_BITS_ARB, 24,
WGL_STENCIL_BITS_ARB, 8,
0 // End of attributes list
};
int attributes[] = {
WGL_CONTEXT_MAJOR_VERSION_ARB, 3
, WGL_CONTEXT_MINOR_VERSION_ARB, 2
, WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB
, 0
};
int nPixelFormat = 0;
UINT iNumFormats = 0;
wglChoosePixelFormatARB( hdc1, iPixelFormatAttribList, NULL, 1, &nPixelFormat, (UINT*)&iNumFormats );
SetPixelFormat( hdc1, nPixelFormat, &pfd );
hrc1 = wglCreateContextAttribsARB( hdc1, 0, attributes );
wglMakeCurrent( NULL, NULL );
wglMakeCurrent( hdc1, hrc1 );
}
else
{
errorStr = "WGL_ARB_create_context";
return 0;
}
return true;
}
// MAIN -----
int CALLBACK WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
)
{
initOpengl( hInstance, hPrevInstance, lpCmdLine, nCmdShow );
ShowWindow( hwnd1, SW_SHOW );
glClearColor( 1, 0, 0, 1 );
MSG msg;
progRun = true;
while( progRun )
{
if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
glClear( GL_COLOR_BUFFER_BIT );
glViewport( 0, 0, 500, 500 );
display();
SwapBuffers( hdc1 );
}
return 0;
}
LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
return DefWindowProc( hWnd, message, wParam, lParam );
}
The problem is not in the context creation code alone, but in the combination of the used OpenGL version and the drawing code.
When requesting an OpenGL context as it is done in the question, there are several attributes that can be set. The relevant one here is the WGL_CONTEXT_PROFILE_MASK_ARB (which is not set). The extension description states:
The default value for WGL_CONTEXT_PROFILE_MASK_ARB is WGL_CONTEXT_CORE_PROFILE_BIT_ARB. [...] If the requested OpenGL version is less than 3.2,
WGL_CONTEXT_PROFILE_MASK_ARB is ignored and the functionality of the
context is determined solely by the requested version.
This means that the code in the question requests a OpenGL 3.2 Core Profile in the not working version a 3.1 (compatibility) profile in the other case.
In a core profile, the use of GL_QUADS as mode for glDrawArrays is deprecated and cannot be used. Due to this, the quad isn't rendered. Note, that you would have found the problem ways faster if you would check for OpenGL errors (glGetError) in your code since it would have reported a GL_INVALID_ENUM for the draw command.
There are two ways how the problem can be solved:
Stop drawing quads and draw triangles instead (GL_TRIANGLES). This is the recommended way.
Explicitly request a OpenGL 3.2 compatibility profile by adding a WGL_CONTEXT_PROFILE_MASK_ARB with the value WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB. But note, that this might cause problems in the future because mixing old OpenGL code with modern OpenGL can lead to problems.

Drawing a child window on top of another child window?

I have different screens serving different purposes in my win32 app, each screen having a different background. The main window have its own static background.
I am drawing screen background on a custom window using following code.
panelBackground = LoadBitmap ( hInstance, MAKEINTRESOURCE ( bitmap ) );
WNDCLASSEX wincl;
wincl.hInstance = hInstance;
wincl.lpszClassName = "jPanel";
wincl.lpfnWndProc = WndProc;
wincl.style = CS_BYTEALIGNWINDOW;// | CS_HREDRAW | CS_VREDRAW;
wincl.cbSize = sizeof (WNDCLASSEX);
wincl.hIcon = 0;
wincl.hIconSm = 0;
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL;
wincl.cbClsExtra = 0;
wincl.cbWndExtra = 4;
wincl.hbrBackground = ( HBRUSH ) GetStockObject( BLACK_BRUSH );
RegisterClassEx (&wincl);
hwnd = CreateWindowEx ( 0, "jPanel", txt.c_str(), WS_CLIPSIBLINGS | WS_CHILD, x, y, width, height, parent, 0, hInstance, 0) ;
SetWindowLong( hwnd , 0 , ( LONG ) this ) ;
SetWindowPos ( hwnd , HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE ) ;
Then in the WndProc :
view::jPanel* panel = ( view::jPanel* ) GetWindowLong( hwnd , 0 ) ;
case WM_PAINT:
{
if ( ! panel )
return 0 ;
HDC hdc ;
PAINTSTRUCT ps ;
RECT rect ;
GetClientRect( hwnd , &rect ) ;
hdc = BeginPaint( hwnd , &ps ) ;
HDC dcSkin = CreateCompatibleDC ( hdc ); // memory dc for skin
HDC hMemDc = CreateCompatibleDC ( hdc ); // memory dc for painting
HBITMAP hmemBmp = CreateCompatibleBitmap ( hdc, rect.right - rect.left, rect.bottom - rect.top ); // Create bitmap to draw on
HBITMAP hOldMemBmp = (HBITMAP)SelectObject ( hMemDc, hmemBmp ); // select memory bitmap in memory dc
HBITMAP hOldSkinBmp = (HBITMAP)SelectObject ( dcSkin, panel->panelBackground ); //select skin bitmap in skin memory dc
BitBlt ( hMemDc, 0, 0, rect.right - rect.left, rect.bottom - rect.top, dcSkin, 0, 0, SRCCOPY ); // Paint Skin on Memory DC
BitBlt ( hdc, 0, 0, rect.right - rect.left, rect.bottom - rect.top, hMemDc, 0, 0, SRCCOPY ); // Paint Skin on Window DC
//<<<... DeleteDC will leak memory if it holds a resource, so lets select the old bitmap back in the memory DCs
SelectObject ( hMemDc, hOldMemBmp ); // select old bitmaps back to their respective DCs before deleting
SelectObject ( dcSkin, hOldSkinBmp ); // select old bitmaps back to their respective DCs before deleting
DeleteObject ( hOldSkinBmp );
DeleteObject ( hOldMemBmp );
DeleteObject( hmemBmp );
DeleteDC ( hMemDc );
DeleteDC ( dcSkin );
EndPaint( hwnd , &ps ) ;
}
break ;
Problem : The child windows(buttons, edit controls) belonging to that screen don't show up, I am guessing
that they are below the screen background window. Moving the controls up the z-order with WS_EX_TOPMOST style doesn't work neither moving the screen background window at the bottom of z-order with SetWindowPos ( hwnd , HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE ) ; works.
And yes buttons are BS_BITMAP styled.
Add the WS_CLIPCHILDREN style when you create the parent window.

How to display text in system tray icon with win32 api C++ - part 2

I have a question similar to this, How to display text in system tray icon with win32 API?
I tried his solution but it's not working for me. I get a small 4x16 white image as the system icon instead of text and I can't understand why.
I'm not using MFC/.NET just win32 api.
void UpdateIcon(HWND hWnd){
NOTIFYICONDATA nid;
nid.cbSize = sizeof(NOTIFYICONDATA);
nid.hWnd = hWnd;
nid.uID = 100;
nid.hIcon = CreateSmallIcon(hWnd);
nid.uFlags = NIF_ICON;
Shell_NotifyIcon(NIM_MODIFY, &nid);
}
HICON CreateSmallIcon( HWND hWnd )
{
static TCHAR *szText = TEXT ( "100" );
HDC hdc, hdcMem;
HBITMAP hBitmap = NULL;
HBITMAP hOldBitMap = NULL;
HBITMAP hBitmapMask = NULL;
ICONINFO iconInfo;
HFONT hFont;
HICON hIcon;
hdc = GetDC ( hWnd );
hdcMem = CreateCompatibleDC ( hdc );
hBitmap = CreateCompatibleBitmap ( hdc, 16, 16 );
hBitmapMask = CreateCompatibleBitmap ( hdc, 16, 16 );
ReleaseDC ( hWnd, hdc );
hOldBitMap = (HBITMAP) SelectObject ( hdcMem, hBitmap );
PatBlt ( hdcMem, 0, 0, 16, 16, WHITENESS );
// Draw percentage
hFont = CreateFont (12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
TEXT ("Arial"));
hFont = (HFONT) SelectObject ( hdcMem, hFont );
TextOut ( hdcMem, 0, 0, szText, lstrlen (szText) );
SelectObject ( hdc, hOldBitMap );
hOldBitMap = NULL;
iconInfo.fIcon = TRUE;
iconInfo.xHotspot = 0;
iconInfo.yHotspot = 0;
iconInfo.hbmMask = hBitmapMask;
iconInfo.hbmColor = hBitmap;
hIcon = CreateIconIndirect ( &iconInfo );
DeleteObject ( SelectObject ( hdcMem, hFont ) );
DeleteDC ( hdcMem );
DeleteDC ( hdc );
DeleteObject ( hBitmap );
DeleteObject ( hBitmapMask );
return hIcon;
}
I don't have windows installed currently so i cannot check if this will work better, but i found potential problem - from MSDN documentation of CreateIconIndirect function:
The application must continue to manage the original bitmaps and delete them when they are no longer necessary.
Seems like you are deleting bitmaps too soon.
You need to set background and possibly foreground colors:
SetTextColor( hdcMem, 0x00FF0000 ); // 0x00bbggrr, not rrggbb !!
SetBkMode( hdcMem, TRANSPARENT ); // VERY IMPORTANT
I think DeleteDC ( hdc ); is not needed here as you used GetDC().

What is wrong with this context creation?

I would like to create a render context to use opengl.
The wglMakeCurrent(hdc, hrc) is returning true.
But for some reason OpenGL functions are ignored.
Here is the code for context creation:
int pixelFormat;
hdc = GetDC(hwnd);
PIXELFORMATDESCRIPTOR pfd;
memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 32;
pfd.cDepthBits = 32;
pfd.iLayerType = PFD_MAIN_PLANE;
pixelFormat = ChoosePixelFormat(hdc,&pfd);
SetPixelFormat(hdc,pixelFormat,&pfd);
hrc = wglCreateContext(hdc);
wglMakeCurrent(hdc, hrc);
And the window creation:
hinst = GetModuleHandle(NULL);
WNDCLASSEX wnd;
memset(&wnd, 0, sizeof(WNDCLASSEX));
wnd.hInstance = hinst;
wnd.style = CS_HREDRAW | CS_VREDRAW;
wnd.cbSize = sizeof(WNDCLASSEX);
wnd.lpszClassName = "__myGLApp__";
wnd.lpfnWndProc = WndProc;
RegisterClassEx(&wnd);
hwnd = CreateWindowEx(WS_EX_TOOLWINDOW,
"__myGLApp__",
"valami",
WS_VISIBLE,
xpos,
ypos,
width,
height,
NULL,
NULL,
hinst,
NULL);
Where am going I wrong?
you can use the glGetError() function to get an error code. You can also get a textual description with the functions gluErrorString() and gluErrorUnicodStringEXT() from the utility library. Something like this:
char *message;
message = gluErrorString(glGetError());
printf("OpenGL error: %s\n", message);