home *** CD-ROM | disk | FTP | other *** search
/ Boston 2 / boston-2.iso / DOS / PROGRAM / C / INST / PROGDDE.C < prev    next >
C/C++ Source or Header  |  1993-12-01  |  15KB  |  587 lines

  1. /*----------------------------------------------------------------------------*\
  2. |   progdde.c - Use DDE to add groups to Program Manager
  3. \*----------------------------------------------------------------------------*/
  4.  
  5. #include "lobotomy.h"
  6. #include <windows.h>
  7.  
  8. #include "sulib.h"
  9. #include "..\install.h"
  10. #include "ws.h"
  11. #include "progdde.h"
  12. #include "gauge.h"
  13. #include <dde.h>
  14.  
  15. #ifdef DEBUG
  16. BOOL fDebug = TRUE;
  17. #endif
  18.  
  19. BOOL    bBuildGroups = FALSE;
  20.  
  21. BOOL PRIVATE WriteString(int fh, PSTR sz);
  22.  
  23. char szCreateCmd[] = "[creategroup(%s)]";
  24.  
  25. typedef struct {
  26.     GROUPDEF    gd;
  27.     int         fh;
  28. }   GRP;
  29.  
  30. typedef GRP *PGRP;
  31.  
  32. char    szProgman[]    = "PROGMAN";
  33. HWND    hwndDDE        = NULL;
  34. HWND    hwndServer    = NULL;  // Currently active DDE conversation
  35. BOOL    fInitiate    = FALSE;
  36. BOOL    fAck        = FALSE;
  37. HWND    hWndProgman    = NULL;        // global handel of progman window
  38.  
  39.  
  40. BOOL PRIVATE ddeExec(HWND hwnd, LPSTR szCmd);
  41. BOOL PRIVATE ddeWait(HWND hwnd);
  42. HWND PRIVATE ddeSendInitiate(ATOM aApp, ATOM aTopic);
  43. BOOL PRIVATE ddeTerminate (HWND hwnd);
  44.  
  45. long EXPORT ddeWndProc(HWND hwnd, unsigned uiMessage, WORD wParam, long lParam);
  46.  
  47. BOOL PRIVATE ddeTerminate (HWND hwnd)
  48. {
  49.     PostMessage (hwnd,WM_DDE_TERMINATE,hwndDDE,0L);
  50.     if (hwnd == hwndServer)
  51.        hwndServer = NULL;
  52.     return TRUE;
  53. }
  54.  
  55. // build the progman groups
  56.  
  57. BOOL PUBLIC wsProgman(HWND hwnd)
  58. {
  59.     PINF     pinf, pinfGroup;
  60.     char     szName[MAXSTR];
  61.     char     szGroupName[MAXSTR];
  62.     char     szExe[MAXSTR];
  63.     char     szPath[MAXSTR];
  64.     char     buf[MAXSTR];
  65.         char     bufTmp[MAXSTR];
  66.     int      iIcon;
  67.     int     root_len;
  68.     int     fh;
  69.     int     num_groups;
  70.  
  71.  
  72.     SetProgmanSize();
  73.  
  74.     pinf = infFindSection(NULL,wsLoadSz(IDS_PROGMAN_GROUP,NULL));
  75.  
  76.     WinAssert(pinf);
  77.  
  78.     if (!pinf)
  79.             return FALSE;
  80.  
  81. #ifdef DEBUG
  82.     if (fDontCopy) {
  83.        if (!bBuildGroups) {
  84.           return TRUE;
  85.        }
  86.     }
  87. #endif
  88.  
  89.     ProOpen(hwnd, NULL);
  90.  
  91.         LoadString(hInstWS, IDS_BUILDPMG, bufTmp, MAXSTR);
  92.         ProPrintf(ID_STATUS1, bufTmp);
  93.  
  94.     num_groups = infLineCount(pinf);
  95.  
  96.     ProSetBarRange(num_groups);
  97.  
  98.     // first build all the groups.
  99.  
  100.         while (pinf) {
  101.  
  102.         /* get group name and file name */
  103.         infParseField(pinf, 1, szGroupName);
  104.  
  105.         dprintf(" Group:%s\n", szGroupName);
  106.  
  107.         ProPrintf(ID_STATUS2, szGroupName);
  108.  
  109.         // open, delete contents
  110.  
  111.         if (fmOpen(szGroupName, TRUE)) {
  112.  
  113.             for (pinfGroup = infFindSection(NULL, szGroupName); pinfGroup; pinfGroup = infNextLine(pinfGroup)) {
  114.  
  115.                 *szExe = 0;
  116.  
  117.                 // get optional icon source file
  118.  
  119.                 infParseField(pinfGroup, 3, szExe);
  120.  
  121.                 // get optional icon index #
  122.  
  123.                 if (infParseField(pinfGroup, 4, buf))
  124.                     iIcon = (int)atoi(buf);    // convert to int
  125.                 else
  126.                     iIcon = 0;        // default icon index
  127.  
  128.                 infParseField(pinfGroup, 1, szName);
  129.                 infParseField(pinfGroup, 2, buf);
  130.  
  131.  
  132.                 GenerateProgmanPath(buf, szPath);
  133.  
  134.                 dprintf(" Item:%s %s %s %d\n", szName, szPath, szExe, iIcon);
  135.  
  136.                 ProPrintf(ID_STATUS3, szName);
  137.  
  138.                 fmAddItem(szName, szPath, *szExe ? (PSTR)szExe : (PSTR)NULL, iIcon);
  139.             }
  140.  
  141.         }
  142.  
  143.         pinf = infNextLine(pinf);
  144.  
  145.         ProDeltaPos(1);
  146.     }
  147.  
  148.     // now run through the groups again and minimize everthing
  149.     // this does not have a second field (non minimize flag)
  150.  
  151.     pinf = infFindSection(NULL,wsLoadSz(IDS_PROGMAN_GROUP,NULL));
  152.  
  153.         while (pinf) {
  154.  
  155.         /* get group name and file name */
  156.         infParseField(pinf, 1, szGroupName);
  157.  
  158.         if (!infParseField(pinf, 2, buf) || *buf == 0)
  159.             fmMinimize(szGroupName);
  160.  
  161.         pinf = infNextLine(pinf);
  162.     }
  163.  
  164.     ActivateMain();
  165.  
  166.     fmClose();
  167.  
  168.     dprintf("Progman has been closed\n");
  169.  
  170.     ProClose();
  171.  
  172. }
  173.  
  174. void PRIVATE SetProgmanSize()
  175. {
  176.     HDC hdc;
  177.     int x1, y1, x2, y2;
  178.     int xScreen, yScreen;
  179.     char    buf[MAXSTR];
  180.  
  181.     #define MARGIN_SIZE(x)    ((x) / 10)
  182.  
  183.     hdc = GetDC(NULL);
  184.     xScreen = GetDeviceCaps(hdc, HORZRES);
  185.     yScreen = GetDeviceCaps(hdc, VERTRES);
  186.     ReleaseDC(NULL, hdc);
  187.  
  188.     x1 = MARGIN_SIZE(xScreen);
  189.     y1 = MARGIN_SIZE(yScreen);
  190.  
  191.     x2 = xScreen - MARGIN_SIZE(xScreen);
  192.     y2 = yScreen - 2*MARGIN_SIZE(yScreen);
  193.  
  194.     wsprintf(buf, "%d %d %d %d 1", x1, y1, x2, y2);
  195.  
  196.     WritePrivateProfileString("Settings", "Window", buf, "progman.ini");
  197. }
  198.  
  199. void PUBLIC ActivateMain()
  200. {
  201.     char    szGroupName[MAXSTR];
  202.     char    buf[MAXSTR];
  203.     PINF    pinf;
  204.  
  205.     dprintf("ActivateMain()\n");
  206.  
  207.     // now activate the groups that weren't minimized
  208.  
  209.     pinf = infFindSection(NULL,wsLoadSz(IDS_PROGMAN_GROUP,NULL));
  210.  
  211.         while (pinf) {
  212.  
  213.         infParseField(pinf, 1, szGroupName);
  214.  
  215.         if (infParseField(pinf, 2, buf)) {
  216.             fmActivate(szGroupName);
  217.             break;
  218.         }
  219.  
  220.         pinf = infNextLine(pinf);
  221.     }
  222. }
  223.  
  224. /****************************************************************************
  225.  * generate an exe name for a progman item
  226.  *
  227.  * if on the path do not fully qualify
  228.  * if not on the path fully qualify
  229.  * if this is command.com use COMSPEC var first
  230.  *
  231.  ***************************************************************************/
  232.  
  233. void PUBLIC GenerateProgmanPath(PSTR filename, PSTR szPath)
  234. {
  235.     LPSTR lp;
  236.     PSTR lpname;
  237.     OFSTRUCT os;
  238.  
  239.     lpname = FileName(filename);
  240.  
  241.     // if we can open the unqualified file name then we know
  242.     // it is on the path or in the windows directory.  In that
  243.     // case don't fully qualify the path name.
  244.  
  245.     if (OpenFile(lpname, &os, OF_EXIST) != -1) {
  246.         lstrcpy(szPath, lpname);    // non fully qualified file name
  247.         return;
  248.     }
  249.         else {
  250.        lstrcpy(szPath,szSetupPath);    // use fully qualified name
  251.            lstrcat(szPath,"\\");
  252.            lstrcat(szPath,lpname);
  253.         }
  254. }
  255.  
  256. LONG PUBLIC atoi(PSTR sz)
  257. {
  258.     LONG n = 0;
  259.  
  260.     while (ISDIGIT(*sz))
  261.     {
  262.     n *= 10;
  263.     n += *sz - '0';
  264.     sz++;
  265.     }
  266.     return n;
  267. }
  268.  
  269. /*----------------------------------------------------------------------------*\
  270. |   ddeInit (hInst, hPrev)                               |
  271. |                                                                              |
  272. |   Description:                                                               |
  273. |       This is called when the application is first loaded into               |
  274. |       memory.  It performs all initialization that doesn't need to be done   |
  275. |       once per instance.                                                     |
  276. |                                                                              |
  277. |   Arguments:                                                                 |
  278. |    hPrev    instance handle of previous instance                   |
  279. |    hInst    instance handle of current instance                   |
  280. |                                                                              |
  281. |   Returns:                                                                   |
  282. |       TRUE if successful, FALSE if not                                       |
  283. |                                                                              |
  284. \*----------------------------------------------------------------------------*/
  285. BOOL PUBLIC ddeInit(HANDLE hInst, HANDLE hPrev)
  286. {
  287.     WNDCLASS rClass;
  288.     if (!hPrev) {
  289.        rClass.hCursor         = NULL;
  290.        rClass.hIcon         = NULL;
  291.        rClass.lpszMenuName   = NULL;
  292.        rClass.lpszClassName  = "ddeClass";
  293.        rClass.hbrBackground  = NULL;
  294.        rClass.hInstance      = hInst;
  295.        rClass.style         = 0;
  296.        rClass.lpfnWndProc    = ddeWndProc;
  297.        rClass.cbClsExtra     = 0;
  298.        rClass.cbWndExtra     = 0;
  299.  
  300.        if (! RegisterClass(&rClass) )
  301.           return FALSE;
  302.     }
  303.     /*
  304.      * Create a window to handle our DDE mesage trafic
  305.      */
  306.     hwndDDE = CreateWindow("ddeClass", NULL, 0L, 0, 0, 0, 0,
  307.                (HWND)NULL,          /* no parent */
  308.                (HMENU)NULL,       /* use class menu */
  309.                (HANDLE)hInst,     /* handle to window instance */
  310.                (LPSTR)NULL          /* no params to pass on */
  311.               );
  312.     return (BOOL)hwndDDE;
  313. }
  314.  
  315. /*----------------------------------------------------------------------------*\
  316. |   ddeWndProc( hWnd, uiMessage, wParam, lParam )                   |
  317. |                                                                              |
  318. |   Description:                                                               |
  319. |                                                                              |
  320. |   Arguments:                                                                 |
  321. |       hWnd            window handle for the parent window                    |
  322. |       uiMessage       message number                                         |
  323. |       wParam          message-dependent                                      |
  324. |       lParam          message-dependent                                      |
  325. |                                                                              |
  326. |   Returns:                                                                   |
  327. |       0 if processed, nonzero if ignored                                     |
  328. |                                                                              |
  329. \*----------------------------------------------------------------------------*/
  330. long EXPORT ddeWndProc(HWND hwnd, unsigned uiMessage, WORD wParam, long lParam )
  331. {
  332.     HANDLE    h;
  333. //    LPDDEDATA    lpData;
  334.     WORD    fRelease;
  335.  
  336.     switch (uiMessage) {
  337.     case WM_DDE_TERMINATE:
  338.         ddeTerminate (wParam);
  339.         return 0L;
  340.  
  341.     case WM_DDE_ACK:
  342.         if (fInitiate) {
  343.            hwndServer = wParam;
  344.            GlobalDeleteAtom(LOWORD(lParam));
  345.         } else {
  346.            fAck = (LOWORD(lParam) & 0x8000);
  347.         }
  348.         GlobalDeleteAtom(HIWORD(lParam));
  349.         return 0L;
  350.  
  351. #if 0
  352.  
  353.     case WM_DDE_DATA:
  354.         h = LOWORD(lParam);
  355.         lpData = (DDEDATA FAR *)GlobalLock(h);
  356.         fRelease  = lpData->fRelease;
  357.         if (lpData->fAckReq)
  358.            PostMessage(wParam,WM_DDE_ACK,hwnd,MAKELONG(0x8000,HIWORD(lParam)));
  359.         else
  360.            GlobalDeleteAtom(HIWORD(lParam));
  361.                 GlobalUnlock(h);
  362.                 if (ghData)
  363.                     DeleteData(ghData);
  364.  
  365.                 if (fRelease)
  366.                 {
  367.                     ghData = h;
  368.                 }
  369.                 else
  370.                 {
  371.                     ghData = CopyData(h);
  372.                 }
  373.  
  374.         return 0L;
  375. #endif
  376.  
  377.     }
  378.     return DefWindowProc(hwnd,uiMessage,wParam,lParam);
  379. }
  380.  
  381.  
  382.  
  383.  
  384. HWND PRIVATE ddeSendInitiate(ATOM aApp, ATOM aTopic)
  385. {
  386.     fInitiate = TRUE;
  387.     SendMessage((HWND)-1, WM_DDE_INITIATE, hwndDDE, MAKELONG(aApp, aTopic));
  388.     fInitiate = FALSE;
  389.     return hwndServer;
  390. }
  391.  
  392. HWND PRIVATE ddeInitiate(LPSTR szApp, LPSTR szTopic)
  393. {
  394.     ATOM   aApp;
  395.     ATOM   aTopic;
  396.     HWND   hwnd;
  397.  
  398.     aApp    = GlobalAddAtom(szApp);
  399.     aTopic  = GlobalAddAtom(szTopic);
  400.  
  401.     //    Try to start a conversation with the requested app
  402.     hwnd = ddeSendInitiate(aApp, aTopic);
  403.  
  404.     // perhaps he is not running, try to exec him
  405.     if (!hwnd) {
  406.         
  407.         dprintf("WinExec:%ls\n", szApp);
  408.     if (!WinExec(szApp, SW_SHOWNORMAL))
  409.             return NULL;
  410.     hwnd = ddeSendInitiate(aApp, aTopic);
  411.     }
  412.  
  413.     GlobalDeleteAtom(aApp);
  414.     GlobalDeleteAtom(aTopic);
  415.     return hwnd;
  416. }
  417.  
  418.  
  419. BOOL PRIVATE ddeWait(HWND hwnd)
  420. {
  421.     MSG    rMsg;
  422.     BOOL   fResult;
  423.  
  424.     LockData(0);
  425.     while (GetMessage(&rMsg, NULL, WM_DDE_FIRST, WM_DDE_LAST)) {
  426.     TranslateMessage(&rMsg);
  427.     DispatchMessage (&rMsg);
  428.     if (rMsg.wParam == hwnd) {   /* DDE message from proper window */
  429.        switch (rMsg.message) {
  430.           case WM_DDE_ACK:
  431.           fResult = fAck;
  432.           goto exit;
  433.  
  434.           case WM_DDE_DATA:
  435.           fResult = TRUE;
  436.           goto exit;
  437.        }
  438.     }
  439.     }
  440. exit:
  441.     UnlockData(0);
  442.     return fResult;
  443. }
  444.  
  445.  
  446. BOOL PRIVATE ddeExec(HWND hwnd, LPSTR szCmd)
  447. {
  448.     HANDLE hCmd;
  449.     LPSTR  lpCmd;
  450.     BOOL   bResult = FALSE;
  451.  
  452.     dprintf("ddeExec:%ls\n", szCmd);
  453.  
  454.     if (hCmd = GlobalAlloc(GMEM_MOVEABLE|GMEM_SHARE, (LONG)lstrlen(szCmd)+1)) {
  455.         
  456.        lpCmd = GlobalLock(hCmd);
  457.  
  458.        if (!lpCmd) {
  459.            dprintf("lock failed!\n");
  460.        goto ERR_FREE;
  461.        }
  462.  
  463.        lstrcpy (lpCmd,szCmd);
  464.        GlobalUnlock(hCmd);
  465.        PostMessage(hwnd, WM_DDE_EXECUTE, hwndDDE, MAKELONG(NULL,hCmd));
  466.        bResult = ddeWait(hwnd);
  467.  
  468. ERR_FREE:
  469.        GlobalFree (hCmd);
  470.     }
  471.     return bResult;
  472. }
  473.  
  474.  
  475.  
  476. BOOL PUBLIC fmActivate(PSTR szGroup)
  477. {
  478.     char buf[MAXSTR];
  479.  
  480.     WinAssert(hWndProgman);
  481.  
  482.     wsprintf(buf, szCreateCmd, (LPSTR)szGroup);
  483.  
  484.     return ddeExec(hWndProgman, buf);
  485. }
  486.  
  487. BOOL PUBLIC fmMinimize(PSTR szGroup)
  488. {
  489.     char buf[MAXSTR];
  490.  
  491.     WinAssert(hWndProgman);
  492.  
  493.     wsprintf(buf, "[showgroup(%s,2)]", (LPSTR)szGroup);    // SW_SHOWMINIMIZED
  494.  
  495.     return ddeExec(hWndProgman, buf);
  496. }
  497.  
  498. /*
  499.  *  fmOpen() - Open a existing Group File. Or create a new one
  500.  *
  501.  *      szName  - Name of the group to create
  502.  *          note, if this group already exists it is cleared.
  503.  *
  504.  *  RETURNS:    progman dde window handel
  505.  *
  506.  */
  507. HWND PUBLIC fmOpen(PSTR szName, BOOL fDelete)
  508. {
  509.     char buf[MAXSTR];
  510.  
  511.     if (!hWndProgman) {
  512.  
  513.         if (!(hWndProgman = ddeInitiate(szProgman, szProgman)))
  514.             return NULL;
  515.  
  516.         // don't let bozo close progman
  517.         BringWindowToTop(hWndProgman);
  518.         ShowWindow(hWndProgman, SW_RESTORE);
  519.  
  520.         EnableWindow(hWndProgman, FALSE);
  521.     }
  522.  
  523.     if (fDelete) {
  524.         wsprintf(buf, "[deletegroup(%s)]", (LPSTR)szName);
  525.         ddeExec(hWndProgman, buf);
  526.     }
  527.  
  528.  
  529.     wsprintf(buf, szCreateCmd, (LPSTR)szName);
  530.     ddeExec(hWndProgman, buf);
  531.  
  532.     return hWndProgman;
  533. }
  534.  
  535. /*
  536.  *  fmClose() - Close a Group file opened with fmOpen()
  537.  *              The header will be updated to reflect any canges made.
  538.  *
  539.  *      fh      - File handle to Group file
  540.  *
  541.  *  RETURNS:    TRUE if successful FALSE otherwise
  542.  *
  543.  */
  544.  
  545. BOOL PUBLIC fmClose()
  546. {
  547.     WinAssert(hWndProgman);
  548.  
  549.     EnableWindow(hWndProgman, TRUE);        // don't let bozo close progman
  550.  
  551.     ddeExec(hWndProgman, "[exitprogman(1)]");    // close save state
  552.  
  553.     hwndServer = hWndProgman = NULL;
  554.  
  555.     return TRUE;
  556. }
  557.  
  558. /*
  559.  *  fmAddItem() - Append a new item to a Group file opened with fmOpen()
  560.  *
  561.  *      szName          - Name of item to add.
  562.  *      szCmd           - Item's Command line
  563.  *    szExe        - EXE file to grab icon from
  564.  *              if NULL then get icon from szCmd
  565.  *    iIcon        - icon # in szExe to get
  566.  *
  567.  *  RETURNS:    TRUE if successful FALSE otherwise
  568.  *
  569.  */
  570. BOOL PUBLIC fmAddItem(PSTR szName, PSTR szCmd, PSTR szExe, int iIcon)
  571. {
  572.  
  573.     #define EXEC_STR_SIZE 200
  574.     char buf[EXEC_STR_SIZE];
  575.  
  576.     WinAssert(szName[0]);
  577.     WinAssert(szCmd[0]);
  578.  
  579.     WinAssert((lstrlen(szCmd) + lstrlen(szName) + lstrlen(szExe) + 10) < EXEC_STR_SIZE);
  580.  
  581.     wsprintf(buf, "[additem(%s,\"%s\",%s,%d)]", (LPSTR)szCmd, (LPSTR)szName, (LPSTR)szExe, iIcon);
  582.  
  583.     WinAssert(hWndProgman);
  584.  
  585.     return ddeExec(hWndProgman, buf);
  586. }
  587.