|
|
I believe there is a better way to do the Capture it the GDI way in the article.
Instead of GetDesktopWindow() and GetDC() you can use CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
«_Superman_»
I love work. It gives me something to do between weekends.
|
|
|
|
|
offcourse superman's suggested method is better
see the code below for help
HDC hDesktopDC, hMemDC;
int nXPos = 0, nYPos = 0;
int nWidth = 0, nHeight = 0;
HGDIOBJ hOldBitmap, hBitmap;
// check for an empty rectangle
if ( IsRectEmpty( lpRect_i ))
{
return NULL;
}
// create a DC for the screen and create
// a memory DC compatible to screen DC
hDesktopDC = CreateDC( _T( "DISPLAY" ), NULL, NULL, NULL );
hMemDC = CreateCompatibleDC( hDesktopDC ); // get points of rectangle to grab
nXPos = lpRect_i->left;
nYPos = lpRect_i->top;
nWidth = lpRect_i->right - lpRect_i->left;
nHeight = lpRect_i->bottom - lpRect_i->top ;
// create a bitmap compatible with the screen DC
hBitmap = CreateCompatibleBitmap( hDesktopDC, nWidth, nHeight );
// select new bitmap into memory DC
hOldBitmap = SelectObject ( hMemDC, hBitmap );
// bitblt screen DC to memory DC
BitBlt( hMemDC, 0, 0, nWidth, nHeight, hDesktopDC, nXPos, nYPos, SRCCOPY );
// select old bitmap back into memory DC and get handle to
// bitmap of the screen
hBitmap = SelectObject( hMemDC, hOldBitmap );
// clean up
DeleteDC( hDesktopDC );
DeleteDC( hMemDC );
// return handle to the bitmap
return ( HBITMAP )hBitmap;
Величие не Бога может быть недооценена.
|
|
|
|
|
Thanks all of you for guidance and providing me a couple of alternates to perform the task. I would implement the stuff then I would be back , if i face some problem.....
|
|
|
|
|
Sorry, I have to ask very primitive questions but I did some work in VC++ around 9 years back and now forget every thing. Even I have to struggle to play with AfxMessageBox these days
Anyhow, now I want to display the captured image. The image is captured in HBITMAP hCaptureBitmap, so what class I should use to display the image. Suppose I have SDI based application and in View class what should I do......
|
|
|
|
|
no more direct code
Clue :-
1. device context.
2. SelectObject
3. bitBlt
Now try yourself
Величие не Бога может быть недооценена.
|
|
|
|
|
You mean , I should get the DC in view class by calling some thing like GetDC , then Select that DC and at the end by using bitBlt should display in the view class....
hmmm. what about if I take an object of Picturebox and then assign the handler of Bitmap to it. but I guess u are right there is no need to take an object of PictureBox, rather view class can be work as a placeholder as well. let me try
|
|
|
|
|
yes u should try
Величие не Бога может быть недооценена.
|
|
|
|
|
void CSDITESTView::OnFileTest()
{
int nScreenWidth = GetSystemMetrics(SM_CXSCREEN);
int nScreenHeight = GetSystemMetrics(SM_CYSCREEN);
HWND hDesktopWnd = GetDesktopWindow()->m_hWnd;
HDC hDesktopDC = ::GetDC(hDesktopWnd);
HDC hCaptureDC = CreateCompatibleDC(hDesktopDC);
HBITMAP hCaptureBitmap =CreateCompatibleBitmap(hDesktopDC,nScreenWidth, nScreenHeight);
SelectObject(hCaptureDC,hCaptureBitmap);
BitBlt(hCaptureDC,0,0,nScreenWidth,nScreenHeight, hDesktopDC,0,0,SRCCOPY|CAPTUREBLT);
::ReleaseDC(hDesktopWnd,hDesktopDC);
DeleteDC(hCaptureDC);
}
I guess this code should work as it is doing the all stuff already, but it not displaying anything ? why
|
|
|
|
|
Who will call the paint?
clue
1. Some one should call painting, isnt
Just simple, usually it is not done to give the whole code,
well check the below code.
HBITMAP CopyScreen( LPRECT lpRect_i )
{
HDC hDesktopDC, hMemDC;
int nXPos = 0, nYPos = 0;
int nWidth = 0, nHeight = 0;
HGDIOBJ hOldBitmap, hBitmap;
// check for an empty rectangle
if ( IsRectEmpty( lpRect_i ))
{
return NULL;
}
// create a DC for the screen and create
// a memory DC compatible to screen DC
hDesktopDC = CreateDC( _T( "DISPLAY" ), NULL, NULL, NULL );
hMemDC = CreateCompatibleDC( hDesktopDC ); // get points of rectangle to grab
nXPos = lpRect_i->left;
nYPos = lpRect_i->top;
nWidth = lpRect_i->right - lpRect_i->left;
nHeight = lpRect_i->bottom - lpRect_i->top ;
// create a bitmap compatible with the screen DC
hBitmap = CreateCompatibleBitmap( hDesktopDC, nWidth, nHeight );
// select new bitmap into memory DC
hOldBitmap = SelectObject ( hMemDC, hBitmap );
// bitblt screen DC to memory DC
BitBlt( hMemDC, 0, 0, nWidth, nHeight, hDesktopDC, nXPos, nYPos, SRCCOPY );
// select old bitmap back into memory DC and get handle to
// bitmap of the screen
hBitmap = SelectObject( hMemDC, hOldBitmap );
// clean up
DeleteDC( hDesktopDC );
DeleteDC( hMemDC );
// return handle to the bitmap
return ( HBITMAP )hBitmap;
}
void CSlideshawDlg::OnFirst()
{
RECT rect;
rect.left = 150;
rect.bottom = 500;
rect.top = 150;
rect.right = 500;
HBITMAP hBit = CopyScreen( &rect );
CDC memdc1;
CClientDC dc(this);
memdc1.CreateCompatibleDC(&dc);
memdc1.SelectObject( hBit );
dc.BitBlt(150,150,500,500,&memdc1,0,0,SRCCOPY);
}
Величие не Бога может быть недооценена.
modified on Thursday, July 30, 2009 7:01 AM
|
|
|
|
|
This is what I cooked, but it is not working... I know there is Invalidate() but it call onpaint again, so why we call it here.
void CSDITESTView::OnFileTest()
{
//m_pDC store the CDC pointer in OnDraw() function.
CDeskTop desktop;
CBitmap bitmap;
HWND hWnd=NULL;
bitmap.Attach(desktop.GetDeskTopImage());
BITMAP bm;
bitmap.GetBitmap(&bm );
CDC memDC;
CClientDC dc(this);
memDC.CreateCompatibleDC(&dc);
memDC.SelectObject(&bitmap );
m_pDC->BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &memDC, 0, 0,SRCCOPY);
}
HBITMAP CDeskTop:: GetDeskTopImage()
{
int nScreenWidth = GetSystemMetrics(SM_CXSCREEN);
int nScreenHeight = GetSystemMetrics(SM_CYSCREEN);
HWND hDesktopWnd = GetDesktopWindow();
HDC hDesktopDC = GetDC(hDesktopWnd);
HDC hCaptureDC = CreateCompatibleDC(hDesktopDC);
HBITMAP hCaptureBitmap =CreateCompatibleBitmap(hDesktopDC,nScreenWidth, nScreenHeight);
SelectObject(hCaptureDC,hCaptureBitmap);
BitBlt(hCaptureDC,0,0,nScreenWidth,nScreenHeight, hDesktopDC,0,0,SRCCOPY|CAPTUREBLT);
ReleaseDC(hDesktopWnd,hDesktopDC);
DeleteDC(hCaptureDC);
return hCaptureBitmap;
}
|
|
|
|
|
Now I got the solution.
m_pDC->BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &memDC, 0, 0,SRCCOPY);
dc.BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &memDC, 0, 0,SRCCOPY);
I replaced m_pDC with dc. and now it works.
THANKS A LOT INDEED FOR YOUR CONTINOUS HELP
|
|
|
|
|
Hi..
Basically I am working with CPP console application. Could any one update me, to capture screenshot of Desktop (by using the code mentioned in this thread).. whether I need to use MFC project or ATL based Project.
Any guidelines will help me a lot.
Thanks in advance.
|
|
|
|
|
Hi all,
I just got a new simple USB framegrabber which uses emBDA.sys (pretty common driver used by many USB frame grabbers/TV tuners these days) and when I try to access it in my MFC program, it BSODs right away with emBDA.sys error (8E code). But when I use their application to capture with the framegrabber, it works fine. I tried it on couple of systems with same result.
It happens as soon as I call capDlgVideoSource(GetSafeHwnd()); command.
Does anyone came accross this problem with accessing this driver before??
Any suggestions for using alternate drivers??
thanks,
PKNT
|
|
|
|
|
Hi,
how can i get the fixed border or proportional border for a rect...
|
|
|
|
|
i'm now wanna to convert the matlab left matrix division \ into cv++ with opencv.
i have no ideal about it. the matlab help file also not help me a lot to understand the algorithm.anyone can help me or gv me the suggestion? I'm waiting your reply.Thank you!
|
|
|
|
|
Hi all,
I write a MFC program that will execute a drawing circle in another thread when I click on somewhere in client area and I got it.
My problem is when I click various time (and quickly) it sometime gives me an "Assertion Failed" error.
here is my code:
void CGSimView::OnLButtonDown(UINT nFlags, CPoint point)
{
...
DCPOINT info;
PTPOINT3D currentPoint = pDoc->m_graph.GetNode(point.x,point.y);
if(currentPoint != NULL)
{
this->m_nodeIndex = currentPoint->index;
info.hwnd = this->GetSafeHwnd();
this->GetClientRect(&info.rect);
info.point = currentPoint;
AfxBeginThread(onGetFocus,&info);
}
CView::OnLButtonDown(nFlags, point);
}
UINT onGetFocus(LPVOID param)
{
DCPOINT *info = (DCPOINT*)param;
HDC hdc = GetDC(info->hwnd);
PTPOINT3D p = info->point;
int i, temp;
CRect rect = info->rect;
HPEN hPen, hOldPen;
hPen = CreatePen(PS_SOLID,1,RGB(225,0,0));
hOldPen = (HPEN)SelectObject(hdc, hPen);
for(i=0;i<9;i++)
{
temp = 10+i;
Ellipse(hdc,p->x - temp,p->y - temp,p->x + temp, p->y + temp);
Sleep(10);
}
SelectObject(hdc, hOldPen);
DeleteObject(hPen);
return 0;
}
please help me to solve this.
Thank in advance.
|
|
|
|
|
When it gives "Assert failed", click "Retry" to debug the program.
The code around the Assert statement usually gives a clue as to why it is failing. Sometimes there's a comment that tells explicitly why it might fail.
|
|
|
|
|
Thank Richard,
I have followed as your advise and the Debugger points to this line of my code:
Ellipse(hdc, p->x - temp, p->y - temp, p->x + temp, p->y + temp);
It says "Access violation".
I guess that it has some conflict between threads on the device context I've used. But I don't know how to solve it.
Please help!
|
|
|
|
|
When you debug it, inspect the variable "p" to be sure that it points to a valid object.
That may be the source of the access violation.
|
|
|
|
|
I failed to notice something serious:
You're trying to draw in the window with a secondary thread.
This is not allowed in MFC.
You must do all your drawing with the same thread that owns the window.
|
|
|
|
|
Thank Richard,
I greatly appreciate your help to me.
But now I'm completely surprised that drawing in the window with a secondary thread is not allowed in MFC.
Actually I'm writing a simple game, when my user selects an object on screen, I want my user take focus on that object by a moving circle around it. How people do that with MFC?
Thank
|
|
|
|
|
|
One thing I see that could also be part of your problem is that you do a GetDC() in your thread, and then you properly select the new pen, use it, select the old pen and delete it, but I don't see anywhere that you do a ReleaseDC().
This probably isn't the entire problem, but you should always release the DC after you use it that way.
Hope that helps.
Karl - WK5M
PP-ASEL-IA (N43CS)
PGP Key: 0xDB02E193
PGP Key Fingerprint: 8F06 5A2E 2735 892B 821C 871A 0411 94EA DB02 E193
|
|
|
|
|
[moved to C++/CLI forum]
dev
modified on Wednesday, July 29, 2009 10:51 PM
|
|
|
|
|