|
这几天研究了一下UI部分的制作方法,感觉要了解的东西挺多,加上时间不允许,我本着“够用就行”的心态学习了两种向3ds Max添加自己控件的方法。一种是添加RollupPage,一种是添加ToolBar。因为没有深入研究,我只能做到添加简单的控件,实现基本交互功能,这里介绍一下,希望大家指点:(程序截图在附件中)
一. 添加RollupPage的方式:
可以利用ApplicationWizard生成Utility程序,查看工程资源可以看到一个对话框:
1.jpg
该对话框的静态文本部分使用StaticEdit控件,交互部分使用的是VC自带的CustomCtrl控件。需要注意的是:一定要指定CustomCtrl的class,例如,如果控件用作表示文本输入框,则class的类型为:CustEdit。如果为按钮,则类型为:CustButton。几个常用的控件类型如下:
Custom Edit control - CustEdit
Custom Spinner Control - SpinnerControl
Custom Button control - CustButton
Custom Toolbar control - CustToolbar
Custom Image control - CustImage
Custom Status control - CustStatus
Color Swatch control - ColorSwatch
Custom Rollup Window - RollupWindow
Custom DragAndDrop Window control - DragDropWindow
Custom TCB Graph ? TCBGraph
下面再来看看程序部分:
首先要实现下面这个函数:
void RollupPageTest::BeginEditParams(Interface *ip,IUtil *iu)
{
this->iu = iu;
this->ip = ip;
hPanel = ip->AddRollupPage(
hInstance,
MAKEINTRESOURCE(IDD_PANEL),
RollupPageTestDlgProc,
GetString(IDS_PARAMS),
0);
}
这里的RollupPageTest继承于UtilityObj,我们可以使用UtilityObj来创建自己的Utility。
而我们需要实现的虚函数BeginEditParams,当用户选择使用该插件时,系统就会掉用这个函数,在这里该函数用来向command Panel添加RollupPage。代码”hPanel = ip->AddRollupPage(…);”用来实现这样的功能,注意其中的参数RollupPageTestDlgProc,这是一个函数的入口地址,也就是一个函数名,主要用来提供控件的消息回调函数。
另一个需要实现的函数是:
void RollupPageTest::EndEditParams(Interface *ip,IUtil *iu)
{
this->iu = NULL;
this->ip = NULL;
ip->DeleteRollupPage(hPanel);
hPanel = NULL;
}
这个函数在用户结束使用控件的时候调用,需要执行一些收尾和释放的工作。
上面这两个函数ApplicationWizard会为你填充好。所以你不用亲自去编写代码。我们只需了解它的原理就行。如果这时候调试插件,可以发现在Utility里面已经多了一个插件,但是没有任何信息交互的功能。
所以现在需要添加消息回调函数:
static BOOL CALLBACK RollupPageTestDlgProc(
HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg) {
case WM_INITDIALOG:
theRollupPageTest.Init(hWnd); //当控件初始化的时候调用。
break;
case WM_DESTROY:
theRollupPageTest.Destroy(hWnd);
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
/*表示如果选择了IDC_CUSTOM_BUTTON
该控件为我用custom ctrl创建的按钮控件*/
case IDC_CUSTOM_BUTTON:
char buf[20];
/*获取插件中的文本框控件*/
ICustEdit* iEditTest = GetICustEdit( GetDlgItem(hWnd,IDC_EDIT) );
/*获取文本框中的文本信息*/
iEditTest->GetText(buf,20);
/*显示文本信息*/
MessageBox(NULL,buf,NULL,MB_OK);
ReleaseICustEdit(iEditTest);
break;
}
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case WM_MOUSEMOVE:
theRollupPageTest.ip->RollupMouseMessage(hWnd,msg,wParam,lParam);
break;
default:
return FALSE;
}
return TRUE;
}
该代码的说明见注释,程序结果如图:
2.jpg
添加RollupPage的方式比较简单,而且有向导生成,比较方便。
二.
添加ToolBar的方式:(声明这里使用了OSGExp的代码和资源)
首先还是利用ApplicationWizar来生成一个Utility。然后在BeginEditParams里添加这样的代码:
this->iu = iu;
this->ip = ip;
/* 返回MAX的窗口句柄*/
HWND hParent = ip->GetMAXHWnd();
/*创建一个独立的Frame,其中包含工具条,菜单,命令面板等等*/
HWND hWnd = CreateCUIFrameWindow(hParent, _T("My Export Toolbar"), 0, 0, 100, 100);
/*获取所创建的Frame指针 */
ICUIFrame* iFrame = ::GetICUIFrame(hWnd);
/*设置frame的内容类型*/
iFrame->SetContentType(CUI_TOOLBAR);
/*设置位置类型*/
iFrame->SetPosType(CUI_HORIZ_DOCK | CUI_VERT_DOCK | CUI_FLOATABLE | CUI_SM_HANDLES);
/*创建一个ToolBar窗体*/
HWND hToolbar = CreateWindow(
CUSTTOOLBARWINDOWCLASS,
NULL,
WS_CHILD | WS_VISIBLE,
0, 0, 250, 100,
hWnd,
NULL,
hInstance,
NULL);
/*讲ToolBar控件和窗体连接起来*/
ICustToolbar *iToolBar = GetICustToolbar(hToolbar);
/*This method links this toolbar to the CUI frame whose window handle and message handler are passed.*/
iToolBar->LinkToCUIFrame(hWnd, NULL);
/*这两个估计是设置外形的,不深究*/
iToolBar->SetBottomBorder(FALSE);
iToolBar->SetTopBorder(FALSE);
/* 创建一个新的消息处理器*/
tbMsgHandler = new TBMsgHandler(this);
/*装载这个消息处理器*/
iFrame->InstallMsgHandler(tbMsgHandler);
/*以下代码向工具栏添加图标和按钮*/
// Get the 0th icon from the CUITest icon file.
// Note that the index is 1-based.
MaxBmpFileIcon* pIcon = new MaxBmpFileIcon(_T("osgexp_simple"), 1);
iToolBar->AddTool(TBITEM(CTB_PUSHBUTTON, pIcon, ID_TB_0));
pIcon = new MaxBmpFileIcon(_T("osgexp_simple"), 2);
iToolBar->AddTool(TBITEM(CTB_PUSHBUTTON, pIcon, ID_TB_1));
// Add a separator
iToolBar->AddTool(ToolSeparatorItem(8));
pIcon = new MaxBmpFileIcon(_T("osgexp_simple"), 3);
iToolBar->AddTool(TBITEM(CTB_PUSHBUTTON, pIcon, ID_TB_2));
pIcon = new MaxBmpFileIcon(_T("osgexp_simple"), 4);
iToolBar->AddTool(TBITEM(CTB_PUSHBUTTON, pIcon, ID_TB_3));
// Add a separator
iToolBar->AddTool(ToolSeparatorItem(8));
pIcon = new MaxBmpFileIcon(_T("osgexp_simple"), 5);
iToolBar->AddTool(TBITEM(CTB_PUSHBUTTON, pIcon, ID_TB_4));
pIcon = new MaxBmpFileIcon(_T("osgexp_simple"), 6);
iToolBar->AddTool(TBITEM(CTB_PUSHBUTTON, pIcon, ID_TB_5));
SIZE sz; RECT rect;
iToolBar->GetFloatingCUIFrameSize(&sz);
rect.top = 100; rect.left = 100;
rect.right = rect.left+sz.cx; rect.bottom = rect.top+sz.cy;
GetCUIFrameMgr()->FloatCUIWindow(hWnd, &rect);
MoveWindow(hWnd, rect.left, rect.right, sz.cx, sz.cy, TRUE);
// We are done, release the toolbar and frame handles
ReleaseICustToolbar(iToolBar);
iToolBar = NULL;
ReleaseICUIFrame(iFrame);
工具栏按钮和函数TBITEM的定义:
#defineTBITEM(type, pIcon, cmd)ToolButtonItem(type,pIcon,GetCUIFrameMgr()->GetImageSize(),\GetCUIFrameMgr()->GetImageSize(),GetCUIFrameMgr()->GetButtonWidth(),\GetCUIFrameMgr()->GetButtonHeight(),cmd,0)
#define ID_TB_0 10000
#define ID_TB_1 10001
#define ID_TB_2 10002
#define ID_TB_3 10003
#define ID_TB_4 10004
#define ID_TB_5 10005
消息处理器的实现:
class TBMsgHandler : public CUIFrameMsgHandler {
MyUtilityToolBar *tb;
public:
TBMsgHandler( MyUtilityToolBar *tb) { this->tb = tb; }
int ProcessMessage(UINT message, WPARAM wParam, LPARAM lParam);
};
接着填充消息相应函数:
int TBMsgHandler: rocessMessage(UINT message, WPARAM wParam, LPARAM lParam) {
BOOL suppressPrompts = TRUE;
DWORD MAXOptions = 0;
switch(message)
{
case WM_COMMAND:
switch (LOWORD(wParam)) {
case ID_TB_0:
MessageBox(NULL,"0",NULL,MB_OK);
break;
case ID_TB_1:
MessageBox(NULL,"1",NULL,MB_OK);
break;
case ID_TB_2:
MessageBox(NULL,"2",NULL,MB_OK);
break;
case ID_TB_3:
MessageBox(NULL,"3",NULL,MB_OK);
break;
case ID_TB_4:
MessageBox(NULL,"4",NULL,MB_OK);
break;
case ID_TB_5:
MessageBox(NULL,"5",NULL,MB_OK);
return TRUE;
default:
return FALSE;
}
}
return FALSE;
}
这里将消息响应处理做了很大的简化,实现的功能是点击按钮会显示相应的数字。编译调试,可以看到新生成的工具栏:
3.jpg
虽然功能实现的较简单,但学习的过程却不轻松,还是一句话,请大家多给批评指教。
(另外,怎么在帖子中添加图片啊?谁能教我一下)
|
|