123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888 |
- /*
- ** Copyright (C) 2003 Nullsoft, Inc.
- **
- ** This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held
- ** liable for any damages arising from the use of this software.
- **
- ** Permission is granted to anyone to use this software for any purpose, including commercial applications, and to
- ** alter it and redistribute it freely, subject to the following restrictions:
- **
- ** 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software.
- ** If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
- **
- ** 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
- **
- ** 3. This notice may not be removed or altered from any source distribution.
- **
- */
- #include <windows.h>
- #include <windowsx.h>
- #include <stdio.h>
- #include "../ml.h"
- #include "resource.h"
- #include "../listview.h"
- #include "../childwnd.h"
- #include "../../winamp/wa_dlg.h"
- #include "../itemlist.h"
- // configuration section in winamp.ini
- #define CONFIG_SEC "ml_ex"
- // columns in our big treeview
- #define COL_ARTIST 0
- #define COL_TITLE 1
- #define COL_ALBUM 2
- #define COL_LENGTH 3
- #define COL_TRACK 4
- #define COL_GENRE 5
- #define COL_YEAR 6
- #define COL_FILENAME 7
- // makes a NULL char * an empty string
- #define MAKESAFE(x) ((x)?(x):"")
- // yes, we could easily use an itemRecord / itemRecordList here instead of 'Song's, but the point of this example
- // is to show how to integrate with some other native structure
- typedef struct
- {
- char *artist;
- char *title;
- char *album;
- int songlen; // seconds?
- int track_nr;
- char *genre;
- int year;
- char *filename;
- } Song;
- // our leading crap reduction agent for use with sorting/etc
- #define SKIP_THE_AND_WHITESPACE(x) { while (!isalnum(*x) && *x) x++; if (!_strnicmp(x,"the ",4)) x+=4; while (*x == ' ') x++; }
- extern winampMediaLibraryPlugin plugin;
- static int myParam; // param of our tree item
- static C_ItemList m_songs, *m_songs_sorted;
- static W_ListView m_list;
- static HWND m_hwnd;
- static HMENU m_context_menus;
- static int m_skinlistview_handle;
- void config(HWND parent);
- void sortResults();
- static void deleteSongPtr(Song *song)
- {
- free(song->album);
- free(song->artist);
- free(song->title);
- free(song->genre);
- free(song->filename);
- free(song);
- }
- static void clearSongList()
- {
- int i=m_songs.GetSize();
- while (i>0)
- {
- Song *song=(Song *)m_songs.Get(--i);
- deleteSongPtr(song);
- m_songs.Del(i);
- }
- }
- // this doesnt actually alloc the memory for all the strings, just references them (so it is only temporarily valid at best)
- void SongsToItemList(itemRecordList *p, int all)
- {
- if (!m_hwnd) all=1;
- p->Alloc=p->Size=0;
- p->Items=0;
- C_ItemList *list=(C_ItemList *)m_songs_sorted;
- if (!list) { list=&m_songs; all=1; }
- int x,l=list->GetSize();
- for (x = 0 ; x < l; x ++)
- {
- if (!all && !m_list.GetSelected(x)) continue;
- allocRecordList(p,p->Size+1,256);
- if (!p->Items) break;
- Song *s=(Song *)list->Get(x);
- memset(&p->Items[p->Size],0,sizeof(itemRecord));
- p->Items[p->Size].album=s->album;
- p->Items[p->Size].artist=s->artist;
- p->Items[p->Size].title=s->title;
- p->Items[p->Size].genre=s->genre;
- p->Items[p->Size].filename=s->filename;
- p->Items[p->Size].track=s->track_nr;
- p->Items[p->Size].year=s->year;
- p->Items[p->Size].length=s->songlen;
- p->Size++;
- }
- }
- static void playFiles(int enqueue, int all)
- {
- if (!m_songs_sorted) return;
- if (!m_hwnd && !all) return;
- itemRecordList obj={0,};
- SongsToItemList(&obj,all);
- if (obj.Size)
- {
- mlSendToWinampStruct s={ML_TYPE_ITEMRECORDLIST,(void*)&obj,!!enqueue};
- SendMessage(plugin.hwndLibraryParent,WM_ML_IPC,(WPARAM)&s,ML_IPC_SENDTOWINAMP);
- }
- free(obj.Items);
- }
- void addItemListToSongs(itemRecordList *p)
- {
- if (p) for (int x = 0 ; x < p->Size; x ++)
- {
- Song *s=(Song *)calloc(1,sizeof(Song));
- if (p->Items[x].album) s->album=_strdup(p->Items[x].album);
- if (p->Items[x].artist) s->artist=_strdup(p->Items[x].artist);
- if (p->Items[x].title) s->title=_strdup(p->Items[x].title);
- if (p->Items[x].genre) s->genre=_strdup(p->Items[x].genre);
- if (p->Items[x].filename) s->filename=_strdup(p->Items[x].filename);
- s->track_nr=p->Items[x].track;
- s->year=p->Items[x].year;
- s->songlen=p->Items[x].length;
- m_songs.Add((void*)s);
- }
- }
- char *conf_file;
- int init() {
- mlAddTreeItemStruct mla={
- 0, // if you used 0, it would put it on top level, or ML_TREEVIEW_ID_DEVICES
- "Item Cache Example",
- 1,
- };
- conf_file=(char*)SendMessage(plugin.hwndWinampParent,WM_WA_IPC,0,IPC_GETINIFILE); // get winamp.ini name :)
- SendMessage(plugin.hwndLibraryParent,WM_ML_IPC,(WPARAM)&mla,ML_IPC_ADDTREEITEM);
- myParam=mla.this_id;
- m_context_menus=LoadMenu(plugin.hDllInstance,MAKEINTRESOURCE(IDR_CONTEXTMENUS));
- return 0;
- }
- void quit()
- {
- clearSongList();
- }
- void loadSongList()
- {
- clearSongList();
- // populate m_songs from whatever source we have
- Song *p=(Song *)calloc(sizeof(Song),1);
- p->filename = _strdup("http://www.firehose.net/~deadbeef/media/Misc/music/030223%20-%20pervert-in-a-satellite.mp3");
- p->album=_strdup("SEP");
- p->artist=_strdup("Nullsoft Band");
- p->genre=_strdup("Shit");
- p->songlen = 666;
- p->track_nr=1;
- p->title=_strdup("Pervert In A Satellite");
- p->year=2003;
- m_songs.Add((void*)p);
- }
- // this is uberadvancedsearchtechnology[tm]
- static void parsequicksearch(char *out, char *in) // parses a list into a list of terms that we are searching for
- {
- int inquotes=0, neednull=0;
- while (*in)
- {
- char c=*in++;
- if (c != ' ' && c != '\t' && c != '\"')
- {
- neednull=1;
- *out++=c;
- }
- else if (c == '\"')
- {
- inquotes=!inquotes;
- if (!inquotes)
- {
- *out++=0;
- neednull=0;
- }
- }
- else
- {
- if (inquotes) *out++=c;
- else if (neednull)
- {
- *out++=0;
- neednull=0;
- }
- }
- }
- *out++=0;
- *out++=0;
- }
- static int in_string(char *string, char *substring)
- {
- if (!string) return 0;
- if (!*substring) return 1;
- int l=strlen(substring);
- while (string[0]) if (!_strnicmp(string++,substring,l)) return 1;
- return 0;
- }
- static void updateList()
- {
- if(!m_hwnd) return;
- char filterstr[256],filteritems[300];
- GetDlgItemText(m_hwnd,IDC_QUICKSEARCH,filterstr,sizeof(filterstr)-1);
- parsequicksearch(filteritems,filterstr);
- delete m_songs_sorted;
- m_songs_sorted=new C_ItemList;
- unsigned int totallen=0,filterlen=0,filterval=0;
- for(int i=0;i<m_songs.GetSize();i++)
- {
- Song *s=(Song *)m_songs.Get(i);
- totallen+=s->songlen;
- char year[32]="";
- if (s->year < 5000 && s->year > 0) sprintf(year,"%d",s->year);
- char *p=filteritems;
- if (*p)
- {
- while (*p)
- {
- // search for 'p' in the song
- if (!in_string(s->album,p) && !in_string(s->artist,p) && !in_string(s->title,p) && !in_string(s->genre,p) && !in_string(year,p))
- break;
- p+=strlen(p)+1;
- }
- if (*p) continue;
- }
- filterval++;
- filterlen+=s->songlen;
- m_songs_sorted->Add((void *)s);
- }
- sortResults();
- char tmp[512];
- if (m_songs.GetSize() != m_songs_sorted->GetSize())
- wsprintf(tmp,"Found: %d items [%d:%02d:%02d]",
- m_songs_sorted->GetSize(),filterval,
- filterlen/3600,(filterlen/60)%60,filterlen%60);
- else
- wsprintf(tmp,"%d items [%d:%02d:%02d]",m_songs.GetSize(),totallen/3600,(totallen/60)%60,totallen%60);
- SetDlgItemText(m_hwnd,IDC_STATUS,tmp);
- }
- static ChildWndResizeItem resize_rlist[]={
- {IDC_QUICKSEARCH,0x0010},
- {IDC_LIST,0x0011},
- {IDC_BUTTON_CONFIG,0x0101},
- {IDC_STATUS,0x0111}
- };
- int g_sortcol, g_sortdir;
- static int STRCMP_NULLOK(const char *pa, const char *pb)
- {
- if (!pa) pa="";
- else SKIP_THE_AND_WHITESPACE(pa)
- if (!pb) pb="";
- else SKIP_THE_AND_WHITESPACE(pb)
-
- return _stricmp(pa,pb);
- }
- static int sortFunc(const void *elem1, const void *elem2)
- {
- Song *a=(Song *)*(void **)elem1;
- Song *b=(Song *)*(void **)elem2;
- int use_by=g_sortcol;
- int use_dir=g_sortdir;
- #define RETIFNZ(v) if ((v)<0) return use_dir?1:-1; if ((v)>0) return use_dir?-1:1;
- // this might be too slow, but it'd be nice
- int x;
- for (x = 0; x < 4; x ++)
- {
- if (use_by == COL_YEAR) // year -> artist -> album -> track
- {
- int v1=a->year;
- int v2=b->year;
- if (v1<0)v1=0;
- if (v2<0)v2=0;
- RETIFNZ(v1-v2)
- use_by=COL_ARTIST;
- }
- else if (use_by == COL_TITLE) // title -> artist -> album -> track
- {
- int v=STRCMP_NULLOK(a->title,b->title);
- RETIFNZ(v)
- use_by=COL_ARTIST;
- }
- else if (use_by == COL_ARTIST) // artist -> album -> track -> title
- {
- int v=STRCMP_NULLOK(a->artist,b->artist);
- RETIFNZ(v)
- use_by=COL_ALBUM;
- }
- else if (use_by == COL_ALBUM) // album -> track -> title -> artist
- {
- int v=STRCMP_NULLOK(a->album,b->album);
- RETIFNZ(v)
- use_dir=0;
- use_by=COL_TRACK;
- }
- else if (use_by == COL_GENRE) // genre -> artist -> album -> track
- {
- int v=STRCMP_NULLOK(a->genre,b->genre);
- RETIFNZ(v)
- use_by=COL_ARTIST;
- }
- else if (use_by == COL_TRACK) // track -> title -> artist -> album
- {
- int v1=a->track_nr;
- int v2=b->track_nr;
- if (v1<0)v1=0;
- if (v2<0)v2=0;
- RETIFNZ(v1-v2)
- use_by=COL_TITLE;
- }
- else if (use_by == COL_LENGTH) // length -> artist -> album -> track
- {
- int v1=a->songlen;
- int v2=b->songlen;
- if (v1<0)v1=0;
- if (v2<0)v2=0;
- RETIFNZ(v1-v2)
- use_by=COL_ARTIST;
- }
- else break; // no sort order?
- }
- #undef RETIFNZ
- return 0;
- }
- void sortResults()
- {
- if (!m_songs_sorted) return;
- qsort(m_songs_sorted->GetAll(),m_songs_sorted->GetSize(),sizeof(void*),sortFunc);
- ListView_SetItemCount(m_list.getwnd(),0);
- ListView_SetItemCount(m_list.getwnd(),m_songs_sorted->GetSize());
- ListView_RedrawItems(m_list.getwnd(),0,m_songs_sorted->GetSize()-1);
- }
- int (*wad_getColor)(int idx);
- int (*wad_handleDialogMsgs)(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
- void (*wad_DrawChildWindowBorders)(HWND hwndDlg, int *tab, int tabsize);
- void (*cr_init)(HWND hwndDlg, ChildWndResizeItem *list, int num);
- void (*cr_resize)(HWND hwndDlg, ChildWndResizeItem *list, int num);
- static BOOL CALLBACK dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
- {
- if (wad_handleDialogMsgs)
- {
- BOOL a=wad_handleDialogMsgs(hwndDlg,uMsg,wParam,lParam); if (a) return a;
- }
- switch (uMsg)
- {
- case WM_DISPLAYCHANGE:
- ListView_SetTextColor(m_list.getwnd(),wad_getColor?wad_getColor(WADLG_ITEMFG):RGB(0xff,0xff,0xff));
- ListView_SetBkColor(m_list.getwnd(),wad_getColor?wad_getColor(WADLG_ITEMBG):RGB(0x00,0x00,0x00));
- ListView_SetTextBkColor(m_list.getwnd(),wad_getColor?wad_getColor(WADLG_ITEMBG):RGB(0x00,0x00,0x00));
- m_list.refreshFont();
- return 0;
- case WM_INITDIALOG:
- m_hwnd=hwndDlg;
- *(void **)&wad_getColor=(void*)SendMessage(plugin.hwndLibraryParent,WM_ML_IPC,1,ML_IPC_SKIN_WADLG_GETFUNC);
- *(void **)&wad_handleDialogMsgs=(void*)SendMessage(plugin.hwndLibraryParent,WM_ML_IPC,2,ML_IPC_SKIN_WADLG_GETFUNC);
- *(void **)&wad_DrawChildWindowBorders=(void*)SendMessage(plugin.hwndLibraryParent,WM_ML_IPC,3,ML_IPC_SKIN_WADLG_GETFUNC);
-
- *(void **)&cr_init=(void*)SendMessage(plugin.hwndLibraryParent,WM_ML_IPC,32,ML_IPC_SKIN_WADLG_GETFUNC);
- // woof: *(void **)&cr_resize=(void*)SendMessage(plugin.hwndLibraryParent,WM_ML_IPC,33,ML_IPC_SKIN_WADLG_GETFUNC);
-
- if (cr_init) cr_init(hwndDlg,resize_rlist,sizeof(resize_rlist)/sizeof(resize_rlist[0]));
-
- m_list.setLibraryParentWnd(plugin.hwndLibraryParent);
- m_list.setwnd(GetDlgItem(hwndDlg,IDC_LIST));
- m_list.AddCol("Artist",200);
- m_list.AddCol("Title",200);
- m_list.AddCol("Album",200);
- m_list.AddCol("Length",64);
- m_list.AddCol("Track #",64);
- m_list.AddCol("Genre",100);
- m_list.AddCol("Year",64);
- m_list.AddCol("Filename",80);
- ListView_SetTextColor(m_list.getwnd(),wad_getColor?wad_getColor(WADLG_ITEMFG):RGB(0xff,0xff,0xff));
- ListView_SetBkColor(m_list.getwnd(),wad_getColor?wad_getColor(WADLG_ITEMBG):RGB(0x00,0x00,0x00));
- ListView_SetTextBkColor(m_list.getwnd(),wad_getColor?wad_getColor(WADLG_ITEMBG):RGB(0x00,0x00,0x00));
- g_sortdir=GetPrivateProfileInt(CONFIG_SEC,"sortdir",0,conf_file);
- g_sortcol=GetPrivateProfileInt(CONFIG_SEC,"sortcol",g_sortcol,conf_file);
- m_skinlistview_handle=SendMessage(plugin.hwndLibraryParent,WM_ML_IPC,(int)m_list.getwnd(),ML_IPC_SKIN_LISTVIEW);
- SetTimer(hwndDlg,32,50,NULL);
- return 0;
- case WM_NOTIFY:
- {
- LPNMHDR l=(LPNMHDR)lParam;
- if (l->idFrom==IDC_LIST)
- {
- if (l->code == NM_DBLCLK)
- {
- playFiles(!!(GetAsyncKeyState(VK_SHIFT)&0x8000),0);
- }
- else if (l->code == LVN_BEGINDRAG)
- {
- SetCapture(hwndDlg);
- }
- else if (l->code == LVN_ODFINDITEM) // yay we find an item (for kb shortcuts)
- {
- NMLVFINDITEM *t = (NMLVFINDITEM *)lParam;
- int i=t->iStart;
- if (i >= m_songs_sorted->GetSize()) i=0;
- int cnt=m_songs_sorted->GetSize()-i;
- if (t->lvfi.flags & LVFI_WRAP) cnt+=i;
- while (cnt-->0)
- {
- Song *thissong = (Song *)m_songs_sorted->Get(i);
- char tmp[128];
- char *name=0;
- switch (g_sortcol)
- {
- case COL_ARTIST: name=thissong->artist; break;
- case COL_TITLE: name=thissong->title; break;
- case COL_ALBUM: name=thissong->album; break;
- case COL_LENGTH:
- wsprintf(tmp,"%d:%02d",thissong->songlen/60,(thissong->songlen)%60); name=tmp;
- break;
- case COL_TRACK: if (thissong->track_nr > 0 && thissong->track_nr < 1000) { wsprintf(tmp,"%d",thissong->track_nr); name=tmp; } break;
- case COL_GENRE: name=thissong->genre; break;
- case COL_YEAR: if (thissong->year < 5000 && thissong->year > 0) { wsprintf(tmp,"%d",thissong->year); name=tmp; } break;
- case COL_FILENAME: name=thissong->filename; break;
- }
- if (!name) name="";
- else SKIP_THE_AND_WHITESPACE(name)
- if (t->lvfi.flags & (4|LVFI_PARTIAL))
- {
- if (!_strnicmp(name,t->lvfi.psz,strlen(t->lvfi.psz)))
- {
- SetWindowLong(hwndDlg,DWL_MSGRESULT,i);
- return 1;
- }
- }
- else if (t->lvfi.flags & LVFI_STRING)
- {
- if (!_stricmp(name,t->lvfi.psz))
- {
- SetWindowLong(hwndDlg,DWL_MSGRESULT,i);
- return 1;
- }
- }
- else
- {
- SetWindowLong(hwndDlg,DWL_MSGRESULT,-1);
- return 1;
- }
- if (++i == m_songs_sorted->GetSize()) i=0;
- }
- SetWindowLong(hwndDlg,DWL_MSGRESULT,-1);
- return 1;
- }
- else if (l->code == LVN_GETDISPINFO)
- {
- NMLVDISPINFO *lpdi = (NMLVDISPINFO*) lParam;
- int item=lpdi->item.iItem;
- if (item < 0 || item >= m_songs_sorted->GetSize()) return 0;
- Song *thissong = (Song *)m_songs_sorted->Get(item);
- if (lpdi->item.mask & (LVIF_TEXT|/*LVIF_IMAGE*/0)) // we can always do images too :)
- {
- if (lpdi->item.mask & LVIF_TEXT)
- {
- char tmpbuf[128];
- char *nameptr=0;
- switch (lpdi->item.iSubItem)
- {
- case COL_ARTIST: nameptr=thissong->artist; break;
- case COL_TITLE: nameptr=thissong->title; break;
- case COL_ALBUM: nameptr=thissong->album; break;
- case COL_LENGTH:
- wsprintf(tmpbuf,"%d:%02d",thissong->songlen/60,(thissong->songlen)%60); nameptr=tmpbuf;
- break;
- case COL_TRACK: if (thissong->track_nr > 0 && thissong->track_nr < 1000) { wsprintf(tmpbuf,"%d",thissong->track_nr); nameptr=tmpbuf; } break;
- case COL_GENRE: nameptr=thissong->genre; break;
- case COL_YEAR: if (thissong->year>0 && thissong->year<5000) { wsprintf(tmpbuf,"%d",thissong->year); nameptr=tmpbuf; } break;
- case COL_FILENAME: nameptr=thissong->filename; break;
- }
- if (nameptr) lstrcpyn(lpdi->item.pszText,nameptr,lpdi->item.cchTextMax);
- else lpdi->item.pszText[0]=0;
- }
- // if(lpdi->item.mask & LVIF_IMAGE)
- } // bother
- return 0;
- } // LVN_GETDISPINFO
- else if (l->code == LVN_COLUMNCLICK)
- {
- NMLISTVIEW *p=(NMLISTVIEW*)lParam;
- if (p->iSubItem == g_sortcol) g_sortdir=!g_sortdir;
- else g_sortcol=p->iSubItem;
- char str[32];
- sprintf(str,"%d",g_sortdir);
- WritePrivateProfileString(CONFIG_SEC,"sortdir",str,conf_file);
- sprintf(str,"%d",g_sortcol);
- WritePrivateProfileString(CONFIG_SEC,"sortcol",str,conf_file);
- sortResults();
- }
- }
- }
- break;
- case WM_COMMAND:
- switch(LOWORD(wParam))
- {
- case IDC_BUTTON_CONFIG:
- config(hwndDlg);
- break;
- case IDC_QUICKSEARCH:
- if (HIWORD(wParam) == EN_CHANGE)
- {
- KillTimer(hwndDlg,500);
- SetTimer(hwndDlg,500,150,NULL);
- }
- break;
- }
- break;
- case WM_TIMER:
- if (wParam == 500)
- {
- KillTimer(hwndDlg,500);
- char buf[256];
- GetDlgItemText(hwndDlg,IDC_QUICKSEARCH,buf,sizeof(buf));
- buf[255]=0;
- WritePrivateProfileString(CONFIG_SEC,"lastfilter",buf,conf_file);
- updateList();
- }
- else if (wParam == 32)
- {
- KillTimer(hwndDlg,32);
- if (!m_songs.GetSize()) loadSongList();
- char buf[256];
- GetPrivateProfileString(CONFIG_SEC,"lastfilter","",buf,sizeof(buf),conf_file);
- SetDlgItemText(hwndDlg,IDC_QUICKSEARCH,buf); // automatically updates the list via EN_CHANGE
- }
- break;
- case WM_SIZE:
- #if 0 // BP:
- if (wParam != SIZE_MINIMIZED)
- {
- if (cr_resize) cr_resize(hwndDlg,resize_rlist,sizeof(resize_rlist)/sizeof(resize_rlist[0]));
- }
- #endif
- break;
- case WM_PAINT:
- {
- if (wad_DrawChildWindowBorders)
- {
- int tab[] = { IDC_QUICKSEARCH|DCW_SUNKENBORDER, IDC_LIST|DCW_SUNKENBORDER};
- wad_DrawChildWindowBorders(hwndDlg,tab,2);
- }
- }
- return 0;
- case WM_DESTROY:
- //clearSongList();
- m_hwnd=NULL;
- SendMessage(plugin.hwndLibraryParent,WM_ML_IPC,m_skinlistview_handle,ML_IPC_UNSKIN_LISTVIEW);
- return 0;
- case WM_ML_CHILDIPC:
- if (lParam == ML_CHILDIPC_DROPITEM && wParam)
- {
- mlDropItemStruct *t=(mlDropItemStruct*)wParam;
- if (t->type == ML_TYPE_ITEMRECORDLIST) t->result=1;
- if (t->data)
- {
- if (t->type == ML_TYPE_ITEMRECORDLIST) // we got a drag&drop to our window, hot!
- {
- addItemListToSongs((itemRecordList*)t->data);
- updateList();
- }
- }
- }
- return 0;
- case WM_LBUTTONUP:
- if (GetCapture() == hwndDlg)
- {
- ReleaseCapture();
- POINT p;
- p.x=GET_X_LPARAM(lParam);
- p.y=GET_Y_LPARAM(lParam);
- ClientToScreen(hwndDlg,&p);
- HWND h=WindowFromPoint(p);
- if (h != hwndDlg && !IsChild(hwndDlg,h))
- {
- mlDropItemStruct m={ML_TYPE_ITEMRECORDLIST,NULL,0};
- m.p=p;
- m.flags=ML_HANDLEDRAG_FLAG_NOCURSOR;
- SendMessage(plugin.hwndLibraryParent,WM_ML_IPC,(WPARAM)&m,ML_IPC_HANDLEDRAG);
- if (m.result>0)
- {
- itemRecordList o={0,};
- SongsToItemList(&o,0);
- if (o.Size)
- {
- //fill in this itemCacheObject if you want to provide drag&drop out of the window
- m.flags=0;
- m.result=0;
- m.data=(void*)&o;
- SendMessage(plugin.hwndLibraryParent,WM_ML_IPC,(WPARAM)&m,ML_IPC_HANDLEDROP);
- }
- free(o.Items);
- }
- }
- }
- break;
- case WM_MOUSEMOVE:
- if (GetCapture()==hwndDlg)
- {
- POINT p;
- p.x=GET_X_LPARAM(lParam);
- p.y=GET_Y_LPARAM(lParam);
- ClientToScreen(hwndDlg,&p);
- mlDropItemStruct m={ML_TYPE_ITEMRECORDLIST,NULL,0};
- m.p=p;
- HWND h=WindowFromPoint(p);
- if (!h || h == hwndDlg || IsChild(hwndDlg,h))
- {
- SetCursor(LoadCursor(NULL,IDC_NO));
- }
- else
- SendMessage(plugin.hwndLibraryParent,WM_ML_IPC,(WPARAM)&m,ML_IPC_HANDLEDRAG);
- }
- break;
- }
- return 0;
- }
- static BOOL CALLBACK config_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
- {
- switch (uMsg)
- {
- case WM_INITDIALOG:
- return 0;
- case WM_COMMAND:
- switch (LOWORD(wParam))
- {
- case IDOK:
- // save combo box
- case IDCANCEL:
- EndDialog(hwndDlg,LOWORD(wParam) == IDOK);
- break;
- }
- return 0;
- }
- return 0;
- }
- static void config(HWND parent)
- {
- DialogBox(plugin.hDllInstance,MAKEINTRESOURCE(IDD_CONFIG),parent,config_dlgproc);
- }
- int onTreeItemClick(int param, int action, HWND hwndParent) // if param is not yours, return 0
- {
- if (action == ML_ACTION_RCLICK)
- {
- POINT p;
- GetCursorPos(&p);
- int r=TrackPopupMenu(GetSubMenu(m_context_menus,0),TPM_RETURNCMD|TPM_RIGHTBUTTON|TPM_LEFTBUTTON|TPM_NONOTIFY,p.x,p.y,0,hwndParent,NULL);
- switch (r)
- {
- case ID_ABOUT:
- MessageBox(hwndParent,"ml_ex!!!","About ml_ex!!!",MB_OK);
- break;
- case ID_CONFIG:
- config(hwndParent);
- break;
- }
- }
- return 1;
- }
- int onTreeItemDropTarget(int param, int type, void *obj)
- {
- if (type != ML_TYPE_ITEMRECORDLIST) return -1;
- if (!obj) return 1;
- // do somethihng with the itemCache object. do not free it however, since the caller owns it
- addItemListToSongs((itemRecordList*)obj);
-
- updateList();
- return 1;
- }
- int onTreeItemDrag(int param, POINT p, int *type)
- {
- HWND h=WindowFromPoint(p);
- if (h && (h == m_hwnd || IsChild(m_hwnd,h))) return -1; // prevent from dropping into ourselves
- // if we wanted to be able to drag&drop our tree item to other people, we'd
- // return 1 and set type to ML_TYPE_ITEMRECORDLIST or ML_TYPE_FILENAMES etc.
- // *type = ML_TYPE_ITEMRECORDLIST;
- return -1;
- }
- int onTreeItemDrop(int param, POINT p) // you should send the appropriate ML_IPC_HANDLEDROP if you support it
- {
- HWND h=WindowFromPoint(p);
- if (h && (h == m_hwnd || IsChild(m_hwnd,h))) return -1; // prevent from dropping into ourselves
- // if we wanted to be able to drag&drop our tree item to other people, we'd
- // create an itemCacheObject or a doublenull terminated list (depending on what we want),
- // and send it back to the media library so it can route it to the appropriate destination:
- //
- // itemCacheObject o={0,};
- // fillInMyObject(&o);
- // mlDropItemStruct m={0,};
- // m.type = ML_TYPE_ITEMRECORDLIST;
- // m.data = (void*)&o;
- // m.p=p;
- // SendMessage(plugin.hwndLibraryParent,WM_ML_IPC,(WPARAM)&m,ML_IPC_HANDLEDROP);
- // freeMyObject(&o);
- // or this:
- itemRecordList o={0,};
- SongsToItemList(&o,1);
- if (o.Size)
- {
- mlDropItemStruct m={0,};
- m.type = ML_TYPE_ITEMRECORDLIST;
- m.data = (void*)&o;
- m.p=p;
- SendMessage(plugin.hwndLibraryParent,WM_ML_IPC,(WPARAM)&m,ML_IPC_HANDLEDROP);
- }
- free(o.Items);
- return 1;
- }
- int PluginMessageProc(int message_type, int param1, int param2, int param3)
- {
- // check for any global messages here
- if (message_type >= ML_MSG_TREE_BEGIN && message_type <= ML_MSG_TREE_END)
- {
- if (param1 != myParam) return 0;
- // local messages for a tree item
- switch (message_type)
- {
- case ML_MSG_TREE_ONCREATEVIEW:
- return (int)CreateDialog(plugin.hDllInstance,MAKEINTRESOURCE(IDD_VIEW_EX),(HWND)param2,dlgproc);
- case ML_MSG_TREE_ONCLICK:
- return onTreeItemClick(param1,param2,(HWND)param3);
- case ML_MSG_TREE_ONDROPTARGET:
- return onTreeItemDropTarget(param1,param2,(void*)param3);
- case ML_MSG_TREE_ONDRAG:
- return onTreeItemDrag(param1,*(POINT*)param2,(int*)param3);
- case ML_MSG_TREE_ONDROP:
- return onTreeItemDrop(param1,*(POINT*)param2);
- }
- }
- else if (message_type == ML_MSG_ONSENDTOBUILD)
- {
- if (param1 == ML_TYPE_ITEMRECORDLIST)
- {
- mlAddToSendToStruct s;
- s.context=param2;
- s.desc="ItemCacheEx";
- s.user32=(int)PluginMessageProc;
- SendMessage(plugin.hwndLibraryParent,WM_ML_IPC,(WPARAM)&s,ML_IPC_ADDTOSENDTO);
- }
- }
- else if (message_type == ML_MSG_ONSENDTOSELECT)
- {
- if (param1 == ML_TYPE_ITEMRECORDLIST && param2 && param3 == (int)PluginMessageProc)
- {
- addItemListToSongs((itemRecordList*)param2);
- updateList();
- return 1;
- }
- }
- return 0;
- }
- winampMediaLibraryPlugin plugin =
- {
- MLHDR_VER,
- "ml_ex v0.1",
- init,
- quit,
- PluginMessageProc,
- };
- extern "C" {
- __declspec( dllexport ) winampMediaLibraryPlugin * winampGetMediaLibraryPlugin()
- {
- return &plugin;
- }
- };
|