|
Hi Bob,
1.
I am not sure where you have put the Sleep stuff; if it is inside a handler (button click, paint,...)
then it won't help you, since that would cause the GUI thread to sleep, i.e. not do anything for
as long as it takes.
2.
many years ago screen coordinates were only 15 or 16 bits effectively (even when their variables could hold more); I don't know what GDI currently accepts. so a wild guess could be your big rect is invalid, InvalidateRect accepts or maybe rejects it (look at its return value!),
and somehow Windows decides there still is nothing to update due to the invalid rect parameters.
If you doubt your coordinates, just use 0 for top and left, 30000 for bottom and right.
BTW, you should always test the return values, and especially when your code does not do what you would like to get...
|
|
|
|
|
Luc,
I put the Sleep calls in the thread that did the computation, not in the GUI thread. The idea was
to give the GUI thread a chance to catch up if it was behind. I also tried setting top and left to 0
with 30000 for bottom and right as you suggested. That did not help either. The methods InvalidateRect and UpdateWindow are void so there are no return values to check.
However, I now believe I understand what the problem was. I was defining a local variable of
type CPaintDC. When the constructor for CPaintDC is called, it was clearing the invalid region. In addition, sitting bottom past the bottom of the screen results in Windows setting it to the bottom of the screen. Now, I can solve my problem of my screen flickering.
Luc, thanks for your help in this matter.
Bob
|
|
|
|
|
Hi Bob,
You're welcome; I am glad I could be of some help.
Could you please show us the relevant code now it is working, similar to what you had here.[^] Thanks.
|
|
|
|
|
Luc,
Here is my working code:
LRESULT
CMainWin::ReportASuccess(WPARAM wParam, LPARAM lParam)
{
successCount ++;
static RECT rect1;
rect1.top = 300;
rect1.bottom = 30000;
rect1.left = 0;
rect1.right = 30000;
this->InvalidateRect( &rect1, 0 );
this->UpdateWindow();
return 0;
}
LRESULT
CMainWin::ReportAFailure(WPARAM wParam, LPARAM lParam){
failCount ++;
static RECT rect1;
rect1.top = 200;
rect1.bottom = 30000;
rect1.left = 0;
rect1.right = 30000;
this->InvalidateRect( &rect1, 0 );
this->UpdateWindow();
return 0;
}
afx_msg void CMainWin::OnPaint()
{
RECT rec1;
int retValue = this->GetUpdateRect( &rec1 );
if ( rec1.top == 200 ) {
char buffer1[512];
CPaintDC DC(this);
sprintf_s( buffer1, "Failed: %d ", failCount );
DC.TextOut( m_X, 200, buffer1 );
return;
}
if ( rec1.top == 300 ) {
char buffer1[512];
CPaintDC DC(this);
sprintf_s( buffer1, "Passed: %d ", successCount );
DC.TextOut( m_X, 300, buffer1 );
return;
}
CPaintDC DC(this);
DC.TextOutW( m_X, 50, TEXT("Other Text"), 11 );
DC.TextOutW( m_X, 100, TEXT("Other Text"), 11 );
.
.
.
You will notice that I do not erase the background when I call InvalidateRect. In addition, I checked in the debugger that the routine OnPaint was taking the right path.
Bob
|
|
|
|
|
Hi Bob,
thanks for sharing the code.
I do still have some remarks:
1. IMO not erasing the background will result in artefacts, such as old text still showing
under new text.
2. you still are not using the updaterect the way it is intended:
your OnPaint should not test for boundaries being equal, it should basically consist of a
series of this pseudocode:
if (theRectThing1Affects.overlaps.with.updateRect) paint.thing1.in.theRectThing1Affects;
if (theRectThing2Affects.overlaps.with.updateRect) paint.thing2.in.theRectThing2Affects;
if (theRectThing3Affects.overlaps.with.updateRect) paint.thing3.in.theRectThing3Affects;
And of course you then should use real heights, i.e. adjust the rect1.bottom values.
The way you have it just may still cause a dirty window when an overlapping window with top==200
(or 300) gets removed.
|
|
|
|
|
Luc,
Your first point is valid, therefore, I am planning on writting some extra spaces accross the
row when I do the update. If I calls InvalidateRect with the erase option, the text appears to
blink. This is something I do not want.
On your second point, I agree with you that my OnPaint routine needs to be a little smarter. I am plan on working on these today and tommorow. I have a small test program that actually works. If you want me to, I can upload it. Just tell me where.
Bob
|
|
|
|
|
Hi Bob,
to reduce flickering, you should make the invalid rect as small as possible, so if the text
is much narrower than your window, try to give reasonable horizontal coordinates as well.
however, if your update frequency is many times per second (if your app is erasing and painting more than it is calculating something), then anything you erase will cause flickering, since erasing takes almost the same time as painting does, hence the text is disappearing and re-appearing all the time, which is always noticeable, unless...
There basically are two rather drastic remedies:
1.
reduce the screen refresh rate; one way I like to apply is perform the calculations without updating the screen; and have a timer periodically (say twice per second) update the screen,
that is sufficient to show progress, but is much less disturbing, since the time your text
is erased now is only a fraction of 1 percent, hardly noticeable. The added advantage is
your performance will be better (more calculations and fewer screen actions per second).
2.
The other approach is to use double-buffering, which basically means that the entire form (or some
part of it) is first erased and painted in memory, then that memory bitmap gets copied to the screen replacing what is there (hence no erase and minimal visual disturbance).
I cannot provide you with any details; I use it quite often in .NET, where it requires no effort
at all, however I do not know how complex it is in GDI.
And it can make sense to combine it all: invalidate only what is needed, apply double-buffering,
and lower the update frequency.
As for code, I don't need it right now; if you make significant further progress, I am still
interested to learn the details; then we can exchange email addresses and send a zip.
Regards,
|
|
|
|
|
Luc,
I have my small program working the way I like it. I would be happy to send it to you, if you
want me to.
Bob
|
|
|
|
|
I now have an easy fixed for this problem. When you are doing the update, you call
CWnd::Invalidate with an argument of 0. In this case, the 0 stands for false and
Windows will not earse the screen. In addition, the window will not flicker.
Bob
modified on Monday, December 29, 2008 3:09 PM
|
|
|
|
|
Write a program that will read a list of numbers and a desired sum,then determine subset of numbers in the list that yield that sum if such a subset exists.
|
|
|
|
|
Hi,
I have two hints for you:
1. A program quite often is just a recipe that explains to a computer how a human person (with
lots of accuracy, courage, and perseverance) would solve the given problem.
2. Recursion normally gets used to replace a single problem by one or several smaller problems.
That should be sufficient.
|
|
|
|
|
Running on Windows XP sp2, with IE7, I notice that when I use the web browser component and call Navigate() with a res url (i.e. something like res://c:\some\path\to\program\program.exe/stuff.html) that it no longer opens the embedded html resource.
Either I get a dialog (I think from IE) complaining about an unknown file type "stuff" and "Navigation to the webpage was canceled" in the browser view, or I just see "This page cannot be displayed" in the browser view. This is used to all work fine, and now it doesn't.
The rc file looks something like this:
STUFF.HTML HTML DISCARDABLE "res\\stuff.html"
The url passed to Navigate (in this example) would be "res://c:\\some\\path\\to\\program\\program.exe/stuff.html". The dialog error (in the first case) makes me think that somehow the stuff.html is getting truncated and the ".html" is getting lost. Is there some new problem with this, as I never had a problem before? I notice that if you change the URL to "res://c:\\some\\path\\to\\program\\program.exe/stuff" (i.e. drop the .html part) then it works.
¡El diablo está en mis pantalones! ¡Mire, mire!
Real Mentats use only 100% pure, unfooled around with Sapho Juice(tm)!
SELECT * FROM User WHERE Clue > 0
0 rows returned
Save an Orange - Use the VCF!
VCF Blog
|
|
|
|
|
Just a hunch, but:
I think it may have something to do with the fact that immediately preceding the "/stuff.html" is a path element called "program.exe".
The fact that there is a dot after "program" may be confusing the parser to think that everything after the dot is the file type.
What do you think?
|
|
|
|
|
I'm not sure. According to MSDN and other docs I found, that is supposed to be the format, i.e.
res://fully-qualified-exe-filename/resource-name
¡El diablo está en mis pantalones! ¡Mire, mire!
Real Mentats use only 100% pure, unfooled around with Sapho Juice(tm)!
SELECT * FROM User WHERE Clue > 0
0 rows returned
Save an Orange - Use the VCF!
VCF Blog
|
|
|
|
|
You're probably right.
It was just a first thought.
|
|
|
|
|
no prob. Interestingly enough I just tried this with an older version of IE and it works perfectly, so it's definitely an issue with IE7, some subsequent patch to IE7, and/or some related windows component. Joy.
¡El diablo está en mis pantalones! ¡Mire, mire!
Real Mentats use only 100% pure, unfooled around with Sapho Juice(tm)!
SELECT * FROM User WHERE Clue > 0
0 rows returned
Save an Orange - Use the VCF!
VCF Blog
|
|
|
|
|
I looked into the htm file I once used for an HTML Dialog box in MFC.
It uses a resource graphic, and it specifies the graphic name as:
src="res://Program.exe/#2/#133"
If I recall correctly, the #2 indicates the resource TYPE, such as bitmap, and the #133 represents the exact resource identifier.
Try that type of res URL, and see if it works.
You'll have to determine the correct number for the resource type of HTML.
|
|
|
|
|
res Protocol
--------------------------------------------------------------------------------
Specifies a resource that will be obtained from a module.
Syntax
res://sFile[/sType]/sID
Tokens
sFile
Path and file name of the module that contains the resource.
sType
Optional. String or numerical resource type. This can be either a custom resource or one of the RT_ predefined resource types described in the FindResource function reference. If a numerical resource type is specified, the actual number of the identifier, not the identifier name, must follow a # character. See the example for more information. If this parameter is not specified, the default resource type is RT_HTML.
sID
String or numerical identifier of the resource. If a numerical identifier is specified, the actual number of the identifier, not the identifier itself, must follow a # character. See the example for more information.
Remarks
Available as of Microsoft Internet Explorer 4.0 or later.
Remember, URLs require that special characters such as '#' be escaped. Use '%23' to escape the '#' character.
Note Internet Explorer 6 Service Pack 1 (SP1) no longer allows browsing a local machine from the Internet zone. For instance, if an Internet site contains a link to a local file, Internet Explorer 6 SP1 displays a blank page when a user clicks on the link. Previous versions of Internet Explorer followed the link to the local file.
Example
This example shows the correct and incorrect ways to format the numerical identifier for the resource type.
#define MYBITMAP 234
// This is correct.
"res://mydll.dll/#2/#234"
// This is not correct.
"res://mydll.dll/#2/MYBITMAP"
|
|
|
|
|
Hi all.
I am trying to create a simple magnifier application which follows the mouse and magnifies the portion around the mouse cursor. I know how to get a screenshot of a desktop. I have tried GDI way and DirectX9 Surface way, but DX surface is too slow for realtime capturing. So I am staying with GDI.
The problem is - when I get a screenshot my magnifier application is included, too. I tried to GetNextWindow and GetFocus to get HDC only for the active window and then render HDC into memory DC. But it is a nightmare - some applications have multiple windows so I get only one of them and the other part of the shot is a mess (from previous shots). I guess it would be really hard to get DC for every window beneath my own and to combine all the DC images myself. Brrr...
One approach could be to hide my app, capture screen, restore my app. But it is not suitable for realtime work.
Of course, I know that Windows keeps track of window clipping regions so area behind my window would not be updated in other windows WM_PAINT. But I think I can force it to render if I use WS_EX_LAYERED style and 99% visibility for my app - then Windows invalidates area even behind my window. Of course, I can remove CAPTUREBLT flag from BitBlt when capturing and then I won't get my window because all layered windows would be ignored. But then I do not get any of the layered windows (like tooltips etc.).
I know that Vista Magnification API can do the trick but it does not work on XP
So the problem is - how can I virtually "erase" my app from the screenshot and get area behind it?
Thanks for any ideas.
modified on Friday, December 26, 2008 9:45 AM
|
|
|
|
|
Hi All
I have a problem to get GetClipboard data?I have a code which is working fine for copy data.I read all data which is copy from system.But problem is when i use Cut option then i am geting NULL Data.Plz help me
LPDATAOBJECT pDO;
TCHAR szPath12[MAX_PATH];
HRESULT hr = OleGetClipboard(&pDO);
FORMATETC fmt = {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
STGMEDIUM stgm;
hr = pDO->GetData(&fmt, &stgm);
if(S_OK == hr)
{
UINT nFiles = DragQueryFile((HDROP)stgm.hGlobal, -1, NULL, 0);
int i = 0;
for( i = 0; i < nFiles; i++)
{
ij=1;
DragQueryFile((HDROP)stgm.hGlobal, i, szPath12, MAX_PATH);
szPath12;
}
ReleaseStgMedium(&stgm);
}
pDO->Release();
|
|
|
|
|
Hi
I am getting the error show below.This is the linker error and i am not able to resolve it.I am afraid that I am giving improper selection in the Properties.
Kindly help me out.
1>AltABFUtil.obj : warning LNK4075: ignoring '/EDITANDCONTINUE' due to '/INCREMENTAL:NO' specification
1>msvcprt.lib(MSVCP80.dll) : error LNK2005: "class std::basic_string<char,struct>,class std::allocator<char> > __cdecl std::operator+<char,struct>,class std::allocator<char> >(class std::basic_string<char,struct>,class std::allocator<char> > const &,class std::basic_string<char,struct>,class std::allocator<char> > const &)" (??$?HDU?$char_traits@D@std@@V?$allocator@D@1@@std@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@ABV10@0@Z) already defined in abflib.obj
1>msvcprt.lib(MSVCP80.dll) : error LNK2005: "class std::basic_string<char,struct>,class std::allocator<char> > __cdecl std::operator+<char,struct>,class std::allocator<char> >(class std::basic_string<char,struct>,class std::allocator<char> > const &,char const *)" (??$?HDU?$char_traits@D@std@@V?$allocator@D@1@@std@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@ABV10@PBD@Z) already defined in abflib.obj
1>LINK : warning LNK4098: defaultlib 'MSVCRTD' conflicts with use of other libs; use /NODEFAULTLIB:library
|
|
|
|
|
You are trying to link with two different versions of the C runtime library (MSVCRT). This usually occurs because you are linking with object code or a static library that was compiled against a different variant of the CRT.
Make sure that all of your code uses the same run-time library option (it's in the C/C++ compiler properties, in the Code Generation page).
|
|
|
|
|
It seems that you are using STL. The possibility is that the variable you are using in the AtlABFUtil.cpp is already been defined in abflib.cpp. Have you included abflib.cpp into atlABFUtil.cpp ? Can you post code snippet for more details ?
|
|
|
|
|
When trying to create CMDIChildWnd in a worker thread I get an ASSERT fails in winmdi.cpp:
if (pParentWnd == NULL)
{
CWinThread *pThread = AfxGetThread();
ASSERT(pThread);
CWnd* pMainWnd = pThread->m_pMainWnd;
ASSERT(pMainWnd != NULL);
ASSERT_KINDOF(CMDIFrameWnd, pMainWnd);//****this line fails
pParentWnd = (CMDIFrameWnd*)pMainWnd;
}
S I guess the parent window is not being set correctly. How can this be set?
|
|
|
|
|
You *have* to create the child window in the same thread its parent was created on. My usual rule is to keep *all* windowing operations within one thread. If you need to create a window in response to an event in a worker thread, post a message across from the worker thread to the main UI thread (posting messages is allowed from worker threads to the UI thread).
|
|
|
|
|