不可移动的窗体可以通过重载PreTranslateMessage方法来实现,在PreTranslateMessage方法中将鼠标在标题栏按下的消息改为鼠标在非标题栏按下的消息就可以了。
程序代码如下:
BOOL CBKydctDlg::PreTranslateMessage(MSG* pMsg)
{
if(pMsg->message == WM_NCLBUTTONDOWN)
{
pMsg->message = WM_LBUTTONDOWN;
}
return CDialog::PreTranslateMessage(pMsg);
}
0340 始终在最上面的窗体
有时会因为打开其他软件,而将正在操作的软件置于其后,为操作带来了不便。要实现将自己的程序永远置前,可以使用API函数SetWindowPos,该函数可以为窗口指定一个新位置和状态。
程序代码如下:
BOOL CTopWindowDlg::OnInitDialog()
{
…… //此处代码省略
CRect rect;
GetClientRect(&rect);
::SetWindowPos(AfxGetMainWnd()->m_hWnd,HWND_TOPMOST,rect.left,
rect.top,rect.right,rect.bottom,SWP_NOMOVE);
return TRUE;
}
0341 跟随鼠标移动的窗体
要实现跟随鼠标移动的窗体,需要在定时器中获得鼠标和窗体的位置,再通过MoveWindow函数来移动窗体。
程序代码如下:
void CButterflyDlg::OnTimer(UINT nIDEvent)
{
m_Static.SetBitmap(LoadBitmap(AfxGetInstanceHandle(),
MAKEINTRESOURCE(IDB_BITMAP1+i))); //设置位图
CDC* pDC;
CDC memDC;
CBitmap bitmap;
CBitmap* bmp = NULL;
COLORREF col;
CRect rc;
int x, y;
CRgn rgn, tmp;
pDC = GetDC();
GetClientRect(&rc);
bitmap.LoadBitmap(IDB_BITMAP1+i); //装载模板位图
memDC.CreateCompatibleDC(pDC);
bmp = memDC.SelectObject(&bitmap);
rgn.CreateRectRgn(0, 0, rc.Width(), rc.Height());
//计算得到区域
for(x=0; x<=rc.Width(); x++)
{
for(y=0; y<=rc.Height(); y++)
{
//将白色部分去掉
col = memDC.GetPixel(x, y); //得到像素颜色
if(col == RGB(255,255,255))
{
tmp.CreateRectRgn(x, y, x+1, y+1);
rgn.CombineRgn(&rgn,&tmp,RGN_XOR);
tmp.DeleteObject();
}
}
}
if(bmp)
{
memDC.SelectObject(bmp);
}
SetWindowRgn((HRGN)rgn,TRUE); //设置窗体为区域的形状
ReleaseDC(pDC);
CRect rect;
CPoint nPoint;
GetCursorPos(&nPoint);
GetWindowRect(&rect);
pOint.x = rect.left;
pOint.y = rect.top;
int xRc = (nPoint.x - pOint.x) /8;
int yRc = (nPoint.y - pOint.y) /8;
MoveWindow(pOint.x+xRc*i,pOint.y+yRc*i,rect.Width(),rect.Height());
i++;
if(i==8)i=0;
CDialog::OnTimer(nIDEvent);
}
0342 控制窗体的最大化和最小化
控制窗体的最大化和最小化有两种方法,第一种是在对话框的属性窗口中设置Minimize Box属性和Maximize Box属性,第二种方法是通过PostMessage函数来发送使窗体最大化和最小化的消息。
程序代码如下:
void CMaxAndMinDlg::OnButton1()
{
PostMessage(WM_SYSCOMMAND,SC_MAXIMIZE,0);
}
void CMaxAndMinDlg::OnButton2()
{
PostMessage(WM_SYSCOMMAND,SC_MINIMIZE,0);
}
0343 判断窗体是否最小化在任务栏
在判断窗体是否最小化在任务栏之前要判断该实例是否已经存在,可以使用FindWindow函数来实现,FindWindow函数语法如下:
static CWnd* PASCAL FindWindow( LPCTSTR lpszClassName, LPCTSTR lpszWindowName );
参数说明如下。
l lpszClassName:窗口类名。
l lpszWindowName:窗口名。
然后使用IsIconic函数判断窗体是否最小化到任务栏中,如图6.2所示。
图6.2 判断窗体是否最小化在任务栏
程序代码如下:
void CMinimizeDlg::OnButton1()
{
UpdateData(TRUE);
CWnd *pWndPrev, *pWndChild;
//根据主窗口类名和主窗口名判断是否已经有实例存在了
if(pWndPrev = CWnd::FindWindow(_T(NULL),m_Edit))
{
//判断是否已经最小化
if(pWndPrev->IsIconic())
MessageBox("已经最小化");
else
MessageBox("没有最小化");
}
else
MessageBox("窗口不存在");
}
0344 可调整大小的对话框
在编写应用程序时,有时候要根据需要调整对话框的大小。要想使对话框的大小可以调整,需要将对话框的Border属性设置为Resizing。
0345 限制窗体的大小
有时候想要创建可以调整大小的窗体,但是又不希望窗体太大或太小,这时就要对窗体的大小进行限制,可以在对话框的WM_SIZE消息的处理函数中进行设置。
程序代码如下:
void CRestrictRectDlg::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
CRect rect;
GetWindowRect(&rect);
if(cx > 400)
rect.right = rect.left + 400;
if(cy > 300)
rect.bottom = rect.top + 300;
if(cx < 200)
rect.right = rect.left + 200;
if(cy < 150)
rect.bottom = rect.top + 150;
MoveWindow(&rect);
}
0346 使用鼠标按键调整窗体大小
使用鼠标按键调整窗体大小,就是在窗体的WM_LBUTTONDOWN消息和WM_RBUTTONDOWN消息中放大和缩小窗体。例如单击鼠标左键是窗体缩小,单击鼠标右键是窗体扩大。
程序代码如下:
void CBmpDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
CRect r;
GetWindowRect(&r);
r.right -= 30;
r.bottom -= 20;
MoveWindow(r);
DrawPicture(); //自定义函数,将图片绘制在窗体上
CDialog::OnLButtonDown(nFlags, point);
}
void CBmpDlg::OnRButtonDown(UINT nFlags, CPoint point)
{
CRect r;
GetWindowRect(&r);
r.right += 30;
r.bottom += 20;
MoveWindow(r);
DrawPicture();
CDialog::OnRButtonDown(nFlags, point);
}
0347 根据图片大小显示的窗体
根据图片大小显示的窗体是使用控件显示图片后获得控件的大小,再根据控件大小设置窗体的大小。如图6.3所示。
图6.3 根据图片大小显示的窗体
程序代码如下:
void CPictureDlg::OnButton1()
{
CFileDialog m_filedlg (true,"bmp",NULL,NULL,"位图文件(.bmp)|*.bmp",this);
if (m_filedlg.DoModal() == IDOK)
{
CString str = m_filedlg.GetPathName();
GetDlgItem(IDC_STATIC)->SetWindowText(str);
HBITMAP m_hbitmap = (HBITMAP)::LoadImage(GetModuleHandle(NULL),str,
IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_DEFAULTSIZE|LR_DEFAULTCOLOR);
m_Picture.SetBitmap(m_hbitmap);
CRect rect;
m_Picture.GetWindowRect(rect);
CRect m_rect;
GetWindowRect(m_rect);
m_rect.right = rect.right + 10;
m_rect.bottom = rect.bottom + 10;
MoveWindow(m_rect);
CenterWindow();
}
}
0348 获取当前鼠标点处的控件
在开发程序时,有时需要捕捉当前鼠标点处的控件,以获得其相关信息。可以在程序中使用窗口对象的WindowFromPoint 实现。效果如图6.4所示。
程序相关代码如下:
void CGetWndDlg::OnMouseMove(UINT nFlags, CPoint point)
{
CWnd * pWnd = WindowFromPoint(point);
if (AfxIsValidAddress(pWnd,sizeof(CWnd)))
if (::IsChild(m_hWnd,pWnd->m_hWnd))
{
CString str;
pWnd->GetWindowText(str);
SetWindowText(str);
}
CDialog::OnMouseMove(nFlags, point);
}
BOOL CGetWndDlg::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message==WM_MOUSEMOVE)
{
CPoint point(LOWORD(pMsg->lParam),HIWORD(pMsg->lParam));
::ClientToScreen(pMsg->hwnd,&point);
OnMouseMove(0,point);
}
return CDialog::PreTranslateMessage(pMsg);
}
图6.4 获取当前鼠标点处的控件
0349 在标题栏上绘制控件的简单方法
在设计程序界面时,通常需要在标题栏上进行绘图操作。例如,在标题栏上绘制最大化、最小化、关闭按钮等控件。绘制这些控件时,最简单的方法是调用CDC的DrawFrameControl方法,该方法可以绘制系统提供的常用控件,非常方便。