有时候用户需要在原有的右键菜单上添加几个选项,有时候需要删掉一些不需要的项,也就是要创建自己的右键菜单。由于右键菜单的实现是由AX核心管理的,我们看不到它的具体实现(至少我没找到实现的代码),我们能做的就是通过控件的showContextMenu来实现自己的想法。
本文以CustTable为例,创建一个Form,数据源为CustTable,关注的字段为CustAccount.
需求一:去掉右键菜单
重载CustAccount的showContextMenu方法即可:
public int showContextMenu(int _menuHandle)
{
return 0;
}
{
return 0;
}
需求二:去掉某个菜单项,比如 转到主窗体 菜单
重载字段CustAccount对应的控件的showContextMenu方法:
public int showContextMenu(int _menuHandle)
{
int ret;
PopupMenu newMenu = PopupMenu::create(_menuHandle,element.hWnd());
;
ret = newMenu.drawEx();
return ret;
}
{
int ret;
PopupMenu newMenu = PopupMenu::create(_menuHandle,element.hWnd());
;
ret = newMenu.drawEx();
return ret;
}
其中的drawEx()为改写draw所得,为免影响系统的其他功能,最好不要修改原有方法:
int drawEx(int posx = 0, int posy = 0)
{
int choosenValue;
int i, numOfItems;
boolean last, cur;
HWND id;
if (itemId)
{
if (prmisdefault(posx))
{
[posx, posy] = WinAPI::getCursorPos();
}
//this.checkEmpty();
numOfItems = WinAPI::getMenuItemCount(hMenu)-1; //zero based
//Farseer Begin 去掉 转到主表窗体菜单
for (i=0; i<= numOfItems;i++)
{
id = WinAPI::getMenuItemId(hMenu, i);
if(id == 293)
{
WinAPI::deleteMenu(hMenu, id);
break;
}
}
//Farseer End
numOfItems = WinAPI::getMenuItemCount(hMenu)-1;
for (i=0; i<= numOfItems;i++)
{
id = WinAPI::getMenuItemId(hMenu, i);
if (id != -1)
{
cur = !(WinAPI::getMenuItemString(hMenu, id));
if ((i==0 || i==numOfItems || last) && cur)
{
WinAPI::deleteMenu(hMenu, id);
numOfItems = WinAPI::getMenuItemCount(hMenu)-1;
i--;
}
}
else
{
cur = false;
}
last = cur;
}
choosenValue = WinAPI::trackPopupMenu(hMenu, #TPM_RETURNCMD, posx+offsetx, posy+offsety, HWND);
choosenValue = this.findMore(choosenValue);
if (choosenValue)
return choosenValue;
return -1;
}
return -1;
}
{
int choosenValue;
int i, numOfItems;
boolean last, cur;
HWND id;
if (itemId)
{
if (prmisdefault(posx))
{
[posx, posy] = WinAPI::getCursorPos();
}
//this.checkEmpty();
numOfItems = WinAPI::getMenuItemCount(hMenu)-1; //zero based
//Farseer Begin 去掉 转到主表窗体菜单
for (i=0; i<= numOfItems;i++)
{
id = WinAPI::getMenuItemId(hMenu, i);
if(id == 293)
{
WinAPI::deleteMenu(hMenu, id);
break;
}
}
//Farseer End
numOfItems = WinAPI::getMenuItemCount(hMenu)-1;
for (i=0; i<= numOfItems;i++)
{
id = WinAPI::getMenuItemId(hMenu, i);
if (id != -1)
{
cur = !(WinAPI::getMenuItemString(hMenu, id));
if ((i==0 || i==numOfItems || last) && cur)
{
WinAPI::deleteMenu(hMenu, id);
numOfItems = WinAPI::getMenuItemCount(hMenu)-1;
i--;
}
}
else
{
cur = false;
}
last = cur;
}
choosenValue = WinAPI::trackPopupMenu(hMenu, #TPM_RETURNCMD, posx+offsetx, posy+offsety, HWND);
choosenValue = this.findMore(choosenValue);
if (choosenValue)
return choosenValue;
return -1;
}
return -1;
}
其中第一个for循环去掉转到主表窗体,第二个for循环按原有逻辑的话,应该是去除重复的间隔符的,我试了半天好像总是出问题,间隔符不能正确处理,由于是调用了API函数,不知道怎么去调试,目前只能暂时这样了。
需求三:增加一个菜单
重载字段CustAccount对应的控件的showContextMenu方法:
public int showContextMenu(int _menuHandle)
{
int ret;
PopupMenu newMenu = PopupMenu::create(_menuHandle,element.hWnd());
int newMenuId = newMenu.insertItem('Hello World');
;
ret = newMenu.draw();
switch(ret)
{
case newMenuId:
//Add Logic
box::info('Hello World');
break;
default:
break;
}
return ret;
}
{
int ret;
PopupMenu newMenu = PopupMenu::create(_menuHandle,element.hWnd());
int newMenuId = newMenu.insertItem('Hello World');
;
ret = newMenu.draw();
switch(ret)
{
case newMenuId:
//Add Logic
box::info('Hello World');
break;
default:
break;
}
return ret;
}
效果如下:
点击后出现Hello World的对话框,当然这里是个简单的例子,可以写其他有意义的业务逻辑。