|
Keith Rules CMemDC should work inside OnPaint() ...
Are you returning FALSE inside of OnEraseBkgnd() so you avoid redrawing the screen...?
"An expert is someone who has made all the mistakes in his or her field" - Niels Bohr
|
|
|
|
|
As Chris said earlier I would use CreateCompatibleBitmap to create your bitmap compatible to the paint DC.
I also wanted to add, you could add the MemoryDC and your bitmap as a member variable to your window class and keep that around as long as your window exists, or at least is visible.
That way you would not have to recreate and initialize the memoryDC and bitmap for each paint message. There are a lot of them, and you would probably see an increase in your paint speed this way.
This would also make it possible for your update routine to paint to the backbuffer bitmap that you are creating and you could then have the bitmap blitted to the screen in your OnEraseBackground handler. This would move all of the code from your OnPaint handler BTW.
Build a man a fire, and he will be warm for a day Light a man on fire, and he will be warm for the rest of his life!
|
|
|
|
|
Thanks guys but...
When I tried using CreateCompatibleBitmap I got a monochrome bitmap for some reason, I might look into that again later though.
Hockey suggested it might be my OnEraseBkgnd, I had to manually add the OnEraseBackground handler and force it to return FALSE but it didn't alter anything.
BUT his idea did put me on the right track, in my OnTimer even I was calling Invalidate() instead of Invalidate(FALSE).
I already made the other suggestions you made earlier today, storing memDC and bitmap as member variables.
I have one more question though.
Back in the old days when I was using one of the Gnu C compilers instead of bitblitting the backbuffer to the front buffer I'd just swap them round.
So the backbuffer became the screens bitmap and the screens bitmap became the backbuffer for the next drawing cycle.
I've had a quick go at it but it doesn't work. :-/
Like using this instead of a dc.bitblt() statement.
if(usingBack){
dc.SelectObject(backBuffer);
usingBack = false;
}else{
dc.SelectObject(originalBuffer);
usingBack = true;
}
I have a funny feeling it's just not possible to do that though.
Damn I just realised I wasn't selecting the alternative bitmap into the memDC so it'd draw onto that, I'll have to go and do some more work on this...
|
|
|
|
|
David_Jenkins wrote:
So the backbuffer became the screens bitmap and the screens bitmap became the backbuffer for the next drawing cycle.
You cannot select a bitmap into a window DC, that is why that does not work, although it would be cool.
Anyway, when you use CreateCompatibleBitmap, you need to use the WindowDC when you are creating a CompatibleBitmap. That is because right after you create your MEMDC, its bit plane depth is set to 1, and if you use that DC, your bitmap will be set to 1 as well. So the process to create a good bitmap and memdc is this:
<br />
CPaintDC dc;<br />
<br />
CBitmap bitmap;<br />
bitmap.CreateCompatibleBitmap(dc);<br />
<br />
CDC memDC;<br />
memDC.CreateCompatibleDC(dc);<br />
memDC.SelectObject(bitmap);<br />
I may not have the syntax or all of the paramaters correct, but you will need to do something relatively close to this.
By moving all of your painting code to the OnEraseBkgnd handler, you will be able to free your paint routine to only do special add on painting that cannot or should not be placed into your cached bitmap.
Good Luck
Build a man a fire, and he will be warm for a day Light a man on fire, and he will be warm for the rest of his life!
|
|
|
|
|
Nice one, Thanks Paul!!
Switching to using the CreateCompatibleBitmap has increased the speed of the BitBlt function, I assume previously it was having to convert the one I made into one compatible with the windows bitmap thus slowing it down drastically.
Thanks again!
|
|
|
|
|
If I have a structure in CMainFrame how can I access it from another view..
inside my view I tried...
CMainFrame* pMain = (CMainFrame*)AfxGetMainWnd();
pMain->m_MyStruct pStruct;
Gives me a error..
error C2273: 'function-style cast' : illegal as right side of '->' operator
|
|
|
|
|
Sort of this:
CMyMainFrame* pMain = (CMyMainFrame*)AfxGetMainWnd();
MyStruct * pStruct=&pMain->m_MyStruct; or, if you want to save yourself a lot of -> s:
CMyMainFrame* pMain = (CMyMainFrame*)AfxGetMainWnd();
MyStruct& myStruct=pMain->m_MyStruct;
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
I guess I am kinda confused, the structure that I am trying to access is declared in CMainFrame.. so do i need to create an identical structure in my view then use the code that you posted?
By the way, thanks for the super fast response
|
|
|
|
|
so do i need to create an identical structure in my view then use the code that you posted?
No. In the first snippet I posted, a pointer to the structure inside your CMainFrame is declared and set. No duplication is made, you access the one and only structure through the pointer.
As for the second snippet, it does basically the same but using references instead of pointers. If you don't know what references are, use the first form (though it is advisable that you learn about C++ references in some C++ tutorial).
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Thanks again.. but in the code you posted..
MyStruct * pStruct=&pMain->m_MyStruct;
What is MyStruct?
Maybe its how i created the structure in CMainFrame.. am I doing something wrong?
struct m_MyStruct
{
CString strA;
CString strB;
CString strC;
CString strD;
int iA;
int iB;
};
|
|
|
|
|
The following works perfectly.. Is there a problem doing it this way??
CMainFrame* pMain = (CMainFrame*)AfxGetMainWnd();
CMainFrame::m_MyStruct* pFriend;
Thanks!
Mr.Anonymous
|
|
|
|
|
Hey,
Its a pretty simple idea really, I'm trying to make a file searcher thats uses a worker thread to do the searching so the user can hit cancel at any time and it won't hang the program. So far the thread is working, it will search and add a list of all the files I want into a CStringArray, but the problem is that I need to use this CStringArray in the main program so it can store the list.
A brief code summary is <br />
---To begin the Thread---<br />
CWinThread* pThread = AfxBeginThread(ListFunc,this);<br />
HANDLE hThread = pThread->m_hThread;<br />
WaitForSingleObject(hThread,INFINITE);<br />
<br />
---To get the search running---<br />
UINT ListFunc(LPVOID pParam)<br />
{<br />
CMyDlg* local = (CMyDlg*)pParam;<br />
local->BuildFileList(local->m_startDir);<br />
return 0;<br />
}<br />
<br />
---To do the actual searching---<br />
void CMyDlg::BuildFileList(CString startingDir)<br />
{<br />
chdir(startingDir);<br />
CFileFind finder;<br />
BOOL bWorking = finder.FindFile();<br />
int counter = 0;<br />
CStringArray pathArray;<br />
pathArray.SetSize(500,500);<br />
<br />
while (bWorking && running)<br />
{<br />
bWorking = finder.FindNextFile();<br />
<br />
if (finder.IsDots())<br />
continue;<br />
<br />
if (finder.IsDirectory())<br />
{<br />
CString str = finder.GetFilePath();<br />
TRACE("str = %s\n",str);<br />
BuildFileList(str);<br />
}<br />
<br />
CString temp = finder.GetFilePath();<br />
if(temp.Find(".wav",0)!= -1)<br />
{<br />
TRACE("Found wav file = %s\n",temp);<br />
temp.Delete(0,(m_startDir.GetLength()+1));<br />
TRACE("wav file now is = %s\n",temp);<br />
pathArray[counter] = temp; <br />
}<br />
filePathArray[counter] = pathArray[counter];<br />
counter++; <br />
}<br />
noOfFiles = counter+1;<br />
filePathArray.Copy(pathArray); <---- Heres the problem as I see it<br />
finder.Close();<br />
}<br />
The problem as far as I know is the filePathArray.Copy function near the end. The filePathArray is a CStringArray defined in the actual Dlg class that I want to store all of the details. But as it is, when the thread ends after a
WaitForSingleObject(hThread,INFINITE);
The filePathArray is empty Does anyone know where I'm going wrong with this thing before I go slightly loopy? At one point I had it copying a list of stuff I didn't want (a list of files in a dir, not .wav files) but I cannot get it to copy anything at all now.
Thanks for looking lads
|
|
|
|
|
Try replacing Copy with Append .
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
hehe, thanks Joaquin, again you're first to chip in an answer
I'll give that a try as soon as I work out the bigger problem I just noticed. Its amazing what you can find out if you add small bits to a TRACE statement. Just found out that when it searches a new directory it resets the counter to 0 so I think I need to fix that first
|
|
|
|
|
Just tried it, as well as fixing my counter messup that Append did the trick.
Thanks again
|
|
|
|
|
Hi!
I need to create a listview where each row would be multiline i.e. each row would have a normal look with an item for each column and another row (a single line) where I couls display some text... The two lines would actualy be ONE item in the list.
I've read many tutorials and many forum threads but nothing seems to do what I really want.
Does anybody know how to do that? I could be a little more clear if necessary...
-------------
-= Nasty_p =-
|
|
|
|
|
CListCtrl provide multicolumn functionality (referred to as items and subitems). Is this what you're after?
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Yes... But I want to know how to do something like this:
|Column 0|Column 1|Column 2|Column 3|
-------------------------------------
| item 1 | item 1 | item 1 | item 1 |
-------------------------------------
| Text related to item 1... |
-------------------------------------
| item 2 | item 2 | item 2 | item 2 |
-------------------------------------
| Text related to item 2... |
-------------------------------------
etc...
-------------
-= Nasty_p =-
|
|
|
|
|
I see... Well, seems like neither CListCtrl nor any of the various grid controls around the net can do this in a easy way.
Maybe this is a solution for your particular problem: CListBox provides a very primitive pseudocolumn facility, by which a string can be displayed as if composed of several substrings tabulated at fixed positions (see CListBox::SetTabStops ), each substring being marked by a '\t' character. Maybe you can mix '\t' -tabulated rows with regular rows to achieve a result similar to what you need.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Can't there be a better way to do so?
I saw a lot of embended "tree control in a listview" but I don't wanna use trees...
-------------
-= Nasty_p =-
|
|
|
|
|
So embed a CListCtrl or CComboBox instead...
"An expert is someone who has made all the mistakes in his or her field" - Niels Bohr
|
|
|
|
|
Easier said than done.... I'm still just a MFC novice...
I'll try though...
Thanx!
-------------
-= Nasty_p =-
|
|
|
|
|
This sounds like what you want:
http://www.codeproject.com/miscctrl/reportctrl.asp[^]
Shog9
------
No one's immune now, from a world of problems
No one's exempt now, from a world of pain
That's the way that it goes
when you're down here with the rest of us...
|
|
|
|
|
YES!!!!
Thanx!!!!
-------------
-= Nasty_p =-
|
|
|
|
|
Hi, I am trying to get a CFileDialog to display having overridden the default implementations of OnFileSaveAs(). My problem is that when CFileDialog::DoModal() is called by my app an access violation occurs.
The funny thing is, no Windows messages are generated to show me this - the only way it is detectable is by running the app from within the debugger at which point I am told in a message box that an access violation has occurred in KERNEL32.DLL when I attempt to display the dialog. I am quite sure I am supplying the correct parameters to the constructor, and if I try to display the Dialog in the same way from a new app everything works fine.
This has confused me for hours now. It seems strange that there are no assertion faliures, and even that when it occurs when the app is not run from within the debugger no messages are displayed - the app just quits!
Any, Any help would really be appreciated as I am close to losing what little hair I have left over this.
Cheers, Alex.
|
|
|
|