Author Topic: WPS dragged object handle  (Read 5156 times)

Doug Clark

  • Sr. Member
  • ****
  • Posts: 323
  • Karma: +8/-1
    • View Profile
WPS dragged object handle
« on: September 29, 2023, 12:18:52 am »
When you drag a WPS object (or anything actually) a _DRAGITEM is created to store data about the item being dragged, the structure of DRAGITEM shown below
-------------------------------
typedef struct _DRAGITEM {
  HWND       hwndItem;           /*  Window handle of the source of the drag operation. */
  ULONG      ulItemID;           /*  Information used by the source to identify the object being dragged. */
  HSTR       hstrType;           /*  String handle of the object type. */
  HSTR       hstrRMF;            /*  String handle of the rendering mechanism and format. */
  HSTR       hstrContainerName;  /*  String handle of the name of the container holding the source object. */
  HSTR       hstrSourceName;     /*  String handle of the name of the source object. */
  HSTR       hstrTargetName;     /*  String handle of the suggested name of the object at the target. */
  SHORT      cxOffset;           /*  X-offset from the pointer hot spot to the origin of the image that represents this object. */
  SHORT      cyOffset;           /*  Y-offset from the pointer hot spot to the origin of the image that represents this object. */
  USHORT     fsControl;          /*  Source-object control flags. */
  USHORT     fsSupportedOps;     /*  Direct manipulation operations supported by the source object. */
} DRAGITEM;
--------------------------------

I am trying to identify the object that is being dragged over my window - either the class of the object or the specific object itself.  Is there someway of translating the hwndItem  or ulItemID  value into a WPS object handle?  I am hoping to avoid searching the source container for the source name in order to find the object being dragged.

There is a value in ulItemID, put there either by the WPS or xWorkplaceShell when a WPProgram type object is being dragged.  Anyone know what that value is?

I only want to accept dragged WPObjects of a certain type being dropped, and disallow everything else.

Thanks in advance

Rich Walsh

  • Sr. Member
  • ****
  • Posts: 342
  • Karma: +23/-0
  • ONU! (OS/2 is NOT Unix!)
    • View Profile
Re: WPS dragged object handle
« Reply #1 on: September 29, 2023, 10:51:36 pm »
I am trying to identify the object that is being dragged over my window [...]

There is a value in ulItemID, put there either by the WPS or xWorkplaceShell when a WPProgram type object is being dragged. Anyone know what that value is?

For items that identify themselves as "<DRM_OBJECT,DRF_OBJECT>" ulItemID is a pointer to the object's container record. This is very useful within the WPS process but useless outside it. Indeed, there's nothing in a DRAGITEM that gives any hint as to the type of object being dragged other than to identify whether it's a file (e.g. "<DRM_OS2FILE,DRF_TEXT>"),

The only way I know of to get info about a WPS object from outside the WPS process is to use RWS. It allows you to call into the WPS using that ulItemID to query the object's attributes, execute its methods, and generally do whatever you want to inside the WPS. My only concern in this case is that it may have too much overhead to use it "live" during a drag.

FYI... RWS's runtime DLLs are included in all releases of AOS. For development, you will need the full package: https://hobbes.nmsu.edu/download/pub/os2/dev/libraries/SOM/RWS_0-80.zip

Doug Clark

  • Sr. Member
  • ****
  • Posts: 323
  • Karma: +8/-1
    • View Profile
Re: WPS dragged object handle
« Reply #2 on: September 30, 2023, 07:05:39 am »
Thanks Rich for the help and info.

There are portions of the app that run in the WPS process and portions that run outside the WPS process.  I was planning on using RWS for the outside-of-WPS-process parts. (BTW thanks for building and releasing that)  I did not know that it was bundled with all AOS versions - that will help with building the install process.

