f



Querying the Draginfo from within DM_RENDERCOMPLETE - some problems

Hallo,

I am implementing drag&drop support for LXPM, the editor that comes with 
VAC 3. One the one hand, I am supporting the drop of files that can 
directly be handled by the drop handler (without going through the 
DM_RENDER/DM_RENDERCOMPLETE cycle). On the other hand, I am supporting 
the drop of marked text fragments from EPM which have to go through the 
rendering process (DM_RENDER / DM_RENDERCOMPLETE).

I have mostly followed this:
http://groups.google.de/group/comp.os.os2.programmer.misc/browse_thread/thread/b2304feeeea36a8d/9641d096b9921c93?lnk=gst&q=DM_RENDER&rnum=7#9641d096b9921c93

In principle, everything works just fine. In particular, dropping files 
(from WPS or elsewhere where <DRM_OS2FILE,DRF_TEXT> is supported and I 
have a valid container and source name) is not a problem at all.
However, for text fragments dropped from EPM, whenever the 
DM_RENDERCOMPLETE handler is entered, the calls to:

DrgQueryDraginfoPtr
DrgQueryDraginfoPtrFromDragitem
DrgQueryDraginfoPtrFromHwnd

all return a NULL pointer which makes it impossible to query and 
therefore properly free the Draginfo structure. This eventually would 
lead to a crash.

Then I implemented the really ugly hack as described in:
http://groups.google.de/group/comp.os.os2.programmer.misc/browse_thread/thread/9684e240d3792f1e/d17414e8b0f167a7?hl=de&q=In+DM_DROP,+do+I#d17414e8b0f167a7
in order to compute the Draginfo pointer directly from the Dragitem pointer:
    PDRAGINFO pDragInfo=NULL;
    PDRAGITEM pDragItem=NULL;

    pDragItem = pDragTransfer->pditem;
    pDragInfo = (PDRAGINFO)(((ULONG)pDragItem & 0xFFFF0000) + 0x2C);

That indeed gives me a valid pointer that I can pass to DrgFreeDragInfo 
and DrgDeleteDraginfoStrHandles without any problems.

Questions:
1.) do I really have to call DrgFreeDragInfo from within DM_DRAGOVER ? 
What's the logic between 
DrgAllocDraginfo,DrgAccessDraginfo,DrgFreeDraginfo ? I am not complete 
sure about the "matching" logic ...
2.) if DM_RENDER fails (returns error to drop target) , will 
DM_RENDERCOMPLETE be invoked by the drag source anyway ? In other words: 
can I do the clean up for every Dragitem that has undergone the 
rendering process in DM_RENDERCOMPLETE or do I have to do the cleanup in 
DM_DROP if rendering fails (as I did in sample code below) ?
3.) is the DragInfo offset of 0x002C an offset into a 64-kByte segment 
(as above) or only into a 4-kByte page like so:
    pDragInfo = (PDRAGINFO)(((ULONG)pDragItem & 0xFFFFF000) + 0x2C); Is 
there a potential possibility that multiple DragInfo structures are 
allocated by one process so that this hack could potentially fail ?
4.) Why do DragQueryDragitem... fail ? What could be the reason ?


Thanks for any hint,
Lars





Here is the current code (relevant drag&drop part):
MRESULT DragOverHandler(HWND hwnd,PDRAGINFO pDragInfo)
{
    PDRAGITEM pDragItem;
    ULONG i,ulItems;
    USHORT usIndicator=DOR_NEVERDROP,usOp=0;

    if (DrgAccessDraginfo(pDragInfo))
    {
       usIndicator = DOR_DROP;
       usOp = DO_MOVE;

       if (pDragInfo->usOperation != DO_DEFAULT)
       {
          usIndicator = DOR_NODROPOP;
          usOp = 0;
       }
       else
       {
          ulItems = DrgQueryDragitemCount(pDragInfo);
          for (i=0;i<ulItems;i++)
          {
             pDragItem = DrgQueryDragitemPtr(pDragInfo,i);
#ifdef DEBUG
             DrgQueryStrName(pDragItem->hstrType,sizeof(testBuf1),testBuf1);
             DrgQueryStrName(pDragItem->hstrRMF,sizeof(testBuf2),testBuf2);
 
DrgQueryStrName(pDragItem->hstrContainerName,sizeof(testBuf3),testBuf3);
 
DrgQueryStrName(pDragItem->hstrSourceName,sizeof(testBuf4),testBuf4);
 
DrgQueryStrName(pDragItem->hstrTargetName,sizeof(testBuf5),testBuf5);
#endif
             if (!pDragItem->hstrContainerName ||
                 !DrgVerifyRMF(pDragItem,"DRM_OS2FILE","DRF_TEXT")
             )
             {
                usIndicator = DOR_NEVERDROP;
                usOp = 0;
                break;
             }
          }
       }
       DrgFreeDraginfo(pDragInfo);
    }
    return MRFROM2SHORT(usIndicator,usOp);
}

