1.用鼠标移动基于对话框的无标题栏程序的简单方法
void CVCTestDlg::OnLButtonDown(UINT nFlags,
CPoint point)
{
//一句话解决问题
SendMessage(WM_SYSCOMMAND,0xF012,0);
CDialog::OnLButtonDown(nFlags,
point);
}
2.对话框消息映射
有对话框
A,B
从
A中发消息给
B然后
B处理。
准备工作,先定义消息,如下
#define
WM_B_NOTIFY WM_USER + 300
首先,必须将
B的对话框句柄传送给
A,暂时叫
m_hWndB;
在
A的发送消息的地方这样写:
::SendMessage(
m_hWndB,WM_B_NOTIFY,TRUE,NULL );
这样
A中的处理就完了,下面说
B 中的
首先定义消息处理函数,如下
void B::ModiNotify( WPARAM wParam,
LPARAM lParam )
{
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可以改变所有应用程序的背景颜色。第一个参数指定了背景颜色,第二个参数指定了文本颜色。下例将应用程序对话设置为蓝色背景
和黄色文本。
BOOL CSampleApp : : InitInstance ( )
{
…
//use blue dialog with
yellow text .
SetDialogBkColor (RGB (0, 0, 255 ), RGB ( 255 ,
255 , 0 ) ) ;
…
}
需要重画对话(或对话的子控件)
时,
Windows向对话发送消息
WM_CTLCOLOR,通常用户可以让
Windows选择绘画背景的刷子,也可重置该消息指定刷子。下例说明了创建一个红色背景对话的步骤。
首先,给对话基类增加一人成员
变量
CBursh
:
class
CMyFormView : public CFormView
{
…
private :
CBrush m_ brush ; //
background brush
…
} ;
其次,
在类的构造函数中将刷子初始化为所需要的背景颜色。
CMyFormView : : CMyFormView ( )
{
// Initialize background
brush .
m_brush .CreateSolidBrush (RGB ( 0, 0, 255 ) )
}
最后,使用
ClassWizard处理
WM_CTLCOLOR消息并返回一个用来绘画对话背景的刷子句
柄。注意:由于当重画对话控件时也要调用该函数,所以要检测
nCtlColor参量。
HBRUSH CMyFormView : :
OnCtlColor (CDC* pDC , CWnd*pWnd , UINT nCtlColor )
{
// Determine if drawing a
dialog box . If we are , return +handle to
//our own background brush .
Otherwise let windows handle it .
if (nCtlColor = = CTLCOLOR _ DLG )
return (HBRUSH) m_brush
.GetSafeHandle ( ) ;
return CFormView : : OnCtlColor (pDC, pWnd ,
nCtlColor );
}
4. 如何实现点一下对话框外面的区域 ,自动隐藏对话框 ?
[问题提出
]
如果想在
点击对话框外面的地方使得对话框关闭
,该如何做
?
[解决方法
]
试试下面
的代码
,原理是在激活对话框时
,捕获鼠标的
动作
,当鼠标点击时判断是否点击在对话框外
,是
的话就释放对话框
.
[程序实现
]
建立名为
My的对话框程序
.实现如下步骤
:
在
MyDlg.h中加入
:
class CShowWindow1Dlg : public CDialog
{
// Construction
public:
int m_cx;
int m_cy;
......
};
在
MyDlg.cpp中
:
//定义消息映象
,处理鼠标单击及激活
BEGIN_MESSAGE_MAP(CMyDlg, CDialog)
//{{AFX_MSG_MAP(CMyDlg)
ON_WM_LBUTTONDOWN()
ON_WM_ACTIVATE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
void
CMyDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
CRect rect;
GetClientRect(&rect);
rect.InflateRect(m_cx,
m_cy);
//Release dialog if the user click outside it.
if(!rect.PtInRect(point))
{
EndDialog(IDCANCEL);
}
CDialog::OnLButtonDown(nFlags,
point);
}
void CMyDlg::OnActivate(UINT nState, CWnd*
pWndOther, BOOL bMinimized)
{
CDialog::OnActivate(nState, pWndOther,
bMinimized);
if( nState == WA_ACTIVE || nState ==
WA_CLICKACTIVE)
SetCapture();
else
ReleaseCapture();
}
BOOL
CMyDlg::OnInitDialog()
{
CDialog::OnInitDialog();
.....
OSVERSIONINFO info;
memset((char*)&info,
0, sizeof(OSVERSIONINFO));
info.dwOSVersionInfoSize =
sizeof(OSVERSIONINFO);
if(GetVersionEx(&info))
{ //we don't run
on Win32s, so check only two values
if(info.dwPlatformId ==
VER_PLATFORM_WIN32_WINDOWS)
{ //On windows 95
m_cx =
GetSystemMetrics(SM_CXFIXEDFRAME);
m_cy =
GetSystemMetrics(SM_CYFIXEDFRAME);
}
else
{ //On NT
m_cx =
GetSystemMetrics(SM_CXDLGFRAME);
m_cy =
GetSystemMetrics(SM_CYDLGFRAME);
}
}
}
说明
:
1)WM_ACTIVATE消息在
ClassWizard中没有
,按如下步骤添加
,右击
CMyDlg类
,选
Add Windows Message
Handle,接着在
Filter for messages available to中选
Window,在
New Windows
messages/events列表中就会出现
WM_ACTIVATE,选中
,点击
Add Handler
2)SM_CXDLGFRAME,SM_CYDLGFRAME NT中取得有
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();
CRect
rectWindows;
GetWinodwRect(&rectWindows);
CRuntimeClass
*pViewClass=RUNTIME_CLASS(CXXXView);
CCreateContext *pContext=new
CCreateContext;
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);
delete
pContext;
CXXXView *pView=DYUNAMIC_DOWNCAST(CXXXView,pWnd);
...............
}
7. 模态对话框初始显示位置的控制
正确的方法是在
OnInitDialog中添加
MoveWindow,如:
MoveWindow(0, 1, 300, 200);
需要注意的是前两个参数不能都为
0。如果你确实希望把窗口放在
(0,
0)处,可以在对话框设计窗口的属性中选中
Absolute Align,然后再加入
MoveWindow(0, 0, 300, 200);
为什么会是这样?你看了
MFC的源程序就会明白。原来
MFC在调用你的
OnInitDialog之后,会调用
CDialog::CheckAutoCenter()(在
dlgcore.cpp中)检查是否需要将窗口居中,你看了这个
函数后就明白为什么需要上面那么做了。
8.动态修改对话框的大小
[问题提出
]
关
于如何动态改变对话框的大小
,我做了个
Demo,大家看看
.
[程序实现
]
//本函数使用方法:
//第一个参数:如果是
TRUE表示显示扩展的对话框,如果是
FALSE,表示缩小对话框。
//第二个参数:表示本对话框的
HWND,
//第三个参数:表示缩小后大小的控件的
ID
void COptionDlg::ExpandBox(BOOL fExpand, HWND hwnd, int
nIDDefaultBox)
{
CWnd *pWndBox=GetDlgItem(nIDDefaultBox);
RECT rcDefaultBox,rcChild,rcIntersection,rcWnd;
pWndBox->GetWindowRect(&rcDefaultBox);
HWND hwndChild = ::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)
{
DWORD dwDims = 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()
函
数里设置定时器:(
WINDOWS API
里面响应消息
WM_INITDIALOG
)
SetTimer(1, 1, NULL);
2.
添加处理
WM_TIMER
的消息处理函
数
OnTimer,
添加代码:
if(nIDEvent == 1)
{
DeleteTimer(1);
ShowWindow(SW_HIDE);
}
10.如何实现点击对话框外的地方使对话框到主窗口的后面
将桌面做为父窗口
pMDlg
= new CMDlg;
pMDlg->Create(IDD_M_DIALOG,CWnd::GetDesktopWindow()/*
设置父窗口
*/);
pMDlg->ShowWindow(SW_SHOW);
然后在任务栏里隐藏对话框程序
如何让对话框应用程序在在任务栏上不出现,并且不隐藏窗口。
[
解决方法
]
把对话框的扩展属性修改成为
WS_EX_TOOLWINDOW
。
[
程序实现
]
把对话框的属
性设置成为
toolwindow
,然后在需要的地方执行本代码。
DWORD Style =
::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类的成员变量
,
弹出这个对话框的消息处理函数为
void CMainFrame::OnNoowner()
{
CDlgNoOwner *m_dlgTest=new
CDlgNoOwner(this);
HWND
hwndDlg=::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函数原型是这样的
:
int
GetDeviceCaps(
HDC hdc, // handle to
DC
int nIndex // index of capability
);
///得到屏幕尺寸
的代码如下
void CMyDlg::OnPaint()
{
CPaintDC dc(this);
int cx = ::GetDeviceCaps(dc.m_hDC,HORZRES);///得到宽度
int cy =
::GetDeviceCaps(dc.m_hDC,VERTRES);///得到高度
CDialog::OnPaint();
}
13.如何在对话框中加入工具条
在 OnInitDialog 中加入下面代码:
BOOL CYourDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Create the toolbar. To understand the meaning of the styles used, you
// can take a look at the MSDN for the Create function of the CToolBar class.
ToolBar.Create(this , WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_TOOLTIPS |CBRS_FLYBY | CBRS_BORDER_BOTTOM);
// I have assumed that you have named your toolbar's resource as IDR_TOOLBAR1.
// If you have given it a different name, change the line below to accomodate
// that by changing the parameter for the LoadToolBar function.
ToolBar.LoadToolBar(IDR_TOOLBAR1);
CRect rcClientStart;
CRect rcClientNow;
GetClientRect(rcClientStart);
// To reposition and resize the control bar
RepositionBars (AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST,0 , reposQuery, rcClientNow);
CPoint ptOffset(rcClientNow.left - rcClientStart.left,rcClientNow.top-rcClientStart.top);
CRect rcChild;
CWnd* pwndChild = GetWindow(GW_CHILD);
while (pwndChild)
{
pwndChild->GetWindowRect(rcChild);
ScreenToClient(rcChild);
rcChild.OffsetRect(ptOffset);
pwndChild->MoveWindow(rcChild, FALSE);
pwndChild = pwndChild->GetNextWindow();
}
CRect rcWindow;
GetWindowRect(rcWindow);
rcWindow.right += rcClientStart.Width() - rcClientNow.Width();
rcWindow.bottom += rcClientStart.Height() - rcClientNow.Height();
MoveWindow(rcWindow, FALSE);
// And position the control bars
RepositionBars (AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0 );
return TRUE; // return TRUE unless you set the focus to a control
}
14.如何改变对话框的形状
可用下面一些涵数:
CreatePolygonRgn
CreateRectRgn
CreateRoundRectRgn
等
.
CRgn m_rgn; // Put this in your dialog's header file. i.e. a member variable
// This Gets the size of the Dialog: This piece of code is to be placed in the
// OnInitDialog Function of your dialog.
CRect rcDialog
GetClientRect(rcDialog);
// The following code Creates the area and assigns it to your Dialog
m_rgn.CreateEllipticRgn(0
, 0
, rcDialog.Width(), rcDialogHeight());
SetWindowRgn(GetSafeHwnd(), (HRGN) m_rgn, TRUE);
15.如何在对话框中加入状态条
定义 CStatusBar 变量:
CStatusBar m_StatusBar;
定义状态条指定状态:
static UINT BASED_CODE indicators[] =
{
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM
};
在 OnInitDialog 中加入下面代码:
m_StatusBar.CreateEx(this ,SBT_TOOLTIPS,WS_CHILD|WS_VISIBLE|CBRS_BOTTOM,AFX_IDW_STATUS_BAR);
// Set the indicators namely caps and nums lock status
m_StatusBar.SetIndicators(indicators,sizeof (indicators)/sizeof (UINT));
CRect rect;
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.如何实现非客户区移动
可用下面二种方法:
// Handler for WM_LBUTTONDOWN message
void CYourDialog::OnLButtonDown(UINT nFlags, CPoint point)
{
CDialog::OnLButtonDown(nFlags, point);
PostMessage( WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM( point.x, point.y));
}
// Handler for WM_NCHITTEST message
LONG CYourDialog::OnNcHitTest( UINT uParam, LONG lParam )
{
int xPos = LOWORD(lParam);
int yPos = HIWORD(lParam);
UINT nHitTest = CDialog::OnNcHitTest(CSize(xPos, yPos));
return (nHitTest == HTCLIENT) ? HTCAPTION : nHitTest;
}
17.如何使对话框初始为最小化状态
在 OnInitDialog 中加入下面代码:
SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE, NULL);
18. 如何限定对话框大小范围
在 WM_SIZING 中加入下面代码:
void CYourDialog::OnSizing(UINT fwSide, LPRECT pRect)
{
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);
}