home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / drdobbs / 1991 / 06 / dflat3 / menubar.c < prev    next >
Text File  |  1991-05-19  |  7KB  |  289 lines

  1. /* ---------------- menubar.c -------------- */
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <ctype.h>
  7. #include <dos.h>
  8. #include "dflat.h"
  9.  
  10. static void reset_menubar(WINDOW);
  11. static void ClosePopDown(void);
  12. static int TestGlobalKeys(PARAM, PARAM);
  13.  
  14. static char *menubar;
  15.  
  16. static struct {
  17.     int x1, x2;        /* position in menu bar */
  18.     char sc;        /* shortcut key value   */
  19. } menu[10];
  20. static int mctr;
  21.  
  22. MENU *ActiveMenu;
  23. int ActiveSelection = -1;
  24.  
  25. static WINDOW mwnd = NULL;
  26.  
  27. #define MSPACE 2
  28.  
  29. int MenuBarProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2)
  30. {
  31.     int offset = 3, wd, offset1, i, j;
  32.     int mx = (int) p1 - GetLeft(wnd);
  33.     MENU *mnu;
  34.  
  35.     switch (msg)    {
  36.         case CREATE_WINDOW:
  37.             reset_menubar(wnd);
  38.             PostMessage(wnd, PAINT, 0, 0);
  39.             break;
  40.         case COMMAND:
  41.             PostMessage(GetParent(wnd), msg, p1, p2);
  42.             return FALSE;
  43.         case SETFOCUS:
  44.             if (p1)    {
  45.                 if (!p2)
  46.                     return FALSE;
  47.                 else     {
  48.                     /* --- accept the focus only if there are no others --- */
  49.                     WINDOW wnd1 = Focus.FirstWindow;
  50.                     while (wnd1 != NULLWND)    {
  51.                         if (wnd != wnd1 && GetParent(wnd) == GetParent(wnd1))
  52.                             break;
  53.                         wnd1 = NextWindow(wnd1);
  54.                     }
  55.                     if (wnd1 != NULLWND)
  56.                         return FALSE;
  57.                 }
  58.             }
  59.             break;
  60.         case BUILDMENU:
  61.             reset_menubar(wnd);
  62.             mctr = 0;
  63.             ActiveMenu = (MENU *) p1;
  64.             while (ActiveMenu->Title != NULL)    {
  65.                 char *cp;
  66.                 menubar = realloc(menubar, strlen(menubar)+5);
  67.                 memmove(menubar + offset+4, menubar + offset, strlen(menubar)-offset+1);
  68.                 CopyCommand(menubar+offset, ActiveMenu->Title, FALSE, cfg.clr.MenuBarBG);
  69.                 menu[mctr].x1 = offset;
  70.                 offset += strlen(ActiveMenu->Title) + (3+MSPACE);
  71.                 menu[mctr].x2 = offset-MSPACE;
  72.                 cp = strchr(ActiveMenu->Title, SHORTCUTCHAR);
  73.                 if (cp)
  74.                     menu[mctr].sc = tolower(*(cp+1));
  75.                 ActiveMenu++;
  76.                 mctr++;
  77.             }
  78.             ActiveMenu = (MENU *) p1;
  79.             break;
  80.         case PAINT:    
  81.             if (!isVisible(wnd))
  82.                 break;
  83.             SetStandardColor(wnd);
  84.             ClearAttribute(wnd, NOCLIP);
  85.             writefull(wnd, menubar, 0);
  86.             AddAttribute(wnd, NOCLIP);
  87.             if (ActiveSelection != -1)    {
  88.                 char sel[80], *cp;
  89.                 offset = menu[ActiveSelection].x1;
  90.                 offset1 = menu[ActiveSelection].x2;
  91.                 menubar[offset1] = '\0';
  92.                 SetReverseColor(wnd);
  93.                 memset(sel, '\0', sizeof sel);
  94.                 strcpy(sel, menubar+offset);
  95.                 cp = strchr(sel, CHANGECOLOR);
  96.                 if (cp != NULL)
  97.                     *(cp + 2) = background | 0x80;
  98.                 wputs(wnd, sel, offset-ActiveSelection*(MSPACE+2), 0);
  99.                 menubar[offset1] = ' ';
  100.             }
  101.             return FALSE;
  102.         case KEYBOARD:
  103.             if (mwnd == NULL)    {
  104.                 /* ----- search for menu bar shortcut keys ---- */
  105.                 for (i = 0; i < 26; i++)
  106.                     if ((char) p1 == altconvert[i])
  107.                         break;
  108.                 if (i < 26)    {
  109.                     for (j = 0; j < mctr; j++)    {
  110.                         if (menu[j].sc == 'a' + i)    {
  111.                             SendMessage(wnd, SELECTION, j, 0);
  112.                             return FALSE;
  113.                         }
  114.                     }
  115.                 }
  116.             }
  117.             /* -------- search for accelerator keys -------- */
  118.             mnu = ActiveMenu;
  119.             while (mnu->Title != NULL)    {
  120.  
  121.                 struct PopDown *pd = mnu->Selections;
  122.                 if (mnu->PrepMenu)
  123.                     (*(mnu->PrepMenu))(GetParent(wnd), mnu);
  124.                 while (pd->SelectionTitle != NULL)    {
  125.                     if (pd->Accelerator == (int) p1)    {
  126.                         if (pd->Attrib & INACTIVE)
  127.                             beep();
  128.                         else
  129.                             PostMessage(GetParent(wnd),
  130.                                 COMMAND, pd->ActionId, 0);
  131.                         return TRUE;
  132.                     }
  133.                     pd++;
  134.                 }
  135.                 mnu++;
  136.             }
  137.             if (TestGlobalKeys(p1, p2))
  138.                 return FALSE;
  139.             if (mwnd == NULLWND)
  140.                 return FALSE;
  141.             switch ((int)p1)    {
  142.                 case FWD:
  143.                     ActiveSelection++;
  144.                     if (ActiveSelection == mctr)
  145.                         ActiveSelection = 0;
  146.                     SendMessage(wnd, SELECTION, ActiveSelection, 0);
  147.                     return FALSE;
  148.                 case BS:
  149.                     if (ActiveSelection == 0)
  150.                         ActiveSelection = mctr;
  151.                     --ActiveSelection;
  152.                     SendMessage(wnd, SELECTION, ActiveSelection, 0);
  153.                     return FALSE;
  154.                 default:
  155.                     break;
  156.             }
  157.             if (mwnd == (void *)-1)
  158.                 return FALSE;
  159.             break;
  160.         case LEFT_BUTTON:
  161.             for (i = 0; i < mctr; i++)
  162.                 if (mx >= menu[i].x1-(MSPACE+2)*i &&
  163.                         mx <= menu[i].x2-(MSPACE+2)*i-5)
  164.                     break;
  165.             if (i < mctr)    {
  166.                 if (i != ActiveSelection || mwnd == NULL)    {
  167.                     SendMessage(wnd, SELECTION, i, 0);
  168.                     SendMessage(NULLWND, WAITMOUSE, 0, 0);
  169.                 }
  170.             }
  171.             break;
  172.         case SELECTION:
  173.             if (mwnd && mwnd != (void *)-1)
  174.                 SendMessage(mwnd, CLOSE_WINDOW, 0, 0);
  175.             mwnd = NULL;
  176.  
  177.             ActiveSelection = (int) p1;
  178.  
  179.             offset = menu[ActiveSelection].x1 -
  180.                         (MSPACE+2) * ActiveSelection;
  181.  
  182.             mnu = ActiveMenu+ActiveSelection;
  183.  
  184.             if (mnu->PrepMenu != NULL)
  185.                 (*(mnu->PrepMenu))(GetParent(wnd), mnu);
  186.  
  187.             wd = MenuWidth(mnu->Selections);
  188.  
  189.             if (offset > WindowWidth(wnd)-wd)
  190.                 offset = WindowWidth(wnd)-wd;
  191.  
  192.             if (mnu->Selections[0].SelectionTitle != NULL)    {
  193.                 mwnd = CreateWindow(POPDOWNMENU, NULL,
  194.                             GetLeft(wnd)+offset, GetTop(wnd)+1,
  195.                             MenuHeight(mnu->Selections),
  196.                             wd,
  197.                             NULL,
  198.                             wnd,
  199.                             NULL,
  200.                             0);
  201. #ifdef INCLUDE_SHADOWS
  202.                 AddAttribute(mwnd, SHADOW);
  203. #endif
  204.                 SendMessage(mwnd, BUILD_SELECTIONS, LPARAM(mnu), 0);
  205.                 SendMessage(wnd, PAINT, 0, 0);
  206.                 SendMessage(mwnd, SHOW_WINDOW, 0, 0);
  207.             }
  208.             else
  209.                 mwnd = (void *)-1;
  210.             SendMessage(wnd, PAINT, 0, 0);
  211.             break;
  212.         case BORDER:
  213.             return TRUE;
  214.         case INSIDE_WINDOW:
  215.             return InsideRect(p1, p2, WindowRect(wnd));
  216.         case CLOSE_POPDOWN:
  217.             ClosePopDown();
  218.             SendMessage(wnd, PAINT, 0, 0);
  219.             break;
  220.         case CLOSE_WINDOW:
  221.             if (menubar != NULL)    {
  222.                 free(menubar);
  223.                 menubar = NULL;
  224.             }
  225.             mctr = 0;
  226.             ActiveSelection = -1;
  227.             ActiveMenu = NULL;
  228.             break;
  229.         default:
  230.             break;
  231.     }
  232.     return BaseWndProc(MENUBAR, wnd, msg, p1, p2);
  233. }
  234.  
  235. static void reset_menubar(WINDOW wnd)
  236. {
  237.     menubar = realloc(menubar, SCREENWIDTH+5);
  238.     memset(menubar, ' ', SCREENWIDTH);
  239.     *(menubar+SCREENWIDTH-
  240.         (TestAttribute(GetParent(wnd), HASBORDER) ? 2 : 0)) = '\0';
  241. }
  242.  
  243. static void ClosePopDown(void)
  244. {
  245.     ActiveSelection = -1;
  246.     mwnd = NULLWND;
  247. }
  248.  
  249. static int TestGlobalKeys(PARAM p1, PARAM p2)
  250. {
  251.     switch ((int)p1)    {
  252.         case ALT_F6:
  253.             if (GetClass(inFocus) != MENUBAR &&
  254.                     GetClass(inFocus) != POPDOWNMENU)
  255.                 SetNextFocus(inFocus, FALSE);
  256.             return TRUE;
  257. #ifdef INCLUDE_SYSTEM_MENUS
  258.         case ALT_HYPHEN:
  259.             if (GetClass(inFocus) == POPDOWNMENU)
  260.                 SendMessage(inFocus, CLOSE_WINDOW, 0, 0);
  261.             if (GetClass(GetParent(inFocus)) == APPLICATION)
  262.                 BuildSystemMenu(GetParent(inFocus));
  263.             return TRUE;
  264.         case ' ':
  265.             if (p2 & ALTKEY)    {
  266.                 if (GetClass(inFocus) == POPDOWNMENU)
  267.                     SendMessage(inFocus, CLOSE_WINDOW, 0, 0);
  268.                 if (GetClass(inFocus) != MENUBAR &&
  269.                         TestAttribute(inFocus, TITLEBAR) &&
  270.                             TestAttribute(inFocus, CONTROLBOX))
  271.                     BuildSystemMenu(inFocus);
  272.                 return TRUE;
  273.             }
  274.             break;
  275. #endif
  276.         case ALT_F4:
  277.             if (GetClass(inFocus) != MENUBAR)
  278.                 PostMessage(inFocus, CLOSE_WINDOW, 0, 0);
  279.             else 
  280.                 PostMessage(GetParent(inFocus), CLOSE_WINDOW, 0, 0);
  281.             return TRUE;
  282.         default:
  283.             break;
  284.     }
  285.     return FALSE;
  286. }
  287.  
  288.  
  289.