home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / drdc011.zip / source / drusrctl.c next >
C/C++ Source or Header  |  2002-03-21  |  25KB  |  661 lines

  1. /**********************************************************************
  2. *                                                                     *
  3. * DRUSRCTL.DLL                                                        *
  4. *                                                                     *
  5. * Copyright C. Wohlgemuth 2001                                        *
  6. *                                                                     *
  7. * This Rexx DLL contains a new  controls for use with                 *
  8. * DrDialog.                                                           *
  9. *                                                                     *
  10. **********************************************************************/
  11. /*
  12.  * Copyright (c) Chris Wohlgemuth 2001 
  13.  * All rights reserved.
  14.  *
  15.  * http://www.geocities.com/SiliconValley/Sector/5785/
  16.  * http://www.os2world.com/cdwriting
  17.  *
  18.  * Redistribution and use in source and binary forms, with or without
  19.  * modification, are permitted provided that the following conditions
  20.  * are met:
  21.  * 1. Redistributions of source code must retain the above copyright
  22.  *    notice, this list of conditions and the following disclaimer.
  23.  * 2. Redistributions in binary form must reproduce the above copyright
  24.  *    notice, this list of conditions and the following disclaimer in the
  25.  *    documentation and/or other materials provided with the distribution.
  26.  * 3. The authors name may not be used to endorse or promote products
  27.  *    derived from this software without specific prior written permission.
  28.  *
  29.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
  30.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  31.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  32.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  33.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  34.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  35.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  36.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  37.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  38.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  39.  * SUCH DAMAGE.
  40.  *
  41.  */
  42.  
  43.  
  44.  
  45. /* Include files */
  46.  
  47. #define  INCL_PM
  48. #define  INCL_WINSYS
  49. #define  INCL_DOS
  50. #define  INCL_DOSMISC
  51. #define  INCL_DOSNMPIPES
  52. #define  INCL_ERRORS
  53. #define  INCL_REXXSAA
  54. #define  _DLL
  55. #define  _MT
  56. #include <os2.h>
  57. #include <rexxsaa.h>
  58. #include <malloc.h>
  59. #include <fcntl.h>
  60. #include <ctype.h>
  61. #include <string.h>
  62. #include <stdlib.h>
  63. #include <stdio.h>
  64. #include <conio.h>
  65.  
  66. #define DRDCTRL_VERSION "0.1.1"
  67.  
  68. /* Window ULONG for the percent bar */
  69. #define QWL_PERCENT 4 /* The location in the window words to store the percent value */
  70. #define QWL_TEXTPTR 8 /* The ptr to our percent bar text */
  71.  
  72. /* Window ULONG for the bubble help control */
  73. #define QWL_DELAY        4
  74. /*#define QWL_TEXTPTR 8   already defined for percent bar */
  75. #define QWL_SHOWTIME     12
  76. #define QWL_SHOWBUBBLE   16
  77. #define QWL_DELTAPOS     20
  78. #define BUBBLEHELP_ULONGS 24
  79.  
  80. #define BUBBLE_DELAY_TIMER  1
  81. #define BUBBLE_SHOW_TIMER   2
  82. #define BUBBLE_CHECK_TIMER  3
  83.  
  84.  
  85.  
  86. #define xVal  12      /* x-distance of Bubble */
  87. #define yVal  8      /* y-distance of Bubble */
  88.  
  89. /*********************************************************************/
  90. /*  Declare all exported functions as REXX functions.                */
  91. /*********************************************************************/
  92.  
  93. RexxFunctionHandler DRCtrlDropFuncs;
  94. RexxFunctionHandler DRCtrlRegister;
  95. RexxFunctionHandler DRCtrlLoadFuncs;
  96. RexxFunctionHandler DRCtrlVersion;
  97.  
  98. /*********************************************************************/
  99. /* RxFncTable                                                        */
  100. /*   Array of names of the REXXUTIL functions.                       */
  101. /*   This list is used for registration and deregistration.          */
  102. /*********************************************************************/
  103.  
  104. static PSZ  RxFncTable[] =
  105.    {
  106.       "DRCtrlRegister",
  107.       "DRCtrlLoadFuncs",
  108.       "DRCtrlDropFuncs",
  109.       "DRCtrlVersion",
  110.    };
  111.  
  112. /*********************************************************************/
  113. /* Numeric Error Return Strings                                      */
  114. /*********************************************************************/
  115.  
  116. #define  NO_UTIL_ERROR    "0"          /* No error whatsoever        */
  117. #define  ERROR_NOMEM      "2"          /* Insufficient memory        */
  118. #define  ERROR_FILEOPEN   "3"          /* Error opening text file    */
  119.  
  120. /*********************************************************************/
  121. /* Alpha Numeric Return Strings                                      */
  122. /*********************************************************************/
  123.  
  124. #define  ERROR_RETSTR   "ERROR:"
  125. #define  EMPTY_RETSTR   ""
  126.  
  127. /*********************************************************************/
  128. /* Numeric Return calls                                              */
  129. /*********************************************************************/
  130.  
  131. #define  INVALID_ROUTINE 40            /* Raise Rexx error           */
  132. #define  VALID_ROUTINE    0            /* Successful completion      */
  133.  
  134. /*********************************************************************/
  135. /* Some useful macros                                                */
  136. /*********************************************************************/
  137.  
  138. #define BUILDRXSTRING(t, s) { \
  139.   strcpy((t)->strptr,(s));\
  140.   (t)->strlength = strlen((s)); \
  141. }
  142.  
  143. /*
  144.  * Paint the percent bar and print the label if necessary.
  145.  */
  146.  
  147. static VOID _paintPercent(int iPercent, HWND hwnd, HPS hps)
  148. {
  149.     POINTL  ptl, ptlText, aptlText[TXTBOX_COUNT];
  150.     RECTL   rcl, rcl2;
  151.     BOOL    bVertical=FALSE;
  152.     CHAR  * ptrChr=NULL;
  153.  
  154.     WinQueryWindowRect(hwnd, &rcl);
  155.     /* Check if it's a vertical percent bar */
  156.     if(rcl.xRight<rcl.yTop)
  157.       bVertical=TRUE;
  158.     else
  159.       bVertical=FALSE;
  160.  
  161.     GpiCreateLogColorTable(hps, 0, LCOLF_RGB, 0, 0, NULL);
  162.     
  163.     /* Draw the bar border */
  164.     WinDrawBorder(hps, &rcl, 1,1,0,0, 0x800);    
  165.     
  166.     rcl.xLeft = 1;
  167.     rcl.xRight -= 1;
  168.     rcl.yBottom = 1;
  169.     rcl.yTop -= 1;
  170.     
  171.     if((ptrChr=(char*)WinQueryWindowPtr(hwnd,QWL_TEXTPTR))!=NULLHANDLE)
  172.       {
  173.         /* Text size */
  174.         GpiQueryTextBox(hps, strlen(ptrChr), ptrChr,
  175.                         TXTBOX_COUNT, (PPOINTL)&aptlText);
  176.    
  177.         ptlText.x = rcl.xLeft+(((rcl.xRight-rcl.xLeft)
  178.                                  -(aptlText[TXTBOX_BOTTOMRIGHT].x-aptlText[TXTBOX_BOTTOMLEFT].x))/2);
  179.         ptlText.y = 3 + rcl.yBottom+(((rcl.yTop-rcl.yBottom)
  180.                                       -(aptlText[TXTBOX_TOPLEFT].y-aptlText[TXTBOX_BOTTOMLEFT].y))/2);
  181.       }
  182.  
  183.     if(!bVertical) {
  184.       rcl2.xLeft = rcl.xLeft;
  185.       rcl2.xRight = (rcl.xRight-rcl.xLeft)*iPercent/100; 
  186.       rcl2.yBottom = rcl.yBottom;
  187.       rcl2.yTop = rcl.yTop-1;
  188.       rcl.xLeft=rcl2.xRight+1;
  189.     }
  190.     else {
  191.       rcl2.xLeft = rcl.xLeft;
  192.       rcl2.xRight = rcl.xRight-1;
  193.       rcl2.yBottom = rcl.yBottom;
  194.       rcl2.yTop = (rcl.yTop-rcl.yBottom)*iPercent/100; 
  195.       rcl.yBottom=rcl2.yTop+1;
  196.     }
  197.  
  198.     /* Background */
  199.     WinFillRect(hps, &rcl,
  200.                 WinQuerySysColor(HWND_DESKTOP, SYSCLR_DIALOGBACKGROUND, 0));
  201.  
  202.     /* Percentbar */
  203.     if ((rcl2.xRight > rcl2.xLeft && !bVertical)||(rcl2.yTop > rcl2.yBottom && bVertical)) {
  204.       ULONG ulBG;
  205.  
  206.       /* Find color. This color is the background color set within DrDialog */
  207.       if(!WinQueryPresParam(hwnd, PP_BACKGROUNDCOLOR, PP_BACKGROUNDCOLORINDEX, NULL, sizeof(ulBG),
  208.                         &ulBG, QPF_ID2COLORINDEX|QPF_NOINHERIT ))
  209.         ulBG=0x002020ff;
  210.       GpiSetColor(hps,ulBG );
  211.  
  212.       rcl2.yBottom+=1;
  213.       rcl2.xLeft+=1;
  214.  
  215.       WinFillRect(hps, &rcl2, ulBG);
  216.       WinDrawBorder(hps, &rcl2, 1,1,0,0, 0x400);
  217.     }
  218.  
  219.     /* now print the percentage */
  220.     if(ptrChr!=NULLHANDLE)
  221.       {
  222.         ULONG ulFG; 
  223.        
  224.         /* Find color. This color is the foreground color set within DrDialog */
  225.         if(!WinQueryPresParam(hwnd, PP_FOREGROUNDCOLOR, PP_FOREGROUNDCOLORINDEX, NULL, sizeof(ulFG),
  226.                               &ulFG, QPF_ID2COLORINDEX|QPF_NOINHERIT ))
  227.           ulFG=WinQuerySysColor(HWND_DESKTOP, SYSCLR_BUTTONDEFAULT, 0);
  228.         GpiSetColor(hps,ulFG );
  229.         GpiMove(hps, &ptlText);
  230.         GpiCharString(hps, strlen(ptrChr), ptrChr);
  231.       }
  232. }
  233.  
  234.  
  235. /*
  236.  * This is the window proc for the percentbar control
  237.  */
  238.  
  239. static MRESULT EXPENTRY _percentBarProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  240. {
  241.   MRESULT mrc;
  242.   HPS hps;
  243.   PWNDPARAMS pwp;
  244.   int iPercent;
  245.   RECTL rcl;
  246.  
  247.   switch(msg) {
  248.  
  249.   case WM_SETWINDOWPARAMS:
  250.     {
  251.       pwp=(PWNDPARAMS)mp1;
  252.       if(pwp->fsStatus==WPM_TEXT) {
  253.         /* The text changed */
  254.         char *ptr;
  255.         char *ptr2;
  256.  
  257.         /* Get the current percent value for the control */
  258.         iPercent=atol(pwp->pszText);
  259.         if(iPercent>100)
  260.           iPercent=100;
  261.         if(iPercent<0)
  262.           iPercent=0;
  263.  
  264.         /* Check if there is some text for the bar */
  265.         if((ptr=strchr(pwp->pszText, '#'))!=NULLHANDLE) {
  266.           /* Everything after the '#' is treated as the label */
  267.           if((ptr2=(char*)WinQueryWindowPtr(hwnd,QWL_TEXTPTR))!=NULLHANDLE)
  268.             free(ptr2); /* Free the old text */
  269.           WinSetWindowPtr(hwnd,QWL_TEXTPTR, NULLHANDLE);
  270.           if(*(ptr++)!=0) {
  271.             /* There's additional text to print */
  272.             if((ptr2=malloc(strlen(ptr)+1))!=NULLHANDLE) {
  273.               strcpy(ptr2,ptr);
  274.               WinSetWindowPtr(hwnd,QWL_TEXTPTR,ptr2);
  275.             }
  276.           }
  277.         }
  278.         mrc = WinDefWindowProc(hwnd, msg, mp1, mp2);
  279.         WinSetWindowULong(hwnd, QWL_PERCENT,iPercent);
  280.         WinInvalidateRect(hwnd, NULLHANDLE,TRUE);
  281.         return mrc;
  282.       }
  283.       break;
  284.     }
  285.   case WM_DESTROY:
  286.     {
  287.       char *ptrText;
  288.       /* Free the memory allocated for the text */
  289.       if((ptrText=(char*)WinQueryWindowPtr(hwnd,QWL_TEXTPTR))!=NULLHANDLE)
  290.         free(ptrText);
  291.       break;
  292.     }
  293.   case WM_PRESPARAMCHANGED:
  294.     /* The color or the font has changed  */
  295.     /* Force a repaint of the percent bar */
  296.     mrc = WinDefWindowProc(hwnd, msg, mp1, mp2);
  297.     if(LONGFROMMP(mp1)==PP_FOREGROUNDCOLOR)
  298.       WinInvalidateRect(hwnd, NULLHANDLE,TRUE);
  299.     else if(LONGFROMMP(mp1)==PP_BACKGROUNDCOLOR)
  300.       WinInvalidateRect(hwnd, NULLHANDLE,TRUE);
  301.     else if(LONGFROMMP(mp1)==PP_FONTNAMESIZE)
  302.       WinInvalidateRect(hwnd, NULLHANDLE,TRUE);
  303.     return mrc;
  304.   case WM_PAINT:
  305.     {
  306.       hps=WinBeginPaint(hwnd, NULLHANDLE, NULLHANDLE);
  307.       _paintPercent(WinQueryWindowULong(hwnd,QWL_PERCENT), hwnd, hps);
  308.       WinEndPaint(hps);
  309.     return (MRESULT) FALSE;
  310.     }
  311.   
  312.   default:
  313.     break;
  314.   }
  315.  
  316.   mrc = WinDefWindowProc(hwnd, msg, mp1, mp2);
  317.   return (mrc);
  318. }
  319.  
  320. static MRESULT EXPENTRY _bubbleHelpProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  321. {
  322.  
  323.   MRESULT mrc;
  324.   HPS hps;
  325.   PWNDPARAMS pwp;
  326.   RECTL rcl;
  327.   static HWND hwndBubbleWindow;
  328.   POINTL ptl;
  329.   POINTL aptlPoints[TXTBOX_COUNT];
  330.  
  331.   switch(msg) {
  332.   case WM_SETWINDOWPARAMS:
  333.     {
  334.       pwp=(PWNDPARAMS)mp1;
  335.       if(pwp->fsStatus==WPM_TEXT) {
  336.         /* The text changed */
  337.         char *ptr;
  338.         char *ptr2;
  339.  
  340.         if((ptr2=(char*)WinQueryWindowPtr(hwnd,QWL_TEXTPTR))!=NULLHANDLE)
  341.           free(ptr2); /* Free the old text */
  342.         WinSetWindowPtr(hwnd,QWL_TEXTPTR, NULLHANDLE);
  343.  
  344.         if(strlen(pwp->pszText)) {
  345.           /* Set the delay */
  346.           if(strstr(pwp->pszText,"#delay")!=NULLHANDLE) {
  347.             ptr=pwp->pszText;
  348.             ptr+=strlen("#delay");
  349.             WinSetWindowULong(hwnd,QWL_DELAY, atol(ptr));
  350.             return (MRESULT)0;
  351.           }
  352.           /* Set the time to show the bubble */
  353.           if(strstr(pwp->pszText,"#show")!=NULLHANDLE) {
  354.             ptr=pwp->pszText;
  355.             ptr+=strlen("#show");
  356.             WinSetWindowULong(hwnd,QWL_SHOWTIME, atol(ptr));
  357.             return (MRESULT)0;
  358.           }
  359. #if 0
  360.           if(strstr(pwp->pszText,"#deltax")!=NULLHANDLE) {
  361.             ULONG ulDelta;
  362.             SHORT dx;
  363.             ptr=pwp->pszText;
  364.             ptr+=strlen("#deltax");
  365.             dx=atoi(ptr);
  366.             ulDelta=WinQueryWindowULong(hwnd, QWL_DELTAPOS) & 0x0000FFFF;
  367.             WinSetWindowULong(hwnd,QWL_DELTAPOS, (ULONG)((LONG)dx));
  368.             return (MRESULT)0;
  369.           }
  370.  
  371.           if(strstr(pwp->pszText,"#deltay")!=NULLHANDLE) {
  372.             ULONG ulDelta;
  373.             ptr=pwp->pszText;
  374.             ptr+=strlen("#deltay");
  375.             ulDelta=WinQueryWindowULong(hwnd, QWL_DELTAPOS)& 0xFFFF0000;
  376.             WinSetWindowULong(hwnd,QWL_DELTAPOS, (atol(ptr)&0x0000FFFF)+ulDelta);
  377.             return (MRESULT)0;
  378.           }
  379. #endif
  380.           /* There's text to save */
  381.           if((ptr2=malloc(strlen(pwp->pszText)))!=NULLHANDLE) {
  382.             strcpy(ptr2, pwp->pszText);
  383.             WinSetWindowPtr(hwnd,QWL_TEXTPTR,ptr2);
  384.             WinStopTimer(WinQueryAnchorBlock(hwnd),hwnd,BUBBLE_DELAY_TIMER);  /* stop the running timer */
  385.             WinStopTimer(WinQueryAnchorBlock(hwnd),hwnd,BUBBLE_SHOW_TIMER);  /* stop the running timer */
  386.             WinStopTimer(WinQueryAnchorBlock(hwnd),hwnd,BUBBLE_CHECK_TIMER);
  387.             if(hwndBubbleWindow){
  388.               WinDestroyWindow(hwndBubbleWindow);/*  close the bubblewindow  */
  389.               hwndBubbleWindow=NULLHANDLE;
  390.             }
  391.             /* Start a timer */
  392.             WinStartTimer(WinQueryAnchorBlock(hwnd),hwnd,BUBBLE_DELAY_TIMER,
  393.                           WinQueryWindowULong(hwnd,QWL_DELAY)); /* New timer for delay */
  394.             WinSetWindowULong(hwnd, QWL_SHOWBUBBLE,1);/* Mark that we have bubble text */
  395.           }
  396.         }
  397.         else {
  398.           /* No text */
  399.             WinStopTimer(WinQueryAnchorBlock(hwnd),hwnd,BUBBLE_DELAY_TIMER);  /* stop the running timer */
  400.             WinSetWindowULong(hwnd, QWL_SHOWBUBBLE,0);/* Mouse left control. We need no bubble */
  401.         }
  402.         return (MRESULT)0;
  403.       }/* WPM_TEXT */
  404.       break;
  405.     }
  406.   case WM_TIMER:
  407.     switch (SHORT1FROMMP(mp1))
  408.       {
  409.       case BUBBLE_DELAY_TIMER: /* Intervall timer */
  410.         {
  411.           HWND hwndBubbleClient;
  412.           ULONG style=FCF_BORDER;
  413.           int deltaY=0;
  414.           int deltaX=0;
  415.           char * winText;
  416.           char chrTBFlyFontName[100];
  417.           ULONG  attrFound;
  418.           ULONG  len;
  419.           RGB rgb;
  420.           SHORT dx;
  421.  
  422. #if 0
  423.           deltaY=WinQueryWindowULong(hwnd, QWL_DELTAPOS)& 0x0000FFFF;
  424. #endif
  425.  
  426.           WinStopTimer(WinQueryAnchorBlock(hwnd),hwnd,BUBBLE_DELAY_TIMER);  /* stop the running timer */
  427.           /*  we have to build a new information window  */
  428.           if(hwndBubbleWindow){
  429.             WinDestroyWindow(hwndBubbleWindow);/*  close the bubblewindow  */
  430.             hwndBubbleWindow=NULLHANDLE;
  431.           }
  432.           /* Query the pointer position */
  433.           WinQueryPointerPos(HWND_DESKTOP,&ptl);
  434.           
  435.           /* Create help window */
  436.           if((hwndBubbleWindow=WinCreateStdWindow(HWND_DESKTOP,
  437.                                               0,
  438.                                               &style,
  439.                                               WC_STATIC,
  440.                                               "The window",
  441.                                               SS_TEXT|DT_CENTER|DT_VCENTER,
  442.                                               NULLHANDLE,
  443.                                               400,
  444.                                               &hwndBubbleClient))==NULLHANDLE)
  445.             return (MRESULT) 0;
  446.  
  447.           /* Set the font for the help */
  448.           if(WinQueryPresParam(hwnd ,
  449.                                PP_FONTNAMESIZE,0,&attrFound,sizeof(chrTBFlyFontName),
  450.                                chrTBFlyFontName,QPF_NOINHERIT))
  451.             WinSetPresParam(hwndBubbleClient,PP_FONTNAMESIZE,
  452.                             sizeof(chrTBFlyFontName),
  453.                             chrTBFlyFontName);
  454.           /* Query the current background colour */
  455.           if(WinQueryPresParam(hwnd,
  456.                                 PP_BACKGROUNDCOLOR,0,&attrFound,sizeof(rgb),
  457.                                 &rgb, QPF_NOINHERIT))
  458.             WinSetPresParam(hwndBubbleClient,
  459.                             PP_BACKGROUNDCOLOR,(ULONG)sizeof(rgb), &rgb );
  460.             /* Query the current foreground colour */
  461.           if(WinQueryPresParam(hwnd,
  462.                                PP_FOREGROUNDCOLOR,0,&attrFound,sizeof(rgb),
  463.                                &rgb,QPF_NOINHERIT))
  464.             WinSetPresParam(hwndBubbleClient,
  465.                             PP_FOREGROUNDCOLOR,(ULONG)sizeof(rgb), &rgb);          
  466.           /* Set bubble text */
  467.           if((winText=(char*)WinQueryWindowPtr(hwnd,QWL_TEXTPTR))!=NULLHANDLE)
  468.             WinSetWindowText(hwndBubbleClient,winText);
  469.           else {
  470.             WinDestroyWindow(hwndBubbleWindow);/*  close the bubblewindow  */
  471.             hwndBubbleWindow=NULLHANDLE;
  472.           }
  473.  
  474.           /* Calculate text size in pixel */
  475.           hps=WinBeginPaint(hwndBubbleClient,(HPS)NULL,(PRECTL)NULL);
  476.           GpiQueryTextBox(hps,strlen(winText),winText,TXTBOX_COUNT,aptlPoints);
  477.           WinEndPaint(hps);
  478.  
  479.           /* Calculate bubble positon and show bubble */
  480.           WinQueryWindowRect(HWND_DESKTOP,&rcl);/* Query desktop size */
  481.  
  482.           deltaX=(aptlPoints[TXTBOX_BOTTOMRIGHT].x+7+xVal+ptl.x+deltaX 
  483.             > rcl.xRight
  484.                   ? -(aptlPoints[TXTBOX_BOTTOMRIGHT].x-(rcl.xRight-ptl.x)+7+7+xVal)
  485.                   /*                 ? -(aptlPoints[TXTBOX_BOTTOMRIGHT].x-(rcl.xRight-ptl.x)+7+7+xVal)*/
  486.  
  487.                   /*? -(rcl.xRight-(aptlPoints[TXTBOX_BOTTOMRIGHT].x-aptlPoints[TXTBOX_BOTTOMLEFT].x))*/
  488.                   /*     ? -(aptlPoints[TXTBOX_BOTTOMRIGHT].x-aptlPoints[TXTBOX_BOTTOMLEFT].x-xVal-xVal-7 )*/
  489.             : deltaX ) ;  
  490.  
  491.  
  492. #if 0
  493.           deltaX+=(aptlPoints[TXTBOX_BOTTOMRIGHT].x-aptlPoints[TXTBOX_BOTTOMLEFT].x+7+xVal+ptl.x+deltaX 
  494.             > rcl.xRight 
  495.             ? -((aptlPoints[TXTBOX_BOTTOMRIGHT].x-aptlPoints[TXTBOX_BOTTOMLEFT].x)-rcl.xRight+deltaX)
  496.                    /*            ? -(aptlPoints[TXTBOX_BOTTOMRIGHT].x-aptlPoints[TXTBOX_BOTTOMLEFT].x-xVal-xVal-7 )*/
  497.             : 0) ;  
  498. #endif     
  499.           deltaY=(aptlPoints[TXTBOX_TOPLEFT].y-aptlPoints[TXTBOX_BOTTOMLEFT].y+2+yVal+ptl.y 
  500.             > rcl.yTop 
  501.             ? deltaY-aptlPoints[TXTBOX_TOPLEFT].y-aptlPoints[TXTBOX_BOTTOMLEFT].y-2*yVal-7
  502.             : 0 );
  503.  
  504.           WinSetWindowPos(hwndBubbleWindow,
  505.                           HWND_DESKTOP,
  506.                           ptl.x+xVal+deltaX,ptl.y+yVal+deltaY,  
  507.                           aptlPoints[TXTBOX_BOTTOMRIGHT].x-aptlPoints[TXTBOX_BOTTOMLEFT].x+8,
  508.                           aptlPoints[TXTBOX_TOPLEFT].y-aptlPoints[TXTBOX_BOTTOMLEFT].y+2,
  509.                           SWP_SIZE|SWP_MOVE|SWP_SHOW);
  510.           WinStartTimer(WinQueryAnchorBlock(hwnd),hwnd,BUBBLE_SHOW_TIMER, 
  511.                         WinQueryWindowULong(hwnd,QWL_SHOWTIME)); /* New timer for delay */
  512.           WinStartTimer(WinQueryAnchorBlock(hwnd),hwnd,BUBBLE_CHECK_TIMER, (ULONG) 100); /* New timer for checking if mouse left */
  513.           return (MRESULT) 0;
  514.         }
  515.         break;
  516.       case BUBBLE_SHOW_TIMER: /* Show timer */
  517.         WinStopTimer(WinQueryAnchorBlock(hwnd),hwnd,BUBBLE_SHOW_TIMER);  /* stop the running timer */
  518.         WinStopTimer(WinQueryAnchorBlock(hwnd),hwnd,BUBBLE_CHECK_TIMER);  /* stop the running timer */
  519.         if(hwndBubbleWindow){
  520.           WinDestroyWindow(hwndBubbleWindow);/*  close the bubblewindow  */
  521.           hwndBubbleWindow=NULLHANDLE;
  522.         }
  523.         return (MRESULT) 0;
  524.       case BUBBLE_CHECK_TIMER: /* Check for mouse leaving the control */
  525.         if(WinQueryWindowULong(hwnd,QWL_SHOWBUBBLE)==0) {
  526.           if(hwndBubbleWindow){
  527.             WinDestroyWindow(hwndBubbleWindow);/*  close the bubblewindow  */
  528.             hwndBubbleWindow=NULLHANDLE;
  529.           }
  530.           WinStopTimer(WinQueryAnchorBlock(hwnd),hwnd,BUBBLE_SHOW_TIMER);  /* stop the running timer */
  531.           WinStopTimer(WinQueryAnchorBlock(hwnd),hwnd,BUBBLE_CHECK_TIMER);  /* stop the running timer */
  532.         }
  533.         return (MRESULT) 0;
  534.       default:
  535.         break;
  536.       }
  537.     break;
  538.   case WM_DESTROY:
  539.     {
  540.       char *ptrText;
  541.       /* Free the memory allocated for the text */
  542.       if((ptrText=(char*)WinQueryWindowPtr(hwnd,QWL_TEXTPTR))!=NULLHANDLE)
  543.         free(ptrText);
  544.       WinStopTimer(WinQueryAnchorBlock(hwnd),hwnd,BUBBLE_DELAY_TIMER);  /* stop the running timer */
  545.       WinStopTimer(WinQueryAnchorBlock(hwnd),hwnd,BUBBLE_SHOW_TIMER);  /* stop the running timer */
  546.       break;
  547.     }
  548.   case WM_PAINT:
  549.     {
  550.       hps=WinBeginPaint(hwnd, NULLHANDLE, NULLHANDLE);
  551. #if 0
  552.       WinQueryWindowRect(hwnd, &rcl);
  553.       WinFillRect(hps,&rcl, CLR_RED);
  554. #endif
  555.       WinEndPaint(hps);
  556.     return (MRESULT) FALSE;
  557.     }
  558.   
  559.   default:
  560.     break;
  561.   }
  562.  
  563.   return WinDefWindowProc(hwnd, msg, mp1, mp2);
  564.  
  565. }
  566.  
  567. ULONG DRCtrlVersion(CHAR *name, ULONG numargs, RXSTRING args[],
  568.                      CHAR *queuename, RXSTRING *retstr)
  569. {
  570.   retstr->strlength = 0;               /* set return value           */
  571.   /* check arguments            */
  572.   if (numargs > 0)
  573.     return INVALID_ROUTINE;
  574.   
  575.  
  576.   sprintf(retstr->strptr, "%s", DRDCTRL_VERSION);
  577.   retstr->strlength = strlen(retstr->strptr);
  578.   return VALID_ROUTINE;
  579. }
  580.  
  581. /*************************************************************************
  582. * Function:  DRCtrlDropFuncs                                             *
  583. *                                                                        *
  584. * Syntax:    call DRCtrlDropFuncs                                        *
  585. *                                                                        *
  586. * Params:    none                                                        *
  587. *                                                                        *
  588. * Return:    null string                                                 *
  589. *************************************************************************/
  590.  
  591. ULONG DRCtrlDropFuncs(CHAR *name, ULONG numargs, RXSTRING args[],
  592.                           CHAR *queuename, RXSTRING *retstr)
  593. {
  594.   INT     entries;                     /* Num of entries             */
  595.   INT     j;                           /* Counter                    */
  596.  
  597.   if (numargs != 0)                    /* no arguments for this      */
  598.     return INVALID_ROUTINE;            /* raise an error             */
  599.  
  600.   retstr->strlength = 0;               /* return a null string result*/
  601.  
  602.   entries = sizeof(RxFncTable)/sizeof(PSZ);
  603.  
  604.   for (j = 0; j < entries; j++)
  605.     RexxDeregisterFunction(RxFncTable[j]);
  606.  
  607.   return VALID_ROUTINE;                /* no error on call           */
  608. }
  609.  
  610.  
  611. /*************************************************************************
  612. *                                                                        *
  613. * Register the percent bar control with the calling PM process           *
  614. *                                                                        *
  615. *************************************************************************/
  616.  
  617. ULONG DRCtrlRegister(CHAR *name, ULONG numargs, RXSTRING args[],
  618.                      CHAR *queuename, RXSTRING *retstr)
  619. {
  620.  
  621.   WinRegisterClass(WinQueryAnchorBlock(HWND_DESKTOP),"DRD_PERCENTBAR",_percentBarProc,0L,12);
  622.   WinRegisterClass(WinQueryAnchorBlock(HWND_DESKTOP),"DRD_BUBBLEHELP",_bubbleHelpProc,0L, BUBBLEHELP_ULONGS);
  623.  
  624.   return VALID_ROUTINE;                /* no error on call           */
  625. }
  626.  
  627.  
  628. /*************************************************************************
  629. * Function:  DRCtrlLoadFuncs                                             *
  630. *                                                                        *
  631. * Syntax:    call DRCtrlLoadFuncs                                        *
  632. *                                                                        *
  633. * Params:    none                                                        *
  634. *                                                                        *
  635. * Return:    null string                                                 *
  636. *************************************************************************/
  637.  
  638. ULONG DRCtrlLoadFuncs(CHAR *name, ULONG numargs, RXSTRING args[],
  639.                            CHAR *queuename, RXSTRING *retstr)
  640. {
  641.   INT    entries;                      /* Num of entries             */
  642.   INT    j;                            /* Counter                    */
  643.  
  644.   retstr->strlength = 0;               /* set return value           */
  645.                                        /* check arguments            */
  646.  
  647.   if (numargs > 0)
  648.     return INVALID_ROUTINE;
  649.  
  650.   entries = sizeof(RxFncTable)/sizeof(PSZ);
  651.  
  652.   for (j = 0; j < entries; j++) {
  653.     RexxRegisterFunctionDll(RxFncTable[j],
  654.           "DRUSRCTL", RxFncTable[j]);
  655.   }
  656.  
  657.   return VALID_ROUTINE;
  658. }
  659.  
  660.  
  661.