wglCreatePbufferARB with compatible device context - windows

Is it possible to create pBuffer using wglCreatePbufferARB for a compatible device context ?
HDC fHDC = ::GetDC((HWND)_window);
HDC _fHDC = ::CreateCompatibleDC(fHDC);
HBITMAP memBM = ::CreateCompatibleBitmap ( fHDC, bounds.xMax - bounds.xMin, bounds.yMax - bounds.yMin );
::SelectObject ( _fHDC, memBM );
later on, i'm creating pBuffer using calls -
wglChoosePixelFormatARB(_fHDC, iAttribList, fAttribList, 1,
&pixelFormat, &numFormats)
hBuffer=wglCreatePbufferARB(_fHDC, pixelFormat, width, height, flags);
My call to wglChoosePixelFormatARB is failing

Related

Bitmap for a three state check box with OBM_CHECKBOXES

I want to use three state checkbox in the list control. Today, there is facility for normal checkbox. The bitmap for normal check box are loaded from OBM_CHECKBOXES.
The problem is, I am not able to find the bitmap image for intermediate state (CBS_MIXEDNORMAL). Could anyone help which image index I can use for intermediate state using OBM_CHECKBOXES.
That is a non-themed bitmap. If you want a themed bitmap, you have to use the DrawThemeBackground to draw it to create a bitmap.
There are two bitmaps may be used for intermediate state:
One is CBS_MIXEDNORMAL. DrawThemeBackground(theme, hdc, BP_CHECKBOX, CBS_MIXEDNORMAL, &rc, nullptr);
Another is CBS_CHECKEDDISABLED. DrawThemeBackground(theme, hdc, BP_CHECKBOX, CBS_CHECKEDDISABLED, &rc, nullptr);
Code sample as below:
HDC hdc = BeginPaint(hWnd, &ps);
HTHEME theme = OpenThemeData(nullptr, L"Button");
RECT rc = {};
rc.right = 12;
rc.bottom = 12;
DrawThemeBackground(theme, hdc, BP_CHECKBOX, CBS_MIXEDNORMAL, &rc, nullptr);
CloseThemeData(theme);
EndPaint(hWnd, &ps);

General capturing with WM_PRINT and WM_PRINTCLIENT, supported on at least Windows 7

So far I got this partially working capturing function in C#:
/// <summary>
/// Captures a HWND, using a WM_PRINT windows message to draw into a memory DC.
/// Pro: Does also work if the HWND is not positioned inside the visible screen.
/// Con: Does only work if the target handle supports WM_PRINT and WM_PRINTCLIENT.
/// TODO: Subclass the target handle and hack the WM_PRINT support for various systems, including Windows 7.
/// Example for Windows 2000 see http://www.fengyuan.com/article/wmprint.html.
/// </summary>
/// <param name="hWnd">The HWND.</param>
/// <returns>Bitmap of the captured visual window, if the operation succeeds. Null, if the operation fails.</returns>
public static Bitmap CaptureHWnd_WM_PRINT(UIntPtr hWnd)
{
Bitmap bitmap = null;
UIntPtr hDC = User32.GetWindowDC(hWnd); //Get the device context of hWnd
if (hDC != UIntPtr.Zero)
{
UIntPtr hMemDC = Gdi32.CreateCompatibleDC(hDC); //Create a memory device context, compatible with hDC
if (hMemDC != UIntPtr.Zero)
{
RECT rc; MyGetWindowRect(hWnd, out rc); //Get bounds of hWnd
UIntPtr hbitmap = Gdi32.CreateCompatibleBitmap(hDC, rc.Width, rc.Height); //Create a bitmap handle, compatible with hDC
if (hbitmap != UIntPtr.Zero)
{
UIntPtr hOld = Gdi32.SelectObject(hMemDC, hbitmap); //Select hbitmap into hMemDC
//#also tried: User32.SendMessage(hWnd, WM.PRINT, hMemDC, (UIntPtr)(DrawingOptions.PRF_CLIENT | DrawingOptions.PRF_CHILDREN | DrawingOptions.PRF_NONCLIENT | DrawingOptions.PRF_OWNED));
User32.DefWindowProc(hWnd, WM.PRINT, hMemDC, (UIntPtr)(DrawingOptions.PRF_CLIENT | DrawingOptions.PRF_CHILDREN | DrawingOptions.PRF_NONCLIENT | DrawingOptions.PRF_OWNED));
bitmap = Image.FromHbitmap(hbitmap.ToIntPtr()); //Create a managed Bitmap out of hbitmap
Gdi32.SelectObject(hMemDC, hOld); //Select hOld into hMemDC (the previously replaced object), to leave hMemDC as found
Gdi32.DeleteObject(hbitmap); //Free hbitmap
}
Gdi32.DeleteDC(hMemDC); //Free hdcMem
}
User32.ReleaseDC(hWnd, hDC); //Free hDC
}
return bitmap;
}
The problem is, that it can only work if hWnd handles the WM_PRINT and WM_PRINTCLIENT messages correctly.
For example, one can test it sucessfully using
UIntPtr hWndMyButton = User32.CreateWindowEx(
WS_EX.NONE, "Button", " HELLO WORLD! :) ", WS.CHILD,
5000, 5000,
200, 30, User32.GetDesktopWindow(), (UIntPtr)0x8807, UIntPtr.Zero, UIntPtr.Zero);
Bitmap capture = CaptureHWnd_WM_PRINT(hWndMyButton);
, but for the most cases it only results in a black image of the size of hWnd. Note that hWndMyButton is far outside the screen bounds (at position {X=5000,Y=5000}), but can still get captured. That is the reason I need WM_PRINT.
The questions is now, how can I force hWnd to handle the print messages correctly on at least Windows 7?
So far, I found this solution for Windows 2000 and would like to get a similar solution for Windows 7, or preferred a generic solution for all Windows systems that support WM_PRINT.
Unfortunately I could not find anything for other systems than Windows 2000.

