⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 menu.c

📁 dos 1.0 其中包含quick basic源代码、内存管理himem emm386 发展历史
💻 C
📖 第 1 页 / 共 3 页
字号:
				    mniCur.pmenuOpen->idMenu,
				    MAKELONG(mniCur.pmenuOpen, mmdMenu));
			}
		else if (FMenuActive())
			{
			/* selecting an item (maybe) */
			if (!FSelectItemMsp(msp))
				ReportMenuInactive();
			}

		/* is he releasing the mouse button ?? */
		if (pmsg->message == WM_LBUTTONUP)
			{
			if (!FMenuActive())
				{
				/* do nothing (except cursor enable) */
				UpdateCursor();
				}
			else if (mniCur.iitem != iitemNil)
				{
				FMakeSelection();
				}
			else if (msp.s.ay == ayMenu)
				{
				/* selecting title - close or keep open */
				Assert(FMenuOpen());
				if (mniCur.fMouseOnTitle)
					{
					/* stay on title => close it */
					SetIdleState();
					}
				/* else : keep it open */
				else if (mniCur.pmenuOpen->citem != 0)
					{
					FSelectItem(0);
					}
				else
					{
					FMakeSelection();
					}
				}
			else
				SetIdleState();
			mniCur.fMouse = FALSE;
			}

		return TRUE;		/* eat it */
		}
	else if (mniCur.fMouse)
		{
		/* mouse control of the menu --> nothing gets through */
		return TRUE;
		}
#ifdef	MULTIPLE_ACTION
	else if ((pmsg->wParam == vkActionPrim ||
		  pmsg->wParam == vkActionSec) &&
		 (pmsg->wParam == VK_MENU) && 
		 (pmsg->message == WM_KEYUP))
#else	/* MULTIPLE_ACTION */
	else if (pmsg->wParam == VK_MENU && pmsg->message == WM_KEYUP)
#endif	/* MULTIPLE_ACTION */
		{
		/* convert keys to Menu Action events */
		if (fNonAltKey)
			{
			/* ignore it */
			if (!FMenuActive())
				HiliteMenuMnem(FALSE);
			return TRUE;
			}
		fMenuAction = TRUE;
		}
#ifdef	MULTIPLE_ACTION
	else if ((pmsg->wParam == vkActionPrim ||
		  pmsg->wParam == vkActionSec) &&
		 (pmsg->message == WM_CHAR))
		 {
		     fMenuAction = TRUE;
		 }   
#endif	/* MULTIPLE_ACTION */
	else if (pmsg->message == WM_CHAR)
		fNonAltKey = (BYTE) (pmsg->wParam != VK_MENU);

	/* allow all non-alt key shifted keys to slip by (if accelerators) */
	if (pmsg->message == WM_CHAR)
		{
		if (FTranslateAccelerator(pmsg->wParam, kk))
			return TRUE;	/* eat it */

#ifdef	MULTIPLE_ACTION
      		if ((!FMenuActive()) &&
		    (pmsg->wParam != vkActionPrim) &&
		    (pmsg->wParam != vkActionSec))
			return FALSE;	/* pass through if menu off */
		}
#else	/* ! MULTIPLE_ACTION */
		if (!(kk & KK_ALT) && !FMenuActive())
			return FALSE;	/* pass through if menu off */
		}
#endif	/* MULTIPLE_ACTION */

	if (!FMenuActive())
		{
		/* we are in idle - handle as fast as possible */
		Assert(mniCur.imenu == imenuNil);	/* no menu yet */

		if (fMenuAction)
			{
			/* Turn on first menu - don't open */
			SelectMenu(0);
			HiliteMenuTitle(TRUE);
			HiliteMenuMnem(TRUE);
			return TRUE;		/* eat it */
			}
		else if (pmsg->message == WM_CHAR)
			{
			/* a character */
#ifdef	MULTIPLE_ACTION
			if ((pmsg->wParam == vkActionPrim) ||
			    (pmsg->wParam == vkActionSec))
#else	/* MULTIPLE_ACTION */
			if (pmsg->wParam == VK_MENU)
#endif	/* MULTIPLE_ACTION */
				{
				HiliteMenuMnem(TRUE);
				return TRUE;	/* eat it */
				}

			if (kk & KK_ALT)
#ifdef	MULTIPLE_ACTION
				{
				WORD imenuT;
				/* otherwise a menu selection */
				if ((imenuT = ImenuPickVk(kk & KK_VK))
				    != imenuNil)
					{
					/* if we don't have a menubar -- get one !! */
					if (pmenubarCur == NULL)
					    SendMessageShort(pwndMenu, WM_MENUSTART);
					/* open that menu */
					SelectMenu(imenuT);
					OpenMenuCur();
					}
				else
					return FALSE;
				return TRUE;		/* eat it */
			    	}
#else	/* !MULTIPLE_ACTION */
			        {
				WORD imenuT;


				/* if we don't have a menubar -- get one !! */
				if (pmenubarCur == NULL)
					SendMessageShort(pwndMenu, WM_MENUSTART);
				/* otherwise a menu selection */
				if ((imenuT = ImenuPickVk(kk & KK_VK))
				    != imenuNil)
					{
					/* open that menu */
					SelectMenu(imenuT);
					OpenMenuCur();
					}
				else
					Beep();
				return TRUE;		/* eat it */
				}
#endif	/* MULTIPLE_ACTION */

			return FALSE;	/* pass through */
		        }

		return FALSE;	/* let the message pass */
		}

	/* not in idle !!!! */
	Assert(mniCur.imenu != imenuNil);
	AssertSz(pmenubarCur != NULL, "processing without a menu bar");

#ifdef DUAL
	/* if we get a null message while processing the menu, we are
	* therefore in an idle loop and should go to sleep for DOS 5
	*/
	if (fProtectMode && pmsg->message == WM_NULL)
		{
		SendMessageShort(pwndMenu, WM_MENUIDLE);
		DosSemWait(hsemaMessage, -1L);
		return TRUE;		/* eat the message */
		}
#else /*!DUAL*/
#ifdef DOS5
	/* if we get a null message while processing the menu, we are
	* therefore in an idle loop and should go to sleep for DOS 5
	*/
	if (pmsg->message == WM_NULL)
		{
		SendMessageShort(pwndMenu, WM_MENUIDLE);
		DosSemWait(hsemaMessage, -1L);
		return TRUE;		/* eat the message */
		}
