|
I follow your reasoning, and it does seem completely reasonable.
The only thing is, I don't see why BitBlt() is /allocating/ memory. As far as I was aware, BitBlt only copies blocks of memory.
I /am/ allocating larger bitmaps as the window size increases, but that's done outside of the code I'm profiling. Here's how I'm profiling the code:
<------------------SNIP---------------------->
#ifdef _DEBUG
LARGE_INTEGER time4;
VERIFY( ::QueryPerformanceCounter( &time4 ) );
#endif
m_memDC.BitBlt( 0, 0, m_iScreenWidth, clientRect.Height(), &m_decorationsMemDC, 0, 0, SRCAND );
#ifdef _DEBUG
LARGE_INTEGER time5;
VERIFY( ::QueryPerformanceCounter( &time5 ) );
#endif
...
...
...
TRACE( " m_memDC.BitBlt( 0, 0, %i, %i, &m_decorationsMemDC, 0, 0, SRCAND ) ] took %f\tmilliseconds\n"
, m_iScreenWidth, clientRect.Height(), ((time5.QuadPart - time4.QuadPart)/(double)freq.QuadPart)*1000 );
<------------------SNIP---------------------->
As you can see, the only thing I'm timing is that one call to BitBlt(...), so it's definitely something within that method that's slowing down.
One thought I had was that maybe BitBlt() is doing some behind-the-scenes allocation for some reason? Or perhaps there's some lazy-initialization going on where the CBitmaps attached to my CDCs only allocate memory when needed, in this case somewhere within BitBlt(). That doesn't really make sense though - I'm drawing into the source CDC before the guilty BitBlt() call (and presumably the memory would have to be allocated then), and I call
m_memDC.BitBlt( 0, 0, m_iScreenWidth,
clientRect.Height(), NULL, 0, 0, WHITENESS );
earlier as well, so as far as I can tell both the source and destination DCs' CBitmaps should already be allocated when that slow call BitBlt() happens.
Strange, no? Anyways, thanks once again for your help. If you have any further thoughts, obviously I'd love to hear them!
Cheers,
Pete
|
|
|
|
|
What is the value for rcClipBox if you call
CRect rcClipBox;
m_memDC.GetClipBox(rcClipBox);
TRACE("l: %d, t: %d, r: %d, b: %d",
rcClipBox.left, rcClipBox.top,
rcClipBox.right, rcClipBox.bottom);
just prior to each BitBlt call?
Pssst. You see that little light on your monitor? That's actually a government installed spy camera. Smile and wave to big brother!
|
|
|
|
|
C2DTrajWindow::UpdateVirt:
ClipBox - l: 0, t: 0, r: 1280, b: 740
m_memDC.BitBlt( 0, 0, 1280, 740, &m_decorationsMemDC, 0, 0, SRCAND ) ] took 617.089323 milliseconds
C2DTrajWindow::UpdateVirt:
ClipBox - l: 0, t: 0, r: 1280, b: 748
m_memDC.BitBlt( 0, 0, 1280, 748, &m_decorationsMemDC, 0, 0, SRCAND ) ] took 1.938794 milliseconds
C2DTrajWindow::UpdateVirt:
ClipBox - l: 0, t: 0, r: 1280, b: 750
m_memDC.BitBlt( 0, 0, 1280, 750, &m_decorationsMemDC, 0, 0, SRCAND ) ] took 628.530162 milliseconds
C2DTrajWindow::UpdateVirt:
ClipBox - l: 0, t: 0, r: 1280, b: 760
m_memDC.BitBlt( 0, 0, 1280, 760, &m_decorationsMemDC, 0, 0, SRCAND ) ] took 1.418616 milliseconds
|
|
|
|
|
OK, how about the clipbox values for m_decorationsMemDC?
Pssst. You see that little light on your monitor? That's actually a government installed spy camera. Smile and wave to big brother!
|
|
|
|
|
Hi Jack,
Pretty much the same story:
<---------------------SNIP----------------------->
C2DTrajWindow::UpdateVirt:
m_memDC's ClipBox - l: 0, t: 0, r: 1280, b: 807
m_decorationsMemDC's ClipBox - l: 0, t: 0, r: 1280, b: 807
m_memDC.BitBlt( 0, 0, 1280, 807, &m_decorationsMemDC, 0, 0, SRCAND ) ] took 684.505154 milliseconds
C2DTrajWindow::UpdateVirt:
m_memDC's ClipBox - l: 0, t: 0, r: 1280, b: 809
m_decorationsMemDC's ClipBox - l: 0, t: 0, r: 1280, b: 809
m_memDC.BitBlt( 0, 0, 1280, 809, &m_decorationsMemDC, 0, 0, SRCAND ) ] took 2.769346 milliseconds
C2DTrajWindow::UpdateVirt:
m_memDC's ClipBox - l: 0, t: 0, r: 1280, b: 812
m_decorationsMemDC's ClipBox - l: 0, t: 0, r: 1280, b: 812
m_memDC.BitBlt( 0, 0, 1280, 812, &m_decorationsMemDC, 0, 0, SRCAND ) ] took 683.831325 milliseconds
C2DTrajWindow::UpdateVirt:
m_memDC's ClipBox - l: 0, t: 0, r: 1280, b: 815
m_decorationsMemDC's ClipBox - l: 0, t: 0, r: 1280, b: 815
m_memDC.BitBlt( 0, 0, 1280, 815, &m_decorationsMemDC, 0, 0, SRCAND ) ] took 2.098870 milliseconds
<---------------------SNIP----------------------->
Cheers,
Pete
|
|
|
|
|
<ctrl><alt> Have you ever look at how many processes might be running on you machine at one time. BitBlt() is like every other piece of code running on youre machine, it is a matter of priority (every body gets a slice of the processors time [at least they are supposed to]). I discover a virus once, becuase I notice that processor time was being eatin (slow down in resonse time).
May be someone can give you an idea for improving the speed if you explained why the graph is rendered in pieces, instead of as a whole.
INTP
"The more help VB provides VB programmers, the more miserable your life as a C++ programmer becomes."
Andrew W. Troelsen
|
|
|
|
|
hai..
I'm working on win32 vc++..I want to know waht is the window message that is processed when the window is maximized and minimized..
thanks.
|
|
|
|
|
Look at WM_SIZE.
wParam = SIZE_MAXIMIZED, SIZE_MINIMIZED, SIZE_RESTORED, etc.
lParam = cx -> lo word cy -> hi word
Hope this helps.
|
|
|
|
|
Is thera any way for
int a = 5;
int b;
b's memory address point to a's?
so &b would equal to &a.
Or the only way is create a pointer to do it
int a = 5;
int *b;
b = &a;
|
|
|
|
|
Or the only way is create a pointer to do it
me think yes.
Maximilien Lincourt
Your Head A Splode - Strong Bad
|
|
|
|
|
Isn't a pointer just a long integer anyways? I didn't try this, but I don't see a reason why a long int couldn't hold an address...it doesn't care if it's an address...as long as it is a value which matches its type.
I don't know why you'd do this though...that's what pointers are for...
|
|
|
|
|
This will break 64 bit code (AMD64) where pointers are 64 bits and integers are 32 bits.
John
|
|
|
|
|
I believe you could use references for this:
int a = 5;
int &b = a;
a = 500; //now a == 500 AND b == 500
b = 1234; //now a == 1234 AND b == 1234
I'm not totally sure that's right though, you should probably step through the code in a debugger and check.
Hope that helps,
Pete
|
|
|
|
|
I stand corrected, forgot about references.
int a = 5;
int &b = a;
in that case, &a == &b ( the address of a and b are the same).
Maximilien Lincourt
Your Head A Splode - Strong Bad
|
|
|
|
|
Thanks. I totally forgot about that one
How would I go about so b's memory address would point to a's memory address?
class CFirst(){
private:
int a;
public:
CFirst(){ a = 25; };
int ReturnA(){ return(a); };
};
class CSecond(){
private
int b;
};
int main(){
CFirst a;
return 0;
}
The stuff I am doing is a little bit more complex. I want to point b's link list data to a's link list's data and then remove the la ink list(without destroying the data)
|
|
|
|
|
You know, you really should join up and sign in if you want people to help you out Membership is the key...
Anyway, something along these lines might point you in the right direction:
class CFirst
{
...
...
public:
int &GetReferenceToA()
{ return a; }
...
...
}
class CSecond
{
public:
class CSecond( int &numberToAttachTo )
: b( numberToAttachTo )
{}
protected:
int &b;
};
int main()
{
CFirst instanceOfFirst;
CSecond instanceOfSecond( instanceOfFirst.GetReferenceToA() );
...
...
}
I don't know how much that helps. There would be quite a few ways of initializing the 'connection' between a and b.
One thing to note is that any member variables of CSecond() that are references MUST be initailized at construction time. This makes them more fiddly to use than pointers, IMHO.
HTH,
Pete
|
|
|
|
|
The stuff I am doing is a little bit more complex. I want to point b's link list data to a's link list's data and then remove the la ink list(without destroying the data)
you can't really do that, at least the way I think you want to do it.
if your data ( a or b ) are not dynamically allocated ( new or malloc ) , then, you will need to copy the data; and passing a reference a to b and then removing a will invalidate b ( at best ).
in your example, ReturnA copies the data.
but for example, if your CFirst looks like :
class CFirst {
int* a; // will be allocated and assigned.
int* ReturnA( return a;};
}
then, you return the address of a to whoever receives it;
int* b = ReturnA();
but you will need to keep track of allocation and deallocation.
Maximilien Lincourt
Your Head A Splode - Strong Bad
|
|
|
|
|
I have an account I just keep forgetting to log in.
int* ReturnA(){ return a;};
doesn't work.
I have been trying to get function to return pointer
Nevermind I am an idiot. Forgot to add () when I call the function
You can't assign &b on the fly right? Only at the intitalization.
|
|
|
|
|
You could create a 'reference'. A reference variable is somewhat like a mix between a pointer and a copy variable. References are much like synonymes with same type.
For example:
int A = 5;
int& B = A; Now both &A and &B operations return the same value, A's address. If A is changed, B changes, and vice versa. In syntactical terms, however, they are the same thing. Same thing (an integer variable) with two seperate names.
-Antti Keskinen
----------------------------------------------
"If we wrote a report stating we saw a jet fighter with a howitzer, who's going to believe us ?"
-- R.A.F. pilot quote on seeing a Me 262 armed with a 50mm Mauser cannon.
|
|
|
|
|
I only saw part of the other answers! But...
-----------------------------------------------------------------------------
int A = 5; // declared and intialized
int *pB = &A; // ponter to int declared and intialized to address of A
// pB is an inderect reference to A, which means it holds the address of A
// &A is the address of A (aka. indirect reference)
// *pB is a dereferncenced pointer (aka. direct reference)
int &C = A; // direct reference declared and intialized
// C and A are both references to the same data (memory location)
// Therefor, &A = pB = &C and A = *pB = C.
-----------------------------------------------------------------------------
Thats it, in a nut shell.
-----------------------------------------------------------------------------
It seems complicated, don't it. Given time it will become second nature to you.
-----------------------------------------------------------------------------
This might help:
#include <stdio.h>
int main(void)
{
int A = 5;
int *pB = &A;
int &rC = A;
prinf(
"Address of A = %p, Value of A = %d\n"
"Address of pB = %p, Address stored in pB = %p, Value of *pB = %d\n"
"Address of rC = %p, Value of rC = %d\n",
&A, A,
&pB, pB, *pB,
&rC, rC);
return 0;
}
I have not tested the code above, but is should give you an idea of the relationships between pointers and references.
INTP
"The more help VB provides VB programmers, the more miserable your life as a C++ programmer becomes."
Andrew W. Troelsen
|
|
|
|
|
can we create a rich colored icon - i.e. 256 colors or more - for VC?
includeh10
|
|
|
|
|
hi,
you can, but not with resource editor supplied with VC.
GSte
|
|
|
|
|
Is it possible to use the standard CFileDialog, and dynamically hide certain controls before it is displayed? I am able to create a hook function to trap the WM_NOTIFY/CDN_INITDONE message sequence, but cannot seem to grab the handles for the controls on the dialog at this stage. Can anyone enlighten me?
I've tried several different versions of the following code, to no avail. What am I doing wrong?
CString CCustomizedDialog::GetFolder()
{
OPENFILENAME ofn;
memset(&ofn, 0, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = NULL; //or any valid parent window handle.
ofn.hInstance = AfxGetInstanceHandle(); //or your hinstance variable if you are not using mfc support.
ofn.lpstrFilter = _T("Text Files\0*.txt\0\0"); //modify this for any other filter.
ofn.lpstrCustomFilter = NULL;
ofn.nFilterIndex = 0;
ofn.lpstrFile = new TCHAR[256];
memset(ofn.lpstrFile, 0, 256 * sizeof(TCHAR));
ofn.nMaxFile = 256;
ofn.lpstrFileTitle = NULL;
ofn.lpstrInitialDir = NULL;
ofn.lpstrTitle = NULL;
ofn.Flags = OFN_EXPLORER | OFN_ENABLEHOOK | OFN_ENABLETEMPLATE;
ofn.lpfnHook = OFNHookProc; //Custom hook procedure.
ofn.lpTemplateName = MAKEINTRESOURCE(FILEOPENORD);
GetOpenFileName(&ofn);
CString theReturnString = ofn.lpstrFile;
delete [] ofn.lpstrFile;
return theReturnString;
}
//Custom hook procedure stub. Must remain outside of the class
UINT CALLBACK OFNHookProc(
HWND hdlg, // handle to child dialog box
UINT uiMsg, // message identifier
WPARAM wParam, // message parameter
LPARAM lParam // message parameter
)
{
// set a flag so we know when the dialog has been initialized
static BOOL isInitialized;
CEdit* theEditBox;
//Do your message processing here.
//Return 0 if you need the default dialog box procedure to process
switch (uiMsg)
case WM_NOTIFY:
{
AfxMessageBox("Notify was caught!");
if(isInitialized == TRUE)
{
HWND theParent = GetParent(hdlg);
if(theParent != NULL)
{
theEditBox = (CEdit*)GetDlgItem(theParent,edt1);
theEditBox->SetWindowText(_T("Readme.txt"));
}
}
/// catch CDN_INITDONE message so we can
/// change the look of the dialog
if(((OFNOTIFY *)lParam)->hdr.code == CDN_INITDONE)
{
AfxMessageBox("INITDONE was caught!");
isInitialized = true;
HWND theDlg = GetParent(hdlg);
CString theMsg = "The ParentHWND: ";
// theMsg += theDlg;
// AfxMessageBox();
}
}
return 0;
}
Thanks,
--Mark
|
|
|
|
|
You might consider using Spy++ to display the dialog and then get info on the control in question - this will give you the control's ID, which you could then use with the GetDlgItem() call, passing in the ID that Spy++ discovered.
¡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
|
|
|
|
|
Hi Jim,
Thanks for the quick reply. I think the problem is with getting a handle to the actual dialog on which the control is drawn. I have to pass this handle (I believe) to the GetDltItem() function. I have tried both the hdlg parameter, and GetParent(hdlg) in the hook function, but neither one seems to work. I have been looking at Spy++, and the handle I get for the actual dialog does not match either one of these...
I will look at it again, though. Thanks.
|
|
|
|
|