积累的VC编程小技巧之对话框
2014-05-01 23:53
543 查看
1.用鼠标移动基于对话框的无标题栏程序的简单方法
voidCVCTestDlg::OnLButtonDown(UINTnFlags,CPointpoint){
//一句话解决问题
SendMessage(WM_SYSCOMMAND,0xF012,0);
CDialog::OnLButtonDown(nFlags,point);
}
2.对话框消息映射
有对话框A,B从A中发消息给B然后B处理。
准备工作,先定义消息,如下
#defineWM_B_NOTIFYWM_USER+300
首先,必须将B的对话框句柄传送给A,暂时叫m_hWndB;
在A的发送消息的地方这样写:
::SendMessage(m_hWndB,WM_B_NOTIFY,TRUE,NULL);
这样A中的处理就完了,下面说B中的
首先定义消息处理函数,如下
voidB::ModiNotify(WPARAMwParam,LPARAMlParam)
{
MessageBox("小样,我就不信,搞不定你!");
}
然后加消息隐射,如下:
BEGIN_MESSAGE_MAP(CB,CDialog)
//{{AFX_MSG_MAP(CRPServerDlg)
ON_MESSAGE(WM_B_NOTIFY,ModiNotify)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
3.如何改变框对话或窗体视窗的背景颜色
调用CWinApp::SetDialogBkColor可以改变所有应用程序的背景颜色。第一个参数指定了背景颜色,第二个参数指定了文本颜色。下例将应用程序对话设置为蓝色背景和黄色文本。BOOLCSampleApp::InitInstance()
{
…
//usebluedialogwithyellowtext.
SetDialogBkColor(RGB(0,0,255),RGB(255,255,0));
…
}
需要重画对话(或对话的子控件)时,Windows向对话发送消息WM_CTLCOLOR,通常用户可以让Windows选择绘画背景的刷子,也可重置该消息指定刷子。下例说明了创建一个红色背景对话的步骤。
首先,给对话基类增加一人成员变量CBursh:
classCMyFormView:publicCFormView
{
…
private:
CBrushm_brush;//backgroundbrush
…
};
其次,在类的构造函数中将刷子初始化为所需要的背景颜色。
CMyFormView::CMyFormView()
{
//Initializebackgroundbrush.
m_brush.CreateSolidBrush(RGB(0,0,255))
}
最后,使用ClassWizard处理WM_CTLCOLOR消息并返回一个用来绘画对话背景的刷子句柄。注意:由于当重画对话控件时也要调用该函数,所以要检测nCtlColor参量。
HBRUSHCMyFormView::OnCtlColor(CDC*pDC,CWnd*pWnd,UINTnCtlColor)
{
//Determineifdrawingadialogbox.Ifweare,return+handleto
//ourownbackgroundbrush.Otherwiseletwindowshandleit.
if(nCtlColor==CTLCOLOR_DLG)
return(HBRUSH)m_brush.GetSafeHandle();
returnCFormView::OnCtlColor(pDC,pWnd,nCtlColor);
}
4.如何实现点一下对话框外面的区域,自动隐藏对话框?
[问题提出]如果想在点击对话框外面的地方使得对话框关闭,该如何做?
[解决方法]
试试下面的代码,原理是在激活对话框时,捕获鼠标的动作,当鼠标点击时判断是否点击在对话框外,是的话就释放对话框.
[程序实现]
建立名为My的对话框程序.实现如下步骤:
在MyDlg.h中加入:
classCShowWindow1Dlg:publicCDialog
{
//Construction
public:
intm_cx;
intm_cy;
......
};
在MyDlg.cpp中:
//定义消息映象,处理鼠标单击及激活
BEGIN_MESSAGE_MAP(CMyDlg,CDialog)
//{{AFX_MSG_MAP(CMyDlg)
ON_WM_LBUTTONDOWN()
ON_WM_ACTIVATE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
voidCMyDlg::OnLButtonDown(UINTnFlags,CPointpoint)
{
CRectrect;
GetClientRect(&rect);
rect.InflateRect(m_cx,m_cy);
//Releasedialogiftheuserclickoutsideit.
if(!rect.PtInRect(point))
{
EndDialog(IDCANCEL);
}
CDialog::OnLButtonDown(nFlags,point);
}
voidCMyDlg::OnActivate(UINTnState,CWnd*pWndOther,BOOLbMinimized)
{
CDialog::OnActivate(nState,pWndOther,bMinimized);
if(nState==WA_ACTIVE||nState==WA_CLICKACTIVE)
SetCapture();
else
ReleaseCapture();
}
BOOLCMyDlg::OnInitDialog()
{
CDialog::OnInitDialog();
.....
OSVERSIONINFOinfo;
memset((char*)&info,0,sizeof(OSVERSIONINFO));
info.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
if(GetVersionEx(&info))
{//wedon'trunonWin32s,socheckonlytwovalues
if(info.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS)
{//Onwindows95
m_cx=GetSystemMetrics(SM_CXFIXEDFRAME);
m_cy=GetSystemMetrics(SM_CYFIXEDFRAME);
}
else
{//OnNT
m_cx=GetSystemMetrics(SM_CXDLGFRAME);
m_cy=GetSystemMetrics(SM_CYDLGFRAME);
}
}
}
说明:
1)WM_ACTIVATE消息在ClassWizard中没有,按如下步骤添加,右击CMyDlg类,选AddWindowsMessageHandle,接着在Filterformessagesavailableto中选Window,在NewWindowsmessages/events列表中就会出现WM_ACTIVATE,选中,点击AddHandler
2)SM_CXDLGFRAME,SM_CYDLGFRAMENT中取得有WS_DLGFRAMEstyle风格的窗口的高和宽95中已经废弃而采用SM_CX_FIXEDFRAME和SM_CYFIXEDFRAME
5.如何使FormView中显示dialog时,不是凹的
[问题提出]为什么FormView中显示dialog时,是凹的,能不能不这样
[解决方法]
在Dialog的属性中:
增加属性WS_BORDER或者WS_EX_WINDOWEDGE
用程序实现:
pView->ModifyStyle(,WS_BORDER)或者pView->ModifyStyleEx(,WS_EX_WINDOWEDGE)
6.对话框上建立View的方法
OnInitDialog(){
CDialog:;OnInitDialog();
CRectrectWindows;
GetWinodwRect(&rectWindows);
CRuntimeClass*pViewClass=RUNTIME_CLASS(CXXXView);
CCreateContext*pContext=newCCreateContext;
pContext->m_pCurrentDoc=NULL;
pContext->m_pCurrentFrame=NULL;
pContext->m_pLastView=NULL;
pContext->m_pNewDocTemplate=NULL;
pContext->m_pNewViewClass=pViewClass;
CWnd*pWnd=DYNAMIC_DOWNCAST(CWnd,pviewClass->CreateObject());
pWnd->Create(NULL,NULL,AFX_WS_DEFAULT_VIEW,CRect(0,0,0,0),this,pContext);
deletepContext;
CXXXView*pView=DYUNAMIC_DOWNCAST(CXXXView,pWnd);
...............
}
7.模态对话框初始显示位置的控制
正确的方法是在OnInitDialog中添加MoveWindow,如:MoveWindow(0,1,300,200);
需要注意的是前两个参数不能都为0。如果你确实希望把窗口放在(0,0)处,可以在对话框设计窗口的属性中选中AbsoluteAlign,然后再加入
MoveWindow(0,0,300,200);
为什么会是这样?你看了MFC的源程序就会明白。原来MFC在调用你的OnInitDialog之后,会调用CDialog::CheckAutoCenter()(在dlgcore.cpp中)检查是否需要将窗口居中,你看了这个函数后就明白为什么需要上面那么做了。
8.动态修改对话框的大小
[问题提出]关于如何动态改变对话框的大小,我做了个Demo,大家看看.
[程序实现]
//本函数使用方法:
//第一个参数:如果是TRUE表示显示扩展的对话框,如果是FALSE,表示缩小对话框。
//第二个参数:表示本对话框的HWND,
//第三个参数:表示缩小后大小的控件的ID
voidCOptionDlg::ExpandBox(BOOLfExpand,HWNDhwnd,intnIDDefaultBox)
{
CWnd*pWndBox=GetDlgItem(nIDDefaultBox);
RECTrcDefaultBox,rcChild,rcIntersection,rcWnd;
pWndBox->GetWindowRect(&rcDefaultBox);
HWNDhwndChild=::GetTopWindow(hwnd);
for(;hwndChild!=NULL;hwndChild=::GetNextWindow(hwndChild,GW_HWNDNEXT))
{
::GetWindowRect(hwndChild,&rcChild);
if(!IntersectRect(&rcIntersection,&rcChild,&rcDefaultBox))
::EnableWindow(hwndChild,fExpand);
}
::GetWindowRect(hwnd,&rcWnd);
if(GetWindowLong(hwnd,GWL_USERDATA)==0)
{
SetWindowLong(hwnd,GWL_USERDATA,
MAKELONG(rcWnd.right-rcWnd.left,
rcWnd.bottom-rcWnd.top));
::ShowWindow(pWndBox->m_hWnd,SW_HIDE);
}
::SetWindowPos(hwnd,NULL,0,0,
rcDefaultBox.right-rcWnd.left,
rcDefaultBox.bottom-rcWnd.top,
SWP_NOZORDER|SWP_NOMOVE);
if(fExpand)
{
DWORDdwDims=GetWindowLong(hwnd,GWL_USERDATA);
::SetWindowPos(hwnd,NULL,0,0,
LOWORD(dwDims),HIWORD(dwDims),SWP_NOZORDER|SWP_NOMOVE);
::SendMessage(hwnd,DM_REPOSITION,0,0);
}
}
9.隐藏对话框窗口(窗口没有焦点时)
在程序启动时InitDialog中使用SetWindowPos将窗体设置到屏幕以外然后再隐藏
1.在OnInitDialog()函数里设置定时器:(WINDOWSAPI里面响应消息WM_INITDIALOG)
SetTimer(1,1,NULL);
2.添加处理WM_TIMER的消息处理函数OnTimer,添加代码:
if(nIDEvent==1)
{
DeleteTimer(1);
ShowWindow(SW_HIDE);
}
10.如何实现点击对话框外的地方使对话框到主窗口的后面
将桌面做为父窗口pMDlg=newCMDlg;
pMDlg->Create(IDD_M_DIALOG,CWnd::GetDesktopWindow()/*设置父窗口*/);
pMDlg->ShowWindow(SW_SHOW);
然后在任务栏里隐藏对话框程序
如何让对话框应用程序在在任务栏上不出现,并且不隐藏窗口。
[解决方法]
把对话框的扩展属性修改成为WS_EX_TOOLWINDOW。
[程序实现]
把对话框的属性设置成为toolwindow,然后在需要的地方执行本代码。
DWORDStyle=::GetWindowLong(AfxGetMainWnd()->m_hWnd,GWL_EXSTYLE);
Style=WS_EX_TOOLWINDOW;
AfxGetMainWnd()->ShowWindow(FALSE);
::SetWindowLong(AfxGetMainWnd()->m_hWnd,GWL_EXSTYLE,Style);
AfxGetMainWnd()->ShowWindow(TRUE);
11.怎么让无模式对话框显示在主窗口后面
要解决这个问题的关键在于CDialog的Create并不能建立一个无属主的窗口.必须用另外方式建窗口.比如你的对话框类叫CDlgNoOwner,在CMainFrame中加一个CDlgNoOwner类的成员变量,
弹出这个对话框的消息处理函数为
voidCMainFrame::OnNoowner()
{
CDlgNoOwner*m_dlgTest=newCDlgNoOwner(this);
HWNDhwndDlg=::CreateDialog(AfxGetInstanceHandle(),MAKEINTRESOURCE(CDlgNoOwner::IDD),NULL/*owner*/,NULL/*dlgproc*/);
//注意此处DLGPROC为NULL,并不要紧,因为接下要subclass啦
m_dlgTest->SubclassWindow(hwndDlg);//挂接到成员变量!
m_dlgTest->ShowWindow(SW_SHOW);
//这时可以看到一个"自由"的对话框弹出,和你的主窗口是平起平坐的.
}
当然不要忘了在对话框关闭时DestroyWindow()..那都是在对话框类中的标准处理了.
12.如何得到屏幕的真实尺寸(以对话框为例)
[问题提出]我的屏幕是1024*800,如何得到屏幕的真实大小,我用GetSystemMetrics(SM_CYFULLSCREEN)得到的高度总是小于800
[问题解答]
GetSystemMetrics(SM_CYFULLSCREEN)得到的只是屏幕用户区的大小。要得到屏幕的真实大小需要使用
GetDeviceCaps函数,该API函数原型是这样的:
intGetDeviceCaps(
HDChdc,//handletoDC
intnIndex//indexofcapability
);
///得到屏幕尺寸的代码如下
voidCMyDlg::OnPaint()
{
CPaintDCdc(this);
intcx=::GetDeviceCaps(dc.m_hDC,HORZRES);///得到宽度
intcy=::GetDeviceCaps(dc.m_hDC,VERTRES);///得到高度
CDialog::OnPaint();
}
13.如何在对话框中加入工具条
在OnInitDialog中加入下面代码:BOOLCYourDlg::OnInitDialog()
{
CDialog::OnInitDialog();
//Createthetoolbar.Tounderstandthemeaningofthestylesused,you
//cantakealookattheMSDNfortheCreatefunctionoftheCToolBarclass.
ToolBar.Create(this,WS_CHILD|WS_VISIBLE|CBRS_TOP|CBRS_TOOLTIPS|CBRS_FLYBY|CBRS_BORDER_BOTTOM);
//Ihaveassumedthatyouhavenamedyourtoolbar'sresourceasIDR_TOOLBAR1.
//Ifyouhavegivenitadifferentname,changethelinebelowtoaccomodate
//thatbychangingtheparameterfortheLoadToolBarfunction.
ToolBar.LoadToolBar(IDR_TOOLBAR1);
CRectrcClientStart;
CRectrcClientNow;
GetClientRect(rcClientStart);
//Torepositionandresizethecontrolbar
RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0,reposQuery,rcClientNow);
CPointptOffset(rcClientNow.left-rcClientStart.left,rcClientNow.top-rcClientStart.top);
CRectrcChild;
CWnd*pwndChild=GetWindow(GW_CHILD);
while(pwndChild)
{
pwndChild->GetWindowRect(rcChild);
ScreenToClient(rcChild);
rcChild.OffsetRect(ptOffset);
pwndChild->MoveWindow(rcChild,FALSE);
pwndChild=pwndChild->GetNextWindow();
}
CRectrcWindow;
GetWindowRect(rcWindow);
rcWindow.right+=rcClientStart.Width()-rcClientNow.Width();
rcWindow.bottom+=rcClientStart.Height()-rcClientNow.Height();
MoveWindow(rcWindow,FALSE);
//Andpositionthecontrolbars
RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0);
returnTRUE;//returnTRUEunlessyousetthefocustoacontrol
}
14.如何改变对话框的形状
可用下面一些涵数:CreatePolygonRgn
CreateRectRgn
CreateRoundRectRgn等.
CRgnm_rgn;//Putthisinyourdialog'sheaderfile.i.e.amembervariable
//ThisGetsthesizeoftheDialog:Thispieceofcodeistobeplacedinthe
//OnInitDialogFunctionofyourdialog.
CRectrcDialog
GetClientRect(rcDialog);
//ThefollowingcodeCreatestheareaandassignsittoyourDialog
m_rgn.CreateEllipticRgn(0,0,rcDialog.Width(),rcDialogHeight());
SetWindowRgn(GetSafeHwnd(),(HRGN)m_rgn,TRUE);
15.如何在对话框中加入状态条
定义CStatusBar变量:CStatusBarm_StatusBar;
定义状态条指定状态:
staticUINTBASED_CODEindicators[]=
{
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM
};
在OnInitDialog中加入下面代码:
m_StatusBar.CreateEx(this,SBT_TOOLTIPS,WS_CHILD|WS_VISIBLE|CBRS_BOTTOM,AFX_IDW_STATUS_BAR);
//Settheindicatorsnamelycapsandnumslockstatus
m_StatusBar.SetIndicators(indicators,sizeof(indicators)/sizeof(UINT));
CRectrect;
GetClientRect(&rect);
m_StatusBar.SetPaneInfo(0,ID_INDICATOR_CAPS,SBPS_NORMAL,rect.Width()/2);
m_StatusBar.SetPaneInfo(1,ID_INDICATOR_NUM,SBPS_STRETCH,rect.Width()/2);
RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,ID_INDICATOR_NUM);
m_StatusBar.GetStatusBarCtrl().SetBkColor(RGB(180,180,180));
16.如何实现非客户区移动
可用下面二种方法://HandlerforWM_LBUTTONDOWNmessage
voidCYourDialog::OnLButtonDown(UINTnFlags,CPointpoint)
{
CDialog::OnLButtonDown(nFlags,point);
PostMessage(WM_NCLBUTTONDOWN,HTCAPTION,MAKELPARAM(point.x,point.y));
}
//HandlerforWM_NCHITTESTmessage
LONGCYourDialog::OnNcHitTest(UINTuParam,LONGlParam)
{
intxPos=LOWORD(lParam);
intyPos=HIWORD(lParam);
UINTnHitTest=CDialog::OnNcHitTest(CSize(xPos,yPos));
return(nHitTest==HTCLIENT)?HTCAPTION:nHitTest;
}
17.如何使对话框初始为最小化状态
在OnInitDialog中加入下面代码:SendMessage(WM_SYSCOMMAND,SC_MAXIMIZE,NULL);
18.如何限定对话框大小范围
在WM_SIZING中加入下面代码:voidCYourDialog::OnSizing(UINTfwSide,LPRECTpRect)
{
if(pRect->right-pRect->left<=200)
pRect->right=pRect->left+200;
if(pRect->bottom-pRect->top<=200)
pRect->bottom=pRect->top+200;
CDialog::OnSizing(fwSide,pRect);
}
相关文章推荐
- 积累的VC编程小技巧之工具提示
- 积累的VC编程小技巧之工具条和状态条
- 积累的VC编程小技巧之属性页
- 积累的VC编程小技巧之列表框
- 积累的VC编程小技巧之标题栏和菜单
- 积累的VC编程小技巧之组合框
- VC编程小技巧之对话框
- 积累的VC编程小技巧之编辑框
- 积累的VC编程小技巧之编辑框
- 积累的VC编程小技巧之编辑框
- 积累的VC编程小技巧之按钮
- VC编程小技巧之对话框
- 积累的VC编程小技巧之标题栏和菜单
- 积累的VC编程小技巧之组合框
- 积累的VC编程小技巧之滚动条
- 积累的VC编程小技巧之工具条和状态条
- 积累的VC编程小技巧之列表框
- 积累的VC编程小技巧之工具条和状态条
- 积累的VC编程小技巧之工具提示
- 积累的VC编程小技巧之树操作