您的位置:首页 > 编程语言

积累的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);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: