MFC在鼠标自定义的一定的范围内实现拖动窗口移动、错误:不支持尝试执行的操作、实现进度条颜色的渐变或者背景和前景色的改变

来源:互联网 发布:频率域低通滤波python 编辑:程序博客网 时间:2024/06/10 06:32

模拟自己设计的窗口上面的客户部分鼠标点击可以实现移动

这部分是MFC的对话框中Border选中None

将对话框的上面一部分设定为客户区,采用下面代码模拟客户区

首先在对话框的类向导中添加事件:MouseMove()、activite()、LButtonDown()、LButtonUp()

在头文件中添加

//添加了两个成员变量,一个用来标记移动状态,一个用来记录鼠标按下时的坐标CPoint m_point;BOOL m_bIsMoving;


void CDfuCtrlServiceToolDlg::OnMouseMove(UINT nFlags, CPoint point){// TODO: 在此添加消息处理程序代码和/或调用默认值if (m_bIsMoving){//偏移量//int dx = point.x - m_point.x;//int dy = point.y - m_point.y;////如果窗口闪烁,可以使dx,dy大于1再移动////if(abs(dx)>2||abs(dy)>2)....//CRect rect = { 0 };//GetWindowRect(&rect);//OffsetRect(&rect, dx, dy);//整个窗口偏移dx,dy//MoveWindow(&rect);//移动窗口if (m_point.x<700&& m_point.x>0&& m_point.y>0&& m_point.y<45)//这部分指定了鼠标所点击的位置后发生移动,如果不需要,只采用上面的即可。{int dx = point.x - m_point.x;int dy = point.y - m_point.y;//如果窗口闪烁,可以使dx,dy大于1再移动//if(abs(dx)>2||abs(dy)>2)....CRect rect = { 0 };GetWindowRect(&rect);OffsetRect(&rect, dx, dy);//整个窗口偏移dx,dyMoveWindow(&rect);//移动窗口}else{}}CDialogEx::OnMouseMove(nFlags, point);}void CDfuCtrlServiceToolDlg::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized){CDialogEx::OnActivate(nState, pWndOther, bMinimized);if (nState == WA_INACTIVE && m_bIsMoving){m_bIsMoving = FALSE;ReleaseCapture();}// TODO: 在此处添加消息处理程序代码}void CDfuCtrlServiceToolDlg::OnLButtonDown(UINT nFlags, CPoint point){// TODO: 在此添加消息处理程序代码和/或调用默认值m_bIsMoving = TRUE;SetCapture();//捕获鼠标消息,就算鼠标超过窗口也可以捕获到m_point = point;//记录按下时的坐标CDialogEx::OnLButtonDown(nFlags, point);}


还有一个

void CDfuCtrlServiceToolDlg::OnLButtonUp(UINT nFlags, CPoint point){// TODO: 在此添加消息处理程序代码和/或调用默认值if (m_bIsMoving){m_bIsMoving = FALSE;ReleaseCapture();}CDialogEx::OnLButtonUp(nFlags, point);}

1、MFC中出现不执行尝试的操作

这个问题是我添加了两个控件,后来不需要直接删除掉,但是并没有将其变量在代码中挨个删除;所以需要将其对应的代码一一删除干净;

2、改变进度条的颜色http://www.codefans.net/articles/1454.shtml

3、使用方法

1.将三个文件添加到工程
2.在对话框上添加一个进度条;
新建一个类CGradientProgressCtrl,其基类为CProgressCtrl
3.为进度条添加变量,变量类型CGradientProgressCtrl
4.
应用:
m_process1.SetRange(0, 100);
m_process1.ShowPercent(TRUE);
m_process1.SetStartColor(RGB(0, 0, 255));
m_process1.SetEndColor(RGB(255, 255, 0));
m_process1.SetTextColor(RGB(0, 0, 255));
m_process1.SetBkColor(RGB(125, 125, 125));
m_process1.SetPos(50);//设置百分比

4、其中GradientProgressCtrl.h

#if !defined(AFX_ENHPROGRESSCTRL_H__12909D73_C393_11D1_9FAE_8192554015AD__INCLUDED_)#define AFX_ENHPROGRESSCTRL_H__12909D73_C393_11D1_9FAE_8192554015AD__INCLUDED_#if _MSC_VER >= 1000#pragma once#endif // _MSC_VER >= 1000// EnhProgressCtrl.h : header file// GradientProgressCtrl.h : header file#include "MemDC.h"/////////////////////////////////////////////////////////////////////////////// CGradientProgressCtrl windowclass CGradientProgressCtrl : public CProgressCtrl{// Constructionpublic:CGradientProgressCtrl();// Attributespublic:// Attributesvoid SetRange(int nLower, int nUpper);void SetRange32( int nLower, int nUpper );int SetPos(int nPos);int SetStep(int nStep);int StepIt(void);// Operationspublic:// Set Functionsvoid SetTextColor(COLORREF color){m_clrText = color;}void SetBkColor(COLORREF color) {m_clrBkGround = color;}void SetStartColor(COLORREF color){m_clrStart = color;}void SetEndColor(COLORREF color){m_clrEnd = color;}// Show the percent captionvoid ShowPercent(BOOL bShowPercent = TRUE){m_bShowPercent = bShowPercent;}// Get FunctionsCOLORREF GetTextColor(void){return m_clrText;}COLORREF GetBkColor(void) {return m_clrBkGround;}COLORREF GetStartColor(void){return m_clrStart;}COLORREF GetEndColor(void){return m_clrEnd;}// Overrides// ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(CGradientProgressCtrl)protected://}}AFX_VIRTUAL// Implementationpublic:virtual ~CGradientProgressCtrl();// Generated message map functionsprotected:void DrawGradient(CPaintDC *pDC, const RECT &rectClient, const int &nMaxWidth, const BOOL &bVertical);int m_nLower, m_nUpper, m_nStep, m_nCurrentPosition;COLORREFm_clrStart, m_clrEnd, m_clrBkGround, m_clrText;BOOL m_bShowPercent;//{{AFX_MSG(CGradientProgressCtrl)afx_msg void OnPaint();afx_msg BOOL OnEraseBkgnd(CDC* pDC);//}}AFX_MSGDECLARE_MESSAGE_MAP()};///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}}// Microsoft Developer Studio will insert additional declarations immediately before the previous line.#endif // !defined(AFX_ENHPROGRESSCTRL_H__12909D73_C393_11D1_9FAE_8192554015AD__INCLUDED_)


5、其中GradientProgressCtrl.c

// GradientProgressCtrl.cpp : implementation file#include "stdafx.h"#include "GradientProgressCtrl.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////// CGradientProgressCtrlCGradientProgressCtrl::CGradientProgressCtrl(){// Defaults assigned by CProgressCtrl()m_nLower = 0;m_nUpper = 100;m_nCurrentPosition = 0;m_nStep = 10;// Initial colorsm_clrStart= COLORREF(RGB(255, 0,0));m_clrEnd = COLORREF(RGB(0,0,255));m_clrBkGround = COLORREF(RGB(0, 0, 0)); //::GetSysColor(COLOR_3DFACE);m_clrText = COLORREF(RGB(255, 255, 255));// Initial show percentm_bShowPercent = FALSE;}CGradientProgressCtrl::~CGradientProgressCtrl(){}BEGIN_MESSAGE_MAP(CGradientProgressCtrl, CProgressCtrl)//{{AFX_MSG_MAP(CGradientProgressCtrl)ON_WM_PAINT()ON_WM_ERASEBKGND()//}}AFX_MSG_MAPEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CGradientProgressCtrl message handlers//////////////////////////////////////////////////////////////////////////////* OnPaintThe main drawing routine.  Consists of two parts(1) Call the DrawGradient routine to draw the visible part of the progress gradient(2) If needed, show the percentage text *//////////////////////////////////////////////////////////////////////////////void CGradientProgressCtrl::OnPaint() {CPaintDC dc(this); // device context for painting// TODO: Add your message handler code hereCRect rectClient;GetClientRect(&rectClient);// If the current positionis  invalid then we should fade into the  backgroundif (m_nCurrentPosition <= m_nLower || m_nCurrentPosition > m_nUpper){CRect rect;GetClientRect(rect);CBrush brush;brush.CreateSolidBrush(COLORREF(RGB(0, 0, 0)));// ::GetSysColor(COLOR_3DFACE));dc.FillRect(&rect, &brush);VERIFY(brush.DeleteObject());return;}// The actions to take depend on whether or not we are a vertical controlDWORD dwStyles = GetStyle();BOOL bVertical = (BOOL)(dwStyles & PBS_VERTICAL);// Figure out what part should be visible so we can stop the gradient when neededfloat maxWidth;if (bVertical)maxWidth = ((float)m_nCurrentPosition/(float)m_nUpper * (float)rectClient.bottom);elsemaxWidth = ((float)m_nCurrentPosition/(float)m_nUpper * (float)rectClient.right);// Draw the gradientDrawGradient(&dc, rectClient, (int)maxWidth, bVertical);// Show percent indicator if neededif (m_bShowPercent){CString strPercent;float fp = 100.0f; fp *= (float)(m_nCurrentPosition-m_nLower); fp /= (float)(m_nUpper-m_nLower); strPercent.Format(_T("%3.0f %%"), fp);dc.SetTextColor(m_clrText);dc.SetBkMode(TRANSPARENT);dc.DrawText(strPercent, &rectClient, DT_VCENTER |  DT_CENTER | DT_SINGLELINE);}// Do not call CProgressCtrl::OnPaint() for painting messages}//////////////////////////////////////////////////////////////////////////////*SetRangeOverridden base class member to remember where the indicator thinks it is and the boundary range of the control.ParamsnLowerlower boundnUpperuppoer bound*//////////////////////////////////////////////////////////////////////////////void CGradientProgressCtrl:: SetRange(int nLower, int nUpper){m_nLower = nLower;m_nUpper = nUpper;m_nCurrentPosition = nLower;CProgressCtrl::SetRange(nLower, nUpper);}//////////////////////////////////////////////////////////////////////////////*SetRange32Overridden base class member to remember where the indicator thinks it is and the boundary range of the control.ParamsnLowerlower boundnUpperuppoer bound*//////////////////////////////////////////////////////////////////////////////void CGradientProgressCtrl:: SetRange32( int nLower, int nUpper ){m_nLower = nLower;m_nUpper = nUpper;m_nCurrentPosition = nLower;CProgressCtrl::SetRange(nLower, nUpper);}//////////////////////////////////////////////////////////////////////////////*SetPosOverridden base class member to retain where the current progress indicatoris located.ParamsnPosCurrent position in range*//////////////////////////////////////////////////////////////////////////////int CGradientProgressCtrl:: SetPos(int nPos){m_nCurrentPosition = nPos;return (CProgressCtrl::SetPos(nPos));}//////////////////////////////////////////////////////////////////////////////*SetStepOverridden base class member to retain the step interval used when filling the progress controlParamsnStepstep interval for filling progress control*//////////////////////////////////////////////////////////////////////////////int CGradientProgressCtrl:: SetStep(int nStep){m_nStep = nStep;return (CProgressCtrl::SetStep(nStep));}//////////////////////////////////////////////////////////////////////////////*StepItOverridden base class member to increment the control according to thecurrent position and the step intervalParamsnStepstep interval for filling progress control*//////////////////////////////////////////////////////////////////////////////int CGradientProgressCtrl:: StepIt(void){m_nCurrentPosition += m_nStep;return (CProgressCtrl::StepIt());}//////////////////////////////////////////////////////////////////////////////*DrawGradientCalled from OnPaint, it does most of the work of filling in the client rectangle with the appropriate colors.  The normal routine would fillthe entire client rectangle, but we truncate the drawing to reflectthe current position in the progress controlParamspDCpointer to CPaintDC for renderingrectClientclient rectangle where we should drawnMaxWidthwhere we should stop drawing the gradient*//////////////////////////////////////////////////////////////////////////////void CGradientProgressCtrl::DrawGradient(CPaintDC *pDC, const RECT &rectClient, const int &nMaxWidth, const BOOL &bVertical){RECT rectFill;   // Rectangle for filling bandfloat fStep;              // How wide is each band?CBrush brush;// Brush to fill in the barCMYMemDC memDC(pDC);// First find out the largest color distance between the start and end colors.  This distance// will determine how many steps we use to carve up the client region and the size of each// gradient rect.int r, g, b;// First distance, then starting valuefloat rStep, gStep, bStep;// Step size for each colorBOOL  bSameColor = FALSE;// Handle case if start color == end color// Get the color differencesr = (GetRValue(m_clrEnd) - GetRValue(m_clrStart));g = (GetGValue(m_clrEnd) - GetGValue(m_clrStart));b =  (GetBValue(m_clrEnd) - GetBValue(m_clrStart));// Check to see if colors are sameif((r == 0) && (g == 0) && (b == 0)){bSameColor = TRUE;//Added the three lines below to fix the drawing //problem which used to occur when both the start //and end colors are same.r = GetRValue(m_clrStart);g = GetGValue(m_clrStart);b = GetBValue(m_clrStart);}int nSteps;//Select max. possible value for nSteps if the colors are equalif(bSameColor && m_clrStart == 0)nSteps = 255;else // Make the number of steps equal to the greatest distancenSteps = max(abs(r), max(abs(g), abs(b)));// Determine how large each band should be in order to cover the// client with nSteps bands (one for every color intensity level)if (bVertical)fStep = (float)rectClient.bottom / (float)nSteps;elsefStep = (float)rectClient.right / (float)nSteps;// Calculate the step size for each colorrStep = r/(float)nSteps;gStep = g/(float)nSteps;bStep = b/(float)nSteps;//这三个变量都设置为0就不会出现渐变颜色// Reset the colors to the starting positionr = GetRValue(m_clrStart);g = GetGValue(m_clrStart);b = GetBValue(m_clrStart);// Start filling bandsfor (int iOnBand = 0; iOnBand < nSteps; iOnBand++) {// Fill the vertical controlif (bVertical){::SetRect(&rectFill,0,// Upper left X(int)(iOnBand * fStep),// Upper left YrectClient.right+1,// Lower right X(int)((iOnBand+1) * fStep));// Lower right Y// CDC::FillSolidRect is faster, but it does not handle 8-bit color depthVERIFY(brush.CreateSolidBrush(RGB(r+rStep*iOnBand, g + gStep*iOnBand, b + bStep *iOnBand)));memDC.FillRect(&rectFill,&brush);VERIFY(brush.DeleteObject());// If we are past the maximum for the current position we need to get out of the loop.// Before we leave, we repaint the remainder of the client area with the background color.if (rectFill.bottom > nMaxWidth){::SetRect(&rectFill, 0, rectFill.bottom, rectClient.right, rectClient.bottom);VERIFY(brush.CreateSolidBrush(m_clrBkGround));memDC.FillRect(&rectFill, &brush);VERIFY(brush.DeleteObject());return;}}else // Fill the horizontal control{::SetRect(&rectFill,(int)(iOnBand * fStep),     // Upper left X 0,// Upper left Y(int)((iOnBand+1) * fStep), // Lower right XrectClient.bottom+1);// Lower right Y// CDC::FillSolidRect is faster, but it does not handle 8-bit color depthVERIFY(brush.CreateSolidBrush(RGB(r+rStep*iOnBand, g + gStep*iOnBand, b + bStep *iOnBand)));memDC.FillRect(&rectFill,&brush);VERIFY(brush.DeleteObject());// If we are past the maximum for the current position we need to get out of the loop.// Before we leave, we repaint the remainder of the client area with the background color.if (rectFill.right > nMaxWidth){::SetRect(&rectFill, rectFill.right, 0, rectClient.right, rectClient.bottom);VERIFY(brush.CreateSolidBrush(m_clrBkGround));memDC.FillRect(&rectFill, &brush);VERIFY(brush.DeleteObject());return;}}}}//////////////////////////////////////////////////////////////////////////////*OnEraseBkgndOverridden CWnd function so that all drawing is done in the OnPaint call.We return TRUE so that CWnd doesn't try to erase our background.ParamspDCpointer to CDC for rendering*//////////////////////////////////////////////////////////////////////////////BOOL CGradientProgressCtrl::OnEraseBkgnd(CDC* pDC) {// TODO: Add your message handler code here and/or call defaultreturn TRUE;}


6、其中MemDC.h

#if !defined(AFX_MEMDC_H__CA1D3541_7235_11D1_ABBA_00A0243D1382__INCLUDED_)#define AFX_MEMDC_H__CA1D3541_7235_11D1_ABBA_00A0243D1382__INCLUDED_#if _MSC_VER >= 1000#pragma once#endif // _MSC_VER >= 1000// MemDC.h : header file////////////////////////////////////////////////////// CMemDC - memory DC//// Author: Keith Rule// Email:  keithr@europa.com// Copyright 1996-1997, Keith Rule//// You may freely use or modify this code provided this// Copyright is included in all derived versions.//// History - 10/3/97 Fixed scrolling bug.//                   Added print support.//           25 feb 98 - fixed minor assertion bug//// This class implements a memory Device Contextclass CMYMemDC : public CDC{public:// constructor sets up the memory DCCMYMemDC(CDC* pDC) : CDC()    {ASSERT(pDC != NULL);m_pDC = pDC;m_pOldBitmap = NULL;        m_bMemDC = !pDC->IsPrinting();        if (m_bMemDC)// Create a Memory DC{            pDC->GetClipBox(&m_rect);            CreateCompatibleDC(pDC);            m_bitmap.CreateCompatibleBitmap(pDC, m_rect.Width(), m_rect.Height());m_pOldBitmap = SelectObject(&m_bitmap);            SetWindowOrg(m_rect.left, m_rect.top);        }else// Make a copy of the relevent parts of the current DC for printing{            m_bPrinting = pDC->m_bPrinting;            m_hDC= pDC->m_hDC;            m_hAttribDC = pDC->m_hAttribDC;        }}// Destructor copies the contents of the mem DC to the original DC~CMYMemDC()    {if (m_bMemDC) {// Copy the offscreen bitmap onto the screen.m_pDC->BitBlt(m_rect.left, m_rect.top, m_rect.Width(), m_rect.Height(),this, m_rect.left, m_rect.top, SRCCOPY);            //Swap back the original bitmap.            SelectObject(m_pOldBitmap);} else {// All we need to do is replace the DC with an illegal value,// this keeps us from accidently deleting the handles associated with// the CDC that was passed to the constructor.            m_hDC = m_hAttribDC = NULL;}}// Allow usage as a pointerCMYMemDC* operator->() {return this;}    // Allow usage as a pointer    operator CMYMemDC*() {return this;}private:CBitmap  m_bitmap;// Offscreen bitmap    CBitmap* m_pOldBitmap;// bitmap originally found in CMYMemDC    CDC*     m_pDC;// Saves CDC passed in constructor    CRect    m_rect;// Rectangle of drawing area.    BOOL     m_bMemDC;// TRUE if CDC really is a Memory DC.};///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}}// Microsoft Developer Studio will insert additional declarations immediately before the previous line.#endif // !defined(AFX_MEMDC_H__CA1D3541_7235_11D1_ABBA_00A0243D1382__INCLUDED_)







阅读全文
0 0