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

Last change on this file since 178 was 178, checked in by gyoung, 15 months ago

Add Media Play Help and M3U help to their folders help menu

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