home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Misc / DC-POS24.LZX / pOS / pOS_RKRM.lzx / pOS_RKRM / pIntui / MultiList.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-03-18  |  25.1 KB  |  847 lines

  1.  
  2. /*******************************************************************
  3.  $CRT 14 Jan 1997 : hp
  4.  
  5.  $AUT Holger Burkarth
  6.  $DAT >>MultiList.c<<   30 Jan 1997    11:25:29 - (C) ProDAD
  7. *******************************************************************/
  8.  
  9. //##ex mcpp:cppc -gs -o pos:pos/Ex/MultiList p:pLib/StartCode.o p:/pOS_RKRM/pIntui/MultiList.c p:pLib/StdIO.o -l pOSStub -l pOS -l CPPList
  10.  
  11.  
  12. // StormC:StormSys/StormC -g20 -gD -gC -O9 -pp -i p: -i ci: -i cc:include -wEPRTcV p:/pOS_RKRM/pIntui/MultiList.c
  13. // StormC:StormSys/StormLink p:pLib/StartCode.o p:/pOS_RKRM/pIntui/MultiList.o To pos:pos/Ex/MultiList LIBPATH ram:lib LIB pOSStub pOS CPPList LOG ram:lib/logfile OOP
  14.  
  15. /***********************************************************
  16.   pOS programing example - Copyright (C) 1995-97 proDAD
  17.  
  18.   This code was written as an easy to understand example,
  19.   how to program pOS features. It is provided 'as-is',
  20.   without any express or implied warranty.
  21.  
  22.   Permission is hereby granted to use, copy and modify
  23.   this source code for any purpose, without fee, subject
  24.   to the following conditions:
  25.  
  26.     (1) This notice may not be removed or altered from any
  27.         source distribution.
  28.  
  29.     (2) Altered source versions must be plainly marked as
  30.         such, and must not be misrepresented as being
  31.         the original source code.
  32.  
  33.     (3) If only executable code is distributed, then the
  34.         accompanying documentation have to state that
  35.         "this software is based in part on examples of
  36.         the pOS developer packet".
  37.  
  38.     (4) Permission for use of this code is granted only
  39.         if the user accepts full responsibility for any
  40.         undesirable consequences. proDAD accept NO LIABILITY
  41.         for damages of any kind.
  42.  
  43.   ©proDAD
  44. ***********************************************************/
  45.  
  46. #include <p:pExec/Types.h>
  47. #include <p:pExec/List.h>
  48. #include <p:pExec/Memory.h>
  49. #include <p:Device/Walker.h>
  50. #include <p:pDOS/ArgTags.h>
  51. #include <p:pDOS/DosArgs.h>
  52. #include <p:pDOS/DosBase.h>
  53. #include <p:pDOS/Files.h>
  54. #include <p:pDOS/DosSig.h>
  55. #include <p:pDOS/Lock.h>
  56. #include <p:pDOS/FIB.h>
  57. #include <p:pDOS/DosTags.h>
  58. #include <p:pDOS/Process.h>
  59. #include <p:pDtType/DtTags.h>
  60. #include <p:pDtType/Ascii.h>
  61. #include <p:pDtType/DClass.h>
  62. #include <p:pDtType/DosObj.h>
  63. #include <p:pIntui/IObj.h>
  64. #include <p:pIntui/GClass.h>
  65. #include <p:pIntui/OClass.h>
  66. #include <p:pIntui/Tags.h>
  67. #include <p:pIntui/IntuMsg.h>
  68. #include <p:pGadget/GadItem.h>
  69. #include <p:pGadget/Gadget.h>
  70. #include <p:pScreen/DrawInfo.h>
  71. #include <p:pScreen/Window.h>
  72. #include <p:pScreen/Screen.h>
  73. #include <p:pScreen/ScrTags.h>
  74. #include <p:proto/pExec2.h>
  75. #include <p:proto/pIntui2.h>
  76. #include <p:proto/pDOS2.h>
  77. #include <p:proto/pList.h>
  78. #include <p:proto/pLibExt.h>
  79. #include <p:proto/pDtType2.h>
  80.  
  81.  
  82. #ifdef __cplusplus
  83. extern "C" {
  84. #endif
  85.  
  86. #include <string.h>
  87. #include <stdio.h>
  88.  
  89. #ifdef __cplusplus
  90. }
  91. #endif
  92.  
  93.  
  94. const CHAR *HelpText=
  95. ""
  96. ;
  97.  
  98. const CHAR *PrgHeader=
  99. "";
  100.  
  101. const CHAR *PrgVerText=
  102. "$VER: 1.0 ("__DATE2__") (Copyright 1996-97 by proDAD) (Created by Holger Papajewski)";
  103.  
  104.  
  105. struct pOS_IntuiDevice  *gb_IntuiBase;
  106. struct pOS_GfxBase      *gb_GfxBase;
  107. struct pOS_DataTypeBase *gb_DtTypeBase;
  108.  
  109.  
  110.  
  111. /*\
  112. *** Buffer für das aktuelle Dir
  113. *** und für die Statusanzeige
  114. \*/
  115. #define DIRBUFSIZE  (pOS_DosFileName_MAX + pOS_DosPathName_MAX + 16)
  116. #define STATBUFSIZE 128
  117. static CHAR DirBuf[DIRBUFSIZE] = "";
  118. static CHAR StatBuf[STATBUFSIZE] = "Status:";
  119.  
  120.  
  121. /*\
  122. *** erweiterte pOS_GadgetItem Struktur
  123. *** es wird zusätzlich noch der FileName aufgenommen
  124. \*/
  125. struct GfxGadItem
  126. {
  127.   pOS_GadgetItem ggi_GI;
  128.   CHAR           ggi_Name[pOS_DosFileName_MAX];
  129. };
  130.  
  131.  
  132. /*\
  133. *** alle wichtigen Pointer & Strukturen
  134. \*/
  135. struct DemoData
  136. {
  137.   pOS_List      dd_GfxList;  // die Liste des ListViews
  138.   pOS_Window   *dd_Win;      // Zeiger auf unser Window
  139.   pOS_Gadget   *dd_ListGad;  // das ListViewGadget
  140.   pOS_Gadget   *dd_StatGad;  // die TextBox für die Status-Anzeige
  141.  
  142.   pOS_WalkerIO  dd_WIO;      // der IORequest für den Walker
  143. };
  144.  
  145.  
  146.  
  147. /*----------------------------------
  148. Erzeugt einen neuen Eintrag für das ListView,
  149. Fügt diesen in die Liste ein und
  150. Läßt den neuen Eintrag zeichnen
  151. -----------------------------------*/
  152. VOID InsertGfx(const pOS_FileLock *dirLk, const pOS_FileInfoBlock *fib,
  153.   pOS_List *list, pOS_Gadget *gad, pOS_Window *win )
  154. {
  155.   CHAR Buf[64];
  156.  
  157.   const pOS_DrawInfo *Dri = win->win_Screen->scr_DrawInfo;
  158.   pOS_IntuiObj       *gfxObj;
  159.   pOS_IntuiObj       *nameObj;
  160.   pOS_IntuiObj       *sizeObj;
  161.   GfxGadItem         *GfxGI;
  162.  
  163. /*\
  164. *** IObj für Grafiken erzeugen
  165. *** Wenn das IGfxObj nicht erzeugt werden kann, dann ist
  166. *** die Datei kein Bild bzw. keine Animation
  167. \*/
  168.   gfxObj = (pOS_IntuiObj*)pOS_NewIObject( NULL,"igfx.class",0,
  169.     ICLTAG_DrawInfo,            (ULONG)Dri,
  170.     IOGFXTAG_FileName,          (ULONG)fib->fib_FileName,
  171.     IOGFXTAG_CurrLock,          (ULONG)dirLk,
  172.     TAG_DONE );
  173.  
  174.   if( gfxObj ) {
  175. /*\
  176. *** Speicher für neuen Listeneintrag
  177. \*/
  178.     GfxGI = (GfxGadItem*)pOS_AllocMem(sizeof(GfxGadItem),MEMF_CLEAR);
  179.  
  180.     if( GfxGI ) {
  181. /*\
  182. *** FileNamen in unseren GadItem kopieren
  183. \*/
  184.       strcpy( GfxGI->ggi_Name, fib->fib_FileName );
  185.  
  186. /*\
  187. *** IObj für den Namen und die Größe erzeugen
  188. \*/
  189.       nameObj = (pOS_IntuiObj*)pOS_NewIObject( NULL, "itext.class", 0,
  190.         ICLTAG_DrawInfo,          (ULONG)Dri,
  191.         IOBJTAG_StaticString,     (ULONG)GfxGI->ggi_Name,
  192.         TAG_DONE );
  193.  
  194.       pOS_SPrintf( Buf, "Size:%ld", fib->fib_Size );
  195.       sizeObj = (pOS_IntuiObj*)pOS_NewIObject( NULL, "itext.class", 0,
  196.         ICLTAG_DrawInfo,          (ULONG)Dri,
  197.         IOBJTAG_String,           (ULONG)Buf,
  198.         TAG_DONE );
  199.  
  200.       if( nameObj && sizeObj ) {
  201.  
  202. /*\
  203. *** Die drei IObj. sollen nebeneinander in der Liste angezeigt werden
  204. *** dazu müssen wir sie nur miteinander verketten und dann
  205. *** im GadgetItem->gdt_Render eintragen
  206. ***
  207. *** gfxObj -> nameObj -> sizeObj
  208. \*/
  209.  
  210.         nameObj->iobj_Next = sizeObj;
  211.         gfxObj->iobj_Next  = nameObj;
  212.         GfxGI->ggi_GI.gdt_Render = gfxObj;
  213.  
  214. /*\
  215. *** GadItem in Liste einfügen &
  216. *** der Liste anzeigen, daß neue Einträge hinzugekommen sind
  217. *** (LVGADTAG_HasNewNodes)
  218. *** neuen Eintrag zeichen lassen (LVGADTAG_RedrawItem)
  219. \*/
  220.         pOS_LockIntuiGadget(win);  // *** WICHTIG
  221.         pOS_ListAddTail( list, &GfxGI->ggi_GI.gdt_Node );
  222.         pOS_SetGadgetAttrs( win, gad,
  223.           LVGADTAG_HasNewNodes, TRUE,
  224.           LVGADTAG_RedrawItem, (ULONG)GfxGI, TAG_DONE );
  225.         pOS_UnlockIntuiGadget(win);
  226.       }
  227.       else {
  228.         pOS_DisposeIObject( gfxObj );
  229.         if( sizeObj ) pOS_DisposeIObject( sizeObj );
  230.         if( nameObj ) pOS_DisposeIObject( nameObj );
  231.         if( GfxGI ) pOS_FreeMem( GfxGI, sizeof(GfxGadItem));
  232.       }
  233.     }
  234.     else pOS_DisposeIObject( gfxObj );
  235.   }
  236. }
  237.  
  238.  
  239.  
  240. /*----------------------------------
  241. Löschen der Liste des ListView-Gadgets
  242. -----------------------------------*/
  243. VOID DeleteGfxList( pOS_List *list, pOS_Gadget *gad, pOS_Window *win )
  244. {
  245.   GfxGadItem *Succ,*GfxGI;
  246.  
  247. /*\
  248. *** gesamte Liste durchlaufen
  249. *** ACHTUNG der Nachfolger muß ermittelt werden, bevor
  250. *** der aktuelle Eintrag gelöscht wird
  251. \*/
  252.   GfxGI = (GfxGadItem*)list->lh_Head;
  253.   while( Succ = (GfxGadItem*)GfxGI->ggi_GI.gdt_Node.ln_Succ ) {
  254.  
  255. /*\
  256. *** Falls das Fenster geöffnet ist - aktuelle Eintrag als ungültig
  257. *** markieren
  258. \*/
  259.     if( gad && win )
  260.       pOS_SetGadgetAttrs( win, gad, LVGADTAG_InvalidItem, (ULONG)GfxGI, TAG_DONE );
  261.  
  262. /*\
  263. *** aktuellen Eintrag aus der Liste entfernen
  264. *** verkettete Liste mit IObjekten löschen
  265. *** Speicher des GadItem freigeben
  266. *** und zum Nächsten
  267. \*/
  268.     pOS_ListRemove( &GfxGI->ggi_GI.gdt_Node );
  269.     pOS_IObjDisposeList( GfxGI->ggi_GI.gdt_Render );
  270.     pOS_FreeMem( GfxGI, sizeof(GfxGadItem));
  271.     GfxGI = Succ;
  272.   }
  273.  
  274. /*\
  275. *** falls das Fenster geöffnet ist - Liste nun neuzeichnen
  276. *** sowie die Vorberechnung der Spaltenbreite zurücksetzen
  277. \*/
  278.   if( gad && win ) {
  279.     pOS_SetGadgetAttrs( win, gad, LVGADTAG_ResetKetArray, TRUE, TAG_DONE );
  280.     pOS_RefreshGadgets( win, gad, 1 );
  281.   }
  282. }
  283.  
  284.  
  285.  
  286.  
  287. /*----------------------------------
  288. Asynchrone ScanRoutine - wird mit Hilfe des Walker.device gestartet
  289. Fügt das übergebene Bild bzw. alle Bilder des Verzeichnisses ein
  290. -----------------------------------*/
  291. VOID WalkerScanGfxDir(_R_A1 pOS_WalkerIO *wio )
  292. {
  293. /*\
  294. *** im UserData[0] des pOS_WalkerIO befindet sich ein Pointer
  295. *** auf unsere Daten
  296. \*/
  297.   pOS_List    *list = &((DemoData*)wio->wio_UserData[0])->dd_GfxList;
  298.   pOS_Gadget  *gad  = ((DemoData*)wio->wio_UserData[0])->dd_ListGad;
  299.   pOS_Gadget  *stat = ((DemoData*)wio->wio_UserData[0])->dd_StatGad;
  300.   pOS_Window  *win  = ((DemoData*)wio->wio_UserData[0])->dd_Win;
  301.  
  302.   pOS_FileInfoBlock *FIB;
  303.   pOS_FileLock      *DirLk;
  304.   BOOL Abort = FALSE;
  305.  
  306. /*\
  307. *** FileInfoBlock erzeugen
  308. *** ACHTUNG: der FIB muß über pOS_AllocDosObject erzeugt werden
  309. \*/
  310.   if( FIB = (pOS_FileInfoBlock*)pOS_AllocDosObject( DOSOBJ_FIB, 0 )) {
  311.     if( DirLk = pOS_LockObject( NULL, DirBuf, FILELKACC_Shared )) {
  312.       if( pOS_ExamineObject( DirLk, FIB )) {
  313.         if( FIB->fib_DirEntryType == FINFENTYP_Dir ) {
  314.           while( pOS_ExNextObject( DirLk, FIB )) {
  315.             if( FIB->fib_DirEntryType == FINFENTYP_File ) {
  316.               pOS_SPrintf( StatBuf, "Status: Insert '%s' ",
  317.                 FIB->fib_FileName );
  318.               pOS_RefreshGadgetsMd( win, stat, 1, GCLMTHRE_Update );
  319.  
  320.               InsertGfx( DirLk, FIB, list, gad, win );
  321.             }
  322.  
  323. /*\
  324. *** DOSSIGF_CTRL_C regelmäßig abfragen
  325. *** sollte das Hauptprogramm ein AbortIO auslösen - bekommen wir
  326. *** ein CTRL C
  327. *** die Arbeit sollte dann so schnell wie nur möglich eingestellt
  328. *** werden
  329. \*/
  330.             if( pOS_SetSignal(0,DOSSIGF_CTRL_C) & DOSSIGF_CTRL_C) {
  331.               Abort = TRUE;
  332.               break;
  333.             }
  334.           }
  335.         }
  336.         else {
  337.           pOS_FileLock *Lk = pOS_ParentObjectDir(DirLk);
  338.  
  339.           if( Lk ) {
  340.             pOS_SPrintf( StatBuf, "Status: Insert '%s' ",
  341.               FIB->fib_FileName );
  342.             pOS_RefreshGadgetsMd( win, stat, 1, GCLMTHRE_Update );
  343.  
  344.             InsertGfx( Lk, FIB, list, gad, win );
  345.  
  346.             pOS_UnlockObject( Lk );
  347.           }
  348.         }
  349.       }
  350.       pOS_UnlockObject( DirLk );
  351.     }
  352.     pOS_FreeDosObject(DOSOBJ_FIB,FIB);
  353.   }
  354.  
  355.   strcpy( StatBuf, Abort ? "Status: Break" : "Status: Ready " );
  356.   pOS_RefreshGadgetsMd( win, stat, 1, GCLMTHRE_Update );
  357. }
  358.  
  359.  
  360. /*----------------------------------
  361. Walker.device öffnen und IO vorbereiten
  362. -----------------------------------*/
  363. BOOL OpenWalker( DemoData *dData )
  364. {
  365.   BOOL res=FALSE;
  366.  
  367. /*\
  368. *** pOS_WalkerIO initialisieren
  369. *** Begin_func ist unsere Funktion, die asynch. ausgeführt werden soll
  370. *** Abort_func wird bei einem AbortIO aufgerufen - nicht benötigt
  371. *** in UserData[0] kommt der Pointer auf unsere Daten
  372. *** UserData[1] benutzen wir, um uns zu merken, ob der Walker
  373. *** gestartet wurde
  374. \*/
  375.   dData->dd_WIO.wio_StackSize  = 8*1024;
  376.   dData->dd_WIO.wio_Begin_func = WalkerScanGfxDir;
  377.   dData->dd_WIO.wio_Abort_func = NULL;
  378.   dData->dd_WIO.wio_UserData[0]= (ULONG)dData;
  379.   dData->dd_WIO.wio_UserData[1]= FALSE;
  380.  
  381. /*\
  382. *** Device öffnen und restliche Werte in IO setzen
  383. *** als ReplyPort können wir unseren ProcessPort benutzen
  384. *** Command ist CMD_WRITE
  385. \*/
  386.   if(pOS_OpenDevice("walker.device",0,(pOS_IORequest*)&dData->dd_WIO,0,0)==0) {
  387.     dData->dd_WIO.wio_Message.mn_ReplyPort =
  388.       &((pOS_Process*)pOS_FindTask(NULL))->pr_MsgPort;
  389.     dData->dd_WIO.wio_Command = CMD_WRITE;
  390.     dData->dd_WIO.wio_Flags   = 0;
  391.  
  392.     res = TRUE;
  393.   }
  394.   else printf("Cannot Open Walker.device\n");
  395.  
  396.   return(res);
  397. }
  398.  
  399.  
  400. /*----------------------------------
  401. Startet die Walker-Routine
  402. Diese wird nun asynchron ausgeführt
  403. -----------------------------------*/
  404. VOID StartWalker( pOS_WalkerIO *io )
  405. {
  406. /*\
  407. *** der IO kann immer wieder versendet werden, ohne die Daten
  408. *** neu zu setzen, da ein Device nur den Error-Wert setzen darf
  409. \*/
  410.   pOS_SendIO((pOS_IORequest*)io );
  411.   if( io->wio_Error == 0 )
  412.     io->wio_UserData[1] = TRUE; // alles Ok - die Routine läuft
  413. }
  414.  
  415.  
  416. /*----------------------------------
  417. Asynchone Walker-Routine abbrechen
  418. -----------------------------------*/
  419. VOID StopWalker( pOS_WalkerIO *io )
  420. {
  421. /*\
  422. *** Routine abbrechen und Message vom Port entfernen (pOS_WaitIO)
  423. *** Sollte die Routine schon beendet sein, so wird nur die
  424. *** Nachricht vom Port entfernt
  425. \*/
  426.   if( io->wio_UserData[1] ) {
  427.     pOS_AbortIO((pOS_IORequest*)io);
  428.     pOS_WaitIO((pOS_IORequest*)io);
  429.  
  430.     io->wio_UserData[1] = FALSE; // Walker läuft nicht
  431.   }
  432. }
  433.  
  434.  
  435.  
  436.  
  437.  
  438. /*----------------------------------
  439. Auf Drop reagieren
  440. Mit Hilfe des ASCII-Datatypes wird der Name des DOSObjs ermittelt
  441. Die Liste wird dann gelöscht & der Walker wird gestartet
  442. -----------------------------------*/
  443. VOID HandleDD( const pOS_IEDragDrop *iedd, DemoData *dData )
  444. {
  445.   pOS_DtTypeAscii DT;
  446.   pOS_DClassInfo  DC={pOS_DTFORM_ASCII,NULL,DCLINFOF_None,&DT};
  447.                   pOS_DCLASSINFO(&DC);
  448.  
  449. /*\
  450. *** Zuerst alten Walker-Process beenden
  451. \*/
  452.   StopWalker( &dData->dd_WIO );
  453.  
  454. /*\
  455. *** Name des DOSObjs vom Datatype ermitteln
  456. \*/
  457.   DT.dtasc_Buffer = DirBuf;
  458.   DT.dtasc_BufSize= DIRBUFSIZE;
  459.   if(pOS_LoadDTObjectA(iedd->iedd_Object,&DC,NULL)) {
  460.  
  461.     if( DC.dci_Result > 0 ) {
  462.       DirBuf[DC.dci_Result]='\0';
  463.  
  464. /*\
  465. *** aktuelle Liste löschen und neuen WindowTitel setzen
  466. \*/
  467.       DeleteGfxList(&dData->dd_GfxList,dData->dd_ListGad,dData->dd_Win);
  468.       pOS_SetWindowTitles( dData->dd_Win, DirBuf, (CHAR*)~0 );
  469.  
  470. /*\
  471. *** Walker-Routine wieder starten - neu Einscannen
  472. *** StartWalker & StopWalker können beliebig oft wiederholt werden
  473. \*/
  474.       StartWalker( &dData->dd_WIO );
  475.     }
  476.   }
  477. }
  478.  
  479.  
  480.  
  481. /*----------------------------------
  482. Auf Drag-Anforderung reagieren
  483. Es wird ein DosObjekt erzeugt und zurückgegeben
  484. -----------------------------------*/
  485. pOS_DataType *MakeDDObject( DemoData *dData )
  486. {
  487.   pOS_DataType *DtObj=NULL;
  488.   GfxGadItem   *GfxGI=NULL;
  489.   pOS_FileLock *DirLk = pOS_LockObject(NULL,DirBuf,FILELKACC_Shared);
  490.  
  491.   pOS_GetGadgetAttr(dData->dd_Win,dData->dd_ListGad,
  492.     LVGADTAG_DragItem, (ULONG*)&GfxGI );
  493.  
  494.   if( GfxGI && DirLk ) {
  495.     pOS_FileInfoBlock *FIB=(pOS_FileInfoBlock*)pOS_AllocDosObject(DOSOBJ_FIB,0);
  496.  
  497.     if( FIB ) {
  498.       if( pOS_ExamineObject(DirLk,FIB)) {
  499.         if( FIB->fib_DirEntryType == FINFENTYP_File ) {
  500.           pOS_FileLock *Parent = pOS_ParentObjectDir( DirLk );
  501.           pOS_UnlockObject( DirLk );
  502.           DirLk = Parent;
  503.         }
  504.       }
  505.       pOS_FreeDosObject(DOSOBJ_FIB,FIB);
  506.     }
  507.  
  508.     DtObj = (pOS_DataType*)pOS_NewIObject(NULL, pOS_DTNAME_DOSOBJ, 0,
  509.       DOSOBJTAG_Name,   (ULONG)GfxGI->ggi_Name,
  510.       DOSOBJTAG_Lock,   (ULONG)DirLk,
  511.       TAG_DONE );
  512.   }
  513.  
  514.   if( DirLk )
  515.     pOS_UnlockObject( DirLk );
  516.  
  517.   return(DtObj);
  518. }
  519.  
  520.  
  521.  
  522.  
  523. /*----------------------------------
  524. Startet GfxView, um das Bild anzuzeigen
  525. GfxView wird asynch. mit Hilfe der Funktion pOS_System gestartet
  526. -----------------------------------*/
  527. VOID StartViewer( const CHAR *dir, pOS_Gadget *gad, pOS_Window *win )
  528. {
  529. /*\
  530. *** Buffer zum erzeugen des Befehls allokieren &
  531. *** Lock auf das BildVerzeichnis holen
  532. \*/
  533.   CHAR         *Buf   = (UBYTE*)pOS_AllocMem( 1024, MEMF_ANY );
  534.   pOS_FileLock *CurLk = pOS_LockObject( NULL, dir, FILELKACC_Shared );
  535.   GfxGadItem   *GfxGI = NULL;
  536.  
  537. /*\
  538. *** selektieren Item aus der Liste ermitteln
  539. \*/
  540.   pOS_GetGadgetAttr( win, gad, LVGADTAG_SelectItem, (ULONG*)&GfxGI );
  541.  
  542.   if( GfxGI && CurLk && Buf) {
  543.     pOS_FileInfoBlock *FIB=(pOS_FileInfoBlock*)pOS_AllocDosObject(DOSOBJ_FIB,0);
  544.  
  545.     if( FIB ) {
  546.       if( pOS_ExamineObject(CurLk,FIB)) {
  547.         if( FIB->fib_DirEntryType == FINFENTYP_File ) {
  548.           pOS_FileLock *Parent = pOS_ParentObjectDir( CurLk );
  549.           pOS_UnlockObject( CurLk );
  550.           CurLk = Parent;
  551.         }
  552.       }
  553.       pOS_FreeDosObject(DOSOBJ_FIB,FIB);
  554.     }
  555.  
  556. /*\
  557. *** Befehl im Buffer aufbereiten & mit pOS_System starten
  558. *** der Lock auf das BildVerzeichnis wird als CurrentDir-Lock
  559. *** für den neuen Process übergeben. Da der Befehl asynch. ausgeführt
  560. *** wird dürfen wir den Lock nicht wieder freigeben. Diese Aufgabe
  561. *** hat pOS, wenn GfxView beendet wird. Dazu muß allerdings von uns
  562. *** das PROCF_FreeCurrDir Flag gesetzt werden.
  563. \*/
  564.  
  565.     pOS_SPrintf( Buf, "Sys:Ex/GfxView \"%s\"", GfxGI->ggi_Name );
  566.     pOS_System( Buf,
  567.       DOSTAG_CurrDirLock,       (ULONG)CurLk,
  568.       DOSTAG_ProcFlags,         PROCF_FreeCurrDir,
  569.       DOSTAG_Synchronous,       FALSE,
  570.       DOSTAG_CrtHomeShell,      TRUE,   // erzeuge Shell-Umgebung
  571.       TAG_DONE);
  572.   }
  573.   else {
  574.     if( CurLk ) pOS_UnlockObject( CurLk );
  575.   }
  576.  
  577.   if( Buf ) pOS_FreeMem( Buf, 1024 );
  578. }
  579.  
  580.  
  581.  
  582.  
  583.  
  584. #ifdef __cplusplus
  585. extern "C"
  586. #endif
  587.  
  588. void main( void )
  589. {
  590.   ULONG Ops[1] = {(ULONG)"Sys:Games/Stones"};
  591.   pOS_DosArgs *Args;
  592.  
  593.   gb_IntuiBase=(struct pOS_IntuiDevice*)pOS_OpenLibrary("pintui.library",0);
  594.   gb_GfxBase=(struct pOS_GfxBase*)pOS_OpenLibrary("pgraphics.library",0);
  595.   gb_DtTypeBase=(struct pOS_DataTypeBase*)pOS_OpenLibrary("pDtType.library",0);
  596.  
  597. /*\
  598. *** Argumente lesen
  599. *** Default-Werte werden vorher im Array abgelegt
  600. \*/
  601.   Args=pOS_ReadDosArgs( "Dir",Ops,sizeof(Ops)/sizeof(ULONG),
  602.     ARGTAG_PrgHeaderText, (ULONG)PrgHeader,    /* kurze Programm-Beschreibung */
  603.     ARGTAG_HelpText,      (ULONG)HelpText,     /* Help-Texte */
  604.     ARGTAG_PrgVerText,    (ULONG)PrgVerText,   /* VER-String */
  605.     TAG_END);
  606.  
  607.   if( Args ) {
  608.     pOS_Screen  *Scr;
  609.  
  610.     strcpy(DirBuf,(CHAR*)Ops[0]);
  611.  
  612. /*\
  613. *** Pointer auf Screen ermitteln
  614. \*/
  615.     if( Scr = pOS_LockPubScreen("Workbench")) {
  616.       const pOS_DrawInfo *Dri = Scr->scr_DrawInfo;
  617.       pOS_Gadget  *GrpGad;
  618.       DemoData     DData;
  619.  
  620.       memset( &DData, 0, sizeof(DData));
  621. /*\
  622. *** die leere Liste initialisieren &
  623. *** das ListView Gadget erzeugen
  624. ***
  625. *** StandardDrop, AddDropAttName  - wir können DOSObj. empfangen
  626. *** StandardDrag, AddDragAttName  - wir können DOSObj. versenden
  627. *** RelVerify - bei Doppelklick IDCMP_GadgetUp Message
  628. *** List - das ist unsere noch leere Liste
  629. *** CursorSelect - Items können mit den Cursortasten angewählt werden
  630. *** VAutoGad, HAutoGad - Scroller werder von der Liste erzeugt
  631. *** HAutoKt - die Verkettung der IObj. soll beachtet werden,
  632. ***           muß für eine mehrspaltige Liste gesetzt werden
  633. ***
  634. \*/
  635.       pOS_ListInit( &DData.dd_GfxList );
  636.       if( DData.dd_ListGad = (pOS_Gadget*)pOS_NewIObject( NULL,
  637.         Dri->dri_Names[SCRNAM_GLVClass], 0,
  638.         ICLTAG_DrawInfo,        (ULONG)Dri,
  639.         ICLTAG_Gwk,             1,
  640.         ICLTAG_StandardDrop,    TRUE,
  641.         ICLTAG_AddDropAttName,  (ULONG)"#?dosobj/#?",
  642.         ICLTAG_StandardDrag,    TRUE,
  643.         ICLTAG_AddDragAttName,  (ULONG)"/dosobj/",
  644.         ICLTAG_RelVerify,       TRUE,
  645.         LVGADTAG_Space,         3,
  646.         LVGADTAG_List,          (ULONG)&DData.dd_GfxList,
  647.         LVGADTAG_CursorSelect,  TRUE,
  648.         LVGADTAG_MultiSelect,   TRUE,
  649.         LVGADTAG_VAutoGad,      TRUE,
  650.         LVGADTAG_HAutoGad,      TRUE,
  651.         LVGADTAG_HAutoKt,       TRUE,
  652.         LVGADTAG_Key1,          TRUE,
  653.         LVGADTAG_CR,            TRUE,
  654.         TAG_DONE)) {
  655.  
  656. /*\
  657. *** GroupGadget erzeugen
  658. *** das AutoSizeGadget für das Window MUSS IMMER eine Gruppe sein
  659. *** ICLTAG_AutoDelete == TRUE - Gadget wird beim Schließen des Fensters
  660. *** automatisch gelöscht
  661. *** die Gruppe löscht ebenfalls alle ihre Members
  662. \*/
  663.         if( GrpGad = (pOS_Gadget*)pOS_NewIObject( NULL,
  664.           Dri->dri_Names[SCRNAM_GGroupClass], 0,
  665.           ICLTAG_DrawInfo,      (ULONG)Dri,
  666.           ICLTAG_AutoDelete,    TRUE,
  667.           GRPGADTAG_BorLeft,    4,
  668.           GRPGADTAG_BorTop,     4,
  669.           GRPGADTAG_BorRight,   4,
  670.           GRPGADTAG_BorBottom,  4,
  671.           GRPGADTAG_AddGadget,  (ULONG)DData.dd_ListGad,
  672.           TAG_DONE )) {
  673.  
  674. /*\
  675. *** StatusGadget für den unteren WindowRand erzeugen
  676. *** zuerst lassem wir uns den Dimensionen des Fensterrandes berechnen
  677. *** die X-Position und die Breite des Gadget werden relativ zu den
  678. *** Fensterdimensionen angegeben. Das Gadget wird später alle
  679. *** Größenänderungen des Fensters mitmachen.
  680. \*/
  681.           pOS_WBox Box;
  682.           pOS_GetWindowBorder( Scr, &Box,
  683.             WINFLGF_SizeBBottom | WINFLGF_SizeBRight,
  684.             GFLG_RelWidth | GFLG_RelBottom, GACT_BottomBorder);
  685.  
  686.           DData.dd_StatGad = (pOS_Gadget*)pOS_NewIObject( NULL,
  687.             Dri->dri_Names[SCRNAM_GTxtBoxClass], 0,
  688.             ICLTAG_DrawInfo,            (ULONG)Dri,
  689.             ICLTAG_GadBorderType,       0,
  690.             ICLTAG_AutoDelete,          TRUE,
  691.             ICLTAG_Left,                Box.Left+3,
  692.             ICLTAG_RelBottom,           Box.Top+2,
  693.             ICLTAG_RelWidth,            Box.Width-6,
  694.             ICLTAG_Height,              Box.Height-4,
  695.             ICLTAG_BottomBorder,        TRUE,
  696.             ICLTAG_RenderLayMode,       IOBLAY_Left,
  697.             IOBJTAG_StaticString,       (ULONG)StatBuf,
  698.             TAG_DONE);
  699.  
  700. /*\
  701. *** Fenster öffnen
  702. *** die Gruppe mit dem ListView wird per SCRTAG_AutoSizeGadget übergeben
  703. *** das StatusGadget (im FensterRand) per SCRTAG_Gadget
  704. \*/
  705.           if( DData.dd_Win = pOS_OpenWindow(
  706.             SCRTAG_Title,       (ULONG)DirBuf,
  707.             SCRTAG_Screen,      (ULONG)Scr,
  708.             SCRTAG_Flags,       WINFLGF_DepthGadget | WINFLGF_SimpleRefresh |
  709.                                 WINFLGF_Activate | WINFLGF_CloseGadget |
  710.                                 WINFLGF_Dragbar | WINFLGF_SizeBBottom |
  711.                                 WINFLGF_SizeGadget,
  712.             SCRTAG_IDCMP,       IDCMP_CloseWindow | IDCMP_StdSysMsg,
  713.             SCRTAG_AutoSizeGadget, (ULONG)GrpGad,
  714.             SCRTAG_Gadget,      (ULONG)DData.dd_StatGad,
  715.             SCRTAG_Height,      200,
  716.             SCRTAG_UnderMouse,  TRUE,
  717.             TAG_DONE )) {
  718.  
  719.  
  720.             pOS_SetWindowTask( DData.dd_Win, pOS_FindTask(NULL),
  721.               1, 0 );
  722. /*\
  723. *** Walker.device öffnen
  724. \*/
  725.             if( OpenWalker( &DData )) {
  726.  
  727.               pOS_IntuiMessage  *Msg;
  728.               BOOL  Run=TRUE;
  729.               ULONG WinSig  = 1L<<DData.dd_Win->win_UserPort->mp_SigBit;
  730.               ULONG SigMask = DOSSIGF_CTRL_C | WinSig;
  731.               ULONG Sig;
  732.  
  733. /*\
  734. *** asynchronen Scanvorgang starten
  735. \*/
  736.               StartWalker( &DData.dd_WIO );
  737.  
  738.               while( Run ) {
  739.                 Sig = pOS_WaitSignal( SigMask );
  740.  
  741. /*\
  742. *** CTRL C -- Programm sofort beenden
  743. \*/
  744.                 if( Sig & DOSSIGF_CTRL_C ) Run = FALSE;
  745.  
  746. /*\
  747. *** Messages vom Fenster auswerten
  748. \*/
  749.                 if( Sig & WinSig ) {
  750.  
  751.                   while( Msg=(pOS_IntuiMessage*)pOS_GetMsg(DData.dd_Win->win_UserPort)) {
  752.                     switch( Msg->im_Class ) {
  753. // -----
  754.                       case IDCMP_CloseWindow:
  755.                         Run = FALSE;
  756.                         break;
  757. // -----
  758.                       case IDCMP_DragDrop:
  759.                         {
  760.                           pOS_IEDragDrop *DD = &((pOS_ISMDrop*)Msg->im_Data)->ismd_IEDD;
  761.  
  762.                           if( Msg->im_Code == IECODE_DROP_WORK &&
  763.                              DD->iedd_Dst.iedd_Gadget == DData.dd_ListGad ) {
  764.  
  765.                             HandleDD( DD, &DData );
  766.                           }
  767.                           else if( Msg->im_Code == IECODE_DROP_FIRST ) {
  768. /*\
  769. *** Wir werden aufgefordert, ein Drag-Objekt zu erzeugen.
  770. *** Das erzeugte Objekt ist in die pOS_IEDragDrop Struktur
  771. *** einzutragen. Der Code IECODE_DROP_REPLAYWORK macht das Objekt
  772. *** gültig. Danach darf pOS_SysIMessage() NICHT mehr aufgerufen werden.
  773. ***
  774. *** Sollte man die Message nicht verarbeiten können, bzw das DtObjekt
  775. *** nicht erzeugen können, sollte die Message an pOS_SysIMessage()
  776. *** weitergegeben werden, um dem Gadget die Chance zu geben, selber
  777. *** ein Objekt zu erzeugen.
  778. \*/
  779.                             if(DD->iedd_Src.iedd_Gadget == DData.dd_ListGad) {
  780.                               if( DD->iedd_Object = MakeDDObject(&DData))
  781.                                 Msg->im_Code = IECODE_DROP_REPLYWORK;
  782.                             }
  783.  
  784.                             if( Msg->im_Code == IECODE_DROP_FIRST )
  785.                               if(pOS_SysIMessage(Msg))
  786.                                 Msg = NULL;
  787.                           }
  788.                         }
  789.                         break;
  790. // -----
  791.                       case IDCMP_GadgetUp:
  792.                         if( Msg->im_IAddress == DData.dd_ListGad )
  793.                           StartViewer( DirBuf, DData.dd_ListGad, DData.dd_Win );
  794.                         break;
  795. // -----
  796. /*\
  797. *** IDCMP Message an das System weiterleiten
  798. *** wenn sie dort verarbeitet werden kann, wird sie auch
  799. *** replyed - wir müssen die Message beantworten, falls
  800. *** pOS_SysIMessage() FALSE zurückgibt
  801. \*/
  802.                       default:
  803.                         if( pOS_SysIMessage(Msg))
  804.                           Msg=NULL;
  805.                         break;
  806.                     }
  807.                     if( Msg ) pOS_ReplyMsg((pOS_Message*)Msg);
  808.                   }
  809.                 }
  810.               }
  811.  
  812. /*\
  813. *** Walker anhalten und Device schließen
  814. *** Fenster schließen - da bei den Gadget das AutoDelete-Tag gesetzt
  815. *** war, werden diese nun auch automatisch gelöscht
  816. \*/
  817.               StopWalker( &DData.dd_WIO );
  818.               pOS_CloseDevice((pOS_IORequest*)&DData.dd_WIO);
  819.             }
  820.             pOS_CloseWindow( DData.dd_Win );
  821.  
  822.             DeleteGfxList( &DData.dd_GfxList, NULL, NULL );
  823.           }
  824.           else {
  825.             printf("Cannot Open Window\n");
  826.             pOS_DisposeIObject( GrpGad );
  827.           }
  828.         }
  829.         else {
  830.           printf("Cannot Create Group Object\n");
  831.           pOS_DisposeIObject( DData.dd_ListGad );
  832.         }
  833.       }
  834.       else printf("Cannot Create List Object\n");
  835.  
  836.       pOS_UnlockPubScreen( Scr );
  837.     }
  838.     else printf("Cannot Lock PubScreen\n");
  839.  
  840.     pOS_DeleteDosArgs( Args );
  841.   }
  842.  
  843.   pOS_CloseLibrary((pOS_Library*)gb_GfxBase);
  844.   pOS_CloseLibrary((pOS_Library*)gb_IntuiBase);
  845.   pOS_CloseLibrary((pOS_Library*)gb_DtTypeBase);
  846. }
  847.