improve WIN32 support and installation
git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@2170 b08c6af1-5177-4d33-ba66-4b1c6b8b522a
This commit is contained in:
308
LGPL/swi_console/menu.c
Normal file
308
LGPL/swi_console/menu.c
Normal file
@@ -0,0 +1,308 @@
|
||||
/* $Id: menu.c,v 1.1 2008-03-27 00:41:33 vsc Exp $
|
||||
|
||||
Part of SWI-Prolog
|
||||
|
||||
Author: Jan Wielemaker
|
||||
E-mail: jan@swi.psy.uva.nl
|
||||
WWW: http://www.swi-prolog.org
|
||||
Copyright (C): 1985-2002, University of Amsterdam
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
#define _MAKE_DLL
|
||||
#include "console.h"
|
||||
#include "console_i.h"
|
||||
#include "menu.h"
|
||||
|
||||
#ifndef EOS
|
||||
#define EOS 0
|
||||
#endif
|
||||
|
||||
#define streq(s,q) (_tcscmp((s), (q)) == 0)
|
||||
|
||||
static TCHAR **menuids;
|
||||
static int nmenus;
|
||||
static int nmenualloc;
|
||||
|
||||
static struct rl_item
|
||||
{ UINT id;
|
||||
const TCHAR *name;
|
||||
} rl_items[] =
|
||||
{ { IDM_EXIT, _T("&Exit") },
|
||||
{ IDM_CUT, _T("&Cut") },
|
||||
{ IDM_COPY, _T("&Copy") },
|
||||
{ IDM_PASTE, _T("&Paste") },
|
||||
{ IDM_BREAK, _T("&Interrupt") },
|
||||
{ IDM_FONT, _T("&Font ...") },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
|
||||
|
||||
static UINT
|
||||
lookupMenuLabel(const TCHAR *label)
|
||||
{ int i;
|
||||
size_t llen;
|
||||
struct rl_item *builtin;
|
||||
|
||||
for(builtin = rl_items; builtin->id; builtin++)
|
||||
{ if ( streq(builtin->name, label) )
|
||||
return builtin->id;
|
||||
}
|
||||
|
||||
for(i=0; i<nmenus; i++)
|
||||
{ if ( streq(menuids[i], label) )
|
||||
return i + IDM_USER;
|
||||
}
|
||||
|
||||
if ( nmenus + 1 > nmenualloc )
|
||||
{ if ( nmenualloc )
|
||||
{ nmenualloc *= 2;
|
||||
menuids = rlc_realloc(menuids, nmenualloc*sizeof(TCHAR *));
|
||||
} else
|
||||
{ nmenualloc = 32;
|
||||
menuids = rlc_malloc(nmenualloc*sizeof(TCHAR *));
|
||||
}
|
||||
}
|
||||
|
||||
llen = _tcslen(label);
|
||||
menuids[nmenus] = rlc_malloc((llen+1)*sizeof(TCHAR));
|
||||
_tcsncpy(menuids[nmenus], label, llen+1);
|
||||
|
||||
return nmenus++ + IDM_USER;
|
||||
}
|
||||
|
||||
const TCHAR *
|
||||
lookupMenuId(UINT id)
|
||||
{ struct rl_item *builtin;
|
||||
|
||||
if ( id >= IDM_USER && (int)id - IDM_USER < nmenus )
|
||||
return menuids[id-IDM_USER];
|
||||
|
||||
for(builtin = rl_items; builtin->id; builtin++)
|
||||
{ if ( builtin->id == id )
|
||||
return builtin->name;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
insertMenu(HMENU in, const TCHAR *label, const TCHAR *before)
|
||||
{ if ( !before )
|
||||
{ if ( !label )
|
||||
AppendMenu(in, MF_SEPARATOR, 0, NULL);
|
||||
else
|
||||
{ UINT id = lookupMenuLabel(label);
|
||||
|
||||
AppendMenu(in, MF_STRING, id, label);
|
||||
}
|
||||
} else
|
||||
{ UINT bid = lookupMenuLabel(before);
|
||||
MENUITEMINFO info;
|
||||
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.cbSize = sizeof(info);
|
||||
info.fMask = MIIM_TYPE;
|
||||
if ( label )
|
||||
{ info.fType = MFT_STRING;
|
||||
info.fMask |= MIIM_ID;
|
||||
info.wID = lookupMenuLabel(label);
|
||||
info.dwTypeData = (TCHAR *)label;
|
||||
info.cch = (int)_tcslen(label);
|
||||
} else
|
||||
{ info.fType = MFT_SEPARATOR;
|
||||
}
|
||||
|
||||
InsertMenuItem(in, bid, FALSE, &info);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Find popup with given name.
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
static HMENU
|
||||
findPopup(RlcData b, const TCHAR *name, int *pos)
|
||||
{ HMENU mb = GetMenu(rlc_hwnd(b));
|
||||
|
||||
if ( mb )
|
||||
{ int i;
|
||||
MENUITEMINFO info;
|
||||
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.cbSize = sizeof(info);
|
||||
info.fMask = MIIM_TYPE;
|
||||
|
||||
for(i=0; ; i++)
|
||||
{ MENUITEMINFO info;
|
||||
TCHAR nbuf[MAXLABELLEN];
|
||||
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.cbSize = sizeof(info);
|
||||
info.fMask = MIIM_TYPE|MIIM_SUBMENU;
|
||||
info.dwTypeData = nbuf;
|
||||
info.cch = sizeof(nbuf);
|
||||
|
||||
if ( !GetMenuItemInfo(mb, i, TRUE, &info) )
|
||||
return NULL;
|
||||
|
||||
if ( info.fType == MF_STRING )
|
||||
{ if ( streq(name, nbuf) )
|
||||
{ if ( pos )
|
||||
*pos = i;
|
||||
|
||||
return info.hSubMenu;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
append_builtin(HMENU menu, UINT id)
|
||||
{ AppendMenu(menu, MF_STRING, id, lookupMenuId(id));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
rlc_add_menu_bar(HWND cwin)
|
||||
{ HMENU menu = CreateMenu();
|
||||
HMENU file = CreatePopupMenu();
|
||||
HMENU edit = CreatePopupMenu();
|
||||
HMENU settings = CreatePopupMenu();
|
||||
HMENU run = CreatePopupMenu();
|
||||
|
||||
append_builtin(file, IDM_EXIT);
|
||||
|
||||
/*append_builtin(edit, IDM_CUT);*/
|
||||
append_builtin(edit, IDM_COPY);
|
||||
append_builtin(edit, IDM_PASTE);
|
||||
|
||||
append_builtin(settings, IDM_FONT);
|
||||
|
||||
append_builtin(run, IDM_BREAK);
|
||||
|
||||
AppendMenu(menu, MF_POPUP, (UINT)file, _T("&File"));
|
||||
AppendMenu(menu, MF_POPUP, (UINT)edit, _T("&Edit"));
|
||||
AppendMenu(menu, MF_POPUP, (UINT)settings, _T("&Settings"));
|
||||
AppendMenu(menu, MF_POPUP, (UINT)run, _T("&Run"));
|
||||
|
||||
SetMenu(cwin, menu);
|
||||
}
|
||||
|
||||
/*******************************
|
||||
* EXTERNAL *
|
||||
*******************************/
|
||||
|
||||
#define MEN_MAGIC 0x6c4a58e0
|
||||
|
||||
typedef struct menu_data
|
||||
{ intptr_t magic; /* safety */
|
||||
const TCHAR *menu; /* menu to operate on */
|
||||
const TCHAR *label; /* new label */
|
||||
const TCHAR *before; /* add before this one */
|
||||
int rc; /* result */
|
||||
} menu_data;
|
||||
|
||||
|
||||
void
|
||||
rlc_menu_action(rlc_console c, menu_data *data)
|
||||
{ RlcData b = rlc_get_data(c);
|
||||
|
||||
if ( !data || !data->magic == MEN_MAGIC )
|
||||
return;
|
||||
|
||||
if ( data->menu ) /* rlc_insert_menu_item() */
|
||||
{ HMENU popup;
|
||||
|
||||
if ( (popup = findPopup(b, data->menu, NULL)) )
|
||||
data->rc = insertMenu(popup, data->label, data->before);
|
||||
else
|
||||
data->rc = FALSE;
|
||||
} else /* insert_menu() */
|
||||
{ HMENU mb;
|
||||
HWND hwnd = rlc_hwnd(c);
|
||||
|
||||
if ( !(mb = GetMenu(hwnd)) )
|
||||
{ data->rc = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !findPopup(b, data->label, NULL) ) /* already there */
|
||||
{ MENUITEMINFO info;
|
||||
int bid = -1;
|
||||
|
||||
if ( data->before )
|
||||
findPopup(b, data->before, &bid);
|
||||
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.cbSize = sizeof(info);
|
||||
info.fMask = MIIM_TYPE|MIIM_SUBMENU;
|
||||
info.fType = MFT_STRING;
|
||||
info.hSubMenu = CreatePopupMenu();
|
||||
info.dwTypeData = (TCHAR *)data->label;
|
||||
info.cch = (int)_tcslen(data->label);
|
||||
|
||||
InsertMenuItem(mb, bid, TRUE, &info);
|
||||
/* force redraw; not automatic! */
|
||||
DrawMenuBar(hwnd);
|
||||
}
|
||||
|
||||
data->rc = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
rlc_insert_menu(rlc_console c, const TCHAR *label, const TCHAR *before)
|
||||
{ HWND hwnd = rlc_hwnd(c);
|
||||
menu_data data;
|
||||
|
||||
data.magic = MEN_MAGIC;
|
||||
data.menu = NULL;
|
||||
data.label = label;
|
||||
data.before = before;
|
||||
|
||||
SendMessage(hwnd, WM_RLC_MENU, 0, (LPARAM)&data);
|
||||
|
||||
return data.rc;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
rlc_insert_menu_item(rlc_console c,
|
||||
const TCHAR *menu, const TCHAR *label, const TCHAR *before)
|
||||
{ HWND hwnd = rlc_hwnd(c);
|
||||
menu_data data;
|
||||
|
||||
data.magic = MEN_MAGIC;
|
||||
data.menu = menu;
|
||||
data.label = label;
|
||||
data.before = before;
|
||||
|
||||
SendMessage(hwnd, WM_RLC_MENU, 0, (LPARAM)&data);
|
||||
|
||||
return data.rc;
|
||||
}
|
Reference in New Issue
Block a user