home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / os2sdk / os2sdk12 / iniedit / iniedit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-07-05  |  26.9 KB  |  742 lines

  1. /******************************* Module Header ******************************\
  2. * Module Name: IniEdit.c
  3. *
  4. *
  5. * PM OS2.ini Editor
  6. *
  7. * Allows adding, deleting and modifying of os2.ini entries through PM
  8. * interface
  9. *
  10. *
  11. \***************************************************************************/
  12.  
  13.  
  14. #define LINT_ARGS                           // Include needed parts of PM
  15. #define INCL_WININPUT                       //    definitions
  16. #define INCL_WINSYS
  17. #define INCL_WINMESSAGEMGR
  18. #define INCL_WINBUTTONS
  19. #define INCL_WINPOINTERS
  20. #define INCL_WINHEAP
  21. #define INCL_WINSHELLDATA
  22. #define INCL_WINMENUS
  23. #define INCL_WINFRAMEMGR
  24. #define INCL_WINDIALOGS
  25. #define INCL_WINLISTBOXES
  26. #define INCL_WINENTRYFIELDS
  27. #define INCL_DOSMEMMGR
  28. #define INCL_WINSWITCHLIST
  29. #define INCL_DOSPROCESS
  30. #define INCL_GPIBITMAPS
  31. #define INCL_GPIREGIONS
  32. #define INCL_GPILCIDS
  33. #define INCL_GPIPRIMITIVES
  34. #define INCL_DEV
  35.  
  36. #include <string.h>
  37. #include <stdio.h>
  38.  
  39. #include <os2.h>
  40.  
  41. #include "IniEdit.h"
  42.  
  43.  
  44. /******************************* Constants **********************************/
  45.  
  46. #define STACK_SIZE            0x2000        // Stack size for second thread
  47. #define UPPER_SEGMENT_LIMIT   0xFD00        // Amount of Segment used
  48.  
  49. /******************************** Globals **********************************/
  50.  
  51. char szIniEdit[] = "IniEdit";               // App String Name
  52.  
  53. HAB       habIniEdit;                       // Handle Anchor Block
  54. HMQ       hmqIniEdit;                       // Handle Message Queue
  55. HWND      hwndIniEdit;                      // Main Client Window
  56. HWND      hwndIniEditFrame;                 // Frame Window
  57. HDC       hdcScreen;                        // DC for Client Window
  58. HPS       hpsScreen;                        // PS for Client Window
  59.  
  60.  
  61. USHORT    cAppNames = 0;                    // Count of App names in os2.ini
  62. USHORT    usShift = 0;                      // DosHugeAlloc segment offsets
  63. HWND      FocusWindow = (HWND)NULL;         // Focus of Dialog Box
  64. USHORT    cxBorder;                         // System border width
  65. USHORT    cyBorder;                         // System border height
  66.  
  67. USHORT    usFormat = APP_FORM;              // Current Display format
  68. USHORT    usPrintFormat = APP_FORM;         // Format for Printing
  69. USHORT    usLineHeight = 12;                // Current font Height
  70. HWND      hwndList = (HWND)NULL;            // Handle of Main ListBox
  71. HWND      hwndMenu = (HWND)NULL;            // Handle of Main Menu
  72.  
  73. PGROUPSTRUCT  pGroups;                      // Pointer to String Groups
  74. PPAIRSTRUCT   pPairsBase;                   // Pointer to Key-Value Pairs
  75. PPAIRSTRUCT   pPairsAlloc;                  // Pointer to next Avail Memory
  76. PBYTE         pPrintStack;                  // Pointer to Print Thread Stack
  77.  
  78. #define HOLD_LEN 4096
  79. CHAR          achNames[HOLD_LEN];           // Array of Character from Query
  80. CHAR          szBuf[2 * MAX_STRING_LEN];        // Character buffer for Pairs
  81.  
  82.  
  83. /***************************** Function Decls ******************************/
  84.  
  85. VOID    ProcessMenuItem( HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2 );
  86. VOID    cdecl main( VOID );
  87. VOID    IniEditPaint( VOID );
  88. VOID    ReadIni( VOID );
  89. VOID    OldProfilePrint( VOID );
  90. VOID    UpdateListBox( BOOL fRead, USHORT usForm );
  91.  
  92. MRESULT _loadds EXPENTRY IniEditWndProc(HWND, USHORT, MPARAM, MPARAM);
  93.  
  94.  
  95. /***************************** Function Header *****************************\
  96. *
  97. * main
  98. *
  99. *
  100. * Do initialization then do a message loop
  101. *
  102. \***************************************************************************/
  103.  
  104. VOID cdecl main()
  105. {
  106.  
  107.     QMSG         qmsg;                      // Current Queue Message
  108.     ULONG        fcf;                       // Frame Control Flags
  109.     SIZEL        sizel;                     // Size of PS
  110.     RECTL        rclWindow;                 // Size Rect for ListBox Window
  111.     SEL          sel;                       // Selector of allocated segments
  112.     SWCNTRL      swcntrl;                   // Switch Control Block
  113.     FONTMETRICS  fmetrics;                  // FontMetrics of current font
  114.  
  115.  
  116.     /*** Set up and Initialization ***/
  117.  
  118.     /* Initialize the anchor block handle */
  119.     habIniEdit = WinInitialize(0);
  120.  
  121.     /* Create the message queue */
  122.     hmqIniEdit = WinCreateMsgQueue(habIniEdit, 0);
  123.  
  124.     /* Register the window class for the IniEdit window */
  125.     WinRegisterClass(habIniEdit, (PCH)szIniEdit, IniEditWndProc,
  126.             CS_SIZEREDRAW, 0);
  127.  
  128.     /* Create the window for IniEdit */
  129.     fcf = FCF_TITLEBAR | FCF_MINMAX | FCF_SYSMENU | FCF_SIZEBORDER | FCF_MENU
  130.         | FCF_SHELLPOSITION | FCF_ACCELTABLE | FCF_ICON;
  131.  
  132.     hwndIniEditFrame = WinCreateStdWindow( HWND_DESKTOP, WS_VISIBLE,
  133.         (PVOID)&fcf, (PSZ)szIniEdit, (PSZ)szIniEdit, WS_VISIBLE,
  134.         (HMODULE)NULL, IDI_INIEDIT, (PHWND)&hwndIniEdit);
  135.  
  136.     /* Create a DC for the IniEdit window */
  137.     hdcScreen = WinOpenWindowDC(hwndIniEdit);
  138.  
  139.     /* also create a screen PS */
  140.  
  141.     sizel.cx= 0L;   // To use the default screen page size.
  142.     sizel.cy= 0L;
  143.  
  144.     if( (hpsScreen = GpiCreatePS( habIniEdit, hdcScreen, &sizel,
  145.             (PU_PELS | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC ))) == (HPS)NULL )
  146.         {
  147.                 ;
  148.         }
  149.  
  150.  
  151.     /* Initially set the keyboard focus to us */
  152.     WinSetFocus(HWND_DESKTOP, hwndIniEdit);
  153.  
  154.     /* get the font size */
  155.     GpiQueryFontMetrics( hpsScreen, (LONG)sizeof( FONTMETRICS ), &fmetrics );
  156.     usLineHeight = (USHORT)(fmetrics.lMaxDescender + fmetrics.lMaxBaselineExt);
  157.  
  158.     /* get the system widths of a border */
  159.     cxBorder = (USHORT) WinQuerySysValue(HWND_DESKTOP, SV_CXBORDER);
  160.     cyBorder = (USHORT) WinQuerySysValue(HWND_DESKTOP, SV_CYBORDER);
  161.  
  162.     /* this menu handle is often used */
  163.     hwndMenu = WinWindowFromID( hwndIniEditFrame, FID_MENU );
  164.  
  165.     /* add program to switch list */
  166.     swcntrl.hwnd             = hwndIniEditFrame;
  167.     swcntrl.hwndIcon         = NULL;
  168.     swcntrl.hprog            = NULL;
  169.     swcntrl.idProcess        = 0;
  170.     swcntrl.idSession        = 0;
  171.     swcntrl.uchVisibility    = 0;
  172.     swcntrl.fbJump           = 0;
  173.     strcpy( swcntrl.szSwtitle, szIniEdit);
  174.     swcntrl.fReserved        = 0;
  175.  
  176.     WinAddSwitchEntry( &swcntrl );
  177.  
  178.     /* Create main list box in main window */
  179.     WinQueryWindowRect( hwndIniEdit, &rclWindow);
  180.     rclWindow.yTop -= usLineHeight;
  181.     rclWindow.yTop += cyBorder;
  182.     rclWindow.xRight += 2*cxBorder;
  183.     hwndList = WinCreateWindow( hwndIniEdit,            // parent
  184.                                 WC_LISTBOX,             // class
  185.                                 (PSZ)"Scroll",          // name
  186.                                 LS_NOADJUSTPOS,         // style
  187.                                 -cxBorder, -cyBorder,   // position
  188.                                 (USHORT)rclWindow.xRight,
  189.                                 (USHORT)rclWindow.yTop,
  190.                                 hwndIniEditFrame,       // Owner
  191.                                 HWND_TOP,               // InsertBehind
  192.                                 IDI_LIST,               // ID
  193.                                 (PVOID)NULL,            // pCtlData,
  194.                                 (PVOID)NULL);
  195.  
  196.  
  197.     /*** Memory Allocation ***/
  198.  
  199.     /* Alloc the needed space for the groups */
  200.     if( DosAllocSeg( 32000, &sel, 0) )
  201.         ErrMessage( "main: DosAlloc for pGroup failed" );
  202.     pGroups = MAKEP( sel, 0);
  203.  
  204.     if( DosAllocHuge( 4, 0, &sel, 0, 0) )
  205.         ErrMessage( "main: DosAlloc for pPairs failed" );
  206.     pPairsAlloc = pPairsBase = MAKEP( sel, 0);
  207.  
  208.     /* create a stack for second thread */
  209.     if( DosAllocSeg( STACK_SIZE, &sel, 0) )
  210.         ErrMessage( "main: DosAlloc for Stack failed" );
  211.     pPrintStack = MAKEP( sel, 0);
  212.  
  213.     DosGetHugeShift( &usShift );
  214.  
  215.     /* read in os2.ini and fill in list box */
  216.     UpdateListBox( TRUE, APP_FORM );
  217.  
  218.     WinShowWindow( hwndList, TRUE );
  219.  
  220.     /* Process messages for the window */
  221.     while ( WinGetMsg(habIniEdit, (PQMSG)&qmsg, (HWND)NULL, 0, 0 ) )
  222.         {
  223.  
  224.         /* Dispatch the message */
  225.         WinDispatchMsg(habIniEdit, (PQMSG)&qmsg);
  226.         }
  227.  
  228.  
  229.     /*** CleanUp ***/
  230.  
  231.     /* Destroy the IniEdit window and message queue */
  232.     GpiDestroyPS( hpsScreen );
  233.     WinDestroyWindow(hwndIniEditFrame);
  234.     WinDestroyMsgQueue(hmqIniEdit);
  235.  
  236.     /* Exit PM */
  237.     WinTerminate( habIniEdit );
  238.     DosExit( EXIT_PROCESS, 0 );
  239.  
  240. }  /* main */
  241.  
  242.  
  243. /****************************** Function Header ****************************\
  244. *
  245. * ReadIni
  246. *
  247. *
  248. * Reads in OS2.ini
  249. *
  250. \***************************************************************************/
  251.  
  252. VOID ReadIni()
  253. {
  254.     USHORT    cchNames;                     // Count of Character from Query
  255.     USHORT    Index[MAX_APP_NAMES];         // Index of Names into achNames
  256.     USHORT    cPairs;                       // Count of pairs in current AppName
  257.     ULONG     ul;
  258.     USHORT    i,j;                          // Loop Counters
  259.  
  260.  
  261.     /* Reset Count of App Names */
  262.     cAppNames = 0;
  263.  
  264.     /* Reset memory available pointer to Base */
  265.     pPairsAlloc = pPairsBase;
  266.  
  267.     /* Determine number of characters in app Names Strings */
  268.     WinQueryProfileSize( habIniEdit, NULL, NULL, &cchNames );
  269.  
  270.     /* Read in the App Name strings */
  271.     WinQueryProfileString( habIniEdit, NULL, NULL, " ", achNames, cchNames );
  272.  
  273.     /*** Find the starting index of each App ***/
  274.  
  275.     /* step through each string in set of app characters
  276.      * adding length of current string to find begining of next string
  277.      * also store each App Name into szAppName element of Group
  278.      */
  279.     for( i=0; i<cchNames; i += (strlen(pGroups[cAppNames-1].szAppName)+1) )
  280.         {
  281.         if( achNames[i] != (char)0 )
  282.             {
  283.             strcpy( pGroups[cAppNames++].szAppName, &achNames[i]);
  284.             }  /* if */
  285.         else
  286.             if( achNames[i+1] == (char)0 )
  287.                 break;
  288.         }  /* for */
  289.  
  290.  
  291.     /*** Read elements of each App Name ***/
  292.     for( i=0; i<cAppNames; i++ )
  293.         {
  294.         /* Get number of Character Associated with App Name */
  295.         WinQueryProfileSize( habIniEdit, pGroups[i].szAppName, NULL, &cchNames );
  296.  
  297.         /* Enumerate all KeyNames for this app name */
  298.         WinQueryProfileString( habIniEdit, pGroups[i].szAppName, NULL, " ", achNames, HOLD_LEN );
  299.  
  300.         /* Count the number of key Names */
  301.         cPairs = 0;
  302.         for( j=0; j<cchNames; j++)
  303.             if( achNames[j] != (CHAR)0 )
  304.                 {
  305.                 Index[cPairs++] = j;
  306.                 j += strlen( &achNames[j] );
  307.                 }
  308.  
  309.         pGroups[i].cKeys = cPairs;
  310.  
  311.         /*
  312.          * Make sure we can fit the entire structure into our current
  313.          * segment, if not, lets jump to the next segment
  314.          */
  315.         ul =  sizeof(PAIRSTRUCT) * cPairs;
  316.         if ((ul + (ULONG)OFFSETOF(pPairsAlloc)) >= 0x10000L)
  317.             pPairsAlloc = MAKEP( (HIUSHORT(pPairsAlloc)+(1<<usShift)), 0);
  318.  
  319.  
  320.  
  321.         /* Allocate the number of pair structures for the current group */
  322.         pGroups[i].pPairs = pPairsAlloc;
  323.  
  324.         // pPairsAlloc += sizeof(PAIRSTRUCT)*cPairs;
  325.         // Remember that incrementing a pointer automatically mult by size of item
  326.         pPairsAlloc += cPairs;
  327.  
  328.         /* Step to next segment if near end of current segment */
  329.         if( LOUSHORT(pPairsAlloc) > UPPER_SEGMENT_LIMIT)
  330.             {
  331.             pPairsAlloc = MAKEP( (HIUSHORT(pPairsAlloc)+(1<<usShift)), 0);
  332.             }
  333.  
  334.         /* Store the KeyName into the pair structure */
  335.         for( j=0; j<cPairs; j++ )
  336.             {
  337.             strcpy( pGroups[i].pPairs[j].szKey, &achNames[Index[j]] );
  338.  
  339.             /* store the key value */
  340.             WinQueryProfileString( habIniEdit, pGroups[i].szAppName,
  341.                      pGroups[i].pPairs[j].szKey, " ",
  342.                      pGroups[i].pPairs[j].szValue, MAX_STRING_LEN );
  343.  
  344.             }
  345.         }  /* each App Name */
  346.  
  347. }  /* ReadIni */
  348.  
  349.  
  350. /****************************** Function Header ****************************\
  351. *
  352. * ProcessMenuItem
  353. *
  354. *
  355. * Act on the corresponding Menu Item Choosen
  356. *
  357. \***************************************************************************/
  358.  
  359. VOID ProcessMenuItem( HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2 )
  360. {
  361.     TID  Tid;                               // ID of new thread; Not used
  362.  
  363.  
  364.     /* Switch on the Menu Item choosen */
  365.     switch( LOUSHORT( mp1 ) )
  366.         {
  367.         case IDMI_SHOW_ALL:
  368.         case IDMI_SHOW_APPNAMES:
  369.             usFormat = (LOUSHORT(mp1) == IDMI_SHOW_ALL);
  370.             UpdateListBox( FALSE, usFormat ? ALL_FORM : APP_FORM );
  371.             break;
  372.  
  373.         case IDM_SEARCH:
  374.             WinDlgBox(HWND_DESKTOP, hwndIniEditFrame, (PFNWP)SearchWndProc,
  375.                             (HMODULE)NULL, IDD_SEARCH, (PVOID)NULL);
  376.             break;
  377.  
  378.         case IDMI_EDIT_DELETE_KEY:
  379.             WinDlgBox(HWND_DESKTOP, hwndIniEditFrame, (PFNWP)DelKeyWndProc,
  380.                             (HMODULE)NULL, IDD_DEL_KEY, (PVOID)NULL);
  381.             UpdateListBox( TRUE, usFormat ? ALL_FORM : APP_FORM );
  382.             break;
  383.  
  384.         case IDMI_EDIT_DELETE_APP:
  385.             WinDlgBox(HWND_DESKTOP, hwndIniEditFrame, (PFNWP)DelAppWndProc,
  386.                             (HMODULE)NULL, IDD_DEL_APP, (PVOID)NULL);
  387.             UpdateListBox( TRUE, usFormat ? ALL_FORM : APP_FORM );
  388.             break;
  389.  
  390.         case IDMI_EDIT_ADD_KEY:
  391.             WinDlgBox(HWND_DESKTOP, hwndIniEditFrame, (PFNWP)AddKeyWndProc,
  392.                             (HMODULE)NULL, IDD_ADD_KEY, (PVOID)NULL);
  393.             UpdateListBox( TRUE, usFormat ? ALL_FORM : APP_FORM );
  394.             break;
  395.  
  396.         case IDMI_EDIT_CHANGE:
  397.             WinDlgBox(HWND_DESKTOP, hwndIniEditFrame, (PFNWP)ChangeKeyWndProc,
  398.                             (HMODULE)NULL, IDD_CHANGE_KEY, (PVOID)NULL);
  399.             UpdateListBox( TRUE, usFormat ? ALL_FORM : APP_FORM );
  400.             break;
  401.  
  402.         case IDMI_PRINT_ALL:
  403.         case IDMI_PRINT_APP:
  404.             usPrintFormat = LOUSHORT(mp1) == IDMI_PRINT_ALL ? ALL_FORM : APP_FORM;
  405.             if( DosCreateThread( PrintThread, &Tid, ((PBYTE)(pPrintStack)+STACK_SIZE) ) )
  406.                 ErrMessage("StartThread2: DosCreateThread Failed");
  407.             break;
  408.  
  409.         case IDMI_REFRESH:
  410.             UpdateListBox( TRUE, usFormat );
  411.             break;
  412.  
  413.         case IDMI_ABOUT:
  414.             WinDlgBox(HWND_DESKTOP, hwndIniEditFrame, (PFNWP)DelAppWndProc,
  415.                             (HMODULE)NULL, IDD_ABOUT, (PVOID)NULL);
  416.             break;
  417.  
  418.         default:
  419.             WinDefWindowProc(hwnd, msg, mp1, mp2);
  420.  
  421.             break;
  422.  
  423.         }  /* switch */
  424.  
  425. }  /* ProcessMenuItem */
  426.  
  427.  
  428. /****************************** Function Header ****************************\
  429. *
  430. * UpdateListBox
  431. *
  432. *
  433. * Update Main List Box to correct state
  434. *    May Also:
  435. *    - Check correct menu item
  436. *    - Repaint title of List Box
  437. *    - ReRead os2.ini file
  438. *
  439. \***************************************************************************/
  440.  
  441. VOID UpdateListBox( BOOL fReadIni, USHORT usNewFormat )
  442. {
  443.     USHORT    i,j;                          // Loop Counters
  444.     USHORT    Index;                        // Index into ListBox
  445.     static    USHORT    usLastFormat = -1;  // Last displayed format
  446.  
  447.  
  448.     /* Check the correct item if format changed */
  449.     if( usLastFormat != usNewFormat )
  450.         {
  451.         WinSendMsg( hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(IDMI_SHOW_ALL, TRUE),
  452.                 MPFROM2SHORT(MIA_CHECKED, usFormat ? MIA_CHECKED:FALSE));
  453.  
  454.         WinSendMsg( hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(IDMI_SHOW_APPNAMES, TRUE),
  455.                 MPFROM2SHORT(MIA_CHECKED, (!usFormat) ? MIA_CHECKED:FALSE));
  456.         usLastFormat = usNewFormat;
  457.  
  458.         WinSendMsg( hwndIniEdit, WM_PAINT, (MPARAM)NULL, (MPARAM)NULL );
  459.         }
  460.  
  461.  
  462.     /* Turn off list box updates */
  463.     WinEnableWindowUpdate( hwndList, FALSE );
  464.  
  465.     /* Remove all items from list box */
  466.     WinSendMsg( hwndList, LM_DELETEALL, (MPARAM)0, (MPARAM)0 );
  467.  
  468.     /* ReRead os2.ini if needed */
  469.     if( fReadIni )
  470.         ReadIni();
  471.  
  472.     /* Add elements to listbox */
  473.     if( usNewFormat == ALL_FORM )
  474.         {
  475.  
  476.         /* Insert all app Names */
  477.         for( i=0; i<cAppNames; i++ )
  478.             {
  479.             Index = SHORT1FROMMR(WinSendMsg( hwndList, LM_INSERTITEM,
  480.                     MPFROM2SHORT(LIT_END, NULL),
  481.                     MPFROMP(pGroups[i].szAppName) ));
  482.  
  483.             WinSendMsg( hwndList, LM_SETITEMHANDLE,
  484.                     MPFROMSHORT(Index),
  485.                     MPFROMSHORT(i) );
  486.  
  487.             /* Insert Key Value Pairs for App Name */
  488.             for( j=0; j<pGroups[i].cKeys; j++ )
  489.                 {
  490.                 sprintf( szBuf, "     %s: %s", pGroups[i].pPairs[j].szKey,
  491.                         pGroups[i].pPairs[j].szValue );
  492.                 Index = SHORT1FROMMR(WinSendMsg( hwndList, LM_INSERTITEM,
  493.                         MPFROM2SHORT(LIT_END, NULL),
  494.                         MPFROMP(szBuf) ));
  495.  
  496.                 WinSendMsg( hwndList, LM_SETITEMHANDLE,
  497.                         MPFROMSHORT(Index),
  498.                         MPFROM2SHORT(i,j) );
  499.  
  500.                 }
  501.             }
  502.         }  /* if */
  503.     else
  504.         {
  505.         /* Insert all app Names */
  506.         for( i=0; i<cAppNames; i++ )
  507.             {
  508.             WinSendMsg( hwndList, LM_INSERTITEM,
  509.                     MPFROM2SHORT(LIT_SORTASCENDING, NULL),
  510.                     MPFROMP(pGroups[i].szAppName) );
  511.             }
  512.         }  /* else */
  513.  
  514.     /* Do All repainting of ListBox */
  515.     WinEnableWindowUpdate( hwndList, TRUE );
  516.  
  517. }  /* UpdateListBox */
  518.  
  519.  
  520. /****************************** Function Header ****************************\
  521. *
  522. * IniEditPaint
  523. *
  524. *
  525. * Window Paint Routine
  526. *
  527. \***************************************************************************/
  528.  
  529. VOID IniEditPaint()
  530. {
  531.     RECTL     rclWindow;                    // Current size of Main Window
  532.     RECTL     rclBlit;                      // Size of Area to Blank for Title
  533.     CHAR      szShowMode[MAX_STRING_LEN];   // String Description of mode
  534.  
  535.  
  536.     /* Get the size of the whole window */
  537.     WinQueryWindowRect( hwndIniEdit, &rclWindow );
  538.  
  539.     /* Paint the window Title Area */
  540.     rclBlit = rclWindow;
  541.     rclBlit.yBottom = rclBlit.yTop - usLineHeight;
  542.  
  543.     GpiBitBlt( hpsScreen, (HPS)NULL, 2L, (PPOINTL)&rclBlit, ROP_ONE, (LONG)NULL);
  544.  
  545.     /* Write the Title */
  546.     strcpy( szShowMode, usFormat == APP_FORM ? SZAPP : SZALL );
  547.     WinDrawText( hpsScreen, strlen(szShowMode), szShowMode, &rclWindow,
  548.             CLR_BLUE, CLR_WHITE, DT_CENTER|DT_TOP);
  549.  
  550. }  /* IniEditPaint */
  551.  
  552.  
  553. /****************************** Function Header ****************************\
  554. *
  555. * IniEditWndProc
  556. *
  557. *
  558. * Window Proc for IniEdit
  559. *
  560. \***************************************************************************/
  561.  
  562. MRESULT _loadds EXPENTRY IniEditWndProc(HWND hwnd, USHORT msg,
  563.         MPARAM mp1, MPARAM mp2)
  564. {
  565.  
  566.     CHAR      szBuf[MAX_STRING_LEN];        // Input character Buffer
  567.     CHAR      szBuf2[MAX_STRING_LEN];       // Second Input Character Buffer
  568.     USHORT    Index;                        // Index of Current ListBox Item
  569.     USHORT    TopIndex;                     // Current Top Item in ListBox
  570.     ULONG     Handle;                       // ListBox Item Handle Info
  571.     HWND      hwndDialog;                   // Window handle of Dailog Box
  572.     HWND      hwndText;                     // Handle of current text window
  573.     HPS       hpsPaint;                     // PS to Paint
  574.     RECTL     rclPaint;                     // Rect in hpsPaint to Paint
  575.     BOOL      fScroll = FALSE;              // Scroll List Box Flag
  576.  
  577.  
  578.     /* Switch on message being processed */
  579.     switch( msg )
  580.         {
  581.         case WM_PAINT:
  582.             /* Paint the IniEdit window portion not covered by List Box */
  583.             hpsPaint = WinBeginPaint(hwnd, (HPS)NULL, &rclPaint);
  584.             IniEditPaint();
  585.             WinEndPaint(hpsPaint);
  586.             break;
  587.  
  588.         case WM_COMMAND:
  589.             /* If menu item call Processing Routine */
  590.             if( LOUSHORT( mp2 ) == CMDSRC_MENU )
  591.                 ProcessMenuItem( hwnd, msg, mp1, mp2 );
  592.  
  593.             /* If accelorator call appropriate routine */
  594.             if( LOUSHORT( mp2 ) == CMDSRC_ACCELERATOR )
  595.                 {
  596.                 switch( LOUSHORT( mp1 ) )
  597.                     {
  598.                     case IDDI_SEARCH_NEXT:
  599.                         FindNext();
  600.                         break;
  601.                     }
  602.                 }
  603.             break;
  604.  
  605.         case WM_SIZE:
  606.             /* Put the list box in the correct location of the window */
  607.             if( hwndList != (HWND)NULL )
  608.                 /* The position is set to fill the client, except for the */
  609.                 /* area at the top for some text.  In addition, the       */
  610.                 /* rectangle is outset by a border width on all dimensions*/
  611.                 /* except for the top so that the list box border is      */
  612.                 /* "tucked" under the clients border and doesn't cause    */
  613.                 /* there to be a double thick border around it.           */
  614.                 WinSetWindowPos( hwndList, HWND_TOP, -cxBorder, -cyBorder,
  615.                         SHORT1FROMMP(mp2)+(2*cxBorder),
  616.                         SHORT2FROMMP(mp2)-usLineHeight + cyBorder,
  617.                         SWP_SIZE | SWP_MOVE );
  618.             break;
  619.  
  620.         case WM_CONTROL:
  621.             /* Switch on Control activated */
  622.             switch( SHORT1FROMMP(mp1) )
  623.                 {
  624.  
  625.                 /*** Process List Box Activity ***/
  626.                 case IDI_LIST:
  627.                     /* was it a double click? */
  628.                     if( SHORT2FROMMP(mp1) == LN_ENTER )
  629.                         {
  630.                         /* get the item clicked on */
  631.                         Index = SHORT1FROMMR(WinSendMsg( hwndList, LM_QUERYSELECTION,
  632.                                 (MPARAM)0, (MPARAM)0 ));
  633.  
  634.                         /* grab its text */
  635.                         WinSendMsg( hwndList, LM_QUERYITEMTEXT,
  636.                                 MPFROM2SHORT(Index, MAX_STRING_LEN), MPFROMP(szBuf) );
  637.  
  638.                         /* if in APP form toggle to ALL form */
  639.                         if( usFormat == APP_FORM )
  640.                             {
  641.                             usFormat = ALL_FORM;
  642.                             fScroll = TRUE;
  643.                             }
  644.                         else
  645.                             {
  646.                             /* if an App name was choosen then go to APP form */
  647.                             if( szBuf[0] != ' ')
  648.                                 {
  649.                                 usFormat = APP_FORM;
  650.                                 fScroll = TRUE;
  651.                                 }
  652.                             else
  653.                                 /* A Key Value Pair was double clicked
  654.                                  * allow editing of key Value
  655.                                  */
  656.                                 {
  657.  
  658.                                 FocusWindow = (HWND)1;
  659.  
  660.                                 hwndDialog = WinLoadDlg( HWND_DESKTOP,
  661.                                     hwndIniEditFrame, ChangeKeyWndProc,
  662.                                     (HMODULE)NULL, IDD_CHANGE_KEY, NULL);
  663.  
  664.                                 Handle = (ULONG)WinSendMsg( hwndList, LM_QUERYITEMHANDLE,
  665.                                     MPFROMSHORT(Index), (MPARAM)NULL );
  666.  
  667.                                 hwndText = WinWindowFromID( hwndDialog, IDDI_CHANGE_KEY_TEXT_APP );
  668.                                 WinSendMsg(hwndText, EM_SETTEXTLIMIT,
  669.                                         MPFROMSHORT(MAX_STRING_LEN), 0L);
  670.                                 WinSetWindowText( hwndText, pGroups[LOUSHORT(Handle)].szAppName);
  671.  
  672.                                 /* note bug in PMWin GPs if full segment */
  673.                                 hwndText = WinWindowFromID( hwndDialog, IDDI_CHANGE_KEY_TEXT_KEY );
  674.                                 WinSendMsg(hwndText, EM_SETTEXTLIMIT,
  675.                                         MPFROMSHORT(MAX_STRING_LEN), 0L);
  676.                                 strcpy( szBuf2, pGroups[LOUSHORT(Handle)].pPairs[HIUSHORT(Handle)].szKey );
  677.                                 WinSetWindowText( hwndText, szBuf2 );
  678.  
  679.                                 hwndText = WinWindowFromID( hwndDialog, IDDI_CHANGE_KEY_TEXT_VAL );
  680.                                 WinSendMsg(hwndText, EM_SETTEXTLIMIT,
  681.                                         MPFROMSHORT(MAX_STRING_LEN), 0L);
  682.                                 strcpy( szBuf2, pGroups[LOUSHORT(Handle)].pPairs[HIUSHORT(Handle)].szValue );
  683.                                 WinSetWindowText( hwndText, szBuf2 );
  684.  
  685.                                 WinPostMsg( hwndText, EM_SETSEL,
  686.                                         MPFROM2SHORT(0, strlen(szBuf2)), (MPARAM)0 );
  687.  
  688.                                 if( WinProcessDlg( hwndDialog ) == IDDI_CHANGE_KEY_OK )
  689.                                     {
  690.                                     TopIndex = SHORT1FROMMR(WinSendMsg( hwndList, LM_QUERYTOPINDEX,
  691.                                          (MPARAM)NULL, (MPARAM)NULL ));
  692.  
  693.                                     UpdateListBox( TRUE, usFormat );
  694.  
  695.                                     /* scroll to top */
  696.                                     WinSendMsg( hwndList, LM_SETTOPINDEX,
  697.                                          MPFROMSHORT(TopIndex), (MPARAM)NULL );
  698.  
  699.                                     /* make the item selected */
  700.                                     WinSendMsg( hwndList, LM_SELECTITEM,
  701.                                             MPFROMSHORT(Index), MPFROMSHORT(TRUE) );
  702.  
  703.                                     /* make selected */
  704.                                     }
  705.  
  706.                                 WinDestroyWindow( hwndDialog );
  707.                                 }
  708.                             }
  709.  
  710.                         /* Make the double clicked item selected in new form */
  711.                         if( fScroll )
  712.                             {
  713.                             /* put in correct form */
  714.                             UpdateListBox( FALSE, usFormat );
  715.  
  716.                             /* get the index of the item clicked on */
  717.                             Index = SHORT1FROMMR(WinSendMsg( hwndList, LM_SEARCHSTRING,
  718.                                     MPFROM2SHORT(LSS_SUBSTRING, LIT_FIRST),
  719.                                     MPFROMP(szBuf) ));
  720.  
  721.                             /* scroll that item to the top */
  722.                             WinSendMsg( hwndList, LM_SETTOPINDEX,
  723.                                     MPFROMSHORT(Index), (MPARAM)NULL );
  724.  
  725.                             /* make the item selected */
  726.                             WinSendMsg( hwndList, LM_SELECTITEM,
  727.                                     MPFROMSHORT(Index), MPFROMSHORT(TRUE) );
  728.                             }
  729.                         }  /* if ENTER */
  730.                 }
  731.             break;
  732.  
  733.         default:
  734.             return WinDefWindowProc(hwnd, msg, mp1, mp2);
  735.             break;
  736.         }
  737.  
  738.     return 0L;
  739.  
  740. }  /* IniEditWndProc */
  741. 
  742.