|
hello,
Why do CDC's created in functions other than OnDraw dont work good? The drawings made with these get eaten during scrolling.
How to avoid this?
I am desperate for the solution.
Heather
|
|
|
|
|
The reason: you draw something in other place than OnDraw, but when window is updated, OnDraw makes something else. Solution:
1) You keep some data which defines what should be drawn in the window (in Doc-View application this data is kept in CDocument class, in general case it can be in any place you want).
2) OnDraw draws window according to this data. Every time window is updated (for example, user minimizes and restores window), OnDraw redraws window according to current data state.
3) When data is changed as result of some user actions (such as scrolling or something else), you never redraw window directly. Instead of this you change your data and call:
Invalidate();
UpdateWindow();
After this Window calls your OnDraw() function and it redraws window in new state.
|
|
|
|
|
(adding to what Alex said)
device contexts acquired outside of OnDraw should be used only for retriving information (like "how many colors", or "how many pixels do I need for writing 'Ophelia' in Hamlet-Thin-12pt style")
|
|
|
|
|
One of my views contains a grid control. In this view I want to select one entry in the grid control. When the entry is selected and the user choose a menu item called:
"View details" I want to open a new view and show details from the selected entry.
The problem is that this new view doesn't know anything about what is selected in the grid control. Is there any way to access data from one view to another view?
|
|
|
|
|
hi there,
You could have been more elaborate.I'll try.
Its Simple. Just make a structure with all the parameters you need for display,initialise the structure data with datails and pass this structure to the concerned function.
Hope this works.
Mussanje
|
|
|
|
|
How can I pass this structure? I have one class for each view. CUnitView and CUnitDetailsView. UnitView contains a grid with all the units and unitdetailsview shows details about one specific unit. From unitdetailsview I can't know if an entry i selected in unitview....
|
|
|
|
|
What actually is the unit you are talking about? Is it just some number or an entity?
Be a bit more clear.
|
|
|
|
|
I have a table called unit in my database. The unit has a unique id and a name. All the units are listed in unitview.
|
|
|
|
|
You could do this by letting the new view send a private message to the grid view asking for the data. When the new view initializes (e.g. in OnCreate) it sends a WM_YOURPRIVATEMESSAGE (which is #defined as WM_APP + 1 (or is it WM_USER + 1? I always have to look that up)) with SendMessage. The gridview returns the relevant data in the lParam.
Since your new view doesn't know the handle of the grid view you'll probably have to send the message to the mainframe which in turn sends it to all it's decendants. You only handle the message in the grid view, all other views simply ignores it. By using SendMessage instead of PostMessage you're sure that the data will be available for the new view in OnCreate.
Cheers
Steen.
"To claim that computer games influence children is rediculous. If Pacman had influenced children born in the 80'ies we would see a lot of youngsters running around in dark rooms eating pills while listening to monotonous music"
|
|
|
|
|
Thanks for your respond. I'm not familiar with Sendmessage. Is it possible for you to give me an example of how I should use it. The information I want from the grid is:
I must first check if an entry is selected and return selected status. If an entry is selected I want to return the identifier of the selected entry. How should I proceed to get sendmessage to return this information.
Best regards
Øyvind
|
|
|
|
|
hi,
how to type cast a struct into LPARAM or WPARAM to be sent in SendMessage(...) ? Mine did not work which was
struct Test{int num;CString name;};
//-----
Test ts;
::SendMessage(hWnd,21,(LPARAM)&ts);
It said something like " no conversion possible. See Test declaration."
Why?
bye.
|
|
|
|
|
That is not the way Sendmessage is defined... From MSDN:
LRESULT SendMessage(
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam
);
You have:
::SendMessage(hWnd,21,(LPARAM)&ts);
Meaning the message is WM_SYSCOLORCHANGE , you are trying to cast a LPARAM to WPARAM that can not hold a pointer as it is only 16 bits, and miss the LPARAM completly.
/moliate
|
|
|
|
|
Noooooooooo,
just a typing eror.The message is correct in place as the second parameter.
Rachel
|
|
|
|
|
Do you mean that your SendMessage looks like
::SendMessage(hWnd, WM_SOMEMESSAGE, 21, (LPARAM)&ts); ?
My VC60 is perfectly happy with this line (using WM_CREATE as message)
Cheers
Steen.
"To claim that computer games influence children is rediculous. If Pacman had influenced children born in the 80'ies we would see a lot of youngsters running around in dark rooms eating pills while listening to monotonous music"
|
|
|
|
|
It works fine for me when I tried it...
Test ts;
::SendMessage(m_hWnd, WM_USER, (WPARAM)21, (LPARAM)&ts);
Perhaps you could send us a larger piece of code?
/moliate
|
|
|
|
|
There is a file called bios.h which a C program is using.
But when i try to search the file on my system it says file not found
i tried to search 9in dos but still giving the same error.
|
|
|
|
|
|
i wrote a simple game in MFC and when someone has won or lose the game i want to kill the focus and display a messagebox saying you have won/lose... can i use OnKillFocus() to do that? i did that but it will only display the messagebox when i minimize the window or point on another window. Any suggestions or anything on what am doing wrong??? ... anyways, thank your for your help in advance....
|
|
|
|
|
OnKillFocus is a handler for WM_KILLFOCUS, which is sent to a window when it loses the focus. That's why it's called when you minimise or point to another window (as your game's window loses the focus). The change the window that has the focus, use SetFocus().
If you create a message box, that will by default obtain the focus, so your game will lose it. I don't think you need to worry about focus at all in this circumstance, you just need to:
if (game_is_won)
{
MessageBox(NULL, _T("Game over, dude!"), _T("MyGame"), MB_OK);
}
------------------------
Derek Waters
derek@lj-oz.com
|
|
|
|
|
Oh, ok thank you very much Derek
|
|
|
|
|
OnKillFocus is used to perform whatever action you please when the window has lost the focus. To make a window lose its focus, set it elsewehere with SetFocus or SetForegroundWindow .
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Ok, I have been trying to get this to work for a while now. The response I got from my previous thread helped me in theory but didn't help my code.. so I'm posting a more detailed question if anyone can help me. I have a dialog based MFC app with a child listcontrol in report view. I then created another class for another window that will display another listcontrol but with the exact same column and data in it. My problem is that I can't copy the data over with what i've tried.. I have the user add item to the first list using SetItemData(). Like the following->
listitems.mask = LVIF_TEXT;
listitems.iItem = 0;
listitems.iSubItem = 0;
listitems.pszText = (LPTSTR)(LPCTSTR)(strTitle);
m_MyList.InsertItem(&listitems);
listitems.mask = LVIF_TEXT;
listitems.iSubItem = 1;
listitems.pszText = (LPTSTR)(LPCTSTR)(m_strFirstName);
m_MyList.SetItem(&listitems); ...... There are five columns
and then when the user clicks a menu item it will open up another window showing the listcontrol that is supposed to show the same data. Here is the code for that->
void CMFCDlg::OnListSortbyday()
{
DWORD_PTR tempdata = m_MyList.GetItemData(0);
GenList SortWindow;
SortWindow.m_SortList.SetItemData(0,tempdata);
SortWindow.DoModal();
}
m_MyList is a public member CListCtrl of the main window, and m_SortList is a public member CListCtrl of the newly opened window.
This is my most recent try at getting this to work... I get an assertion error when compiling though....
My previous methods were declaring m_SortList as a CListCtrl pointer and point it to m_MyList, or setting the DDX_Control of the listview to CMFCDlg::m_MyList, but neither methods worked. I'm sure there is a way to get this to work.. Maybe making an instance of my main window.. but I don't know how to do that... So can someone guide me in the right direction? I don't want to just loop through and copy every single row, but I may have to.. Please help me out with some explicit instructions and sample code. Thanks!!
Sorry for the long post..
|
|
|
|
|
Hi,
Your problem (which I assume is an assertion when running, not compiling) is that when you call SetItemData in your OnListSortByDay() function, the list control does not exist (if you look at the assertion, it will assert on (m_hWnd == NULL), ie. your control hasn't been created yet). All of the creation is done once you call DoModal. But of course, as it's modal, you can't call any subsequent functions in OnListSortByDay().
So, here's my suggestion. I'm sure other people will have others. In your GenList class, create a public function called SetCopyFromList, where you pass in a CListCtrl pointer:
void GenList::SetCopyFromList(CListCtrl *apCopyDataFrom);
In that function, store the pointer for later use in a member variable of GenList. Then, in the OnInitDialog() handler for GenList, you can use this pointer to obtain data for your list control, safe in the knowledge that m_SortList has been created.
Another alternative would be to override GenList::DoModal() with another function such as GenList::DoModal(CListCtrl *apCopyDataFrom) and then call CDialog::DoModal() inside that function.
Hope this helps.
------------------------
Derek Waters
derek@lj-oz.com
|
|
|
|
|
Great Response Derek! You are right that the assertion error is at runtime, I got confused.. This definitely put me in the right direction. However, after I copied the list through item data, nothing is showing in the newly generated list... I just added this code to test if the data are being copied in an overridden OnInitDialog function->
LVITEM tempdata;
CopiedList->GetItem(&tempdata);
m_SortedList.InsertItem(&tempdata);
No luck...
Please help me solve this final obstacle. Thanks.
|
|
|
|
|
LVITEM tempdata;
TCHAR textBuf[1024] = { 0 }; // unless your strings may be longer...
// specify which item to copy:
tempdata.iItem = <index of="" item="">;
tempdata.iSubItem = 0;
// specify which data to copy:
tempdata.mask = LVIF_IMAGE | LVIF_INDENT | LVIF_PARAM | LVIF_STATE | LVIF_TEXT;
tempdata.stateMask = -1;
tempdata.pszText = textBuf;
tempdata.cchTextMax = 1023;
CopiedList->GetItem(&tempdata);
int insertIdx = m_SortedList.InsertItem(&tempdata); // idx where item was isnerted
// also, you would need to copy sub item text manually...
for(colIdx=1 to columns) {
CString text = CopiedList->GetItemText( <index of="" item="">, colIdx);
m_SortedList.SetItemText(insertIdx, colIdx, text);
}
--------------
completely different approach:
probably it's to late to change now, but I'd used two virtual list controls for this
Instead of feeding the list control, it asks you what to display when something is to be displayed.
(However, you would need to sort the stuff yourself)
Peter
|
|
|
|