How do I correctly convert an ICON to a BITMAP using MFC?

I'm loading an ICON of another application via
HICON ico = ExtractIcon(NULL, L"path\\to\\OtherApp.exe", 0);
How can I create a CBitmap object from this icon?
Specifically (not really answered in the dup question for me):
Which device context?
At the end, I want a CBitmap object that outlives the function that converts the icon:
What do I need to clean up immediately and what do I need to keep around? (DC, ...?)
Here's the code I have so far:
void ConvertIconToBitmap(CBitmap& bmpObj, HICON hIcon, int cx, int cy) {
CClientDC clientDC(NULL);
CDC dc;
dc.CreateCompatibleDC(NULL);
CBitmap bmpTmp;
VERIFY( bmpTmp.CreateCompatibleBitmap(&clientDC, cx, cy) );
CBitmap* pOldBmp = (CBitmap*)dc.SelectObject(&bmpTmp);
VERIFY( ::DrawIconEx( dc.GetSafeHdc(), 0, 0, hIcon, cx, cy, 0, NULL, DI_NORMAL) );
dc.SelectObject( pOldBmp );
// For some reason I need to copy the bitmap here: (maybe it's the DIB flag)
HBITMAP hDibBmp = (HBITMAP)::CopyImage((HANDLE)(HBITMAP)bmpTmp, IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE | LR_CREATEDIBSECTION);
VERIFY( hDibBmp );
VERIFY( bmpObj.Attach(hDibBmp) );
// VERIFY( bmpObj.Attach(bmpTmp.Detach()) );
}
Now, this code works, but I don't understand it:
Why do I need a CClientDC? (If I use only CDC the bitmap is not shown or Black&White, depending on where I put it.)
(Why) is the dc.SelectObject( pOldBmp ) line needed?
Why do I have to do CopyImage? (If I don't, the bitmap is sometimes drawn with inverted colors.)
Does this code leak anything or is everything properly cleaned up?
Here's another version that also seems to work:
void ConvertIconToBitmap2(CBitmap& bmpObj, HICON hIcon, int cx, int cy) {
CClientDC clientDC(NULL);
CDC memDC;
memDC.CreateCompatibleDC(&clientDC);
ASSERT(hIcon);
ICONINFO info;
VERIFY(GetIconInfo(hIcon, &info));
BITMAP bmp;
GetObject(info.hbmColor, sizeof(bmp), &bmp);
HBITMAP hBitmap = (HBITMAP)CopyImage(info.hbmColor, IMAGE_BITMAP, 0, 0, 0);
ASSERT(hBitmap);
ASSERT(memDC.GetSafeHdc());
HBITMAP hOldBmp = (HBITMAP)memDC.SelectObject(hBitmap);
clientDC.BitBlt(0, 0, bmp.bmWidth, bmp.bmHeight, &memDC, 0, 0, SRCCOPY);
memDC.SelectObject(hOldBmp);
VERIFY( bmpObj.Attach(hBitmap) );
DeleteObject(info.hbmColor);
DeleteObject(info.hbmMask);
}
•Why do I need a CClientDC? (If I use only CDC the bitmap is not shown or Black&White, depending on where I put it.)
You would need a DC that is based on your window or the screen, just declaring a CDC is not enough, you will also need to call dc.Attach() or one of the CDC::Create* functions.
•(Why) is the dc.SelectObject( pOldBmp ) line needed?
So that the bitmap is disconnected from the DC
•Why do I have to do CopyImage? (If I don't, the bitmap is sometimes drawn with inverted colors.)
It looks like you are creating a device independent bimap using the CopyImage() call using the LR_CREATEDIBSECTION parameter
•Does this code leak anything or is everything properly cleaned up?
Looks ok to me!

Correctly release resources after flipping a bitmap

I have an application that writes a very large data set as a bitmap. [~500MB] I am writing the data patch wise from top to down. Due to the nature of BMP's file structure it must be flipped once written to the disk. (I wrote it this way because I assumed that flipping a bitmap would be a common application and I would find libraries to do the task)
I am using a code snippet I found on the internet to flip the bitmap. This one:
// GetInvertedBitmap - Creates a new bitmap with the inverted image
// Returns - Handle to a new bitmap with inverted image
// hBitmap - Bitmap to invert
// bLateral - Flag to indicate whether to invert laterally or vertically
HBITMAP CRisatImport::GetInvertedBitmap( HBITMAP hBitmap, BOOL bLateral )
{
// Create a memory DC compatible with the display
CDC sourceDC, destDC;
sourceDC.CreateCompatibleDC( NULL );
destDC.CreateCompatibleDC( NULL );
// Get logical coordinates
BITMAP bm;
::GetObject( hBitmap, sizeof( bm ), &bm );
// Create a bitmap to hold the result
HBITMAP hbmResult = ::CreateCompatibleBitmap(CClientDC(NULL),
bm.bmWidth, bm.bmHeight);
// Select bitmaps into the DCs
HBITMAP hbmOldSource = (HBITMAP)::SelectObject( sourceDC.m_hDC, hBitmap );
HBITMAP hbmOldDest = (HBITMAP)::SelectObject( destDC.m_hDC, hbmResult );
if( bLateral )
destDC.StretchBlt( 0, 0, bm.bmWidth, bm.bmHeight, &sourceDC,
bm.bmWidth-1, 0, -bm.bmWidth, bm.bmHeight, SRCCOPY );
else
destDC.StretchBlt( 0, 0, bm.bmWidth, bm.bmHeight, &sourceDC,
0, bm.bmHeight-1, bm.bmWidth, -bm.bmHeight, SRCCOPY );
// Reselect the old bitmaps
::SelectObject( sourceDC.m_hDC, hbmOldSource );
::SelectObject( destDC.m_hDC, hbmOldDest );
return hbmResult;
}
The problem is that I have a limited understanding of the above code. I tried to write a function to use the above snippet the best I could from sample code from MSDN. I do not think I am releasing all resources correctly. And I cant seem to figure out the error - mainly because my lack of knowledge about GDI. I would really appreciate it if some one pointed out what I am doing wrong.
The program crashes if I try to call this function twice - that is why I suspect that I am releasing resources incorrectly.
This is the function I wrote:
void CRisatImport::flipBitMapSaveAsJPG( CString outputFileName, CString outputJPGName, bool saveAsJpg)
{
// Flip the bitmap to correct odd file structure
HBITMAP hBitmap;
hBitmap = (HBITMAP)::LoadImage(NULL, outputFileName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
hBitmap = GetInvertedBitmap( hBitmap, FALSE );
CImage image;
image.Attach(hBitmap);
image.Save(outputFileName,Gdiplus::ImageFormatBMP);
if(saveAsJpg){
image.Save(outputJPGName,Gdiplus::ImageFormatJPEG);
}
image.Destroy();
DeleteObject( hBitmap );
}
I am using MFC and VS2010 for this application - I have 4GB of RAM and no other applications running.
This is the error I get:
When you Attach your bitmap handle to CImage you're handing over responsibility for the handle's lifetime to CImage so you don't want to Destory it after. But you're also using the same variable name for your new bitmap. Try this instead:
void CRisatImport::flipBitMapSaveAsJPG( CString outputFileName, CString outputJPGName, bool saveAsJpg)
{
// Flip the bitmap to correct odd file structure
HBITMAP hBitmapLoad = (HBITMAP)::LoadImage(NULL, outputFileName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
HBITMAP hBitmapInverted = GetInvertedBitmap( hBitmapLoad , FALSE );
DeleteObject( hBitmapLoad );
CImage image;
image.Attach(hBitmapInverted );
image.Save(outputFileName,Gdiplus::ImageFormatBMP);
if(saveAsJpg){
image.Save(outputJPGName,Gdiplus::ImageFormatJPEG);
}
image.Destroy();
}

How to create a window and fill it with color using OpenES 2.0 + X11?

I googled as hard as I can, but I found nothing.
What I want to do:
create a window with X11 (Xlib) and show it
fill the window with color using OpenGL ES 2.0
For OpenGL ES 2.0 support on my ArchLinux, I use MESA. I know how to create a simple X window using Xlib, I have a basic knowledge of EGL and OpenGL ES, but I can't understand how to use all them (X11 + EGL + OpenGL ES 2.0) in conjuction.
I would be very thakful if someone wrote at least a short code example on how to prepare a X window and connect it with OpenGL ES 2.0 correctly and start rendering.
Create Window:
Window root;
XSetWindowAttributes swa;
XSetWindowAttributes xattr;
Atom wm_state;
XWMHints hints;
XEvent xev;
EGLConfig ecfg;
EGLint num_config;
Window win;
/*
* X11 native display initialization
*/
x_display = XOpenDisplay(NULL);
if ( x_display == NULL )
{
return EGL_FALSE;
}
root = DefaultRootWindow(x_display);
swa.event_mask = ExposureMask | PointerMotionMask | KeyPressMask;
win = XCreateWindow(
x_display, root,
0, 0, esContext->width, esContext->height, 0,
CopyFromParent, InputOutput,
CopyFromParent, CWEventMask,
&swa );
xattr.override_redirect = FALSE;
XChangeWindowAttributes ( x_display, win, CWOverrideRedirect, &xattr );
hints.input = TRUE;
hints.flags = InputHint;
XSetWMHints(x_display, win, &hints);
// make the window visible on the screen
XMapWindow (x_display, win);
XStoreName (x_display, win, title);
// get identifiers for the provided atom name strings
wm_state = XInternAtom (x_display, "_NET_WM_STATE", FALSE);
memset ( &xev, 0, sizeof(xev) );
xev.type = ClientMessage;
xev.xclient.window = win;
xev.xclient.message_type = wm_state;
xev.xclient.format = 32;
xev.xclient.data.l[0] = 1;
xev.xclient.data.l[1] = FALSE;
XSendEvent (
x_display,
DefaultRootWindow ( x_display ),
FALSE,
SubstructureNotifyMask,
&xev );
Set color:
glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f );
// Set the viewport
glViewport ( 0, 0, esContext->width, esContext->height );
// Clear the color buffer
glClear ( GL_COLOR_BUFFER_BIT );
Sources:
https://github.com/danginsburg/opengles-book-samples/blob/master/LinuxX11/Chapter_2/Hello_Triangle/Hello_Triangle.c
https://github.com/danginsburg/opengles-book-samples/blob/master/LinuxX11/Common/esUtil.c
https://github.com/danginsburg/opengles-book-samples/blob/master/LinuxX11/Common/esUtil.h
The opengles-book-samples code actually fails for me. If you see the same init failures, a call to eglBindAPI(EGL_OPENGL_ES_API) seemed to fix it.

Resources