Jump to content

DrgDrag

From EDM2
Revision as of 00:01, 15 May 2025 by Martini (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

This function performs a drag operation.

Syntax

DrgDrag(hwndSource, pdinfo, pdimg, cdimg, vkTerminate, pRsvd)

Parameters

hwndSource (HWND) - input
Handle of the source window calling this function.
pdinfo (PDRAGINFO) - in/out
Pointer to the DRAGINFO structure.
pdimg (PDRAGIMAGE) - input
Pointer to an array of DRAGIMAGE structures.
These structures describe the images that are to be drawn under the direct manipulation pointer during the drag.
cdimg (ULONG) - input
Number of DRAGIMAGE structures in the pdimg array. Must be > 0.
vkTerminate (LONG) - input
Pointing device button that ends the drag operation.
Possible values:
VK_BUTTON1 - Release of button 1 ends the drag.
VK_BUTTON2 - Release of button 2 ends the drag.
VK_BUTTON3 - Release of button 3 ends the drag.
VK_ENDDRAG - Release of the system-defined direct manipulation button ends the drag. This is the recommended value if the DrgDrag function call is invoked in response to a WM_BEGINDRAG message.
pRsvd (PVOID) - input
Reserved value, must be NULL.

Returns

hwndDest (HWND) - returns
Handle of window on which the dragged objects were dropped.
A return value of NULL indicates that an error occurred.

Remarks

This function:

  • Captures the mouse to the current thread
  • Initiates a direct manipulation operation
  • Uses the DRAGIMAGE structure to provide visual feedback to the user during the drag operation
  • Notifies other windows as the drag object passes over
  • Notifies the destination if the object is dropped
  • Releases mouse capture.

Note: DrgDrag will fail if it is unable to capture the mouse. For example, if another window in the same thread has already set the capture.

Before invoking DrgDrag, the caller is responsible for:

DrgDrag is called when the system-defined direct-manipulation button is pressed while the pointer is over a window and a pointing device movement follows. As the pointer moves over a potential target, a DM_DRAGOVER message is sent to the target. When the pointer moves from one target window to another, a DM_DRAGLEAVE message is sent to the former target.

If the pointer is over a valid target when the direct-manipulation button is released, a DM_DROP message is sent to the target. Before the DM_DROP message is sent, the cxOffset and cyOffset fields are copied from the DRAGIMAGE structures to the corresponding fields in the DRAGITEM structures. The values from the first DRAGIMAGE are copied to the first DRAGITEM, from the second DRAGIMAGE to the second DRAGITEM, and so on. The target can use this information to place the images in the same spatial relationship after the drop. If there are more DRAGITEM structures than there are DRAGIMAGE structures, the cxOffset and cyOffset from the final DRAGIMAGE are placed in each of the remaining DRAGITEM structures.

The caller can define a default operation for the objects represented by the DRAGINFO structure by modifying the usOperation field. If the usOperation field is modified, the new value will be sent to the target as the operation whenever a DO_DEFAULT operation would normally be sent. The caller should not modify any other part of the DRAGINFO structure. The DRAGITEM structures associated with the DRAGINFO structure should only be altered with DrgSetDragitem or by using a pointer obtained with DrgQueryDragitemPtr.

The following keys are active during the drag operation:

  • Esc - The drag operation is canceled.
  • F1 - A DM_DROPHELP message is posted to the target so that it can provide context help for the drag operation. The drag operation is canceled.

Once the drag is commenced by calling DrgDrag, neither the image under the pointer nor the objects that comprise the drag set can be modified without canceling the drag and restarting.

On return from DrgDrag, the caller must free the DRAGINFO structure using DrgFreeDraginfo.

If the dragged objects are not dropped, NULL is returned.

Errors

Possible returns from WinGetLastError:

PMERR_INVALID_HWND (0x1001)
An invalid window handle was specified.
PMERR_INVALID_PARAMETERS (0x1208)
An application parameter value is invalid for its converted PM type. For example: a 4-byte value outside the range -32 768 to +32 767 cannot be converted to a SHORT, and a negative number cannot be converted to a ULONG or USHORT.
PMERR_INSUFFICIENT_MEMORY (0x203E)
The operation terminated through insufficient memory.

Example Code

#define INCL_WINSTDDRAG /* Direct Manipulation (Drag) Functions */
#define INCL_WININPUT   /* Window Input Functions            */
#include <os2.h>

PDRAGINFO pdinfo; /* Pointer to DRAGINFO structure */
HWND      hwnd;     /* Handle of calling (source) window */
BOOL      flResult; /* Result indicator                  */
DRAGITEM  ditem;    /* DRAGITEM structure                */
DRAGIMAGE dimg;     /* DRAGIMAGE structure               */
HBITMAP   hbm;      /* Bit-map handle                    */
HWND      hwndDrop; /* Handle of drop (target) window    */

case WM_BEGINDRAG:
/*************************************************************/
/* Initialize the DRAGITEM structure                         */
/*************************************************************/
ditem.hwndItem          = hwnd;                      /* Conversation partner            */
ditem.ulItemID          = ID_ITEM;                   /* Identifies item being dragged */
ditem.hstrType          = DrgAddStrHandle(DRT_TEXT); /* Text item                     */
ditem.hstrRMF           = DrgAddStrHandle("<DRM_OS2FILE,DRF_TEXT>");
ditem.hstrContainerName = DrgAddStrHandle("C:\\");
ditem.hstrSourceName    = DrgAddStrHandle("C:\\CONFIG.SYS");
ditem.hstrTargetName    = DrgAddStrHandle("C:\\OS2\\CONFIG.SYS");
ditem.cxOffset          = 0;                         /* X-offset of the origin of     */
                                                   /* the image from the pointer    */
                                                   /* hotspot                       */
ditem.cyOffset          = 0;                         /* Y-offset of the origin of     */
                                                   /* the image from the pointer    */
                                                   /* hotspot                       */
ditem.fsControl         = 0;                         /* Source item control flags     */
                                                   /* object is open                */
ditem.fsSupportedOps    = 0;
/*************************************************************/
/* Create the DRAGINFO structure                             */
/*************************************************************/
pdinfo = DrgAllocDraginfo(1);
if (!pdinfo) return (FALSE); /* If allocation fails,          */
                             /* return FALSE                   */
/*************************************************************/
/* Initialize the DRAGIMAGE structure                            */
/*************************************************************/
dimg.cb            = sizeof(DRAGIMAGE); /* Size control block              */
dimg.cptl          = 0;                 /* */
dimg.hImage        = hbm;               /* Image handle passed to          */
                                       /* DrgDrag                         */
dimg.sizlStretch.cx = 20L;              /* Size to stretch ico or bmp to */
dimg.sizlStretch.cy = 20L;
dimg.fl            = DRG_BITMAP |        /* Flags passed to DrgDrag         */
                     DRG_STRETCH;       /* Stretch to size specified     */
                                       /* in sizlStretch                */
dimg.cxOffset      = 0;                 /* Offset of the origin of         */
dimg.cyOffset      = 0;                 /* the image from the pointer        */
                                       /* hotspot                           */
/*************************************************************/
/* Set the drag item                                         */
/*************************************************************/
flResult= DrgSetDragitem(pdinfo, &ditem, (ULONG)sizeof(ditem),
                        0);
/*************************************************************/
/* Perform the drag operation:                               */
/* - Give the user a visual cue by changing the pointer to a */
/* bit map                                                 */
/* - Send DM_DRAGOVER messages to the target window (in this */
/* case it is also the source)                            */
/* NOTE: DrgDrag will fail if another window in the same     */
/* thread already has the capture.                     */
/*************************************************************/
hwndDrop = DrgDrag(hwnd,            /* Source of the drag            */
                  pdinfo,          /* Pointer to DRAGINFO structure */
                  (PDRAGIMAGE)&dimg, /* Drag image                    */
                  1,               /* Size of the pdimg array       */
                  VK_ENDDRAG,      /* Release of direct-manipulation  */
                                   /* button ends the drag          */
                  NULL);          /* Reserved                      */

Related Functions