MRESULT DropHandler(HWND hwnd,PDRAGINFO pDragInfo)
{
    PDRAGTRANSFER pDragTransfer,pTemp;
    PDRAGITEM pDragItem;
    ULONG ulLen;
    ULONG i,j,ulItems,ulItemsDelayed;
    int ret;

    if (DrgAccessDraginfo(pDragInfo))
    {
       ulItemsDelayed = 0;
       ulItems = DrgQueryDragitemCount(pDragInfo);
       for (i=0;i<ulItems;i++)
       {
          pDragItem = DrgQueryDragitemPtr(pDragInfo,i);
          if (pDragItem->hstrSourceName)
          {
             memset(pCmdString,0,CCHMAXPATH);
             pCmdString[0]='"';
             ulLen = 
DrgQueryStrName(pDragItem->hstrContainerName,CCHMAXPATH,pCmdString+1);
             ulLen = ulLen + 
DrgQueryStrName(pDragItem->hstrSourceName,CCHMAXPATH-ulLen,pCmdString+ulLen+1);
             pCmdString[ulLen+1]='"';
             if (strlen(pParamString))
             {
                strcat(pCmdString," ");
                strcat(pCmdString,pParamString);
             }

             ret = lxcall("lx",pCmdString);

             DrgSendTransferMsg(pDragItem->hwndItem,
                                  DM_ENDCONVERSATION,
                                  MPFROMP(pDragItem->ulItemID),
                                  ret >= 0 ? 
MPFROMLONG(DMFL_TARGETSUCCESSFUL):MPFROMLONG(DMFL_TARGETFAIL));
          }
          else
          {
             ulItemsDelayed++;
          }
       }
       if (!ulItemsDelayed || (pDragTransfer = 
DrgAllocDragtransfer(ulItemsDelayed)) == NULL)
       {
          DrgDeleteDraginfoStrHandles(pDragInfo);
          DrgFreeDraginfo(pDragInfo);
       }
       else
       {
          for (i=0,j=ulItemsDelayed,pTemp = pDragTransfer;i<ulItems;i++,j--)
          {
             pDragItem = DrgQueryDragitemPtr(pDragInfo,i);
             if (!pDragItem->hstrSourceName)
             {
                pTemp->cb               = sizeof(DRAGTRANSFER);
                pTemp->hwndClient       = hwnd;
                pTemp->pditem           = pDragItem;
                pTemp->hstrSelectedRMF  = 
DrgAddStrHandle("<DRM_OS2FILE,DRF_TEXT>");
                pTemp->hstrRenderToName = 0;
                pTemp->ulTargetInfo     = j;
                pTemp->fsReply          = 0;
                pTemp->usOperation      = DO_DEFAULT;

                if (pDragItem->fsControl & DC_PREPAREITEM)
                {
 
DrgSendTransferMsg(pDragItem->hwndItem,DM_RENDERPREPARE,(MPARAM)pTemp,0);
                }
                memset(pCmdString,0,CCHMAXPATH);
                ulLen = 
DrgQueryStrName(pDragItem->hstrContainerName,CCHMAXPATH,pCmdString);
                ulLen = ulLen + 
DrgQueryStrName(pDragItem->hstrTargetName,CCHMAXPATH-ulLen,pCmdString+ulLen);
                pTemp->hstrRenderToName = DrgAddStrHandle(pCmdString);
                if ((pDragItem->fsControl & (DC_PREPARE|DC_PREPAREITEM)) 
== DC_PREPARE)
                {
 
DrgSendTransferMsg(pDragItem->hwndItem,DM_RENDERPREPARE,(MPARAM)pTemp,0);
                }

                if 
(!DrgSendTransferMsg(pDragItem->hwndItem,DM_RENDER,(MPARAM)pTemp,0))
                {
 
DrgSendTransferMsg(pDragItem->hwndItem,DM_ENDCONVERSATION,(MPARAM)pDragItem->ulItemID,(MPARAM)DMFL_TARGETFAIL);
                   DrgDeleteStrHandle(pTemp->hstrSelectedRMF);
                   DrgDeleteStrHandle(pTemp->hstrRenderToName);
                   DrgFreeDragtransfer(pTemp);
                }
                else
                {
                   pTemp++;
                }
             }
          }
          if (pTemp == pDragTransfer)
          {
             DrgDeleteDraginfoStrHandles(pDragInfo);
             DrgFreeDraginfo(pDragInfo);
          }
       }
    }
    return MRFROMLONG(0);
}