#endif
#endif /*!DUAL*/

	if (fMenuAction)
		{
		/* Menu Action */
		if (FMenuOpen())
			{
			PMENU pmenu;
			/* close menu */
			CloseMenuCur(TRUE);
			HiliteMenuMnem(TRUE);	/* back to menu browse */
			/* update the help */
			pmenu = &pmenubarCur->rgmenu[mniCur.imenu];
			SendMessage(pwndMenu, WM_MENUSELECT, pmenu->idMenu,
			    MAKELONG(pmenu, mmdMenu));
			}
		else
			{
			/* go back to idle */
			SetIdleState();
			}
		}
	else if (pmsg->message == WM_CHAR)
		{
		WORD imenuT;
		BOOL fWasOpen;

		/* undo repeat before processing */
		UndoRepeat(pmsg->wParam, pmsg->lParam);

		imenuT = mniCur.imenu;

#ifdef	MULTIPLE_ACTION
		if (pmsg->wParam == vkActionPrim ||
      			pmsg->wParam == vkActionSec)
		      return(TRUE);

		if (pmsg->wParam == vkCancelPrim || pmsg->wParam == vkCancelSec) {
		    SetIdleState();
		    return TRUE;
		}
#endif	/* MULTIPLE_ACTION */

		/* Cases : similar whether menu is open or not */
		switch (pmsg->wParam)
			{
		default:
			break;		/* drop out & do second set of cases */

#ifndef	MULTIPLE_ACTION
		case LOBYTE(VK_ESCAPE):	/* escape character */
			SetIdleState();
			return TRUE;
#endif	/* !MULTIPLE_ACTION */

		case VK_LEFT:
			imenuT -= 2;
			/* fall through to right */
		case VK_RIGHT:
			imenuT++;	/* right +1, left -2+1 == -1 */
			/* check for wrap */
			if (imenuT >= pmenubarCur->cmenu)
				{
				if (imenuT == (WORD) -1) /* wrapped */
					imenuT = pmenubarCur->cmenu - 1;
				else
					{
					Assert(imenuT == pmenubarCur->cmenu);
					imenuT = 0;
					}
				}
			/* select new menu */
			fWasOpen = FMenuOpen();
			BeginDraw();
			CloseMenuCur(TRUE);
			ReportMenuInactive();
			HiliteMenuTitle(FALSE);
			SelectMenu(imenuT);
			if (fWasOpen)
				OpenMenuCur();
			EndDraw();
			return TRUE;

#ifndef	MULTIPLE_ACTION
		case VK_MENU:
			return TRUE;
#endif	/* !MULTIPLE_ACTION */

		case VK_HELP_KEY:
			SendMenuHelp(kk);
			MoveHardwareCursor(0, 0, FALSE);
			return TRUE;
			}

		/* cases which are different whether FMenuOpen() or not */
		if (!FMenuOpen())
			{
			/* Menu not open, let's try and open one */

			switch (pmsg->wParam)
				{
			default:
				/* select menu */
				if ((imenuT = ImenuPickVk(pmsg->wParam))
				    != imenuNil)
					{
					SelectMenu(imenuT);
					OpenMenuCur();
					}
				else
					Beep();	/* bad choice */
				break;

			case LOBYTE(VK_RETURN):
			case VK_UP:
			case VK_DOWN:	/* same as up */
				/* Open the current menu */
				OpenMenuCur();
				break;
				}
			}
		else
			{
			/* Menu open, keys effect item selection */
			WORD iitemT = mniCur.iitem;

			switch (pmsg->wParam)
				{
			default:
				/* select item */
				if (!FMatchItemVk(pmsg->wParam))
					{
					/* bad key */
					Beep();
					break;
					}
#ifdef ACCEL_MULTIPLE
				if (fOneOfMultiple)
					break;
#endif /*ACCEL_MULTIPLE*/
				/* fall through to accept */
			case LOBYTE(VK_RETURN):
				FMakeSelection();
				break;

			case VK_UP:
			case VK_DOWN:
				/* previous / next menu item */
				do
					{
					if (pmsg->wParam == VK_UP)
						iitemT--;
					else
						iitemT++;
					}
				while (!FSelectItem(iitemT));
				}
			}
		}
	return TRUE;	/* normally eat */
	}



STATIC VOID
SetIdleState()
/*
  -- jump to idle state
*/
	{
	/* do it all -- all routines handle nil cases */
	CloseMenuCur(TRUE);
	HiliteMenuTitle(FALSE);
	mniCur.imenu = imenuNil;
	HiliteMenuMnem(FALSE);
	ReportMenuInactive();
	mniCur.fMouse = FALSE;
	UpdateCursor();
	}



/********** Utilities **********/


