Farseer

导航

创建自定义的右键菜单

有时候用户需要在原有的右键菜单上添加几个选项,有时候需要删掉一些不需要的项,也就是要创建自己的右键菜单。由于右键菜单的实现是由AX核心管理的,我们看不到它的具体实现(至少我没找到实现的代码),我们能做的就是通过控件的showContextMenu来实现自己的想法。
本文以CustTable为例,创建一个Form,数据源为CustTable,关注的字段为CustAccount.
需求一:去掉右键菜单
重载CustAccount的showContextMenu方法即可:

public int showContextMenu(int _menuHandle)
{
    
return 0;
}

需求二:去掉某个菜单项,比如 转到主窗体 菜单
重载字段CustAccount对应的控件的showContextMenu方法:

public int showContextMenu(int _menuHandle)
{
 
    
int                     ret;
    PopupMenu               newMenu  
= PopupMenu::create(_menuHandle,element.hWnd());
    ;
    ret 
= newMenu.drawEx();
    
return ret;
}

其中的drawEx()为改写draw所得,为免影响系统的其他功能,最好不要修改原有方法:

int drawEx(int posx = 0int 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;
}

其中第一个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;
}

效果如下:

点击后出现Hello World的对话框,当然这里是个简单的例子,可以写其他有意义的业务逻辑。

posted on 2007-07-23 20:12  佛西亚  阅读(860)  评论(7编辑  收藏  举报