home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: Product / Product.zip / sbcspsht.zip / SBCSPSHT.C
C/C++ Source or Header  |  1997-03-27  |  13KB  |  327 lines

  1. /******************************************************************************/
  2. /*                                                                            */
  3. /* Description: Extends the VisPro Spreadsheet Object to make it more usable  */
  4. /*              SubClass the SpreadSheet Class to enhance functionality       */
  5. /*              OPTIMIZE the Spreadsheet so that the cols width is big enough */
  6. /*              for every entry in this col.                                  */
  7. /*              EDIT STYLE enhace the posibilities of the edit mode           */
  8. /*              e.g. start edit by simply typing in the field                 */
  9. /*                                                                            */
  10. /* File Name : SBCSPSHT.C                                                     */
  11. /*                                                                            */
  12. /* Author : THOMAS KORFHAGE                                                   */
  13. /*                                                                            */
  14. /* Copyright 1997 (c) Thomas Korfhage, 100271.16@compuserve.com               */
  15. /*                                                                            */
  16. /* Generated using VisPro/C serial number VPC5016481                          */
  17. /*                                                                            */
  18. /* ---------------------------- ADVICE -------------------------------------- */
  19. /*                                                                            
  20. Put this file into the subprocs folder of your project.
  21.  
  22. ## At Code sections - Extra include files - add this lines:
  23. BOOL SubClassSprShtClass ( VOID );
  24. #define SPRM_OPTIMZE WM_USER+26
  25. #define SPRM_SET_EDTSTYLE WM_USER+27
  26. #define OPTIMZE_ALLCOLS       -1
  27. #define OPTIMZE_COLS          1
  28. #define OPTIMZE_HEADER        2
  29. #define SPRS_ENTER_EDITS   0x00000100L   /* Enter Key starts editing */
  30. #define SPRS_CHAR_EDITS    0x00000200L   /* Any Char-Key starts editing */
  31. #define SPRS_EDITFULLSEL   0x00000400L   /* editing starts with full selection of entire text thats an overwrite mode */
  32. #define SPRS_EDITFIXLEN    0x00000800L   /* the edited text can not be longer than the text set in the entry field. */
  33.  
  34. ## At Code section - Application initialization - add this call:
  35. SubClassSprShtClass ();
  36.  
  37. ## At Form Event When Opened set the desired Edit Stile with this call:
  38. WinSendDlgItemMsg (hwndDlg, ID_SPREADSHEET, SPRM_SET_EDTSTYLE, MPFROMSHORT (SPRS_ENTER_EDITS), 0);
  39.  
  40. ## To Optimize the whole SpeadSheet Display use this call:
  41. WinSendDlgItemMsg (hwndDlg, ID_SPREADSHEET, SPRM_OPTIMZE, MPFROM2SHORT (OPTIMZE_ALLCOLS, OPTIMZE_COLS|OPTIMZE_HEADER), MPFROM2SHORT (ExtraSpaceX, ExtraSpaceY);
  42. ## To Optimize one column of the SpeadSheet use this call:
  43. WinSendDlgItemMsg (hwndDlg, ID_SPREADSHEET, SPRM_OPTIMZE, MPFROM2SHORT (column, OPTIMZE_COLS), MPFROM2SHORT (ExtraSpaceX, ExtraSpaceY);
  44. */
  45. /*                                                                            */
  46. /******************************************************************************/
  47.  
  48. /*INCLUDES*/
  49.  
  50. #define INCL_WIN
  51. #define INCL_NLS
  52. #define INCL_DOS
  53. #define INCL_GPI
  54. #include <os2.h>
  55. #include <string.h>
  56. #include <stdlib.h>
  57. #include <stdio.h>
  58. #include <VCSPRSHT.H>
  59.  
  60. /*TYPEDEFS*/
  61. /*MACROS*/
  62. /*DEFINES*/
  63.  
  64. #define SPRM_OPTIMZE WM_USER+26
  65. #define SPRM_SET_EDTSTYLE WM_USER+27
  66. #define OPTIMZE_ALLCOLS       -1
  67. #define OPTIMZE_COLS          1
  68. #define OPTIMZE_HEADER        2
  69. #define SPRS_ENTER_EDITS   0x00000100L
  70. #define SPRS_CHAR_EDITS    0x00000200L
  71. #define SPRS_EDITFULLSEL   0x00000400L
  72. #define SPRS_EDITFIXLEN    0x00000800L
  73. #define SPRS_ALLEDITSTYLES 0x00000F00L
  74.  
  75. /*FTY*/
  76. HWND FindHwndClassNr (HWND hwnd, int ClassNr);
  77. HWND FindHwndSprShtEF (HWND hwndSpreadSheet);
  78. USHORT GetScrollBarWidth (HWND hwnd);
  79. VOID OptimizeSprShtDisplay (HWND hwnd, SHORT Col, SHORT flOpti, SHORT SpaceX, SHORT SpaceY);
  80. BOOL IsSprShtEFVisible  (HWND hwndSpreadSheet);
  81. BOOL SubClassSpreadSheetEF (HWND hwndSpreadSheet);
  82. MRESULT EXPENTRY NewSprShtEFWindowProc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  83. MRESULT EXPENTRY fnwpVPSPRSHT (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  84. BOOL SubClassSprShtClass ( VOID );
  85.  
  86. /*externe FTY*/
  87.  
  88. /*externe DATA*/
  89.  
  90. /*DATA*/
  91. static PFNWP  fnwpDefVPSPRSHT = NULL;
  92. static PFNWP pOldSprShtEFWindowProc = NULL; 
  93. static ULONG VPSPRSHTExtraOffset;
  94.  
  95. /*CODE*/
  96. BOOL SubClassSprShtClass ( VOID )
  97. {
  98.    HAB hab;
  99.    CLASSINFO    ClassInfo;                                 /*  Class information structure. */
  100.  
  101.    hab = WinInitialize(0);
  102.  
  103.    WinQueryClassInfo (hab, WC_SPRSHT, &ClassInfo);
  104.    fnwpDefVPSPRSHT = ClassInfo.pfnWindowProc;
  105.    VPSPRSHTExtraOffset = ClassInfo.cbWindowData;
  106.    return WinRegisterClass (hab,                           /* Anchor block handle      */
  107.                             WC_SPRSHT,                     /* Window class name (Upper)*/
  108.                             fnwpVPSPRSHT,                  /* Address window procedure */
  109.                             ClassInfo.flClassStyle ,       /* Class style        */
  110.                             ClassInfo.cbWindowData + sizeof (USHORT)   /* Extra window words       */
  111.                            );
  112. }
  113.  
  114. MRESULT EXPENTRY fnwpVPSPRSHT (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  115. {
  116.    MRESULT mres;
  117.  
  118.    if (msg == WM_CREATE) {
  119.       PCREATESTRUCT pCrst;
  120.  
  121.       pCrst = (PCREATESTRUCT) PVOIDFROMMP (mp2);
  122.       WinSetWindowUShort (hwnd, VPSPRSHTExtraOffset, (USHORT)pCrst->flStyle&SPRS_ALLEDITSTYLES);
  123.       mres = fnwpDefVPSPRSHT (hwnd, msg, mp1, mp2);
  124.       SubClassSpreadSheetEF (hwnd);
  125.       return mres;
  126.    } else if (msg == WM_CHAR) {
  127.       USHORT EStyle = WinQueryWindowUShort (hwnd, VPSPRSHTExtraOffset);
  128.       USHORT EFAktiv = IsSprShtEFVisible (hwnd);
  129.  
  130.       if ((CHARMSG (&msg)->fs & (KC_KEYUP | KC_CHAR | KC_VIRTUALKEY)) == KC_CHAR && !(CHARMSG (&msg)->vkey == VK_NEWLINE || CHARMSG (&msg)->vkey == VK_ENTER)) {
  131.          if (!EFAktiv) {
  132.             if ((EStyle & SPRS_CHAR_EDITS) != 0) {
  133.                MPARAM SavMp1 = mp1, SavMp2 = mp2;
  134.                HWND hwndEF = FindHwndSprShtEF (hwnd);
  135.  
  136.                CHARMSG (&msg)->fs = KC_TOGGLE |KC_LONEKEY|KC_SCANCODE|KC_VIRTUALKEY|KC_KEYUP|KC_ALT;
  137.                CHARMSG (&msg)->vkey = VK_NEWLINE;
  138.                CHARMSG (&msg)->scancode = 0x1c;
  139.                CHARMSG (&msg)->chr = 0x1c00;
  140.                mres = fnwpDefVPSPRSHT (hwnd, msg, mp1, mp2);
  141.                if (hwndEF)
  142.                   WinSendMsg (hwndEF, msg, SavMp1, SavMp2);
  143.                return mres;
  144.             } else
  145.                return FALSE;
  146.          }
  147.       }
  148.       if (!(CHARMSG (&msg)->fs & KC_KEYUP) && (CHARMSG (&msg)->vkey == VK_NEWLINE || CHARMSG (&msg)->vkey == VK_ENTER)) {
  149.          if (!EFAktiv) {
  150.             if ((EStyle & SPRS_ENTER_EDITS) != 0) {
  151.                CHARMSG (&msg)->fs = KC_TOGGLE |KC_LONEKEY|KC_SCANCODE|KC_VIRTUALKEY|KC_KEYUP|KC_ALT;
  152.                CHARMSG (&msg)->vkey = VK_NEWLINE;
  153.                CHARMSG (&msg)->scancode = 0x1c;
  154.                CHARMSG (&msg)->chr = 0x1c00;
  155.             } else
  156.                return FALSE;
  157.          }
  158.       }
  159.    } else if (msg == SPRM_SET_EDTSTYLE) {
  160.       USHORT EStyle = WinQueryWindowUShort (hwnd, VPSPRSHTExtraOffset);
  161.       EStyle &= ~SPRS_ALLEDITSTYLES;
  162.       WinSetWindowUShort (hwnd, VPSPRSHTExtraOffset, (USHORT)(SHORT1FROMMP (mp1)&SPRS_ALLEDITSTYLES)|EStyle);
  163.    } else if (msg == SPRM_OPTIMZE) {                       /* Optimize SpreadSheet Display */
  164.       OptimizeSprShtDisplay (hwnd, SHORT1FROMMP (mp1), SHORT2FROMMP (mp1), SHORT1FROMMP (mp2), SHORT2FROMMP (mp2));
  165.       return (MRESULT )TRUE;
  166.    }
  167.    return fnwpDefVPSPRSHT (hwnd, msg, mp1, mp2);
  168. }
  169.  
  170. MRESULT EXPENTRY NewSprShtEFWindowProc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  171. {
  172.    switch (msg) {
  173.       /* Check if Set Text  */
  174.       case WM_SETWINDOWPARAMS:
  175.          {
  176.             PWNDPARAMS pwprm = (PWNDPARAMS) PVOIDFROMMP (mp1);   /* pointer to WNDPARAMS */
  177.             if (pwprm->fsStatus & (WPM_TEXT | WPM_CCHTEXT)) {
  178.                HWND hwndParent = WinQueryWindow( hwnd, QW_PARENT );
  179.                /* get Extended Style of Spreadsheet */
  180.                USHORT EStyle =  WinQueryWindowUShort (hwndParent, VPSPRSHTExtraOffset);
  181.                long len = strlen (pwprm->pszText);
  182.                if (len)
  183.                   (*pOldSprShtEFWindowProc) (hwnd, EM_SETTEXTLIMIT, MPFROMLONG( (EStyle & SPRS_EDITFIXLEN) == 0 ? 200 : len), 0);
  184.                if ((EStyle & SPRS_EDITFULLSEL) != 0) {
  185.                   MRESULT mres;
  186.                   mres =  (*pOldSprShtEFWindowProc) (hwnd, msg, mp1, mp2);
  187.                   (*pOldSprShtEFWindowProc) (hwnd, EM_SETSEL, MPFROM2SHORT (0, 255), 0);
  188.                   return mres;
  189.                }
  190.             }
  191.          }
  192.          break;
  193.    }
  194.    return (*pOldSprShtEFWindowProc) (hwnd, msg, mp1, mp2);
  195. }
  196.  
  197. BOOL SubClassSpreadSheetEF (HWND hwndSpreadSheet)
  198. {
  199.    HWND hwndEF;
  200.  
  201.    hwndEF = FindHwndSprShtEF (hwndSpreadSheet);
  202.    if (hwndEF != (HWND)0) {
  203.       /* Spreadsheet Entryfield gefunden */
  204.       pOldSprShtEFWindowProc = WinSubclassWindow (hwndEF, NewSprShtEFWindowProc);
  205.       return pOldSprShtEFWindowProc != 0;
  206.    }
  207.    return FALSE;
  208. }
  209.  
  210. BOOL IsSprShtEFVisible  (HWND hwndSpreadSheet)
  211. {
  212.    HWND hwndEF;
  213.  
  214.    hwndEF = FindHwndSprShtEF (hwndSpreadSheet);
  215.    if (hwndEF != (HWND)0)
  216.       return WinIsWindowVisible (hwndEF);
  217.    return FALSE;
  218. }
  219.  
  220. VOID OptimizeSprShtDisplay (HWND hwnd, SHORT Col, SHORT flOpti, SHORT SpaceX, SHORT SpaceY)
  221. {
  222.    HPS hps = WinGetPS (hwnd);
  223.    RECTL rctl;
  224.    PSPRSHTCDATA pCtl;
  225.    int i, nrrows, nrcols;
  226.  
  227.    if (hps == (HPS)0)
  228.       return;
  229.  
  230.    pCtl = (PSPRSHTCDATA )((PBYTE)WinQueryWindowPtr (hwnd, 4) + 0x7C);
  231.    if (pCtl == NULL || pCtl->cb != sizeof (SPRSHTCDATA)) {
  232.       pCtl = NULL;
  233.       nrrows = 100;
  234.       nrcols = 100;
  235.    } else {
  236.       nrrows = pCtl->numCells.cy + 1;
  237.       nrcols = pCtl->numCells.cx + 1;
  238.    }
  239.    memset (&rctl, 0, sizeof (rctl));
  240.    if (flOpti & OPTIMZE_HEADER) {
  241.       rctl.yTop = rctl.xRight = 10000;
  242.       WinDrawText (hps, -1, "ATIqg~?_", &rctl, 0, 0 , DT_LEFT|DT_VCENTER|DT_QUERYEXTENT|DT_TEXTATTRS);
  243.       WinSendMsg (hwnd, SSM_SETDEFHEADERHEIGHT, MPFROMLONG (i = rctl.yTop - rctl.yBottom + SpaceY), 0);
  244.    }
  245.    if (flOpti & OPTIMZE_COLS) {
  246.       int col, maxcol, width;
  247.  
  248.       col = maxcol = Col;
  249.       if (Col == OPTIMZE_ALLCOLS) {
  250.          col = 0;
  251.          maxcol = nrcols-1;
  252.       }
  253.       while (col <= maxcol) {
  254.          int row;
  255.          PSZ pCell;
  256.          int iwidth;
  257.  
  258.          width = 0;
  259.          for (row = 0; row < nrrows; ++row) {
  260.             pCell = WinSendMsg (hwnd, SSM_GETCELL, MPFROM2SHORT (col, row), 0);
  261.             if (pCell == NULL || (row == 0 && atoi (pCell) == col && *pCell != '@'))   // Zelle nicht vorhanden
  262.                break;
  263.             if (*pCell) {
  264.                rctl.yTop = rctl.xRight = 10000;
  265.                WinDrawText (hps, -1, pCell, &rctl, 0, 0 , DT_LEFT|DT_VCENTER|DT_QUERYEXTENT|DT_TEXTATTRS);
  266.                iwidth = rctl.xRight - rctl.xLeft;
  267.                if (iwidth > width)
  268.                   width = iwidth;
  269.             }
  270.          }
  271.          if (row == 0)                                     /* Spalte nicht vorhanden */
  272.             break;
  273.          if (width > 0) {
  274.             if (col == 0)
  275.                WinSendMsg (hwnd, SSM_SETDEFROWLABELWIDTH, MPFROMLONG (width + SpaceX), 0);
  276.             else
  277.                WinSendMsg (hwnd, SSM_SETCOLWIDTH, MPFROMLONG (col), MPFROMLONG (width += SpaceX));
  278.          }
  279.          ++col;
  280.       }
  281.       if (Col == OPTIMZE_ALLCOLS) {
  282.          WinSendMsg (hwnd, SSM_SETDEFCELLWIDTH, MPFROMLONG (width), 0);
  283.       }
  284.    }
  285.    WinReleasePS (hps);
  286. }
  287.  
  288. USHORT GetScrollBarWidth (HWND hwnd)
  289. {
  290.    HWND hwndSB = FindHwndClassNr (hwnd, 8);
  291.  
  292.    if (hwndSB) {
  293.       SWP swp;
  294.  
  295.       WinQueryWindowPos( hwndSB, (PSWP)&swp );
  296.       return (USHORT)min (swp.cx, swp.cy);
  297.    }
  298.    return 0;
  299. }
  300.  
  301. HWND FindHwndSprShtEF (HWND hwndSpreadSheet)
  302. {
  303.    return FindHwndClassNr (hwndSpreadSheet, 6);
  304. }
  305.  
  306. HWND FindHwndClassNr (HWND hwnd, int ClassNr)
  307. {
  308.    HWND hwndNext;                                          /* Handle of the window to test */
  309.    HENUM Henum;                                            /* Enumeration handle */
  310.    SHORT sRetLen;                                          /* returned string length               */
  311.    char szClassName[32];
  312.  
  313.    Henum = WinBeginEnumWindows (hwnd);
  314.    while ((hwndNext = WinGetNextWindow (Henum)) != NULLHANDLE) {
  315.       sRetLen = WinQueryClassName (hwndNext, sizeof (szClassName), szClassName);
  316.       if (sRetLen >= 2 && szClassName[0] == '#' && atoi (&szClassName[1]) == ClassNr) {
  317.          /* 1.Window of standart class with correct nr found */
  318.          WinEndEnumWindows (Henum);
  319.          return hwndNext;
  320.       }
  321.    }
  322.    WinEndEnumWindows (Henum);
  323.    return (HWND)0;
  324. }
  325.  
  326.  
  327.