home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / CNREZ.ZIP / CNREZ.C next >
Text File  |  1992-10-11  |  26KB  |  645 lines

  1. /*********************************************************************
  2.  *                                                                   *
  3.  * MODULE NAME :  cnrez.c                AUTHOR:  Rick Fishman       *
  4.  * DATE WRITTEN:  10-06-92                                           *
  5.  *                                                                   *
  6.  * HOW TO RUN THIS PROGRAM:                                          *
  7.  *                                                                   *
  8.  *  Just enter CNREZ on the command line.                            *
  9.  *                                                                   *
  10.  * MODULE DESCRIPTION:                                               *
  11.  *                                                                   *
  12.  *  Only module for CNREZ.EXE, a program that demonstrates the base  *
  13.  *  functionality of a container control. This module creates a      *
  14.  *  standard window with a container in it. It then inserts records  *
  15.  *  into the container and allows the user to switch between views.  *
  16.  *                                                                   *
  17.  *  Drag/Drop, Deltas, Context Menus, Ownerdraw, MiniIcons,          *
  18.  *  record-sharing, sorting are not demonstrated in this sample      *
  19.  *  program.                                                         *
  20.  *                                                                   *
  21.  * NOTES:                                                            *
  22.  *                                                                   *
  23.  *  This program is strictly a sample and should be treated as such. *
  24.  *  There is minimal error-checking and global variables are used.   *
  25.  *  I *hate* doing that but the clarity of a sample program suffers  *
  26.  *  when error-checking code is put in and window words are used to  *
  27.  *  eliminate globals.                                               *
  28.  *                                                                   *
  29.  *  I hope this code proves useful for other PM programmers. The     *
  30.  *  more of us the better!                                           *
  31.  *                                                                   *
  32.  * HISTORY:                                                          *
  33.  *                                                                   *
  34.  *  10-06-92 - Program coded                                         *
  35.  *                                                                   *
  36.  *  Rick Fishman                                                     *
  37.  *  Code Blazers, Inc.                                               *
  38.  *  4113 Apricot                                                     *
  39.  *  Irvine, CA. 92720                                                *
  40.  *  CIS ID: 72251,750                                                *
  41.  *                                                                   *
  42.  *********************************************************************/
  43.  
  44. /*********************************************************************/
  45. /*------- Include relevant sections of the OS/2 header files --------*/
  46. /*********************************************************************/
  47.  
  48. #define  INCL_WINFRAMEMGR
  49. #define  INCL_WINMLE
  50. #define  INCL_WINPOINTERS
  51. #define  INCL_WINSTDCNR
  52. #define  INCL_WINSTDDLGS
  53. #define  INCL_WINWINDOWMGR
  54.  
  55. /**********************************************************************/
  56. /*----------------------------- INCLUDES -----------------------------*/
  57. /**********************************************************************/
  58.  
  59. #include <os2.h>
  60. #include <stdio.h>
  61. #include <stdlib.h>
  62. #include <string.h>
  63. #include "cnrez.h"
  64.  
  65. /*********************************************************************/
  66. /*------------------- APPLICATION DEFINITIONS -----------------------*/
  67. /*********************************************************************/
  68.  
  69. #define FRAME_FLAGS         (FCF_TASKLIST | FCF_TITLEBAR   | FCF_SYSMENU | \
  70.                              FCF_MINMAX   | FCF_SIZEBORDER | FCF_MENU    | \
  71.                              FCF_SHELLPOSITION)
  72.  
  73. #define PROGRAM_TITLE       "CNREZ Container Sample"
  74.  
  75. #define CONTAINER_COLUMNS   5
  76.  
  77. #define SPLITBAR_OFFSET     150
  78.  
  79. #define MAX_DATA_LENGTH     25
  80.  
  81. /**********************************************************************/
  82. /*---------------------------- STRUCTURES ----------------------------*/
  83. /**********************************************************************/
  84.  
  85. typedef struct _CNRITEM
  86. {
  87.   MINIRECORDCORE    rc;
  88.   HPOINTER          hptrIcon;
  89.   CDATE             date;
  90.   CTIME             time;
  91.   ULONG             ulData;
  92.   PSZ               szData;
  93.  
  94. } CNRITEM, *PCNRITEM;
  95.  
  96. /**********************************************************************/
  97. /*----------------------- FUNCTION PROTOTYPES ------------------------*/
  98. /**********************************************************************/
  99.  
  100.        INT   main               ( VOID );
  101. static VOID  CustomizeWindow    ( VOID );
  102. static VOID  SetContainerColumns( VOID );
  103. static VOID  InsertRecord       ( VOID );
  104. static VOID  FillInRecord       ( PCNRITEM pci, INT iRecNum );
  105. static VOID  SetContainerView   ( ULONG ulViewType );
  106. static VOID  CnrBeginEdit       ( PCNREDITDATA pced );
  107. static VOID  CnrEndEdit         ( PCNREDITDATA pced );
  108.  
  109. FNWP wpClient;
  110.  
  111. /**********************************************************************/
  112. /*------------------------ GLOBAL VARIABLES --------------------------*/
  113. /**********************************************************************/
  114.  
  115. CHAR szRecName[]  = "Container Item";
  116.  
  117. CHAR szChildRecName[]  = "Container Child Item";
  118.  
  119. CHAR szItemData[] = "Item Data";
  120.  
  121. CHAR szCnrTitle[] = "This is a Container";
  122.  
  123. CHAR szClass[] = "TestClass";
  124.  
  125. HAB  hab;
  126.  
  127. HWND hwndFrame, hwndClient, hwndCnr;
  128.  
  129. HPOINTER hptr;
  130.  
  131. /**********************************************************************/
  132. /*------------------------------ MAIN --------------------------------*/
  133. /*                                                                    */
  134. /*  PROGRAM ENTRYPOINT                                                */
  135. /*                                                                    */
  136. /*  INPUT: nothing                                                    */
  137. /*                                                                    */
  138. /*  1.                                                                */
  139. /*                                                                    */
  140. /*  OUTPUT: return code                                               */
  141. /*                                                                    */
  142. /*--------------------------------------------------------------------*/
  143. /**********************************************************************/
  144. INT main( VOID )
  145. {
  146.     HMQ   hmq;
  147.     QMSG  qmsg;
  148.     ULONG flFrame = FRAME_FLAGS;
  149.  
  150.     hab = WinInitialize( 0 );
  151.  
  152.     hmq = WinCreateMsgQueue( hab, 0 );
  153.  
  154.     WinRegisterClass( hab, szClass, wpClient, CS_SIZEREDRAW, 0 );
  155.  
  156.     hwndFrame = WinCreateStdWindow( HWND_DESKTOP, 0, &flFrame, szClass, NULL,
  157.                                     0, NULLHANDLE, ID_RESOURCES, &hwndClient );
  158.  
  159.     CustomizeWindow();
  160.  
  161.     while( WinGetMsg( hab, &qmsg, (HWND) NULL, 0, 0 ) )
  162.         WinDispatchMsg( hab, &qmsg );
  163.  
  164.     WinDestroyWindow( hwndFrame );
  165.  
  166.     WinDestroyMsgQueue( hmq );
  167.  
  168.     WinTerminate( hab );
  169.  
  170.     return 0;
  171. }
  172.  
  173. /**********************************************************************/
  174. /*------------------------- CustomizeWindow --------------------------*/
  175. /*                                                                    */
  176. /*  CREATE THE CONTAINER AND SET IT INTO FRAME/CLIENT.                */
  177. /*                                                                    */
  178. /*  INPUT: nothing                                                    */
  179. /*                                                                    */
  180. /*  1.                                                                */
  181. /*                                                                    */
  182. /*  OUTPUT: nothing                                                   */
  183. /*                                                                    */
  184. /*--------------------------------------------------------------------*/
  185. /**********************************************************************/
  186. static VOID CustomizeWindow()
  187. {
  188.     INT i;
  189.  
  190.     hwndCnr = WinCreateWindow( hwndClient, WC_CONTAINER, NULL,
  191.                                CCS_MINIRECORDCORE | WS_VISIBLE,
  192.                                0, 0, 0, 0, hwndClient, HWND_BOTTOM,
  193.                                CNR_SAMPLE, NULL, NULL );
  194.  
  195.     // Set up the Details view columns before we start
  196.  
  197.     SetContainerColumns();
  198.  
  199.     WinSetWindowPos( hwndFrame, HWND_TOP, 10, 10, 400, 400,
  200.                      SWP_SIZE | SWP_MOVE | SWP_ZORDER | SWP_ACTIVATE );
  201.  
  202.     // Get the icon handle that will be used for all container records
  203.  
  204.     hptr = WinLoadPointer( HWND_DESKTOP, 0, ICO_DOIT );
  205.  
  206.     // Insert all records into the container
  207.  
  208.     for( i = 0; i < 10; i++ )
  209.         InsertRecord();
  210.  
  211.     // Set the initial view of the container
  212.  
  213.     SetContainerView( CV_ICON );
  214.  
  215.     // Cause all container records to be painted
  216.  
  217.     WinSendMsg( hwndCnr, CM_INVALIDATERECORD, NULL, NULL );
  218.  
  219.     WinSetWindowText( hwndFrame, PROGRAM_TITLE );
  220.  
  221.     WinShowWindow( hwndFrame, TRUE );
  222. }
  223.  
  224. /**********************************************************************/
  225. /*----------------------- SetContainerColumns ------------------------*/
  226. /*                                                                    */
  227. /*  SET THE COLUMNS OF THE CONTAINER FOR DETAIL VIEW                  */
  228. /*                                                                    */
  229. /*  INPUT: nothing                                                    */
  230. /*                                                                    */
  231. /*  1.                                                                */
  232. /*                                                                    */
  233. /*  OUTPUT: nothing                                                   */
  234. /*                                                                    */
  235. /*--------------------------------------------------------------------*/
  236. /**********************************************************************/
  237. static VOID SetContainerColumns()
  238. {
  239.     CNRINFO         cnri;
  240.     PFIELDINFO      pfi, pfiFirst, pfiLastLeftCol;
  241.     FIELDINFOINSERT fii;
  242.  
  243.     // Allocate memory for the container column data
  244.  
  245.     pfi = WinSendMsg( hwndCnr, CM_ALLOCDETAILFIELDINFO,
  246.                       MPFROMLONG( CONTAINER_COLUMNS ), NULL );
  247.  
  248.     // Save the pointer to all column info. It will be needed for the
  249.     // CM_INSERTDETAILFIELDINFO msg
  250.  
  251.     pfiFirst = pfi;
  252.  
  253.     // Set up information about each container column
  254.  
  255.     pfi->flData     = CFA_BITMAPORICON | CFA_HORZSEPARATOR | CFA_CENTER |
  256.                       CFA_SEPARATOR;
  257.     pfi->flTitle    = CFA_CENTER;
  258.     pfi->pTitleData = "Icon";
  259.     pfi->offStruct  = FIELDOFFSET( CNRITEM, hptrIcon );
  260.  
  261.     pfi             = pfi->pNextFieldInfo;
  262.     pfi->flData     = CFA_STRING | CFA_CENTER | CFA_HORZSEPARATOR;
  263.     pfi->flTitle    = CFA_CENTER;
  264.     pfi->pTitleData = "Data";
  265.     pfi->offStruct  = FIELDOFFSET( CNRITEM, szData );
  266.  
  267.     // pfiLastLeftCol is the last left column before the splitbar
  268.  
  269.     pfiLastLeftCol = pfi;
  270.  
  271.     pfi             = pfi->pNextFieldInfo;
  272.     pfi->flData     = CFA_DATE | CFA_CENTER | CFA_HORZSEPARATOR | CFA_SEPARATOR;
  273.     pfi->flTitle    = CFA_CENTER;
  274.     pfi->pTitleData =  "Date";
  275.     pfi->offStruct  = FIELDOFFSET( CNRITEM, date );
  276.  
  277.     pfi             = pfi->pNextFieldInfo;
  278.     pfi->flData    = CFA_ULONG | CFA_CENTER | CFA_HORZSEPARATOR | CFA_SEPARATOR;
  279.     pfi->flTitle    = CFA_CENTER;
  280.     pfi->pTitleData = "Ulong";
  281.     pfi->offStruct  = FIELDOFFSET( CNRITEM, ulData );
  282.  
  283.     pfi             = pfi->pNextFieldInfo;
  284.     pfi->flData     = CFA_TIME | CFA_CENTER | CFA_HORZSEPARATOR;
  285.     pfi->flTitle    = CFA_CENTER;
  286.     pfi->pTitleData = "Time";
  287.     pfi->offStruct  = FIELDOFFSET( CNRITEM, time );
  288.  
  289.     // Fill in information about the column data we are about to give the
  290.     // container.
  291.  
  292.     (void) memset( &fii, 0, sizeof( FIELDINFOINSERT ) );
  293.  
  294.     fii.cb                   = sizeof( FIELDINFOINSERT );
  295.     fii.pFieldInfoOrder      = (PFIELDINFO) CMA_FIRST;
  296.     fii.cFieldInfoInsert     = (SHORT) CONTAINER_COLUMNS;
  297.     fii.fInvalidateFieldInfo = TRUE;
  298.  
  299.     // Give the container the column information
  300.  
  301.     WinSendMsg( hwndCnr, CM_INSERTDETAILFIELDINFO, MPFROMP( pfiFirst ),
  302.                 MPFROMP( &fii ) );
  303.  
  304.     // Tell the container about the splitbar
  305.  
  306.     cnri.cb             = sizeof( CNRINFO );
  307.     cnri.pFieldInfoLast = pfiLastLeftCol;
  308.     cnri.xVertSplitbar  = SPLITBAR_OFFSET;
  309.  
  310.     WinSendMsg( hwndCnr, CM_SETCNRINFO, MPFROMP( &cnri ),
  311.                 MPFROMLONG( CMA_PFIELDINFOLAST | CMA_XVERTSPLITBAR ) );
  312. }
  313.  
  314. /**********************************************************************/
  315. /*---------------------------- wpClient ------------------------------*/
  316. /*                                                                    */
  317. /*  CLIENT WINDOW PROCEDURE.                                          */
  318. /*                                                                    */
  319. /*  INPUT: nothing                                                    */
  320. /*                                                                    */
  321. /*  1.                                                                */
  322. /*                                                                    */
  323. /*  OUTPUT: nothing                                                   */
  324. /*                                                                    */
  325. /*--------------------------------------------------------------------*/
  326. /**********************************************************************/
  327. MRESULT EXPENTRY wpClient( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
  328. {
  329.     switch( msg )
  330.     {
  331.         case WM_ERASEBACKGROUND:
  332.  
  333.             return (MRESULT) TRUE;
  334.  
  335.  
  336.         case WM_SIZE:
  337.  
  338.             WinSetWindowPos( hwndCnr, (HWND) NULL, 0, 0,
  339.                              SHORT1FROMMP( mp2 ), SHORT2FROMMP( mp2 ),
  340.                              SWP_SIZE | SWP_MOVE );
  341.  
  342.             return 0;
  343.  
  344.  
  345.         case WM_DESTROY:
  346.  
  347.             // Free all memory allocated for the column data
  348.  
  349.             WinSendMsg( hwndCnr, CM_REMOVEDETAILFIELDINFO, NULL,
  350.                         MPFROM2SHORT( 0, CMA_FREE ) );
  351.  
  352.             // Free all memory allocated for the container records
  353.  
  354.             WinSendMsg( hwndCnr, CM_REMOVERECORD, NULL,
  355.                         MPFROM2SHORT( 0, CMA_FREE ) );
  356.  
  357.             WinDestroyPointer( hptr );
  358.  
  359.             break;
  360.  
  361.  
  362.         case WM_COMMAND:
  363.  
  364.             switch( SHORT1FROMMP( mp1 ) )
  365.             {
  366.                 case IDM_NAME:
  367.  
  368.                     SetContainerView( CV_NAME | CV_FLOW );
  369.  
  370.                     return 0;
  371.  
  372.                 case IDM_ICON:
  373.  
  374.                     SetContainerView( CV_ICON );
  375.  
  376.                     return 0;
  377.  
  378.                 case IDM_TREE:
  379.  
  380.                     SetContainerView( CV_TREE | CV_ICON );
  381.  
  382.                     return 0;
  383.  
  384.                 case IDM_DETAILS:
  385.  
  386.                     SetContainerView( CV_DETAIL );
  387.  
  388.                     return 0;
  389.  
  390.                 case IDM_TEXT:
  391.  
  392.                     SetContainerView( CV_TEXT | CV_FLOW );
  393.  
  394.                     return 0;
  395.             }
  396.  
  397.             break;
  398.  
  399.  
  400.         case WM_CONTROL:
  401.  
  402.             if( SHORT1FROMMP( mp1 ) == CNR_SAMPLE )
  403.                 switch( SHORT2FROMMP( mp1 ) )
  404.                 {
  405.                     case CN_BEGINEDIT:
  406.  
  407.                         CnrBeginEdit( (PCNREDITDATA) mp2 );
  408.  
  409.                         break;
  410.  
  411.  
  412.                     case CN_ENDEDIT:
  413.  
  414.                         CnrEndEdit( (PCNREDITDATA) mp2 );
  415.  
  416.                         break;
  417.                 }
  418.  
  419.             break;
  420.     }
  421.  
  422.     return WinDefWindowProc( hwnd, msg, mp1, mp2 );
  423. }
  424.  
  425. /**********************************************************************/
  426. /*-------------------------- InsertRecord ----------------------------*/
  427. /*                                                                    */
  428. /*  INSERT RECORD AND ITS CHILD RECORDS INTO THE CONTAINER            */
  429. /*                                                                    */
  430. /*  INPUT: nothing                                                    */
  431. /*                                                                    */
  432. /*  1.                                                                */
  433. /*                                                                    */
  434. /*  OUTPUT: nothing                                                   */
  435. /*                                                                    */
  436. /*--------------------------------------------------------------------*/
  437. /**********************************************************************/
  438. static VOID InsertRecord()
  439. {
  440.     USHORT       usRecs = 1;
  441.     static INT   iParent = 1, iChild;
  442.     ULONG        cbExtra;
  443.     PCNRITEM     pciDad, pciSave, pciChild;
  444.     RECORDINSERT ri;
  445.  
  446.     // Calculate extra bytes needed for each record besides that needed for the
  447.     // MINIRECORDCORE structure
  448.  
  449.     cbExtra = sizeof( CNRITEM ) - sizeof( MINIRECORDCORE );
  450.  
  451.     // Allocate memory for the parent record
  452.  
  453.     pciDad = WinSendMsg( hwndCnr, CM_ALLOCRECORD, MPFROMLONG( cbExtra ),
  454.                          MPFROMSHORT( usRecs ) );
  455.  
  456.     // Fill in the parent record data
  457.  
  458.     FillInRecord( pciDad, iParent++ );
  459.  
  460.     (void) memset( &ri, 0, sizeof( RECORDINSERT ) );
  461.  
  462.     ri.cb                 = sizeof( RECORDINSERT );
  463.     ri.pRecordOrder       = (PRECORDCORE) CMA_END;
  464.     ri.pRecordParent      = (PRECORDCORE) NULL;
  465.     ri.zOrder             = (USHORT) CMA_TOP;
  466.     ri.cRecordsInsert     = usRecs;
  467.     ri.fInvalidateRecord  = FALSE;
  468.  
  469.     // Insert the parent record
  470.  
  471.     WinSendMsg( hwndCnr, CM_INSERTRECORD, MPFROMP( pciDad ), MPFROMP( &ri ) );
  472.  
  473.     // We are about to insert the child records. Set the parent record to be
  474.     // the one we just inserted.
  475.  
  476.     ri.pRecordParent = (PRECORDCORE) pciDad;
  477.  
  478.     // Insert 10 child records under the parent record.
  479.  
  480.     usRecs = 10;
  481.  
  482.     ri.cRecordsInsert = usRecs;
  483.  
  484.     pciChild = WinSendMsg( hwndCnr, CM_ALLOCRECORD, MPFROMLONG( cbExtra ),
  485.                            MPFROMSHORT( usRecs ) );
  486.  
  487.     // Save the pointer to the beginning of the linked list
  488.  
  489.     pciSave = pciChild;
  490.  
  491.     for( iChild = 100; iChild < 110; iChild++ )
  492.     {
  493.         FillInRecord( pciChild, iChild );
  494.  
  495.         pciChild->rc.pszIcon = szChildRecName;
  496.  
  497.         pciChild = (PCNRITEM) pciChild->rc.preccNextRecord;
  498.     }
  499.  
  500.     WinSendMsg( hwndCnr, CM_INSERTRECORD, MPFROMP( pciSave ), MPFROMP( &ri ) );
  501. }
  502.  
  503. /**********************************************************************/
  504. /*-------------------------- FillInRecord ----------------------------*/
  505. /*                                                                    */
  506. /*  POPULATE CONTAINER RECORD                                         */
  507. /*                                                                    */
  508. /*  INPUT: pointer to record buffer to fill,                          */
  509. /*         number of record                                           */
  510. /*                                                                    */
  511. /*  1.                                                                */
  512. /*                                                                    */
  513. /*  OUTPUT: nothing                                                   */
  514. /*                                                                    */
  515. /*--------------------------------------------------------------------*/
  516. /**********************************************************************/
  517. static VOID FillInRecord( PCNRITEM pci, INT iRecNum )
  518. {
  519.     pci->rc.cb          = sizeof( MINIRECORDCORE );
  520.     pci->rc.pszIcon     = szRecName;
  521.     pci->rc.hptrIcon    = hptr;
  522.  
  523.     pci->hptrIcon       = hptr;
  524.     pci->szData         = szItemData;
  525.     pci->date.day       = 11;
  526.     pci->date.month     = 11;
  527.     pci->date.year      = 11;
  528.     pci->time.seconds   = 12;
  529.     pci->time.minutes   = 12;
  530.     pci->time.hours     = 12;
  531.     pci->ulData         = iRecNum;
  532. }
  533.  
  534. /**********************************************************************/
  535. /*------------------------- SetContainerView -------------------------*/
  536. /*                                                                    */
  537. /*  SET THE TYPE OF VIEW FOR THE CONTAINER                            */
  538. /*                                                                    */
  539. /*  INPUT: view type to set to                                        */
  540. /*                                                                    */
  541. /*  1.                                                                */
  542. /*                                                                    */
  543. /*  OUTPUT: nothing                                                   */
  544. /*                                                                    */
  545. /*--------------------------------------------------------------------*/
  546. /**********************************************************************/
  547. static VOID SetContainerView( ULONG ulViewType )
  548. {
  549.     CNRINFO cnri;
  550.  
  551.     cnri.cb = sizeof( CNRINFO );
  552.  
  553.     cnri.pszCnrTitle = szCnrTitle;
  554.  
  555.     cnri.flWindowAttr = ulViewType | CA_CONTAINERTITLE | CA_TITLESEPARATOR;
  556.  
  557.     switch( ulViewType )
  558.     {
  559.         case CV_DETAIL:
  560.  
  561.             cnri.flWindowAttr |= CA_DETAILSVIEWTITLES;
  562.  
  563.             break;
  564.  
  565.         case CV_TREE:
  566.         case (CV_TREE | CV_ICON):
  567.  
  568.             cnri.cxTreeIndent = -1;
  569.             cnri.cxTreeLine   = -1;
  570.  
  571.             cnri.flWindowAttr |=  CA_TREELINE;
  572.  
  573.             break;
  574.     }
  575.  
  576.     WinSendMsg( hwndCnr, CM_SETCNRINFO, MPFROMP( &cnri ),
  577.                 MPFROMLONG( CMA_FLWINDOWATTR | CMA_CNRTITLE ) );
  578.  
  579.     if( ulViewType == CV_ICON )
  580.         WinSendMsg( hwndCnr, CM_ARRANGE, NULL, NULL );
  581. }
  582.  
  583. /**********************************************************************/
  584. /*--------------------------- CnrBeginEdit ---------------------------*/
  585. /*                                                                    */
  586. /*  PROCESS CN_BEGINEDIT NOTIFY MESSAGE.                              */
  587. /*                                                                    */
  588. /*  INPUT: pointer to the CNREDITDATA structure                       */
  589. /*                                                                    */
  590. /*  1.                                                                */
  591. /*                                                                    */
  592. /*  OUTPUT: nothing                                                   */
  593. /*                                                                    */
  594. /*--------------------------------------------------------------------*/
  595. /**********************************************************************/
  596. static VOID CnrBeginEdit( PCNREDITDATA pced )
  597. {
  598.     PFIELDINFO  pfi = pced->pFieldInfo;
  599.     HWND        hwndMLE = WinWindowFromID( hwndCnr, CID_MLE );
  600.  
  601.     // pfi only available if details view
  602.  
  603.     if( !pfi || pfi->offStruct == FIELDOFFSET( CNRITEM, szData ) )
  604.         WinSendMsg( hwndMLE, MLM_SETTEXTLIMIT,
  605.                     MPFROMLONG( MAX_DATA_LENGTH ), (MPARAM) NULL );
  606. }
  607.  
  608. /**********************************************************************/
  609. /*---------------------------- CnrEndEdit ----------------------------*/
  610. /*                                                                    */
  611. /*  PROCESS CN_ENDEDIT NOTIFY MESSAGE.                                */
  612. /*                                                                    */
  613. /*  INPUT: pointer to the CNREDITDATA structure                       */
  614. /*                                                                    */
  615. /*  1.                                                                */
  616. /*                                                                    */
  617. /*  OUTPUT: nothing                                                   */
  618. /*                                                                    */
  619. /*--------------------------------------------------------------------*/
  620. /**********************************************************************/
  621. static VOID CnrEndEdit( PCNREDITDATA pced )
  622. {
  623.     PCNRITEM        pcnri = (PCNRITEM) pced->pRecord;
  624.     PFIELDINFO      pfi = pced->pFieldInfo;
  625.     HWND            hwndMLE = WinWindowFromID( hwndCnr, CID_MLE );
  626.     CHAR            szData[ MAX_DATA_LENGTH + 1 ];
  627.  
  628.     // pfi only available if details view
  629.  
  630.     if( !pfi || pfi->offStruct == FIELDOFFSET( CNRITEM, szData ) )
  631.     {
  632.         WinQueryWindowText( hwndMLE, MAX_DATA_LENGTH, szData );
  633.  
  634.         if( !stricmp( szData, "BADREC" ) )
  635.             WinAlarm( HWND_DESKTOP, WA_WARNING );
  636.     }
  637.  
  638.     WinSendMsg( hwndCnr, CM_INVALIDATERECORD, MPFROMP( &pcnri ),
  639.                 MPFROM2SHORT( 1, CMA_TEXTCHANGED ) );
  640. }
  641.  
  642. /*************************************************************************
  643.  *                     E N D     O F     S O U R C E                     *
  644.  *************************************************************************/
  645.