View in DialogBox via Bitblt of HPixmap

Hi,
I'm trying to get the Pixelinformation of my View into a Dialog-Window. And I don't see any reason why the following code does not work...

void CViewDlg::OnPaint()
{
CPaintDC dc(this); // device context for painting

Handle(Aspect_Window) anAspectWindow = myView->Window();
Handle(WNT_Window) aWNTWindow = Handle(WNT_Window)::DownCast(anAspectWindow);

HWND hWindow = (HWND)aWNTWindow->HWindow();

RECT SrcRect;
::GetClientRect(hWindow,&SrcRect);

HDC hDCWindow=::GetDC(hWindow);
HDC hDCDialog=(HDC)dc;
HDC hDCMem=CreateCompatibleDC(hDCWindow);
::ReleaseDC(hWindow, hDCWindow);

RECT DstRect;
::GetClientRect(GetSafeHwnd(),&DstRect);

int WindowWidth=SrcRect.right;
int WindowHeight=SrcRect.bottom;

if(SelectObject(hDCMem,aWNTWindow->HPixmap())==NULL)
AfxMessageBox("Error in Select Pixmap");

if(!BitBlt(hDCDialog,0,0,WindowWidth,WindowHeight,hDCMem,0,0,SRCCOPY))
AfxMessageBox("Error in BitBlt");
ReleaseDC(&dc);
// TODO: Code für die Behandlungsroutine für Nachrichten hier einfügen

// Kein Aufruf von CDialog::OnPaint() für Zeichnungsnachrichten
}

Most of it is similar to the source code of Opencascade, for example in the RestoreArea-Function of WNT_Window or the SaveBitmapToFile-Function of WNT_ImageProcessor.
Does anybody know why my code does not work?
Espacially the line where I select the HPixmap into the Memory DC doesn't work, which I check with the MessageBox (it always appears!).

Thanks Andreas

Stephane Routelous's picture

Hi Andreas,

Do you try to have a OCC View in a dialog box ?
I think it is not the easiest way to do ...

Andreas Hussong's picture

Actually I don't want to have a real view in the Dialog box, but single "Screenshots" of it.
If you know a easier way to do this - please let me know !!!
I try to do it for the last few days now...

Andreas

Stephane Routelous's picture

Well, dump the V3d_View in a .bmp on disk, and in the OnInitdialog, read the BMP, resize it if you want, and display it in your dialog box.

HTH

Andreas Hussong's picture

Ok, that would be possible and I know that it would work - I thought about it, but its not suitable for what I want. Actually, the preview of the picture in a dialog-box is just something like a test.
Later on I want to take a few hundred screenshots to pass them over to some image-processing functions.
If I would dump every single one to disk it would take too long... That's why I wanted to avoid the dump function and tried to find out how it works and do the same to save the screenshots in memory-bitmaps.
The dialog-box is just for the testing stage to check if I succesfully captured the view.

Hope you have another tip for me how to do this.

Andreas

Stephane Routelous's picture

get the pixmap from V3d::ToPixMap.

In the WNT_Pixmap class, you have trhe bitmap.
Unfortunaly, you cannot access the bitmap ( no access method )
2 solutions :
1/ you add a GetBitmap method to WNT_PixMap, but you will need to recompile OCC.
2/ inheritance :
you inherits from V3d_View and from WNT_Pixmap.
In the method V3d_View::ToPixMap, you change the pixmap from WNT_Pixmap to yours.
3/ ( i'm not sure it will work, but you can try ) : you change only the header file WNT_Pixmap.hxx to put the myBitmap field as public. You can try to access it in your programm

Viel Glueck !

Andreas Hussong's picture

Thank you very much !!!
Your 3 hint helped!
I simply changed the WNT_Pixmap.hxx and set the mBitmap field to public and now my Code works.

For everybody who is interested in it, here it is, a bit changed to the previous posting:

void CViewDlg::CaptureView()
{
Handle(Aspect_Window) anAspectWindow = myView->Window();
Handle(WNT_Window) aWNTWindow = Handle(WNT_Window)::DownCast(anAspectWindow);
HWND hWindow = (HWND)aWNTWindow->HWindow();

RECT r;
::GetClientRect(hWindow,&r);
int WindowWidth=r.right;
int WindowHeight=r.bottom;

HDC hDCWindow=::GetDC(hWindow);
HDC hDCMem=CreateCompatibleDC(hDCWindow); //MemoryDC

HDC hDCDialog=*GetDC();
HDC hDCMem2=CreateCompatibleDC(hDCDialog); //MemoryDC

HBITMAP hMemBmp=CreateCompatibleBitmap(hDCWindow,WindowWidth,WindowHeight);

HGDIOBJ hOldObject=SelectObject(hDCMem,hMemBmp);

SelectObject(hDCWindow,(HBITMAP)aWNTWindow->HPixmap());

BitBlt(hDCMem,0,0,WindowWidth,WindowHeight,hDCWindow,0,0,SRCCOPY);

SelectObject(hDCMem,hOldObject);

SelectObject(hDCMem2,hMemBmp);

BitBlt(hDCDialog,10,10,WindowWidth,WindowHeight,hDCMem2,0,0,SRCCOPY);

::ReleaseDC((HWND)this,hDCDialog);
::ReleaseDC(hWindow,hDCWindow);
DeleteDC(hDCMem);
DeleteDC(hDCMem2);
}

It's just a bit funny, that it even captures the content of windows which lie over the view-window. so sometimes even the dialog window :-)
But for me its OK !

Thanks for your help,

Andreas

Ashesh Vashi's picture

Hi Andres,
Thanks for your hints.
I m using this in my code but i m having some problem. I have one application which i found on top of the desktop so if it is over the OCC_View, it's image also get captured in the CaptureView function. Can you tell why this is happening?

Thanks for your code.
Looking forward to your reply.

Ashesh