Annotation of mstools/samples/ddeml/ddeprog/proghelp.c, revision 1.1.1.2

1.1       root        1: /*****************************************************************************\
                      2: * PROGHELP.C
                      3: *
                      4: * Main module to implement a simple DDEML service DLL that makes interaction
                      5: * with progman simple.
                      6: \*****************************************************************************/
                      7: 
                      8: #include <windows.h>
                      9: #include <ddeml.h>
                     10: #include <string.h>
                     11: 
                     12: typedef struct {
                     13:     HCONV hConv;
                     14:     DWORD idInst;
                     15: } THREADINFO;
                     16: 
                     17: DWORD TlsIndex;
                     18: 
                     19: /*
                     20:  * This is the default DDEML callback function for ProgHelp
                     21:  */
                     22: HDDEDATA CALLBACK ProgHelpDdeCallback(
                     23: UINT wType,
                     24: UINT wFmt,
                     25: HCONV hConv,
                     26: HSZ hsz1,
                     27: HSZ hsz2,
                     28: HDDEDATA hData,
                     29: DWORD dwData1,
                     30: DWORD dwData2)
                     31: {
                     32:     return(0);
                     33: }
                     34: 
                     35: 
                     36: /*
                     37:  * This is the DLL init routine called by the system at attach/detatch time.
                     38:  *
                     39:  * We allocate a Tls for each thread that calls this DLL so that their state
                     40:  * can be tracked independently.
                     41:  */
                     42: BOOLEAN APIENTRY ProgHelpInit(
                     43: IN PVOID hmod,
                     44: ULONG Reason,
                     45: IN PCONTEXT pctx OPTIONAL)
                     46: {
                     47:     THREADINFO *pti;
                     48:     UNREFERENCED_PARAMETER(hmod);
                     49:     UNREFERENCED_PARAMETER(pctx);
                     50: 
                     51:     switch (Reason) {
                     52:     case DLL_PROCESS_ATTACH:
                     53:         TlsIndex = TlsAlloc();
1.1.1.2 ! root       54: 
        !            55:     case DLL_THREAD_ATTACH:
1.1       root       56:         pti = (THREADINFO *)LocalAlloc(LPTR, sizeof(THREADINFO));
                     57:         if (!pti) {
                     58:             return(FALSE);
                     59:         }
                     60:         TlsSetValue(TlsIndex, pti);
                     61:         break;
                     62: 
                     63:     case DLL_THREAD_DETACH:
                     64:     case DLL_PROCESS_DETACH:
                     65:         pti = TlsGetValue(TlsIndex);
                     66:         LocalFree(pti);
1.1.1.2 ! root       67:         if (Reason == DLL_PROCESS_DETACH) {
        !            68:             TlsFree(TlsIndex);
        !            69:         }
1.1       root       70:         break;
                     71:     }
                     72:     return TRUE;
                     73: }
                     74: 
                     75: /*
                     76:  * An application must call this API first to establish a conversation
                     77:  * with progman.  DDEML initialization is done automatically if needed.
                     78:  */
                     79: BOOL ConnectToProgman()
                     80: {
                     81:     THREADINFO *pti;
                     82:     HSZ hszProgman;
                     83: 
                     84:     pti = TlsGetValue(TlsIndex);
                     85: 
                     86:     if (!pti->idInst) {
                     87:         if (DdeInitialize(&(pti->idInst), ProgHelpDdeCallback,
                     88:                 APPCMD_CLIENTONLY | CBF_SKIP_ALLNOTIFICATIONS,
                     89:                 0L) != DMLERR_NO_ERROR) {
                     90:             return(FALSE);
                     91:         }
                     92:     }
                     93: 
                     94:     if (pti->hConv == 0) {
                     95:         hszProgman = DdeCreateStringHandle(pti->idInst, "Progman", 0);
                     96:         pti->hConv = DdeConnect(pti->idInst, hszProgman, hszProgman, NULL);
                     97:     }
                     98:     return(pti->hConv != 0);
                     99: }
                    100: 
                    101: /*
                    102:  * This API should be called when operations with progman are complete.
                    103:  * We shutdown DDEML here as well so we don't have to deal with it
1.1.1.2 ! root      104:  * at DLL detatch time.
1.1       root      105:  */
                    106: BOOL DisconnectFromProgman()
                    107: {
                    108:     THREADINFO *pti;
                    109: 
                    110:     pti = TlsGetValue(TlsIndex);
                    111: 
                    112:     if (!pti->idInst) {
                    113:         return(TRUE);
                    114:     }
                    115: 
                    116:     if (pti->hConv) {
                    117:         DdeDisconnect(pti->hConv);
                    118:         pti->hConv = 0;
                    119:     }
                    120: 
                    121:     DdeUninitialize(pti->idInst);
1.1.1.2 ! root      122:     pti->idInst = 0;
1.1       root      123:     return(TRUE);
                    124: }
                    125: 
                    126: 
                    127: /*
                    128:  * This API sends an ASCII execute string to progman.  It immediately returns
                    129:  * and the results of the execute are not known.  Calling applications should
                    130:  * be aware that these transactions are done asynchronously.  This allows
                    131:  * this API to work under modal-loop conditions.  DisconnectFromProgman()
                    132:  * will not succeed until all transactions are complete.
                    133:  */
                    134: BOOL ProgmanExecuteString(
                    135: LPCSTR pszExec)
                    136: {
                    137:     THREADINFO *pti;
                    138:     DWORD dwResult;
                    139: 
                    140:     pti = TlsGetValue(TlsIndex);
                    141: 
                    142:     if (!pti->idInst || !pti->hConv) {
                    143:         return(FALSE);
                    144:     }
                    145:     if (!DdeClientTransaction((PBYTE)pszExec, strlen(pszExec) + 1,
                    146:             pti->hConv, 0, 0, XTYP_EXECUTE, TIMEOUT_ASYNC, &dwResult)) {
                    147:         return(FALSE);
                    148:     }
                    149:     return(TRUE);
                    150: }
                    151: 
                    152: 
                    153: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.