如何使用WINXGUI实现对话框布局控制Splitter与Pane?
在DELPHI和.NET的可视化设计中,利用Splitter和Panel可以实现控件的分组和布局控制,在WTL中提供了SplitterWindow对于对话框程序非常方便,而提供的CPaneContainer只能容纳一个控件,不能达到完全可视化的目的.
WINXGUI提供了嵌入对话框设计的方式,本文的PANE控制就是基于WINXGUI实现的.实际上在WTL中也可以实现类似控制,但是用WINXGUI实现起来尤其方便,并且WINXGUI本身支持可视化设计.参见http://winxgui.com
利用WINGUI的子类化技术,可以实现PANE控制,利用类似WINGUI设计的宏可以简化设计,利用WTL的SplitterWindow可以实现窗口分割控制.这样通过Spliter和Pane可以在VS6.0的对话框上直接进行设计,其中Splitter控制可以使用StaticText控件占位生成或直接动态生成,而Pane可以直接子类化StaticText控件.
一个应用例子: 需要使用WINXGUI.
代码下载请见http://www.winxgui.com/forum/viewthread.php?tid=4&extra=page%3D1
WTL::CHorSplitterWindowExm_left;
intOnInitDialog(HWNDhWnd,HWNDwParam)
{
CenterWindow();
m_left.CreateFromID(m_hWnd,IDC_LEFT);
m_left.SetSplitterPos(100);
WINX_PANE_BEGIN(IDC_PANE2)
WINX_PANEITEM(IDC_MY_EDIT,PANE_SIZE_X|PANE_SIZE_Y)
WINX_PANE_END();
WINX_PANE_BEGIN(IDC_PANE1)
WINX_PANEACCEL(IDR_ACCELERATOR)
WINX_PANEITEM(IDC_HELP_BTN,PANE_MOVE_X)
WINX_PANEITEM(IDC_HIDE_BTN,PANE_MOVE_X)
WINX_PANE_END();
WINX_PANE_BEGIN(IDC_PANE3)
WINX_PANEACCEL(IDR_ACCELERATOR)
WINX_PANEITEM(IDOK,0)
WINX_PANEITEM(IDCANCEL,0)
WINX_PANEITEM(IDC_ABOUT,PANE_MOVE_Y)
WINX_PANE_END();
CWindowpane1=GetDlgItem(IDC_PANE1);
pane1.SetParent(m_left);
CWindowpane2=GetDlgItem(IDC_PANE2);
pane2.SetParent(m_left);
m_left.SetSplitterPanes(pane1,pane2);
return0;
}
intOnInitDialog(HWNDhWnd,HWNDwParam)
{
CenterWindow();
m_left.CreateFromID(m_hWnd,IDC_LEFT);
m_left.SetSplitterPos(100);
WINX_PANE_BEGIN(IDC_PANE2)
WINX_PANEITEM(IDC_MY_EDIT,PANE_SIZE_X|PANE_SIZE_Y)
WINX_PANE_END();
WINX_PANE_BEGIN(IDC_PANE1)
WINX_PANEACCEL(IDR_ACCELERATOR)
WINX_PANEITEM(IDC_HELP_BTN,PANE_MOVE_X)
WINX_PANEITEM(IDC_HIDE_BTN,PANE_MOVE_X)
WINX_PANE_END();
WINX_PANE_BEGIN(IDC_PANE3)
WINX_PANEACCEL(IDR_ACCELERATOR)
WINX_PANEITEM(IDOK,0)
WINX_PANEITEM(IDCANCEL,0)
WINX_PANEITEM(IDC_ABOUT,PANE_MOVE_Y)
WINX_PANE_END();
CWindowpane1=GetDlgItem(IDC_PANE1);
pane1.SetParent(m_left);
CWindowpane2=GetDlgItem(IDC_PANE2);
pane2.SetParent(m_left);
m_left.SetSplitterPanes(pane1,pane2);
return0;
}
PANE的源代码
//winx使用子类化(Subclass)技术实现Pane控制
//byQWL1996@GMAIL.COM
/*
用法:在对话框的初始化中使用,允许子类化GroupBox,Picture,StaticText三种控件
允许在对话框设计中直接作为Pane,容纳子控件,并进行布局控制.
如果使用Splitter控制Pane,则只能子类化StaticText控件
例:
WINX_DLGRESIZE_BEGIN(TRUE)//layout
WINX_DLGRESIZE(IDC_STATIC1,ResizeAll)
WINX_DLGRESIZE_END();
intOnInitDialog(HWNDhWnd,HWNDwParam)
{
CenterWindow();
WINX_PANE_BEGIN(IDC_STATIC1)
WINX_PANEACCEL(IDR_ACCELERATOR)
WINX_PANEITEM(IDC_BTN1,PANE_SIZE_X|PANE_MOVE_Y)
WINX_PANEITEM(IDC_BTN2,0)//nomoveandnosize
WINX_PANE_END();
return0;
}
*/
#ifndef_WINX_STATIC_PANE_H_
#define_WINX_STATIC_PANE_H_
#pragmaonce
#definePANE_SIZE_NONE0x00000000
#definePANE_MOVE_NONE0x00000000
#definePANE_SIZE_X0x00000001
#definePANE_SIZE_Y0x00000002
#definePANE_MOVE_X0x00000004
#definePANE_MOVE_Y0x00000008
namespacewinx{
#ifndefWINX_DLGRESIZE_BEGIN_NOGRIPPER
#defineWINX_DLGRESIZE_BEGIN_NOGRIPPER(fMinSizeLimit)
WINX_DLGRESIZE_BEGIN_EX(fMinSizeLimit)
WINX_DLGRESIZE_ADDGRIPPER(FALSE)
WINX_DLGRESIZE_MAP_BEGIN()
#endif
#defineWINX_PANE_ACCEL()
private:
WINX_ACCEL_EX(_winx_hAccel);
HACCEL_winx_hAccel;
public:
VOIDwinx_msgOnAccelInit(HWNDhWnd){
_winx_hAccel=NULL;
}
VOIDwinx_msgOnAccelLoad(intidAccel){
_winx_hAccel=winx::LoadAccelerators(m_hWnd,idAccel);
}
VOIDwinx_msgOnAccelTerm(HWNDhWnd){
if(_winx_hAccel!=NULL)
::DestroyAcceleratorTable(_winx_hAccel);
_winx_hAccel=NULL;
}
classCStaticPane:publicwinx::Static<CStaticPane>
{
public:
WINX_DLG_ACCEL();//enableaccelerator
WINX_PANE_ACCEL();
WINX_CMDS_BEGIN_EX()//commanddispatcher
::SendMessage(::GetParent(hWnd),WM_COMMAND,wParam,(LPARAM)hWnd);
returnTRUE;
WINX_CMDS_END_EX();
WINX_NOTIFY_BEGIN()
*pResult=::SendMessage(::GetParent(hWnd),WM_NOTIFY,(WPARAM)idCtrl,(LPARAM)pnmh);
returnTRUE;
WINX_NOTIFY_END()
WINX_DLGRESIZE_BEGIN_NOGRIPPER(TRUE)
WINX_DLGRESIZE_END();
voidAddItem(HWNDhDlg,intid)
{
RECTrect;
GetWindowRect(&rect);
CWindowitem=::GetDlgItem(hDlg,id);
RECTrc;
item.GetWindowRect(&rc);
item.SetParent(m_hWnd);
rc.left-=rect.left;
rc.top-=rect.top;
rc.right-=rect.left;
rc.bottom-=rect.top;
item.MoveWindow(&rc);
}
voidAddResize(intm_nCtlID,DWORDm_dwResizeFlags)
{
ATL::CWindowctl=GetDlgItem(m_nCtlID);
ATLASSERT(ctl.IsWindow());
RECTrectCtl={0,0,0,0};
ctl.GetWindowRect(&rectCtl);
::MapWindowPoints(NULL,m_hWnd,(LPPOINT)&rectCtl,2);
//DWORDdwGroupFlag=(nGroupStart!=-1&&m_arrData.GetSize()==nGroupStart)?_DLSZ_BEGIN_GROUP:0;
WTL::CDialogResize<DialogResizeClass>::_AtlDlgResizeDatadata={m_nCtlID,m_dwResizeFlags,{rectCtl.left,rectCtl.top,rectCtl.right,rectCtl.bottom}};
_winx_resizer.m_arrData.Add(data);
}
};
}//namespacewinx
#defineWINX_PANE_BEGIN(nPaneID)
{
winx::CStaticPane::DoSubclassDlgItem(m_hWnd,nPaneID);
winx::CStaticPane*pPane=winx::CStaticPane::UnsafeGetInstance(::GetDlgItem(m_hWnd,nPaneID));
pPane->ModifyStyleEx(0,WS_EX_TRANSPARENT,0);
#defineWINX_PANEACCEL(iAccel)
pPane->OnAccelLoad(iAccel);
#defineWINX_PANEITEM(id,flags)
{
pPane->AddItem(m_hWnd,id);
pPane->AddResize(id,flags);
}
#defineWINX_PANE_END()
}
#endif//WINX_STATICPANE_H_
//byQWL1996@GMAIL.COM
/*
用法:在对话框的初始化中使用,允许子类化GroupBox,Picture,StaticText三种控件
允许在对话框设计中直接作为Pane,容纳子控件,并进行布局控制.
如果使用Splitter控制Pane,则只能子类化StaticText控件
例:
WINX_DLGRESIZE_BEGIN(TRUE)//layout
WINX_DLGRESIZE(IDC_STATIC1,ResizeAll)
WINX_DLGRESIZE_END();
intOnInitDialog(HWNDhWnd,HWNDwParam)
{
CenterWindow();
WINX_PANE_BEGIN(IDC_STATIC1)
WINX_PANEACCEL(IDR_ACCELERATOR)
WINX_PANEITEM(IDC_BTN1,PANE_SIZE_X|PANE_MOVE_Y)
WINX_PANEITEM(IDC_BTN2,0)//nomoveandnosize
WINX_PANE_END();
return0;
}
*/
#ifndef_WINX_STATIC_PANE_H_
#define_WINX_STATIC_PANE_H_
#pragmaonce
#definePANE_SIZE_NONE0x00000000
#definePANE_MOVE_NONE0x00000000
#definePANE_SIZE_X0x00000001
#definePANE_SIZE_Y0x00000002
#definePANE_MOVE_X0x00000004
#definePANE_MOVE_Y0x00000008
namespacewinx{
#ifndefWINX_DLGRESIZE_BEGIN_NOGRIPPER
#defineWINX_DLGRESIZE_BEGIN_NOGRIPPER(fMinSizeLimit)
WINX_DLGRESIZE_BEGIN_EX(fMinSizeLimit)
WINX_DLGRESIZE_ADDGRIPPER(FALSE)
WINX_DLGRESIZE_MAP_BEGIN()
#endif
#defineWINX_PANE_ACCEL()
private:
WINX_ACCEL_EX(_winx_hAccel);
HACCEL_winx_hAccel;
public:
VOIDwinx_msgOnAccelInit(HWNDhWnd){
_winx_hAccel=NULL;
}
VOIDwinx_msgOnAccelLoad(intidAccel){
_winx_hAccel=winx::LoadAccelerators(m_hWnd,idAccel);
}
VOIDwinx_msgOnAccelTerm(HWNDhWnd){
if(_winx_hAccel!=NULL)
::DestroyAcceleratorTable(_winx_hAccel);
_winx_hAccel=NULL;
}
classCStaticPane:publicwinx::Static<CStaticPane>
{
public:
WINX_DLG_ACCEL();//enableaccelerator
WINX_PANE_ACCEL();
WINX_CMDS_BEGIN_EX()//commanddispatcher
::SendMessage(::GetParent(hWnd),WM_COMMAND,wParam,(LPARAM)hWnd);
returnTRUE;
WINX_CMDS_END_EX();
WINX_NOTIFY_BEGIN()
*pResult=::SendMessage(::GetParent(hWnd),WM_NOTIFY,(WPARAM)idCtrl,(LPARAM)pnmh);
returnTRUE;
WINX_NOTIFY_END()
WINX_DLGRESIZE_BEGIN_NOGRIPPER(TRUE)
WINX_DLGRESIZE_END();
voidAddItem(HWNDhDlg,intid)
{
RECTrect;
GetWindowRect(&rect);
CWindowitem=::GetDlgItem(hDlg,id);
RECTrc;
item.GetWindowRect(&rc);
item.SetParent(m_hWnd);
rc.left-=rect.left;
rc.top-=rect.top;
rc.right-=rect.left;
rc.bottom-=rect.top;
item.MoveWindow(&rc);
}
voidAddResize(intm_nCtlID,DWORDm_dwResizeFlags)
{
ATL::CWindowctl=GetDlgItem(m_nCtlID);
ATLASSERT(ctl.IsWindow());
RECTrectCtl={0,0,0,0};
ctl.GetWindowRect(&rectCtl);
::MapWindowPoints(NULL,m_hWnd,(LPPOINT)&rectCtl,2);
//DWORDdwGroupFlag=(nGroupStart!=-1&&m_arrData.GetSize()==nGroupStart)?_DLSZ_BEGIN_GROUP:0;
WTL::CDialogResize<DialogResizeClass>::_AtlDlgResizeDatadata={m_nCtlID,m_dwResizeFlags,{rectCtl.left,rectCtl.top,rectCtl.right,rectCtl.bottom}};
_winx_resizer.m_arrData.Add(data);
}
};
}//namespacewinx
#defineWINX_PANE_BEGIN(nPaneID)
{
winx::CStaticPane::DoSubclassDlgItem(m_hWnd,nPaneID);
winx::CStaticPane*pPane=winx::CStaticPane::UnsafeGetInstance(::GetDlgItem(m_hWnd,nPaneID));
pPane->ModifyStyleEx(0,WS_EX_TRANSPARENT,0);
#defineWINX_PANEACCEL(iAccel)
pPane->OnAccelLoad(iAccel);
#defineWINX_PANEITEM(id,flags)
{
pPane->AddItem(m_hWnd,id);
pPane->AddResize(id,flags);
}
#defineWINX_PANE_END()
}
#endif//WINX_STATICPANE_H_
本文地址:http://www.45fan.com/dnjc/70893.html