Hi all,
I am using eVC++ 4.0, and i've dynamically created a CListView like this:
Code:
lv.Create(0,_T(""),WS_CHILD|WS_VISIBLE,r,this,5);
but I dont know how to handle the events of this control... any ideas??
Mohammad
To get events from a listview (win32) I normally subclass it. I use the subclassing routine to post a message back to the parent when the user is doing something like tapping on it, then the windows routine can check whats selected etc and act on it. Is subclassing possible in mfc ?( I don't use it).
Thank u
but can anybody post some code??
thnx
Ok, I am a bit lazy to look up code at the moment, but here's something:
Yes, subclassing is possible in MFC. You just derive your class from the basic class provided like this:
Code:
class MyListView : pubic CListView
Then you add message handlers in the normal matter.
EDIT: The following passage is incorrect:
But I think subclassing may not be necessary in you case. List box controls send WM_COMMAND messages with notifications of major events like selection change to the parent window. All you have to do is to create a WM_COMMAND handler in your parent class.
Sorry I was thinking of ListBox not list view when I wrote it.
To manually add message handlers you need to put macros like ON_MESAGE or ON_COMMAND in the DECLARE_MESSAGE_MAP section of the class cpp file. All the detaisl are available on MSDN.
Are you saying that a listview will send the same WM_COMMAND as a list box in mfc? Dose this also happen in win32 made listviews. I have always thought it was a bit too tedious to find out when the user taps an item in the listview.
After reading your post levenum I had a quick look and it says that a WM_NOTIFY gets sent to the parent with a LVN_ITEMCHANGED for example. I had not used the LVN_**** because when I looked at them there was none that seem to deal with selections. I would guess that LVN_ITEMACTIVATE or LVN_ODSTATECHANGED would be usefull for this but then a second tap would not be picked up still leaving me wanting subclassing in many situations to get the users tap.
Ok, I have read what u wrote guys and my problem is almost solved, I used the OnNotify() method to handle messages sent from child controls like this:
Code:
BOOL CTest2Dlg::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
// TODO: Add your specialized code here and/or call the base class
if(wParam ==5 ) //5 is control ID
{
NMHDR *ph =(NMHDR*)lParam;
if(ph->code==NM_CLICK)
MessageBox("Click");
else if(ph->code==HDN_ITEMCLICK)
MessageBox("Item Click");
else
{
CString str;
str.Format("%d",ph->code);
MessageBox(str);
}
}
return CDialog::OnNotify(wParam, lParam, pResult);
}
Now there still a very small prolem: what messages should I handle for 'Selected Item Changed' event ?? I know its easy but I couldnt find it
Regards
mohgdeisat: I am sorry, I made a mistake about WM_COMMAND.
OdeeanRDeathshead is right, I was thinking of a list box not list view.
To make up for this, here is some sample code from a win32 dialog app that uses list view control. I hope it will be of some help:
Code:
//this is from the dialog window function:
case WM_NOTIFY: //handle events:
nmhdr = (LPNMHDR)lParam;
switch (nmhdr->idFrom)
{
case IDC_LEDLIST: //list control ID.
return OnLEDListEvent(hwndDlg, (LPNMLISTVIEW)lParam);
break;
}
break;
BOOL OnLEDListEvent(HWND hwndDlg, LPNMLISTVIEW nmlv)
{
/////
// Handles list view control notification messages
switch (nmlv->hdr.code)
{
case LVN_ITEMCHANGED:
return OnLEDListItemChanged(hwndDlg, nmlv);
break;
}
return 0;
}
BOOL OnLEDListItemChanged(HWND hwndDlg, LPNMLISTVIEW nmlv)
{
if (ListView_GetSelectionMark(nmlv->hdr.hwndFrom) != nmlv->iItem) return 0;
/* do what you need here */
return 0;
}
Don't mind the fact that I used 3 different functions. This is part of a bigger program and I am trying to keep things well organized without resorting to classes.
As I understand it, LVN_ITEMCHANGE is received for different reasons so I try to handle only the one coming from selected item. LVN_ITEMACTIVATE is only sent when you double click the item so if you just want to catch selection change you need to use LVN_ITEMCHANGE.
Once again, sorry for confusing you before.
thanx pals, good job!!!
I think my problem is now solved with ur help :wink:
Mohammad
Ok guys, I said that my problem was solved, yet, another problem arises...
When the list view is in the report mode, how can I determine when a header button is clicked, and determine which one was clicked???????
thanx in advance
To identify a header column click, you need to handle the WM_NOTIFY/HDN_ITEMCLICK message. Normally this message will be received by the header's parent control (i.e. the listview) -- some frameworks may redirect the message to the header control itself. I haven't worked with MFC in 10 years so I can't really if it reflects notification messages back to the control.
If you're trying to implement column sort, do yourself a favor and check out the Windows Template Library (WTL) at sourceforge.net. It's a set of C++ template classes that provide a thin yet useful wrapper around the standard Windows UI components. One of the classes is a sortable listview control. I've been using WTL with big Windows for more than 5 years -- you couldn't pay me to go back to MFC.
hi,
I have seen the WTL library and it seems very useful and time-saver, but I have a couple of questions about it:
1. can WTL 8.0 be installed with VC++ 6.0, specifically the appwizard stuff??how?? I see only javascript files of vc7.0 and 7.1 and 8.0!!
2. is there a good documentation about those classes??
Mohammad
I don't know about WTL 8; I'm still using WTL 7.5 with VS .Net 2003 for all my Win32 development. My guess is that it wouldn't work too well, as WTL is based on ATL, which has substantially changed between VC 6 and 7.
Good references for WTL include www.codeproject.com/wtl, and the WTL group over at Yahoo groups (reflected at www.gmane.org).
Greetings,
I have some calculations on the main view based on some data you set in the options view. What I want to do is, when you go to the options view and change some data then click SAVE(this throws you back to the main view) that the calculations will have been made already based on the new data. The calculations are done by a service and are called once when you first open the app, so currently you need to close and reopen the app to see the new calculations.
help appreciated
I'm guessing you have a main activity for your "main view", from which you launch an options activity? If so you can simply startActivityForResult(...) from the main activity. When the user clicks SAVE just have the activity setResult(...) with an intent that contains the necessary data. Then override the onActivityResult(...) method in your main activity to handle that intent with the new data. There are also API's for activities specifically designed to manage application settings.
Also, remember that onResume() is called after onCreate() even when an activity first launches. So you could move the code that performs the calculations from onCreate() to onResume().
Hope this helps
I'm developing a simple android application using the TabActivity.
This Activity adds 3 tabs, each one with its own activity.
The problem is: when I tap each tab, the system calls onDestroy of the current activity. So, when I tap the first activity again, all the state of private fields are gone, its like it has created a new instance every time I change tabs.
I was searching around about this, and looking on the samples, but I guess that the default behavior is to keep the activity instances paused when the tab is not current.
Anyone have an idea of what I'm missing?
Thanks.
That is by design. You need to override onSaveInstanceState() and onRestoreInstanceState() in your activity class. You can store/retrieve state data there, or retrieve it int the Bundle passed into OnCreate(). See:
http://developer.android.com/reference/android/app/Activity.html#onCreate(android.os.Bundle)
Hi guys.
New to Android Development and was wondering if there was some way of taking the users input to create an activity? For example say the user is going through the process of setting up a profile of themself. One of the questions is "how many pets do you have?". The user inputs "4" and then clicks the 'Next' button (which opens the next activity).
How would I take the users input of "4" to create four editText objects in the next activity so that the user can now input the name's of his/her's pets?
I'm an ok-ish programmer (have never touched XML before) so you don't need to go into detail I just don't know how I would access this variable to create the four editText objects. From what I've found you can't add strings to the resources at runtime.
Don't bother replying, I've solved my problem. Just need to create a dynamic layout in JAVA
So I'm a noob when comes to android programing. Can someone tell me if the "Complete Action Using" dialog box is suppose to set the defaults when you use the "Always" response? Personally I thought it was however in my programming I have not been able to get it to use the "always" response always. What I mean is if I have "Google Music" installed and then I want to kick off the music player i ALWAYS get the "Complete Action Using" dialog popup.
To remove my code I went back to the Android developers first app program and used that. The SendMessage code now looks like this below. When running this on the emulator the "Complete Action Using" popup always comes up irrespective of selecting "Always" or "Just Once". What have I missed or done wrong?
Code:
public void sendMessage(View view) {
// Do something in response to button
if(android.os.Build.VERSION.SDK_INT>=15){
Intent intent=Intent.makeMainSelectorActivity(Intent.ACTION_MAIN,
Intent.CATEGORY_APP_MUSIC);
startActivity(intent);
}else{
Intent intent = new Intent("android.intent.action.MUSIC_PLAYER");//Min SDK 8 and deprecated in API 17 for makeMainSelectoryActivity
startActivity(intent);
}
}
tommiyau said:
So I'm a noob when comes to android programing. Can someone tell me if the "Complete Action Using" dialog box is suppose to set the defaults when you use the "Always" response? Personally I thought it was however in my programming I have not been able to get it to use the "always" response always. What I mean is if I have "Google Music" installed and then I want to kick off the music player i ALWAYS get the "Complete Action Using" dialog popup.
To remove my code I went back to the Android developers first app program and used that. The SendMessage code now looks like this below. When running this on the emulator the "Complete Action Using" popup always comes up irrespective of selecting "Always" or "Just Once". What have I missed or done wrong?
Code:
public void sendMessage(View view) {
// Do something in response to button
if(android.os.Build.VERSION.SDK_INT>=15){
Intent intent=Intent.makeMainSelectorActivity(Intent.ACTION_MAIN,
Intent.CATEGORY_APP_MUSIC);
startActivity(intent);
}else{
Intent intent = new Intent("android.intent.action.MUSIC_PLAYER");//Min SDK 8 and deprecated in API 17 for makeMainSelectoryActivity
startActivity(intent);
}
}
Click to expand...
Click to collapse
If you select "Always", the default application will be set which you can remove from the settings.
However, there should be a better possibility to do this.
You could try to use the unofficial Google Music API.
EDIT: If you just want to start Google Music use that code:
Code:
Intent LaunchIntent = getPackageManager().getLaunchIntentForPackage("com.package.address"); //replace the package name
startActivity(LaunchIntent);
nikwen said:
If you select "Always", the default application will be set which you can remove from the settings.
However, there should be a better possibility to do this.
You could try to use the unofficial Google Music API.
EDIT: If you just want to start Google Music use that code:
Code:
Intent LaunchIntent = getPackageManager().getLaunchIntentForPackage("com.package.address"); //replace the package name
startActivity(LaunchIntent);
Click to expand...
Click to collapse
Actually you can not use this to set a default application. You can try this in the emulator. The selection of Always does not impact the default application setting.
It appears that the Confirmation of "Always" and "Just Once" when ACTION_MAIN is used with a CATEGORY is a misnormer altogether. A default is only set when an Intent contains a mime type. So if you did not use ACTION_MAIN but say GET_CONTENT with a type of audio/* then you can launch with a default player.
Try it your self in the emulator this never sets a default. Seems everyone says it does but certainly the emulator and a real device support the outcomes that a default is never established through his call at all.
Stll looking for a answer but at least I now know that the above will always prompt you to select an application irrespective of any defaults set.
did you try it on a device?
out of ideas said:
did you try it on a device?
Click to expand...
Click to collapse
you mean my original code. Yes I did and the way it behaves is as described. I also went debugging what the makemainselector actually does under these situations. It actually registers the selected application in the packagemanager against the "Android device". Subsequent calls with the APP_MUSIC Category do not get found for some reason. Its like the code does not look for the application that is registered but asks for the number of applications that support the category and then throws a prompt rather than checking if there is a existing default. So either the makemainselector is the wrong thing to use or this just behaves incorrectly. When looking through the developer apps it does state to use makemainselectoractivity for API>15 as the action for the <15 intent of MUSIC_PLAYER is deprecated. However, an intent using MUSIC_PLAYER works corrctly and kicks off the default where as makemainselectoractivity seems to set the default, and kick off the app but does this every time. So either the documentation is incorrect or the code has a bug. If I get time I'll try and look through the code but at present it does not seem that this actually works to select a default allocated application and use it......you have to put up with being prompted and then selecting an option or double clicking every time.
Code:
Intent intent=Intent.makeMainSelectorActivity(Intent.ACTION_MAIN,
Intent.CATEGORY_APP_MUSIC);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//Min SDK 15
PackageManager pm = this.getPackageManager();
final ResolveInfo mInfo = pm.resolveActivity(intent, 0);
Toast.makeText(this, pm.getApplicationLabel(mInfo.activityInfo.applicationInfo), Toast.LENGTH_LONG).show();
startActivity(intent);