STATIC BOOL
FTranslateAccelerator(vk, kk)
/*
  -- check to see if key "vk" should be treated as an accelerator
  -- send 2 messages if it is an accelerator (DO NOT POST!!!) and return TRUE
  -- return FALSE if not translated
*/
WORD vk;
WORD kk;
	{
	REGISTER MPVKEYID *pmpvkeyid = pmenubarCur->rgmpvkeyid;
	WORD vkeyCur, vkeyFind;

	/* look for correct "VKEY" value & proper shift states */
	vkeyFind = VkeyOfVkKk(vk, kk & (KK_ALT | KK_CONTROL | KK_SHIFT));

	while ((vkeyCur = pmpvkeyid->vkey) != 0)
		{
		if (vkeyCur == vkeyFind)
			{
			WORD idItem = pmpvkeyid->idItem;
			PMENUITEM pmenuitem = FindMenuItem(idItem);
			
			/* found an accelerator */
			if (FMenuActive())
				SetIdleState();

			if (pmenuitem != NULL)
				{
				SendMessage(pwndMenu, WM_INITMENUPOPUP,
				    pmenuFound->idMenu, MAKELONG(pmenuFound, 1));
				if (!pmenuitem->fEnabled)
					return TRUE;
				}
			/* send item message even if not with menu item */
			SendMessage(pwndMenu, WM_COMMAND, idItem,
			    MAKELONG(pmenuitem, mmdAccel));

			return TRUE;
			}
		else
			pmpvkeyid++;
		}
	return FALSE;
	}



STATIC BOOL
FMatchVkCh(vk, chMenu)
/*
  -- return TRUE if virtual key "vk" matches matches menu character "ch"
  -- (i.e. vk will be Upper case ASCII, menu char may be upper or lower case)
  -- for KANJI -- also check the alternate KANA/ROMAN key
*/
WORD vk;
char chMenu;
	{
	char ch = (char) LOBYTE(vk);

	if (vk >= 'a' && vk <= 'z')
		ch -= ('a' - 'A');
	else if ((unsigned) ch > 0x7f)
		ch = ChUpperFromChExt(ch);

	if (chMenu >= 'a' && chMenu <= 'z')
		chMenu -= ('a' - 'A');
	else if ((unsigned) chMenu > 0x7f)
		chMenu = ChUpperFromChExt(chMenu);

#ifdef KANJI
	if (ch != chMenu)
		{
		/* possibly the alternate character on that key -- try it */
		ch = ChAlternateKeytop(ch);
		}
#endif /*KANJI*/
	return(chMenu == ch);
	}



STATIC char *
SzItem(pmenuitem)
/*
  -- return the text of the menu item
*/
REGISTER PMENUITEM pmenuitem;
	{
	return (pmenuitem->fHandle ? *(pmenuitem->u.pszItem) :
	    pmenuitem->u.szItem);
	}



STATIC VOID
SendMenuHelp(kk)
/*
  -- send menu help message
*/
WORD	kk;
	{
	/* process HELP */
	WORD imenuSave;

	/* save old state, turn off menu for the help portion */
	imenuSave = mniCur.imenu;
	Assert(imenuSave != imenuNil);
	mniCur.imenu = imenuNil;

	if (mniCur.iitem != iitemNil)
		{
		PMENUITEM pmenuitem;
		Assert(FMenuOpen());

		pmenuitem = &PmenuitemOfPmenu(mniCur.pmenuOpen)[mniCur.iitem];
		Help(hemMenuItem, pmenuitem->idItem, pmenuitem, kk);
		}
	else
		{
		PMENU pmenu;

		pmenu = &pmenubarCur->rgmenu[imenuSave];
		Help(hemMenu, pmenu->idMenu, pmenu, kk);
		}
	mniCur.imenu = imenuSave;
#ifdef	DIALOG_NOSAVE
	DrawMenuCur();
#endif
	}




#ifdef MENU_UTILS
VOID FARPUBLIC
OpenMenu(idMenu)
/*
  -- application wants a menu open
*/
WORD idMenu;	/* id of menu to open */
	{
	REGISTER PMENU pmenu;
	WORD imenu;

	Assert(mniCur.imenu == imenuNil);	/* must be closed */

	for (imenu = 0, pmenu = pmenubarCur->rgmenu;
	    imenu < pmenubarCur->cmenu;
	    pmenu++, imenu++)
		{
		if (pmenu->idMenu == idMenu)
			{
			/* found it */
			SelectMenu(imenu);
			OpenMenuCur();
			fNonAltKey = FALSE;	/* allow up transition */
			return;
			}
		}
	AssertSz(FALSE, "Invalid call to OpenMenu()");
	}
#endif /*MENU_UTILS*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -