|
Did you ever get this straightened out?
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
Hi all,
i am trying to step through my simple application. But its so annoying in MFC. Well when i use F10 or F11 it goes directly to appmodul.h and run the whole application frm there. Now if i put break pt. and press F5 and the step through it. It would start going to so many MFC lib source files and after going through 5-6 header files it gives error that no source found...
I really dont want to step through or step into the mfc inbuild source files. I want to only step through my written code. How can i achieve this. There must be some way out. Its so hard to debug like this.
Any help would be appreciated.
Thanks
|
|
|
|
|
Don't step in, just step over. Stepping in will go into MFC, this is a *feature*, I wish I could do that in C#, the best I can do is read the source via reflection. But, you can just step over, or if you find yourself in MFC code, step out.
worst comes to worst, set a breakpoint where you next want to stop and hit 'continue'.
Christian Graus - Microsoft MVP - C++
Metal Musings - Rex and my new metal blog
"I am working on a project that will convert a FORTRAN code to corresponding C++ code.I am not aware of FORTRAN syntax" ( spotted in the C++/CLI forum )
|
|
|
|
|
What is the correct way to populate a CBitmap object from a CDC object in the function below?
How should the return object be release properly in order to avoid resource leakage?
<br />
CStatic m_picture;<br />
WMPPlayer4 m_player;<br />
<br />
CBitmap bm_copy;<br />
CopyWindowAreaToStatic( CWindowDC( &m_player ), bm_copy );<br />
<br />
void CopyWindowAreaToStatic( CDC& cdc_source, CBitmap& bm_copy )<br />
{<br />
CClientDC dc_static( &m_picture );<br />
CRect rc_static;<br />
m_picture.GetClientRect( rc_static );<br />
dc_static.BitBlt( 0, 0, rc_static.Width(), rc_static.Height(), &cdc_source, 0, 0, SRCCOPY );<br />
<br />
CSize sc(rc_static.Width(), rc_static.Height());<br />
bm_copy.CreateCompatibleBitmap(&cdc_source, sc.cx, sc.cy);<br />
}<br />
|
|
|
|
|
C. Tam wrote: CSize sc(rc_static.Width(), rc_static.Height());
bm_copy.CreateCompatibleBitmap(&cdc_source, sc.cx, sc.cy);
Add the following code below the above statement.
CDC MemDc;<br />
MemDc.CreatecompatibleDC(&cdc_source);<br />
CBitmap *pOld = MemDc.SelectObject( &bm_copy );<br />
MemDc.BitBlt( 0, 0, sc.cx, sc.cy, &cdc_source, 0, 0, SRCCOPY );<br />
MemDc.SelectObject( pOld );
|
|
|
|
|
I've updated the function with your reply. Thanks.
Unfortunately, I've noticed this function fails to work when it is invoked by a timer and the source window area is obscured by another application.
E.g. An application with the function "CopyWindowAreaToStatic" is running in the background and its source window area is partially covered by another application. Under this situation, the target's contents include a partial source and the foreground application window area.
Do you know how it should be corrected?
|
|
|
|
|
if your using window xp or later you can use the PrintWindow() function instead of the
MemDc.BitBlt( 0, 0, sc.cx, sc.cy, &cdc_source, 0, 0, SRCCOPY );
Other options are sending the WM_PRINTCLIENT message to the window.
|
|
|
|
|
I've replaced the line
"MemDc.BitBlt( 0, 0, sc.cx, sc.cy, &cdc_source, 0, 0, SRCCOPY );"
with the following line
"PrintWindow(cdc_source, (HDC)MemDc);"
Unfortunately, I couldn't get it to compile. The error is
"error C2065: 'PrintWindow' : undeclared identifier".
Do you know how to correct it?
FYI: I'm using VS6 and I've installed MS Platform SDK for Windows Server 2003 R2.
|
|
|
|
|
C. Tam wrote: PrintWindow(cdc_source, (HDC)MemDc);"
the first parameter is handle to the window not the device context.
C. Tam wrote: error C2065: 'PrintWindow' : undeclared identifier".
You have to set the _WIN32_WINNT version. For this take Project Settings->C++->In the preprocessor definition edit box, put _WIN32_WINNT=0x0501 and rebuild
|
|
|
|
|
I've corrected the line to "PrintWindow(m_player.m_hWnd, (HDC)MemDc);" and
updated the preprocessor definition as "_WIN32_WINNT=0x0501,WIN32,_DEBUG,_WINDOWS,_AFXDLL,_MBCS".
After a full rebuild, I received the following error,
": error C2065: 'PrintWindow' : undeclared identifier"
How should I correct this problem?
|
|
|
|
|
Have you set the include directories and lib directories of the Platform SDK 2003 in the msdev->Tools->Options->Directories->Include file ???
|
|
|
|
|
Thanks for your reply. I got it to compile after installing Platform SDK Feb 2003 which is compatible with VS C++ 6.
Below is the updated function.
Is it correct? Would it leak any resources?
How should I clean up bitmap_output after use?
<br />
void CopyToBitmap(CWMPPlayer4& player, CBitmap& bitmap_output)<br />
{<br />
CClientDC player_dc(&player);<br />
CRect player_rc;<br />
player.GetClientRect( player_rc );<br />
CSize player_sc(player_rc.Width(), player_rc.Height());<br />
bitmap_output.CreateCompatibleBitmap(&player_dc, player_sc.cx, player_sc.cy);<br />
<br />
CDC* dc_p = this->GetDC();<br />
CDC bitmap_dc;<br />
bitmap_dc.CreateCompatibleDC( dc_p );<br />
CBitmap *prev_bitmap_p = bitmap_dc.SelectObject( &bitmap_output );<br />
PrintWindow( player.m_hWnd, (HDC)bitmap_dc, PW_CLIENTONLY );<br />
bitmap_dc.SelectObject( prev_bitmap_p );<br />
ReleaseDC( dc_p );<br />
}
|
|
|
|
|
C. Tam wrote: How should I clean up bitmap_output after use?
This code is ok. No need to cleanyp the bitmap_output. the destrucor of the CBitmap will take care of it.
C. Tam wrote: CDC* dc_p = this->GetDC();
I think this code is not needed. You can use the player_dc itself.
|
|
|
|
|
I've updated the code to use player_dc as below. Thanks for inputs.
During testing, I've discovered that the app does not work all the time.
So far, it works on XPProSP2 hosted on MS Virtual PC 2004.
However, it doesn't work on XPProSP2 running on a real computer. The CBitmap's output is black.
How do I resolve this problem?
<br />
void CopyToBitmap(CWMPPlayer4& player, CBitmap& bitmap_output)<br />
{<br />
CClientDC player_dc(&player);<br />
CRect player_rc;<br />
player.GetClientRect( player_rc );<br />
CSize player_sc(player_rc.Width(), player_rc.Height());<br />
bitmap_output.CreateCompatibleBitmap(&player_dc, player_sc.cx, player_sc.cy);<br />
<br />
CDC bitmap_dc;<br />
bitmap_dc.CreateCompatibleDC( &player_dc );<br />
CBitmap *prev_bitmap_p = bitmap_dc.SelectObject( &bitmap_output );<br />
PrintWindow( player.m_hWnd, (HDC)bitmap_dc, PW_CLIENTONLY );<br />
bitmap_dc.SelectObject( prev_bitmap_p );<br />
}<br />
-- modified at 4:33 Wednesday 6th June, 2007
|
|
|
|
|
I found no reasond for this code to work. Did you debug? Its dosent work means any function failed?
How ever try the next option, WM_PRINTCLIENT
|
|
|
|
|
I've found a workaround for this problem as quoted below.
"During testing, I've discovered that the app does not work all the time.
So far, it works on XPProSP2 hosted on MS Virtual PC 2004.
However, it doesn't work on XPProSP2 running on a real computer. The CBitmap's output is black."
On a real computer's display control panel, reduces the levels of hardware acceleration controlled by device drivers.
By the way, when I run the app on a Windows 2000 machine, an error message is displayed (shown below) before it is shutdown.
"app.exe - Entry Point Not Found"
"The procedure entry point PrintWindow could not be located in the dynamic link library USER32.dll".
Could you show me how to display a more user friendly error message insteads of the one above?
|
|
|
|
|
C. Tam wrote: "The procedure entry point PrintWindow could not be located in the dynamic link library USER32.dll".
Definitly it will come because the Printwindow() function is suppported only in windows XP or a later OS. It will not work in windows 2000. As I said earlier, you can use the WM_PRINTCLIENT message for the same purpose. It will work in windows 95 also.
|
|
|
|
|
I've replaced the following line
PrintWindow(m_player.m_hWnd, (HDC)MemDc, PW_CLIENTONLY);
with
::SendMessage(m_player.m_hWnd, WM_PRINTCLIENT, (WPARAM)(HDC)MemDc, PRF_CHILDREN | PRF_CLIENT | PRF_ERASEBKGND | PRF_NONCLIENT); .
Unfortunately, it no longer copies the image.
How should I correct it?
|
|
|
|
|
May be a problem with the m_player window. Try passing the handle of another window and verify the image is correct or not.
|
|
|
|
|
Yes, you're right. It's the problem with the m_player window. I works on a CStatic window. Do you know why?
In the meantime, I've rolled back to PrintWindow API which will only work on Windows XP.
As I've mentioned before, when I run the app on a Windows 2000 machine, an error message is displayed (shown below) before it is shutdown.
"app.exe - Entry Point Not Found"
"The procedure entry point PrintWindow could not be located in the dynamic link library USER32.dll".
Is it possible replace the above message with my own custom one?
|
|
|
|
|
C. Tam wrote: Do you know why?
May be the m_player window is not using the usual paint messages to draw the window.
C. Tam wrote: Is it possible replace the above message with my own custom one?
You can if you dynamically load this function. For this first declare the function as below
typedef BOOL ( WINAPI *MyPrintWindow)(IN HWND hwnd, IN HDC hdcBlt, IN UINT nFlags);
Then
To check whether the function is available or not, you an do like this,
HMODULE hUser32Module = LoadLibrary( _T("User32.dll"));<br />
MyPrintWindow p = (MyPrintWindow)GetProcAddress( hUser32Module, "PrintWindow");<br />
if( p == 0 )<br />
{<br />
AfxMessageBox( _T("Your custom message here"));<br />
return;<br />
}
And if you want to call the printwindow function,
p( m_player.m_hWnd, (HDC)MemDc, PW_CLIENTONLY);
|
|
|
|
|
C. Tam wrote: Unfortunately, I've noticed this function fails to work when it is invoked by a timer and the source window area is obscured by another application.
If there's aother window on top of the one you are copying pixels from then you're going to get
the pixels of the obscurring window. Is this what's happening?
If you want this to work you'll need to keep a bitmap copy of the window's contents so when you
receive a timer event you can use that bitmap instead of scraping the screen.
Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
The anwser is Yes to your question "If there's aother window on top of the one you are copying pixels from then you're going to get the pixels of the obscurring window. Is this what's happening?"
Thanks for your reply, on the point of using the bitmap copy instead of scraping the screen.
|
|
|
|
|
This is probably a very simple question, but I'm new to ATL.
Is it possible to mix code that uses the MFC library with code that uses the ATL library?
I've tried a simple example, but it won't compile. I get the following error:
1>c:\program files\microsoft visual studio 8\vc\atlmfc\include\cstringt.h(2508) : error C2872: 'ULONG_PTR' : ambiguous symbol
1> could be 'c:\program files\microsoft platform sdk\include\basetsd.h(123) : __w64 unsigned long ULONG_PTR'
1> or 'c:\documents and settings\tribble\my documents\vc32\test\debug\dte80a.tlh(463) : EnvDTE::ULONG_PTR'
1> c:\program files\microsoft visual studio 8\vc\atlmfc\include\cstringt.h(2505) : while compiling class template member function 'bool ATL::CStringT<BaseType,StringTraits>::CheckImplicitLoad(const void *)'
1> with
1> [
1> BaseType=char,
1> StringTraits=StrTraitMFC_DLL<char>
1> ]
1> c:\program files\microsoft visual studio 8\vc\atlmfc\include\afxstr.h(83) : see reference to class template instantiation 'ATL::CStringT<BaseType,StringTraits>' being compiled
1> with
1> [
1> BaseType=char,
1> StringTraits=StrTraitMFC_DLL<char>
1> ]
|
|
|
|
|
Yes. It is possible to mix ATL and MFC but it can be very tricky. It's a few years since I did any of this, ATL 3.0 and MFC 4.2 in those days. It worked best if you approached it from the ATL point of view. As in start with an ATL based app and add MFC code to it rather than the other way around.
Nothing is exactly what it seems but everything with seems can be unpicked.
|
|
|
|
|