home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / winbase / ipc / ddeml / ddeinst / ddeinst.c < prev    next >
C/C++ Source or Header  |  1997-10-05  |  11KB  |  391 lines

  1.  
  2. /******************************************************************************\
  3. *       This is a part of the Microsoft Source Code Samples. 
  4. *       Copyright (C) 1993-1997 Microsoft Corporation.
  5. *       All rights reserved. 
  6. *       This source code is only intended as a supplement to 
  7. *       Microsoft Development Tools and/or WinHelp documentation.
  8. *       See these sources for detailed information regarding the 
  9. *       Microsoft samples programs.
  10. \******************************************************************************/
  11.  
  12. /*
  13.    ddeinst.c
  14. */
  15.  
  16. #include <windows.h>
  17. #include "ddeinst.h"
  18. #include "ddextrn.h"
  19.  
  20. #include <stdio.h>
  21. #include <string.h>
  22.  
  23. extern CONVCONTEXT CCFilter;
  24.  
  25. /********************************************************************
  26.  
  27.    StartTraverseThread
  28.  
  29.    Function that starts thread to traverse the specified directory.
  30.  
  31. ********************************************************************/
  32. BOOL StartTraverseThread (LPSTR lpArg) {
  33.    HANDLE   hThread;
  34.    LONG     lThreadId;
  35.  
  36.    hThread = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) TraversePath,
  37.       lpArg, CREATE_SUSPENDED | STANDARD_RIGHTS_REQUIRED, &lThreadId);
  38.    if (hThread) {
  39.       // SetThreadPriority (hThread, THREAD_PRIORITY_BELOW_NORMAL);
  40.       ResumeThread(hThread);
  41.  
  42. /* Close the handle since we don't need it anymore */
  43.  
  44.       CloseHandle (hThread);
  45.       return (TRUE);
  46.    }/*endIf*/
  47.    return (FALSE);
  48. }/* end StartTraverseThread */
  49.  
  50.  
  51. int   iRecurse = 0;
  52.  
  53. /********************************************************************
  54.  
  55.    TraversePath
  56.  
  57.    Function that recursively descends a specified directory looking
  58.    for files that have the .exe extension.
  59.  
  60. ********************************************************************/
  61.  
  62. BOOL TraversePath (LPSTR szPath) {
  63.    HANDLE            hSearch;
  64.    WIN32_FIND_DATA   findData;
  65.    LPSTR             szTemp;
  66.    LPSTR             szNewPath;
  67.    LPSTR             szTempName;
  68.    LPSTR             szFullPath;
  69.    int               iLen;
  70.    long              lError;
  71.    long              lPos;
  72.    long              lTemp;
  73.    long              lNewPath;
  74.  
  75. // If there is no path then we need to exit.
  76.    if (!szPath || (strlen (szPath) > (MAX_PATH - 5))) {
  77.       return (FALSE);
  78.    }/*endIf*/
  79.  
  80. // Increment the recursion level.
  81.    iRecurse++;
  82.  
  83. // Get the length of the path plus room for the wildcard and nul.
  84.    lTemp = strlen (szPath) + 5;
  85.  
  86. // allocate some memory
  87.    szTemp = VirtualAlloc (NULL, lTemp, MEM_COMMIT, PAGE_READWRITE);
  88.  
  89. // Append the wildcard
  90.    sprintf (szTemp, "%s\\*.*", szPath);
  91.  
  92. // Look for a file
  93.    hSearch = FindFirstFile (szTemp, &findData);
  94.  
  95. // If nothing found then return.
  96.    if (!hSearch || hSearch == (HANDLE) -1) {
  97.       VirtualFree (szTemp, lTemp, MEM_DECOMMIT);
  98.       iRecurse--;
  99.       return (FALSE);
  100.    }/*endIf*/
  101.  
  102. // Loop through the current directory looking for exectuables.
  103.    do {
  104.       if (strcmp (findData.cFileName, ".") &&
  105.             strcmp (findData.cFileName, "..")) {
  106.  
  107.       // Ignore '.' and '..'
  108.          if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
  109.  
  110.          // If it is a directory then recurse.
  111.  
  112.             lNewPath = strlen (szPath) + strlen (findData.cFileName) + 1;
  113.             szNewPath = VirtualAlloc (NULL, lNewPath, MEM_COMMIT,
  114.                   PAGE_READWRITE);
  115.             sprintf (szNewPath, "%s\\%s", szPath, findData.cFileName);
  116.             TraversePath (szNewPath);
  117.             VirtualFree (szNewPath, lNewPath, MEM_DECOMMIT);
  118.          } else {
  119.  
  120.          // See if it ends in .exe
  121.  
  122.             iLen = strlen (findData.cFileName) - 4;
  123.             szTempName = findData.cFileName + iLen;
  124.             if (!strnicmp (szTempName, ".exe", 4)) {
  125.  
  126.             // Add the file name to the list of files.
  127.  
  128.                if (!(lPos = SendMessage (hwndFileList, LB_ADDSTRING,
  129.                   (WPARAM) NULL, (LPARAM) findData.cFileName))) {
  130.  
  131.                // Debugging code
  132.  
  133.                   lError = GetLastError ();
  134.                }/*endIf*/
  135.                szTempName = VirtualAlloc (NULL, iLen + 4, MEM_COMMIT,
  136.                      PAGE_READWRITE);
  137.                strncpy (szTempName, findData.cFileName, iLen);
  138.  
  139.             // Add the constructed file name to the list of names
  140.  
  141.                SendMessage (hwndFileList2, LB_INSERTSTRING, (WPARAM) lPos,
  142.                      (LPARAM) szTempName);
  143.                VirtualFree (szTempName, iLen + 4, MEM_DECOMMIT);
  144.                iLen = strlen (szPath) + iLen + 4;
  145.  
  146.             // Construct a full pathname to the file.
  147.  
  148.                szFullPath = VirtualAlloc (NULL, iLen, MEM_COMMIT,
  149.                      PAGE_READWRITE);
  150.                sprintf (szFullPath, "%s\\%s", szPath, findData.cFileName);
  151.  
  152.             // Add the full path to the hidden list.
  153.  
  154.                SendMessage (hwndPathList, LB_INSERTSTRING, (WPARAM) lPos,
  155.                      (LPARAM) szFullPath);
  156.                VirtualFree (szFullPath, iLen, MEM_DECOMMIT);
  157.             }/*endIf*/
  158.          }/*endIf*/
  159.       }/*endIf*/
  160.  
  161.    // Keep looping until no more files.
  162.  
  163.    } while (FindNextFile (hSearch, &findData));
  164.  
  165. // End the search.
  166.  
  167.    FindClose (hSearch);
  168.    VirtualFree (szTemp, lTemp, MEM_DECOMMIT);
  169.  
  170. // Decrement the recursion count.
  171.  
  172.    iRecurse--;
  173.    if (!iRecurse) {
  174.  
  175.    // If recursion count == 0 then we are done so inform the primary thread.
  176.  
  177.       PostMessage (ghwndMain, WM_USER_THREAD_DONE, 0, 0L);
  178.    }/*endIf*/
  179.    return (TRUE);
  180. }/* end TraversePath */
  181.  
  182. /********************************************************************
  183.  
  184.    StartGroupRetrievalThread
  185.  
  186.    Function that starts thread to retrieve the names of existing groups
  187.    from the Program Manager.
  188.  
  189. ********************************************************************/
  190.  
  191.  
  192. BOOL StartGroupRetrievalThread () {
  193.    HANDLE   hThread;
  194.    LONG     lThreadId;
  195.  
  196.    hThread = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) GroupRetrieval,
  197.       "test", CREATE_SUSPENDED | STANDARD_RIGHTS_REQUIRED, &lThreadId);
  198.    if (hThread) {
  199.       SetThreadPriority (hThread, THREAD_PRIORITY_BELOW_NORMAL);
  200.       ResumeThread (hThread);
  201.  
  202. /* Close the handle since we don't need it anymore */
  203.  
  204.       CloseHandle (hThread);
  205.       return (TRUE);
  206.    }/*endIf*/
  207.    return (FALSE);
  208. }/* end StartGroupRetrievalThread */
  209.  
  210.  
  211. // Prototype for DDECallback function.
  212. HDDEDATA CALLBACK GroupDDECallback (UINT, UINT, HANDLE, HSZ, HSZ, HDDEDATA,
  213.       LONG, LONG);
  214.  
  215.  
  216. /********************************************************************
  217.  
  218.    GroupRetrieval
  219.    Function to obtain the names of all of the defined program groups in
  220.    the Program Manager.
  221.  
  222. ********************************************************************/
  223.  
  224. BOOL GroupRetrieval (LPSTR lpDummy) {
  225.    LPBYTE     lpByte;
  226.    LPSTR      szGroups;
  227.    LPSTR      szToken;
  228.    LPSTR      szMem;
  229.    LPSTR      szToken2;
  230.    long       lResult;
  231.    LONG       lIdLocal;
  232.    CRITICAL_SECTION lpCritical;
  233.    HCONV      hConv;
  234.    HDDEDATA   hDdeData;
  235.    HSZ        szProgMan;
  236.    HSZ        szTopic;
  237.  
  238.  
  239. // Initialize the Dde id to 0
  240.  
  241.    lIdLocal = 0L;
  242.    szGroups = NULL;
  243.  
  244. // Attempt to initialize a conversation.
  245.  
  246.    if (DdeInitialize (&lIdLocal, (PFNCALLBACK) GroupDDECallback,
  247.          (DWORD) APPCMD_CLIENTONLY, 0L)) { 
  248.       return (FALSE);
  249.    }/*endIf*/
  250.  
  251. // Start a critical section. This fixes a problem where the DDEML
  252. // Can hang under threaded conditions.
  253.  
  254.    InitializeCriticalSection (&lpCritical);
  255.    EnterCriticalSection (&lpCritical);
  256.  
  257. // Create a string handle for the Dde conversation.
  258.  
  259.    szProgMan = DdeCreateStringHandle (lIdLocal, "PROGMAN", CP_WINANSI);
  260.    
  261. // Connect to the program manager.
  262.  
  263.    hConv = DdeConnect (lIdLocal, szProgMan, szProgMan, &CCFilter);
  264.  
  265.    PostMessage (hwndStatus, WM_USER_UPDATE_STATUS, 0, ID_DDEML_CONNECT);
  266.  
  267. // Create a handle for the Group topic.
  268.  
  269.    szTopic = DdeCreateStringHandle (lIdLocal, "Groups", CP_WINANSI);
  270.  
  271. // Execute a request for the group names.
  272.  
  273.    hDdeData = DdeClientTransaction (NULL, 0L, hConv, szTopic, CF_TEXT,
  274.          XTYP_REQUEST, 1000, &lResult);
  275.  
  276.    PostMessage (hwndStatus, WM_USER_UPDATE_STATUS, 0, ID_DDEML_RETRIEVING);
  277. // Release the two string handles.
  278.  
  279.    DdeFreeStringHandle (lIdLocal, szProgMan);
  280.    DdeFreeStringHandle (lIdLocal, szTopic);
  281.  
  282. // Disconnect the conversation.
  283.  
  284.    DdeDisconnect (hConv);
  285.  
  286.    PostMessage (hwndStatus, WM_USER_UPDATE_STATUS, 0, ID_DDEML_COMPLETE);
  287.  
  288. // Exit and delete the critical section.
  289.  
  290.    LeaveCriticalSection (&lpCritical);
  291.    DeleteCriticalSection (&lpCritical);
  292.  
  293. // Verify that we got something back.
  294.  
  295.    if (hDdeData && (hDdeData != (HDDEDATA) TRUE)) {
  296.  
  297.    // Access the data to get a character pointer.
  298.  
  299.       lpByte = DdeAccessData (hDdeData, &lResult);
  300.  
  301.    // allocate a block of memory to use.
  302.  
  303.       szGroups = szMem = VirtualAlloc (NULL, lResult, MEM_COMMIT,
  304.          PAGE_READWRITE);
  305.       if (!szMem) {
  306.          lResult = GetLastError ();
  307.       } else {
  308.  
  309.       // Copy the Dde data to our own block.
  310.  
  311.          memcpy (szGroups, lpByte, lResult);
  312.       }/*endIf*/
  313.  
  314.    // Free the Dde data that is there. This is our responsibility.
  315.  
  316.       DdeUnaccessData (hDdeData);
  317.       DdeFreeDataHandle (hDdeData);
  318.    }/*endIf*/
  319.  
  320. // If we have a memory block then parse it.
  321.  
  322.    if (szMem != NULL) {
  323.  
  324.    // Search for 'cr'.
  325.  
  326.       szToken = strtok (szGroups, "\n");
  327.  
  328.    // While we have a token use it.
  329.  
  330.       while (szToken) {
  331.  
  332.       // We have to strip out line feeds.
  333.  
  334.          if (szToken2 = strrchr (szToken, 0x0d)) {
  335.             *szToken2 = '\0';
  336.          }/*endIf*/
  337.       
  338.       // Add the resulting string to the combo box of groups.
  339.  
  340.          SendMessage (hwndCombo, CB_ADDSTRING, (WPARAM) 0, (LPARAM) szToken);
  341.  
  342.       // Find the next 'cr'.
  343.  
  344.          szToken = strtok (NULL, "\n");
  345.       }/*endWhile*/
  346.  
  347.    // Release the memory block.
  348.  
  349.       VirtualFree (szMem, lResult, MEM_DECOMMIT);
  350.    }/*endIf*/
  351.  
  352. // If there is a default name defined then use it. And enable the AddGroup
  353. // Button.
  354.  
  355.    if (strlen (szUserGroup)) {
  356.       SetWindowText (hwndCombo, szUserGroup);
  357.       EnableWindow (hwndAddGroupButton, TRUE);
  358.    } else {
  359.  
  360.    // There is no default group so disable the button.
  361.  
  362.       EnableWindow (hwndAddGroupButton, FALSE);
  363.    }/*endIf*/
  364.  
  365. // Release the DDEML.
  366.  
  367.    DdeUninitialize (lIdLocal);
  368.  
  369. // Inform the primary thread that the group retrieval is completed.
  370.  
  371.    PostMessage (ghwndMain, WM_USER_THREAD_DONE, 0, 0L);
  372.    return (TRUE);
  373. }/* end GroupRetrieval */
  374.  
  375.  
  376. /********************************************************************
  377.  
  378.    GroupDDECallback.
  379.    
  380.    Function exists for compatibility. Does nothing.
  381.  
  382. ********************************************************************/
  383.  
  384. HDDEDATA CALLBACK GroupDDECallback (UINT uiType, UINT uiFmt, HANDLE hConv,
  385.       HSZ sz1, HSZ sz2, HDDEDATA hData, LONG lData1, LONG lData2) {
  386.    switch (uiType) {
  387.  
  388.    }/*endSwitch*/
  389.    return ((HDDEDATA) NULL);
  390. }/* end GroupDDECallback */
  391.