For anyone else that might follow this topic, the code section looks something like this
----------------------------------------------
if( DrgVerifyRMF( DrgQueryDragitemPtr( pdrgInfo, ulCount),"DRM_OBJECT", NULL))
{
     WPObject * pObject;
     PDRAGITEM   pDragItem;     
     
     pDragItem =  DrgQueryDragitemPtr( pdrgInfo, ulCount);
     pObject = OBJECT_FROM_PREC(pDragItem->ulItemID);     
     if (_debug) PmPrintfPtr("wpDragOver   DRM_OBJECT name: %s",_somGetClassName(pObject));

   ...
----------------------------------------------------------------------
after you know that ulItemID contains pointer to the container record (thanks Rich)  for the object, the magic sauce is the WPS macro OBJECT_FROM_PREC(), which extracts a pointer to WObject  from ulItemID

-- editor to remove late night operator error --
« Last Edit: September 30, 2023, 02:01:22 pm by Doug Clark »

Lars

  • Hero Member
  • *****
  • Posts: 1303
  • Karma: +66/-0
    • View Profile
Re: WPS dragged object handle
« Reply #3 on: September 30, 2023, 04:24:31 pm »
Thanks Rich for the help and info.

There are portions of the app that run in the WPS process and portions that run outside the WPS process.  I was planning on using RWS for the outside-of-WPS-process parts. (BTW thanks for building and releasing that)  I did not know that it was bundled with all AOS versions - that will help with building the install process.

For anyone else that might follow this topic, the code section looks something like this
----------------------------------------------
if( DrgVerifyRMF( DrgQueryDragitemPtr( pdrgInfo, ulCount),"DRM_OBJECT", NULL))
{
     WPObject * pObject;
     PDRAGITEM   pDragItem;     
     
     pDragItem =  DrgQueryDragitemPtr( pdrgInfo, ulCount);
     pObject = OBJECT_FROM_PREC(pDragItem->ulItemID);     
     if (_debug) PmPrintfPtr("wpDragOver   DRM_OBJECT name: %s",_somGetClassName(pObject));

   ...
----------------------------------------------------------------------
after you know that ulItemID contains pointer to the container record (thanks Rich)  for the object, the magic sauce is the WPS macro OBJECT_FROM_PREC(), which extracts a pointer to WObject  from ulItemID

-- editor to remove late night operator error --

... and if you feel uneasy about using the pointer, you can use somIsObj(pObject) to check if it indeed is a SOM (or derived thereof) object.
And if you follow the example code for "somIsObj" in the SOM Programming Reference, it shows how to query the SOM/WPS classname of the passed object which should give you an exact clue of what you are dealing with.

Another helpful SOM member function is "somIsA" which will allow you to check if an object is of a given class or a derived class thereof:
if (pObject->somIsA(_WPFolder)) will tell you if the passed object is a folder or a derived class thereof. Don't worry about WPFolder class replacements: the SOM runtime will detect if WPFolder class has been replaced by something else. There never is a need to code the check against a replacement class (you won't need to do a if (pObject->somIsA(_XFolder)) if you have XWorkplace installed. SOM will find out by itself).

As to C++ vs. C bindings (I always prefer C++ even if I code in plain C):
C++ bindings: pObject->somIsA(_WPFolder)
C bindings: _somIsA(pObject,_WPFolder)
« Last Edit: September 30, 2023, 04:42:02 pm by Lars »

Doug Clark

  • Sr. Member
  • ****
  • Posts: 323
  • Karma: +8/-1
    • View Profile
Re: WPS dragged object handle
« Reply #4 on: October 01, 2023, 12:18:19 am »
Thanks Lars for the tips.

WPS programming is actually pretty interesting.  The difficult part is finding all the "special" tricks or knowledge you need to do some stuff.

For anyone else starting out, I found the book "OS/2 Workplace Shell API" by Mindy Pollack to be very helpful because it lists a lot of those special things that are helpful or necessary to know.  Although the book doesn't go much in the SOM aspect - it stays pretty much in the WPS, so it doesn't have Lars' tips.

Lars

  • Hero Member
  • *****
  • Posts: 1303
  • Karma: +66/-0
    • View Profile
Re: WPS dragged object handle
« Reply #5 on: October 01, 2023, 03:47:52 am »
Hi Doug, yes I also bought that book (I found a used one for a few bucks). And it helped a lot to fill the voids (in particular: object locking -> some methods lock the objects they return, some others do not. Need to make sure that locks and unlocks are always balanced ...).
Then the SOM and WPS programming guides and references are a bit sparse on a couple of things but the rest always is trial and error (and debugging).

The greatest thing about the WPS is that you can extend and modify (and even fix) the WPS as the main interface to the end user.That is unsurpassed to the present day.

Lars

  • Hero Member
  • *****
  • Posts: 1303
  • Karma: +66/-0
    • View Profile
Re: WPS dragged object handle
« Reply #6 on: October 04, 2023, 01:52:23 pm »
By the way: the drag control memory Block is gettable shared memory. You will need to do a DrgAccessDraginfo and DrgFreeDraginfo to request (respectively free) shared mem access before you access any of DragInfo or Dragitem structures.