home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / drgfil.zip / srcwin.c < prev    next >
C/C++ Source or Header  |  1993-08-01  |  32KB  |  721 lines

  1. /*********************************************************************
  2.  *                                                                   *
  3.  * MODULE NAME :  srcwin.c               AUTHOR:  Rick Fishman       *
  4.  * DATE WRITTEN:  07-28-93                                           *
  5.  *                                                                   *
  6.  * MODULE DESCRIPTION:                                               *
  7.  *                                                                   *
  8.  *  Part of the 'DRGFILES' drag/drop sample program.                 *
  9.  *                                                                   *
  10.  *  This module takes care of all the code relating to the source    *
  11.  *  window (the initiator of the drag operation)                     *
  12.  *                                                                   *
  13.  * NOTES:                                                            *
  14.  *                                                                   *
  15.  *                                                                   *
  16.  * FUNCTIONS AVALABLE TO OTHER MODULES:                              *
  17.  *                                                                   *
  18.  *   srcCreateWindow                                                 *
  19.  *                                                                   *
  20.  *                                                                   *
  21.  * HISTORY:                                                          *
  22.  *                                                                   *
  23.  *  07-28-93 - Program coded.                                        *
  24.  *                                                                   *
  25.  *  Rick Fishman                                                     *
  26.  *  Code Blazers, Inc.                                               *
  27.  *  4113 Apricot                                                     *
  28.  *  Irvine, CA. 92720                                                *
  29.  *  CIS ID: 72251,750                                                *
  30.  *                                                                   *
  31.  *********************************************************************/
  32.  
  33. #pragma strings(readonly)   // used for debug version of memory mgmt routines
  34.  
  35. /*********************************************************************/
  36. /*------- Include relevant sections of the OS/2 header files --------*/
  37. /*********************************************************************/
  38.  
  39. #define  INCL_WINERRORS
  40. #define  INCL_WINDIALOGS
  41. #define  INCL_WINFRAMEMGR
  42. #define  INCL_WININPUT
  43. #define  INCL_WINPOINTERS
  44. #define  INCL_WINSHELLDATA
  45. #define  INCL_WINSTDCNR
  46. #define  INCL_WINSTDDRAG
  47. #define  INCL_WINSYS
  48. #define  INCL_WINWINDOWMGR
  49.  
  50. /**********************************************************************/
  51. /*----------------------------- INCLUDES -----------------------------*/
  52. /**********************************************************************/
  53.  
  54. #include <os2.h>
  55. #include <stdarg.h>
  56. #include <stdio.h>
  57. #include <stdlib.h>
  58. #include <string.h>
  59. #include "drgfiles.h"
  60.  
  61. /*********************************************************************/
  62. /*------------------- APPLICATION DEFINITIONS -----------------------*/
  63. /*********************************************************************/
  64.  
  65. #define ID_FRAME                    1
  66.  
  67. #define WINDOW_TITLE                "'Drag' Window"
  68.  
  69. #define FRAME_FLAGS                 (FCF_TASKLIST   | FCF_TITLEBAR | \
  70.                                      FCF_SYSMENU    | FCF_MINMAX   | \
  71.                                      FCF_SIZEBORDER | FCF_ICON     | \
  72.                                      FCF_ACCELTABLE)
  73.  
  74. #define CONTAINER_STYLES            (flSelType | CCS_MINIRECORDCORE | \
  75.                                      CCS_AUTOPOSITION)
  76.  
  77. #define BASE_TEMPFILE_NAME          "TEMP"
  78.  
  79. /**********************************************************************/
  80. /*---------------------------- STRUCTURES ----------------------------*/
  81. /**********************************************************************/
  82.  
  83.  
  84. /**********************************************************************/
  85. /*----------------------- FUNCTION PROTOTYPES ------------------------*/
  86. /**********************************************************************/
  87.  
  88. BOOL    InsertRecords       ( HWND hwndCnr );
  89. void    DragInit            ( HWND hwndFrame, PCNRDRAGINIT pcdi );
  90. int     CountSelectedRecs   ( HWND hwndFrame, PCNRREC pCnrRecUnderMouse,
  91.                               PBOOL pfUseSelectedRecs );
  92. MRESULT RenderFile          ( PRENDERFILE pRenderFile );
  93. void    DragFileComplete    ( HWND hwndFrame, HSTR hstrFileName, USHORT fsDrop);
  94. void    RemoveSourceEmphasis( HWND hwndFrame );
  95.  
  96. FNWP wpFrame;
  97.  
  98. /**********************************************************************/
  99. /*------------------------ GLOBAL VARIABLES --------------------------*/
  100. /**********************************************************************/
  101.  
  102. PFNWP pfnwpFrame;
  103.  
  104. char szDragCnrTitle[] = "Drag an icon to the drop spot over there ══>";
  105.  
  106. // Set this to TRUE if you want to enable rendering. At this time (10/30//93)
  107. // using 2.1 there are major bugs that cause rendering to trap in PMDRAG.DLL,
  108. // so it is not enabled. All the code is in place - you just have to set
  109. // fRender to TRUE;
  110.  
  111. BOOL fRender = FALSE;
  112.  
  113. // Set this to CCS_EXTENDSEL if you want to enable multi-icon dragging. At this
  114. // time (10/30//93) using 2.1 there are major bugs that cause a second drop
  115. // to cause a trap in PMDRAG.DLL, so it is not enabled. All the code is in
  116. // place - you just have to set flSelType to CCS_EXTENDSEL;
  117.  
  118. ULONG flSelType = CCS_SINGLESEL;
  119.  
  120. /**********************************************************************/
  121. /*------------------------- srcCreateWindow --------------------------*/
  122. /*                                                                    */
  123. /*  CREATE THE SOURCE WINDOW                                          */
  124. /*                                                                    */
  125. /*  PARMS: anchor block handle                                        */
  126. /*                                                                    */
  127. /*  NOTES:                                                            */
  128. /*                                                                    */
  129. /*  RETURNS: Frame window handle                                      */
  130. /*                                                                    */
  131. /*--------------------------------------------------------------------*/
  132. /**********************************************************************/
  133. HWND srcCreateWindow( HAB hab )
  134. {
  135.     HWND       hwndFrame = NULLHANDLE, hwndCnr;
  136.     FRAMECDATA fcdata;
  137.  
  138.     memset( &fcdata, 0, sizeof fcdata );
  139.     fcdata.cb            = sizeof( FRAMECDATA );
  140.     fcdata.idResources   = ID_RESOURCES;
  141.     fcdata.flCreateFlags = FRAME_FLAGS;
  142.  
  143.     // Create the container as the client window of the frame. There is no
  144.     // need for a normal client window. Because of this we must subclass the
  145.     // frame window so we can catch the messages that the container sends to
  146.     // its owner.
  147.  
  148.     hwndFrame = WinCreateWindow( HWND_DESKTOP, WC_FRAME, NULL,
  149.                                  FS_NOBYTEALIGN | WS_CLIPCHILDREN,
  150.                                  0, 0, 0, 0, NULLHANDLE, HWND_TOP,
  151.                                  ID_FRAME, &fcdata, NULL );
  152.     if( hwndFrame )
  153.     {
  154.         pfnwpFrame = WinSubclassWindow( hwndFrame, wpFrame );
  155.  
  156.         if( pfnwpFrame )
  157.         {
  158.             hwndCnr = WinCreateWindow( hwndFrame, WC_CONTAINER, NULL,
  159.                                        WS_VISIBLE | CONTAINER_STYLES,
  160.                                        0, 0, 0, 0, hwndFrame, HWND_TOP,
  161.                                        FID_CLIENT, NULL, NULL );
  162.             if( hwndCnr )
  163.                 WinSetWindowText( hwndFrame, WINDOW_TITLE );
  164.             else
  165.             {
  166.                 WinDestroyWindow( hwndFrame );
  167.                 hwndFrame = NULLHANDLE;
  168.                 Msg( "WinCreateWindow(hwndCnr,%s) RC(%X)", WINDOW_TITLE,
  169.                      HABERR( hab ) );
  170.             }
  171.         }
  172.         else
  173.         {
  174.             WinDestroyWindow( hwndFrame );
  175.             hwndFrame = NULLHANDLE;
  176.             Msg( "WinSubclassWindow(%s) RC(%X)", WINDOW_TITLE, HABERR( hab ) );
  177.         }
  178.     }
  179.     else
  180.         Msg( "WinCreateWindow(%s) RC(%X)", WINDOW_TITLE, HABERR( hab ) );
  181.  
  182.     if( hwndFrame )
  183.     {
  184.         CNRINFO cnri;
  185.  
  186.         // Set container into Icon view and give it a read-only title
  187.  
  188.         cnri.cb           = sizeof( CNRINFO );
  189.         cnri.pszCnrTitle  = szDragCnrTitle;
  190.         cnri.flWindowAttr = CV_ICON | CA_CONTAINERTITLE | CA_TITLESEPARATOR |
  191.                             CA_TITLEREADONLY;
  192.  
  193.         if( !WinSendMsg( hwndCnr, CM_SETCNRINFO, MPFROMP( &cnri ),
  194.                          MPFROMLONG( CMA_FLWINDOWATTR | CMA_CNRTITLE ) ) )
  195.         {
  196.             WinDestroyWindow( hwndFrame );
  197.             hwndFrame = NULLHANDLE;
  198.             Msg( "CM_SETCNRINFO(%S) RC(%X)", WINDOW_TITLE, HABERR( hab ) );
  199.         }
  200.     }
  201.  
  202.     if( hwndFrame )
  203.         if( ! InsertRecords( hwndCnr ) )
  204.         {
  205.             WinDestroyWindow( hwndFrame );
  206.             hwndFrame = NULLHANDLE;
  207.         }
  208.  
  209.     return hwndFrame;
  210. }
  211.  
  212. /**********************************************************************/
  213. /*-------------------------- InsertRecords ---------------------------*/
  214. /*                                                                    */
  215. /*  INSERT RECORDS INTO A CONTAINER                                   */
  216. /*                                                                    */
  217. /*  PARMS: container window handle                                    */
  218. /*                                                                    */
  219. /*  NOTES: We just insert a few records to start us off. Each record  */
  220. /*         represents a temp file that we create.                     */
  221. /*                                                                    */
  222. /*  RETURNS: TRUE if successful, FALSE if not                         */
  223. /*                                                                    */
  224. /*--------------------------------------------------------------------*/
  225. /**********************************************************************/
  226. #define INITIAL_CONTAINER_RECS 5
  227.  
  228. BOOL InsertRecords( HWND hwndCnr )
  229. {
  230.     BOOL         fSuccess = TRUE;
  231.     RECORDINSERT ri;
  232.     PCNRREC      pCnrRec, pCnrRecSave;
  233.  
  234.     pCnrRec = WinSendMsg( hwndCnr, CM_ALLOCRECORD, MPFROMLONG( EXTRA_BYTES ),
  235.                           MPFROMLONG( INITIAL_CONTAINER_RECS ) );
  236.  
  237.     if( pCnrRec )
  238.     {
  239.         FILE     *fh;
  240.         int      i;
  241.         PSZ      pszFileExt;
  242.         ICONINFO iconinfo;
  243.  
  244.         memset( &iconinfo, 0, sizeof iconinfo );
  245.  
  246.         pCnrRecSave = pCnrRec;
  247.  
  248.         for( i = 0; fSuccess && (i < INITIAL_CONTAINER_RECS); i++ )
  249.         {
  250.             // Create a temporary filename (zero-length).
  251.  
  252.             strcpy( pCnrRec->szFileName, BASE_TEMPFILE_NAME );
  253.             strcat( pCnrRec->szFileName, "." );
  254.             pszFileExt = pCnrRec->szFileName + strlen( pCnrRec->szFileName );
  255.             _itoa( i + 1, pszFileExt, 10 );
  256.  
  257.             strcpy( pCnrRec->szFullFileName, szCurrentPath );
  258.             strcat( pCnrRec->szFullFileName, pCnrRec->szFileName );
  259.  
  260.             fh = fopen( pCnrRec->szFileName, "w" );
  261.             if( fh )
  262.             {
  263.                 fclose( fh );
  264.  
  265.                 // Set the icon attached to the temporary file so it will show
  266.                 // up when dropped onto other containers.
  267.  
  268.                 iconinfo.fFormat     = ICON_FILE;
  269.                 iconinfo.pszFileName = DRGFILES_ICON_FILENAME;
  270.                 WinSetFileIcon( pCnrRec->szFileName, &iconinfo );
  271.  
  272.                 pCnrRec->mrc.pszIcon  = (PSZ) &pCnrRec->szFileName;
  273.                 pCnrRec->mrc.hptrIcon = hptrCnrRec;
  274.             }
  275.             else
  276.             {
  277.                 fSuccess = FALSE;
  278.                 Msg( "Could not create %s file", pCnrRec->szFileName );
  279.             }
  280.  
  281.             pCnrRec = (PCNRREC) pCnrRec->mrc.preccNextRecord;
  282.         }
  283.  
  284.         memset( &ri, 0, sizeof( RECORDINSERT ) );
  285.         ri.cb                 = sizeof( RECORDINSERT );
  286.         ri.pRecordOrder       = (PRECORDCORE) CMA_END;
  287.         ri.pRecordParent      = (PRECORDCORE) NULL;
  288.         ri.zOrder             = (USHORT) CMA_TOP;
  289.         ri.cRecordsInsert     = INITIAL_CONTAINER_RECS;
  290.         ri.fInvalidateRecord  = TRUE;
  291.  
  292.         if( !WinSendMsg( hwndCnr, CM_INSERTRECORD, MPFROMP( pCnrRecSave ),
  293.                          MPFROMP( &ri ) ) )
  294.         {
  295.             fSuccess = FALSE;
  296.             Msg( "InsertRecords CM_INSERTRECORD RC(%X)", HWNDERR( hwndCnr ) );
  297.         }
  298.     }
  299.     else
  300.     {
  301.         fSuccess = FALSE;
  302.         Msg( "InsertRecords CM_ALLOCRECORD RC(%X)", HWNDERR( hwndCnr ) );
  303.     }
  304.  
  305.     return fSuccess;
  306. }
  307.  
  308. /**********************************************************************/
  309. /*----------------------------- wpFrame ------------------------------*/
  310. /*                                                                    */
  311. /*  SUBCLASSED FRAME WINDOW PROCEDURE.                                */
  312. /*                                                                    */
  313. /*  PARMS: normal winproc parms                                       */
  314. /*                                                                    */
  315. /*  NOTES:                                                            */
  316. /*                                                                    */
  317. /*  RETURNS: MRESULT value                                            */
  318. /*                                                                    */
  319. /*--------------------------------------------------------------------*/
  320. /**********************************************************************/
  321. MRESULT EXPENTRY wpFrame( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
  322. {
  323.     switch( msg )
  324.     {
  325.         // Don't let the message queue be destroyed until the user has closed
  326.         // *both* windows. If SC_CLOSE gets processed by the default window
  327.         // proc, a WM_QUIT message will get posted to the queue which will in
  328.         // effect end this program.
  329.  
  330.         case WM_SYSCOMMAND:
  331.             if( SHORT1FROMMP( mp1 ) == SC_CLOSE )
  332.                 if( hwndDrop )
  333.                 {
  334.                     WinDestroyWindow( hwnd );
  335.                     hwndDrag = NULLHANDLE;
  336.                     WinSetActiveWindow( HWND_DESKTOP, hwndDrop );
  337.                     return 0;
  338.                 }
  339.  
  340.             break;
  341.  
  342.         // From the F3 accelerator key
  343.         case WM_COMMAND:
  344.             if( SHORT1FROMMP( mp1 ) == IDM_EXIT )
  345.             {
  346.                 WinPostMsg( hwnd, WM_SYSCOMMAND, MPFROMSHORT( SC_CLOSE ),
  347.                             MPFROM2SHORT( CMDSRC_ACCELERATOR, FALSE ) );
  348.                 return 0;
  349.             }
  350.  
  351.             break;
  352.  
  353.         case WM_DESTROY:
  354.  
  355.             // Free all container resources associated with any records that
  356.             // were inserted (note that the container is actually the client
  357.             // window.
  358.  
  359.             WinSendDlgItemMsg( hwnd, FID_CLIENT, CM_REMOVERECORD, NULL,
  360.                                MPFROM2SHORT( 0, CMA_FREE ) );
  361.             break;
  362.  
  363.         case WM_CONTROL:
  364.             if( SHORT1FROMMP( mp1 ) == FID_CLIENT )
  365.                 switch( SHORT2FROMMP( mp1 ) )
  366.                 {
  367.                     case CN_INITDRAG:
  368.                         DragInit( hwnd, (PCNRDRAGINIT) mp2 );
  369.                         return 0;
  370.                 }
  371.  
  372.             break;
  373.  
  374.         // These are the only messages that we need to process if we use the
  375.         // DrgDragFiles API.
  376.  
  377.         case DM_DRAGERROR:
  378.             return DragError( SHORT1FROMMP( mp1 ), SHORT2FROMMP( mp1 ),
  379.                               (HSTR) mp2 );
  380.  
  381.         case DM_RENDERFILE:
  382.             return RenderFile( (PRENDERFILE) mp1 );
  383.  
  384.         case DM_DRAGFILECOMPLETE:
  385.             DragFileComplete( hwnd, (HSTR) mp1, SHORT1FROMMP( mp2 ) );
  386.             return 0;
  387.     }
  388.  
  389.     return pfnwpFrame( hwnd, msg, mp1, mp2 );
  390. }
  391.  
  392. /**********************************************************************/
  393. /*----------------------------- DragInit -----------------------------*/
  394. /*                                                                    */
  395. /*  PROCESS CN_INITDRAG NOTIFY MESSAGE.                               */
  396. /*                                                                    */
  397. /*  PARMS: frame window handle,                                       */
  398. /*         pointer to the CNRDRAGINIT structure                       */
  399. /*                                                                    */
  400. /*  NOTES: the CN_INITDRAG message is equivalent to the WM_BEGINDRAG  */
  401. /*         message. The reason I mention this is because if the source*/
  402. /*         window in the drag is not a container you will get the     */
  403. /*         WM_BEGINDRAG message.                                      */
  404. /*                                                                    */
  405. /*         WM_BEGINDRAG is sent to windows to allow them to know that */
  406. /*         the user is requesting a drag from their window. This      */
  407. /*         message contains only the x,y coordinates of the mouse at  */
  408. /*         the time of WM_BEGINDRAG.                                  */
  409. /*                                                                    */
  410. /*         The reason for CN_INITDRAG is first so that the container  */
  411. /*         can notify its owner when it gets a WM_BEGINDRAG message   */
  412. /*         and second so that the container can give its owner more   */
  413. /*         info, like what container record the mouse pointer is over.*/
  414. /*         To accomplish this, the container packages up this informa-*/
  415. /*         tion in a CNRDRAGINIT structure and sends that structure   */
  416. /*         along with the CN_INITDRAG message.                        */
  417. /*                                                                    */
  418. /*         DrgDragFiles takes a pointer to an array of filename       */
  419. /*         pointers. First the array of PSZ's is allocated. Then      */
  420. /*         memory for each filename is allocated and its pointer      */
  421. /*         placed in the array of PSZ's.                              */
  422. /*                                                                    */
  423. /*  RETURNS: nothing                                                  */
  424. /*                                                                    */
  425. /*--------------------------------------------------------------------*/
  426. /**********************************************************************/
  427. void DragInit( HWND hwndFrame, PCNRDRAGINIT pcdi )
  428. {
  429.     PCNRREC pCnrRecUnderMouse = (PCNRREC) pcdi->pRecord;
  430.     BOOL    fUseSelectedRecs;
  431.     int     cRecs;
  432.  
  433.     cRecs = CountSelectedRecs( hwndFrame, pCnrRecUnderMouse, &fUseSelectedRecs);
  434.  
  435.     if( cRecs )
  436.     {
  437.         int     i;
  438.         PSZ     *apszFiles;
  439.         PCNRREC pCnrRec = (PCNRREC) CMA_FIRST;
  440.  
  441.         apszFiles = _alloca( sizeof( PSZ ) * cRecs );
  442.  
  443.         // CountSelectedRecs returned in the fUseSelected variable whether or
  444.         // not we should go thru the container and drag all records that have
  445.         // selection emphasis or if we should just drag the record under the
  446.         // mouse. We continue accordingly.
  447.  
  448.         if( fUseSelectedRecs )
  449.             for( i = 0; i < cRecs; i++ )
  450.             {
  451.                 pCnrRec = (PCNRREC) WinSendDlgItemMsg( hwndFrame, FID_CLIENT,
  452.                                                  CM_QUERYRECORDEMPHASIS,
  453.                                                  MPFROMP( pCnrRec ),
  454.                                                  MPFROMSHORT( CRA_SELECTED ) );
  455.  
  456.                 if( pCnrRec == (PCNRREC) -1 )
  457.                     Msg( "DragInit..CM_QUERYRECORDEMPHASIS RC(%X)",
  458.                          HWNDERR( hwndFrame ) );
  459.                 else
  460.                 {
  461.                     apszFiles[ i ] =
  462.                         _alloca( strlen( pCnrRec->szFullFileName ) + 1 );
  463.                     strcpy( apszFiles[ i ], pCnrRec->szFullFileName );
  464.  
  465.                     // Give the selected record source emphasis
  466.                     if( !WinSendDlgItemMsg( hwndFrame, FID_CLIENT,
  467.                                             CM_SETRECORDEMPHASIS,
  468.                                             MPFROMP( pCnrRec ),
  469.                                             MPFROM2SHORT( TRUE, CRA_SOURCE ) ) )
  470.                             Msg( "DragInit..CM_SETRECORDEMPHASIS RC(%X)",
  471.                                  HWNDERR( hwndFrame ) );
  472.                 }
  473.             }
  474.         else
  475.         {
  476.             apszFiles[ 0 ] =
  477.                 _alloca( strlen( pCnrRecUnderMouse->szFullFileName ) + 1 );
  478.             strcpy( apszFiles[ 0 ], pCnrRecUnderMouse->szFullFileName );
  479.  
  480.             // Give the selected record source emphasis
  481.             if( !WinSendDlgItemMsg( hwndFrame, FID_CLIENT, CM_SETRECORDEMPHASIS,
  482.                                     MPFROMP( pCnrRecUnderMouse ),
  483.                                     MPFROM2SHORT( TRUE, CRA_SOURCE ) ) )
  484.                 Msg( "DragInit..CM_SETRECORDEMPHASIS RC(%X)",
  485.                      HWNDERR( hwndFrame ) );
  486.         }
  487.  
  488.         // The fRender parameter determines if rendering is going to be done
  489.         // when files are dropped. If set to TRUE, the source needs to process
  490.         // one more message (DM_RENDERFILE) and the target needs to process
  491.         // one more message (DM_FILERENDERED). The code is in place to do this
  492.         // but is only enabled if fRender is set to TRUE.
  493.  
  494.         DrgDragFiles( hwndFrame, (const char **) apszFiles, NULL, NULL, cRecs,
  495.                       hptrCnrRec, VK_ENDDRAG, fRender, 0 );
  496.  
  497.         RemoveSourceEmphasis( hwndFrame );
  498.     }
  499. }
  500.  
  501. /**********************************************************************/
  502. /*------------------------ CountSelectedRecs -------------------------*/
  503. /*                                                                    */
  504. /*  COUNT THE NUMBER OF RECORDS THAT ARE CURRENTLY SELECTED.          */
  505. /*                                                                    */
  506. /*  PARMS: frame window handle,                                       */
  507. /*         pointer to the record that was under the pointer,          */
  508. /*         address of BOOL - should we process selected records?      */
  509. /*                                                                    */
  510. /*  NOTES:                                                            */
  511. /*                                                                    */
  512. /*  RETURNS: number of records to process                             */
  513. /*                                                                    */
  514. /*--------------------------------------------------------------------*/
  515. /**********************************************************************/
  516. int CountSelectedRecs( HWND hwndFrame, PCNRREC pCnrRecUnderMouse,
  517.                        PBOOL pfUseSelectedRecs )
  518. {
  519.     int cRecs = 0;
  520.  
  521.     *pfUseSelectedRecs = FALSE;
  522.  
  523.     // If the record under the mouse is NULL, we must be over whitespace, in
  524.     // which case we don't want to drag any records.
  525.  
  526.     if( pCnrRecUnderMouse )
  527.     {
  528.         PCNRREC pCnrRec = (PCNRREC) CMA_FIRST;
  529.  
  530.         // Count the records with 'selection' emphasis. These are the records
  531.         // we want to drag, unless the container record under the mouse does
  532.         // not have selection emphasis. If that is the case, we only want to
  533.         // process that one.
  534.  
  535.         while( pCnrRec )
  536.         {
  537.             pCnrRec = (PCNRREC) WinSendDlgItemMsg( hwndFrame, FID_CLIENT,
  538.                                                    CM_QUERYRECORDEMPHASIS,
  539.                                                    MPFROMP( pCnrRec ),
  540.                                                    MPFROMSHORT( CRA_SELECTED ));
  541.  
  542.             if( pCnrRec == (PCNRREC) -1 )
  543.                 Msg( "CountSelectedRecs..CM_QUERYRECORDEMPHASIS RC(%X)",
  544.                      HWNDERR( hwndFrame ) );
  545.             else if( pCnrRec )
  546.             {
  547.                 if( pCnrRec == pCnrRecUnderMouse )
  548.                     *pfUseSelectedRecs = TRUE;
  549.  
  550.                 cRecs++;
  551.             }
  552.         }
  553.  
  554.         if( !(*pfUseSelectedRecs) )
  555.             cRecs = 1;
  556.     }
  557.  
  558.     return cRecs;
  559. }
  560.  
  561. /**********************************************************************/
  562. /*--------------------------- RenderFile -----------------------------*/
  563. /*                                                                    */
  564. /*  PROCESS A DM_RENDERFILE MESSAGE.                                  */
  565. /*                                                                    */
  566. /*  PARMS: pointer to a RENDERFILE struct                             */
  567. /*                                                                    */
  568. /*  NOTES: PM sends this to the source for each file that was dropped,*/
  569. /*         but only if the fRender global variable is set to TRUE.    */
  570. /*                                                                    */
  571. /*  RETURNS: TRUE if we do the rendering, FALSE if not                */
  572. /*                                                                    */
  573. /*--------------------------------------------------------------------*/
  574. /**********************************************************************/
  575. MRESULT RenderFile( PRENDERFILE pRenderFile )
  576. {
  577.     char szSource[ CCHMAXPATH ];
  578.     char szTarget[ CCHMAXPATH ];
  579.     int  cbSource;
  580.  
  581.     // hstrSource file is not fully qualified, hstrTarget is
  582.  
  583.     strcpy( szSource, szCurrentPath );
  584.     cbSource = strlen( szSource );
  585.     DrgQueryStrName( pRenderFile->hstrSource,
  586.                      sizeof szSource - cbSource, szSource + cbSource );
  587.     DrgQueryStrName( pRenderFile->hstrTarget, sizeof szTarget, szTarget );
  588.  
  589.     // If the filenames are the same there is nothing to do. Otherwise we
  590.     // do the copy or move as instructed.
  591.  
  592.     if( stricmp( szSource, szTarget ) != 0 )
  593.     {
  594.         APIRET rc;
  595.  
  596.         rc = DosCopy( szSource, szTarget, DCPY_EXISTING );
  597.         if( rc )
  598.             Msg( "DosCopy of %s to %s failed with a return code of %u\n",
  599.                  szSource, szTarget, rc );
  600.  
  601.         if( pRenderFile->fMove )
  602.         {
  603.             rc = DosDelete( szSource );
  604.             if( rc )
  605.                 Msg( "DosDelete of %s failed with a return code of %u\n",
  606.                      szSource, rc );
  607.         }
  608.     }
  609.  
  610.     // Let the target know that the rendering is complete. As of 10/3/93 using
  611.     // 2.1 GA, this message currently causes PMDRAG.DLL to trap.
  612.  
  613.     WinSendMsg( pRenderFile->hwndDragFiles, DM_FILERENDERED,
  614.                 MPFROMP( pRenderFile ), MPFROMLONG( TRUE ) );
  615.  
  616.     return (MRESULT) TRUE;
  617. }
  618.  
  619. /**********************************************************************/
  620. /*------------------------ DragFileComplete --------------------------*/
  621. /*                                                                    */
  622. /*  PROCESS A DM_DRAGFILECOMPLETE MESSAGE.                            */
  623. /*                                                                    */
  624. /*  PARMS: frame window handle,                                       */
  625. /*         HSTR that contains the dragged filename,                   */
  626. /*         flags that indicate what happened on the drop              */
  627. /*                                                                    */
  628. /*  NOTES: PM sends this to the source for each file that was dragged.*/
  629. /*                                                                    */
  630. /*  RETURNS: nothing                                                  */
  631. /*                                                                    */
  632. /*--------------------------------------------------------------------*/
  633. /**********************************************************************/
  634. void DragFileComplete( HWND hwndFrame, HSTR hstrFileName, USHORT fsDrop )
  635. {
  636.     char    szFileName[ CCHMAXPATH ];
  637.     USHORT  usCmd = CMA_FIRST;
  638.     PCNRREC pCnrRec = NULL;
  639.  
  640.     DrgQueryStrName( hstrFileName, sizeof szFileName, szFileName );
  641.  
  642.     // Find the container record that was dropped by matching the name with
  643.     // one that has source emphasis (we applied source emphasis to all records
  644.     // that were dragged). If the record was moved, remove it from the
  645.     // container.
  646.  
  647.     for( ; ; )
  648.     {
  649.         pCnrRec = (PCNRREC) WinSendDlgItemMsg( hwndFrame, FID_CLIENT,
  650.                                         CM_QUERYRECORD, MPFROMP( pCnrRec ),
  651.                                         MPFROM2SHORT( usCmd, CMA_ITEMORDER ) );
  652.  
  653.         if( pCnrRec == (PCNRREC) -1 )
  654.         {
  655.             Msg( "DragFileComplete..CM_QUERYRECORDEMPHASIS RC(%X)",
  656.                  HWNDERR( hwndFrame ) );
  657.             break;
  658.         }
  659.         else if( pCnrRec )
  660.         {
  661.             // The returned filename is not qualified (no path info)
  662.  
  663.             if( strcmp( pCnrRec->szFileName, szFileName ) == 0 )
  664.             {
  665.                 if( (fsDrop & DF_MOVE) && (fsDrop & DF_SUCCESSFUL) )
  666.                     WinSendDlgItemMsg( hwndFrame, FID_CLIENT, CM_REMOVERECORD,
  667.                                MPFROMP( &pCnrRec ),
  668.                                MPFROM2SHORT( 1, CMA_INVALIDATE | CMA_FREE ) );
  669.                 break;
  670.             }
  671.         }
  672.  
  673.         usCmd = CMA_NEXT;
  674.     }
  675. }
  676.  
  677. /**********************************************************************/
  678. /*----------------------- RemoveSourceEmphasis -----------------------*/
  679. /*                                                                    */
  680. /*  REMOVE SOURCE EMPHASIS FROM THE DRAGGED RECORDS.                  */
  681. /*                                                                    */
  682. /*  PARMS: frame window handle                                        */
  683. /*                                                                    */
  684. /*  NOTES:                                                            */
  685. /*                                                                    */
  686. /*  RETURNS: nothing                                                  */
  687. /*                                                                    */
  688. /*--------------------------------------------------------------------*/
  689. /**********************************************************************/
  690. void RemoveSourceEmphasis( HWND hwndFrame )
  691. {
  692.     PCNRREC pCnrRec = (PCNRREC) CMA_FIRST;
  693.  
  694.     // For every record with source emphasis, remove it.
  695.  
  696.     while( pCnrRec )
  697.     {
  698.         pCnrRec = (PCNRREC) WinSendDlgItemMsg( hwndFrame, FID_CLIENT,
  699.                                             CM_QUERYRECORDEMPHASIS,
  700.                                             MPFROMP( pCnrRec ),
  701.                                             MPFROMSHORT( CRA_SOURCE ) );
  702.  
  703.         if( pCnrRec == (PCNRREC) -1 )
  704.         {
  705.             Msg( "RemoveSourceEmphasis..CM_QUERYRECORDEMPHASIS RC(%X)",
  706.                  HWNDERR( hwndFrame ) );
  707.             break;
  708.         }
  709.         else if( pCnrRec )
  710.             if( !WinSendDlgItemMsg( hwndFrame, FID_CLIENT,
  711.                                     CM_SETRECORDEMPHASIS, MPFROMP( pCnrRec ),
  712.                                     MPFROM2SHORT( FALSE, CRA_SOURCE ) ) )
  713.                 Msg( "RemoveSourceEmphasis..CM_SETRECORDEMPHASIS RC(%X)",
  714.                      HWNDERR( hwndFrame ) );
  715.     }
  716. }
  717.  
  718. /*************************************************************************
  719.  *                     E N D     O F     S O U R C E                     *
  720.  *************************************************************************/
  721.