home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c480 / 18.ddi / SAMPLES / PROFILER / WIN / QSORTW.C_ / QSORTW.C
Encoding:
C/C++ Source or Header  |  1993-02-08  |  10.1 KB  |  445 lines

  1. /*
  2.  * QSORTW.C
  3.  *
  4.  * This program is described in Chapters 2 and 3 of the Microsoft Source
  5.  * Profiler User's Guide.
  6.  */
  7.  
  8. #include <WINDOWS.H>
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12.  
  13. #include "qsortw.h"
  14.  
  15. HWND        hWnd1;
  16. WNDCLASS    rClass;
  17. char        szInFile[_MAX_PATH];
  18. char        szOutFile[_MAX_PATH];
  19.  
  20. /*
  21.  * WinMain:
  22.  *     Parameters:
  23.  *         hInstance     - Handle to current Data Segment
  24.  *         hPrevInstance - Handle to previous Data Segment (NULL if none)
  25.  *         lpszCmdLine   - Long pointer to command line info
  26.  *         nCmdShow      - Integer value specifying how to start program
  27.  *                            (Iconic [7] or Normal [1,5])
  28.  */
  29. int PASCAL WinMain (HANDLE hInstance,
  30.             HANDLE hPrevInstance,
  31.             LPSTR  lpszCmdLine,
  32.             int    nCmdShow)
  33. {
  34. int nReturn;
  35.  
  36.     if (Init(hInstance, hPrevInstance,lpszCmdLine,nCmdShow))
  37.     {
  38.     nReturn = DoMain(hInstance);
  39.     }
  40.     return nReturn;
  41. }
  42.  
  43. /*
  44.  * Init
  45.  *     Initialization for the program is done here:
  46.  *     1)  Register the window class (if this is the first instance)
  47.  *     2)  Create the desktop window for the app.
  48.  *     3)  Show the desktop window in the manner requested by the User.
  49.  *
  50.  */
  51. BOOL Init(HANDLE hInstance,   HANDLE hPrevInstance,
  52.       LPSTR  lpszCmdLine, int    nCmdShow) 
  53. {
  54.  
  55.     if (!hPrevInstance)
  56.     {
  57.     /*  Register Class for First Overlapped Window  */
  58.     rClass.lpszClassName = "OVERLAPPED:1";
  59.     rClass.hInstance     = hInstance;
  60.     rClass.lpfnWndProc   = OverlappedWindowProc1;
  61.     rClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
  62.     rClass.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
  63.     rClass.lpszMenuName  = "SORTMENU";
  64.     rClass.hbrBackground = GetStockObject(WHITE_BRUSH);
  65.     rClass.style         = 0L;
  66.     rClass.cbClsExtra    = 0;
  67.     rClass.cbWndExtra    = 0;
  68.  
  69.     if (!RegisterClass( &rClass))
  70.         return FALSE;
  71.     }
  72.  
  73.     hWnd1 = CreateWindow("OVERLAPPED:1",
  74.         "Microsoft QSORT for Windows",
  75.         WS_OVERLAPPEDWINDOW,
  76.         CW_USEDEFAULT,
  77.         CW_USEDEFAULT,
  78.         CW_USEDEFAULT,
  79.         CW_USEDEFAULT,
  80.         NULL,
  81.         NULL,
  82.         hInstance,
  83.         NULL);
  84.  
  85.     ShowWindow(hWnd1,nCmdShow);
  86.  
  87.     return hWnd1;
  88. }
  89.  
  90. /*
  91.  * DoMain:
  92.  *     This is the main loop for the application, often called the message
  93.  *     pump.
  94.  */
  95. int  DoMain(HANDLE hInstance)
  96. {
  97. MSG msg;
  98.  
  99.     while (GetMessage(&msg,NULL,0,0))
  100.     {
  101.     TranslateMessage(&msg);
  102.     DispatchMessage(&msg);
  103.     }
  104.     return msg.wParam;
  105. }
  106.  
  107. /* OverlappedWindowProc1 - Handles messages for the main QSORT window.
  108.  *     Parameters:
  109.  *         hWnd    - Handle to Window which message is delivered to.
  110.  *         msgID   - ID number of message
  111.  *         wParam  - 16-bit parameter
  112.  *         lParam  - 32-bit parameter
  113.  *
  114.  */
  115. long _export FAR PASCAL OverlappedWindowProc1 (HWND     hWnd,
  116.                        unsigned wMsgID,
  117.                        unsigned wParam,
  118.                        LONG     lParam)
  119. {
  120. FARPROC lpfnDlgProc;
  121. unsigned    idEnd;
  122.  
  123.     switch (wMsgID)
  124.     {
  125.  
  126.     case WM_DESTROY:
  127.     PostQuitMessage(0);
  128.     break;
  129.  
  130.     case WM_COMMAND:
  131.  
  132.     switch(wParam) {
  133.  
  134.         case IDM_EXIT:
  135.         PostMessage(hWnd,WM_CLOSE,0,0L);
  136.         break;
  137.  
  138.         case IDM_SORT:
  139.  
  140.         lpfnDlgProc = MakeProcInstance((FARPROC) GetIOFiles, rClass.hInstance);
  141.         if(lpfnDlgProc) {
  142.  
  143.             /* Ask for the input and output files */
  144.             idEnd = DialogBox(rClass.hInstance,
  145.                 "GETFILE",
  146.                 hWnd,
  147.                 lpfnDlgProc);
  148.             FreeProcInstance(lpfnDlgProc);
  149.  
  150.             if( idEnd == IDOK )
  151.             SortMain (szInFile, szOutFile, hWnd);
  152.             }
  153.         break;
  154.         }
  155.     break;
  156.  
  157.     default:
  158.     return DefWindowProc(hWnd, wMsgID, wParam, lParam);
  159.     }
  160.  
  161. return 0;
  162. }
  163.  
  164. int _export FAR PASCAL GetIOFiles(
  165. HWND  hDlg,
  166. WORD  wMsg,
  167. WORD  wParam,
  168. DWORD lParam
  169. )
  170.  
  171. {
  172.  
  173. switch(wMsg) {
  174.  
  175.     case WM_INITDIALOG:
  176.     szInFile[0] = '\0';
  177.     szOutFile[0] = '\0';
  178.     SetFocus(hDlg);
  179.     break;
  180.  
  181.     case WM_COMMAND:
  182.  
  183.     switch(wParam) {
  184.  
  185.         // copy the string to the buffer originally pointed to by lParam
  186.         case IDOK:
  187.         GetDlgItemText(hDlg, ID_IN_EDIT, szInFile, sizeof(szInFile));
  188.         GetDlgItemText(hDlg, ID_OUT_EDIT, szOutFile, sizeof(szOutFile));
  189.         EndDialog(hDlg, IDOK);
  190.         return(TRUE);
  191.         break;
  192.  
  193.         case IDCANCEL:
  194.         EndDialog(hDlg, IDCANCEL);
  195.         return(TRUE);
  196.         break;
  197.         }
  198.     break;
  199.     }
  200.  
  201. return(FALSE);
  202. }
  203.  
  204. int _export FAR PASCAL StubDlgProc(
  205. HWND  hDlg,
  206. WORD  wMsg,
  207. WORD  wParam,
  208. DWORD lParam
  209. ) {
  210.  
  211. switch(wMsg) {
  212.  
  213.     case WM_INITDIALOG:
  214.     return(TRUE);
  215.     break;
  216.     }
  217.  
  218. return(FALSE);
  219. }
  220.  
  221.  
  222. /*
  223.  * SortMain
  224.  *
  225.  * This function is equivalent to the main function of QSORT.C
  226.  *
  227.  */
  228.  
  229. void SortMain (char * szIn, char * szOut, HANDLE hWnd)
  230. {
  231.     int NumWords;
  232.     int index;
  233.     HWND    hWndDlg;
  234.     FARPROC lpfnDlgProc;
  235.  
  236.     /* loading the file */
  237.     hWndDlg = NULL;
  238.     lpfnDlgProc = MakeProcInstance((FARPROC) StubDlgProc, rClass.hInstance);
  239.     if(lpfnDlgProc) {
  240.  
  241.     /* Ask for the input and output files */
  242.     hWndDlg = CreateDialog(rClass.hInstance,
  243.             "LOADING",
  244.             hWnd,
  245.             lpfnDlgProc);
  246.     }
  247.  
  248.     NumWords = GetWords( szIn );
  249.  
  250.     /* end load */
  251.     if(hWndDlg)
  252.     DestroyWindow(hWndDlg);
  253.     if(lpfnDlgProc)
  254.     FreeProcInstance(lpfnDlgProc);
  255.  
  256.     /* Initialize WordIndex array */
  257.     for ( index = 0; index < NumWords; index++ )
  258.     WordIndex[index] = index;
  259.     if ( NumWords > 0 )
  260.     {
  261.     /* sorting the file */
  262.     hWndDlg = NULL;
  263.     lpfnDlgProc = MakeProcInstance((FARPROC) StubDlgProc, rClass.hInstance);
  264.     if(lpfnDlgProc) {
  265.  
  266.         /* Ask for the input and output files */
  267.         hWndDlg = CreateDialog(rClass.hInstance,
  268.             "SORTING",
  269.             hWnd,
  270.             lpfnDlgProc);
  271.         }
  272.  
  273.     QuickSort( 0, NumWords-1 );
  274.     OutWords( NumWords, szOut );
  275.  
  276.     /* end sort */
  277.     if(hWndDlg)
  278.         DestroyWindow(hWndDlg);
  279.     if(lpfnDlgProc)
  280.         FreeProcInstance(lpfnDlgProc);
  281.     }
  282. }
  283.  
  284. /* GetWords - GetWords loads and parses an ASCII text file and stores each
  285.  * word into WordArray. Returns the number of words read.
  286.  */
  287. int GetWords(char *filename)
  288. {
  289.     FILE    *FileHandle;
  290.     int     WordNumber = 0;
  291.     int     CharNumber = 0;
  292.     char    TempChar   = '\0';
  293.  
  294.     FileHandle = fopen(filename, "r");
  295.     if (FileHandle == NULL)
  296.     {
  297.     MessageBox(hWnd1, (char far *) "Error opening input file.",
  298.               (char far *) "Error", MB_ICONSTOP | MB_OK);
  299.     return 0;
  300.     }
  301.  
  302.     while ((WordNumber < MAXNUMWORDS) && (TempChar != EOF))
  303.     {
  304.     TempChar = fgetc(FileHandle);
  305.     switch(TempChar)
  306.     {
  307.         /* Word delimiters */
  308.         case ' ' :
  309.         case '\n':
  310.         case '\t':
  311.         /* Start new word unless at beginning */
  312.         if (CharNumber != 0)
  313.         {
  314.             WordArray[WordNumber][CharNumber] = '\0';
  315.             CharNumber = 0;
  316.             WordNumber++;
  317.         }
  318.         break;
  319.         /* Quit if at end of file */
  320.         case EOF:
  321.         break;
  322.         /* Characters to add to word */
  323.         default:
  324.         WordArray[WordNumber][CharNumber] = TempChar;
  325.         /* Truncate word if too long */
  326.         if (++CharNumber >= MAXWORDSIZE)
  327.         {
  328.             WordArray[WordNumber][CharNumber-1] = '\0';
  329.             CharNumber = 0;
  330.             WordNumber++;
  331.             /* Skip over remaining characters */
  332.             while ((TempChar != ' ') && (TempChar != '\n') &&
  333.                (TempChar != '\t'))
  334.              TempChar = fgetc(FileHandle);
  335.         }
  336.         break;
  337.     }
  338.     }
  339.     fclose( FileHandle );
  340.     return  WordNumber;
  341. }
  342.  
  343. /* QuickSort - QuickSort works by picking a random "pivot" element,
  344.  * then moving every element that is bigger to one side of the pivot,
  345.  * and every element that is smaller to the other side. QuickSort is
  346.  * then called recursively with the two subdivisions created by the pivot.
  347.  * Once the number of elements in a subdivision reaches two, the recursive
  348.  * calls end and the array is sorted.
  349.  */
  350. void QuickSort( int iLow, int iHigh )
  351. {
  352.     int iUp, iDown;
  353.  
  354.     char cBreak[MAXWORDSIZE];
  355.  
  356.     if( iLow < iHigh )
  357.     {
  358.     /* Only two elements in this subdivision; swap them if they are
  359.      * out of order, then end recursive calls.
  360.      */
  361.     if( (iHigh - iLow) == 1 )
  362.     {
  363.         if( stricmp( WordArray[WordIndex[iLow]], WordArray[WordIndex[iHigh]] ) > 0 )
  364.         SwapWords( iLow, iHigh );
  365.     }
  366.     else
  367.     {
  368.         /* Pick a pivot element at random, then move it to the end. */
  369.         SwapWords( iHigh, getrandom( iLow, iHigh ) );
  370.         strcpy( cBreak, WordArray[WordIndex[iHigh]] );
  371.         do
  372.         {
  373.         /* Move in from both sides towards the pivot element. */
  374.         iUp = iLow;
  375.         iDown = iHigh;
  376.         while( (iUp < iDown) &&
  377.                (stricmp( WordArray[WordIndex[iUp]], cBreak ) <= 0) )
  378.             iUp++;
  379.         while( (iDown > iUp) &&
  380.                (stricmp( WordArray[WordIndex[iDown]], cBreak ) >= 0) )
  381.             iDown--;
  382.         /* If we haven't reached the pivot, it means that two
  383.          * elements on either side are out of order, so swap them.
  384.          */
  385.         if( iUp < iDown )
  386.             SwapWords( iUp, iDown );
  387.         } while ( iUp < iDown );
  388.  
  389.         /* Move pivot element back to its proper place in the array. */
  390.         SwapWords( iUp, iHigh );
  391.  
  392.         /* Recursively call the QuickSort procedure (pass the smaller
  393.          * subdivision first to use less stack space).
  394.          */
  395.         if( (iUp - iLow) < (iHigh - iUp) )
  396.         {
  397.         QuickSort( iLow, iUp - 1 );
  398.         QuickSort( iUp + 1, iHigh );
  399.         }
  400.         else
  401.         {
  402.         QuickSort( iUp + 1, iHigh );
  403.         QuickSort( iLow, iUp - 1 );
  404.         }
  405.     }
  406.     }
  407. }
  408.  
  409.  
  410. /* SwapWords - SwapWords swaps the WordIndex index values of two words,
  411.  * thereby swapping the indexed positions of the words.
  412.  */
  413. void SwapWords( int index1, int index2 )
  414. {
  415.     int     TempIndex;
  416.     TempIndex = WordIndex[index1];
  417.     WordIndex[index1] = WordIndex[index2];
  418.     WordIndex[index2] = TempIndex;
  419. }
  420.  
  421. /* OutWords - OutWords writes the sorted array of words to a file.
  422.  */
  423. void OutWords(int NumWords, char *filename)
  424. {
  425.     FILE *FileHandle;
  426.     int TempIndex;
  427.     FileHandle = fopen(filename, "w");
  428.     if (FileHandle == NULL)
  429.     {
  430.     MessageBox(hWnd1, (char far *) "Error opening output file.",
  431.               (char far *) "Error", MB_ICONSTOP | MB_OK);
  432.     return;
  433.     }
  434.     for (TempIndex=0; TempIndex < NumWords; TempIndex++ )
  435.     if ( fputs( WordArray[WordIndex[TempIndex]], FileHandle ) == EOF)
  436.     {
  437.         MessageBox(hWnd1, (char far *) "Error writing output file.",
  438.               (char far *) "Error", MB_ICONSTOP | MB_OK);
  439.         break;
  440.     }
  441.     else
  442.         fputs( "\n", FileHandle );
  443.     fclose( FileHandle );
  444. }
  445.