home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / valset.zip / VALUESET.C < prev    next >
Text File  |  1992-01-04  |  19KB  |  589 lines

  1. /*
  2.  
  3. a Value Set example,
  4.  
  5. Copyright TASP Group, Inc., 1992
  6. All Rights Reserved
  7.  
  8. By Paul Montgomery, TASP Group, Inc.
  9.    4776 Blackberry Drive
  10.    Melbourne, FL. 32904
  11.  
  12.    CIS: 71500,3525
  13.  
  14. You may use this example as a learning tool, feel free to make copies and
  15. distribute them.  You may not sell them.  This header text must accompany
  16. this example when copied or distributed. 
  17.  
  18. */
  19.  
  20.  
  21.  
  22. #define INCL_WIN
  23. #define INCL_WINSTDVALSET
  24. #include <os2.h>
  25.  
  26. HAB         hab;
  27. HSTR        vlstype;
  28.  
  29. HPOINTER  barney;
  30. HPOINTER  fred;
  31. HPOINTER  wilma;
  32. HPOINTER  bart;
  33. HPOINTER  bear;
  34. HPOINTER  cat;
  35. HPOINTER  andy;
  36. HPOINTER  donatelo;
  37. HPOINTER  face;
  38. HPOINTER  frame;
  39.  
  40. LONG iconx;       // system values for icon dimensions
  41. LONG icony;
  42.  
  43. HWND hwVs1, hwVs2;
  44.  
  45. // function prototypes
  46. #pragma linkage ( WinProc, system )
  47. MRESULT WinProc ( HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2 );
  48. MRESULT InitDrag ( HWND hwnd, HWND hcont, MPARAM mp1, MPARAM mp2 );
  49. MRESULT DragOver ( HWND hwnd, HWND hcont, MPARAM mp1, MPARAM mp2 );
  50. MRESULT DragDrop ( HWND hwnd, HWND hcont, MPARAM mp1, MPARAM mp2 );
  51.  
  52.  
  53. /* **************************************************************
  54.  * Function Name:  main
  55.  *
  56.  * Description: 
  57.  * 
  58.  * Parameter      Description
  59.  * --------------------------------------------------------------
  60.  * 
  61.  * Returns:  
  62.  * 
  63.  * Comments: 
  64.  * 
  65.  ***************************************************************/
  66.  
  67. int main ( int argc, char *argv[] )
  68. {
  69.    QMSG        qmsg;
  70.    HMQ         hmq;
  71.    ULONG       fs;
  72.    HWND        hframe;
  73.    HWND        hclient;
  74.  
  75.    fs =  FCF_TITLEBAR      |
  76.          FCF_SYSMENU       |
  77.          FCF_ICON          |
  78.          FCF_TASKLIST      |
  79.          FCF_MINBUTTON     |
  80.          FCF_MAXBUTTON     |
  81.          FCF_SIZEBORDER
  82.          ;
  83.    if((hab = WinInitialize(0)) == 0)
  84.       {
  85.       return(FALSE);
  86.       }
  87.  
  88.    if((hmq = WinCreateMsgQueue(hab, 0)) == 0)
  89.       {
  90.       WinTerminate(hab);
  91.       return(FALSE);
  92.       }
  93.  
  94.  
  95.    WinRegisterClass(hab,
  96.                     "VALUETEST",
  97.                     WinProc,
  98.                     CS_SIZEREDRAW | CS_SYNCPAINT,
  99.                     0);
  100.  
  101.    iconx = WinQuerySysValue ( HWND_DESKTOP, SV_CXICON );
  102.    icony = WinQuerySysValue ( HWND_DESKTOP, SV_CYICON );
  103.  
  104.    hframe = WinCreateStdWindow(HWND_DESKTOP,
  105.            0,
  106.            &fs,
  107.            "VALUETEST",
  108.            "Value Set Example",
  109.            0L,
  110.            0L,
  111.            1,
  112.            &hclient);
  113.  
  114.    WinSetWindowPos ( hframe, HWND_TOP, 640/3, 480/3,
  115.          (iconx * 10) + 20 , (icony * 5 ) + 20,
  116.          SWP_SHOW | SWP_MOVE | SWP_ZORDER | SWP_SIZE );
  117.  
  118.    while(WinGetMsg(hab, &qmsg, 0, 0, 0))
  119.       {
  120.       WinDispatchMsg(hab, &qmsg);
  121.       }
  122.  
  123.    WinDestroyWindow(hframe);
  124.    WinDestroyMsgQueue(hmq);
  125.    WinTerminate(hab);
  126.    return (0);
  127.  
  128. }
  129.  
  130. /* **************************************************************
  131.  * Function Name:  WinProc
  132.  *
  133.  * Description: 
  134.  * 
  135.  * Parameter      Description
  136.  * --------------------------------------------------------------
  137.  * 
  138.  * Returns:  
  139.  * 
  140.  * Comments: 
  141.  * 
  142.  ***************************************************************/
  143.   
  144. MRESULT WinProc ( HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2 )
  145. {
  146.    VSCDATA vscdata;
  147.    SWP  swp[2];
  148.    HPS  hps;
  149.    LONG cx, cy, clientx, clienty;
  150.    HWND hother;
  151.    HPOINTER hicon;
  152.    LONG itemid;
  153.    HWND hvs;
  154.  
  155.    switch (msg)
  156.       {
  157.  
  158.       case WM_CREATE:
  159.          // here we need to create the 2 value sets
  160.          // the first we will fill with icons,
  161.          // the second we want so that we can show drag and drop between
  162.          // them.  
  163.          
  164.          // You must create and fill out one of these structs and 
  165.          // pass it in on the CreateWindow call or else the value set will
  166.          // not be created.
  167.  
  168.          vscdata.cbSize = sizeof(vscdata);
  169.          vscdata.usRowCount = 3;
  170.          vscdata.usColumnCount = 3;
  171.  
  172.          cx = 3 * iconx;
  173.          cy = 3 * icony;
  174.  
  175.          hwVs1 = WinCreateWindow ( hwnd,
  176.                   WC_VALUESET,
  177.                   "",
  178.                   WS_VISIBLE | VS_BORDER | VS_ICON,
  179.                   1,1,
  180.                   cx, cy,
  181.                   hwnd,
  182.                   HWND_TOP,
  183.                   1,
  184.                   &vscdata,
  185.                   0 );
  186.  
  187.  
  188.          hwVs2 = WinCreateWindow ( hwnd,
  189.                   WC_VALUESET,
  190.                   "",
  191.                   WS_VISIBLE | VS_BORDER | VS_ICON,
  192.                   cx + 20,1,
  193.                   cx, cy,
  194.                   hwnd,
  195.                   HWND_TOP,
  196.                   2,
  197.                   &vscdata,
  198.                   0 );
  199.  
  200.          // load the icons for the valuesets from the RC file or
  201.          // whereever you are getting them from.
  202.          // remember that they could be bitmaps, text, colors, ownerdraw,
  203.          // or any combination there of.  I am using icons for simplicity
  204.  
  205.          barney =   WinLoadPointer ( HWND_DESKTOP, (HMODULE)NULL, 1);
  206.          wilma =    WinLoadPointer ( HWND_DESKTOP, (HMODULE)NULL, 2);
  207.          fred =     WinLoadPointer ( HWND_DESKTOP, (HMODULE)NULL, 3);
  208.          andy =     WinLoadPointer ( HWND_DESKTOP, (HMODULE)NULL, 4);
  209.          bart =     WinLoadPointer ( HWND_DESKTOP, (HMODULE)NULL, 5);
  210.          bear =     WinLoadPointer ( HWND_DESKTOP, (HMODULE)NULL, 6);
  211.          cat =      WinLoadPointer ( HWND_DESKTOP, (HMODULE)NULL, 7);
  212.          face =     WinLoadPointer ( HWND_DESKTOP, (HMODULE)NULL, 8);
  213.          donatelo = WinLoadPointer ( HWND_DESKTOP, (HMODULE)NULL, 9);
  214.          frame    = WinLoadPointer ( HWND_DESKTOP, (HMODULE)NULL, 10);
  215.  
  216.          // place the icons into the first value set
  217.  
  218.          WinSendMsg ( hwVs1, VM_SETITEM,
  219.                    MPFROM2SHORT ( 1, 1 ), (MPARAM)barney );
  220.          WinSendMsg ( hwVs1, VM_SETITEM,
  221.                    MPFROM2SHORT ( 1, 2 ), (MPARAM)wilma  );
  222.          WinSendMsg ( hwVs1, VM_SETITEM,
  223.                    MPFROM2SHORT ( 1, 3 ), (MPARAM)fred   );
  224.          WinSendMsg ( hwVs1, VM_SETITEM,
  225.                    MPFROM2SHORT ( 2, 1 ), (MPARAM)andy  );
  226.          WinSendMsg ( hwVs1, VM_SETITEM,
  227.                    MPFROM2SHORT ( 2, 2 ), (MPARAM)bart   );
  228.          WinSendMsg ( hwVs1, VM_SETITEM,
  229.                    MPFROM2SHORT ( 2, 3 ), (MPARAM)bear   );
  230.          WinSendMsg ( hwVs1, VM_SETITEM,
  231.                    MPFROM2SHORT ( 3, 1 ), (MPARAM)cat    );
  232.          WinSendMsg ( hwVs1, VM_SETITEM,
  233.                    MPFROM2SHORT ( 3, 2 ), (MPARAM)face   );
  234.          WinSendMsg ( hwVs1, VM_SETITEM,
  235.                    MPFROM2SHORT ( 3, 3 ), (MPARAM)donatelo);
  236.  
  237.  
  238.          // set the attributes for the first value set  I dont see a way
  239.          // of doing this globally for anything other than "TYPE".  This could
  240.          // be a loop instead of individual calls, but hey.
  241.          WinSendMsg ( hwVs1, VM_SETITEMATTR,
  242.                   MPFROM2SHORT ( 1, 1 ),
  243.                   MPFROM2SHORT(VIA_ICON | VIA_DRAGGABLE | VIA_DROPONABLE, TRUE) );
  244.          WinSendMsg ( hwVs1, VM_SETITEMATTR,
  245.                   MPFROM2SHORT ( 1, 2 ),
  246.                   MPFROM2SHORT(VIA_ICON | VIA_DRAGGABLE | VIA_DROPONABLE, TRUE) );
  247.          WinSendMsg ( hwVs1, VM_SETITEMATTR,
  248.                   MPFROM2SHORT ( 1, 3 ),
  249.                   MPFROM2SHORT(VIA_ICON | VIA_DRAGGABLE | VIA_DROPONABLE, TRUE) );
  250.          WinSendMsg ( hwVs1, VM_SETITEMATTR,
  251.                   MPFROM2SHORT ( 2, 1 ),
  252.                   MPFROM2SHORT(VIA_ICON | VIA_DRAGGABLE | VIA_DROPONABLE, TRUE) );
  253.          WinSendMsg ( hwVs1, VM_SETITEMATTR,
  254.                   MPFROM2SHORT ( 2, 2 ),
  255.                   MPFROM2SHORT(VIA_ICON | VIA_DRAGGABLE | VIA_DROPONABLE, TRUE) );
  256.          WinSendMsg ( hwVs1, VM_SETITEMATTR,
  257.                   MPFROM2SHORT ( 2, 3 ),
  258.                   MPFROM2SHORT(VIA_ICON | VIA_DRAGGABLE | VIA_DROPONABLE, TRUE) );
  259.          WinSendMsg ( hwVs1, VM_SETITEMATTR,
  260.                   MPFROM2SHORT ( 3, 1 ),
  261.                   MPFROM2SHORT(VIA_ICON | VIA_DRAGGABLE | VIA_DROPONABLE, TRUE) );
  262.          WinSendMsg ( hwVs1, VM_SETITEMATTR,
  263.                   MPFROM2SHORT ( 3, 2 ),
  264.                   MPFROM2SHORT(VIA_ICON | VIA_DRAGGABLE | VIA_DROPONABLE, TRUE) );
  265.          WinSendMsg ( hwVs1, VM_SETITEMATTR,
  266.                   MPFROM2SHORT ( 3, 3 ),
  267.                   MPFROM2SHORT(VIA_ICON | VIA_DRAGGABLE | VIA_DROPONABLE, TRUE) );
  268.  
  269.                   
  270.          // set the attributes for the second values set
  271.          WinSendMsg ( hwVs2, VM_SETITEMATTR,
  272.                   MPFROM2SHORT ( 1, 1 ),
  273.                   MPFROM2SHORT(VIA_ICON | VIA_DRAGGABLE | VIA_DROPONABLE, TRUE) );
  274.          WinSendMsg ( hwVs2, VM_SETITEMATTR,
  275.                   MPFROM2SHORT ( 1, 2 ),
  276.                   MPFROM2SHORT(VIA_ICON | VIA_DRAGGABLE | VIA_DROPONABLE, TRUE) );
  277.          WinSendMsg ( hwVs2, VM_SETITEMATTR,
  278.                   MPFROM2SHORT ( 1, 3 ),
  279.                   MPFROM2SHORT(VIA_ICON | VIA_DRAGGABLE | VIA_DROPONABLE, TRUE) );
  280.          WinSendMsg ( hwVs2, VM_SETITEMATTR,
  281.                   MPFROM2SHORT ( 2, 1 ),
  282.                   MPFROM2SHORT(VIA_ICON | VIA_DRAGGABLE | VIA_DROPONABLE, TRUE) );
  283.          WinSendMsg ( hwVs2, VM_SETITEMATTR,
  284.                   MPFROM2SHORT ( 2, 2 ),
  285.                   MPFROM2SHORT(VIA_ICON | VIA_DRAGGABLE | VIA_DROPONABLE, TRUE) );
  286.          WinSendMsg ( hwVs2, VM_SETITEMATTR,
  287.                   MPFROM2SHORT ( 2, 3 ),
  288.                   MPFROM2SHORT(VIA_ICON | VIA_DRAGGABLE | VIA_DROPONABLE, TRUE) );
  289.          WinSendMsg ( hwVs2, VM_SETITEMATTR,
  290.                   MPFROM2SHORT ( 3, 1 ),
  291.                   MPFROM2SHORT(VIA_ICON | VIA_DRAGGABLE | VIA_DROPONABLE, TRUE) );
  292.          WinSendMsg ( hwVs2, VM_SETITEMATTR,
  293.                   MPFROM2SHORT ( 3, 2 ),
  294.                   MPFROM2SHORT(VIA_ICON | VIA_DRAGGABLE | VIA_DROPONABLE, TRUE) );
  295.          WinSendMsg ( hwVs2, VM_SETITEMATTR,
  296.                   MPFROM2SHORT ( 3, 3 ),
  297.                   MPFROM2SHORT(VIA_ICON | VIA_DRAGGABLE | VIA_DROPONABLE, TRUE) );
  298.  
  299.          // make vlstype known to the system for the drag and drop operations
  300.          vlstype = DrgAddStrHandle ("VALUESETTEST_DATA");
  301.  
  302.          return (MRESULT) FALSE;
  303.          break;
  304.  
  305.       case WM_SIZE:
  306.          WinQueryWindowPos ( hwVs1, &swp[0] );
  307.          WinQueryWindowPos ( hwVs2, &swp[1] );
  308.  
  309.          // divide the client area in two and place one on the left
  310.          // and one on the right
  311.          clientx = SHORT1FROMMP(mp2);
  312.          clienty = SHORT2FROMMP(mp2);
  313.  
  314.          swp[0].cx = (clientx / 2) - 10;
  315.          swp[0].cy = clienty;
  316.          swp[0].fl = SWP_MOVE | SWP_SHOW | SWP_SIZE;
  317.  
  318.          swp[1].x = swp[0].cx + swp[0].x + 20;
  319.          swp[1].y = 1;
  320.          swp[1].cx = swp[0].cx;
  321.          swp[1].cy = swp[0].cy;
  322.          swp[0].fl = SWP_MOVE | SWP_SHOW | SWP_SIZE;
  323.  
  324.          WinSetMultWindowPos ( hab, &swp[0], 2 );
  325.          return (MRESULT) TRUE;
  326.          break;
  327.  
  328.       case WM_CONTROL:
  329.          switch (SHORT2FROMMP(mp1))
  330.             {
  331.             case VN_SELECT:
  332.                // Just beep to show that the selected item msg was
  333.                // received.
  334.                WinAlarm ( HWND_DESKTOP, WA_NOTE );
  335.                return (MRESULT) TRUE;
  336.                break;
  337.  
  338.             case VN_ENTER:
  339.                // switch the icon to the other value set
  340.                // this is done by querying the selected item in the
  341.                // value set that sent the message.
  342.                itemid = (LONG)WinSendMsg ( (HWND)mp2, VM_QUERYSELECTEDITEM,
  343.                               (MPARAM)0,(MPARAM)0 );
  344.  
  345.                // then get the icon associated with that item
  346.                hicon  = (HPOINTER)WinSendMsg ( (HWND)mp2, VM_QUERYITEM,
  347.                               (MPARAM)itemid,NULL );
  348.  
  349.                // figure out the handle for the other value set
  350.                hother = ((HWND)mp2 == hwVs1) ? hwVs2 : hwVs1;
  351.  
  352.                // if the item is not occupied in the other value set
  353.                if (WinSendMsg ( hother, VM_QUERYITEM, (MPARAM)itemid, NULL) == NULL)
  354.                   {
  355.                   // set the item to the icon
  356.                   WinSendMsg ( hother, VM_SETITEM,(MPARAM)itemid, (MPARAM)hicon );
  357.                   // delete the icon in current window
  358.                   WinSendMsg ( (HWND)mp2, VM_SETITEM, (MPARAM)itemid, (MPARAM)NULL);
  359.                   }
  360.  
  361.                return (MRESULT) TRUE;
  362.                break;
  363.  
  364.             case VN_INITDRAG:
  365.                // the user has initiated a drag from the value set
  366.                // we need to fill out a  drag init structure and then initiate
  367.                // the drag operation if it is valid.
  368.                hvs = WinWindowFromID ( hwnd, SHORT1FROMMP(mp1));
  369.                return InitDrag ( hwnd, hvs, mp1, mp2 );
  370.                break;
  371.  
  372.             case VN_DRAGOVER:
  373.                hvs = WinWindowFromID ( hwnd, SHORT1FROMMP(mp1));
  374.                return DragOver ( hwnd, hvs, mp1, mp2 );
  375.                break;
  376.  
  377.             case VN_DROP:
  378.                hvs = WinWindowFromID ( hwnd, SHORT1FROMMP(mp1));
  379.                return DragDrop ( hwnd, hvs, mp1, mp2 );
  380.                break;
  381.  
  382.             } 
  383.          break;
  384.  
  385.       case WM_CONTROLPOINTER:
  386.          return (MRESULT) frame;
  387.          break;
  388.  
  389.       case WM_PAINT:
  390.          hps = WinBeginPaint ( hwnd, 0, 0 );
  391.          GpiErase ( hps );
  392.          WinEndPaint ( hps );
  393.          return (MRESULT) TRUE;
  394.          break;
  395.       }
  396.  
  397. return(WinDefWindowProc(hwnd, msg, mp1, mp2));
  398.  
  399. }
  400.  
  401.  
  402. /* **************************************************************
  403.  * Function Name:  InitDrag
  404.  *
  405.  * Description: 
  406.  * 
  407.  * Parameter      Description
  408.  * --------------------------------------------------------------
  409.  * 
  410.  * Returns:  
  411.  * 
  412.  * Comments:
  413.  * 
  414.  ***************************************************************/
  415.  
  416. MRESULT InitDrag ( HWND hwnd, HWND hvs, MPARAM mp1, MPARAM mp2 )
  417. {
  418.    PDRAGINFO   pdrg;
  419.    PDRAGITEM   pdrgitem;
  420.    PVSDRAGINIT pvsd;
  421.    DRAGIMAGE   drgimg;
  422.    HPOINTER    hicon;
  423.  
  424.    // make sure that the drag operation is over a record
  425.    pvsd = (PVSDRAGINIT)mp2;
  426.    hicon = (HPOINTER)WinSendMsg ( hvs, VM_QUERYITEM,
  427.                MPFROM2SHORT(pvsd->usRow, pvsd->usColumn),
  428.                NULL );
  429.  
  430.    if (hicon == NULL)
  431.       {
  432.       // there is no icon under the mouse.
  433.       // there is nothing to drag.  We could query the selected item and 
  434.       // drag that, but we will leave that for an excercise for the reader
  435.       // <GRIN>
  436.       return (MRESULT)FALSE;
  437.       }
  438.  
  439.  
  440.    // for lots of info on drag and drop, see the 1.3 docs.
  441.    
  442.    pdrg = DrgAllocDraginfo (1);
  443.    pdrg->hwndSource = hwnd;
  444.    pdrgitem = DrgQueryDragitemPtr ( pdrg, 0 );
  445.    if (pdrgitem != NULL)
  446.       {
  447.       pdrgitem->hwndItem = hvs;
  448.       pdrgitem->ulItemID = (ULONG)MPFROM2SHORT(pvsd->usRow, pvsd->usColumn);
  449.       pdrgitem->hstrType = vlstype;
  450.       pdrgitem->hstrRMF = DrgAddStrHandle ("<DRM_PRINT,DRF_TEXT>");
  451.       pdrgitem->hstrContainerName = NULL;
  452.       pdrgitem->hstrSourceName = DrgAddStrHandle ("???");
  453.       pdrgitem->hstrTargetName = DrgAddStrHandle ("???");
  454.       pdrgitem->fsControl = DC_OPEN;
  455.       pdrgitem->fsSupportedOps = DO_MOVEABLE;
  456.       }
  457.    drgimg.cb = sizeof(DRAGIMAGE);
  458.    drgimg.hImage = hicon;
  459.    drgimg.fl = DRG_ICON;
  460.    drgimg.cxOffset = 0;
  461.    drgimg.cyOffset = 0;
  462.    DrgDrag ( hwnd, pdrg, &drgimg, 1, VK_BUTTON2, NULL );
  463.  
  464.    // note: at this point the drag operation is complete.  Be very carefull,
  465.    // all of the drag operations and messages ocurred reentrantly in this
  466.    // window proc.
  467.  
  468.    DrgFreeDraginfo ( pdrg );
  469.    
  470.    return (MRESULT) TRUE;
  471.  
  472. }
  473.  
  474. /* **************************************************************
  475.  * Function Name:  DragOver
  476.  *
  477.  * Description: 
  478.  * 
  479.  * Parameter      Description
  480.  * --------------------------------------------------------------
  481.  * 
  482.  * Returns:  
  483.  * 
  484.  * Comments: 
  485.  * 
  486.  ***************************************************************/
  487.  
  488. MRESULT DragOver ( HWND hwnd, HWND hvs, MPARAM mp1, MPARAM mp2 )
  489. {
  490.    PDRAGITEM      pdrgitem;
  491.    PVSDRAGINFO    pvsd;
  492.    PDRAGINFO      prdi;
  493.    MPARAM         itemid;
  494.  
  495.    pvsd = (PVSDRAGINFO) mp2;
  496.    prdi = pvsd->pDragInfo;
  497.  
  498.    if ( DrgAccessDraginfo ( prdi ) )
  499.       {
  500.       pdrgitem = DrgQueryDragitemPtr(prdi, 0);
  501.       // is the drag item a type of item that we understand?
  502.       if (pdrgitem->hstrType == vlstype)
  503.          {
  504.          DrgFreeDraginfo ( prdi );
  505.          // check to see if we can drop over the current item
  506.          // the item must be empty in this example
  507.          itemid = MPFROM2SHORT(pvsd->usRow, pvsd->usColumn );
  508.          if (WinSendMsg ( hvs, VM_QUERYITEM, itemid, NULL) == NULL)
  509.             {
  510.             // yes we can accept it.
  511.             return ( MPFROM2SHORT ( DOR_DROP, DO_MOVE ) );
  512.             }
  513.  
  514.          // its only droppable if the user moves over an empty slot
  515.          return ( MPFROM2SHORT ( DOR_NODROP, DO_MOVE ) );
  516.          }
  517.       DrgFreeDraginfo ( prdi );
  518.       }
  519.  
  520.    // we could never accept it even over an empty slot
  521.    return ( MPFROM2SHORT ( DOR_NEVERDROP, DO_MOVE ) );
  522.  
  523. }
  524.  
  525. /* **************************************************************
  526.  * Function Name:  DragDrop
  527.  *
  528.  * Description: 
  529.  * 
  530.  * Parameter      Description
  531.  * --------------------------------------------------------------
  532.  * 
  533.  * Returns:  
  534.  * 
  535.  * Comments: 
  536.  * 
  537.  ***************************************************************/
  538.  
  539. MRESULT DragDrop ( HWND hwnd, HWND hvs, MPARAM mp1, MPARAM mp2 )
  540. {
  541.    PDRAGITEM      pdrgitem;
  542.    PVSDRAGINFO    pvsd;
  543.    PDRAGINFO      prdi;
  544.    HPOINTER       hicon;
  545.    HWND           hwsource;
  546.    MPARAM         itemid;
  547.  
  548.    // look at the CN_DROP message parms for details of a VSDRAGINFO struct
  549.    pvsd = (PVSDRAGINFO) mp2;
  550.    prdi = pvsd->pDragInfo;
  551.  
  552.    if ( DrgAccessDraginfo ( prdi ))
  553.       {
  554.       pdrgitem = DrgQueryDragitemPtr(prdi, 0);
  555.       // we need to take the icon out of the source window
  556.       // and insert it into the designated value set at the 
  557.       // mouse location.  Notice that source and dest could be the same
  558.       // also notice that we are sure that the spot it is over is a valid
  559.       // spot to drop it and that the dragged item is a valid type.  This 
  560.       // was all checked in the dragover message.
  561.  
  562.       // dest location
  563.       itemid = MPFROM2SHORT(pvsd->usRow, pvsd->usColumn);
  564.       
  565.       // source value set
  566.       hwsource = pdrgitem->hwndItem;
  567.  
  568.       // get the icon from the source window
  569.       hicon  = (HPOINTER)WinSendMsg ( (HWND)hwsource, VM_QUERYITEM,
  570.                               (MPARAM)pdrgitem->ulItemID, NULL );
  571.  
  572.       // set the item to the icon in the dest value set
  573.       WinSendMsg ( hvs, VM_SETITEM,(MPARAM)itemid, (MPARAM)hicon );
  574.  
  575.       // delete the icon in source window
  576.       WinSendMsg ( (HWND)hwsource, VM_SETITEM, (MPARAM)pdrgitem->ulItemID,
  577.                    (MPARAM)NULL);
  578.             
  579.       // clean up.
  580.       DrgDeleteDraginfoStrHandles ( prdi );
  581.       DrgFreeDraginfo ( prdi );
  582.       }
  583.    return((MPARAM)NULL);
  584.  
  585. }
  586.  
  587.  
  588. 
  589.