MRESULT RenderCompleteHandler(PDRAGTRANSFER pDragTransfer,USHORT usResults)
{
    PDRAGINFO pDragInfo=NULL;
    PDRAGITEM pDragItem=NULL;
    ULONG ulLen,ulTargetInfo;
    int ret;

    pDragItem = pDragTransfer->pditem;
    pDragInfo = (PDRAGINFO)(((ULONG)pDragItem & 0xFFFF0000) + 0x2C);
    ulTargetInfo = pDragTransfer->ulTargetInfo;

    if (usResults & DMFL_RENDEROK)
    {
       memset(pCmdString,0,CCHMAXPATH);
       pCmdString[0]='"';
       ulLen = 
DrgQueryStrName(pDragTransfer->hstrRenderToName,sizeof(pCmdString),pCmdString+1);
       pCmdString[ulLen+1]='"';
       ret = lxcall("get",pCmdString);
       lxcmd("LP_SELALL");
       memmove(pCmdString,pCmdString+1,ulLen);
       pCmdString[ulLen]='\0';
       DosForceDelete(pCmdString);
    }

    DrgSendTransferMsg(pDragItem->hwndItem,
                         DM_ENDCONVERSATION,
                         (MPARAM)pDragItem->ulItemID,
                         ret >= 0 ? (MPARAM)DMFL_TARGETSUCCESSFUL: 
(MPARAM)DMFL_TARGETFAIL);

    DrgDeleteStrHandle(pDragTransfer->hstrSelectedRMF);
    DrgDeleteStrHandle(pDragTransfer->hstrRenderToName);
    DrgFreeDragtransfer(pDragTransfer);

    if (ulTargetInfo == 1)
    {
#ifdef DEBUG
       DosBeep(400,100);
#endif
       DrgDeleteDraginfoStrHandles(pDragInfo);
       DrgFreeDraginfo(pDragInfo);
    }

    return (MRESULT)0;
}

MRESULT ShowHelp(HWND hwnd,PDRAGINFO pDragInfo)
{
    MB2EXTINFO mb  ={0};

    mb.cb          = sizeof(mb);
    mb.cButtons    = 2;
    mb.flStyle     = MB_INFORMATION | MB_NONMODAL | MB_MOVEABLE;
    mb.hwndNotify  = hwnd;
    strcpy(mb.mb2d[0].achText,"Cancel");
    mb.mb2d[0].idButton  = 10;
    mb.mb2d[0].flStyle  = BS_PUSHBUTTON;
    strcpy(mb.mb2d[1].achText,"Help");
    mb.mb2d[1].idButton  = 20;
    mb.mb2d[1].flStyle  = BS_PUSHBUTTON;


    if (DrgAccessDraginfo(pDragInfo))
    {
       WinMessageBox2(HWND_DESKTOP,
                      NULLHANDLE,
                      "DRGDRP can take the following parameters when 
invoked through the LPEX command execution line:\n"\
                      "/settings\n"\
                      "\tto query the current settings\n"\
                      "/nopro,/np\n"\
                      "/nosys,/ns\n"\
                      "/asis,/as\n"\
                      "/doctype DocType,/dt DocType\n"\
                      "\tsame meaning as parameters to \"lx\" command\n"\
                      "\tpress \"Help\" to see Editor Reference\n\n"\
                      "Note: DRGDRP will only correctly handle 
parameters\n"\
                      "if it is initially loaded through the 
\"profinit.lx\" profile !",
                      "Info",
                      0,
                      (PMB2INFO)&mb);

       DrgDeleteDraginfoStrHandles(pDragInfo);
       DrgFreeDraginfo(pDragInfo);
    }
    return MPFROMLONG(0);
}

VOID InvokeHelp(HWND hwnd)
{
    PROGDETAILS d={0};

    d.Length = sizeof(d);
    d.pszExecutable = "VIEW.EXE";
    WinStartApp(hwnd,&d,"LPXCREF.INF \"lx command\"",NULL,0UL);
    return;
}


MRESULT EXPENTRY ClientProc(HWND hwnd,ULONG msg,MPARAM mp1,MPARAM mp2)
{
    switch(msg)
    {
       case DM_DRAGOVER:
          return DragOverHandler(hwnd,(PDRAGINFO)MPFROMP(mp1));

       case DM_DROP:
          return DropHandler(hwnd,(PDRAGINFO)MPFROMP(mp1));

       case DM_DROPHELP:
          return ShowHelp(hwnd,(PDRAGINFO)MPFROMP(mp1));

       case DM_RENDERCOMPLETE:
          return 
RenderCompleteHandler((PDRAGTRANSFER)MPFROMP(mp1),SHORT1FROMMP(mp2));

       case WM_MSGBOXDISMISS:
          {
             BOOL rc = FALSE;
             HWND hwndMsgBox=HWNDFROMMP(mp1);
             if (LONGFROMMP(mp2) == 20)
             {
                InvokeHelp(hwnd);
             }
             rc = WinDestroyWindow(hwndMsgBox);
             return (MRESULT)0;
          }

       default:
          break;
    }
    return gOldClientProc(hwnd,msg,mp1,mp2);
}
0
Lars
10/26/2009 8:32:08 PM
comp.os.os2.programmer.misc 1326 articles. 0 followers. Post Follow

0 Replies
227 Views

Similar Articles

[PageSpeed] 33

Reply: