source: trunk/mediafolder/c/mediafldr/mediafolderoverridenwpmethods.cpp@ 133

Last change on this file since 133 was 133, checked in by gyoung, 21 months ago

Merge Lar's 2.9 branch into the trunk

File size: 51.9 KB
Line 
1/*
2 * This file is (C) Chris Wohlgemuth 2002
3 *
4 * It's part of the Media-Folder distribution
5 */
6/*
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; see the file COPYING. If not, write to
19 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#define INCL_DOSERRORS
23#define INCL_DOSERRORS
24#define INCL_GPIBITMAPS
25
26#include "mediafolder.hh"
27#include <stdio.h>
28#include <stdlib.h>
29#include <string.h>
30#include "mediafolderres.h"
31#include "menufolder.hh"
32
33#include "sys_funcs.h"
34
35/* typedef for somTP_MMAudio_cwmmQueryTrackInfo */
36/* For calling the method in the CWAudio class. Linking to the DLL would require the
37 new audio classes. By dynamically querying the method the media folder works without
38 installing the audio classes. */
39#include "cwmmquerytrackinfo.h"
40
41extern LOADEDBITMAP allBMPs[];
42extern somTD_MMAudio_cwmmQueryTrackInfo methodPtr;
43
44BOOL g_fRegisteredWindowClass=FALSE;
45ULONG g_ulFrameDataOffset=0;
46
47/* The following offsets will be calclated in wpOpen() */
48ULONG ulQWP_CONTAINERPROC=0;
49ULONG ulQWP_THISPTR=4;
50ULONG ulQWL_TOPCTRLHWND=8;
51ULONG ulQWL_BOTTOMCTRLHWND=12;
52ULONG ulQWL_RIGHTCTRLHWND=16;
53ULONG ulQWL_LEFTCTRLHWND=20;
54
55PFNWP pfnwpGenericFrame;
56
57void errorResource();
58ULONG messageBox( char* text, ULONG ulTextID , LONG lSizeText,
59 char* title, ULONG ulTitleID, LONG lSizeTitle,
60 HMODULE hResource, HWND hwnd, ULONG ulFlags);
61void getMessage(char* text,ULONG ulID, LONG lSizeText, HMODULE hResource,HWND hwnd);
62void sendCommand(char *chrObject, char* command);
63HMODULE queryResModuleHandle(void);
64
65MRESULT EXPENTRY topCtrlDialogProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) ;
66MRESULT EXPENTRY rightCtrlDialogProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) ;
67MRESULT EXPENTRY leftCtrlDialogProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) ;
68MRESULT EXPENTRY bottomCtrlDialogProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) ;
69MRESULT EXPENTRY mediaFrameProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) ;
70MRESULT EXPENTRY mediaFldrContainerProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) ;
71/* This function sets the repeat button checkstate */
72void winCheckRepeatButton(CWMediaFolder *thisPtr);
73/* This function sets the position of the volume slider */
74void winSetVolumeSlider(CWMediaFolder *thisPtr);
75HWND playTimeControlFromFrameHWND(HWND hwndFrame);
76HWND bottomControlFromFrameHWND(HWND hwndFrame);
77HWND playControlDialogFromFrameHWND(HWND hwndFrame);
78HWND topControlFromFrameHWND(HWND hwndFrame);
79
80extern void _Optlink playThreadFunc (void *arg);/* Every folder has one running play thread to handle play commands */
81
82MRESULT cwInsertMenuSeparator(int iPosition, HWND hwndMenu, HWND hwndSubMenu);
83
84SOMClass* somhlpQueryMMAudioClass(void);
85SOMClass* somhlpGetSomClass(char* chrClassName);
86BOOL somhlpQueryCWAudioMethodPtr(CWMediaFolder *thisPtr);
87
88/* ID tag defines */
89#define IDINFO_NAME 1
90#define IDINFO_ARTIST 2
91#define IDINFO_ALBUM 3
92#define IDINFO_YEAR 4
93#define IDINFO_COMMENT 5
94#define IDINFO_GENRE 6
95
96#define IDINFO_PLAYTIME 7
97#define IDINFO_BPS 8
98#define IDINFO_SAMPLERATE 9
99#define IDINFO_CHANNELS 10
100
101#define IDINFO_LASTINFO 10
102
103/***************************************************************/
104/* */
105/* This thread calculates the size of the audio files in this */
106/* folder. It is started by the status line dialog after the */
107/* folder is opened. */
108/* */
109/***************************************************************/
110void _Optlink openThreadFunc (void *arg)
111{
112 HAB hab;
113 HMQ hmq;
114 QMSG qmsg;
115 THREADPARAMS* tPt;
116 CWMediaFolder *thisPtr;
117 MMAudio* cwAudio;
118
119 tPt=(THREADPARAMS*) arg;
120 if(!tPt)
121 return;
122 thisPtr=(CWMediaFolder*)tPt->thisPtr; //Pointer auf CWMediaFolder-Object
123 if(!somIsObj(thisPtr))
124 return;
125
126 hab=WinInitialize(0);
127 if(hab) {
128 hmq=WinCreateMsgQueue(hab,0);
129 if(hmq) {
130 WPObject *wpObject;
131 WPObject *fsObject;
132 HWND hwndContainer;
133 CNRINFO cnrInfo;
134 char text[100];
135 char time[50];
136 int iNum=0;
137 somId mySomId;
138 SOMClass *cwAudioClass=somhlpGetSomClass("MMAudio");
139 ULONG ulSize=0;
140 ULONG ulSecs=0;
141
142 TRY_LOUD(MEDIAFLDR_OPEN_THREAD) {
143 /* Wait until folder is populated */
144 while(!(thisPtr->wpQueryFldrFlags() & FOI_POPULATEDWITHALL))
145 DosSleep(300);
146
147 hwndContainer=WinWindowFromID(tPt->hwndFrame, FID_CLIENT);
148 WinSendMsg(hwndContainer,CM_QUERYCNRINFO, MPFROMP(&cnrInfo),
149 MPFROMLONG(sizeof(cnrInfo)));
150
151 /* Get class object of MMAudio. We need it so we can check if a file is an audio file. */
152 if(somIsObj(cwAudioClass)) {
153 /* We have the class object */
154 char chrBuf[2];
155 /* Get first object in the container */
156 wpObject=thisPtr->wpQueryContent(NULLHANDLE, QC_FIRST);
157 /* Works only for size < 4Gb up to now */
158 while(wpObject)
159 {
160 /* Follow shadows to the filesystem object (if any) */
161 if((fsObject=thisPtr->cwGetFileSystemObject(wpObject))!=NULLHANDLE){/* Filesystem object or NULL */
162 /* Check if the file is an audio file */
163 if(fsObject->somIsA(cwAudioClass)) {
164 /* It's an audio file */
165 if(!methodPtr)
166 somhlpQueryCWAudioMethodPtr(thisPtr);
167 ulSize+=((WPFileSystem*)fsObject)->wpQueryFileSize();
168 iNum++;
169 if(methodPtr)/* Query playtime in secs */
170 ulSecs+=methodPtr((MMAudio*)fsObject, NULLHANDLE, 0, IDINFO_PLAYTIME);
171 }
172 }
173 wpObject=thisPtr->wpQueryContent(wpObject, QC_NEXT);
174 };/* while(wpObject) */
175
176 if(thisPtr->mfData) {
177 thisPtr->mfData->ulTotalTime=ulSecs;
178 thisPtr->mfData->ulNumTracks=iNum;
179 thisPtr->mfData->ulSize=ulSize;
180 thisPtr->mfData->bOpened=TRUE;
181 }
182 /* Set status line text */
183 thisPtr->cwSetStatusLineText(NULLHANDLE);
184 }/* if(somIsObj(cwAudioClass)) */
185 else
186 {
187 /* Error */
188 /* !!!!!!!!!!! Insert messagebox here. !!!!!!!!!!!!!!!*/
189 }
190 }
191 CATCH(MEDIAFLDR_OPEN_THREAD)
192 {
193 SysWriteToTrapLog("\nTrap occured in %s, file: %s, near line %d.\n",
194 __FUNCTION__, __FILE__, __LINE__);
195 } END_CATCH;
196
197 WinDestroyMsgQueue(hmq);
198 }
199 WinTerminate(hab);
200 }
201
202 thisPtr->wpFreeMem((PBYTE)tPt);
203}
204
205
206BOOL CWMediaFolder::wpAddToContent(WPObject* Object)
207{
208 WPFileSystem *fsObject;
209 char time[200];
210 ULONG ulSecs;
211 BOOL rc;
212 static int iCounter=0;
213
214 rc=CWProgFolder::wpAddToContent(Object);
215
216 if(mfData)
217 if(mfData->bOpened)/* Only post notification if the folder was already populated. On first
218 opening a separate thread calculates the contents. */
219 WinPostMsg(hwndBottom, WM_APPTERMINATENOTIFY,MPFROMSHORT(NOTIFY_STARTSTATUSTIMER), 0L);
220
221 iCounter++;
222 if(iCounter==10) {
223 DosSleep(30);/* Yield processor to another thread to prevent WPS blocking */
224 iCounter=0;
225 }
226 return rc;
227 /* On first opening a separate thread calculates the playtime. Doing it this way we don't
228 update the statusbar for every single object. */
229}
230
231BOOL CWMediaFolder::wpDeleteFromContent(WPObject* Object)
232{
233 WPFileSystem *fsObject;
234 char time[200];
235 ULONG ulSecs;
236
237 if(!methodPtr)
238 somhlpQueryCWAudioMethodPtr(this);
239
240 if(methodPtr){
241 if((fsObject=(WPFileSystem*)cwGetFileSystemObject(Object))!=NULLHANDLE){/* Filesystem object or NULL */
242 if(mfData) {
243 /* Query playtime in secs */
244 mfData->ulTotalTime-=methodPtr((MMAudio*)fsObject, NULLHANDLE, 0, IDINFO_PLAYTIME);
245 mfData->ulNumTracks-=1;
246 mfData->ulSize-=fsObject->wpQueryFileSize();
247 cwSetStatusLineText(NULLHANDLE);
248 }
249 }
250 }
251 return CWProgFolder::wpDeleteFromContent(Object);
252}
253
254HWND CWMediaFolder::wpOpen(HWND hwndCnr,ULONG ulView,ULONG ulParam)
255{
256 HWND hwnd;
257 SIZEL sizel={0};
258 HWND myFrameCtrlHWND;
259 RECTL rectl;
260 MENUITEM mi={0};
261 HWND hwndMenu;
262 int iItemCount=0;
263 char text[200];
264 HMODULE hResource=queryResModuleHandle();
265
266 /* Reregister wpFolder window class on first opening */
267 /* We need this private code to have some private
268 window words */
269 if(!g_fRegisteredWindowClass)
270 {
271 CLASSINFO ci;
272
273 if(WinQueryClassInfo(WinQueryAnchorBlock(HWND_DESKTOP),
274 (PSZ)"wpFolder window",
275 &ci))
276 {
277 g_ulFrameDataOffset=ci.cbWindowData;
278 //g_pfnwpOrgFrameProc=ci.pfnWindowProc;
279 if (WinRegisterClass(WinQueryAnchorBlock(HWND_DESKTOP),
280 (PSZ)"wpFolder window",
281 ci.pfnWindowProc,
282 ci.flClassStyle,
283 ci.cbWindowData + MFLDR_WINDOWBYTES))
284 {
285 /* */
286 ulQWP_CONTAINERPROC+=g_ulFrameDataOffset;
287 ulQWP_THISPTR+=g_ulFrameDataOffset;
288 ulQWL_TOPCTRLHWND+=g_ulFrameDataOffset;
289 ulQWL_BOTTOMCTRLHWND+=g_ulFrameDataOffset;
290 ulQWL_LEFTCTRLHWND+=g_ulFrameDataOffset;
291 ulQWL_RIGHTCTRLHWND+=g_ulFrameDataOffset;
292 g_fRegisteredWindowClass=TRUE;
293 }
294 }
295 }
296
297 /* Prevent opening in tree view */
298 if(ulView==OPEN_TREE || ulView==OPEN_CONTENTS)
299 return NULLHANDLE;
300
301#if 0
302 for(pViewItem=wpFindViewItem(VIEW_ANY, NULLHANDLE); pViewItem; pViewItem=wpFindViewItem(VIEW_ANY, pViewItem))
303 iItemCount+=1;
304#endif
305
306 /* Only one open window for now */
307 if(hwndMFldrFrame && ulView!=OPEN_SETTINGS)
308 return NULLHANDLE;
309
310 /* Call parent to build folder window */
311 hwnd=CWProgFolder::wpOpen(hwndCnr, ulView, ulParam);
312
313 /* Only subclass folder frames, not settings notebooks */
314 if(ulView!=OPEN_SETTINGS){
315 if(!hResource) {
316 errorResource();
317 return hwnd;
318 }
319
320 /* Save this ptr */
321 WinSetWindowULong( hwnd, ulQWP_THISPTR, (ULONG)this); /* Moved from outside the if clause */
322
323 hwndMFldrFrame=hwnd;
324
325 TRY_LOUD(MEDIAFLDR_OPEN) {
326 THREADPARAMS* pTp;
327 ULONG ulErr;
328 BOOL bDisabled=FALSE;
329
330 if(!(ulFlags & FLAG_ALREADYSIZED)) {
331 /* Make sure on first open the container is visible */
332 SWP swp;
333 /* Prevent window flickering while resizing */
334 WinEnableWindowUpdate(hwnd, FALSE);
335 bDisabled=TRUE;
336 WinQueryWindowPos(hwnd, &swp);
337 WinSetWindowPos(hwnd, NULLHANDLE, swp.x, swp.y-100, swp.cx, swp.cy+100, SWP_SIZE|SWP_MOVE);
338 ulFlags|=FLAG_ALREADYSIZED;
339 }
340
341 /* Build new menu entries. */
342 myFrameCtrlHWND=WinWindowFromID(hwnd,FID_MENU);//Get menu hwnd
343 if(WinIsWindow(WinQueryAnchorBlock(hwnd), myFrameCtrlHWND)) {
344 /* Menu bar found */
345 if(WinSendMsg(myFrameCtrlHWND,MM_QUERYITEM,MPFROM2SHORT(ID_MBMENUSKRIPTS,FALSE),MPFROMP(&mi))) {
346 /* Script menu is inserted so WPS-Wizard is installed */
347 hwndMenu=mi.hwndSubMenu;
348 if(hwndMenu){
349 // ULONG ulItemId;
350 // ulItemId=cwInsertUserMenuItems(hwndMenu, SKRIPTFOLDER_MEDIAFOLDER, FIRSTUSERITEM, FALSE);
351 /* sprintf(text, " %x",ulItemId);
352 WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, text, "",
353 1234, MB_OK|MB_MOVEABLE);
354 */
355
356 /* The class specific skript menu is inserted in class CWFolder */
357 /* Query the number of items in the menubar */
358 iItemCount=(int)WinSendMsg(hwndMenu,MM_QUERYITEMCOUNT,(MPARAM)0,
359 (MPARAM)0);
360 if(iItemCount)
361 cwInsertUserMenuItems(hwndMenu, USERMENUFOLDER_MEDIAFOLDER, FIRSTUSERITEM, TRUE);
362 else
363 cwInsertUserMenuItems(hwndMenu, USERMENUFOLDER_MEDIAFOLDER, FIRSTUSERITEM, FALSE);
364 }
365 }
366#ifndef ECS
367 else {
368 /* Load the user menu from the resource if WPS-Wizard is not installed. If installed the menu item
369 is added by WPS-Wizzard. */
370 hwndMenu=WinLoadMenu(myFrameCtrlHWND,hResource, ID_MBMENUSKRIPTS);
371 if(hwndMenu){
372 // ULONG ulItemId;
373 // ulItemId=cwInsertUserMenuItems(hwndMenu, SKRIPTFOLDER_MEDIAFOLDER, FIRSTUSERITEM, FALSE);
374 /* sprintf(text, " %x",ulItemId);
375 WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, text, "",
376 1234, MB_OK|MB_MOVEABLE);
377 */
378 /* Query the number of items in the menu */
379 iItemCount=(int)WinSendMsg(hwndMenu,MM_QUERYITEMCOUNT,(MPARAM)0,
380 (MPARAM)0);
381
382 if(iItemCount)
383 cwInsertUserMenuItems(hwndMenu, USERMENUFOLDER_MEDIAFOLDER, FIRSTUSERITEM, TRUE);
384 else
385 cwInsertUserMenuItems(hwndMenu, USERMENUFOLDER_MEDIAFOLDER, FIRSTUSERITEM, FALSE);
386
387 /* Query the number of items in the menubar */
388 iItemCount=(int)WinSendMsg(myFrameCtrlHWND,MM_QUERYITEMCOUNT,(MPARAM)0,
389 (MPARAM)0);
390
391 /* Fill the MENUITEM structure */
392 mi.iPosition=iItemCount-1;
393 mi.afStyle=MIS_TEXT|MIS_SUBMENU;
394 mi.id=ID_MBMENUSKRIPTS;
395 mi.afAttribute=NULL;
396 mi.hwndSubMenu=hwndMenu;
397 mi.hItem=NULL;
398 /* Add the Misc-tools item to the folder menubar */
399 /* Text: "Skripts and tools" */
400 getMessage(text, IDSTR_MENUSKRIPTS,sizeof(text), hResource, hwnd);
401 WinSendMsg(myFrameCtrlHWND,MM_INSERTITEM,MPFROMP(&mi),
402 (MPARAM)text);
403 }/* end of if(hwndMenu) */
404 }
405#endif
406 }/* menu hwnd */
407
408 /* Subclass container for tabbing */
409 myFrameCtrlHWND=WinWindowFromID(hwnd,FID_CLIENT);//Get container hwnd
410 if(myFrameCtrlHWND){
411 PFNWP pfnwpContainer;
412 pfnwpContainer=WinSubclassWindow(myFrameCtrlHWND, mediaFldrContainerProc);
413 /* Save container proc in frame window words */
414 WinSetWindowULong( hwnd, ulQWP_CONTAINERPROC, (ULONG)pfnwpContainer);
415 }
416
417 /* Now add the framecontrols */
418
419 /* This is the Top-frameCtrl. */
420 /* Load the dialog from the resource. The object pointer of this
421 folder is given to the dialog procedure (this). In WM_INITDLG
422 the procedure saves this pointer for later use. */
423 myFrameCtrlHWND=WinLoadDlg(hwnd,hwnd,topCtrlDialogProc,hResource,IDDLG_TOPFRAME ,this);
424 /* Save the HWND in the Window words */
425 WinSetWindowULong( hwnd, ulQWL_TOPCTRLHWND, myFrameCtrlHWND);
426
427 if(myFrameCtrlHWND){
428 /* Query the size of the dialog */
429 WinQueryWindowRect(myFrameCtrlHWND, &rectl);
430 /* It's the top dialog so we need the height but not the width. The width
431 is always the width of the folder. */
432 sizel.cy=allBMPs[MAIN_BMP_IDX].bmpInfoHdr.cy;
433 /* Call a method of CWProgFolder to add the dialog as a framecontrol.
434 FCTL_TOP means put it at the top of the folder.
435 After calling cwUpdateFrame(hwnd) it will be visible */
436 cwAddFrameCtl(hwnd, myFrameCtrlHWND, sizel, FCTL_TOP,0);
437 }
438
439
440 /* Load the dialog from the resource. The object pointer of this
441 folder is given to the dialog procedure (this). In WM_INITDLG
442 the procedure saves this pointer for later use. */
443 myFrameCtrlHWND=WinLoadDlg(hwnd,hwnd,leftCtrlDialogProc,hResource,IDDLG_LEFTFRAME ,this);
444 /* Save the HWND in the Window words */
445 WinSetWindowULong( hwnd, ulQWL_LEFTCTRLHWND, myFrameCtrlHWND);
446
447 if(myFrameCtrlHWND){
448 /* Query the size of the dialog */
449 WinQueryWindowRect(myFrameCtrlHWND, &rectl);
450 /* It's the right dialog so we need the width but not the height. */
451 sizel.cx=allBMPs[CTRLIDX_TOPRIGHT].bmpInfoHdr.cx-1-7-2;//rectl.xRight-rectl.xLeft;
452 /* Call a method of CWProgFolder to add the dialog as a framecontrol.
453 FCTL_RIGHT means put it at the RIGHT of the folder.
454 After calling cwUpdateFrame(hwnd) it will be visible */
455 cwAddFrameCtl(hwnd, myFrameCtrlHWND, sizel, FCTL_LEFT, FCTL_POSABOVE|FCTL_POSBELOW);
456 }
457
458 /* Load the dialog from the resource. The object pointer of this
459 folder is given to the dialog procedure (this). In WM_INITDLG
460 the procedure saves this pointer for later use. */
461 myFrameCtrlHWND=WinLoadDlg(hwnd,hwnd,rightCtrlDialogProc,hResource,IDDLG_FRAMERIGHT ,this);
462 /* Save the HWND in the Window words */
463 WinSetWindowULong( hwnd, ulQWL_RIGHTCTRLHWND, myFrameCtrlHWND);
464
465 if(myFrameCtrlHWND){
466 CNRINFO cnrInfo;
467 HWND hwndContainer;
468 PVIEWITEM pView;
469
470 /* Query the size of the dialog */
471 WinQueryWindowRect(myFrameCtrlHWND, &rectl);
472 /* It's the right dialog so we need the width but not the height. */
473 sizel.cx=allBMPs[CTRLIDX_TOPRIGHT].bmpInfoHdr.cx-1-7-2;// rectl.xRight-rectl.xLeft;
474 /* Call a method of CWProgFolder to add the dialog as a framecontrol.
475 FCTL_RIGHT means put it at the RIGHT of the folder.
476 After calling cwUpdateFrame(hwnd) it will be visible */
477 cwAddFrameCtl(hwnd, myFrameCtrlHWND, sizel, FCTL_RIGHT, FCTL_POSABOVE|FCTL_POSBELOW);
478
479 hwndContainer=WinWindowFromID(myFrameCtrlHWND, IDCNR_PLAYLIST);
480 WinSendMsg(hwndContainer,CM_QUERYCNRINFO, MPFROMP(&cnrInfo),
481 MPFROMLONG(sizeof(cnrInfo)));
482 }/* if(hwndRight) */
483
484
485 /* Load the dialog from the resource. The object pointer of this
486 folder is given to the dialog procedure (this). In WM_INITDLG
487 the procedure saves this pointer for later use. */
488 myFrameCtrlHWND=WinLoadDlg(hwnd,hwnd,bottomCtrlDialogProc,hResource,IDDLG_BOTTOMFRAME ,this);
489 /* Save the HWND in the instance data */
490 hwndBottom=myFrameCtrlHWND;
491 /* Save the HWND in the Window words */
492 WinSetWindowULong( hwnd, ulQWL_BOTTOMCTRLHWND, myFrameCtrlHWND);
493
494 if(hwndBottom){
495 /* Query the size of the dialog */
496 WinQueryWindowRect(hwndBottom,&rectl);
497 //sizel.cy=20;
498 sizel.cy=rectl.yTop-rectl.yBottom-2;
499 // sizel.cy=allBMPs[MAIN_BMP_IDX].bmpInfoHdr.cy;
500 /* Call a method of CWProgFolder to add the dialog as a framecontrol.
501 FCTL_TOP means put it at the top of the folder.
502 After calling cwUpdateFrame(hwnd) it will be visible */
503 cwAddFrameCtl(hwnd, hwndBottom, sizel, FCTL_BOTTOM,0);
504 }
505
506 if(bDisabled) {
507 WinEnableWindowUpdate(hwnd, TRUE);
508 }
509
510 /* Refresh frame to show the new framecontrols */
511 cwUpdateFrame(hwnd);
512
513 pfnwpFrame=WinSubclassWindow(hwnd, mediaFrameProc);
514 pfnwpGenericFrame=pfnwpFrame;
515
516 /* Start play thread handling user input */
517 pTp=(THREADPARAMS*)this->wpAllocMem(sizeof(THREADPARAMS), &ulErr);
518 if(pTp) {
519 pTp->thisPtr=this;
520 pTp->hwndFrame=hwnd;
521 _beginthread(playThreadFunc,NULL,8192*16,(void*)pTp); //Fehlerbehandlung fehlt
522 }
523 }
524 CATCH(MEDIAFLDR_OPEN)
525 {
526 SysWriteToTrapLog("\nTrap occured in %s, file: %s above line %d.\n",
527 __FUNCTION__, __FILE__, __LINE__);
528
529 } END_CATCH;
530 }
531 return hwnd;
532}
533
534/**************************************************************/
535/* */
536/* This thread handles the about dialog. */
537/* */
538/**************************************************************/
539void _Optlink aboutThreadFunc (void *arg)
540{
541 HAB hab;
542 HMQ hmq;
543 QMSG qmsg;
544 CWMediaFolder *thisPtr;
545
546 thisPtr=(CWMediaFolder*)arg; //Pointer auf CWMediaFolder-Object
547 hab=WinInitialize(0);
548 if(hab) {
549 hmq=WinCreateMsgQueue(hab,0);
550 if(hmq) {
551 /* Call the method from CWProgFolder */
552 thisPtr->cwShowAboutDlg(queryResModuleHandle(), IDDLG_ABOUT);
553 WinDestroyMsgQueue(hmq);
554 }
555 WinTerminate(hab);
556 }
557}
558
559/**************************************************************/
560/* */
561/* Override method: */
562/* */
563/**************************************************************/
564BOOL CWMediaFolder::wpSetupOnce(PSZ pSetupString)
565{
566 BOOL rcParent=FALSE;
567 char buffer[CCHMAXPATH];
568 ULONG bufferSize;
569 int iIndex;
570
571 rcParent=CWProgFolder::wpSetupOnce(pSetupString);
572
573 /* Doing our own setup here if not done by the user. */
574 /* Set volume */
575 bufferSize=sizeof(buffer);
576 if(!wpScanSetupString(pSetupString, MEDIAFLDR_VOLUME, buffer,&bufferSize))
577 {
578 ulVolume=70;
579 /* Set position of slider bar */
580 winSetVolumeSlider(this);
581 }
582
583 bufferSize=sizeof(buffer);
584 if(!wpScanSetupString(pSetupString,"DEFAULTVIEW",buffer,&bufferSize))
585 wpSetup( "DEFAULTVIEW=DETAILS");/* Fill in defaults */
586
587 bufferSize=sizeof(buffer);
588 if(!wpScanSetupString(pSetupString,"ICONVIEW",buffer,&bufferSize))
589 wpSetup( "ICONVIEW=NONFLOWED,MINI");/* Fill in defaults */
590
591 /* Size and position of the folder window */
592 bufferSize=sizeof(buffer);
593 if(!wpScanSetupString(pSetupString,"ICONVIEWPOS",buffer,&bufferSize))
594 wpSetup( "ICONVIEWPOS=20,10,60,75");/* Fill in defaults */
595
596 /* Set folder details- and sortclass to CWAudioShadow so track infos are shown */
597 bufferSize=sizeof(buffer);
598 if(!wpScanSetupString(pSetupString,"DETAILSCLASS",buffer,&bufferSize))
599 wpSetup("DETAILSCLASS=CWAudioShadow");/* Fill in defaults */
600
601 bufferSize=sizeof(buffer);
602 if(!wpScanSetupString(pSetupString,"SORTCLASS",buffer,&bufferSize))
603 wpSetup("SORTCLASS=CWAudioShadow");/* Fill in defaults */
604
605 /* This works only on Warp 4 and above */
606 bufferSize=sizeof(buffer);
607 if(!wpScanSetupString(pSetupString,"DETAILSTODISPLAY",buffer,&bufferSize))
608 /* This works only on Warp 4 and above */
609 wpSetup("DETAILSTODISPLAY=0,1,4,12,13,14,15,16,17,18,19,20,21");/* Fill in defaults */
610
611 /* This works only on Warp 4 and above */
612 bufferSize=sizeof(buffer);
613 if(!wpScanSetupString(pSetupString,"SORTBYATTR",buffer,&bufferSize))
614 /* This works only on Warp 4 and above */
615 wpSetup("SORTBYATTR=6,24,25,26,27,28,29,30,31,32,33");/* Fill in defaults */
616
617 return rcParent;
618}
619
620static HWND _findOpenMediaFldrViewHWND(CWMediaFolder *thisPtr)
621{
622 PVIEWITEM pViewItem;
623
624 /* Check if we close a settings view or a folder view. */
625 pViewItem=thisPtr->wpFindViewItem(VIEW_DETAILS|VIEW_CONTENTS, NULLHANDLE);
626 if(pViewItem)
627 return pViewItem->handle;
628
629 return NULLHANDLE;
630}
631
632/**************************************************************/
633/* */
634/* Override method: */
635/* */
636/**************************************************************/
637BOOL CWMediaFolder::wpSetup(PSZ pSetupString)
638{
639 char buffer[CCHMAXPATH];
640 ULONG bufferSize;
641 int tid;
642
643 bufferSize=sizeof(buffer);
644 if(wpScanSetupString(pSetupString, MEDIAFLDR_PLAY_FIRST, buffer,&bufferSize))
645 {
646 HWND hwndFrame=_findOpenMediaFldrViewHWND(this);
647 if(WinIsWindow(WinQueryAnchorBlock(HWND_DESKTOP), hwndFrame)) {
648 HWND hwndCnr=WinWindowFromID(hwndFrame, FID_CLIENT);
649 if(WinIsWindow(WinQueryAnchorBlock(HWND_DESKTOP), hwndCnr)) {
650 PRECORDCORE prc;
651 prc=(PRECORDCORE)WinSendMsg(hwndCnr, CM_QUERYRECORD, 0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
652 WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(prc), MPFROM2SHORT(TRUE, CRA_SELECTED));
653 }
654 cwPlayAudioFile( hwndFrame, PLAY_FIRST);
655 }
656 }
657 bufferSize=sizeof(buffer);
658 if(wpScanSetupString(pSetupString, MEDIAFLDR_PLAY, buffer,&bufferSize))
659 {
660 HWND hwndFrame=_findOpenMediaFldrViewHWND(this);
661 if(WinIsWindow(WinQueryAnchorBlock(HWND_DESKTOP), hwndFrame))
662 cwPlayAudioFile( hwndFrame, PLAY_FIRST);
663 }
664 bufferSize=sizeof(buffer);
665 if(wpScanSetupString(pSetupString, MEDIAFLDR_STOP, buffer,&bufferSize))
666 {
667 HWND hwndFrame=_findOpenMediaFldrViewHWND(this);
668 if(WinIsWindow(WinQueryAnchorBlock(HWND_DESKTOP), hwndFrame))
669 cwStopAudioFile( hwndFrame);
670 }
671 bufferSize=sizeof(buffer);
672 if(wpScanSetupString(pSetupString, MEDIAFLDR_NEXT, buffer,&bufferSize))
673 {
674 HWND hwndFrame=_findOpenMediaFldrViewHWND(this);
675 if(WinIsWindow(WinQueryAnchorBlock(HWND_DESKTOP), hwndFrame))
676 cwPlayAudioFile( hwndFrame, PLAY_NEXT);
677 }
678 bufferSize=sizeof(buffer);
679 if(wpScanSetupString(pSetupString, MEDIAFLDR_PREV, buffer,&bufferSize))
680 {
681 HWND hwndFrame=_findOpenMediaFldrViewHWND(this);
682 if(WinIsWindow(WinQueryAnchorBlock(HWND_DESKTOP), hwndFrame))
683 cwPlayAudioFile( hwndFrame, PLAY_PREV);
684 }
685
686 /* Set volume */
687 bufferSize=sizeof(buffer);
688 if(wpScanSetupString(pSetupString, MEDIAFLDR_VOLUME, buffer,&bufferSize))
689 {
690 ulVolume=atol(buffer);
691 if(ulVolume<0)
692 ulVolume=0;
693 else if(ulVolume>100)
694 ulVolume=100;
695 /* Set position of slider bar */
696 winSetVolumeSlider(this);
697 }
698 /* Set repeat */
699 bufferSize=sizeof(buffer);
700 if(wpScanSetupString(pSetupString, MEDIAFLDR_REPEAT, buffer,&bufferSize))
701 {
702 switch(atol(buffer))
703 {
704 case 0:
705 ulFlags&=~FLAG_REPEAT;
706 winCheckRepeatButton(this);
707 break;
708 case 1:
709 ulFlags|=FLAG_REPEAT;
710 winCheckRepeatButton(this);
711 break;
712 }
713 ulVolume=atol(buffer);
714 }
715
716 /* Set object window HWND */
717 bufferSize=sizeof(buffer);
718 if(wpScanSetupString(pSetupString, "M3UOBJECTWINDOW", buffer,&bufferSize))
719 {
720 hwndObject=atol(buffer);
721 }
722
723 /* Set object pointer to M3U-File */
724 bufferSize=sizeof(buffer);
725 if(wpScanSetupString(pSetupString, "M3UOBJECTHANDLE", buffer,&bufferSize))
726 {
727 WPObject *wpObject;
728
729 wpObjM3UFile=NULLHANDLE;
730 wpObject=(WPObject*)atol(buffer);
731 if(somIsObj(wpObject))
732 wpObjM3UFile=wpObject;
733 }
734
735 /* Insert tracks */
736 bufferSize=sizeof(buffer);
737 if(wpScanSetupString(pSetupString, "INSERTTRACKS", buffer,&bufferSize))
738 {
739 cwInsertAllTracks(NULLHANDLE);
740 }
741
742 /* FIXME: Use immediate parent here !!!! */
743 return CWProgFolder::wpSetup(pSetupString);
744}
745
746
747/**************************************************************/
748/* */
749/* Added with V0.2.8 (07.09.2003) */
750/* */
751/* This method is only overriden to set a flag in the instance*/
752/* data so the wpInsertSettingsPage() method knows when */
753/* the details page is inserted. */
754/* */
755/* This is done because the details page needs a major tab */
756/* when the icon page is removed. The necessary style bit */
757/* is set in wpInsertSettingsPage(). */
758/* */
759/**************************************************************/
760ULONG CWMediaFolder::wpAddFolderView3Page(HWND hwndNotebook)
761{
762 ULONG rc;
763
764 /* Mark in the instance data from where we're coming */
765 ulPrivFlags|=MFLDR_CURACTION_ADDFOLDERVIEW3;
766
767 rc=CWProgFolder::wpAddFolderView3Page(hwndNotebook);
768
769 ulPrivFlags&= ~MFLDR_CURACTION_ADDFOLDERVIEW3;
770 return rc;
771}
772
773/**************************************************************/
774/* */
775/* Override method: Remove the Icon view settings page. */
776/* */
777/* Added with V0.2.8 (07.09.2003) */
778/**************************************************************/
779ULONG CWMediaFolder::wpAddFolderView1Page(HWND hwndNotebook)
780{
781 /*
782 Removing this page also means removing the XWorkplace
783 view page. It would be possible to call the XWP method
784 directly to insert it's page but unfortunately XWP is a moving
785 target without frozen interfaces/methods so every new
786 XWP release is likely to break any code relying on certain
787 XWP features so nothing is done to keep the XWP pages.
788 */
789 return SETTINGS_PAGE_REMOVED;
790}
791
792/**************************************************************/
793/* */
794/* Override method: Remove the tree view settings page. */
795/* */
796/**************************************************************/
797ULONG CWMediaFolder::wpAddFolderView2Page(HWND hwndNotebook)
798{
799 return SETTINGS_PAGE_REMOVED;
800}
801
802/**************************************************************/
803/* */
804/* Added with V0.2.8 (07.09.2003) */
805/* */
806/* Overriden to give the details view page a major tab */
807/* because the icon view page is removed. */
808/* */
809/* */
810/**************************************************************/
811ULONG CWMediaFolder::wpInsertSettingsPage(HWND hwndNotebook, PPAGEINFO ppageinfo)
812{
813 somId mySomId;
814
815 /* V0.2.8 (07.09.2003):
816
817 Removing the icon page isn't that easy because if doing so we lose the major tab
818 and the details page will become a second background page.
819 So in wpAddFolderView3Page() we set a flag in the instance data telling us here
820 from where we are coming. The BKA_MAJOR style bit is switched on so
821 a tab is displayed.
822 This is only part of the solution because normaly there's no name for
823 the details view page. So a string must be loaded and inserted into the
824 ppageinfo.
825
826 */
827 if(ulPrivFlags & MFLDR_CURACTION_ADDFOLDERVIEW3) /* Check if called from wpAddFolderView3Page() */
828 {
829 char chr[50]="~View";
830
831 /* Get title for the page */
832 getMessage(chr, IDSTR_VIEWPAGENAME, sizeof(chr), queryResModuleHandle(), hwndNotebook);
833
834 ppageinfo->usPageStyleFlags|=BKA_MAJOR; /* Switch on major tab */
835 ppageinfo->pszName=chr;
836 }
837 /*
838
839 Climb up the list of parents to make sure we call the right
840 method if the parent was replaced. Otherwise we may skip a replacement class
841 and call CWProgFolder directly.
842
843 */
844 if((mySomId=somIdFromString("wpInsertSettingsPage"))!=NULLHANDLE) {
845 ULONG rc;
846 rc=((somTD_WPObject_wpInsertSettingsPage)
847 somParentNumResolve(__ClassObject->somGetPClsMtabs(),
848 1,
849 __ClassObject->
850 somGetMethodToken(mySomId))
851 )(this, hwndNotebook, ppageinfo);
852 SOMFree(mySomId);
853 return rc;
854 }
855 else
856 return CWProgFolder::wpInsertSettingsPage(hwndNotebook, ppageinfo);
857}
858
859
860/**************************************************************/
861/* Override function: Add the 'About' and the 'Compact' menu */
862/* items. */
863/**************************************************************/
864BOOL CWMediaFolder::wpMenuItemSelected(HWND hwndFrame,ULONG ulMenuId)
865{
866 BOOL rcParent;
867 int tid;
868
869 switch(ulMenuId)
870 {
871 //#ifndef ECS
872 case ID_ABOUTITEM:
873 tid=_beginthread(aboutThreadFunc,NULL,8192*8,this); //Fehlerbehandlung fehlt
874 return TRUE;
875 //#endif
876 case 0x2ce: /* Detail view */
877 /* Call parent */
878#if 0
879 if(cwUnshrinkFolder(hwndFrame))
880 ulPrivFlags&=MFLDR_CHANGING_VIEW; /* Mark that we are changing views.
881 This flag is checked in CWCDFldr::wpRefresh() to know if it's
882 necessary to reinsert the tracks */
883#endif
884 rcParent=CWProgFolder::wpMenuItemSelected(hwndFrame, ulMenuId);
885 cwUnshrinkFolder(hwndFrame);
886 ulPrivFlags&= ~MFLDR_VIEW_COMPACT;
887 return rcParent;
888 case ID_MENUVIEWCOMPACT: /* Compact view */
889 if(cwShrinkFolderToCompact(hwndFrame)) {
890 /* Mark that we are in compact view. May be removed later when 'Compact'
891 is an 'official' view?
892 */
893 ulPrivFlags|=MFLDR_VIEW_COMPACT;
894 }
895 return TRUE;
896 default:
897 break;
898 }
899
900 /* Call parent */
901 rcParent=CWProgFolder::wpMenuItemSelected(hwndFrame, ulMenuId);
902 return rcParent;
903}
904
905/************************************************/
906/* Override function: Add the 'About' and the */
907/* 'Compact' menu items. */
908/************************************************/
909BOOL CWMediaFolder::wpModifyPopupMenu(HWND hwndMenu, HWND hwndCnr, ULONG ulPosition)
910{
911 HMODULE hResource=queryResModuleHandle();
912
913 if(hResource) {
914 //#ifndef ECS
915 /* Insert the 'About'-Item */
916 wpInsertPopupMenuItems(hwndMenu,-1,hResource,ID_MENUABOUT,WPMENUID_HELP);
917 //#endif
918
919 /* Insert the new 'Compact' view item but only if folder not already in compact view.
920 By doing that the 'compact' menu item doesn't show in the Sysmenu of the folder when
921 folder is shrinked.
922 */
923 if(!(cwQueryMFldrFlags() & MFLDR_VIEW_COMPACT))
924 wpInsertPopupMenuItems(hwndMenu,1,hResource, ID_MENUVIEWCOMPACT, MENUID_VIEW);
925 }
926 return CWProgFolder::wpModifyPopupMenu( hwndMenu, hwndCnr, ulPosition);
927}
928
929/************************************************/
930/* Override function: Remove the tree view open */
931/* item from the menu. */
932/************************************************/
933ULONG CWMediaFolder::wpFilterPopupMenu(ULONG ulFlags, HWND hwndCnr, BOOL fMultiSelect)
934{
935 somId mySomId;
936
937 /* V0.2.8 (07.09.2003):
938 Removed icon view item form menu. Icon view is no longer supported by
939 the media folder.
940
941 Changed to climb up the list of parents to make sure we call the right
942 method if the parent was replaced. Otherwise we may skip a replacement class
943 and call CWProgFolder directly.
944
945 */
946 if((mySomId=somIdFromString("wpFilterPopupMenu"))!=NULLHANDLE) {
947 ULONG rc;
948 rc=((somTD_WPObject_wpFilterPopupMenu)
949 somParentNumResolve(__ClassObject->somGetPClsMtabs(),
950 1,
951 __ClassObject->
952 somGetMethodToken(mySomId))
953 )(this, ulFlags, hwndCnr, fMultiSelect);
954 SOMFree(mySomId);
955 return rc & ~( CTXT_TREE | CTXT_ICON);
956 }
957 else
958 return CWProgFolder::wpFilterPopupMenu( ulFlags, hwndCnr, fMultiSelect) & ~( CTXT_TREE | CTXT_ICON);
959}
960
961//#if 0
962BOOL CWMediaFolder::wpRefresh(ULONG ulView, PVOID pReserved)
963{
964 somId mySomId;
965 ULONG rc;
966
967 if((mySomId=somIdFromString("wpRefresh"))!=NULLHANDLE) {
968 rc=((somTD_WPFileSystem_wpRefresh)
969 somParentNumResolve(__ClassObject->somGetPClsMtabs(),
970 1,
971 __ClassObject->
972 somGetMethodToken(mySomId))
973 )(this, ulView,pReserved);
974 SOMFree(mySomId);
975 }
976 else
977 rc=CWProgFolder::wpRefresh(ulView, pReserved);
978
979 /* Start timer which triggers time calculation */
980 WinStartTimer(WinQueryAnchorBlock(hwndBottom),hwndBottom, IDTIMER_STATUS, 300);
981 return rc;
982}
983//#endif
984
985BOOL CWMediaFolder::wpAddSettingsPages(HWND hwndNotebook)
986{
987 ULONG rc;
988 somId mySomId;
989
990 if((mySomId=somIdFromString("wpAddSettingsPages"))!=NULLHANDLE) {
991 rc=((somTD_WPObject_wpAddSettingsPages)
992 somParentNumResolve(__ClassObject->somGetPClsMtabs(),
993 1,
994 __ClassObject->
995 somGetMethodToken(mySomId))
996 )(this,hwndNotebook);
997 SOMFree(mySomId);
998 }
999 else
1000 rc=CWProgFolder::wpAddSettingsPages(hwndNotebook);
1001
1002 if(!queryResModuleHandle()) {
1003 errorResource();
1004 return rc;
1005 }
1006 return(rc/* && cwAddToolbarOptionPage(hwndNotebook)*/);
1007}
1008
1009
1010MRESULT CWMediaFolder::wpDragOver(HWND hwndCnr,PDRAGINFO pDragInfo)
1011{
1012 WPObject *wpObject;
1013 USHORT usIndicator=DOR_DROP,usOp=DO_LINK;
1014 SOMClass *mmAudioClass = somhlpGetSomClass("MMAudio");
1015 SOMClass *cdTrackClass = somhlpGetSomClass("MMCDTrack");
1016
1017 if (DrgAccessDraginfo(pDragInfo)) {
1018 ULONG ulNum=DrgQueryDragitemCount(pDragInfo);/* Num items */
1019 ULONG a=0;
1020
1021 for(a=0;a<ulNum; a++)
1022 {
1023 PDRAGITEM pDragItem = DrgQueryDragitemPtr(pDragInfo,a);
1024 if (!DrgVerifyRMF(pDragItem,"DRM_OBJECT","DRF_OBJECT")) {
1025 usIndicator = DOR_NEVERDROP;
1026 usOp = 0;
1027 goto quit;
1028 } /* endif */
1029 /* Check every object dragged */
1030 wpObject=(WPObject*)OBJECT_FROM_PREC(pDragItem->ulItemID);
1031 if (!somIsObj(wpObject) || !wpObject->somIsA(mmAudioClass) || wpObject->somIsA(cdTrackClass)) {
1032 usIndicator = DOR_NEVERDROP;
1033 usOp = 0;
1034 goto quit;
1035 } /* endif */
1036#if 0
1037 if (somIsObj(wpObject) && this->wpQueryFolder() == wpObject->wpQueryFolder()) {
1038 usIndicator = DOR_DROP;
1039 usOp = DO_LINK;
1040 } /* endif */
1041#endif
1042 }
1043 /* Do not create shadows if the source is the current container */
1044 if(hwndCnr==pDragInfo->hwndSource) {
1045 usIndicator = DOR_DROP;
1046 usOp = DO_MOVE;
1047 }
1048
1049quit:
1050 DrgFreeDraginfo(pDragInfo);
1051 } /* endif */
1052
1053 return MRFROM2SHORT(usIndicator,usOp);
1054}
1055
1056void _Optlink dropThreadFunc (void *arg)
1057{
1058 HAB hab;
1059 HMQ hmq;
1060 QMSG qmsg;
1061 PDROPTHREADPARAMS threadParams;
1062 CWMediaFolder *thisPtr;
1063 MMAudio* cwAudio;
1064 HWND hwndCnr;
1065
1066 threadParams=(PDROPTHREADPARAMS) arg;
1067 if(!threadParams)
1068 return;
1069 thisPtr=(CWMediaFolder*)threadParams->thisPtr; //Pointer auf CWMediaFolder-Object
1070
1071 if(!somIsObj(thisPtr))
1072 return;
1073
1074 if(thisPtr->mfData)
1075 thisPtr->mfData->bProcessing=TRUE;
1076
1077 hab=WinInitialize(0);
1078 if(hab) {
1079 hmq=WinCreateMsgQueue(hab,0);
1080 if(hmq) {
1081 WPObject *wpObject;
1082 somId mySomId;
1083 M_WPObject *mAudioObject;
1084 SOMClass* scCWShadowClass;
1085 ULONG ulCount;
1086 ULONG ulNumObjects;
1087 /* Needed for specifying the drop point */
1088 POINTL ptl;
1089 PMINIRECORDCORE pmrc;
1090 CNRINFO cnrInfo;
1091 int ID;
1092 HWND hwndSource;
1093
1094 hwndCnr=threadParams->hwndCnr;
1095
1096 /* The objects are already checked by the wpDragOver() method. */
1097
1098 TRY_LOUD(MEDIAFLDR_DROP_THREAD) {
1099 hwndSource=threadParams->hwndSource;
1100 ulNumObjects=threadParams->ulNumObjects;
1101
1102 if((mySomId=somIdFromString(SHADOW_CLASS_NAME))!=NULLHANDLE) {
1103 WPFileSystem *wpFSObject;
1104 /* Get the CWAudioShadow class object */
1105 scCWShadowClass=(SOMClass*)SOMClassMgrObject->somClassFromId(mySomId);
1106 SOMFree(mySomId);
1107 /* Check shadow class */
1108 if(somIsObj(scCWShadowClass)) {
1109 if(hwndSource!=hwndCnr){/* Dropped on white space of an open folder */
1110 QUERYRECFROMRECT qRecRcl;
1111 ptl.x=threadParams->ptl.x;
1112 ptl.y=threadParams->ptl.y;
1113
1114 /* Map to CNR */
1115 WinMapWindowPoints(HWND_DESKTOP, hwndCnr,&ptl, 1);
1116 ptl.y+=10;
1117 /* Window below the mouse ptr. We need it to check if we are over the column title area. */
1118 ID=WinQueryWindowUShort(WinWindowFromPoint(hwndCnr,&ptl, TRUE),QWS_ID);
1119 ptl.y-=10;
1120
1121 /* Find the record near the drop point */
1122 qRecRcl.cb=sizeof(qRecRcl);
1123 qRecRcl.rect.yBottom=ptl.y-10;
1124 qRecRcl.rect.yTop=ptl.y;
1125 qRecRcl.rect.xLeft=ptl.x;
1126 qRecRcl.rect.xRight=ptl.x+10;
1127 qRecRcl.fsSearch=CMA_PARTIAL|CMA_ITEMORDER;
1128 pmrc=(PMINIRECORDCORE)WinSendMsg(hwndCnr, CM_QUERYRECORDFROMRECT,MPFROMLONG(CMA_FIRST),
1129 MPFROMP(&qRecRcl));
1130 WinSendMsg(hwndCnr, CM_QUERYCNRINFO, MPFROMP(&cnrInfo), MPFROMSHORT(sizeof(cnrInfo)));
1131 }/*if(hwndSource!=hwndCnr)*/
1132
1133 /* For all dropped objects */
1134 for(ulCount=0; ulCount<ulNumObjects; ulCount++) {
1135 if(ulCount%10)/* Redraw window every 10 objects */
1136 WinEnableWindowUpdate(hwndCnr, FALSE);
1137 else
1138 WinEnableWindowUpdate(hwndCnr, TRUE);
1139
1140 wpObject=(WPObject*) threadParams->wpObject[ulCount];
1141 /* Get the filesystem object in case it's a shadow */
1142 wpFSObject=(WPFileSystem*)thisPtr->cwGetFileSystemObject(wpObject);
1143 if(somIsObj(wpFSObject)){
1144 if(hwndSource==hwndCnr)/* The folder is closed or dropped on the folder icon. */
1145 wpFSObject->wpCreateShadowObjectExt(thisPtr, FALSE, "", (M_WPObject*)scCWShadowClass);
1146 else {
1147 /* Dropped on white space of the folder */
1148 WPObject *wpo;
1149 if(cnrInfo.flWindowAttr& CV_DETAIL)
1150 {
1151 /* Detailsview */
1152 RECORDINSERT recInsert;
1153
1154 recInsert.cb=sizeof(recInsert);
1155 recInsert.pRecordParent=NULL;
1156 recInsert.fInvalidateRecord=TRUE;
1157 recInsert.zOrder=CMA_TOP;
1158 recInsert.cRecordsInsert=1;
1159
1160 // WinEnableWindowUpdate(hwndCnr, FALSE);
1161 /* Create the shadow */
1162 // wpo=
1163 //wpFSObject->wpCreateShadowObject(thisPtr, FALSE);
1164 wpo=wpFSObject->wpCreateShadowObjectExt(thisPtr, FALSE, "",
1165 (M_WPObject*) scCWShadowClass);
1166 /* Move the record to the right position in the details view */
1167 if(somIsObj(wpo)) {
1168 wpo->wpCnrRemoveObject(hwndCnr);
1169 // WinEnableWindowUpdate(hwndCnr, TRUE);
1170 if(pmrc && ((int)pmrc)!=-1) {
1171 recInsert.pRecordOrder=(PRECORDCORE)pmrc;
1172 /* Insert at the right place. For some reason wpSetNextIconPos() does not work!? */
1173 wpo->wpCnrInsertObject(hwndCnr, &ptl, NULL, &recInsert);
1174 }
1175 else {
1176 /* No record found check if we are at the top or the bottom */
1177 if(ID!=0x7ff0 && ID!=0x7ff1)
1178 recInsert.pRecordOrder=(PRECORDCORE)CMA_END;
1179 else
1180 recInsert.pRecordOrder=(PRECORDCORE)CMA_FIRST;
1181 /* Insert at the right place. For some reason wpSetNextIconPos() does not work!? */
1182 wpo->wpCnrInsertObject(hwndCnr, &ptl, NULL, &recInsert);
1183 }
1184 }/* if(somIsObj(wpo)) */
1185 // WinEnableWindowUpdate(hwndCnr, TRUE);
1186 }/* if(cnrInfo.flWindowAttr& CV_DETAIL) */
1187 else
1188 /* Icon view */
1189 wpo=wpFSObject->wpCreateShadowObjectExt(thisPtr, FALSE, "", (M_WPObject*) scCWShadowClass);
1190 if(somIsObj(wpo))
1191 wpo->wpCnrRefreshDetails();
1192 }/* else(hwndSource==hwndCnr) */
1193 }/* if(somIsObj(wpFSObject)) */
1194 }/* for(ulCount=0;ulCount<ulNumObjects ; ulCount++) */
1195 WinEnableWindowUpdate(hwndCnr, TRUE);
1196 }/* if(somIsObj(scCWShadowClass)) */
1197 }/* if((mySomId=somIdFromString(SHADOW_CLASS_NAME))!=NULLHANDLE)*/
1198 }/* Try */
1199 CATCH(MEDIAFLDR_DROP_THREAD)
1200 {
1201 SysWriteToTrapLog("\nTrap occured in %s, file: %s, line %d.\n",
1202 __FUNCTION__, __FILE__, __LINE__);
1203 } END_CATCH;
1204
1205 WinDestroyMsgQueue(hmq);
1206 }
1207 WinTerminate(hab);
1208 }
1209 if(thisPtr->mfData)
1210 thisPtr->mfData->bProcessing=FALSE;
1211
1212 thisPtr->wpFreeMem((PBYTE)threadParams);
1213}
1214
1215
1216
1217MRESULT CWMediaFolder::wpDrop(HWND hwndCnr,PDRAGINFO pDragInfo,PDRAGITEM pDragItem)
1218{
1219 if (DrgAccessDraginfo(pDragInfo)) {
1220 /* The objects are already checked by the wpDragOver() method. */
1221 TRY_LOUD(MEDIAFLDR_DROP) {
1222 PDROPTHREADPARAMS pThreadParams;
1223 ULONG ulErr;
1224 ULONG ulCount;
1225 ULONG ulNumObjects=DrgQueryDragitemCount(pDragInfo);
1226
1227 /* DROPTHREADPARAMS already contains one WPObject var so only memory for ulNumObjects-1 must be added to the end */
1228 pThreadParams=(PDROPTHREADPARAMS)wpAllocMem(sizeof(DROPTHREADPARAMS)+(ulNumObjects-1)*sizeof(WPObject*), &ulErr);
1229 pThreadParams->hwndCnr=hwndCnr;
1230 pThreadParams->hwndSource=pDragInfo->hwndSource;
1231 pThreadParams->ulNumObjects=ulNumObjects;
1232 pThreadParams->thisPtr=this;
1233 pThreadParams->ptl.x=pDragInfo->xDrop;
1234 pThreadParams->ptl.y=pDragInfo->yDrop;
1235
1236 /* For all dropped objects */
1237 for(ulCount=0;ulCount<ulNumObjects ; ulCount++) {
1238 pThreadParams->wpObject[ulCount]=(WPObject*)OBJECT_FROM_PREC(DrgQueryDragitemPtr( pDragInfo, ulCount)->ulItemID);
1239 }
1240 _beginthread(dropThreadFunc,NULL,8192*16,(void*)pThreadParams); //Fehlerbehandlung fehlt
1241 }
1242 CATCH(MEDIAFLDR_DROP)
1243 {
1244 SysWriteToTrapLog("\nTrap occured in %s, file: %s, around line %d.\n",
1245 __FUNCTION__, __FILE__, __LINE__);
1246 } END_CATCH;
1247 DrgFreeDraginfo(pDragInfo);
1248 }
1249 return MRFROMLONG(RC_DROP_DROPCOMPLETE);
1250}
1251
1252
1253BOOL CWMediaFolder::wpSaveState()
1254{
1255
1256 wpSaveLong("CWMediaFolder", KEY_VOLUME, ulVolume);
1257 // wpSaveData("CWMediaFolder", KEY_FLYBACKGROUND, (PBYTE)&rgbTBFlyBackground, sizeof(RGB));
1258 // wpSaveData("CWMediaFolder", KEY_FLYFOREGROUND, (PBYTE)&rgbTBFlyForeground,sizeof(RGB));
1259 // wpSaveString("CWMediaFolder", KEY_FLYFONT, (PBYTE)&chrTBFlyFontName);
1260 // wpSaveLong("CWMediaFolder", KEY_FLYENABLED,bTBFlyOverEnabled);
1261 // wpSaveLong("CWMediaFolder", KEY_FLYDELAY,iTBFlyOverDelay);
1262 wpSaveLong("CWMediaFolder", KEY_FLAGS, ulFlags);
1263 wpSaveLong("CWMediaFolder", KEY_DISPLAYTYPE, (LONG)usWhichDisplay);
1264 if(mfData)
1265 wpSaveString("CWMediaFolder", KEY_PLAYTIMEFONT, (PBYTE)&mfData->chrPlayTimeFont);
1266 return CWProgFolder::wpSaveState();
1267}
1268
1269BOOL CWMediaFolder::wpRestoreState(ULONG ulReserved)
1270{
1271 ULONG dataSize;
1272 ULONG ulActionButtons;
1273
1274
1275 if(!wpRestoreLong("CWMediaFolder", KEY_VOLUME, &ulVolume))
1276 ulVolume=75;
1277#if 0
1278 if(!wpRestoreLong("CWMediaFolder", KEY_FLYENABLED,&bTBFlyOverEnabled))
1279 bTBFlyOverEnabled=1;
1280 if(!wpRestoreLong("CWMediaFolder", KEY_FLYDELAY,(PULONG)&iTBFlyOverDelay))
1281 iTBFlyOverDelay=250;
1282#endif
1283 if(!wpRestoreLong("CWMediaFolder", KEY_FLAGS,(PULONG)&ulFlags))
1284 ulFlags=0;
1285 if(!wpRestoreLong("CWMediaFolder", KEY_DISPLAYTYPE,(PULONG)&dataSize))
1286 usWhichDisplay=0;
1287 else
1288 usWhichDisplay=(USHORT)dataSize;
1289
1290#if 0
1291 dataSize=sizeof(RGB);
1292 if(!wpRestoreData("CWMediaFolder", KEY_FLYBACKGROUND,(PBYTE)&rgbTBFlyBackground,&dataSize)) {
1293 rgbTBFlyBackground.bBlue=180;
1294 rgbTBFlyBackground.bGreen=255;
1295 rgbTBFlyBackground.bRed=255;
1296 }
1297
1298 dataSize=sizeof(RGB);
1299 if(!wpRestoreData("CWMediaFolder",KEY_FLYFOREGROUND,(PBYTE)&rgbTBFlyForeground,&dataSize)) {
1300 rgbTBFlyForeground.bRed=0;
1301 rgbTBFlyForeground.bGreen=0;
1302 rgbTBFlyForeground.bBlue=0;
1303 }
1304
1305 memset(chrTBFlyFontName,0,sizeof(chrTBFlyFontName));
1306 dataSize=sizeof(chrTBFlyFontName);
1307 if(!wpRestoreString("CWMediaFolder",KEY_FLYFONT,(PBYTE)&chrTBFlyFontName,&dataSize))
1308 memcpy(&chrTBFlyFontName,"8.Helv",sizeof("8.Helv"));
1309#endif
1310
1311 if(mfData)
1312 {
1313 dataSize=sizeof(mfData->chrPlayTimeFont);
1314 wpRestoreString("CWMediaFolder", KEY_PLAYTIMEFONT,(PBYTE)&mfData->chrPlayTimeFont, &dataSize);
1315 }
1316
1317 return CWProgFolder::wpRestoreState(ulReserved);
1318}
1319
1320
1321BOOL CWMediaFolder::cwClose(HWND hwndFrame)
1322{
1323 char text[200];
1324 char title[50];
1325 HWND hwndOwner=HWND_DESKTOP;
1326
1327 /* Check if we currently play a song */
1328 if(iWave && !(ulPrivFlags & MFLDR_SHOWING_MBOX)) {
1329 LONG lDelay;
1330
1331#if 0
1332 PVIEWITEM pViewItem;
1333 int a=0;
1334 /* Check if we close a settings view or a folder view. */
1335 for(pViewItem=wpFindViewItem(VIEW_ANY, NULLHANDLE); pViewItem; pViewItem=wpFindViewItem(VIEW_ANY, pViewItem))
1336 a+=1;
1337 if(a!=1)
1338 return TRUE;
1339#endif
1340
1341 if(hwndFrame!=hwndMFldrFrame)
1342 return TRUE;
1343
1344 if(WinIsWindow(WinQueryAnchorBlock(HWND_DESKTOP), hwndFrame))
1345 hwndOwner=hwndFrame;
1346
1347 /* Start a timer which will cause the folder to close automatically after some time even
1348 if the user doesn't click any button. Get the timeout from the INI file if available. */
1349 if((lDelay=PrfQueryProfileInt(HINI_USERPROFILE, "CWMM", MFLDR_TIMER_DELAY_KEY, MFLDR_MBOX_TIMER_DELAY))
1350 < MFLDR_MBOX_MIN_TIMER_DELAY)
1351 lDelay=MFLDR_MBOX_MIN_TIMER_DELAY;
1352
1353 WinStartTimer(WinQueryAnchorBlock(HWND_DESKTOP), hwndFrame, MFLDR_MBOX_TIMER_ID, lDelay);
1354 ulPrivFlags|= MFLDR_SHOWING_MBOX;
1355 /* Ask user if he really wants to stop playing and close the folder */
1356 if(messageBox( text, IDSTR_CLOSETEXT, sizeof(text),
1357 title, IDSTR_CLOSETITLE, sizeof(title),
1358 queryResModuleHandle(), hwndOwner, MB_YESNO|MB_MOVEABLE|MB_ICONQUESTION)==MBID_NO) {
1359 WinStopTimer(WinQueryAnchorBlock(HWND_DESKTOP), hwndFrame, MFLDR_MBOX_TIMER_ID);
1360 ulPrivFlags&= ~MFLDR_SHOWING_MBOX;
1361 return FALSE;
1362 }
1363 }
1364 cwStopAudioFile(hwndFrame);
1365 /* Stop the playing thread */
1366 WinPostMsg(mfData->hwndPlayObject, WM_QUIT, 0, 0);
1367
1368 /* We were opened by an M3U file. Notify it that we're closing */
1369 if(WinIsWindow(WinQueryAnchorBlock(HWND_DESKTOP), hwndObject)) {
1370 WinPostMsg(hwndObject, WM_APPTERMINATENOTIFY, 0, 0);
1371 }
1372
1373 ulPrivFlags&= ~(MFLDR_VIEW_COMPACT|MFLDR_SHOWING_MBOX);
1374 hwndMFldrFrame=NULL;
1375 wpSaveDeferred();
1376 return TRUE;
1377}
1378
1379void CWMediaFolder::wpInitData()
1380{
1381 ULONG ulErr;
1382 /*
1383 FIXME:
1384 This init call of the parent should be changed to allow replacement of
1385 CWProgFolder.
1386 */
1387 CWProgFolder::wpInitData();
1388 /* Get storage for private data. */
1389 if((mfData=(PMEDIAFLDRDATA)wpAllocMem(sizeof(MEDIAFLDRDATA), &ulErr))!=NULLHANDLE)
1390 memset((void*)mfData, 0, sizeof(MEDIAFLDRDATA));
1391
1392 ulPrivFlags=0;
1393}
1394
1395void CWMediaFolder::wpUnInitData()
1396{
1397 if(mfData)
1398 wpFreeMem((PBYTE)mfData);
1399
1400 /*
1401 FIXME:
1402 This uninit call of the parent should be changed to allow replacement of
1403 CWProgFolder.
1404 */
1405 CWProgFolder::wpUnInitData();
1406}
1407
1408
1409
1410
1411
Note: See TracBrowser for help on using the repository browser.